Freigeben über


Geräte- und Adapterinitialisierung

In diesem Thema werden die Schritte beschrieben, mit denen ein NetAdapterCx-Clienttreiber WDFDEVICE- und NETADAPTER-Objekte initialisiert und startet. Weitere Informationen zu diesen Objekten und deren Beziehung finden Sie unter Zusammenfassung der NetAdapterCx-Objekte.

EVT_WDF_DRIVER_DEVICE_ADD

Ein NetAdapterCx-Clienttreiber registriert seine EVT_WDF_DRIVER_DEVICE_ADD-Rückruffunktion, wenn er WdfDriverCreate aus seiner DriverEntry-Routine aufruft.

In EVT_WDF_DRIVER_DEVICE_ADD sollte ein NetAdapterCx-Clienttreiber die folgenden Schritte ausführen:

  1. NetDeviceInitConfig aufrufen.

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

    Tipp

    Wenn Ihr Gerät mehrere NETADAPTER unterstützt, empfiehlt es sich, Zeiger auf jeden Adapter im Gerätekontext zu speichern.

  3. Das NETADAPTER-Objekt erstellen. Dazu ruft der Client die NetAdapterInitAllocate-Methode auf und dann optional die NetAdapterInitSetXxx-Methode, um die Attribute des Adapters zu initialisieren. Abschließend ruft der Client NetAdapterCreate auf.

    Das folgende Beispiel zeigt, wie ein Clienttreiber ein NETADAPTER-Objekt initialisieren kann. Beachten Sie, dass die Fehlerbehandlung in diesem Beispiel vereinfacht ist.

    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);
    ...
    

Optional können Sie dem NETADAPTER-Objekt einen Kontextbereich hinzufügen. Da Sie einen Kontext für jedes WDF-Objekt festlegen können, können Sie für die Objekte WDFDEVICE und NETADAPTER jeweils einen separaten Kontextbereich hinzufügen. Im Beispiel fügt der Client in Schritt 3 MY_ADAPTER_CONTEXT dem NETADAPTER-Objekt hinzu. Weitere Informationen finden Sie unter Kontextbereich des Frameworkobjekts.

Es wird empfohlen, gerätebezogene Daten im Kontext für Ihr WDFDEVICE und netzwerkbezogene Daten wie Adressen der Netzzugangsschicht im NETADAPTER-Kontext aufzunehmen. Wenn Sie einen vorhandenen NDIS 6.x-Treiber portieren, verfügen Sie wahrscheinlich über einen einzelnen MiniportAdapterContext, der netzwerk- und gerätebezogene Daten in einer einzelnen Datenstruktur verbindet. Um den Portierungsprozess zu vereinfachen, konvertieren Sie einfach diese gesamte Struktur in den WDFDEVICE-Kontext, und verfassen Sie den NETADAPTER-Kontext als kleine Struktur, die auf den WDFDEVICE-Kontext verweist.

Sie können optional zwei Rückrufe für die NET_ADAPTER_DATAPATH_CALLBACKS_INIT-Methode bereitstellen:

Ausführliche Informationen zur Bereitstellung dieser Rückrufe in Ihren Implementierungen finden Sie auf den einzelnen Referenzseiten.

EVT_WDF_DEVICE_PREPARE_HARDWARE

Viele NetAdapterCx-Clienttreiber starten ihre Adapter innerhalb ihrer EVT_WDF_DEVICE_PREPARE_HARDWARE-Rückruffunktion. Eine erwähnenswerte Ausnahme sind hier nur Clienttreiber der Mobile Broadband-Klassenerweiterung. Um eine EVT_WDF_DEVICE_PREPARE_HARDWARE-Rückruffunktion zu registrieren, muss ein NetAdapterCx-Clienttreiber WdfDeviceInitSetPnpPowerEventCallbacks aufrufen.

In EVT_WDF_DEVICE_PREPARE_HARDWARE legt der Clienttreiber zusätzlich zu anderen Hardwarevorbereitungsaufgaben die erforderlichen und optionalen Funktionen des Adapters fest.

NetAdapterCx verlangt, dass der Clienttreiber die folgenden Funktionen festlegt:

Der Treiber muss dann NetAdapterStart aufrufen, um den Adapter zu starten.

Das folgende Beispiel zeigt, wie ein Clienttreiber ein NETADAPTER-Objekt starten kann. Beachten Sie, dass der Code zum Einrichten der einzelnen Adapterfunktionsmethoden aus Gründen der Übersichtlichkeit weggelassen wurde und die Fehlerbehandlung vereinfacht dargestellt wird.

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;
}