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:
NetDeviceInitConfig aufrufen.
status = NetDeviceInitConfig(DeviceInit); if (!NT_SUCCESS(status)) { return status; }
WdfDeviceCreate aufrufen.
Tipp
Wenn Ihr Gerät mehrere NETADAPTER unterstützt, empfiehlt es sich, Zeiger auf jeden Adapter im Gerätekontext zu speichern.
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:
Datenpfadfunktionen. Der Treiber ruft NetAdapterSetDataPathCapabilities auf, um diese Funktionen festzulegen. Weitere Informationen finden Sie unter Verwaltung des Netzwerkdatenpuffers.
Funktionen der Netzzugangsschicht. Der Treiber ruft NetAdapterSetLinkLayerCapabilities auf, um diese Funktionen festzulegen.
Maximale Übertragungseinheit (Maximum Transfer Unit, MTU) der Netzzugangsschicht. Der Treiber ruft NetAdapterSetLinkLayerMtuSize auf, um die MTU-Größe 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 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;
}