處理裝置電源原則擁有者中的系統Query-Power IRP

當裝置電源原則擁有者收到系統電源狀態 的IRP_MN_QUERY_POWER 時,它會藉由傳遞查詢來回應,並在 IoCompletion 常式中傳送裝置電源狀態 的IRP_MN_QUERY_POWER 。 當堆疊中的所有驅動程式都完成裝置查詢時,裝置電源原則擁有者就會完成系統查詢。

裝置電源原則擁有者應該在其 DispatchPower 常式 中採取下列步驟來回應系統查詢:

  1. 呼叫 IoAcquireRemoveLock,傳遞目前的 IRP,以確保驅動程式在處理電源 IRP 時不會收到 PnP IRP_MN_REMOVE_DEVICE 要求。

    如果 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. 呼叫 IoCopyCurrentIrpStackLocationToNext,以設定下一個較低驅動程式的 IRP 堆疊位置。

  5. 在系統查詢電源 IRP 中設定 IoCompletion 常式。

  6. 在 Windows Server 2003、Windows XP 和 Windows 2000) 中呼叫IoC (allDriver) (,將 IRP 傳遞至下一個較低的驅動程式。

  7. 傳回STATUS_PENDING。

IoCompletion常式應該執行下列動作:

  1. 請檢查 Irp-IoStatus.Status > ,以確保較低的驅動程式已成功完成 IRP。 如果較低驅動程式已指定非成功的 NTSTATUS 值, IoCompletion 常式應該會傳回 NTSTATUS 值。

  2. 如果較低的驅動程式已成功完成 IRP,請呼叫 PoRequestPowerIrp 以傳送裝置查詢電源 IRP,以取得適用于查詢系統電源狀態的裝置電源狀態。 如有必要,請參閱 DEVICE_CAPABILITIES 結構中的DEVICE_STATE陣列,以判斷哪些裝置電源狀態對查詢的系統電源狀態有效。

  3. 呼叫 PoRequestPowerIrp時指定回呼常式 (CompletionFunction參數) ,並在內容區域中傳遞系統 IRP。

  4. 傳回STATUS_MORE_PROCESSING_REQUIRED,讓驅動程式可以在回呼常式中完成系統查詢 IRP 的處理。

在 IRP 完成且 IRP 處理期間設定的所有 IoCompletion 常式都已執行之後,電源管理員會透過 I/O 管理員呼叫電源原則管理員的回呼常式, (CompletionFunction 參數至 PoRequestPowerIrp) 。 回呼常式接著必須執行下列動作:

  1. 呼叫 PoStartNextPowerIrp 以啟動下一個電源 IRP。 (Windows Server 2003、Windows XP 和 Windows 2000 only.)

  2. 完成系統查詢電源 IRP (呼叫 IoCompleteRequest) ,並傳回裝置查詢電源 IRP 的狀態。

  3. 呼叫 IoReleaseRemoveLock 以釋放先前取得的鎖定。

請記住,裝置電源原則擁有者不僅會傳送裝置查詢,也必須在裝置堆疊下處理它。 如需詳細資訊,請參閱 處理裝置電源狀態的IRP_MN_QUERY_POWER