
はじめに
まず、NDISのバージョンと、それらが複数あるという事実のための機能を扱います。
- NDIS 5.1。 Windows XP、Server2003。ほとんどのドライバーはこのバージョン用に作成されており、誰もそれらを移植しません。 そこに移植する特別なものはありません-ほとんどすべてを再度書き換える必要があります。
- NDIS 5.2。 Windows Server 2003 SP2。 このバージョンでは、ほとんどの場合、単一のドライバーは作成されません。 ここでは、5.1のドライバーは正常に動作します。
- NDIS 6.0。 Windows Vista Windows VistaのNDISサブシステムは大幅に変更され、新しい種類のドライバーが追加され、パフォーマンスが向上しました。
- NDIS 6.1。 Windows Vista SP2、Server2008。NDIS5.2と同じストーリー。
- NDIS 6.20。 Windows7。NDIS6.0に関する小さな変更、エミュレーションモードでの後者のサポート。
NDIS 4.0でW2Kの形の古いゴミに触れないのは、 サポートする意味はありません。 Microsoftは、Windows 8でのNDIS 5.1のサポートも停止します。
リストからわかるように、NDIS 5.xとNDIS 6.xの間には大きなギャップがあります。 実際、全体から見ると、アーキテクチャ上の機能と機能のライブラリしかありませんでした。 残りの詰め物は生産性を高めるために移動されました。 ちなみに、20%がこの増加を調査しているため、少なくともVistaは以前のバージョンよりも優れています。 フィルタードライバーがアーキテクチャに追加されましたが、以前のバージョンにはあまりありませんでした。 パケット送信の原理が劇的に変わりました。つまり、中間ドライバーがパケットを送受信する少なくとも3つの機能を実装しなければならない場合、これらの機能の数はいずれにしても1つになります。 これは、NET_BUFFERと呼ばれる新しいパケット転送アーキテクチャのおかげで可能になりました。 以下で説明します。
NET_BUFFERアーキテクチャ
それは何ですか? 実際、NET_BUFFERは以前のNDIS_BUFFER'yに置き換わるものですが、最初のものが最初です。 どうした? このドライバーは、パケットを送受信するための3つの機能を実装しています。 ロシア語では、これらの関数を次のように呼び出します。
- パッケージを受け入れます。
- パッケージを受け入れます。
- パッケージの受け入れを確認します。
- パッケージを送信;
- パッケージを送信します。
- パッケージの送信を確認します。
1つのパケットを受信するには、一連のアクションを実行する必要があったことは明らかです。 そして、中間ドライバーの場合、一般的には、パッケージを骨に分解し、自分のものを組み立てて(とにかく自分のものではないので)それを送信します。 したがって、NET_BUFFERアーキテクチャはNDIS 6.xで導入されました。
このアーキテクチャによれば、パケットを送受信するための2つの機能を実装するだけで十分です(現在はパケットではなくバッファです。NDIS6+の場合は、これらの単語を同義語として使用してください)。 はい、私は約2倍嘘をつきましたが、これら2つは特別なことは何もせず、変更せずにドライバー間をさまよいます。 だから、受信と送信の機能、私はここで一般的な理解のために署名を書きます:
VOID FilterSendNetBufferLists( IN NDIS_HANDLE FilterModuleContext, IN PNET_BUFFER_LIST NetBufferLists, IN NDIS_PORT_NUMBER PortNumber, IN ULONG SendFlags ); VOID FilterReceiveNetBufferLists( IN NDIS_HANDLE FilterModuleContext, IN PNET_BUFFER_LIST NetBufferLists, IN NDIS_PORT_NUMBER PortNumber, IN ULONG NumberOfNetBufferLists, IN ULONG ReceiveFlags );
最初のパラメーターは、基本的にNDISを渡すポインターです。 ドライバーを登録するとき、またはキューにアタッチするときに、このポインターを指定できます。 T.O. ご存じのように、ユーザー変数へのリンクは常に自由に使用できます。 とても快適です。
2番目のパラメーターは、NET_BUFFERリストへのポインターです。 これについては後で対処します。
他のすべてのパラメーターはめったに使用されないため、それらは考慮しません。
アーキテクチャ自体に渡します。
以下の図は、アーキテクチャを大まかに説明しています。

各NET_BUFFERは、下の画像のようにパッケージを記述できます。

影付きのスペースには、パッケージも保存されます。 ご覧のとおり、これは必ずしも連続したメモリブロックではなく、1つのパケットがシステムアドレス空間全体に散在している可能性があります。 また、パッケージを非ページメモリに保存することをお勧めします(参照:IRQL> = DISPATCH_LEVELでページメモリにアクセスしようとすると、コードD1のブルースクリーンが表示されます。DRIVER_IRQL_NOT_LESS_OR_EQUAL、最も一般的なドライバーライターエラー)。
すぐに問題は、なぜパッケージの前に空きスペースを残すのですか? 次に、IPパケットがダウンすると、送信用のイーサネットフレームに変わります。 また、このビジネスを再構築しないために、イーサネットヘッダーはパケットの前に単純に書き込まれます。 よく考えました。 同じ原則がトップレベルのドライバーに実装されています。 いわゆるに関するすべての情報 バックフィル(別名DataOffset)スペース、オフセット、およびバッファー長は、NET_BUFFER構造体に格納されます。 また、バッファサイズを変更できることにも注意してください。 バッファの先頭を左に、または末尾を右に移動できます。 これを行うには、NDISカーネルによってエクスポートされた特別な関数を使用します。
結論の代わりに
この記事では、NDISサブシステムを研究する過程で遭遇した膨大な詳細を見逃すことを意図しています。 私はそれらを公開しません、なぜなら ただし、材料の量は合理的なフレームワークに適合しません。 同時に、私は何が起こっているかの本質を理解するために基本と考えるいくつかの重要な機能に光を当てようとします。
ここでさらに読む:
www.codemachine.com/article_ndis6nbls.html
msdn.microsoft.com/en-us/library/ff564881(v = vs. 85).aspx
次回まで。