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


Отправка IRP устройства Set-Power в ответ на системную Set-Power IRP

Владелец политики управления питанием устройства должен выполнить следующие действия, чтобы реагировать на IRP, настроенную системой:

  1. Вызовите 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, а затем вернуть состояние сбоя.

  2. Настройте расположение стека IRP для следующего ниже драйвера, вызвав IoCopyCurrentIrpStackLocationToNext.

  3. Задайте подпрограмму IoCompletion в системном IRP set-power.

  4. Вызовите IoMarkIrpPending , чтобы пометить системный IRP set-power как ожидающий.

  5. Вызовите IoCallDriver (начиная с Windows Vista) или PoCallDriver (в Windows Server 2003, Windows XP и Windows 2000), чтобы передать IRP с установленной мощностью системы драйверу следующего уровня.

  6. Возврат STATUS_PENDING из подпрограммы DispatchPower .

В процедуре IoCompletion (см. шаг 3 в предыдущем списке) владелец политики питания устройства отправляет IRP с набором питания устройства следующим образом:

  1. Проверьте IRP набора питания системы, чтобы получить запрошенное состояние питания системы. Выберите соответствующее состояние питания устройства для этого состояния питания системы. Дополнительные сведения см. в разделе Определение правильного состояния питания устройства.

  2. Вызовите PoRequestPowerIrp , чтобы отправить IRP_MN_SET_POWER для состояния питания устройства, определенного на шаге 1. Владелец политики управления питанием должен отправить запрос на настройку питания устройства, даже если устройство уже находится в этом состоянии.

  3. Укажите подпрограмму обратного вызова завершения питания (CompletionFunction) в вызове PoRequestPowerIrp и передайте системный IRP set-power в буфер контекста .

  4. Верните STATUS_MORE_PROCESSING_REQUIRED из процедуры IoCompletion , чтобы драйвер смог завершить обработку IRP для установки питания системы в подпрограмме обратного вызова с завершением питания.

Помните, что владелец политики управления питанием устройства не только отправляет IRP установленной мощности устройства, но и должен обрабатывать этот IRP при прохождении через стек устройств. Следовательно, владелец политики управления питанием устройства может иметь не только подпрограмму обратного вызова с завершением питания, связанную с IRP set-power, и процедуру IoCompletion для IRP с набором питания системы, но и процедуру IoCompletion для IRP набора устройств. Дополнительные сведения см. в разделе Обработка IRP_MN_SET_POWER для состояний питания устройства.

После того как диспетчер ввода-вывода вызывает все подпрограммы IoCompletion , которые были заданы при перемещении IRP с набором питания устройства вниз по стеку устройств, диспетчер операций ввода-вывода вызывает процедуру обратного вызова завершения питания. К этому времени все драйверы в стеке завершили IRP с набором питания устройства и переход на питание устройства завершен.

Подпрограмма обратного вызова с завершением питания должна выполнять следующие действия.

  1. Вызовите PoStartNextPowerIrp , чтобы запустить следующий IRP питания. (Только Windows Server 2003, Windows XP и Windows 2000.)

  2. Завершите системный IRP set-power (IoCompleteRequest) с возвращенным состоянием для устройства set-power IRP.

  3. Вызовите IoReleaseRemoveLock , чтобы освободить ранее полученную блокировку.

  4. Возвращает состояние, с которым завершено выполнение irps set-power.