Partager via


Étude de cas : Résolution des problèmes d’un périphérique USB inconnu à l’aide d’ETW et de Netmon

Cette rubrique fournit un exemple d’utilisation d’ETW USB et de Netmon pour résoudre les problèmes d’un périphérique USB que Windows ne reconnaît pas.

Pour cet exemple, nous avons branché un appareil qui est apparu comme un appareil inconnu dans Gestionnaire de périphériques et d’autres parties de l’interface utilisateur. L’ID matériel était USB\UNKNOWN. Pour diagnostiquer davantage, nous avons débranché l’appareil, commencé une trace ETW et branché à nouveau l’appareil. Une fois que l’appareil est apparu en tant qu’appareil inconnu, nous avons arrêté la trace.

À propos du problème d’appareil inconnu

Pour déboguer un problème de périphérique USB inconnu, il est utile de comprendre ce que la pile de pilotes USB fait pour énumérer un appareil lorsqu’un utilisateur le connecte au système. Pour plus d’informations sur l’énumération USB, consultez le billet de blog intitulé Comment la pile USB énumère-t-elle un appareil ?

En règle générale, lorsque la pile de pilotes USB ne parvient pas à énumérer un appareil, le pilote hub signale toujours l’arrivée de l’appareil sur Windows et le périphérique USB est marqué comme un appareil inconnu dans Gestionnaire de périphériques. L’appareil a un ID d’appareil USB\VID_0000&PID_0000 et un ID matériel et un ID compatible USB\UNKNOWN. Les événements suivants amènent le pilote du hub USB à énumérer un périphérique USB en tant qu’appareil inconnu :

  • Une demande de réinitialisation de port a expiré pendant l’énumération.
  • Échec de la demande Définir l’adresse pour le périphérique USB.
  • La demande de descripteur de périphérique du périphérique USB a échoué.
  • Le descripteur de périphérique USB a été mal formé et la validation a échoué.
  • La demande pour le descripteur de configuration a échoué.
  • Le descripteur de configuration USB a été mal formé et la validation a échoué.

Dans Windows 7, les appareils inconnus qui échouent à l’énumération sont marqués avec le code d’échec 43 dans Gestionnaire de périphériques.

Si un appareil est marqué avec le code d’échec 28 dans Gestionnaire de périphériques, l’appareil a été correctement énuméré, mais est toujours un appareil inconnu. Ce code d’échec indique que l’appareil n’a pas fourni de chaîne d’ID de produit pendant l’énumération et que Windows n’a pas trouvé d’INF correspondant pour que l’appareil installe un pilote.

Démarrage de l’analyse des traces d’événements

Étant donné qu’il s’agit d’une défaillance d’appareil, nous vous recommandons d’utiliser Netmon avec l’analyseur USB pour analyser le fichier journal.

Pour afficher le journal de suivi des événements

  1. Exécutez Netmon, cliquez sur Fichier -> Ouvrir -> Capture, puis sélectionnez le fichier.

  2. Sélectionnez le premier événement dans le volet Résumé du cadre , qui a la description SystemTrace. Cette image montre à quoi ressemble l’écran lorsque vous sélectionnez le premier événement.

    Capture d’écran montrant la fenêtre « Microsoft Network Monitor » après avoir sélectionné le premier événement.

  3. Pour personnaliser les colonnes affichées par Netmon, cliquez avec le bouton droit sur un nom de colonne et sélectionnez Choisir des colonnes.

  4. Le premier événement, qui est identifié comme de type SystemTrace, contient des informations générales sur le journal. Vous pouvez développer l’arborescence d’informations dans le volet Détails du cadre pour afficher des informations telles que le nombre d’événements perdus et l’heure de début de la trace.

Événements de résumé des périphériques USB

L’événement 2 est le premier événement USB dans le journal. Cet événement et plusieurs événements suivants décrivent les contrôleurs hôtes USB, les hubs et les appareils qui étaient connectés au système lorsque nous avons démarré la trace. Nous pouvons appeler ce groupe d’événements les événements récapitulatives de l’appareil, ou simplement les événements récapitulatives. Comme pour le premier événement, les événements récapitulatives ne décrivent pas l’activité du pilote. Les événements récapitulatives enregistrent l’état des appareils au début d’une session de journalisation. D’autres événements représentent un événement qui se produit sur le bus, des interactions avec les pilotes du client ou le système, ou des changements d’état interne.

Le hub USB et le port USB pilotent tous deux les événements de résumé des journaux. Le pilote qui a enregistré un événement est identifié dans la colonne Nom du protocole. Par exemple, un événement enregistré par le pilote de port USB a le nom de protocole USBPort_MicrosoftWindowsUSBPORT. Une trace d’événements USB contient généralement une séquence d’événements récapitulatives de port, suivie d’une séquence d’événements récapitulatives du hub. La plupart des événements de synthèse du port USB et du hub USB ont les mots « Information » ou « Attributs » dans leur description.

Comment pouvez-vous identifier la fin des événements récapitulatives ? S’il y a une interruption significative du modèle d’horodatage parmi les événements du hub USB au début du journal, cette interruption est probablement la fin du résumé de l’appareil. Sinon, le premier événement de port USB après les événements de hub USB est probablement le premier événement non récapitulatif. La figure 3 de la page suivante montre le premier événement non récapitulative de cet exemple de trace.

Dans cet exemple, l’appareil concerné n’était pas connecté au système lorsque nous avons démarré la trace. Vous pouvez donc ignorer les événements de résumé de l’appareil pour l’instant.

Capture d’écran montrant un appareil d’intérêt sélectionné dans le « Résumé de l’image » qui n’était pas connecté au démarrage de la trace.

Description de l’événement et charge utile des données

Dans l’exemple de journal, le premier événement après les événements récapitulatives de l’appareil est un événement IRP d’attente du hub USB terminé. Nous avons branché un appareil, et un contrôleur hôte ou un hub se réveille en réponse. Pour déterminer le composant qui se réveille, examinez les données de l’événement. Les données se trouve dans le volet Détails de l’image, qui s’affiche dans une arborescence sous la forme suivante environ :

Frame information
ETW event header information
    ETW event descriptor (Constant information about the event ID such
    as error level)
Event payload (Data logged at the time of the event)
    Name of a USB-specific structure
        Structure members and their values (Types: numbers, strings,
        or arrays)
    ...

Développez les données de charge utile pour l’événement IRP d’attente du hub USB terminé, et vous verrez une structure ETW nommée fid_USBHUB_Hub. Le nom de la structure comporte les composants suivants :

Terme Description
Fid_ Préfixe classique pour une structure ETW USB.
USBHUB_ Indique que le pilote du hub USB a enregistré l’événement.
Le reste de la chaîne Nom de l’objet décrit par les données de la structure. Pour cet événement, il s’agit d’un objet Hub.

Le pilote de hub USB utilise la structure fid_USBHUB_Hub pour décrire un hub USB. Les événements qui ont cette structure hub dans leur charge utile de données font référence à un hub, et nous pouvons identifier le hub spécifique à l’aide du contenu de la structure. La figure 4 montre le volet Détails du cadre, avec la structure fid_USBHUB_Hub développée pour afficher ses champs.

moniteur réseau microsoft - détails de l’image.

La structure du hub est très similaire à deux autres structures qui apparaissent généralement dans les événements ETW USB : fid_USBHUB_Device et fid_USBPORT_Device. Les champs importants suivants sont communs aux trois structures :

Champ Description
fid_idVendor ID de fournisseur USB (VID) de l’appareil
fid_idProduct ID de produit USB (PID) de l’appareil
fid_PortPath Liste des numéros de port hub à base unique via lesquels un périphérique USB est attaché. Le nombre de numéros de port dans la liste est contenu dans le champ PortPathDepth . Pour les appareils hub racine, cette liste correspond à tous les zéros. Pour un périphérique USB connecté directement à un port hub racine, la valeur dans PortPath[0] est le numéro de port hub racine du port auquel l’appareil est attaché.

Pour un périphérique USB connecté via un ou plusieurs hubs USB supplémentaires, la liste des numéros de port du hub commence par le port hub racine et se poursuit avec les hubs supplémentaires (par ordre de distance par rapport au hub racine). Ignorez les zéros. Par exemple :

Exemple de valeur Description
[0, 0, 0, 0, 0, 0] L’événement fait référence à un hub racine (un port sur le PC, directement contrôlé par un contrôleur hôte USB).
[3, 0, 0, 0, 0, 0] L’événement fait référence à un hub ou à un appareil connecté au numéro de port 3 d’un hub racine.
[3, 1, 0, 0, 0, 0] Un hub est connecté au port 3 d’un hub racine. L’événement fait référence à un hub ou à un appareil connecté au port 1 de ce hub externe.

Vous devez surveiller les chemins de port de tous les appareils qui vous intéressent. Lorsqu’un appareil est énuméré, le VID et le PID sont inconnus et enregistrés sous la forme 0. Le VID et le PID n’apparaissent pas lors de certaines demandes d’appareil de bas niveau, telles que la réinitialisation et la suspension. Ces demandes sont envoyées au hub auquel l’appareil est connecté.

Dans notre exemple de journal, l’événement d’achèvement Wait Wake a un chemin de port avec six zéros. L’événement indique une action Wait Wake sur un hub racine. Cela est logique en raison de nos actions : nous avons branché l’appareil à un port hub racine, de sorte que le hub racine se réveille.

Filtres Netmon USB

Vous pouvez examiner chaque événement dans un journal dans l’ordre chronologique, si vous en avez le temps. Même avec l’expérience, il est difficile d’identifier rapidement les événements importants en analysant la liste des descriptions des événements. Pour trouver plus rapidement la cause de l’appareil inconnu, vous pouvez utiliser la fonctionnalité de filtre Netmon.

Filtre d’erreur USB

Pour activer le filtre d’erreurs USB dans Netmon, cliquez sur Filtre -> Filtre d’affichage - Filtre de> chargement -> Filtres standard -> USB -> Erreurs du hub USB, puis cliquez sur Appliquer dans le volet Filtre d’affichage .

Le filtre d’erreurs USB réduit la liste des événements à ceux qui répondent aux critères indiqués dans le tableau suivant.

Filtrer le texte Description
(USBPort_MicrosoftWindowsUSBUSBPORT AND NetEvent.Header.Descriptor.Opcode == 34) Les événements de port USB qui ont opcode 34 sont des erreurs de port.
(USBHub_MicrosoftWindowsUSBUSBHUB AND NetEvent.Header.Descriptor.Opcode == 11) Les événements de hub USB qui ont opcode 11 sont des erreurs de hub.
(NetEvent.Header.Descriptor.Level == 0x2) Les événements qui ont un niveau 0x2 sont généralement des erreurs.
(USBHub_MicrosoftWindowsUSBUSBHUB AND NetEvent.Header.Descriptor.Id == 210) Les événements de hub USB avec l’ID 210 sont des événements « Journalisation de l’exception du hub USB ». Pour plus d’informations, consultez Présentation des événements d’erreur et des codes d’état.

Cette image montre le plus petit ensemble d’événements qui s’affichent dans le volet Résumé de l’image après avoir appliqué le filtre d’erreur USB à notre exemple de journal de trace.

Capture d’écran montrant un ensemble d’événements dans le volet « Résumé des images » après l’application du filtre d’erreur USB.

Pour afficher une vue d’ensemble de la séquence d’erreurs, vous pouvez afficher brièvement chaque événement d’erreur. Les champs importants à observer incluent fid_NtStatus, fid_UsbdStatus et fid_DebugText. Pour plus d’informations, consultez Présentation des événements d’erreur et des codes d’état. Pour désactiver un filtre, cliquez sur le bouton Supprimer dans le volet Filtre d’affichage .

Filtres Netmon personnalisés

Vous pouvez créer des filtres personnalisés dans Netmon. La méthode la plus simple consiste à créer un filtre à partir de données à l’écran de l’une des manières suivantes :

  • Cliquez avec le bouton droit sur un champ dans le volet Détails du cadre et sélectionnez Ajouter une valeur sélectionnée pour afficher le filtre.
  • Cliquez avec le bouton droit sur un champ dans le volet Résumé du cadre, puis sélectionnez Ajouter [nom du champ] à Afficher le filtre.

Vous pouvez modifier les opérateurs (tels que OR, AND et ==) et les valeurs de filtre pour générer les expressions de filtre appropriées.

Présentation des événements d’erreur et des codes d’état

Dans notre exemple d’appareil inconnu, la plupart des exceptions de hub USB ont une fid_DebugText données de CreateDeviceFailure. Il n’est pas clair à quel point l’exception est grave, mais le texte de débogage donne une indication sur la cause : une opération liée au nouvel appareil a échoué. Pour l’instant, supposons que les événements Create Device Failed adjacents sont redondants. Les deux dernières exceptions sont CreateDeviceFailure_Popup et GenErr_UserIoctlFailed. L’exception contextuelle ressemble à une erreur qui a été exposée à l’utilisateur, mais toutes ces erreurs peuvent être liées au problème d’appareil inconnu.

Les événements d’erreur USB et d’autres événements ont des valeurs status dans leurs données qui fournissent des informations précieuses sur le problème. Vous trouverez des informations sur status valeurs à l’aide des ressources du tableau suivant.

Type d’état Ressource
fid_NtStatus Consultez Valeurs NTSTATUS.
Champ status d’un bloc de requête USB (URB) ou d’un fid_UsbdStatus Recherchez la valeur en tant que USBD_STATUS dans inc\api\usb.h dans le Kit de pilotes Windows (WDK). Vous pouvez également utiliser le USBD_STATUS. Cette rubrique répertorie les noms symboliques et les significations des valeurs USBD_STATUS.

Lecture à l’envers à partir d’événements problématiques

Les événements enregistrés avant les événements d’erreur peuvent fournir des indices importants quant à la cause de l’erreur. Vous devez examiner les événements enregistrés avant les erreurs pour essayer de déterminer la cause racine de l’appareil inconnu. Dans cet exemple, commencez à regarder vers l’arrière à partir de l’événement CreateDeviceFailure_Popup, l’avant-dernière exception. Sélectionnez cet événement lorsque le filtre d’erreurs USB est activé, puis cliquez sur Supprimer dans le volet Filtre d’affichage . Le filtre d’erreur USB apparaît toujours dans le volet Filtre d’affichage et vous pouvez le réappliquer ultérieurement. Mais maintenant, le filtre est désactivé et le volet Résumé du cadre affiche tous les événements comme indiqué dans cette image.

moniteur réseau microsoft.

Les deux événements enregistrés juste avant l’événement de CreateDeviceFailure_Popup sont dispatch et terminé d’un transfert de contrôle USB. Le champ chemin de port fid_USBPORT_Device est égal à zéro pour les deux événements, ce qui indique que la cible du transfert est le hub racine. Dans la structure fid_USBPORT_URB_CONTROL_TRANSFER de l’événement d’achèvement, le status est égal à zéro (USBD_STATUS_SUCCESS), ce qui indique que le transfert a réussi. Continuez à examiner les événements précédents.

Les deux événements précédents suivants sont le quatrième (final) événement Create Device Failed et la quatrième (finale) l’exception CreateDeviceFailure, que nous avons examinée précédemment.

L’événement précédent suivant est Fermeture du point de terminaison. Cet événement signifie qu’un point de terminaison n’est plus utilisable. Les données d’événement décrivent à la fois l’appareil et le point de terminaison sur cet appareil. Le chemin du port de l’appareil est [1, 0, 0, 0, 0]. Le système sur lequel nous avons exécuté la trace n’a que des contrôleurs hôtes (hubs racines) plus l’appareil que nous connectons, de sorte que ce chemin de port ne décrit pas un hub. Le point de terminaison fermé doit se trouver sur l’appareil unique que nous avons branché, et nous savons maintenant que le chemin d’accès de l’appareil est 1. Il est probable que les pilotes ont rendu le point de terminaison de l’appareil inaccessible en raison d’un problème rencontré précédemment. Continuez à examiner les événements précédents.

L’événement précédent suivant est un transfert de contrôle USB terminé. Les données d’événement indiquent que la cible du transfert est l’appareil (le chemin du port est 1). La structure fid_USBPORT_Endpoint_Descriptor indique que l’adresse du point de terminaison est 0. Il s’agit donc du point de terminaison de contrôle par défaut défini par USB. Le status URB est 0xC0000004. Étant donné que le status n’est pas égal à zéro, le transfert n’a probablement pas réussi. Pour plus d’informations sur cette valeur USBD_STATUS, consultez usb.h et Présentation des événements d’erreur et des codes d’état.

#define USBD_STATUS_STALL_PID ((USBD_STATUS)0xC0000004L)

Signification : l’appareil a retourné un identificateur de paquet de décrochage. Quelle demande a été bloquée par le point de terminaison ? Les autres données enregistrées pour l’événement indiquent que la demande était une demande de contrôle d’appareil standard. Voici la demande analysée :

  Frame: Number = 184, Captured Frame Length = 252, MediaType = NetEvent
+ NetEvent:
- MicrosoftWindowsUSBUSBPORT: Complete Internal URB_FUNCTION_CONTROL_TRANSFER
  - USBPORT_ETW_EVENT_COMPLETE_INTERNAL_URB_FUNCTION_CONTROL_TRANSFER: Complete Internal URB_FUNCTION_CONTROL_TRANSFER
   + fid_USBPORT_HC:
   + fid_USBPORT_Device:
   + fid_USBPORT_Endpoint:
   + fid_USBPORT_Endpoint_Descriptor:
   + fid_URB_Ptr: 0x84539008
   - ControlTransfer:
    + Urb: Status = 0xc0000004, Flags 0x3, Length = 0
    - SetupPacket: GET_DESCRIPTOR
     + bmRequestType: (Standard request) 0x80
       bRequest: (6) GET_DESCRIPTOR
       Value_DescriptorIndex: 0 (0x0)
       Value_DescriptorType: (1) DEVICE
       _wIndex: 0 (0x0)
       wLength: 64 (0x40)

Combinez le bRequest (GET_DESCRIPTOR) avec le Value_DescriptorType (DEVICE) et vous pouvez déterminer que la demande était un descripteur get-device.

Pour que l’énumération USB continue, l’appareil doit avoir répondu à cette demande avec son descripteur d’appareil. Au lieu de cela, l’appareil a bloqué la demande, ce qui a provoqué l’échec de l’énumération. Par conséquent, les quatre échecs de création d’appareil ont été causés par des demandes bloquées pour le descripteur d’appareil. Vous avez déterminé que l’appareil est inconnu car l’énumération a échoué et que cette énumération a échoué parce que l’appareil n’a pas terminé la demande pour son descripteur d’appareil.