共用方式為


裝置和配接器初始化

本主題描述 NetAdapterCx 用戶端驅動程式初始化和啟動 WDFDEVICE 和 NETADAPTER 物件的步驟。 如需這些物件及其關聯性的詳細資訊,請參閱 NetAdapterCx 物件的摘要。

EVT_WDF_DRIVER_DEVICE_ADD

NetAdapterCx 用戶端驅動程式從其 DriverEntry 例程呼叫 WdfDriverCreate 時,會註冊其EVT_WDF_DRIVER_DEVICE_ADD回呼函式

EVT_WDF_DRIVER_DEVICE_ADD 中,NetAdapterCx 用戶端驅動程序應該依序執行下列動作:

  1. 呼叫 NetDeviceInitConfig

    status = NetDeviceInitConfig(DeviceInit);
    if (!NT_SUCCESS(status)) 
    {
        return status;
    }
    
  2. 呼叫 WdfDeviceCreate

    提示

    如果您的裝置支援多個 NETADAPTER,建議您將指標儲存到裝置內容中的每個適配卡。

  3. 建立 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 的範例中,用戶端會將 新增 MY_ADAPTER_CONTEXT 至 NETADAPTER 物件。 如需詳細資訊,請參閱 Framework 對象內容空間

我們建議您將裝置相關數據放在WDFDEVICE的內容中,以及網路相關數據,例如將連結層位址放入 NETADAPTER 內容中。 如果您要移植現有的 NDIS 6.x 驅動程式,您可能會有一個 MiniportAdapterContext,可將網路相關和裝置相關數據合併成單一數據結構。 為了簡化移植程式,只要將該整個結構轉換成 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 需要用戶端驅動程式來設定下列功能:

然後,驅動程式必須呼叫 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;
}