Анализ кода для предупреждений драйверов
В этом разделе перечислены и описаны предупреждения о том, что анализ кода для драйверов сообщает при обнаружении возможной ошибки в коде драйвера. Обратите внимание, что некоторые предупреждения предназначены для кода в режиме ядра и могут игнорироваться при анализе драйверов пользовательского режима.
Внимание
Анализ кода для драйверов доступен в Windows 24H2 WDK и EWDK, но следует рекомендовать, что он будет снят в будущем.
В будущем CodeQL будет основным средством статического анализа драйверов. CodeQL предоставляет мощный язык запросов, который обрабатывает код как базу данных для запроса, что упрощает запись запросов для конкретных поведения, шаблонов и многого другого.
Дополнительные сведения об использовании CodeQL см. в разделе CodeQL и проверка логотипа статических инструментов.
Анализ кода для драйверов сообщает следующие типы предупреждений:
Общие предупреждения (6000-6999): потенциальные ошибки в синтаксисе C и C++ и общая практика написания кода. Описание этих предупреждений см. в разделе "Анализ кода для предупреждений C/C++".
Определенные предупреждения Windows (28600-28799): эти предупреждения относятся к определенным шаблонам использования в Windows, но не относятся к драйверам.
Предупреждения для конкретного драйвера (28100-28199): ошибки в взаимодействии драйвера с приложением, с другими драйверами и операционной системой.
Ошибки заметки (28200-28299 и 36000-36999): эти предупреждения указывают на то, что заметка была неправильно закодирована или использована в неправильном контексте. В большинстве случаев наличие такого предупреждения указывает на то, что заметка не имеет требуемого (или какого-либо) эффекта.
Предупреждения выделения памяти (30029-30035): это предупреждения о выделении памяти.
В этом разделе
Раздел | Описание |
---|---|
предупреждение C28101: модуль драйверов показал, что текущая функция не является правильным типом функции. |
|
предупреждение C28110: драйверы должны защищать состояние оборудования с плавающей запятой. См. сведения об использовании float |
|
предупреждение C28111: IRQL, в котором сохранено состояние с плавающей запятой, не соответствует текущему IRQL (для этой операции восстановления). |
|
предупреждение: C28114: копирование всей записи стека IRP оставляет определенные поля инициализированы, которые следует очистить или обновить. |
|
предупреждение C28120: функция не допускается вызывать на текущем уровне IRQ. Текущий уровень слишком низкий. |
|
предупреждение C28121: функция не допускается вызывать на текущем уровне IRQ. Текущий уровень слишком высок. |
|
предупреждение C28122: функция не допускается вызывать на низком уровне IRQ. Предыдущие вызовы функций несовместимы с этим ограничением. |
|
предупреждение C28123: функция не допускается вызывать на высоком уровне IRQ. Предыдущие вызовы функций несовместимы с этим ограничением. |
|
предупреждение C28124: вызов вызывает определение уровня IRQ ниже минимально допустимого для анализируемой функции. |
|
предупреждение C28126: параметр AccessMode для ObReferenceObject* должен иметь значение IRP-RequestorMode> |
|
предупреждение C28127: функция, используемая в качестве подпрограммы, не соответствует ожидаемому типу. |
|
предупреждение C28128: доступ к полю был сделан напрямую. Он должен быть сделан подпрограммой. |
|
предупреждение C28129: назначение было сделано операндам, которое следует изменять только с помощью битовых наборов и очистки |
|
предупреждение C28131: подпрограмма DriverEntry должна сохранить копию аргумента, а не указатель, так как диспетчер ввода-вывода освобождает буфер. |
|
предупреждение C28132: получение размера указателя |
|
предупреждение C28133: IoInitializeTimer лучше всего вызывать из AddDevice |
|
предупреждение C28134: тип тега пула должен быть целым, а не строковым указателем или строковым указателем |
|
предупреждение C28135: если первый аргумент к KeWaitForSingleObject является локальной переменной, параметр Mode должен быть KernelMode |
|
предупреждение C28139: аргумент должен точно соответствовать типу |
|
предупреждение C28141: аргумент вызывает настройку уровня IRQ ниже текущего IRQL, и эту функцию нельзя использовать для этой цели. |
|
предупреждение C28143: подпрограмма отправки, которая вызывает IoMarkIrpPending, также должна возвращать STATUS_PENDING |
|
предупреждение C28144: в рамках подпрограммы отмены в точке выхода IRQL в Irp-CancelIrql> должен быть текущим IRQL. |
|
предупреждение C28145: непрозрачная структура MDL не должна изменяться драйвером. |
|
предупреждение C28146: драйверы режима ядра должны использовать ntstrsafe.h, а не strsafe.h. Найден в исходном файле |
|
предупреждение C28147: использование тега пула по умолчанию ('kdD' или mdW') для вызовов этой функции побеждает назначение тегов пула |
|
предупреждение C28150: функция приводит к настройке уровня IRQ выше максимального допустимого для анализируемой функции. |
|
предупреждение C28151: значение не является юридическим значением для IRQL |
|
предупреждение C28152: возврат из функции AddDevice, похожей на непредвиденное DO_DEVICE_INITIALIZING |
|
предупреждение C28153: значение IRQL из заметки не удалось оценить в этом контексте. |
|
предупреждение C28156: фактический IRQL не согласуется с обязательным IRQL |
|
предупреждение C28157: IRQL никогда не был восстановлен |
|
предупреждение C28158: не было сохранено IRQL |
|
предупреждение C28161: выход без получения права на использование плавающего оборудования |
|
предупреждение C28162: выход при удержании права на использование оборудования с плавающей запятой |
|
предупреждение C28165: указатель функции класса не соответствует классу функции |
|
предупреждение C28166: функция не восстанавливает IRQL в значение, которое было текущим в записи функции и требуется для этого. |
|
предупреждение C28167: функция изменяет IRQL и не восстанавливает IRQL перед выходом. Оно должно быть аннотировано, чтобы отразить изменение или IRQL необходимо восстановить. |
|
предупреждение C28168: функция отправки не имеет Dispatch_type заметки, соответствующие этой записи таблицы отправки. |
|
предупреждение C28169: функция отправки не имеет никаких заметок Dispatch_type |
|
предупреждение C28170: функция объявлена в сегменте страниц, но ни PAGED_CODE, ни PAGED_CODE_LOCKED не найдена |
|
предупреждение C28171: функция имеет несколько экземпляров PAGED_CODE или PAGED_CODE_LOCKED |
|
предупреждение C28172: функция имеет PAGED_CODE или PAGED_CODE_LOCKED, но не объявляется в сегменте страниц |
|
предупреждение C28173: текущая функция, как представляется, неправильно адаптируется к физической памяти выше 4 ГБ |
|
предупреждение C28175: член структуры не должен получить доступ к драйверу |
|
предупреждение C28176: член структуры не должен быть изменен драйвером |
|
предупреждение C28177: функция аннотирована с несколькими классами функций. Все, кроме одного, будут игнорироваться. |
|
предупреждение C28260: синтаксическая ошибка в заметках была найдена при анализе свойства внутри функции. |
|
Синтаксическая ошибка в заметках была найдена для свойства в функции. |
|
предупреждение C28268: класс функции функции не соответствует классу функции, используемому здесь. |
|
предупреждение C28601: избегайте блокировки на HWND_BROADCAST |
|
предупреждение C28602: избегайте вызова SendMessageTimeout с помощью HWND_BROADCAST |
|
предупреждение C28604: избегайте вызова SendMessageTimeout с SMTO_ABORTIFHUNG с истечением времени ожидания 0 |
|
предупреждение C28615: необходимо вызывать _resetstkoflw в блоке __except() при вызове _alloca в блоке __try. Не вызывайте _resetstkoflw из блока catch() |
|
предупреждение C28616: многопоточное состояние AV |
|
предупреждение C28617: избегайте использования возвращаемого значения _beginthread(). Вместо этого используйте _beginthreadex() |
|
предупреждение C28623: неподписанный приведение координат GetMessagePos(). Используйте GET_X_LPARAM/GET_Y_LPARAM вместо LOWORD/HIWORD |
|
предупреждение C28624: нет вызова release() для сопоставления добавочного ссылки из LResultFromObject |
|
предупреждение C28625: вызов функции, используемый для очистки конфиденциальных данных, будет оптимизирован |
|
предупреждение C28636: вызов LocalFree на не выделенном указателе, полученном из вызовов GetSecurityDescriptorOwner/Group/Dacl/Sacl |
|
предупреждение C28637: вызов функции в глобальном инициализаторе небезопасн |
|
предупреждение C28638: заглушка задержки функции отсутствует соответствующее объявление |
|
предупреждение C28639: вызов закрывающего дескриптора со строкой |
|
предупреждение C28640: заглушка задержки функции должна быть статической функцией |
|
предупреждение C28644: возвращаемое значение из DPA_InsertPtr не проверено |
|
предупреждение C28645: MessageBox был вызван с помощью символа сообщения с вопросительным знаком, который больше не рекомендуется |
|
предупреждение C28648: PulseEvent является ненадежной функцией |
|
предупреждение C28649: автоматические или глобальные массивы стека никогда не имеют значения NULL |
|
предупреждение C28650: тип, для которого используется !0, не обрабатывает его как случай сбоя. Возвращает значение состояния, например ! ЗНАЧЕНИЕ TRUE не совпадает с возвратом значения состояния, указывающего на сбой. |
|
предупреждение C28651: статический инициализатор приводит к копированию на страницах записи из-за указателей функции-члена |
|
предупреждение C28652: статический инициализатор приводит к копированию на страницах записи из-за перегруженных битовых операторов |
|
предупреждение C28714: приведение между семантически разными целыми типами |
|
предупреждение C28715: приведение между семантически разными целыми типами |
|
предупреждение C28716: вставленный компилятором приведение между семантически разными целочисленными типами |
|
предупреждение C28717: недопустимый тип VARIANT |
|
предупреждение C28718: ненататированный буфер |
|
предупреждение C28719: запрещенное использование API |
|
предупреждение C28720: запрещенное использование API |
|
предупреждение C28721: устаревшая архитектура счетчика производительности |
|
предупреждение C28722: ненататированный буфер в объявлении функции |
|
предупреждение C28723: ненататированный буфер в определении функции, не имеющий соответствующего объявления |
|
предупреждение C28725: используйте Уотсон вместо этого SetUnhandledExceptionFilter |
|
предупреждение C28726: запрещенное использование API |
|
предупреждение C28727: запрещенное использование API |
|
предупреждение C28728: запрещенное использование API |
|
предупреждение C28730: возможное назначение "\0" непосредственно указателю. |
|
предупреждение C28735: запрещенное использование API C28735 |
|
предупреждение C28736: запрещенное использование аргумента API |
|
предупреждение C28740: ненататированный буфер без знака |
|
предупреждение C28741: ненататированный буфер в функции |
|
предупреждение C28742: ненататированный буфер в функции |
|
предупреждение C28750: запрещено использование lstrlen и его вариантов |
|
предупреждение C28751: запрещено использование ExAllocatePool и его вариантов |
|
предупреждение C28752: запрещено использование API ядра32 или advapi32 |
|
предупреждение C28753: использование неопределенного порядка оценки параметров |
|
предупреждение C30029: вызов функции выделения памяти, которая запрашивает исполняемую память. |
|
предупреждение C30030: вызов функции выделения памяти и передача параметра, указывающего исполняемую память |
|
предупреждение C30031: вызов функции выделения памяти и передача параметра, указывающего исполняемую память |
|
предупреждение C30032: вызов функции выделения памяти и принудительное выполнение запроса исполняемой памяти с помощью директивы POOL_NX_OPTOUT |
|
предупреждение C30033: выделение исполняемых файлов обнаружено в драйвере, скомпилированном с POOL_NX_OPTIN. Этот драйвер был определен для загрузки во время выполнения другим драйвером. Убедитесь, что драйвер загрузки вызывает ExInitializeDriverRuntime(DrvRtPoolNxOptIn) в driverEntry. |
|
предупреждение C30034: передача значения флага в функцию выделения, которая может привести к выделению исполняемой памяти. Убедитесь, что функция выделения не запрашивает форму исполняемого пула, отличного от буфера. |
|
предупреждение C30035: вызов был выполнен в функцию, которая должна выполняться внутри функции инициализации (например, DriverEntry() или DllInitialize()). PREfast не удалось определить, был ли вызов выполнен из функции инициализации. |