Partager via


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 sous-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 / Astuce

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

  3. Créez l’objet NETADAPTER. Pour ce faire, le client appelle NetAdapterInitAllocate, suivi de méthodes NetAdapterInitSetXxx facultatives pour initialiser 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 de contexte à 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 l’espace de contexte de l’objet Framework.

Nous vous recommandons de placer des données liées à l’appareil dans le contexte de votre WDFDEVICE et des données liées à la mise en réseau, telles que les adresses de couche de liaison dans votre contexte NETADAPTER. Si vous transférez un pilote NDIS 6.x existant, vous disposez probablement d’un seul MiniportAdapterContext qui combine les données liées à la mise en réseau et liées à l’appareil dans une seule structure de données. Pour simplifier le processus de portage, convertissez simplement cette structure entière en contexte WDFDEVICE et faites 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 les capacités de chaque adaptateur est omis pour des raisons 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;
}