ディスパッチ ルーチン内で IRP を完了する方法

入力 IRP をすぐに完了できる場合、ディスパッチ ルーチンは以下の処理を行います。

  1. IRP の I/O ステータス ブロックの Status メンバーと Information メンバーを適切な値で設定します。一般的には次のとおりです。

    • ディスパッチ ルーチンは、Status を STATUS_SUCCESS または適切なエラー (STATUS_XXX) に設定します。これは、サポート ルーチンの呼び出しによって返される値、または特定の同期要求の場合は下位ドライバーによって返される値です。

      下位レベルのドライバーが STATUS_PENDING を返した場合、上位レベルのドライバーは、IRP の IoCompleteRequest を呼び出してはなりません。ただし、1 つの例外があります。上位レベルのドライバーは、イベントを使用して、その IoCompletion ルーチンとそのディスパッチ ルーチンの間で同期できます。その場合、IoCompletion ルーチンはイベントについて通知し、STATUS_MORE_PROCESSING_REQUIRED を返します。 ディスパッチ ルーチンはイベントを待機し、IoCompleteRequest を呼び出して IRP を完了します。

    • Information を、データ転送要求 (読み取り要求や書き込み要求など) が満たされた場合に正常に転送されたバイト数に設定します。

    • Information を、STATUS_SUCCESS で完了する他の IRP の特定の要求に応じて変化する値に設定します。

    • Information を、警告 STATUS_XXX で完了した IRP の特定の要求に応じて変化する値に設定します。 たとえば、Information を、STATUS_BUFFER_OVERFLOW などの警告に対して転送されたバイト数に設定します。

    • 通常、エラー STATUS_XXX で完了した要求では、Information を 0 に設定します。

  2. IRP と、PriorityBoost = IO_NO_INCREMENT を使用して IoCompleteRequest を呼び出します。

  3. I/O ステータス ブロックで既に設定されている適切な STATUS_XXX を返します。 IoCompleteRequest を呼び出すと、指定された IRP が呼び出し元からアクセス不能になるため、ディスパッチ ルーチンからの戻り値は、既に完了した IRP の I/O ステータス ブロックから設定できない点に注意してください。

IRP を使用して IoCompleteRequest を呼び出す場合は、以下の実装ガイドラインに従ってください。

IoCompleteRequest を呼び出す前に、ドライバーが保持しているスピン ロックを常に解放します。

特に階層化されたドライバーのチェーンでは、IRP が完了するまで、予想できない時間がかかります。 さらに、上位レベルのドライバーの IoCompletion ルーチンが IRP をスピン ロックを保持している下位ドライバーに戻すと、デッドロックが発生する可能性があります。