處理裝置Power-Down IRP

裝置關閉電源 IRP 會指定IRP_MN_SET_POWER和裝置電源狀態 (PowerDeviceD0PowerDeviceD1、PowerDeviceD2PowerDeviceD3) 小於電源或等於目前裝置電源狀態的次要函式程式碼。 驅動程式必須處理關閉電源 IRP,因為 IRP 會向下移動裝置堆疊。 較高層級的驅動程式必須在較低層級的驅動程式之前處理 IRP。 沒有裝置特定工作的驅動程式應該會立即將 IRP 傳遞至下一個較低的驅動程式。

下圖顯示處理這類 IRP 時所涉及的步驟。

說明處理裝置關閉電源要求的圖表。

如果 IRP 指定 PowerDeviceD3,函式驅動程式通常會執行下列工作:

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

    如果 IoAcquireRemoveLock 傳回失敗狀態,驅動程式不應該繼續處理 IRP。 相反地,從 Windows Vista 開始,驅動程式應該呼叫 IoCompleteRequest 來完成 IRP,然後傳回失敗狀態。 在 Windows Server 2003、Windows XP 和 Windows 2000 中,驅動程式應該呼叫 IoCompleteRequest 來完成 IRP,然後呼叫 PoStartNextPowerIrp 來啟動下一個電源 IRP,然後傳回失敗狀態。

  • 執行在移除裝置電源之前必須完成的任何裝置特定工作,例如關閉裝置、完成或排清任何擱置的 I/O、停用中斷、 佇列後續傳入 IRP,以及儲存要從中還原或重新初始化裝置的裝置內容。

    例如,驅動程式不應該造成長時間的延遲 (,使用者在處理 IRP 時,這類裝置) 可能找不到不合理的延遲。

    驅動程式應該將任何傳入的 I/O 要求排入佇列,直到裝置回到工作狀態為止。

  • 可能檢查 Parameters.Power.ShutdownType的值。 如果系統設定電源 IRP 為作用中, ShutdownType 會提供系統 IRP 的相關資訊。 如需此值的詳細資訊,請參閱 系統 Power Actions

    休眠路徑上的裝置驅動程式必須檢查此值。 如果 ShutdownTypePowerActionHibernate,驅動程式應該儲存還原裝置所需的任何內容,但不應該關閉裝置電源。

  • 如果驅動程式能夠這麼做,以及是否適合變更,請變更裝置的實體電源狀態。

  • 呼叫 PoSetPowerState 以通知電源管理員新的裝置電源狀態。

  • 呼叫 IoCopyCurrentIrpStackLocationToNext 以設定下一個較低驅動程式的堆疊位置。

  • 設定呼叫PoStartNextPowerIrpIoCompletion常式,指出驅動程式已準備好處理下一個電源 IRP。 Windows 7 和 Windows Vista 中不需要此步驟。

  • 在 Windows 7 和 Windows Vista) 中呼叫 IoCallDriver (,或在 Windows Server 2003、Windows XP 和 Windows 2000) 中呼叫 PoCallDriver (,以將 IRP 傳遞至下一個較低的驅動程式。 IRP 必須一路傳遞至匯流排驅動程式,以完成 IRP。

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

  • 傳回STATUS_PENDING。

驅動程式必須儲存任何裝置內容資訊,並在轉送 IRP 之前設定新的電源狀態。 內容資訊至少應包含要求的新電源狀態。 它也應該包含驅動程式在啟動電源時所需的任何其他資訊。 完成 IRP 且裝置已關閉電源之後,驅動程式就無法再存取裝置,且無法使用裝置內容。

每個驅動程式都必須將 IRP 傳遞至下一個較低的驅動程式。 當 IRP 到達匯流排驅動程式時,如果裝置能夠) (,則匯流排驅動程式會關閉裝置,並呼叫 PoSetPowerState 來通知電源管理員,並完成 IRP。

不過,如果匯流排驅動程式服務休眠裝置,它應該檢查 IRP 中 ShutdownType 的值是否為 PowerSystemHibernate。 如果是這樣,匯流排驅動程式應該呼叫 PoSetPowerState 來報告 PowerDeviceD3,但不應該關閉裝置電源。 裝置會在儲存休眠檔案後關閉電源,以及系統的其餘部分。

在其所有子裝置關閉電源之後,匯流排驅動程式可能也會選擇關閉其匯流排。 這類行為與裝置相關。

如果 IRP 指定任何其他狀態 (D0、D1 或 D2) ,則必要的驅動程式動作與裝置相關。 一般而言,支援這些狀態的裝置可以在 I/O 要求送達時快速返回工作狀態。 這類裝置的驅動程式必須完成任何擱置的 I/O 要求、將任何新要求排入佇列,並儲存所有必要的內容,再將 IRP 轉送至下一個較低的驅動程式。 當 IRP 到達匯流排驅動程式時,它會設定處於要求狀態的硬體。 驅動程式在睡眠時無法存取裝置。

在某些情況下,當裝置已處於 D0 狀態時,函式或篩選驅動程式可能會收到指定 PowerDeviceD0 的裝置電源 IRP。 驅動程式應該處理此 IRP,就像任何其他設定電源 IRP 一樣:完成擱置的 I/O 要求、佇列傳入 I/O 要求、設定 IoCompletion 常式,並將 IRP 向下傳遞至下一個較低的驅動程式。 不過,驅動程式不得變更裝置的硬體設定。 當公車驅動程式收到 IRP 時,它應該只會完成 IRP。 當 IRP 完成時,函式和篩選驅動程式可以處理任何已排入佇列的要求。 將 I/O 排入佇列,直到 IRP 完成為止,可避免驅動程式嘗試變更裝置暫存器的可能性,而較高的驅動程式嘗試 I/O。