下のデバイス スタックへの PnP IRP の受け渡し

PnP マネージャーは IRP を使用して、デバイスを起動、停止、削除すること、およびドライバーのデバイスに関してドライバーにクエリを実行することをドライバーに指示します。 すべての PnP IRP には主要な関数コード IRP_MJ_PNP があるので、すべての PnP ドライバーは、この関数コードを扱う DispatchPnP ルーチンを提供する必要があります。 PnP マネージャーは、IRP を送信するときに Irp->IoStatus.Status を STATUS_NOT_SUPPORTEDに初期化します。 詳細については「DispatchPnP ルーチン」を参照してください。

PnP マイナー IRP の一覧については「プラグ アンド プレイのマイナー IRP」を参照してください。

デバイスのすべてのドライバーには、スタックでドライバーが IRP の処理に失敗しない限り、PnP IRP に応答する機会を用意する必要があります (次の図を参照してください)。

diagram illustrating passing a plug and play irp down the device stack.

デバイスのドライバーのうち、PnP IRP に応答するドライバーが 1 つのみであると想定することはできません。 たとえば、IRP_MN_QUERY_CAPABILITIES 要求に応答して、次の下位ドライバーに渡すことなく IRP を完了するファンクション ドライバーがあるとします。 この場合は、下位ドライバーでサポートされている機能が報告されません。このような機能として、親バス ドライバーでサポートされている一意のインスタンス ID や電源管理機能などがあります。

親バス ドライバーが IoCompleteRequest を呼び出し、I/O マネージャーがファンクション ドライバーまたはフィルター ドライバーによって登録されている IoCompletion ルーチンを呼び出すと、PnP IRP はデバイス スタックを上位方向へ戻ります。

ファンクション ドライバーやフィルター ドライバーは、PnP IRP を受信したときに次の処理を実行する必要があります。

  • ドライバーが IRP に応答してアクションを実行する場合:
    1. 適切なアクションを実行します。
    2. Irp->IoStatus.Status を、STATUS_SUCCESS などの適切な状態に設定します。 Irp->IoStatus.Information を、IRP に適切であれば設定します。
    3. IoSkipCurrentIrpStackLocation または IoCopyCurrentIrpStackLocationToNext を使用して、次のスタックの場所を設定します。 IoCompletion ルーチンを設定している場合は後者のルーチンを呼び出します。
    4. 必要に応じて IoCompletion ルーチンを設定します。
    5. IRP を完了しないでください (IoCompleteRequest を呼び出さないようにします)。IRP は親バス ドライバーによって完了します。
  • この IRP に対してドライバーがアクションを実行しない場合、そのドライバーは次のドライバーに IRP を渡す準備します。
    1. IoSkipCurrentIrpStackLocation を呼び出して、ドライバーのスタックの場所を IRP から削除します。
    2. Irp->IoStatus ではどのフィールドも設定しないでください。
    3. IoCompletion ルーチンを設定しないでください。
    4. IRP を完了しないでください (IoCompleteRequest を呼び出さないようにします)。IRP は親バス ドライバーによって完了します。

ファンクション ドライバーまたはフィルター ドライバーが IRP の処理に失敗しなかった場合、そのドライバーは IoCallDriver を使用して次の下位ドライバーに IRP を渡します。 ドライバーには次の下位ドライバーへのポインターがあります。そのポインターは、上位ドライバーの AddDevice ルーチンで IoAttachDeviceToDeviceStack を呼び出すことによって返されます。

親バス ドライバーは、IRP に応答するあらゆるタスクを実行した後で IRP を完了します。 バス ドライバーが IoCompleteRequest を呼び出した後、I/O マネージャーは、デバイスのファンクション ドライバーまたはフィルター ドライバーによって登録されたすべての IoCompletion ルーチンを呼び出します。