傳送裝置電源狀態的IRP_MN_QUERY_POWER或IRP_MN_SET_POWER
裝置電源原則擁有者會傳送裝置查詢電源 IRP (IRP_MN_QUERY_POWER) ,以判斷較低驅動程式是否可以容納裝置電源狀態的變更,以及裝置設定電源 IRP (IRP_MN_SET_POWER) 來變更裝置電源狀態。 (此驅動程式也可以傳送等候/喚醒 IRP,讓其裝置能夠喚醒,以回應外部訊號;如需詳細資訊 ,請參閱支援具有Wake-Up功能的裝置 。)
當下列任一項成立時,驅動程式應該傳送 IRP_MN_QUERY_POWER 要求:
驅動程式會收到系統查詢能力 IRP。
驅動程式正在準備讓閒置裝置進入睡眠狀態,因此必須查詢較低的驅動程式,以瞭解是否可行。
當下列任一項成立時,驅動程式應該傳送 IRP_MN_SET_POWER 要求:
驅動程式已判斷裝置處於閒置狀態,並可進入睡眠狀態。
裝置處於睡眠狀態,且必須重新進入工作狀態,才能處理等候 I/O。
驅動程式會收到系統設定的 IRP。
驅動程式不得配置自己的電源 IRP;電源管理員會為此目的提供 PoRequestPowerIrp 常式。 如同 處理 Power IRP 的規則 所述, PoRequestPowerIrp 會配置和傳送 IRP,並結合 Windows 7 和 Windows Vista) 中的 IoCallDriver (,或 Windows Server 2003、Windows XP 和 Windows 2000) 中的 PoCallDriver (,確保所有電源要求都已正確同步。 PoRequestPowerIrp的呼叫端必須在 IRQL < = DISPATCH_LEVEL執行。
以下是此常式的原型:
NTSTATUS
PoRequestPowerIrp (
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PREQUEST_POWER_COMPLETE CompletionFunction,
IN PVOID Context,
OUT PIRP *Irp OPTIONAL
);
若要傳送 IRP,驅動程式會呼叫PoRequestPowerIrp,在DeviceObject中指定目標裝置物件的指標、次要 IRP 程式碼IRP_MN_SET_POWER或IRP_MN_QUERY_POWER MinorFunction中的DevicePowerState值。在PowerState中輸入和裝置電源狀態。狀態。 在 Windows 98/Me 中, DeviceObject 必須指定基礎裝置的 PDO;在 Windows 2000 和更新版本的 Windows 中,此值可以指向相同裝置堆疊中驅動程式的 PDO 或 FDO。
如果驅動程式必須在所有其他驅動程式完成 IRP 之後執行其他工作,它應該會在 CompletionFunction中將指標傳遞至電源完成函式。 I/O 管理員會在呼叫驅動程式在將 IRP 傳遞至堆疊之後設定的所有IoCompletion常式之後呼叫CompletionFunction。
每當裝置電源原則擁有者傳送裝置電源查詢 IRP 時,它後續應該從回呼常式傳送裝置設定電源 IRP, (CompletionFunction) 在呼叫 PoRequestPowerIrp 中指定的裝置集電源 IRP。 如果查詢成功,set-power IRP 會指定查詢的電源狀態。 如果查詢失敗,set-power IRP 會重新判斷目前裝置電源狀態。 重新判斷提示目前狀態很重要,因為驅動程式會佇列 I/O 以回應查詢;原則擁有者必須傳送 set-power IRP,以通知其裝置堆疊中的驅動程式開始處理已排入佇列的 I/O 要求。
請記住,裝置的原則擁有者不僅會傳送裝置電源 IRP,也會在裝置堆疊下傳遞時處理 IRP。 因此,這類驅動程式通常會使用IoSetCompletionRoutine (設定 IoCompletionRoutine) 作為其 IRP 處理常式代碼的一部分,特別是當裝置啟動時。 IoCompletion常式會依序呼叫,且 IoCompletion常式是由其他驅動程式設定,並在CompletionFunction之前呼叫。 如需詳細資訊,請參閱 裝置 Power IRP 的 IoCompletion 常式。
由於呼叫 CompletionFunction 時,所有驅動程式都已完成 IRP, 因此 CompletionFunction 不得呼叫 IoCallDriver、 PoCallDriver或 PoStartNextPowerIrp ,並使用其產生的 IRP。 不過, (它可能會針對不同的電源 IRP 呼叫這些常式。) 相反地,此常式會執行產生 IRP 的驅動程式所需的任何其他動作。 如果驅動程式傳送裝置 IRP 以回應系統 IRP, CompletionFunction 可能會完成系統 IRP。 如需詳細資訊,請參閱 在裝置電源原則擁有者中處理系統Set-Power IRP。
為了回應 PoRequestPowerIrp的呼叫,電源管理員會配置電源 IRP,並將它傳送至裝置的裝置堆疊頂端。 電源管理員會傳回已配置之 IRP 的指標。
如果沒有發生錯誤, PoRequestPowerIrp 會傳回STATUS_PENDING。 此狀態表示 IRP 已成功傳送,且擱置完成。 如果電源管理員無法配置 IRP,或呼叫端已指定不正確次要電源 IRP 程式碼,則呼叫會失敗。
啟動裝置的要求必須先由裝置的基礎匯流排驅動程式處理,然後再由堆疊中每個後續較高的驅動程式處理。 因此,傳送 PowerDeviceD0 要求時,驅動程式必須確定其 CompletionFunction 會在 IRP 完成且裝置開啟電源之後執行必要的工作。
關閉裝置電源 (PowerDeviceD3) 時,裝置堆疊中的每個驅動程式都必須儲存其所有必要的內容,並在將 IRP 傳送至下一個較低的驅動程式之前執行任何必要的清除。 內容資訊和清除的範圍取決於驅動程式的類型。 函式驅動程式必須儲存硬體內容;篩選驅動程式可能需要儲存自己的軟體內容。 在此情況下, 完成函式 集可以採取與已完成電源 IRP 相關聯的動作,但驅動程式無法存取裝置。