Объявление функций с помощью типов ролей функций для драйверов WDM
Примечание.
Начиная с Windows 10 версии 2004, средство проверки статических драйверов (SDV) больше не требует заметок для определения типов подпрограмм отправки для драйверов WDM. Следуйте инструкциям в разделе "Базовые и расширенные инициализации" этой страницы .
Чтобы сообщить SDV о точках входа драйвера при анализе драйвера WDM, необходимо объявить функции с помощью объявлений типов ролей функции. Типы ролей функции определяются в Wdm.h. Каждая точка входа в подпрограмме DriverEntry в драйвере WDM должна быть объявлена путем указания соответствующего типа роли. Типы ролей представляют собой стандартные типдефы, соответствующие распознаваемым точкам входа в драйвере WDM.
Например, чтобы создать объявление типа роли функции для подпрограммы выгрузки драйвера с именем CsampUnload, используйте предопределенное объявление типа типа DRIVER_UNLOAD роли. Объявление типа роли функции должно отображаться перед определением функции.
DRIVER_UNLOAD CsampUnload;
Определение функции CsampUnload остается неизменным:
VOID
CsampUnload(
IN PDRIVER_OBJECT DriverObject
)
{
...
}
SDV распознает типы точек входа, показанных в следующей таблице.
Тип роли функции WDM | Подпрограмма WDM |
---|---|
DRIVER_INITIALIZE |
|
DRIVER_STARTIO |
|
DRIVER_UNLOAD |
|
DRIVER_ADD_DEVICE |
|
DRIVER_DISPATCH Dispatch_type( тип ) | Подпрограммы диспетчера, используемые драйвером. См. статью "Написание подпрограмм отправки". |
IO_COMPLETION_ROUTINE |
Подпрограмма IoCompletion устанавливается путем вызова IoSetCompletionRoutine или IoSetCompletionRoutineEx и передачи указателя функции в подпрограмму IoCompletion в качестве второго параметра. |
DRIVER_CANCEL |
Подпрограмма отмены задается путем вызова IoSetCancelRoutine и передачи указателя функции в подпрограмму отмены для IRP в качестве второго параметра функции. |
IO_DPC_ROUTINE |
Подпрограмма DpcForIsr регистрируется путем вызова IoInitializeDpcRequest и передачи указателя функции в подпрограмму DpcForIsr в качестве второго параметра. Чтобы очередь DPC, вызовите IoQueueDpc из подпрограммы ISR с помощью того же объекта DPC. |
KDEFERRED_ROUTINE |
Подпрограмма CustomDpc задается путем вызова KeInitializeDpc и передачи указателя функции в CustomDpc в качестве второго параметра. Чтобы очередь CustomDpc для драйвера, вызовите KeInsertQueueDpc из подпрограммы ISR с помощью одного объекта DPC. |
KSERVICE_ROUTINE |
Подпрограмма InterruptService (ISR) обслуживает прерывание устройства и при необходимости планирует обработку полученных данных после прерывания. |
REQUEST_POWER_COMPLETE |
Подпрограмма обратного вызова PowerCompletion завершает обработку power IRP. Если драйверу необходимо выполнить дополнительные задачи после завершения IRP всех других драйверов, драйвер регистрирует подпрограмму обратного вызова PowerCompletion во время вызова подпрограммы PoRequestPowerIrp , которая выделяет IRP. |
WORKER_THREAD_ROUTINE |
Рутина Подпрограмма — это подпрограмма обратного вызова, указанная во втором параметре функции ExInitializeWorkItem . Подпрограмма должна объявляться таким образом, только если драйвер вызывает ExQueueWorkItem, чтобы добавить рабочий элемент в системную очередь. |
Объявление подпрограмм диспетчеризации драйверов
Начиная с Windows 10 версии 2004 объявления типов ролей функции для подпрограмм отправки автоматически уточняются с их категорией IRP на основе инициализации таблицы DriverObject-MajorFunction> в подпрограмме DriverEntry драйвера WDM.
Драйвер Foo должен выполнять объявления ролей с помощью базового или расширенного стиля объявления, чтобы соответствовать SDV.
Базовые и расширенные инициализации
Базовый стиль можно увидеть в приведенном ниже примере (обратите внимание, что имена подпрограмм диспетчера FooCreate и FooCleanup являются лишь примерами, можно использовать любое соответствующее имя):
DriverObject->MajorFunction[IRP_MJ_CREATE] = FooCreate; //Basic style
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FooCleanup;
Более сложный подход можно использовать для сокращения необходимого списка. Хотя одна и та же подпрограмма отправки используется для нескольких категорий IRP, драйвер может кодировать два инициализации таким образом:
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FooCreateCleanup; // Advanced style for a multi-role dispatch routine
Чтобы драйвер мог правильно запускать SDV, драйвер должен использовать только базовый или расширенный стиль, показанный выше. Проверка SDV на драйвере не будет работать должным образом , если один из этих двух методов не используется.
Параметры функции и типы ролей функций
По мере необходимости в языке программирования C типы параметров, используемые в определении функции, должны соответствовать типам параметров прототипа функции или в данном случае типу роли функции. SDV зависит от подписей функции для анализа и игнорирует функции, подписи которых не совпадают.
Например, следует объявить подпрограмму IoCompletion с помощью типа роли функции IO_COMPLETION_ROUTINE:
IO_COMPLETION_ROUTINE myCompletionRoutine;
При реализации myCompletionRoutine типы параметров должны соответствовать типам, используемым IO_COMPLETION_ROUTINE, а именно, PDEVICE_OBJECT, ПИРП и PVOID (см. подпрограмму IoCompletion для синтаксиса).
NTSTATUS
myCompletionRoutine(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
}
Выполнение анализа кода для драйверов для проверки объявлений функций
Чтобы определить, подготовлен ли исходный код, запустите анализ кода для драйверов. Анализ кода для драйверов проверяет объявления типов ролей функции и может помочь определить объявления функций, которые могли быть пропущены или предупреждать вас, если параметры определения функции не соответствуют значениям в типе роли функции.