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


Новые рабочие процедуры в WDM драйверах - часть 4


/p>

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

(подробности &#8212 ниже) с уровня IRQL равного PASSIVE_LEVEL, то процедура завершения находящегося выше драйвера выполняется на уровне PASSIVE_LEVEL. В случае, если лежащий ниже драйвер завершает обработку IRP пакета на уровне DIPATCH_LEVEL (например, из DPC процедуры), то и процедура завершения лежащего выше драйвера выполняется на уровне DISPATCH_LEVEL.

Выполнение программного кода на уровне DISPATCH_LEVEL ограничивается системными вызовами, которые работают на этом уровне IRQL. Разумеется, следует особо позаботиться, чтобы здесь не производилась работа со страничной памятью.

Таблица 9.10. Прототип функции IoCompleteRequest

VOID IoCompleteRequest IRQL &#60= DISPATCH_LEVEL
Параметры Вызывается, когда драйвер желает полностью завершить обработку данного IRP пакета. Обеспечивает вызов процедур завершения всех драйверов, имеющихся над данным (см. ниже)
IN PIRP pIrp Указатель на текущий IRP пакет, обработка которого только что завершена
IN CCHAR PriorBoost Величина, на которую следует изменить приоритет потока, выполняющего обработку данного IRP пакета. Величина IO_NO_INCREMENT используется, если никаких изменений делать не нужно.
Возвращаемое значение void

Чтобы устранить упомянутую выше неоднозначность уровня IRQL работы процедуры завершения, можно прибегнуть к следующей уловке. Предположим, что мы имеем программный код рабочей процедуры. Известно также, что PnP Менеджер (как, впрочем, и Диспетчер ввода/вывода) всегда выполняет вызов рабочей процедуры драйвера на уровне PASSIVE_LEVEL. Тогда, отправляя пакет IRP нижним слоям драйвера, организуем ожидание (средствами объекта события режима ядра) не выходя из кода данной рабочей процедуры, пока отосланный нижним слоям IRP пакет не возвратится в зарегистрированную функцию CompletionRoutine. Как только это произойдет, объект события кодом функции CompletionRoutine будет переведен в сигнальное состояние, и стадия ожидания в основном потоке завершится.


Начало  Назад  Вперед