Partager via


Initialisation de l’appareil et de l’adaptateur

Cette rubrique décrit les étapes pour qu’un pilote client NetAdapterCx initialise et démarre les objets WDFDEVICE et NETADAPTER. Pour plus d’informations sur ces objets et leur relation, veuillez consulter la section Résumé des objets NetAdapterCx.

EVT_WDF_DRIVER_DEVICE_ADD

Un pilote client NetAdapterCx enregistre sa fonction de rappel EVT_WDF_DRIVER_DEVICE_ADD lorsqu’il appelle WdfDriverCreate depuis sa routine DriverEntry.

Dans EVT_WDF_DRIVER_DEVICE_ADD, un pilote client NetAdapterCx doit faire ce qui suit dans l’ordre :

  1. Appeler NetDeviceInitConfig.

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

    Conseil

    Si votre appareil prend en charge plus d’un NETADAPTER, nous recommandons de stocker des pointeurs vers chaque adaptateur dans le contexte de votre appareil.

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

    L’exemple suivant montre comment un pilote client pourrait 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);
    ...
    

Optionnellement, vous pouvez ajouter un espace de contexte à l’objet NETADAPTER. Étant donné que vous pouvez définir un contexte sur n’importe quel objet WDF, vous pourriez ajouter un espace de contexte séparé 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, veuillez consulter la section Espaces de contexte d’objet Framework.

Nous recommandons de mettre les données liées à l’appareil 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 aurez probablement un MiniportAdapterContext unique qui combine les données liées au réseau et à l’appareil en une seule structure de données. Pour simplifier le processus de portage, convertissez simplement toute cette structure en contexte WDFDEVICE et faites du contexte de NETADAPTER une petite structure qui pointe vers le contexte de WDFDEVICE.

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

Pour plus de détails sur ce qu’il faut 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 depuis leur fonction de rappel EVT_WDF_DEVICE_PREPARE_HARDWARE, à l’exception notable des pilotes clients de l’extension de classe Mobile Broadband. Pour enregistrer 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 capacités requises et optionnelles de l’adaptateur.

NetAdapterCx exige que le pilote client définisse les capacités suivantes :

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

L’exemple suivant montre comment un pilote client pourrait démarrer un objet NETADAPTER. Notez que le code requis pour configurer chaque méthode de capacités de l’adaptateur est omis pour plus de concision et de clarté, et 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;
}