プロトコル ドライバーからのデータの送信

次の図は、プロトコル ドライバーの送信操作を示しています。これには、ドライバー スタック内のプロトコル ドライバー、NDIS、および下位ドライバーが含まれます。

Diagram showing a protocol driver send operation with a protocol driver, NDIS, and underlying drivers in a driver stack.

フィルター ドライバーは、NdisSendNetBufferLists 関数を呼び出して、NET_BUFFER_LIST 構造体の一覧で定義されているネットワーク データを送信します。

プロトコル ドライバーは、各 NET_BUFFER_LIST 構造体の SourceHandle メンバーを NdisBindingHandle パラメーターに渡すのと同じ値に設定する必要があります。 バインド ハンドルは、下位ミニポート ドライバーが NdisMSendNetBufferListsComplete を呼び出した後、NDIS がプロトコル ドライバーにNET_BUFFER_LIST 構造体を返すために必要な情報を提供します。

NdisSendNetBufferLists を呼び出す前に、プロトコル ドライバーは、NET_BUFFER_LIST_INFO マクロを使って送信要求に付随する情報を設定できます。 下位ドライバーは、NET_BUFFER_LIST_INFO マクロを使用してこの情報を取得できます。

プロトコル ドライバーが NdisSendNetBufferLists を呼び出すとすぐに、NET_BUFFER_LIST 構造体とすべての関連リソースの所有権が放棄されます。 NDIS は、プロトコル ドライバーに構造体とデータを返す ProtocolSendNetBufferListsComplete 関数を呼び出します。 NDIS は、ProtocolSendNetBufferListsComplete にリストを渡す前に、複数の送信要求からの構造体とデータを NET_BUFFER_LIST 構造体の単一の連結リストに収集できます。

NDIS が ProtocolSendNetBufferListsComplete を呼び出すまで、プロトコル ドライバーが開始する送信の現在の状態は不明です。 プロトコル ドライバーは、NdisSendNetBufferLists を呼び出すときに、送信要求に割り当てられたすべてのリソースの所有権を一時的に解放します。 NDIS が ProtocolSendNetBufferListsComplete に構造体を返す前に、プロトコル ドライバーは、NET_BUFFER_LIST 構造体または関連するデータを調べようとしてはいけません。

ProtocolSendNetBufferListsComplete は、送信操作を完了するために必要な後処理を実行します。 たとえば、プロトコル ドライバーは、ネットワーク データの送信をプロトコル ドライバーに要求したクライアントに、送信操作が完了したことを通知できます。

NDIS が ProtocolSendNetBufferListsComplete を呼び出すと、プロトコル ドライバーは、NetBufferLists パラメーターで指定された NET_BUFFER_LIST 構造体に関連付けられているすべてのリソースの所有権を回復します。 ProtocolSendNetBufferListsComplete は、これらのリソースを解放するか (たとえば、NdisFreeNetBuffer 関数と NdisFreeNetBufferList 関数を呼び出すことで)、NdisSendNetBufferLists への後続の呼び出しで再利用できるようにリソースを準備することができます。

NDIS は常に、NdisSendNetBufferLists に渡されるプロトコルによって決定された順序で、下位ミニポート ドライバーにプロトコル提供のネットワーク データを送信しますが、下位ドライバーはランダムな順序で送信要求を完了できます。 つまり、バインドされているすべてのプロトコル ドライバーは、下位ドライバーに FIFO でプロトコル ドライバーが NdisSendNetBufferLists に渡すネットワーク データを送信する NDIS に依存できます。 ただし、どのプロトコル ドライバーも、下位ドライバーに依存して NdisMSendNetBufferListsComplete を同じ順序で呼び出すことはできません。