NDIS ミニポート ドライバーの NetAdapterCx への移植
このページでは、NDIS 6.x ミニポート ドライバーを NetAdapterCx クライアント ドライバーに変換する方法について説明します。
WDF の一般的な情報については、「WDF ドライバー開発ガイド」を参照してください。
コンパイル設定
Visual Studio で既存の NDIS ミニポート ドライバー プロジェクトを開き、次の手順を使用して、KMDF プロジェクトに変換します。
まず、[構成プロパティ>]-[>ドライバーモデル] に移動し、ドライバーの種類 が KMDF に設定され、[KMDF バージョン メジャー] と KMDF バージョン マイナー が両方とも空であることを確認します。
プロジェクトのプロパティで、[ドライバー設定]-[>ネットワーク アダプタ ドライバー] を開き、[ネットワーク アダプター クラス拡張機能へのリンク を [はい] に設定します。
- 変換されたドライバーが、引き続き NDIS API を呼び出す場合は、引き続き
ndis.lib
にリンクします。
- 変換されたドライバーが、引き続き NDIS API を呼び出す場合は、引き続き
NDIS プリプロセッサ マクロ (
NDIS650_MINIPORT=1
など) を削除します。次のヘッダーをすべてのソース ファイル (または、共通/プリコンパイル済みヘッダー) に追加します。
#include <ntddk.h> #include <wdf.h> #include <netadaptercx.h>
標準の WDF デコレーションを INF に追加します。
[Yourdriver.Wdf] KmdfService = Yourdriverservice, Yourdriver.wdfsect [Yourdriver.wdfsect] KmdfLibraryVersion = <insert here>
新しい必須のネットワーク キーワードを INF の NT セクションに追加します。
*IfConnectorPresent
ConnectionType
*DirectionType
*AccessType
*HardwareLoopback
これらのキーワードと例の詳細については、「NetAdapterCx クライアント ドライバーの INF ファイル」を参照してください。
ドライバーの初期化
NdisMRegisterMiniportDriver の呼び出しを DriverEntry から削除し、以下を追加します
WDF_DRIVER_CONFIG_INIT(&config, EvtDriverDeviceAdd);
status = WdfDriverCreate(. . . );
if (!NT_SUCCESS(status)) {
return status;
}
設定されている場合は、WdfDriverCreate の呼び出しから WdfDriverInitNoDispatchOverride フラグを削除します。
DriverUnload は、WDF ネットワーク クライアント ドライバーの省略可能なルーチンであるため、必要に応じて削除することができます。 DriverUnload から NdisMDeregisterMiniportDriver を呼び出さないでください。
デバイスの初期化
次に、MiniportInitializeEx から適切な WDF イベント コールバック ハンドラー (そのうちのいくつかは省略可能) にコードを配布します。 コールバック シーケンスの詳細については、「ネットワーク アダプター WDF クライアント ドライバーの電源投入シーケンス」を参照してください。
ネット アダプターを起動するとき、NetAdapterStart を呼び出す前に、NdisMSetMiniportAttributes と同等のメソッドを呼び出します。 ただし、ジェネリック NDIS_MINIPORT_ADAPTER_ATTRIBUTES 構造体を使用して 1 つのルーチンを呼び出す代わりに、クライアント ドライバーはさまざまな関数を呼び出して、さまざまな種類の機能を設定します。
指定する必要があるコールバックと、ネットアダプターを起動するタイミングについては、「デバイスとアダプターの初期化」を参照してください。
レジストリからの構成の読み取り
次に、NdisOpenConfigurationEx、および、関連する関数の呼び出しを NetConfiguration*
メソッドに置き換えます。 NetConfiguration*
メソッドは Ndis*Configuration*
関数と似ており、コードを再構築する必要はありません。
詳しくは、「構成情報へのアクセス」をご覧ください。
ユーザー モードからの I/O 制御コード (IOCTL) の受信
NDIS ドライバーが NdisRegisterDeviceEx (ユーザー モードから IOCTL を受信するコントロール デバイス オブジェクト (CDO) を作成するために使用されるルーチン) を呼び出す場合は、このセクションをお読みください。
WDF ネットワーク クライアント ドライバーでこれを行うには、次の 2 つの方法があります。
最も簡単なポートは、クライアントの EVT_WDF_DRIVER_DEVICE_ADD コールバックから WdfControlDeviceInitAllocate を呼び出してコントロール デバイス オブジェクトを作成することです。 詳しくは、「コントロールデバイスオブジェクトの使用」をご覧ください。
ただし、推奨される解決策は、「デバイス インターフェイスの使用」で説明されているように、デバイス インターフェイスを作成することです。
デバイスの初期化の完了
EVT_WDF_DRIVER_DEVICE_ADD のこの時点では、割り込みの割り当てなど、デバイスを初期化するために、他の操作を行うことができます。
電源状態変更通知の処理
WDF クライアント ドライバーは、電源状態の変更に対して OID_PNP_SET_POWER を受け取りません。
代わりに、WDF クライアントは、電源状態の変更通知を受信するための、コールバック関数オプションを登録します。 概要については、「ファンクション ドライバーでの PnP と電源管理のサポート」を参照してください。
通常、OID_PNP_SET_POWER ハンドラーのコードは EVT_WDF_DEVICE_D0_EXIT と EVT_WDF_DEVICE_D0_ENTRY に移動します。
WDF 電源状態マシンは若干異なっており、コードに若干の変更が必要な場合があります。
具体的には、MiniportInitializeEx コールバック関数では、NDIS ミニポート ドライバーは 1 回限りの初期化タスクを実行して、デバイスを D0 状態にするための作業を行います。 次に、OID_PNP_SET_POWER ハンドラーで、D0 に移動する作業を繰り返します。
これに対し、WDF クライアントは、デバイスが低電力状態にある EVT_WDF_DEVICE_D0_ENTRY の前に、イベント コールバックで 1 回限りの初期化タスクを実行します。 次に、EVT_WDF_DEVICE_D0_ENTRY で D0 に移動する作業を行います。
要約すると、WDF では、"D0 に移動" コードを 2 か所ではなく 1 か所に配置します。
コールバック シーケンスの詳細については、「 NetAdapterCx クライアント ドライバーの電源投入シーケンス」を参照してください。
電源管理機能の照会と設定
同様に、WDF クライアント ドライバーは、ネットワーク アダプターの電源管理ハードウェア機能を照会または設定するために OID_PM_PARAMETERS を受け取りません。
代わりに、ドライバーは、NETPOWERSETTINGS オブジェクトから必要な Wake-on-LAN (WoL) 構成を照会します。 詳細については、「電源管理の構成」を参照してください。
返される実際のフラグは、NDIS 6 ミニポートの場合と同じセマンティックを持つため、ロジックを大幅に変更する必要はありません。 主な違いは、電源切断シーケンス中にこれらのフラグを照会できるようになったことです。 NetAdapterCx クライアント ドライバーの電源切断シーケンスを参照してください。
このコードを移動したら、OID_PNP_SET_POWER と OID_PM_PARAMETERS の OID ハンドラーを削除できます。
NetAdapter フレームワークは、ホストがネットワーク インターフェイスを使用している間、デバイスを D0 に保持するため、通常、クライアントは、電源ロジックを実装しません。デフォルトの NetAdapter 電源動作で十分です。
データ パス
データ パスのプログラミング モデルは大きく変化しました。 主な違いは次のとおりです。
- NetAdapter モデルでは、ネットワーク トラフィックは NDIS のようにアダプターごとではなく、WDF キューごとになります。 I/O キューの作成を参照してください。
- NET_BUFFER_LIST プールと NET_BUFFER プールの代わりに、NetAdapterCx では、次のように NDIS にマップされる、ネット パケットで構成されるリング バッファーが導入されます。
- NET_PACKET は、NET_BUFFER_LIST + NET_BUFFER に似ています。
- NET_PACKET_FRAGMENT は、メモリ記述子リスト (MDL) に似ています。 各 NET_PACKET> には、これらが 1 つ以上あります。
- 置換構造体とその使用方法の詳細については、「パケットディスクリプタと拡張」を参照してください。
- NDIS 6.x では、ミニポートは開始と一時停止のセマンティックを処理する必要があります。 NetAdapterCx モデルでは、これは当てはまりません。
- EVT_RXQUEUE_ADVANCE コールバックは、NDIS 6.x の MINIPORT_RETURN_NET_BUFFER_LISTS に似ています。
- EVT_TXQUEUE_ADVANCE コールバックは、NDIS 6.x の MINIPORT_SEND_NET_BUFFER_LISTS に似ています。
デバイスの削除
WDF NIC ドライバーのデバイスの削除は、他の WDF デバイス ドライバーの場合と同じで、ネットワーク固有の処理は必要ありません。 ネットワーク データ パスが最初にシャットダウンされ、次に WDF デバイスがシャットダウンします。 WDF のシャットダウンについては、「ユーザーがデバイスのプラグを抜く」を参照してください。
MiniportHaltEx ハンドラーは、EVT_WDF_DEVICE_D0_EXIT と EVT_WDF_DEVICE_RELEASE_HARDWARE の間で分散される可能性があります。
NetAdapter または作成したデータパス キューを WDF クライアントが削除する必要はありません。 WDF が、これらのオブジェクトを自動的に削除します。
ユーザーは、MiniportShutdownEx、MiniportResetEx、MiniportCheckForHangEx を削除できます。 これらのコールバックは、サポートされなくなりました。
NDIS-WDF 関数に対応する関数
ほとんどの NdisXxx
関数を、同等の WDF 関数に置き換えることができます。 一般に、NDIS.SYS
からインポートされる機能はほとんど必要ありません。
同等の関数の一覧については、「NDIS-WDF 関数の同等物」を参照してください。
デバッグ
「NetAdapterCx クライアント ドライバーのデバッグ」を参照してください。
!ndiskd.netadapter デバッガー拡張機能は、NDIS 6 ドライバーの !ndiskd.miniport と同様の結果を示します。
まとめ
このトピックの手順を使用すると、デバイスを起動および停止するドライバーが動作するはずです。
注: NetAdapterCx は現在 iSCSI ブートをサポートしていません。