Отправка IRP устройства Set-Power в ответ на системную Set-Power IRP
Владелец политики управления питанием устройства должен выполнить следующие действия, чтобы реагировать на IRP, настроенную системой:
Вызовите IoAcquireRemoveLock, передав текущую IRP в качестве параметра Tag, чтобы убедиться, что драйвер не получит запрос Plug and Play IRP_MN_REMOVE_DEVICE при обработке IRP питания.
Если IoAcquireRemoveLock возвращает состояние сбоя, драйвер не должен продолжать обработку IRP. Вместо этого, начиная с Windows Vista, драйвер должен вызвать IoCompleteRequest , чтобы завершить запрос, а затем вернуть состояние сбоя. В Windows Server 2003, Windows XP и Windows 2000 драйвер должен сначала вызвать PoStartNextPowerIrp, вызвать IoCompleteRequest для завершения IRP, а затем вернуть состояние сбоя.
Настройте расположение стека IRP для следующего ниже драйвера, вызвав IoCopyCurrentIrpStackLocationToNext.
Задайте подпрограмму IoCompletion в системном IRP set-power.
Вызовите IoMarkIrpPending , чтобы пометить системный IRP set-power как ожидающий.
Вызовите IoCallDriver (начиная с Windows Vista) или PoCallDriver (в Windows Server 2003, Windows XP и Windows 2000), чтобы передать IRP с установленной мощностью системы драйверу следующего уровня.
Возврат STATUS_PENDING из подпрограммы DispatchPower .
В процедуре IoCompletion (см. шаг 3 в предыдущем списке) владелец политики питания устройства отправляет IRP с набором питания устройства следующим образом:
Проверьте IRP набора питания системы, чтобы получить запрошенное состояние питания системы. Выберите соответствующее состояние питания устройства для этого состояния питания системы. Дополнительные сведения см. в разделе Определение правильного состояния питания устройства.
Вызовите PoRequestPowerIrp , чтобы отправить IRP_MN_SET_POWER для состояния питания устройства, определенного на шаге 1. Владелец политики управления питанием должен отправить запрос на настройку питания устройства, даже если устройство уже находится в этом состоянии.
Укажите подпрограмму обратного вызова завершения питания (CompletionFunction) в вызове PoRequestPowerIrp и передайте системный IRP set-power в буфер контекста .
Верните STATUS_MORE_PROCESSING_REQUIRED из процедуры IoCompletion , чтобы драйвер смог завершить обработку IRP для установки питания системы в подпрограмме обратного вызова с завершением питания.
Помните, что владелец политики управления питанием устройства не только отправляет IRP установленной мощности устройства, но и должен обрабатывать этот IRP при прохождении через стек устройств. Следовательно, владелец политики управления питанием устройства может иметь не только подпрограмму обратного вызова с завершением питания, связанную с IRP set-power, и процедуру IoCompletion для IRP с набором питания системы, но и процедуру IoCompletion для IRP набора устройств. Дополнительные сведения см. в разделе Обработка IRP_MN_SET_POWER для состояний питания устройства.
После того как диспетчер ввода-вывода вызывает все подпрограммы IoCompletion , которые были заданы при перемещении IRP с набором питания устройства вниз по стеку устройств, диспетчер операций ввода-вывода вызывает процедуру обратного вызова завершения питания. К этому времени все драйверы в стеке завершили IRP с набором питания устройства и переход на питание устройства завершен.
Подпрограмма обратного вызова с завершением питания должна выполнять следующие действия.
Вызовите PoStartNextPowerIrp , чтобы запустить следующий IRP питания. (Только Windows Server 2003, Windows XP и Windows 2000.)
Завершите системный IRP set-power (IoCompleteRequest) с возвращенным состоянием для устройства set-power IRP.
Вызовите IoReleaseRemoveLock , чтобы освободить ранее полученную блокировку.
Возвращает состояние, с которым завершено выполнение irps set-power.