Initialisation de l’appareil et de l’adaptateur

Cette rubrique décrit les étapes d’un pilote client NetAdapterCx pour initialiser et démarrer des objets WDFDEVICE et NETADAPTER. Pour plus d’informations sur ces objets et leur relation, consultez Résumé des objets NetAdapterCx.

EVT_WDF_DRIVER_DEVICE_ADD

Un pilote client NetAdapterCx inscrit sa fonction de rappel EVT_WDF_DRIVER_DEVICE_ADD lorsqu’il appelle WdfDriverCreate à partir de sa routine DriverEntry .

Dans EVT_WDF_DRIVER_DEVICE_ADD, un pilote client NetAdapterCx doit effectuer les opérations suivantes dans l’ordre :

  1. Appelez NetDeviceInitConfig.

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

    Conseil

    Si votre appareil prend en charge plusieurs NETADAPTER, nous vous recommandons de stocker des pointeurs vers chaque adaptateur dans le contexte de votre appareil.

  3. Créez l’objet NETADAPTER. Pour ce faire, le client appelle NetAdapterInitAllocate, suivi des méthodes Facultatives NetAdapterInitSetXxx pour initailiser les attributs de l’adaptateur. Enfin, le client appelle NetAdapterCreate.

    L’exemple suivant montre comment un pilote client peut initialiser un objet NETADAPTER. Notez que la gestion des erreurs est simplifiée dans cet exemple.

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

Si vous le souhaitez, vous pouvez ajouter de l’espace contextuel à l’objet NETADAPTER. Étant donné que vous pouvez définir un contexte sur n’importe quel objet WDF, vous pouvez ajouter un espace de contexte distinct pour les objets WDFDEVICE et NETADAPTER. Dans l’exemple de l’étape 3, le client ajoute MY_ADAPTER_CONTEXT à l’objet NETADAPTER. Pour plus d’informations, consultez Framework Object Context Space.

Nous vous recommandons de placer les données relatives aux appareils dans le contexte de votre WDFDEVICE et les données liées au réseau, telles que les adresses de la couche de liaison, dans votre contexte NETADAPTER. Si vous portez un pilote NDIS 6.x existant, vous disposez probablement d’un seul MiniportAdapterContext qui combine les données liées au réseau et aux appareils en une seule structure de données. Pour simplifier le processus de portage, il suffit de convertir cette structure entière en contexte WDFDEVICE et de faire du contexte de NETADAPTER une petite structure qui pointe vers le contexte de WDFDEVICE.

Vous pouvez éventuellement fournir 2 rappels à la méthode NET_ADAPTER_DATAPATH_CALLBACKS_INIT :

Pour plus d’informations sur les éléments à fournir dans vos implémentations de ces rappels, consultez les pages de référence individuelles.

EVT_WDF_DEVICE_PREPARE_HARDWARE

De nombreux pilotes clients NetAdapterCx démarrent leurs adaptateurs à partir de leur fonction de rappel EVT_WDF_DEVICE_PREPARE_HARDWARE , à l’exception notable des pilotes clients d’extension de classe Haut débit mobile. Pour inscrire une fonction de rappel EVT_WDF_DEVICE_PREPARE_HARDWARE , un pilote client NetAdapterCx doit appeler WdfDeviceInitSetPnpPowerEventCallbacks.

Dans EVT_WDF_DEVICE_PREPARE_HARDWARE, en plus d’autres tâches de préparation matérielle, le pilote client définit les fonctionnalités requises et facultatives de l’adaptateur.

NetAdapterCx nécessite que le pilote client définisse les fonctionnalités suivantes :

Le pilote doit ensuite appeler NetAdapterStart pour démarrer son adaptateur.

L’exemple suivant montre comment un pilote client peut démarrer un objet NETADAPTER. Notez que le code requis pour configurer chaque méthode de fonctionnalités d’adaptateur est omis par souci de concision et de clarté, et que la gestion des erreurs est simplifiée.

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