I/O キューの管理

I/O キューの開始

ドライバーが WdfIoQueueCreate を呼び出して I/O キューを作成すると、フレームワークは自動的にキューが I/O 要求を受信し、ドライバーに配信できるようにします。

ドライバーは通常、EvtDriverDeviceAdd コールバック関数内から WdfIoQueueCreate を呼び出します。 フレームワークは、ドライバーの EvtDriverDeviceAdd コールバック関数が返された後、ドライバーへの I/O 要求の配信を開始できます。

ドライバーが電源管理 I/O キューを使用している場合、フレームワークは、デバイスが動作状態に入り、フレームワークがドライバーの EvtDeviceD0Entry コールバック関数を呼び出すまで、ドライバーへの要求の配信を開始できません。

I/O キューの停止と再起動

ドライバーは WdfIoQueueStop または WdfIoQueueStopSynchronously を呼び出して、フレームワークが I/O キューから I/O 要求を一時的に配信できないようにすることができます。 I/O 要求の配信を再開するために、ドライバーは WdfIoQueueStart を呼び出します。

ドライバーが電源管理 I/O キューを使用している場合、デバイスが動作中 (D0) 状態を離れると、フレームワークによってデバイスのキューが自動的に停止され、デバイスの状態が D0 に戻ったときにフレームワークによってキューが再起動されます。

I/O キューへの要求の追加

システムが読み取り、書き込み、またはデバイスの I/O 制御要求をドライバーに送信すると、フレームワークは I/O キューに要求を配置します。 ドライバーは、WdfDeviceConfigureRequestDispatching を呼び出すことによって、フレームワークが各キューに格納する要求の種類を制御できます。

ドライバーは、WdfRequestForwardToIoQueue を呼び出すことによって、フレームワークから受信した要求を再キューすることもできます。

I/O キューからの要求の取得

ドライバーは、I/O キューの順次または並列ディスパッチ メソッドを指定する場合は、要求ハンドラーで要求を受信します。

ドライバーは、手動または順次ディスパッチ メソッドを指定する場合は、WdfIoQueueRetrieveNextRequest または WdfIoQueueRetrieveRequestByFileObject を呼び出すことによって要求を取得できます。

I/O 要求の検索

ドライバーは、I/O キューの手動 ディスパッチ メソッド を指定する場合は、キュー内の特定の要求を検索するために、次の手順を使用できます:

  1. WdfIoQueueFindRequest を呼び出して、ドライバーが指定した条件に一致する要求を見つけます。

  2. WdfIoQueueRetrieveFoundRequest を呼び出して、WdfIoQueueFindRequest が見つけた要求を取得します。

I/O キューの削除またはドレイン

I/O キューを削除すると、キューへの I/O 要求の挿入が停止し、キューに既に存在するすべての要求が取り消されます。

I/O キューをドレインすると、キューへの I/O 要求の挿入を停止しながら、既にキュー内にある要求をドライバーに配信できるようになります。

通常、ドライバーは、キューが電源管理されていない場合にのみ、キューを削除またはドレインします。 電源管理 I/O キューの場合、ドライバーは EvtIoStop および EvtIoResume コールバック関数を提供できます。

一部のドライバーのキューが電源管理されていない場合は、関連付けられているデバイスまたは I/O チャネルが使用できなくなった場合にキューを削除またはドレインできます。 通常、各要求に非常に重要な情報が含まれている可能性が高い場合を除き、キューはドレインではなく削除します。 たとえば、ネットワーク デバイスのドライバーはキューを削除し、ストレージ デバイスのドライバーはキューをドレインする可能性があります。

ドライバーで I/O キューを削除またはドレインする場合、ドライバーは次のいずれかのキュー オブジェクト メソッドを呼び出すことができます:

WdfIoQueueDrainWdfIoQueueDrainSynchronously を呼び出す場合は注意が必要です。 ドレイン操作は要求の完了を待機するため、キューの保留中の要求が適切なタイミングで完了することが確実な場合にのみ、キューをドレインする必要があります。 I/O 要求の完了にかかる時間が不明で、未処理の要求をキャンセルできる場合は、キューの削除を検討してください。

ある I/O キューから別の I/O キューへの要求の移動

ドライバーが I/O 要求を受信した後、ドライバーが別の I/O キューに要求を再キューに入れる場合があります。 これを行うには、ドライバーは、指定されたキューの末尾に要求を追加する WdfRequestForwardToIoQueue または WdfRequestForwardToParentDeviceIoQueue を呼び出します。 最終的に、フレームワークは、指定されたキューのディスパッチメソッドを使用して、ドライバーに要求を再び配信します。 I/O 要求をある I/O キューから別の I/O キューに移動する方法の詳細については、「I/O 要求の再キューイング」を参照してください。

キューに入れる前に I/O 要求をインターセプトする

フレームワークが I/O キューに要求を配置する前に、ドライバーが I/O 要求をインターセプトすることができます。 I/O 要求をインターセプトするには、ドライバーが WdfDeviceInitSetIoInCallerContextCallback を呼び出して EvtIoInCallerContext コールバック関数を登録する必要があります。

フレームワークは、 EvtIoInCallerContext コールバック関数をデバイスに関連付けます。 その結果、フレームワークは、システムがデバイスに送信している要求を受信するたびに、フレームワークは EvtIoInCallerContext コールバック関数を呼び出します。

通常、EvtIoInCallerContext コールバック関数は、要求を受信すると、要求に対して何らかの予備処理を実行します。 次に、コールバック関数は WdfDeviceEnqueueRequest を呼び出し、要求をフレームワークに返します。 その後、フレームワークは、EvtIoInCallerContext コールバック関数を呼び出さなかった場合と同様に、適切な I/O キューに要求を配置できます。

ドライバーが EvtIoInCallerContext コールバック関数を提供する場合がある主な理由は、ドライバーがバッファー I/O または直接 I/O のどちらでもない呼び出された I/O メソッドをサポートする I/O 操作を処理する必要があるためです。 この I/O メソッドの場合、ドライバーは I/O 要求の発信元のプロセス コンテキストで受信したバッファーにアクセスする必要があります。 詳細については、「フレームワーク ベースのドライバーでのデータ バッファーへのアクセス」を参照してください。

I/O キューのプロパティの取得

フレームワーク キュー オブジェクトのプロパティを取得するために、ドライバーは、次のメソッドを呼び出すことができます: