Partager via


Comment écrire votre premier pilote client USB (UMDF)

Dans cet article, vous allez utiliser le modèle Pilote en mode utilisateur, USB (UMDF V2) fourni avec Microsoft Visual Studio 2022 pour écrire un pilote client basé sur l’infrastructure de pilotes en mode utilisateur (UMDF). Après avoir créé et installé le pilote client, vous allez afficher le pilote client dans Gestionnaire de périphériques et afficher la sortie du pilote dans un débogueur.

UMDF (appelé framework dans cet article) est basé sur le modèle objet de composant (COM). Chaque objet framework doit implémenter IUnknown et ses méthodes, QueryInterface, AddRef et Release, par défaut. Les méthodes AddRef et Release gèrent la durée de vie de l’objet, de sorte que le pilote client n’a pas besoin de conserver le nombre de références. La méthode QueryInterface permet au pilote client d’obtenir des pointeurs d’interface vers d’autres objets d’infrastructure dans le modèle objet WDF (Windows Driver Frameworks). Les objets framework effectuent des tâches de pilote complexes et interagissent avec Windows. Certains objets d’infrastructure exposent des interfaces qui permettent à un pilote client d’interagir avec l’infrastructure.

Un pilote client UMDF est implémenté en tant que serveur COM in-process (DLL), et C++ est le langage préféré pour l’écriture d’un pilote client pour un périphérique USB. En règle générale, le pilote client implémente plusieurs interfaces exposées par le framework. Cet article fait référence à une classe définie par le pilote client qui implémente des interfaces d’infrastructure en tant que classe de rappel. Une fois ces classes instanciées, les objets de rappel résultants sont associés à des objets d’infrastructure particuliers. Ce partenariat donne au pilote client la possibilité de répondre aux événements liés à l’appareil ou au système signalés par l’infrastructure. Chaque fois que Windows avertit l’infrastructure de certains événements, l’infrastructure appelle le rappel du pilote client, le cas échéant. Sinon, l’infrastructure poursuit le traitement par défaut de l’événement. Le code du modèle définit les classes de rappel de pilote, de périphérique et de file d’attente.

Pour obtenir une explication sur le code source généré par le modèle, consultez Présentation du code du modèle UMDF pour le pilote client USB.

Avant de commencer

Pour développer, déboguer et installer un pilote en mode utilisateur, vous avez besoin de deux ordinateurs :

  • Un ordinateur hôte exécutant Windows 10 ou une version ultérieure du système d’exploitation Windows. L’ordinateur hôte est votre environnement de développement, où vous écrivez et déboguez votre pilote.
  • Un ordinateur cible exécutant la version du système d’exploitation sur lequel vous souhaitez tester votre pilote, par exemple, Windows 11, version 22H2. L’ordinateur cible dispose du pilote en mode utilisateur que vous souhaitez déboguer et de l’un des débogueurs.

Dans certains cas, lorsque les ordinateurs hôtes et cibles exécutent la même version de Windows, vous pouvez avoir un seul ordinateur exécutant Windows 10 ou une version ultérieure de Windows. Cet article suppose que vous utilisez deux ordinateurs pour le développement, le débogage et l’installation de votre pilote en mode utilisateur.

Avant de commencer, vérifiez que vous répondez aux exigences suivantes :

Configuration logicielle requise

  • Votre ordinateur hôte a Visual Studio 2022.

  • Votre ordinateur hôte dispose de la dernière version du Kit de pilotes Windows (WDK) pour Windows 11, version 22H2.

    Le kit comprend des en-têtes, des bibliothèques, des outils, de la documentation et les outils de débogage nécessaires pour développer, générer et déboguer un pilote client USB. Vous pouvez obtenir la dernière version du WDK à l’adresse How to Get the WDK.

  • Votre ordinateur hôte dispose de la dernière version des outils de débogage pour Windows. Vous pouvez obtenir la dernière version à partir du WDK ou télécharger et installer les outils de débogage pour Windows.

  • Si vous utilisez deux ordinateurs, vous devez configurer les ordinateurs hôte et cible pour le débogage en mode utilisateur. Pour plus d’informations, consultez Configuration du débogage User-Mode dans Visual Studio.

Configuration matérielle requise

Obtenez un périphérique USB pour lequel vous allez écrire le pilote client. Dans la plupart des cas, vous disposez d’un périphérique USB et de sa spécification matérielle. La spécification décrit les fonctionnalités de l’appareil et les commandes du fournisseur prises en charge. Utilisez la spécification pour déterminer les fonctionnalités du pilote USB et les décisions de conception associées.

Si vous débutez dans le développement de pilotes USB, utilisez le kit d’apprentissage OSR USB FX2 pour étudier les exemples USB inclus avec le WDK. Il contient le périphérique USB FX2 et toutes les spécifications matérielles requises pour implémenter un pilote client.

Étape 1 : Générer le code du pilote

Pour plus d’informations sur l’écriture de code de pilote UMDF, consultez Écriture d’un pilote UMDF basé sur un modèle.

Pour du code spécifique à USB, sélectionnez les options suivantes dans Visual Studio 2022

  1. Dans la boîte de dialogue Nouveau projet , dans la zone de recherche située en haut, tapez USB.
  2. Dans le volet central, sélectionnez Pilote en mode utilisateur, USB (UMDF V2).
  3. Sélectionnez Suivant.
  4. Entrez un nom de projet, choisissez un emplacement d’enregistrement, puis sélectionnez Créer.

Les captures d’écran suivantes montrent la boîte de dialogue Nouveau projet pour le modèle pilote usb User-Mode .

Capture d’écran des options de création de projet visual Studio.

Capture d’écran de l’écran de configuration de création de projet de Visual Studio.

Cet article suppose que le nom du projet est MyUSBDriver_UMDF_. Il contient les fichiers suivants :

Fichiers Description
Driver.h ; Driver.c Contient l’implémentation du point d’entrée du module de pilote. Fonctionnalités et rappels liés à DriverEntry et WDFDRIVER.
Device.h ; Device.c Fonctionnalités et rappels liés à WDFDEVICE et WDFUSBDEVICE.
Queue.h ; Queue.c Fonctionnalités et rappels liés à WDFQUEUE.
Trace.h Définit le GUID de l’interface de l’appareil. Il déclare également des fonctions de suivi et des macros.
< >Nom du projet.inf Fichier INF requis pour installer le pilote client sur l’ordinateur cible.

Étape 2 : Ajouter des informations sur votre appareil

Avant de générer le pilote, vous devez ajouter des informations sur votre appareil, en particulier l’ID matériel. Pour fournir l’ID matériel :

  1. Dans la fenêtre Explorateur de solutions, cliquez avec le bouton droit sur MyUSBDriver_UMDF_, puis choisissez Propriétés.
  2. Dans la fenêtre MyUSBDriver_UMDF_ Pages de propriétés, accédez à Propriétés > de configuration Déploiement du pilote d’installation>, comme illustré ici. Capture d’écran de la fenêtre pages de propriétés de Visual Studio 2022.
  3. Cochez Supprimer les versions précédentes du pilote avant le déploiement.
  4. Pour Nom de l’appareil cible, sélectionnez le nom de l’ordinateur que vous avez configuré pour le test et le débogage.
  5. Sélectionnez Mise à jour du pilote d’ID matériel, puis entrez l’ID matériel de votre pilote. Dans cet exercice, l’ID matériel est Root\MyUSBDriver_UMDF_. Sélectionnez OK.

Notes

Dans cet exercice, l’ID matériel n’identifie pas un élément matériel réel. Il identifie un appareil imaginaire qui se verra attribuer une place dans l’arborescence de l’appareil en tant qu’enfant du nœud racine. Pour le matériel réel, ne sélectionnez pas Mise à jour du pilote d’ID matériel. Au lieu de cela, sélectionnez Installer et vérifier. Vous pouvez voir l’ID matériel dans le fichier d’informations de votre pilote (INF). Dans la fenêtre Explorateur de solutions, accédez à MyUSBDriver_UMDF_ > Fichiers du pilote, puis double-cliquez sur MyUSBDriver_UMDF_.inf. L’ID matériel se trouve sous [Standard.NT$ARCH$].

Tous les pilotes clients USB basés sur UMDF nécessitent deux pilotes fournis par Microsoft, le réflecteur et WinUSB.

  • Réflecteur : si votre pilote est correctement chargé, le réflecteur est chargé en tant que pilote le plus élevé dans la pile en mode noyau. Le réflecteur doit être le pilote supérieur de la pile en mode noyau. Pour répondre à cette exigence, le fichier INF du modèle spécifie le réflecteur en tant que service et WinUSB comme pilote de filtre inférieur dans l’INF :

    [MyDevice_Install.NT.Services]
    AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall  ; flag 0x2 sets this as the service for the device
    AddService=WinUsb,0x000001f8,WinUsb_ServiceInstall  ; this service is installed because its a filter.
    
  • WinUSB : le package d’installation doit contenir des coinstallateurs pour Winusb.sys, car pour le pilote client, WinUSB est la passerelle vers la pile de pilotes USB en mode noyau. Un autre composant chargé est une DLL en mode utilisateur, nommée WinUsb.dll, dans le processus hôte du pilote client (Wudfhost.exe). Winusb.dll expose winUSB Functions qui simplifient le processus de communication entre le pilote client et WinUSB.

Étape 3 : Générer le code du pilote client USB

Pour générer votre pilote :

  1. Ouvrez le projet ou la solution de pilote dans Visual Studio 2022.
  2. Cliquez avec le bouton droit sur la solution dans le Explorateur de solutions, puis sélectionnez Configuration Manager.
  3. Dans le Configuration Manager, sélectionnez votre configuration de solution active (par exemple, Déboguer ou Mettre en production) et votre plateforme de solution active (par exemple, x64) qui correspondent au type de build qui vous intéresse.
  4. Vérifiez que le GUID d’interface de votre appareil est précis tout au long du projet.
    • Le GUID d’interface d’appareil est défini dans Trace.h et est référencé à partir de MyUSBDriverUMDFCreateDevice Device.c. Lorsque vous créez votre projet avec le nom MyUSBDriver_UMDF_, Visual Studio 2022 définit le GUID d’interface de l’appareil avec le nom GUID_DEVINTERFACE_MyUSBDriver_UMDF_ , mais appelle WdfDeviceCreateDeviceInterface avec le paramètre &GUID_DEVINTERFACE_MyUSBDriverUMDFincorrect . Remplacez le paramètre incorrect par le nom défini dans Trace.h pour vous assurer que le pilote est généré correctement.
  5. Dans le menu Générer, sélectionnez Générer la solution.

Pour plus d’informations, consultez Génération d’un pilote.

Étape 4 : Configurer un ordinateur pour le test et le débogage

Pour tester et déboguer un pilote, vous exécutez le débogueur sur l’ordinateur hôte et le pilote sur l’ordinateur cible. Jusqu’à présent, vous avez utilisé Visual Studio sur l’ordinateur hôte pour générer un pilote. Vous devez ensuite configurer un ordinateur cible. Pour configurer un ordinateur cible, suivez les instructions fournies dans Provisionner un ordinateur pour le déploiement et le test de pilotes.

Étape 5 : Activer le suivi pour le débogage du noyau

Le code du modèle contient plusieurs messages de trace (TraceEvents) qui peuvent vous aider à suivre les appels de fonction. Toutes les fonctions du code source contiennent des messages de trace qui marquent l’entrée et la sortie d’une routine. Pour les erreurs, le message de trace contient le code d’erreur et une chaîne explicite. Étant donné que le suivi WPP est activé pour votre projet de pilote, le fichier de symboleS PDB créé pendant le processus de génération contient des instructions de mise en forme des messages de suivi. Si vous configurez les ordinateurs hôtes et cibles pour le suivi WPP, votre pilote peut envoyer des messages de trace à un fichier ou au débogueur.

Pour configurer votre ordinateur hôte pour le suivi WPP

  1. Créez des fichiers de format de message de suivi (TMF) en extrayant les instructions de mise en forme du message de suivi à partir du fichier de symboles PDB.

    Vous pouvez utiliser Tracepdb.exe pour créer des fichiers TMF. L’outil se trouve dans le <dossier>Installer Windows Kits\10\bin\<architecture> du WDK. La commande suivante crée des fichiers TMF pour le projet de pilote.

    tracepdb -f <PDBFiles> -p <TMFDirectory>
    

    L’option -f spécifie l’emplacement et le nom du fichier de symboles PDB. L’option -p spécifie l’emplacement des fichiers TMF créés par Tracepdb. Pour plus d’informations, consultez Commandes Tracepdb.

    Il existe trois fichiers à l’emplacement spécifié, un par fichier de code C dans le projet. Ils reçoivent des noms de fichiers GUID.

  2. Dans le débogueur, tapez les commandes suivantes :

    .load Wmitrace
    .chain
    !wmitrace.searchpath + <TMF file location>
    

Il s’agit de ces commandes :

  • Chargez l’extension Wmitrace.dll.
  • Vérifie que l’extension du débogueur est chargée.
  • Ajoute l’emplacement des fichiers TMF au chemin de recherche de l’extension de débogueur.

La sortie ressemble à ceci :

Trace Format search path is: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE;c:\drivers\tmf

Pour configurer votre ordinateur cible pour le suivi WPP

  1. Vérifiez que vous disposez de l’outil Tracelog sur votre ordinateur cible. L’outil se trouve dans le <install_folder> dossierKits Windows\10\Tools\<arch> du WDK. Pour plus d’informations, consultez Syntaxe de la commande Tracelog.

  2. Ouvrez une fenêtre commande et exécutez en tant qu’administrateur.

  3. Tapez la commande suivante :

    tracelog -start MyTrace -guid \#c918ee71-68c7-4140-8f7d-c907abbcb05d -flag 0xFFFF -level 7-rt -kd
    

La commande démarre une session de suivi nommée MyTrace.

L’argument guid spécifie le GUID du fournisseur de trace, qui est le pilote client. Vous pouvez obtenir le GUID à partir de Trace.h dans le projet Visual Studio 2022. Comme autre option, vous pouvez taper la commande suivante et spécifier le GUID dans un fichier .guid. Le fichier contient le GUID au format de trait d’union :

tracelog -start MyTrace -guid c:\\drivers\\Provider.guid -flag 0xFFFF -level 7-rt -kd

Vous pouvez arrêter la session de suivi en tapant la commande suivante :

tracelog -stop MyTrace

Étape 6 : Déployer le pilote sur l’ordinateur cible

  1. Dans la fenêtre Explorateur de solutions, cliquez avec le bouton droit sur le nom du projet (MyUSBDriver_UMDF_), puis choisissez Propriétés.
  2. Dans le volet gauche, accédez à Propriétés > de configuration Déploiement du pilote d’installation>.
  3. Pour Nom de l’appareil cible, spécifiez le nom de l’ordinateur cible.
  4. Sélectionnez Installer/réinstaller et vérifier.
  5. Sélectionnez OK.
  6. Dans le menu Déboguer , choisissez Démarrer le débogage ou appuyez sur F5 sur le clavier.

Notes

Ne spécifiez pas l’ID matériel de votre appareil sous Mise à jour du pilote d’ID matériel. L’ID matériel doit être spécifié uniquement dans le fichier d’informations (INF) de votre pilote.

Étape 7 : Afficher le pilote dans Gestionnaire de périphériques

  1. Entrez la commande suivante pour ouvrir Gestionnaire de périphériques.

    devmgmt
    
  2. Vérifiez que Gestionnaire de périphériques affiche le nœud suivant.

    Périphérique USB

    MyUSBDriver_UMDF_Device

Étape 8 : Afficher la sortie dans le débogueur

Vérifiez que les messages de suivi s’affichent dans la fenêtre Exécution du débogueur sur l’ordinateur hôte.

La sortie doit ressembler à ce qui suit :

[0]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::OnPrepareHardware Entry
[0]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::OnPrepareHardware Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::CreateInstanceAndInitialize Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::Initialize Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::Initialize Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::CreateInstanceAndInitialize Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::Configure Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyIoQueue::CreateInstanceAndInitialize Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyIoQueue::Initialize Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyIoQueue::Initialize Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyIoQueue::CreateInstanceAndInitialize Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::Configure Exit

Remarques

Examinons comment l’infrastructure et le pilote client fonctionnent ensemble pour interagir avec Windows et gérer les requêtes envoyées au périphérique USB. Cette illustration montre les modules chargés dans le système pour un pilote client USB basé sur UMDF.

Diagramme de l’architecture du pilote client en mode utilisateur.

L’objectif de chaque module est décrit ici :

  • Application : processus en mode utilisateur qui émet des demandes d’E/S pour communiquer avec le périphérique USB.
  • Gestionnaire d’E/S : un composant Windows qui crée des paquets de demandes d’E/S (IRPs) pour représenter les demandes d’application reçues et les transfère en haut de la pile d’appareils en mode noyau pour l’appareil cible.
  • Réflecteur : un pilote en mode noyau fourni par Microsoft installé en haut de la pile d’appareils en mode noyau (WUDFRd.sys). Le réflecteur redirige les IRPs reçus du gestionnaire d’E/S vers le processus hôte du pilote client. À la réception de la demande, l’infrastructure et le pilote client gèrent la demande.
  • Processus hôte : processus dans lequel le pilote en mode utilisateur s’exécute (Wudfhost.exe). Il héberge également l’infrastructure et le répartiteur d’E/S.
  • Pilote client : pilote de fonction en mode utilisateur pour le périphérique USB.
  • UMDF : module d’infrastructure qui gère la plupart des interactions avec Windows pour le compte du pilote client. Il expose les interfaces de pilote de périphérique (DDIs) en mode utilisateur que le pilote client peut utiliser pour effectuer des tâches courantes du pilote.
  • Répartiteur : mécanisme qui s’exécute dans le processus hôte ; détermine comment transférer une demande en mode noyau une fois qu’elle a été traitée par les pilotes en mode utilisateur et qu’elle a atteint le bas de la pile en mode utilisateur. Dans l’illustration, le répartiteur transfère la demande à la DLL en mode utilisateur, Winusb.dll.
  • Winusb.dll : une DLL en mode utilisateur fournie par Microsoft qui expose les fonctions WinUSB qui simplifient le processus de communication entre le pilote client et WinUSB (Winusb.sys, chargées en mode noyau).
  • Winusb.sys : un pilote fourni par Microsoft qui est requis par tous les pilotes clients UMDF pour les périphériques USB. Le pilote doit être installé sous le réflecteur et faire office de passerelle vers la pile de pilotes USB en mode noyau. Pour plus d’informations, consultez WinUSB.
  • Pile de pilotes USB : ensemble de pilotes, fournis par Microsoft, qui gèrent la communication au niveau du protocole avec le périphérique USB. Pour plus d’informations, consultez Pilotes côté hôte USB dans Windows.

Chaque fois qu’une application effectue une demande pour la pile de pilotes USB, le gestionnaire d’E/S Windows envoie la demande au réflecteur, qui la dirige vers le pilote client en mode utilisateur. Le pilote client gère la requête en appelant des méthodes UMDF spécifiques, qui appellent en interne WinUSB Functions pour envoyer la demande à WinUSB. À la réception de la demande, WinUSB traite la demande ou la transfère à la pile de pilotes USB.