使用すべき DPC の種類
ドライバーの設計によっては、次のいずれかを持つことができます。
すべての割り込み駆動 I/O 操作を完了する単一の DpcForIsr
1 つ以上 の CustomDpc ルーチンのセット。
DpcForIsr と一連の固有の操作 CustomDpc ルーチンのセット
ドライバーに 1 つの DpcForIsr ルーチンを持つか、 CustomDpc ルーチンのセットを持つか、またはその両方があるかどうかは、基になるデバイスの性質と、サポートする必要がある I/O 要求のセットによって異なります。
ほとんどの最下位レベルのデバイス ドライバーには、単一の DpcForIsr ルーチンがあり、それぞれのデバイスで 1 つ以上の操作を必要とする各 IRP の I/O 処理を完了します。 単一の DpcForIsr を使用して、一度に 1 つの操作を実行するデバイスで、要求ごとの割り込み駆動 I/O 操作を完了することは比較的簡単です。 このようなドライバーの ISR では、割り込み駆動 I/O 操作ごとに IoRequestDpc のみを呼び出す必要があります。
ほとんどの下位レベルドライバーは、デバイスがさまざまな割り込み駆動 I/O 操作を完了するために複数の DPC を必要としない限り CustomDpc ルーチンを持っていません。
慎重な設計を施せば、同時実行可能な操作を実行できるデバイス上で、単一の DpcForIsr を使用して、重複する割り込み駆動 I/O 操作を完了させることは可能ですが、比較的困難です。 DpcForIsrをキューに入れる代わりに、またはそれに加えて、ISR は、ドライバー提供の操作固有の CustomDpc ルーチンセットを、 KeInsertQueueDpcを呼び出すことでキューに入れることができます。
たとえば、シリアル ドライバーの作成に関連する設計上の課題をいくつか考えてみます。 全二重デバイスのドライバーとして、シリアル ドライバーは、IIP が StartIo ルーチンをキューに入れる順序と、マルチタスク マルチプロセッサ システムで、そのデバイスからの割り込みシーケンスとの間の 1 対 1 の対応に依存することはできません。 さらに、シリアル ドライバーは、要求のタイムアウト処理、ユーザー生成された非同期取り消し要求 (以前に要求された操作の中止、バッファリングされたデータの消去など) にも対応する必要があります。
そのため、シリアル ドライバーは、ユーザー モード COM ポート アプリケーションが要求できる読み取り、書き込み、消去、および待機操作の内部キューを保持することになります。 また、参照カウントを保持したり、その内部キュー内の IRP に対してフラグのセットなどの他の追跡メカニズムを使用することもできます。 その ISR は、複数のドライバーによって割り当てられ、初期化された DPC オブジェクトののいずれかを使って KeInsertQueueDpc を呼び出し、それぞれドライバーが提供する CustomDpc ルーチンに関連付けられます。