次の方法で共有


読み取り/書き込みディスパッチ ルーチンの概要

DispatchRead、DispatchWrite、または DispatchReadWrite ルーチンを実装する場合は、次の点に注意してください。

  • IRP で次の下位レベルのドライバーの I/O スタックの場所を設定する前に、受信読み取り/書き込み IRP のパラメーターの有効性を確認する階層化されたドライバーのチェーン内の最上位のドライバーの責任です。

  • 一般に、中間ドライバーと最下位レベルドライバーは、チェーン内の最上位レベルのドライバーに依存して、有効なパラメーターを使用して転送要求を渡すことができます。 ただし、すべてのドライバーは、IRP の I/O スタックの場所でパラメーターのサニティ チェックを実行できます、各デバイス ドライバーは、そのデバイスによって課される制限に違反する可能性がある条件のパラメーターを確認する必要があります。

  • DispatchReadWrite ルーチンがエラーで IRP を完了する場合は、I/O スタックのステータスメンバーに適切な NTSTATUS 型の値を設定し、情報メンバーをゼロに設定し、IRP と IO_NO_INCREMENT のPriorityBoostIoCompleteRequestを呼び出す必要があります。

  • ドライバーがバッファー処理された I/O を使用する場合は、転送するデータを含む構造体を定義する必要があり、これらの構造体の一部を内部でバッファーする必要がある場合があります。

  • ドライバーが直接 I/O を使用する場合、 Irp->MdlAddress の MDL が、1 回の転送操作で処理する基になるデバイスのデータが多すぎる (または改ページが多すぎる) バッファーを記述しているかどうかを確認する必要がある場合があります。 その場合、ドライバーは、元の転送要求をより小さな転送操作のシーケンスに分割する必要があります。

    密接に結合されたクラス ドライバーは、基になるポート ドライバーの DispatchReadWrite ルーチンでこのような要求を分割する可能性があります。 これを行うには、特に大容量記憶装置用の SCSI クラス ドライバーが必要です。 SCSI ドライバーの要件の詳細については、「 記憶域ドライバー」を参照してください。

  • 下位レベルのデバイス ドライバーの DispatchReadWrite ルーチンは、別のドライバー ルーチンが IRP をデキューして転送用にデバイスをセットアップするまで、大きな転送要求を部分的な転送に分割することを延期する必要があります。

  • 下位レベルのデバイス ドライバーは、それ自体のルーチンによる処理のために読み取り/書き込み IRP をキューする場合は、IRP をキューに入れます前に IoMarkIrpPending を呼び出す必要があります。 DispatchReadWrite ルーチンは、このような状況でSTATUS_PENDINGを使用して制御を返す必要もあります。

  • DispatchReadWrite ルーチンが下位ドライバーに IRP を渡す場合は、IRP の次の下位ドライバーの I/O スタックの場所を設定する必要があります。 上位レベルのドライバーが、IoCallDriver で渡す前に IRP の IoCompletion ルーチンも設定するかどうかは、ドライバーの設計と、その下に階層化されたドライバーの設計によって異なります。

    ただし、上位レベルのドライバーは、IRP やメモリなどのリソースを割り当てる場合、IoCallDriver を呼び出す前に IoSetCompletionRoutine を呼び出す必要があります。 IoCompletion ルーチンは、下位のドライバーが要求を完了した後、しかし、IoCompleteRequest を元の IRP で呼び出す前に、ドライバーに割り当てられたリソースを解放する必要があります。

  • 上位レベルのドライバーが基になるリムーバブル メディア デバイス ドライバーを含む可能性がある下位ドライバーの IRP を割り当てる場合、割り当てるドライバーは、割り当てる各 IRP でスレッド コンテキストを確立する必要があります。