Énumération dynamique

L’énumération dynamique est la capacité d’un pilote à détecter et à signaler les modifications apportées au nombre et au type d’appareils connectés au système pendant l’exécution du système.

Les pilotes de bus doivent utiliser l’énumération dynamique si le nombre ou les types d’appareils connectés à l’appareil parent dépendent de la configuration d’un système. Certains de ces appareils peuvent être toujours connectés au système, et d’autres peuvent être branchés et débranchés pendant que le système est en cours d’exécution.

Par exemple, le nombre et le type d’appareils connectés au bus PCI d’un système dépendent du système, mais ils sont permanents, sauf si un utilisateur éteint l’alimentation, ouvre le boîtier et ajoute ou supprime un appareil à l’aide d’un tournevis. D’autre part, un utilisateur peut ajouter ou supprimer des périphériques USB en branchant ou en débranchant un câble pendant que le système est en cours d’exécution.

Listes enfants dynamiques

L’infrastructure permet aux pilotes de prendre en charge l’énumération dynamique en fournissant des objets de liste enfant de framework. Chaque objet de liste enfant représente une liste d’appareils enfants connectés à un appareil parent. Le pilote de bus de l’appareil parent doit identifier les appareils enfants du parent, les ajouter à la liste enfant de l’appareil parent et créer un objet d’appareil physique (PDO) pour chaque enfant.

Chaque fois qu’un pilote crée un objet d’appareil framework qui représente un FDO pour un appareil, l’infrastructure crée une liste enfant par défaut vide pour l’appareil. Votre pilote peut obtenir un handle pour la liste enfant par défaut d’un appareil en appelant WdfFdoGetDefaultChildList. En règle générale, si vous écrivez un pilote de bus qui énumère les enfants d’un appareil, votre pilote peut ajouter des enfants à la liste enfant par défaut. Si vous devez créer des listes enfants supplémentaires, votre pilote peut appeler WdfChildListCreate.

Avant qu’un pilote puisse utiliser une liste enfant, il doit configurer l’objet de liste enfant en initialisant une structure WDF_CHILD_LIST_CONFIG et en transmettant la structure à WdfFdoInitSetDefaultChildListConfig, pour la liste enfant par défaut, ou à WdfChildListCreate, pour les listes enfants supplémentaires.

Descriptions enfants dynamiques

Chaque fois qu’un pilote de bus identifie un appareil enfant, il doit ajouter la description de l’appareil enfant à une liste enfant. Une description enfant se compose d’une description d’identification requise et d’une description d’adresse facultative.

Description de l’identification Une description d’identification est une structure qui contient des informations qui identifient de manière unique chaque appareil énuméré par le pilote. Le pilote définit cette structure, mais son premier membre doit être une structure WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER .

En règle générale, une description d’identification contient les chaînes d’identification d’un appareil, éventuellement un numéro de série et des informations sur l’emplacement de l’appareil dans le bus, telles qu’un numéro d’emplacement.

Le pilote peut fournir l’ensemble suivant de fonctions de rappel, qui permettent à l’infrastructure de manipuler les informations dans une description d’identification :

En règle générale, vous devez fournir ces fonctions de rappel si les structures de description d’identification de votre pilote contiennent des pointeurs vers des mémoires tampons allouées dynamiquement. Pour plus d’informations sur l’objectif de ces fonctions de rappel, consultez leurs pages de référence.

Description de l’adresse Une description d’adresse est une structure qui contient les informations dont le pilote a besoin pour qu’il puisse accéder à l’appareil sur son bus, si les informations peuvent changer pendant que l’appareil est branché. Le pilote définit cette structure, mais son premier membre doit être une structure WDF_CHILD_ADDRESS_DESCRIPTION_HEADER .

Les descriptions d’adresses sont facultatives. Si les informations d’adresse d’un appareil ne peuvent pas changer entre le moment où l’appareil est branché et le moment où il est débranché, toutes les informations d’adresse de l’appareil peuvent être stockées dans une description d’identification. Par exemple, les contrôleurs USB attribuent des adresses aux appareils lorsque les appareils sont branchés, et ces adresses ne changent pas.

D’autre part, certains bus utilisent des informations d’adressage qui peuvent changer. Par exemple, le bus IEEE 1394 utilise un « nombre de génération », qui correspond au nombre de réinitialisations de bus qui se sont produites. Chaque demande d’E/S asynchrone sur un appareil IEEE 1394 doit inclure le nombre de génération. Étant donné que ces informations d’adresse peuvent changer, votre pilote doit les stocker dans une description d’adresse.

Le pilote peut fournir l’ensemble suivant de fonctions de rappel pour manipuler les informations d’une description d’adresse :

En règle générale, vous devez fournir ces fonctions de rappel si les structures de description d’adresse de votre pilote contiennent des pointeurs vers des mémoires tampons allouées dynamiquement. Pour plus d’informations sur l’objectif de ces fonctions de rappel, consultez leurs pages de référence.

Ajout d’appareils à une liste enfant dynamique

Lorsque l’infrastructure appelle la fonction de rappel EvtDriverDeviceAdd d’un pilote de bus, la fonction de rappel doit appeler WdfDeviceCreate pour créer un FDO pour l’appareil parent, qui est généralement un adaptateur de bus. Pour plus d’informations sur la création d’un FDO, consultez Création d’objets d’appareil dans un pilote de fonction. Le pilote doit ensuite énumérer les enfants de l’appareil parent et ajouter les enfants à une liste enfant.

Si vous le souhaitez, le pilote peut appeler WdfDeviceSetBusInformationForChildren pour fournir à l’infrastructure des informations sur le bus. Cette opération est recommandée, car elle permet aux appareils et applications enfants d’identifier plus facilement le bus.

Pour ajouter des enfants à une liste enfant, le pilote doit appeler WdfChildListAddOrUpdateChildDescriptionAsPresent pour chaque appareil enfant qu’il trouve. Cet appel informe l’infrastructure qu’un pilote a découvert un appareil enfant connecté à un appareil parent. Lorsque votre pilote appelle WdfChildListAddOrUpdateChildDescriptionAsPresent, il fournit une description d’identification et, éventuellement, une description d’adresse.

Une fois que le pilote a appelé WdfChildListAddOrUpdateChildDescriptionAsPresent pour signaler un nouvel appareil, l’infrastructure informe le gestionnaire PnP que le nouvel appareil existe. Le gestionnaire PnP génère ensuite une pile d’appareils et une pile de pilotes pour le nouvel appareil. Dans le cadre de ce processus, l’infrastructure appelle la fonction de rappel EvtChildListCreateDevice du pilote de bus. Cette fonction de rappel doit appeler WdfDeviceCreate pour créer un PDO pour le nouvel appareil.

En règle générale, plusieurs appareils enfants étant connectés à un parent, le pilote de bus doit appeler WdfChildListAddOrUpdateChildDescriptionAsPresent plusieurs fois. La façon la plus efficace d’effectuer cette opération est la suivante :

  1. Appelez WdfChildListBeginScan.

  2. Appelez WdfChildListAddOrUpdateChildDescriptionAsPresent pour chaque appareil enfant.

  3. Appelez WdfChildListEndScan.

Si vous entourez l’énumération dynamique de votre pilote d’appels à WdfChildListBeginScan et WdfChildListEndScan, le framework stocke toutes les modifications apportées à la liste enfant et avertit le gestionnaire PnP des modifications lorsque le pilote appelle WdfChildListEndScan. À un moment ultérieur, l’infrastructure appelle la fonction de rappel EvtChildListCreateDevice du pilote de bus pour chaque appareil de la liste enfant. Cette fonction de rappel appelle WdfDeviceCreate pour créer un PDO pour chaque nouvel appareil.

Lorsque votre pilote appelle WdfChildListBeginScan, l’infrastructure marque tous les appareils précédemment signalés comme étant absents. Par conséquent, le pilote doit appeler WdfChildListAddOrUpdateChildDescriptionAsPresent pour tous les enfants que le pilote peut détecter, et pas seulement pour les enfants nouvellement découverts. Pour ajouter un seul enfant à une liste enfant, le pilote peut effectuer un seul appel à WdfChildListUpdateAllChildDescriptionsAsPresent sans appeler D’abord WdfChildListBeginScan.

Mise à jour d’une liste enfant dynamique

Il existe deux façons courantes de mettre à jour les informations dans une liste enfant dynamique :

  1. Lorsqu’un appareil parent reçoit une interruption indiquant l’arrivée ou la suppression d’un enfant, la fonction de rappel EvtInterruptDpc du pilote appelle WdfChildListAddOrUpdateChildDescriptionAsPresent si un appareil a été branché ou WdfChildListUpdateChildDescriptionAsMissing si un appareil a été débranché.

  2. Le pilote peut fournir une fonction de rappel EvtChildListScanForChildren , que l’infrastructure appelle chaque fois que l’appareil parent entre dans son état de fonctionnement (D0). Cette fonction de rappel doit énumérer tous les appareils enfants en appelant WdfChildListBeginScan, WdfChildListAddOrUpdateChildDescriptionAsPresent (ou WdfChildListUpdateAllChildDescriptionsAsPresent) et WdfChildListEndScan.

Vous pouvez utiliser l’une de ces techniques ou les deux dans votre pilote.

Parcourir une liste enfant dynamique

Si vous souhaitez que votre pilote examine le contenu d’une liste enfant, il peut parcourir la liste à l’aide de l’une des techniques suivantes :

  • Pour obtenir le contenu de chaque description d’appareil enfant, une par une, le pilote peut :

    1. Appelez WdfChildListBeginIteration.
    2. Appelez WdfChildListRetrieveNextDevice, autant de fois que nécessaire.
    3. Appelez WdfChildListEndIteration.

    Lors de l’appel de WdfChildListBeginIteration, le pilote spécifie un indicateur de type WDF_RETRIEVE_CHILD_FLAGS qui indique si l’infrastructure doit récupérer toutes les descriptions d’appareil ou uniquement un sous-ensemble. Lorsque WdfChildListRetrieveNextDevice trouve une correspondance, il récupère l’identification et les descriptions d’adresse de l’appareil enfant, ainsi qu’un handle à son objet d’appareil.

  • Si vous devez obtenir la description d’adresse qui est actuellement contenue dans une description d’appareil enfant, votre pilote peut appeler WdfChildListRetrieveAddressDescription, en spécifiant une description d’identification. L’infrastructure traverse la liste enfant jusqu’à ce qu’elle trouve un appareil enfant avec une description d’identification correspondante, puis récupère la description de l’adresse.

  • Si vous avez besoin d’obtenir un handle pour l’objet d’appareil framework associé à un appareil enfant particulier, votre pilote peut appeler WdfChildListRetrievePdo. L’infrastructure traverse la liste enfant jusqu’à trouver un appareil enfant avec une description d’identification correspondante, puis retourne un handle d’objet d’appareil. Veillez à encapsuler l’appel avec WdfChildListBeginIteration et WdfChildListEndIteration pour protéger l’appelant contre la suppression soudaine de PnP de l’AOP sur un autre thread.

Accès aux descriptions d’identification et d’adresse d’un PDO

Votre pilote peut appeler les méthodes suivantes pour accéder à la description d’identification ou à l’adresse d’un AOP :

Gestion des demandes de réinentre énumération

Les pilotes de bus basés sur l’infrastructure qui prennent en charge l’énumération dynamique peuvent recevoir une demande d’énumération d’un appareil enfant particulier via l’interface REENUMERATE_SELF_INTERFACE_STANDARD . Pour plus d’informations, consultez Gestion des demandes d’énumération