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 et il est apparu comme un appareil inconnu dans Device Manager et d’autres parties de l’interface utilisateur . L’ID matériel était USB\UNKNOWN. Pour diagnostiquer davantage, nous avons débranché l’appareil, entamé une trace ETW, et rebranché l'appareil. Une fois l’appareil apparu comme un appareil inconnu, nous avons arrêté le suivi.

À propos du problème d’appareil inconnu

Pour déboguer un problème de périphérique USB inconnu, il permet de comprendre ce que fait la pile des pilotes USB 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 le Gestionnaire de périphériques. L'appareil a un code d'appareil USB\VID_0000&PID_0000 et un code matériel et un code compatible USB\UNKNOWN. Les événements suivants entraînent l’énumération d’un périphérique USB en tant que périphérique inconnu :

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

Dans Windows 7, les appareils inconnus qui échouent sont marqués avec le code d’échec 43 dans Device Manager.

Si un appareil est marqué avec le code d’échec 28 dans Device Manager, l’appareil a été énuméré avec succès, 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 pu trouver un 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 des traces d’événements

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

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

    Capture d’écran montrant la fenêtre « Moniteur réseau Microsoft » 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, identifié comme 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 récapitulatifs des périphériques USB

L’événement 2 est le premier événement USB enregistré dans le journal. Ces événements et plusieurs événements suivants décrivent les contrôleurs hôtes USB, les hubs et les appareils connectés au système lorsque nous avons démarré la trace. Nous pouvons appeler ce groupe d'événements les événements récapitulatifs de l'appareil ou simplement les événements récapitulatifs. Comme le premier événement, les événements récapitulatives ne décrivent pas l’activité du pilote. Les événements récapitulatifs enregistrent l’état des appareils au début d’une session d'enregistrement. D'autres événements représentent quelque chose se passant dans le bus, des interactions avec les conducteurs clients ou le système, ou des modifications des états internes.

Le hub USB et les pilotes de port USB journalisent les événements récapitulatifs. 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 du 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 hub. La plupart des événements de synthèse du port USB et du hub USB ont les mots « Informations » ou « Attributs » dans leur description.

Comment pouvez-vous identifier la fin des événements récapitulatives ? S'il existe une rupture significative dans le schéma d'horodatage des événements du hub USB au début du journal, cette rupture est probablement la fin du résumé des dispositifs. Sinon, le premier événement de port USB après tous les événements de hub USB est probablement le premier événement non résumé. La figure 3 de la page suivante montre le premier événement non résumé de cette trace d'exemple.

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

Capture d’écran montrant un appareil d’intérêt sélectionné dans le « Résumé des images » qui n’a pas été connecté lors du 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 USB Hub Wait Wake IRP Completed. Nous avons branché un appareil et un contrôleur hôte ou un hub se réveille en réponse. Pour déterminer quel composant se réveille, examinez les données de l’événement. Les données se situent dans le volet Détails du cadre, qui s’affiche dans une arborescence au format suivant :

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 Wait Wake Completed du concentrateur USB, et vous verrez une structure ETW nommée fid_USBHUB_Hub. Le nom de la structure comporte les composants suivants :

Terme Descriptif
fid_ Préfixe classique pour une structure ETW USB.
USBHUB_ Indication 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 du 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.

Microsoft Network Monitor - Détails de trame.

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 suivantes :

Terrain Descriptif
fid_idVendor ID du 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 de la liste est contenu dans le champ PortPathDepth . Pour les appareils du hub racine, cette liste est composée que de zéros. Pour un périphérique USB connecté directement à un port de hub racine, la valeur dans PortPath[0] est le numéro de port du 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 du hub racine et continue avec les hubs supplémentaires (dans l’ordre de distance du hub racine). Ignorez les zéros. Par exemple:

Exemple de valeur Descriptif
[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é, les VID et PID sont inconnus et enregistrés en tant que 0. Les données VID et PID n’apparaissent pas pendant 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 de veille-réveil sur un hub racine. C’est logique en raison de nos actions : nous avons branché l’appareil dans un port de 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 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 la cause de l’appareil inconnu plus rapidement, 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’erreur USB limite la liste des événements à ceux qui répondent aux critères indiqués dans le tableau suivant.

Filtrer le texte Descriptif
(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 ET 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 du hub USB avec l’ID 210 sont des événements « Journalisation des exceptions 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é du cadre 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é du cadre » après l’application du filtre d’erreur USB.

Pour afficher une vue d’ensemble de la séquence d’erreurs, vous pouvez brièvement afficher 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 , puis 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] pour afficher le filtre.

Vous pouvez modifier les opérateurs (par exemple, 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 du hub USB ont des données fid_DebugText de type CreateDeviceFailure. Il n’est pas clair combien l’exception est grave, mais le texte de débogage donne un indicateur 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 de popup ressemble à une erreur qui a été exposée à l’utilisateur, mais n'importe laquelle ou toutes ces erreurs pourraient être liées au problème de périphérique inconnu.

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

Type d’état Ressource
fid_NtStatus Consultez les valeurs NTSTATUS.
Champ d’état d’un bloc de requête USB (URB) ou 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 inverse des événements problématiques

Les événements enregistrés avant les événements d’erreur peuvent fournir des indices importants sur 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 à revenir en arrière à partir de l’événement CreateDeviceFailure_Popup, la deuxième à la dernière exception. Sélectionnez cet événement pendant que le filtre d’erreur USB est activé, puis cliquez sur Supprimer dans le volet Filtre d’affichage . Le filtre d’erreur USB s’affiche toujours dans le volet Filtre d’affichage et vous pouvez l’appliquer ultérieurement. Mais maintenant, le filtre est désactivé et le volet Résumé du cadre affiche tous les événements, comme illustré dans cette image.

moniteur réseau microsoft.

Les deux événements enregistrés juste avant l’événement CreateDeviceFailure_Popup sont un Dispatch et un événement de finalisation d'un transfert de contrôle USB. Le champ de chemin d’accès 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, l’état 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 sont le quatrième (dernier) événement de création d'appareil échouée et la quatrième (dernière) exception CreateDeviceFailure que nous avons examinée précédemment.

L’événement précédent suivant est Endpoint Close. 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 comporte uniquement des contrôleurs hôtes (hubs racines) ainsi que l’appareil que nous avons connecté, donc le chemin de ce port ne décrit pas un hub. Le point de terminaison fermé doit se trouver sur le seul appareil que nous avons branché, et nous savons maintenant que le chemin de l’appareil est 1. Il est probable que les pilotes rendent 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. L’état URB est 0xC0000004. Étant donné que l’état 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 d'arrêt. 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 requête 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 la requête bRequest (GET_DESCRIPTOR) avec l’Value_DescriptorType (DEVICE) et vous pouvez déterminer que la requête était 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 requête, ce qui a provoqué l’échec de l’énumération. Par conséquent, les quatre défaillances lors de la création de l'appareil ont été provoquées 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é, car l’appareil n’a pas terminé la demande de son descripteur d’appareil.