Share via


Geräte- und Adapterinitialisierung

In diesem Thema werden die Schritte für einen NetAdapterCx-Clienttreiber zum Initialisieren und Starten von WDFDEVICE- und NETADAPTER-Objekten beschrieben. Weitere Informationen zu diesen Objekten und ihrer 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 folgende Reihenfolge ausführen:

  1. Rufen Sie NetDeviceInitConfig auf.

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

    Tipp

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

  3. Erstellen Sie das NETADAPTER-Objekt. Dazu ruft der Client NetAdapterInitAllocate auf, gefolgt von optionalen NetAdapterInitSetXxx-Methoden , um die Attribute des Adapters zu initailisieren. Schließlich 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 wird.

    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 Kontextbereich hinzufügen. Da Sie einen Kontext für ein beliebiges WDF-Objekt festlegen können, können Sie separaten Kontextraum für die WDFDEVICE- und die NETADAPTER-Objekte hinzufügen. Im Beispiel in Schritt 3 fügt der Client dem NETADAPTER-Objekt hinzu MY_ADAPTER_CONTEXT . Weitere Informationen finden Sie unter Framework-Objektkontextraum.

Es wird empfohlen, gerätebezogene Daten in den Kontext für Ihre WDFDEVICE-Instanz und netzwerkbezogene Daten wie Linkschichtadressen in Ihren NETADAPTER-Kontext einzufügen. Wenn Sie einen vorhandenen NDIS 6.x-Treiber portieren, verfügen Sie wahrscheinlich über einen einzelnen MiniportAdapterContext, der netzwerkbezogene und gerätebezogene Daten in einer einzelnen Datenstruktur kombiniert. Um den Portierungsprozess zu vereinfachen, konvertieren Sie einfach diese gesamte Struktur in den WDFDEVICE-Kontext, und machen Sie den NETADAPTER-Kontext zu einer kleinen Struktur, die auf den Kontext des WDFDEVICE verweist.

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

Ausführliche Informationen dazu, was in Ihren Implementierungen dieser Rückrufe bereitgestellt werden soll, finden Sie auf den einzelnen Referenzseiten.

EVT_WDF_DEVICE_PREPARE_HARDWARE

Viele NetAdapterCx-Clienttreiber starten ihre Adapter in ihrer EVT_WDF_DEVICE_PREPARE_HARDWARE Rückruffunktion, mit der bemerkenswerten Ausnahme von Clienttreibern der Mobile Broadband-Klassenerweiterung. Um eine EVT_WDF_DEVICE_PREPARE_HARDWARE Rückruffunktion zu registrieren, muss ein NetAdapterCx-Clienttreiber WdfDeviceInitSetPnpPowerEventCallbacks aufrufen.

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

NetAdapterCx erfordert den Clienttreiber, um die folgenden Funktionen festzulegen:

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 code, der zum Einrichten der einzelnen Adapterfunktionensmethoden erforderlich ist, aus Gründen der Kürze und Übersichtlichkeit weggelassen wird und die Fehlerbehandlung vereinfacht 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;
}