デバイスの電源投入 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 を処理するとき、ドライバーは、IRP が完了し、デバイスの電源がオンになった後、IoCompletion ルーチンを設定して、コンテキストの復元、取り出しロックの解放、その他の必要なタスクの実行を行う必要があります。 ドライバーは、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 をキューに入れた場合、またはデバイスに突入電力が必要な場合、バス ドライバーはデバイスに電力を供給します。 それ以外の場合、バス ドライバーは、デバイスと通信する必要が生じるとすぐに電源を適用します。
電源オフ、スタンバイ、休止状態からの起動時間を短縮するためのベスト プラクティスの一覧については、「システム起動パフォーマンスの向上」をご覧ください。