共用方式為


處理裝置電源政策擁有者中的系統 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. 呼叫 IoCallDriver (在 Windows 7 和 Windows Vista 中)或 PoCallDriver (在 Windows Server 2003、Windows XP 和 Windows 2000 中),將 IRP 傳遞至下一個較低的驅動程式。

  7. 傳回狀態_待處理。

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 管理員呼叫電源原則管理員的回呼例程(PoRequestPowerIrpCompletionFunction 參數)。 回呼例程接著必須執行下列動作:

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

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

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

請記住,裝置電源政策的擁有者不僅需傳送裝置查詢,還必須在其沿裝置堆疊向下的過程中進行處理。 如需詳細資訊,請參閱 IRP_MN_QUERY_POWER 裝置電源狀態的處理方法