Поделиться через


Анализ кода для предупреждений драйверов

В этом разделе перечислены и описаны предупреждения о том, что анализ кода для драйверов сообщает при обнаружении возможной ошибки в коде драйвера. Обратите внимание, что некоторые предупреждения предназначены для кода в режиме ядра и могут игнорироваться при анализе драйверов пользовательского режима.

Внимание

Анализ кода для драйверов доступен в 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

предупреждение C28101: модуль драйверов показал, что текущая функция не является правильным типом функции.

C28110

предупреждение C28110: драйверы должны защищать состояние оборудования с плавающей запятой. См. сведения об использовании float

C28111

предупреждение C28111: IRQL, в котором сохранено состояние с плавающей запятой, не соответствует текущему IRQL (для этой операции восстановления).

C28114

предупреждение: C28114: копирование всей записи стека IRP оставляет определенные поля инициализированы, которые следует очистить или обновить.

C28120

предупреждение C28120: функция не допускается вызывать на текущем уровне IRQ. Текущий уровень слишком низкий.

C28121

предупреждение C28121: функция не допускается вызывать на текущем уровне IRQ. Текущий уровень слишком высок.

C28122

предупреждение C28122: функция не допускается вызывать на низком уровне IRQ. Предыдущие вызовы функций несовместимы с этим ограничением.

C28123

предупреждение C28123: функция не допускается вызывать на высоком уровне IRQ. Предыдущие вызовы функций несовместимы с этим ограничением.

C28124

предупреждение C28124: вызов вызывает определение уровня IRQ ниже минимально допустимого для анализируемой функции.

C28126

предупреждение C28126: параметр AccessMode для ObReferenceObject* должен иметь значение IRP-RequestorMode>

C28127

предупреждение C28127: функция, используемая в качестве подпрограммы, не соответствует ожидаемому типу.

C28128

предупреждение C28128: доступ к полю был сделан напрямую. Он должен быть сделан подпрограммой.

C28129

предупреждение C28129: назначение было сделано операндам, которое следует изменять только с помощью битовых наборов и очистки

C28131

предупреждение C28131: подпрограмма DriverEntry должна сохранить копию аргумента, а не указатель, так как диспетчер ввода-вывода освобождает буфер.

C28132

предупреждение C28132: получение размера указателя

C28133

предупреждение C28133: IoInitializeTimer лучше всего вызывать из AddDevice

C28134

предупреждение C28134: тип тега пула должен быть целым, а не строковым указателем или строковым указателем

C28135

предупреждение C28135: если первый аргумент к KeWaitForSingleObject является локальной переменной, параметр Mode должен быть KernelMode

C28139

предупреждение C28139: аргумент должен точно соответствовать типу

C28141

предупреждение C28141: аргумент вызывает настройку уровня IRQ ниже текущего IRQL, и эту функцию нельзя использовать для этой цели.

C28143

предупреждение C28143: подпрограмма отправки, которая вызывает IoMarkIrpPending, также должна возвращать STATUS_PENDING

C28144

предупреждение C28144: в рамках подпрограммы отмены в точке выхода IRQL в Irp-CancelIrql> должен быть текущим IRQL.

C28145

предупреждение C28145: непрозрачная структура MDL не должна изменяться драйвером.

C28146

предупреждение C28146: драйверы режима ядра должны использовать ntstrsafe.h, а не strsafe.h. Найден в исходном файле

C28147

предупреждение C28147: использование тега пула по умолчанию ('kdD' или mdW') для вызовов этой функции побеждает назначение тегов пула

C28150

предупреждение C28150: функция приводит к настройке уровня IRQ выше максимального допустимого для анализируемой функции.

C28151

предупреждение C28151: значение не является юридическим значением для IRQL

C28152

предупреждение C28152: возврат из функции AddDevice, похожей на непредвиденное DO_DEVICE_INITIALIZING

C28153

предупреждение C28153: значение IRQL из заметки не удалось оценить в этом контексте.

C28156

предупреждение C28156: фактический IRQL не согласуется с обязательным IRQL

C28157

предупреждение C28157: IRQL никогда не был восстановлен

C28158

предупреждение C28158: не было сохранено IRQL

C28161

предупреждение C28161: выход без получения права на использование плавающего оборудования

C28162

предупреждение C28162: выход при удержании права на использование оборудования с плавающей запятой

C28165

предупреждение C28165: указатель функции класса не соответствует классу функции

C28166

предупреждение C28166: функция не восстанавливает IRQL в значение, которое было текущим в записи функции и требуется для этого.

C28167

предупреждение C28167: функция изменяет IRQL и не восстанавливает IRQL перед выходом. Оно должно быть аннотировано, чтобы отразить изменение или IRQL необходимо восстановить.

C28168

предупреждение C28168: функция отправки не имеет Dispatch_type заметки, соответствующие этой записи таблицы отправки.

C28169

предупреждение C28169: функция отправки не имеет никаких заметок Dispatch_type

C28170

предупреждение C28170: функция объявлена в сегменте страниц, но ни PAGED_CODE, ни PAGED_CODE_LOCKED не найдена

C28171

предупреждение C28171: функция имеет несколько экземпляров PAGED_CODE или PAGED_CODE_LOCKED

C28172

предупреждение C28172: функция имеет PAGED_CODE или PAGED_CODE_LOCKED, но не объявляется в сегменте страниц

C28173

предупреждение C28173: текущая функция, как представляется, неправильно адаптируется к физической памяти выше 4 ГБ

C28175

предупреждение C28175: член структуры не должен получить доступ к драйверу

C28176

предупреждение C28176: член структуры не должен быть изменен драйвером

C28177

предупреждение C28177: функция аннотирована с несколькими классами функций. Все, кроме одного, будут игнорироваться.

C28260

предупреждение C28260: синтаксическая ошибка в заметках была найдена при анализе свойства внутри функции.

C28266

Синтаксическая ошибка в заметках была найдена для свойства в функции.

C28268

предупреждение C28268: класс функции функции не соответствует классу функции, используемому здесь.

C28601

предупреждение C28601: избегайте блокировки на HWND_BROADCAST

C28602

предупреждение C28602: избегайте вызова SendMessageTimeout с помощью HWND_BROADCAST

C28604

предупреждение C28604: избегайте вызова SendMessageTimeout с SMTO_ABORTIFHUNG с истечением времени ожидания 0

C28615

предупреждение C28615: необходимо вызывать _resetstkoflw в блоке __except() при вызове _alloca в блоке __try. Не вызывайте _resetstkoflw из блока catch()

C28616

предупреждение C28616: многопоточное состояние AV

C28617

предупреждение C28617: избегайте использования возвращаемого значения _beginthread(). Вместо этого используйте _beginthreadex()

C28623

предупреждение C28623: неподписанный приведение координат GetMessagePos(). Используйте GET_X_LPARAM/GET_Y_LPARAM вместо LOWORD/HIWORD

C28624

предупреждение C28624: нет вызова release() для сопоставления добавочного ссылки из LResultFromObject

C28625

предупреждение C28625: вызов функции, используемый для очистки конфиденциальных данных, будет оптимизирован

C28636

предупреждение C28636: вызов LocalFree на не выделенном указателе, полученном из вызовов GetSecurityDescriptorOwner/Group/Dacl/Sacl

C28637

предупреждение C28637: вызов функции в глобальном инициализаторе небезопасн

C28638

предупреждение C28638: заглушка задержки функции отсутствует соответствующее объявление

C28639

предупреждение C28639: вызов закрывающего дескриптора со строкой

C28640

предупреждение C28640: заглушка задержки функции должна быть статической функцией

C28644

предупреждение C28644: возвращаемое значение из DPA_InsertPtr не проверено

C28645

предупреждение C28645: MessageBox был вызван с помощью символа сообщения с вопросительным знаком, который больше не рекомендуется

C28648

предупреждение C28648: PulseEvent является ненадежной функцией

C28649

предупреждение C28649: автоматические или глобальные массивы стека никогда не имеют значения NULL

C28650

предупреждение C28650: тип, для которого используется !0, не обрабатывает его как случай сбоя.

Возвращает значение состояния, например ! ЗНАЧЕНИЕ TRUE не совпадает с возвратом значения состояния, указывающего на сбой.

C28651

предупреждение C28651: статический инициализатор приводит к копированию на страницах записи из-за указателей функции-члена

C28652

предупреждение C28652: статический инициализатор приводит к копированию на страницах записи из-за перегруженных битовых операторов

C28714

предупреждение C28714: приведение между семантически разными целыми типами

C28715

предупреждение C28715: приведение между семантически разными целыми типами

C28716

предупреждение C28716: вставленный компилятором приведение между семантически разными целочисленными типами

C28717

предупреждение C28717: недопустимый тип VARIANT

C28718

предупреждение C28718: ненататированный буфер

C28719

предупреждение C28719: запрещенное использование API

C28720

предупреждение C28720: запрещенное использование API

C28721

предупреждение C28721: устаревшая архитектура счетчика производительности

C28722

предупреждение C28722: ненататированный буфер в объявлении функции

C28723

предупреждение C28723: ненататированный буфер в определении функции, не имеющий соответствующего объявления

C28725

предупреждение C28725: используйте Уотсон вместо этого SetUnhandledExceptionFilter

C28726

предупреждение C28726: запрещенное использование API

C28727

предупреждение C28727: запрещенное использование API

C28728

предупреждение C28728: запрещенное использование API

C28730

предупреждение C28730: возможное назначение "\0" непосредственно указателю.

C28735

предупреждение C28735: запрещенное использование API C28735

C28736

предупреждение C28736: запрещенное использование аргумента API

C28740

предупреждение C28740: ненататированный буфер без знака

C28741

предупреждение C28741: ненататированный буфер в функции

C28742

предупреждение C28742: ненататированный буфер в функции

C28750

предупреждение C28750: запрещено использование lstrlen и его вариантов

C28751

предупреждение C28751: запрещено использование ExAllocatePool и его вариантов

C28752

предупреждение C28752: запрещено использование API ядра32 или advapi32

C28753

предупреждение C28753: использование неопределенного порядка оценки параметров

C30029

предупреждение C30029: вызов функции выделения памяти, которая запрашивает исполняемую память.

C30030

предупреждение C30030: вызов функции выделения памяти и передача параметра, указывающего исполняемую память

C30031

предупреждение C30031: вызов функции выделения памяти и передача параметра, указывающего исполняемую память

C30032

предупреждение C30032: вызов функции выделения памяти и принудительное выполнение запроса исполняемой памяти с помощью директивы POOL_NX_OPTOUT

C30033

предупреждение C30033: выделение исполняемых файлов обнаружено в драйвере, скомпилированном с POOL_NX_OPTIN. Этот драйвер был определен для загрузки во время выполнения другим драйвером. Убедитесь, что драйвер загрузки вызывает ExInitializeDriverRuntime(DrvRtPoolNxOptIn) в driverEntry.

C30034

предупреждение C30034: передача значения флага в функцию выделения, которая может привести к выделению исполняемой памяти. Убедитесь, что функция выделения не запрашивает форму исполняемого пула, отличного от буфера.

C30035

предупреждение C30035: вызов был выполнен в функцию, которая должна выполняться внутри функции инициализации (например, DriverEntry() или DllInitialize()). PREfast не удалось определить, был ли вызов выполнен из функции инициализации.