Программирование драйверов Windows

Процедуры отложенного вызова обслуживания прерываний DpcForIsr


Вызов процедуры DpcForIsr может быть запланирован из собственно ISR процедуры вызовом IoRequestDpc. Прототип этой функции драйвера описан в таблице 8.13.

Таблица 8.13. Прототип функции для процедуры DpcForIsr



VOID DpcForIsr IRQL == DISPATCH_LEVEL
Параметры Завершает обработку прерывания, начатую в ISR процедуре драйвера
IN PKDPC pDpc DPC-объект
IN PDEVICE_OBJECT pDevObj Указатель на объект устройства, для которого зарегистрирована данная DPC процедура
IN PIRP pIrp Интересующий пакет IRP
IN VOID pContext Контекстный указатель, переданный вызовом IoRequestDpc
Возвращаемое значение void

При анализе прототипа вызова IoRequestDpc и примера кода перед таблицей 8.13, возникает правомерный вопрос: вызов какой функции планирует ISR процедура, выполняя вызов IoRequestDpc? Ведь DpcForIsr функция не фигурирует ни при регистрации ISR процедуры вызовом IoConnectInterrupt, ни в тексте OnInterrupt.

Ответ состоит в том, что DpcForIsr регистрируется для конкретного объекта устройства вызовом IoInitializeDpcRequest (см. таблицу 8.14). Если обратить внимание на структуру DEVICE_OBJECT, описанную в заголовочных файлах wdm.h и ntddk.h (см. пакет DDK), то несложно заметить поле 'KDPC Dpc', предназначенное как раз для хранения DPC объекта. Соответственно, выполняя вызов IoRequestDpc

c указателем на объект устройства в качестве первого аргумента, ISR процедура драйвера однозначно определяет, какая именно DpcForIsr функция будет вызвана позже &#8212 хранящаяся в объекте устройства.

Таблица 8.14. Прототип вызова IoInitializeDpcRequest

VOID IoInitializeDpcRequest IRQL == PASSIVE_LEVEL
Параметры Регистрирует DpcForIsr процедуру для данного объекта устройства, создает и инициализирует DPC объект
IN PDEVICE_OBJECT pDevObj Указатель на объект устройства, для которого регистрируется данная DPC процедура
IN VOID (*DpcForIsr) Адрес DpcForIsr процедуры, которая должна иметь прототип, описанный в таблице 8.13
Возвращаемое значение void

Регистрацию DpcForIsr процедуры (и ее связывание с объектом устройства) для PnP драйверов рекомендуется делать в процедуре AddDevice драйвера.

Первый параметр pDpc в описании прототипа процедуры DpcForIsr (таблица 8.13) не должен пугать разработчика. Если используется вызов IoInitializeDpcRequest, то именно он создает данный объект, а в вызов DpcForIsr поступит указатель на уже готовый DPC объект.



Содержание раздела