デバイスの電源投入 IRP の処理

デバイスの電源投入 IRP は 、IRP_MN_SET_POWER と、現在のデバイスの電源状態よりも多くの電力を必要とするデバイスの電源状態を指定します。 通常、電源投入 IRP は、デバイスの動作状態 PowerDeviceD0 を指定します。

デバイスの電源をオンにする要求は、最初にデバイスの基になるバス ドライバーによって処理され、次にスタックをバックアップする後続の各ドライバーによって処理される必要があります。

次の図は、電源投入 IRP の処理に関連する手順を示しています。

デバイスの電源投入要求の処理を示す図。

電源投入の IRP_MN_SET_POWER 要求を処理する場合、関数またはフィルター ドライバーは次の操作を行う必要があります。

  • IoAcquireRemoveLock を呼び出して、ドライバーが電源投入 IRP の処理中にIRP_MN_REMOVE_DEVICE要求を受け取らないようにします。

    IoAcquireRemoveLock がエラー状態を返す場合、ドライバーは IRP の処理を続行しないでください。 代わりに、Windows Vista 以降では、ドライバーは IoCompleteRequest を呼び出して IRP を完了し、エラー状態を返す必要があります。 Windows Server 2003、Windows XP、および Windows 2000 では、ドライバーは IoCompleteRequest を呼び出して IRP を完了し、 PoStartNextPowerIrp を呼び出して次の電源 IRP を起動し、エラー状態を返す必要があります。

  • IoMarkIrpPending を呼び出して、IRP の保留中をマークします。

  • IoCopyCurrentIrpStackLocationToNext を呼び出して、IRP スタックの場所を設定します。 ドライバーは、IoCompletion ルーチンを設定する場合、IoSkipCurrentIrpStackLocation を呼び出す必要があります。

  • IoSetCompletionRoutine を呼び出して、パワーアップ IoCompletion ルーチンを設定します。

    デバイスの電源投入 IRP を処理する場合、ドライバーは、コンテキストを復元する IoCompletion ルーチンを設定する必要があります、ロックの削除を解放し、IRP が完了し、デバイスの電源をオンにした後、その他の必要なタスクを実行します。 ドライバーは、IRP が完了する前にコンテキストを復元しないでください。 詳細については、「 デバイス電源 IRP の IoCompletion ルーチン」を参照してください

  • IoCallDriver (Windows 7 および Windows Vista の場合) または PoCallDriver (Windows Server 2003、Windows XP、Windows 2000) を呼び出して、IRP を次の下位ドライバーに渡します。 IRP は、デバイス スタックからバス ドライバーまで移動する必要があります。 バス ドライバーのみが IRP を完了できます。

  • STATUS_PENDINGを返します。

バス ドライバーは、IRP を受け取るときに、デバイスがまだ存在し、スリープ中に削除または交換されていないことを確認するために最初にチェックする必要があります。 デバイスが存在しなくなった場合、バス ドライバーは親デバイスの IoInvalidateDeviceRelations を呼び出して、デバイスが消えたことをプラグ アンド プレイ マネージャーに通知する必要があります。 この状況では、バス ドライバーは、デバイスの電源投入 IRP に失敗する可能性があります。

デバイスがまだ存在する場合、バス ドライバーは、デバイスを動作状態に戻すために必要なタスクを実行し、 PoSetPowerState を呼び出して、新しいデバイスの電源状態を電源マネージャーに通知し、IRP (IoCompleteRequest) を完了します。 デバイスのスリープ中にドライバーが I/O をキューに入れた場合、またはデバイスに突入電力が必要な場合、バス ドライバーはデバイスに電源を適用します。 それ以外の場合、バス ドライバーは、デバイスとの通信が必要になるとすぐに電源を適用します。

電源オフ、スタンバイ、休止状態から起動時間を短縮するためのベスト プラクティスの一覧については、「 システムスタートアップパフォーマンスの向上」を参照してください。