Allocation et création d’URBs

Un pilote client USB peut utiliser des routines de pilotes WDM (Windows Driver Model) pour allouer et mettre en forme un URB avant d’envoyer la demande à la pile de pilotes USB fournie par Microsoft.

Le pilote client utilise un URB pour empaqueter toutes les informations requises par les pilotes inférieurs dans la pile de pilotes USB pour traiter la demande. 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 générer des requêtes URB pour certaines opérations spécifiées et les transférer vers le bas de la pile USB. Si vous préférez, vous pouvez concevoir votre pilote client pour appeler les routines de bibliothèque pour les opérations prises en charge au lieu de créer vos propres requêtes URB.

Allocation URB dans Windows 7 et versions antérieures

Pour envoyer une requête USB à l’aide de routines incluses dans le Kit de pilotes Windows (WDK) pour Windows 7 et les versions antérieures de Windows, un pilote client alloue et remplit généralement une structure URB , associe la structure URB à une nouvelle IRP et envoie l’IRP à la pile des 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 , la met en forme pour une demande de configuration de sélection et retourne l’adresse de la structure URB au pilote client. Toutefois, les routines d’assistance ne peuvent pas être utilisées pour tous les types de demandes.

Microsoft fournit également des macros qui mettez en forme des URB pour certains types de demandes. Pour ces macros, le pilote client doit allouer la structure URB en appelant ExAllocatePoolWithTag ou allouer la structure sur la pile. Par exemple, une fois que le pilote client alloue un URB, le pilote peut appeler UsbBuildSelectConfigurationRequest pour mettre en forme l’URB pour une demande de configuration de sélection ou pour effacer la configuration.

Pour les autres requêtes, le pilote client doit allouer et mettre en forme l’URB manuellement en définissant différents 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 l’étendue. Si l’URB est alloué dans un pool non paginé, le pilote client doit appeler ExFreePool pour libérer l’URB.

Allocation URB dans Windows 8

WDK pour Windows 8 fournit une nouvelle bibliothèque statique, Usbdex.lib, qui exporte des routines pour l’allocation, la mise en forme et la publication d’URIB. En outre, 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 s’exécutant sur Windows Vista et versions ultérieures doit utiliser les nouvelles routines afin que la pile de pilotes USB sous-jacente puisse utiliser certaines améliorations en matière de performances et de fiabilité. Ces améliorations s’appliquent à la nouvelle pile de pilotes USB introduite dans Windows 8 pour prendre en charge les périphériques USB 3.0 et les contrôleurs hôtes. 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. Quelle que soit la version de la pile de pilotes sous-jacente ou la version de 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 que vous disposez d’une poignée USBD pour l’inscription du pilote client auprès de la pile de pilotes USB. Pour obtenir un handle USBD, appelez USBD_CreateHandle.

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

Les routines d’allocation dans la liste précédente retournent 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 afficher 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 URB. Le contexte URB est utilisé uniquement 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 URB plus sûr et plus efficace. Par exemple, la pile de pilotes USB doit s’assurer que le pilote client n’envoie pas d’URB, puis tenter de réutiliser ce même URB avant la première requête. Pour détecter ce type d’erreur, la pile de pilotes USB stocke les informations d’état dans le contexte URB. Sans les informations d’état, la pile de pilotes USB devrait comparer l’URB entrant à tous les URB 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 URB supplémentaires. L’utilisation du contexte URB est préférable à l’allocation de mémoire supplémentaire en fonction des besoins ou au stockage d’informations supplémentaires dans les membres réservés de la structure URB . La pile de pilotes USB alloue des URB et leur contexte URB associé dans un pool non paginé, de sorte qu’à l’avenir, si un contexte URB plus important est nécessaire, le seul ajustement requis sera la taille d’une allocation de pool.

URB Routine Migration

Le tableau suivant récapitule les modifications apportées aux routines URB.

Cas d’utilisation 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 met en forme la structure en fonction de la requête.

Le pilote client alloue la structure URB sur la pile, ou le pilote 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é à un contexte URB, en fonction de la version d’interface USBD de la pile de pilotes USB sous-jacente.
Pour créer un URB pour une demande de sélection de configuration... Le pilote client appelle la routine USBD_CreateConfigurationRequestEx qui retourne un pointeur vers le nouveau URB créé et mis en forme 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 mise en forme (pour la demande de configuration de sélection) par la pile de pilotes USB. L’URB peut être associé à un contexte URB, en fonction de la version d’interface USBD de la pile de pilotes USB sous-jacente.
Pour créer un URB pour une demande d’interface de sélection... Le pilote client alloue une structure URB et utilise la structure _URB_SELECT_INTERFACE pour définir le format d’une commande d’interface select pour un périphérique USB. Le pilote client appelle USBD_SelectInterfaceUrbAllocateAndBuild et reçoit un pointeur vers la nouvelle structure URB , qui est allouée et mise en forme (pour la demande d’interface de sélection) par la pile de pilotes USB. L’URB peut être associé à un contexte URB, en fonction de la version d’interface USBD de la pile de pilotes USB sous-jacente.
Pour associer un URB à un IRP... Le pilote client obtient un pointeur vers l’emplacement de pile IRP suivant en appelant IoGetNextIrpStackLocation. Ensuite, le pilote client définit manuellement le membre Parameters.Others.Argument1 de l’emplacement de la pile sur l’adresse de la structure URB . Le pilote client obtient un pointeur vers l’emplacement de pile IRP suivant en appelant IoGetNextIrpStackLocation. Ensuite, le pilote client appelle USBD_AssignUrbToIoStackLocation pour associer un URB à l’emplacement de la pile.
Pour libérer un URB... Si le pilote client alloue un URB sur la pile, la variable sort de l’étendue une fois la demande terminée.

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