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


Объявление функций с помощью типов ролей функций для драйверов 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

DriverEntry

DRIVER_STARTIO

StartIO

DRIVER_UNLOAD

Разгружать

DRIVER_ADD_DEVICE

AddDevice

DRIVER_DISPATCH Dispatch_type( тип )

Подпрограммы диспетчера, используемые драйвером. См. статью "Написание подпрограмм отправки".

IO_COMPLETION_ROUTINE

IoCompletion

Подпрограмма IoCompletion устанавливается путем вызова IoSetCompletionRoutine или IoSetCompletionRoutineEx и передачи указателя функции в подпрограмму IoCompletion в качестве второго параметра.

DRIVER_CANCEL

Cancel

Подпрограмма отмены задается путем вызова IoSetCancelRoutine и передачи указателя функции в подпрограмму отмены для IRP в качестве второго параметра функции.

IO_DPC_ROUTINE

DpcForIsr

Подпрограмма DpcForIsr регистрируется путем вызова IoInitializeDpcRequest и передачи указателя функции в подпрограмму DpcForIsr в качестве второго параметра. Чтобы очередь DPC, вызовите IoQueueDpc из подпрограммы ISR с помощью того же объекта DPC.

KDEFERRED_ROUTINE

CustomDpc

Подпрограмма 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
 )
{
}

Выполнение анализа кода для драйверов для проверки объявлений функций

Чтобы определить, подготовлен ли исходный код, запустите анализ кода для драйверов. Анализ кода для драйверов проверяет объявления типов ролей функции и может помочь определить объявления функций, которые могли быть пропущены или предупреждать вас, если параметры определения функции не соответствуют значениям в типе роли функции.