Comment puis-je obtenir USB_DEVICE_DESCRIPTOR avec un chemin de périphérique

J’ai pu énumérer les périphériques USB en utilisant le SetupAPI, et j’ai regardé l’application usbview depuis le WDK, mais je n’arrive toujours pas à comprendre comment obtenir le fichier USB_DEVICE_DESCRIPTOR .

  • Je préférerais éviter d’utiliser WMI.
  • DeviceIoControl est ce que l’aperçu usbview utilise, mais cela ne fonctionne vraiment que si vous énumérez des périphériques sur un concentrateur. Je suppose que si je peux accéder au concentrateur parent (et au port) en fonction d’un chemin d’access (ou d’un identifiant), cette méthode peut fonctionner, mais je n’ai pas été en mesure de déterminer comment procéder.
  • J’ai un mélange de périphériques pour lesquels je souhaite obtenir le descripteur. Certains d’entre eux sont des HID et il est possible que certains soient des périphériques WinUsb.sys. Si ce sont des périphériques WinUsb, je peux utiliser WinUsb_GetDescriptor , mais cela ne fonctionnera pas pour les HID (et je ne sais pas comment les distinguer de l’ID ou du chemin … Classe d’interface, je suppose?).
  • Je pourrais utiliser SetupDiGetDeviceRegistryProperty mais dans la liste des propriétés disponibles, je peux voir la chaîne du fabricant, mais pas l’ID du fournisseur.
  • Je pourrais peut-être parsingr cette valeur à partir du chemin d’access du périphérique ou de l’ID de périphérique, mais cela semble en quelque sorte … hack-ish. Est-ce juste ce que font les gens? De plus, cela me laisse toujours aller à d’autres méthodes si je veux d’autres champs comme le fabricant, où si je pouvais juste avoir tout l’USB_DEVICE_DESCRIPTOR, je pense que j’aurais à peu près tout ce dont j’ai besoin.
  • LibUsb.Net ne supporte apparemment que les périphériques WinUsb. Voilà comment il semble obtenir le descripteur.
  • Apparemment, WinRT a de nouvelles API et par conséquent les applications Windows Store ont un bon moyen d’obtenir le descripteur. Mais ce n’est certainement pas une application Windows Store et je ne sais pas s’il existe une autre façon d’utiliser les nouvelles API.

Est-ce que quelqu’un peut-il me montrer la bonne direction? N’est-il pas possible d’obtenir ces informations de la WinAPI sans commencer par le Hub?

Votre meilleur pari serait d’extraire les informations du chemin d’access du périphérique et d’utiliser les fonctions SetupDi pour obtenir les autres éléments. Pour autant que je sache, le chemin du périphérique suit toujours la même convention. c’est à dire:

“\\? \ usb # vid_ 0000 & pid_ 1111 # SERIAL # { GUID }” où 0000 est le VID et 1111 est le PID en tant que chaînes hexadécimales. SERIAL est le numéro de série fourni par le matériel ou la valeur de série atsortingbuée par le système d’exploitation.

Personnellement, j’ai trouvé une instance où je voulais absolument obtenir le descripteur de périphérique afin de tirer la série de cette façon. Dans certains cas, le système d’exploitation ne reconnaissait pas le numéro de série fourni par mon matériel. J’ai corrigé cela du côté du matériel, mais je voulais tout de même adapter l’ancien matériel du côté du PC. Ci-dessous est mon approche. Il y a peut-être quelque chose de mieux, mais c’est le meilleur que j’ai trouvé jusqu’ici. Vous pouvez toujours le considérer comme un “hack-ish”.

  1. Appelez SetupDiGetClassDevs () pour configurer votre DeviceInfoSet désiré
  2. Obtenez les données d’informations de votre appareil à l’aide de SetupDiEnumDeviceInfo ()
  3. Appelez SetupDiGetDeviceRegistryProperty () avec SPDRP_LOCATION_INFORMATION pour obtenir les informations d’emplacement. Cette chaîne doit ressembler à “Port_ # 0001.Hub_ # 0001”. Analyser cette chaîne pour obtenir le numéro de port où se trouve votre appareil. (Je suppose que cette valeur est la base 10, mais je n’ai pas encore vérifié)
  4. Appelez CM_Get_Parent () pour obtenir la valeur du pointeur de nœud de périphérique du parent (concentrateur)
  5. Appelez SetupDiGetClassDevs () avec le GUID de {0xf18a0e88, 0xc30c, 0x11d0, {0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8} pour obtenir tous les concentrateurs sur votre système. Ce GUID doit être défini comme GUID_DEVINTERFACE_USB_HUB dans usbiodef.h.
  6. Parcourez la liste des périphériques à l’aide de SetupDiEnumDeviceInfo (). Arrêtez une fois que DevInst est égal à la valeur obtenue à l’étape 4.
  7. Appelez SetupDiGetDeviceInterfaceDetail () sur l’index trouvé à l’étape 6.
  8. Appelez CreateFile () sur le DevicePath obtenu à l’étape 7.
  9. Appelez DeviceIoControl () en utilisant le fichier créé à l’étape 8 et le numéro de port obtenu à l’étape 3 comme index de connexion.

-MODIFIER-

Comme Ben l’a souligné dans les commentaires, vous pouvez ignorer les étapes 5, 6 et 7 en utilisant CM_Get_Device_ID sur le noeud dev du parent obtenu à l’étape 4. Modifiez les barres obliques (\) dans cette chaîne en livres (#). Ajoutez “\\? \” Et ajoutez “# {f18a0e88-c30c-11d0-8815-00a0c906bed8}”. Utilisez-le comme chemin d’access de votre périphérique à l’étape 8. Cela évite les itérations sur tous les périphériques concentrateurs de votre système 🙂