web-dev-qa-db-fra.com

Création d'un périphérique USB virtuel

Je suis un débutant qui apprend à écrire des pilotes de périphérique WDM pour les périphériques USB et a constaté que les documents disponibles sont trop difficiles à comprendre (le document en ligne DDK est l'un des plus difficiles à lire, et le livre de pilotes de périphérique WDM par Oney n'est pas '' rien de mieux).

Donc, j'ai une question simple. Par où commencer si je veux créer un périphérique USB virtuel (par exemple, une souris USB virtuelle qui ressemble à une vraie souris USB connectée à un port USB) pour tester/apprendre.

Jusqu'à présent, ce que je comprends, c'est que le pilote HIDClass (hidclass.sys) a un minidriver pour le bus USB (hidusb.sys) qui effectue l'énumération du matériel USB connecté. Donc, si je veux détourner le processus d'énumération matérielle et créer mon propre matériel virtuel, dois-je inclure un pilote de filtre quelque part pour intercepter certains IRP liés au processus d'énumération matérielle?

Désolé si ce qui précède n'a aucun sens, car je suis encore au stade de l'apprentissage et c'est en fait l'un des exercices qui, selon moi, pourrait m'aider à mieux écrire les pilotes de périphérique USB.

19
JavaMan

Windows utilise une architecture Plug and Play. Lorsque vous insérez un périphérique USB, il envoie une demande USB de bas niveau au périphérique, puis en fonction de la réponse d'un périphérique décide du pilote à charger. La correspondance est effectuée en comparant l'ID du fournisseur, l'ID du produit, etc. aux sections des fichiers inf. Les pilotes se présentent sous la forme d'un fichier xxx.sys compilé avec le fichier xxx.inf et sont chargés dans l'espace du noyau. Windows décide quel xxx.sys charger en fonction du fichier * .inf fourni avec le pilote du périphérique.

Ces fichiers ont des sections comme celle-ci:

[Manufacturer]
%Manufacturer% = DeviceInstall

[DeviceInstall]
"some usb dev"=OTHER_SECTION_DEV, USB\Vid_XXXX&Pid_yyyy

# This is where windows learns to match this information
# to your device, using the product id (Pid) and the 
# vendor id (Vid) that Windows gets back during the
# low level USB DeviceDescriptor request

[OTHER_SECTION_DEV]
CopyFiles = xxx.sys, 10,system32\drivers

(une description plus détaillée de ce qui se trouve dans les fichiers inf est disponible sur https://docs.Microsoft.com/en-us/windows-hardware/drivers/install/inf-manufacturer- section )


Un aperçu détaillé du processus d'énumération USB (Utiliser USB Logger):

  • Périphérique USB branché
  • Demande de pilote de bus USB
    • GetDescriptor (périphérique)
    • GetDescriptor (configuration)
    • GetDescriptor (String iSerialNumber), utilisé comme ID d'instance de périphérique
    • GetDescriptor (String iProduct), utilisé dans les fenêtres contextuelles "nouveau matériel identifié"
  • Le gestionnaire PNP (Plug and Play) est informé qu'un périphérique a été ajouté par les chauffeurs de bus.
  • Le gestionnaire PNP demande ensuite au conducteur du bus des informations sur le périphérique en utilisant une demande PNP, en demandant:
    • DeviceID string, représentant l'USB Vendor et Product ID,
    • Chaîne HardwareIDs,
    • CompatibleIDs string, représentant la classe d'interface, la sous-classe et le protocole du périphérique USB, et
    • Chaîne InstanceID, représentant l'uid de ce périphérique particulier dans l'ensemble de toutes les instances avec le même identifiant compatible connecté à l'ordinateur.

Pour tout périphérique USB connecté, vous pouvez voir ces chaînes à l'aide du Gestionnaire de périphériques:

  • Ouvrez le Gestionnaire de périphériques (menu Windows -> "gestionnaire de périphériques" ou panneau de configuration -> "Système" -> "Matériel" -> "Gestionnaire de périphériques")
  • puis utilisez le menu "view" pour passer à "Device by Connection"
  • ouvrir "ACPI [...]" -> "PCI bus"/"PCI Express Root Complex" -> "[...] USB [...] Host Controller"
  • développez l'une des entrées sous le contrôleur hôte, et pour l'un des périphériques répertoriés, cliquez avec le bouton droit pour obtenir leurs propriétés, ouvrez l'onglet "Détails", puis utilisez le menu déroulant des propriétés pour rechercher "ID matériel", "ID compatibles" , "ID d'instance de périphérique", "ID d'appareil correspondant", "Service", etc.

Par exemple, j'ai un périphérique de stockage USB avec Device Id = usb\class_08&subclass_06&prot_50 raccordé, et cette chaîne peut être mise en correspondance avec un .inf fichier ajouté à la liste des périphériques connus après la première énumération. Ce fichier a une chaîne Service = USBSTOR, et nous savons donc que usbstor.sys est utilisé pour l'interface avec ce périphérique de stockage de masse USB.

Continuons avec le processus d'appariement.

  • Le PNP Manager essaie de déterminer si le périphérique était déjà "installé":
    • Il recherche dans le registre une clé correspondant à "DeviceInstance ID" pour voir quel service gère l'interfaçage avec ce périphérique. Plus précisément, il recherche cela dans HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB

Pour le disque sur clé, vous pouvez voir quelque chose comme:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vid_0781&Pid_5406\0775555ACA54ADE3]
"Service"="USBSTOR"
  • Le gestionnaire PNP charge ensuite le pilote associé en fonction d'une correspondance entre les chaînes dans les demandes PNP et les données de la base de données .inf:
    • base de données inf située sous: C:\WINDOWS\inf \
    • pilotes fichiers .sys situés: C:\WINDOWS\system32\drivers
  • Si PNP ne trouve pas la chaîne correspondante, vous obtiendrez une invite pour montrer un chemin vers xxx.sys et xxx.inf

Pour écrire des pilotes, mon conseil est:

  1. Ne commencez pas par implémenter des périphériques HID (périphérique d'interface humaine), car vous pouvez amener Windows à utiliser votre pilote personnalisé pour votre souris ou votre clavier au lieu du pilote d'origine, cela désactivera votre souris ou votre clavier, très dangereux.
  2. Ne chargez pas de pilotes dans votre machine de développement:
    1. utiliser une machine virtuelle et y installer vos pilotes. Configurez un débogueur de noyau pour votre machine virtuelle: http://www.codeproject.com/KB/winsdk/KernelModeDebuggerSetup.asp
    2. ou charger des pilotes sur une autre machine de test.
  3. Une bonne plate-forme d'apprentissage pour les pilotes USB est "OSR USB-FX2 Learning Kit"
20
Alex.Salnikov
4
Amir Saniyan

Vous pouvez utiliser le projet USB/IP pour émuler n'importe quel appareil de votre choix. Dans mon blog, j'ai montré comment émuler un périphérique de souris USB en python en utilisant le projet USB/IP: http://breaking-the-system.blogspot.com/2014/08 /emulating-usb-devices-in-python-with-no.html

Cela ne vous aidera pas à comprendre comment créer le périphérique USB virtuel (le processus se fait dans le pilote USB/IP, vous pouvez lire le code), mais cela créera le périphérique USB HID virtuel et vous pourrez jouer avec les arguments HID envoyés au pilote USB.

2
Yaron Shani

Ne serait-il pas plus logique de fournir votre propre type de bus et votre propre énumérateur?

1
Simon Richter