の実際のパケット ペイロードは、NET_BUFFER
MDL チェーン全体のペイロードのサブセットです。パケットは MDL チェーンの先頭で開始されず、MDL チェーンの最後で終了しない場合があります。
NET_BUFFER
したがって、最も一般的なケースでは、新しい MDL を追加する前に、実際には の末尾からいくつかの MDL を削除する必要があります。具体例を挙げましょう。
NET_BUFFER
* DataOffset=300 bytes
* DataLength=200 bytes
* MdlChain=[200 bytes]->[200 bytes]->[300 bytes]->[200 bytes]
したがって、この例では、 はNET_BUFFER
4 つの MDL を持つ MDL チェーンを指しています。アスキーアートのバッファを見てみましょう:
0 100 200 300 400 500 600 700 800 900
| | | | | | | | | |
[ First MDL ][ Second MDL ][ Third MDL ][ Fourth MDL ]
↑ ↑ [ Packet ] ↑
| | |
| | ↑ ↑ |
| | | | |
MdlChain | DataOffset DataLength End-of-MDL-chain
|
CurrentMdl
図が示すように、実際のパケット ペイロードは 2 番目と 3 番目の MDL にのみ分散されます。最初と 4 番目の MDL は両方とも完全に無視されます。したがって、パケットにデータを追加する場合は、次のことを行う必要があります。
- MDL チェーンの末尾からすべての MDL を削除します。MDL のバッファーの最後のバイトは、論理パケット バッファーの一部ではありません。(上記の例では、3 番目と 4 番目の MDL の両方を削除します)。
- データと、上記の手順 1 で削除した実際のパケット ペイロードを保持するのに十分な大きさの新しいバッファを割り当てます。(この例では、3 番目の MDL の最初の 100 バイトを保持するために、追加の 100 バイトを割り当てる必要があります。)
- 新しい MDL をチェーンの最後にチェーンします。
- 増分し
NET_BUFFER::DataLength
ます。
- パケットを NDIS に渡します。
以下は、ステップ 3 を終了した後のパケットの外観の図です。
0 100 200 300 400 500 600 700 800 900
| | | | | | | | | |
[ First MDL ][ Second MDL ][ Your MDL ]
↑ ↑ [ Packet ] ↑
| | |
| | ↑ ↑ |
| | | | |
MdlChain | DataOffset DataLength |
| |
CurrentMdl End-of-MDL-chain
次に、ステップ #4 の後:
0 100 200 300 400 500 600 700 800 900
| | | | | | | | | |
[ First MDL ][ Second MDL ][ Your MDL ]
↑ ↑ [ Packet ]
| |
| | ↑ ↑
| | | |
MdlChain | DataOffset DataLength
| |
CurrentMdl End-of-MDL-chain
パケットがドライバーに返されたら、以前に行った変更を元に戻す必要があります。
- 減分し
DataLength
ます。
- 追加した MDL を削除します。
- 追加した MDL を解放します。
- 削除した元の MDL を復元します。