Обработка системного Query-Power IRP у владельца политики управления питанием устройства

Когда владелец политики управления питанием устройства получает IRP_MN_QUERY_POWER состояния питания системы, он отвечает, передавая запрос и в подпрограмме IoCompletion , отправляя IRP_MN_QUERY_POWER для состояния питания устройства. Когда все драйверы в стеке завершили запрос устройства, владелец политики питания устройства завершает системный запрос.

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

  1. Вызовите IoAcquireRemoveLock, передав текущую IRP, чтобы убедиться, что драйвер не получит запрос IRP_MN_REMOVE_DEVICE PnP при обработке IRP питания.

    Если IoAcquireRemoveLock возвращает состояние сбоя, драйвер не должен продолжать обработку IRP. Вместо этого, начиная с Windows Vista, драйвер должен вызвать IoCompleteRequest , чтобы завершить IRP и вернуть состояние сбоя. В Windows Server 2003, Windows XP и Windows 2000 драйвер должен вызвать PoStartNextPowerIrp, вызвать IoCompleteRequest для завершения IRP и вернуть состояние сбоя.

  2. Убедитесь, что драйвер может поддерживать запрошенное состояние питания системы, как описано в разделе Сбой системного Query-Power IRP в фильтре или драйвере функции. В противном случае завершите IRP с состоянием сбоя, как описано в этом разделе.

    Однако драйвер не должен завершать запрос S4 (PowerSystemHibernate), если его устройство включено для пробуждения, но оно не может выпустить систему из состояния гибернации. В этом случае владелец политики питания для драйвера (который отправил IRP_MN_WAIT_WAKE) должен отменить IRP ожидания и пробуждения и выполнить системный запрос. Дополнительные сведения см. в разделе Отмена IRP ожидания и пробуждения.

  3. Если драйвер может поддерживать запрошенное состояние питания системы, вызовите IoMarkIrpPending.

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

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

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

  7. Возврат STATUS_PENDING.

Подпрограмма IoCompletion должна выполнять следующие действия:

  1. Проверьте Irp-IoStatus.Status>, чтобы убедиться, что более низкие драйверы успешно завершили IRP. Если драйвер более низкого уровня указал значение NTSTATUS, то подпрограмма IoCompletion должна вернуть значение NTSTATUS.

  2. Если более низкие драйверы успешно завершили IRP, вызовите PoRequestPowerIrp , чтобы отправить IRP-запрос устройства для состояния питания устройства, допустимого для запрашиваемого состояния питания системы. При необходимости обратитесь к массиву DEVICE_STATE в структуре DEVICE_CAPABILITIES , чтобы определить, какие состояния питания устройства допустимы для запрашиваемого состояния питания системы.

  3. Укажите подпрограмму обратного вызова (параметр CompletionFunction ) в вызове PoRequestPowerIrp и передайте системный IRP в области Контекст .

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

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

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

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

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

Помните, что владелец политики управления питанием устройства не только отправляет запрос устройства, но и должен обрабатывать его на пути вниз по стеку устройств. Дополнительные сведения см. в разделе Обработка IRP_MN_QUERY_POWER для состояний питания устройства.