デバイスとアダプターの初期化
このトピックでは、NetAdapterCx クライアント ドライバーが WDFDEVICE オブジェクトと NETADAPTER オブジェクトを初期化して起動する手順について説明します。 これらのオブジェクトとその関係の詳細については、「NetAdapterCx オブジェクトの概要」を参照してください。
EVT_WDF_DRIVER_DEVICE_ADD
NetAdapterCx クライアント ドライバーは、 DriverEntry ルーチンから WdfDriverCreate を呼び出すときに、その EVT_WDF_DRIVER_DEVICE_ADD コールバック関数を登録します。
EVT_WDF_DRIVER_DEVICE_ADDでは、NetAdapterCx クライアント ドライバーは、次の順序で実行する必要があります。
NetDeviceInitConfig を呼び出します。
status = NetDeviceInitConfig(DeviceInit); if (!NT_SUCCESS(status)) { return status; }
WdfDeviceCreate を呼び出 します。
ヒント
デバイスで複数の NETADAPTER がサポートされている場合は、各アダプターへのポインターをデバイス コンテキストに格納することをお勧めします。
NETADAPTER オブジェクトを作成します。 そのためには、クライアントは NetAdapterInitAllocateを呼び出し、続いてオプションの NetAdapterInitSetXxx メソッドを呼び出してアダプターの属性を初期化します。 最後に、クライアントは NetAdapterCreate を呼び出 します。
次の例は、クライアント ドライバーが NETADAPTER オブジェクトを初期化する方法を示しています。 この例では、エラー処理が簡略化されていることに注意してください。
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attribs, MY_ADAPTER_CONTEXT); // // Allocate the initialization structure // PNETADAPTER_INIT adapterInit = NetAdapterInitAllocate(device); if(adapterInit == NULL) { return status; } // // Optional: set additional attributes // // Datapath callbacks for creating packet queues NET_ADAPTER_DATAPATH_CALLBACKS datapathCallbacks; NET_ADAPTER_DATAPATH_CALLBACKS_INIT(&datapathCallbacks, MyEvtAdapterCreateTxQueue, MyEvtAdapterCreateRxQueue); NetAdapterInitSetDatapathCallbacks(adapterInit, datapathCallbacks); // // Required: create the adapter // NETADAPTER* netAdapter; status = NetAdapterCreate(adapterInit, &attribs, netAdapter); if(!NT_SUCCESS(status)) { NetAdapterInitFree(adapterInit); adapterInit = NULL; return status; } // // Required: free the adapter initialization object even // if adapter creation succeeds // NetAdapterInitFree(adapterInit); adapterInit = NULL; // // Optional: initialize the adapter's context // PMY_ADAPTER_CONTEXT adapterContext = GetMyAdapterContext(&netAdapter); ...
必要に応じて、NETADAPTER オブジェクトにコンテキスト空間を追加できます。 任意の WDF オブジェクトにコンテキストを設定できるため、WDFDEVICE オブジェクトと NETADAPTER オブジェクトに個別のコンテキスト空間を追加できます。 手順 3 の例では、クライアントは NETADAPTER オブジェクトに MY_ADAPTER_CONTEXT
を追加 します。 詳細については、「フレームワーク オブジェクト コンテキスト空間」を参照してください。
デバイス関連のデータを WDFDEVICE のコンテキストに配置し、ネットワーク関連のデータ (リンク レイヤー アドレスなど) を NETADAPTER コンテキストに配置することをお勧めします。 既存の NDIS 6.x ドライバーを移植する場合は、ネットワーク関連とデバイス関連のデータを 1 つのデータ構造に結合する 1 つのミニポートAdapterContext があります。 移植プロセスを簡略化するには、その構造体全体を WDFDEVICE コンテキストに変換し、NETADAPTER のコンテキストを WDFDEVICE のコンテキストを指す小さな構造体にします。
必要に応じて、 NET_ADAPTER_DATAPATH_CALLBACKS_INIT メソッドに 2 つのコールバックを指定できます。
これらのコールバックの実装で提供する内容の詳細については、個々のリファレンス ページを参照してください。
EVT_WDF_DEVICE_PREPARE_HARDWARE
多くの NetAdapterCx クライアント ドライバーは、 モバイル ブロードバンド クラス拡張クライアント ドライバーの注目すべき例外を除き、 EVT_WDF_DEVICE_PREPARE_HARDWARE コールバック関数内からアダプターを起動します。 EVT_WDF_DEVICE_PREPARE_HARDWARE コールバック関数を登録するには、NetAdapterCx クライアント ドライバーが WdfDeviceInitSetPnpPowerEventCallbacks を呼び出す必要があります。
EVT_WDF_DEVICE_PREPARE_HARDWARE内では、他のハードウェア準備タスクに加えて、クライアント ドライバーはアダプターの必須機能とオプション機能を設定します。
NetAdapterCx では、クライアント ドライバーで次の機能を設定する必要があります。
WDI_TLV_DATAPATH_CAPABILITIES ドライバーは NetAdapterSetDataPathCapabilities を呼び出して、これらの機能を設定します。 詳しくは、 ネットワーク データ バッファ管理に関する記事をご覧ください。
リンク レイヤー機能。 ドライバーは NetAdapterSetLinkLayerCapabilities を呼び出して、これらの機能を設定します。
リンク 層の最大転送単位 (MTU) サイズ。 ドライバーは、 NETAdapterSetLinkLayerMtuSize を呼び出して MTU サイズを設定します。
その後、ドライバーは、アダプターを起動するために NetAdapterStart を呼び出す必要があります。
次の例は、クライアント ドライバーが NETADAPTER オブジェクトを起動する方法を示しています。 各アダプター機能メソッドを設定するために必要なコードは簡潔でわかりやすくするために省略され、エラー処理が簡略化されることに注意してください。
PMY_DEVICE_CONTEXT deviceContext = GetMyDeviceContext(device);
NETADAPTER netAdapter = deviceContext->NetAdapter;
PMY_ADAPTER_CONTEXT adapterContext = GetMyAdapterContext(netAdapter);
//
// Set required adapter capabilities
//
// Link layer capabilities
...
NetAdapterSetDatapathCapabilities(netAdapter,
&txCapabilities,
&rxCapabilities);
...
NetAdapterSetLinkLayerCapabilities(netAdapter,
&linkLayerCapabilities);
...
NetAdapterSetLinkLayerMtuSize(netAdapter,
MY_MAX_PACKET_SIZE - ETHERNET_HEADER_LENGTH);
//
// Set optional adapter capabilities
//
// Link layer capabilities
...
NetAdapterSetPermanentLinkLayerAddress(netAdapter,
&adapterContext->PermanentAddress);
...
NetAdapterSetCurrentLinkLayerAddress(netAdapter,
&adapterContext->CurrentAddress);
// Datapath capabilities
...
NetAdapterSetDatapathCapabilities(netAdapter,
&txCapabilities,
&rxCapabilities);
// Receive scaling capabilities
...
NetAdapterSetReceiveScalingCapabilities(netAdapter,
&receiveScalingCapabilities);
// Hardware offload capabilities
...
NetAdapterOffloadSetChecksumCapabilities(netAdapter,
&checksumCapabilities);
...
NetAdapterOffloadSetLsoCapabilities(netAdapter,
&lsoCapabilities);
...
NetAdapterOffloadSetRscCapabilities(netAdapter,
&rscCapabilities);
//
// Required: start the adapter
//
status = NetAdapterStart(netAdapter);
if(!NT_SUCCESS(status))
{
return status;
}