フィルター ドライバーは、送信要求を開始したり、上位ドライバーが開始する送信要求をフィルター処理することができます。 プロトコル ドライバーが NdisSendNetBufferLists 関数を呼び出すと、NDIS は指定した NET_BUFFER_LIST 構造体をドライバー スタックの最上位のフィルター モジュールに送信します。
フィルタードライバーによって開始されたリクエストの送信
次の図は、フィルター ドライバーによって開始される送信操作を示しています。
フィルター ドライバーは、 NdisFSendNetBufferLists 関数を呼び出して、 NET_BUFFER_LIST 構造体の一覧で定義されているネットワーク データを送信します。
フィルター ドライバーは、NdisFSendNetBufferLists の NdisFilterHandle パラメーターに渡すのと同じ値に作成する各NET_BUFFER_LIST構造体の SourceHandle メンバーを設定する必要があります。 NDIS ドライバーは、自身が生成していない NET_BUFFER_LIST 構造体の SourceHandle メンバーを変更しないでください。
NdisFSendNetBufferLists を呼び出す前に、フィルター ドライバーは、NET_BUFFER_LIST_INFO マクロで送信要求に付随する情報を設定できます。 基になるドライバーは、NET_BUFFER_LIST_INFO マクロを使用してこの情報を取得できます。
フィルター ドライバーが NdisFSendNetBufferLists を呼び出すとすぐに、NET_BUFFER_LIST構造体とすべての関連リソースの所有権が放棄されます。 NDIS は、送信要求を処理するか、基になるドライバーに要求を渡すことができます。
NDIS は、フィルター ドライバーに構造体とデータを返す FilterSendNetBufferListsComplete 関数を呼び出します。 NDIS は、FilterSendNetBufferListsComplete に一覧を渡す前に、複数の送信要求から NET_BUFFER_LIST 構造体の単一のリンクされたリストに構造体とデータを収集できます
NDIS が FilterSendNetBufferListsComplete を呼び出すまで、送信要求の現在の状態は不明です。 フィルター ドライバーは、NDIS が FilterSendNetBufferListsComplete に構造体を返す前に、NET_BUFFER_LIST構造体または関連するデータを調べないようにする必要があります。
FilterSendNetBufferListsComplete は、送信操作を完了するために必要な後処理を実行します。
NDIS が FilterSendNetBufferListsComplete を呼び出すと、フィルター ドライバーは 、NetBufferLists パラメーターで指定されたNET_BUFFER_LIST構造体に関連付けられているすべてのリソースの所有権を回復します。 FilterSendNetBufferListsComplete は、これらのリソースを解放するか (たとえば、NdisFreeNetBuffer 関数と NdisFreeNetBufferList 関数を呼び出すことによって)、NdisFSendNetBufferLists への後続の呼び出しで再利用できるように準備することができます。
NDIS は常に、 NdisFSendNetBufferLists に渡されたフィルター ドライバーによって決定された順序で、基になるドライバーにフィルター指定のネットワーク データを送信します。 ただし、指定した順序でデータを送信した後、基になるドライバーは任意の順序でバッファーを返すことができます。
フィルター ドライバーは、送信要求のループバックを要求できます。 ループバックを要求するために、ドライバーは NdisFSendNetBufferLists の SendFlags パラメーターにNDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK フラグを設定します。 NDIS は、送信データを含む受信パケットを示します。
手記 フィルター ドライバーは、発生した送信要求を追跡し、このような要求が完了したときに NdisFSendNetBufferListsComplete 関数を呼び出さないことを確認する必要があります。
送信要求のフィルター処理
次の図は、基になるドライバーによって開始される送信要求のフィルター処理を示しています。
NDIS は、フィルター ドライバーの FilterSendNetBufferLists 関数を呼び出して、上にあるドライバーの送信要求をフィルター処理します。
フィルター ドライバーは、他のドライバーから受信するNET_BUFFER_LIST構造体の SourceHandle メンバーを変更することはできません。
フィルター ドライバーは、データをフィルター処理し、基になるドライバーにフィルター処理されたデータを送信できます。 FilterSendNetBufferLists に送信されたNET_BUFFER構造体ごとに、フィルター ドライバーは次の操作を実行できます。
NdisFSendNetBufferLists 関数を呼び出して、次の基になるドライバーにバッファーを渡します。 NDIS は、フィルター ドライバーのコンテキスト空間 ( NET_BUFFER_LIST_CONTEXT構造体を参照) の可用性を保証します。 フィルター ドライバーは、NdisFSendNetBufferLists 呼び出す前にバッファーの内容を変更できます。 フィルター処理されたデータの処理は、フィルター ドライバーによって開始された送信操作と同様に続行されます。
NdisFSendNetBufferListsComplete 関数を呼び出してバッファーを削除します。
後で処理するために、バッファーをローカル データ構造にキューに入れます。 フィルター ドライバーの設計によって、キューに入ったバッファーをドライバーが処理する原因が決まります。 たとえば、タイムアウト後の処理や、特定のバッファーの受信後の処理などがあります。
手記 ドライバー キューが後で処理するために要求を送信する場合は、キャンセル要求の送信をサポートする必要があります。 キャンセル要求の送信の詳細については、「 フィルター ドライバーでの要求の送信のキャンセル」を参照してください。
バッファーをコピーし、コピーを使用して送信要求を生成します。 送信操作は、フィルター ドライバーによって開始された送信要求に似ています。 この場合、ドライバーは NdisFSendNetBufferListsComplete 関数を呼び出すことによって、基になるドライバーに元のバッファーを返す必要があります。
要求の送信が完了すると、ドライバー スタックが上に進みます。 ミニポート ドライバーが NdisMSendNetBufferListsComplete 関数を呼び出すと、NDIS は最下位のフィルター モジュールの FilterSendNetBufferListsComplete 関数を呼び出します。
送信操作が完了すると、フィルター ドライバーは、フィルター ドライバーが FilterSendNetBufferLists で行った、上にあるドライバーのバッファー記述子への変更を元に戻します。 ドライバーは、 NdisFSendNetBufferListsComplete 関数を呼び出して、上にあるドライバーにNET_BUFFER_LIST構造体のリンクされたリストを返し、送信要求の最終的な状態を返します。
最上位のフィルター モジュールが NdisFSendNetBufferListsComplete を呼び出すと、NDIS は、元のプロトコル ドライバーの ProtocolSendNetBufferListsComplete 関数を呼び出します。
FilterSendNetBufferLists 関数を提供しないフィルター ドライバーは、引き続き送信要求を開始できます。 このようなドライバーが送信要求を開始する場合は、 FilterSendNetBufferListsComplete 関数を提供する必要があり、ドライバー スタックの完全なイベントを渡してはなりません。
フィルタードライバーは、上位ドライバーのループバック要求を渡したりフィルタリングしたりできます。 ループバック要求を渡すためには、NDIS が FilterSendNetBufferLists の SendFlags パラメーターに NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK を設定している場合、フィルタードライバーは NdisFSendNetBufferLists を呼び出すときに SendFlags パラメーターに NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK を設定します。 NDIS は、送信データを含む受信パケットを示します。
一般に、フィルター ドライバーは、NDIS が標準サービス (ループバックなど) を提供できないように動作を変更する場合、フィルター ドライバーは NDIS のそのサービスを提供する必要があります。 たとえば、ハードウェア アドレスの要求を変更するフィルター ドライバー ( OID_802_3_CURRENT_ADDRESSを参照) は、新しいハードウェア アドレスに転送されるバッファーのループバックを処理する必要があります。 この場合、フィルターによってアドレスが変更されたため、NDIS は通常提供するループバック サービスを提供できません。 また、フィルター ドライバーが無差別モードを設定する場合 ( OID_GEN_CURRENT_PACKET_FILTER参照)、上にあるドライバーに受け取る追加のデータを渡さないでください。