I/O キューの管理

このトピックでは、次の事項について説明します。

I/O キューの開始

I/O キューの停止と再開

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

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

I/O 要求の検索

I/O キューの削除とドレイン

I/O キュー間での要求の移動

I/O 要求のキュー追加前の途中受信

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

I/O キューの開始

ドライバーが WdfIoQueueCreate を呼び出して I/O キューを作成すると、フレームワークは、その I/O キューによる I/O 要求の受信およびドライバーへの送信を自動的に有効にします。

ドライバーは、通常、WdfIoQueueCreateEvtDriverDeviceAdd コールバック関数から呼び出します。フレームワークが I/O 要求のドライバーへの送信を開始できるのは、ドライバーの EvtDriverDeviceAdd コールバック関数から制御が戻った後です。

ドライバーが電源管理された 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 キューを削除またはドレインするには、次のいずれかのキュー オブジェクト メソッドを呼び出します。

I/O キュー間での要求の移動

ドライバーが I/O 要求を受信した後に、その要求を別の I/O キューに再配置する必要が生じる場合があります。これを行うには、ドライバーで WdfRequestForwardToIoQueue または WdfRequestForwardToParentDeviceIoQueue を呼び出して、指定したキューの末尾に要求を追加します。その結果、フレームワークは、指定されたキューのディスパッチ方法を使用して、その要求をドライバーに再度送信します。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 キューのプロパティの取得

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