Partager via


Allocation et Construction des URBs

Un pilote client USB peut utiliser les routines de pilote du modèle de pilote Windows (WDM) pour allouer et formater un URB avant d’envoyer la requête à la pile de pilotes USB fournie par Microsoft.

Le pilote client utilise un URB pour encapsuler toutes les informations requises par les pilotes inférieurs dans la pile de pilotes USB pour traiter la requête. Dans le système d’exploitation Windows, un URB est décrit dans une structure URB.

Microsoft fournit une bibliothèque de Routines pour les pilotes clients USB. En utilisant ces routines, les pilotes clients USB peuvent construire des requêtes URB pour certaines opérations spécifiées et les transmettre vers le bas de la pile USB. Si vous le préférez, vous pouvez concevoir votre pilote client pour appeler les routines de bibliothèque pour les opérations prises en charge plutôt que de construire vos propres requêtes URB.

Allocation d’URB dans Windows 7 et versions antérieures

Pour envoyer une requête USB en utilisant les routines incluses dans le Kit de pilotes Windows (WDK) pour Windows 7 et les versions antérieures de Windows, un pilote client alloue généralement et remplit une structure URB, associe la structure URB à un nouvel IRP et envoie l’IRP à la pile de pilotes USB.

Pour certains types de requêtes, Microsoft fournit des routines d’assistance (exportées par Usbd.sys) qui allouent et formatent la structure URB. Par exemple, la routine USBD_CreateConfigurationRequestEx alloue de la mémoire pour une structure URB, formate l’URB pour une requête de sélection de configuration et renvoie l’adresse de la structure URB au pilote client. Cependant, les routines d’assistance ne peuvent pas être utilisées pour tous les types de requêtes.

Microsoft fournit également des macros qui formatent les URBs pour certains types de requêtes. Pour ces macros, le pilote client doit allouer la structure URB en appelant ExAllocatePoolWithTag ou allouer la structure sur la pile. Par exemple, après que le pilote client a alloué un URB, le pilote peut appeler UsbBuildSelectConfigurationRequest pour formater l’URB pour une requête de sélection de configuration ou pour effacer la configuration.

Pour d’autres requêtes, le pilote client doit allouer et formater l’URB manuellement en définissant divers membres de la structure URB, en fonction du type de requête.

Lorsqu’une requête USB est terminée, le pilote client doit libérer la structure URB. Si l’URB est alloué sur la pile, l’URB est libéré lorsqu’il sort de la portée. Si l’URB est alloué dans un pool non paginé, le pilote client doit appeler ExFreePool pour libérer l’URB.

Allocation d’URB dans Windows 8

Le WDK pour Windows 8 fournit une nouvelle bibliothèque statique, Usbdex.lib, qui exporte des routines pour allouer, formater et libérer des URBs. De plus, il existe une nouvelle façon d’associer un URB à un IRP. Les nouvelles routines peuvent être appelées par un pilote client ciblant Windows Vista et les versions ultérieures de Windows.

Un pilote client fonctionnant sur Windows Vista et les versions ultérieures doit utiliser les nouvelles routines pour que la pile de pilotes USB sous-jacente puisse utiliser certaines améliorations de performance et de fiabilité. Ces améliorations s’appliquent à la nouvelle pile de pilotes USB introduite dans Windows 8 pour prendre en charge les dispositifs et les contrôleurs hôtes USB 3.0. Pour les contrôleurs hôtes USB 2.0, Windows charge une version antérieure de la pile de pilotes qui ne prend pas en charge les améliorations. Quel que soit la version de la pile de pilotes sous-jacente ou la version du protocole prise en charge par le contrôleur hôte, vous devez toujours appeler les nouvelles routines URB.

Avant d’appeler l’une des nouvelles routines, assurez-vous d’avoir un handle USBD pour l’enregistrement de votre pilote client avec la pile de pilotes USB. Pour obtenir un handle USBD, appelez USBD_CreateHandle.

Les routines suivantes sont disponibles avec le WDK pour Windows 8. Ces routines sont définies dans Usbdlib.h.

Les routines d’allocation de la liste précédente renvoient un pointeur vers une nouvelle structure URB, qui est allouée par la pile de pilotes USB. Selon la version de la pile de pilotes USB chargée par Windows, la structure URB peut être associée à un contexte URB opaque. Un contexte URB est un bloc d’informations sur l’URB. Vous ne pouvez pas voir le contenu de l’en-tête URB ; les informations sont destinées à être utilisées en interne par la pile de pilotes USB pour améliorer le suivi et le traitement des URBs. Le contexte URB est uniquement utilisé par la pile de pilotes USB pour Windows 8. Si le contexte URB est disponible, la pile de pilotes USB l’utilise pour rendre le traitement des URBs plus sûr et plus efficace. Par exemple, la pile de pilotes USB doit s’assurer que le pilote client ne soumet pas un URB puis tente de réutiliser ce même URB avant que la première requête ne soit terminée. Pour détecter ce type d’erreur, la pile de pilotes USB stocke des informations d’état dans le contexte URB. Sans les informations d’état, la pile de pilotes USB devrait comparer l’URB entrant avec tous les URBs actuellement en cours. Les informations d’état sont également utilisées par la pile de pilotes USB lorsque le pilote client tente de libérer l’URB. Avant de libérer l’URB, la pile de pilotes USB vérifie l’état pour s’assurer que l’URB n’est pas en attente.

Le contexte URB fournit un mécanisme officiel pour stocker des informations supplémentaires sur l’URB. L’utilisation du contexte URB est préférable à l’allocation de mémoire supplémentaire au besoin ou au stockage d’informations supplémentaires dans les membres réservés de la structure URB. La pile de pilotes USB alloue les URBs et leurs contextes URB associés dans un pool non paginé, de sorte que si des contextes URB plus grands sont nécessaires à l’avenir, le seul ajustement requis sera la taille d’une allocation de pool.

Migration des Routines URB

Le tableau suivant résume les changements dans les routines URB.

Cas d’usage Disponible dans WDK pour Windows 7 et versions antérieures Disponible dans WDK pour Windows 8 et versions ultérieures
  Cible Windows 7 et versions antérieures du système d’exploitation Cible Windows 8 et versions ultérieures du système d’exploitation
Pour créer un URB... Le pilote client alloue une structure URB et formate la structure en fonction de la requête.

Le pilote client alloue la structure URB sur la pile ou alloue la structure dans un pool non paginé en appelant ExAllocatePoolWithTag.
Le pilote client appelle USBD_UrbAllocate et reçoit un pointeur vers la nouvelle structure URB, qui est allouée par la pile de pilotes USB. L’URB peut être associée à un contexte URB, en fonction de la version de l’interface USBD de la pile de pilotes USB sous-jacente.
Pour créer un URB pour une requête de sélection de configuration... Le pilote client appelle la routine USBD_CreateConfigurationRequestEx qui renvoie un pointeur vers le nouvel URB créé et formaté par la pile de pilotes USB. Le pilote client appelle USBD_SelectConfigUrbAllocateAndBuild et reçoit un pointeur vers la nouvelle structure URB, qui est allouée et formatée (pour la requête de sélection de configuration) par la pile de pilotes USB. L’URB peut être associée à un contexte URB, en fonction de la version de l’interface USBD de la pile de pilotes USB sous-jacente.
Pour créer un URB pour une requête de sélection d’interface... Le pilote client alloue une structure URB et utilise la structure _URB_SELECT_INTERFACE pour définir le format d’une commande de sélection d’interface pour un dispositif USB. Le pilote client appelle USBD_SelectInterfaceUrbAllocateAndBuild et reçoit un pointeur vers la nouvelle structure URB, qui est allouée et formatée (pour la requête de sélection d’interface) par la pile de pilotes USB. L’URB peut être associée à un contexte URB, en fonction de la version de l’interface USBD de la pile de pilotes USB sous-jacente.
Pour associer un URB à un IRP... Le pilote client obtient un pointeur vers la prochaine localisation de pile IRP en appelant IoGetNextIrpStackLocation. Ensuite, le pilote client définit manuellement le membre Parameters.Others.Argument1 de la localisation de pile sur l’adresse de la structure URB. Le pilote client obtient un pointeur vers la prochaine localisation de pile IRP en appelant IoGetNextIrpStackLocation. Ensuite, le pilote client appelle USBD_AssignUrbToIoStackLocation pour associer l’URB à la localisation de pile.
Pour libérer un URB... Si le pilote client alloue un URB sur la pile, la variable sort de la portée après que la requête est terminée.

Pour libérer une structure URB que le pilote client ou la pile de pilotes USB a allouée dans un pool non paginé, le pilote client appelle ExFreePool.
Le pilote client appelle USBD_UrbFree.