Utilisation d’objets d’appareil de contrôle
Un objet d’appareil de contrôle est un objet d’appareil framework qui ne prend pas en charge les opérations de Plug-and-Play (PnP) ou de gestion de l’alimentation. Les pilotes peuvent utiliser des objets d’appareil de contrôle pour représenter des appareils virtuels logiciels uniquement ou des périphériques matériels hérités (c’est-à-dire des appareils qui ne fournissent pas de fonctionnalités PnP ou de gestion de l’alimentation).
Un pilote qui crée un objet d’appareil de contrôle crée généralement un lien symbolique pour l’objet d’appareil. Les applications peuvent envoyer des demandes d’E/S à l’objet d’appareil de contrôle en transmettant le nom de lien symbolique à un élément d’API, tel que la fonction CreateFile Microsoft Win32.
L’infrastructure n’attache pas d’objets d’appareil de contrôle à une pile d’appareils. Par conséquent, lorsqu’une application envoie une demande d’E/S à un objet de périphérique de contrôle, le gestionnaire d’E/S remet la demande directement au pilote qui a créé l’objet d’appareil de contrôle, plutôt qu’au pilote situé en haut de la pile. (Toutefois, un pilote supplémentaire peut appeler IoAttachDevice pour attacher un objet d’appareil au-dessus de l’objet d’appareil de contrôle. Dans ce cas, le pilote supplémentaire reçoit d’abord la demande d’E/S.)
Utilisations d’objets d’appareil de contrôle
Deux utilisations courantes pour les appareils de contrôle sont les suivantes :
Pilote de filtre pour un périphérique PnP, si le pilote prend en charge un ensemble de codes de contrôle d’E/S personnalisés que les applications doivent utiliser.
Si une application tente d’envoyer les codes de contrôle d’E/S personnalisés en haut de la pile de pilotes (en utilisant, par exemple, le nom de lien symbolique d’une interface de périphérique), un pilote au-dessus du pilote de filtre peut échouer à la demande d’E/S si le pilote ne reconnaît pas les codes de contrôle d’E/S personnalisés. Pour éviter ce problème, le pilote de filtre peut créer un objet de périphérique de contrôle. Les applications peuvent utiliser le nom de lien symbolique de l’objet d’appareil de contrôle pour envoyer des codes de contrôle d’E/S directement au pilote de filtre.
(Notez qu’un meilleur moyen pour le pilote de filtre d’éviter le problème consiste à agir en tant que pilote de bus et à énumérer les appareils enfants qui fonctionnent en mode brut. En d’autres termes, pour chaque appareil pris en charge par le pilote de filtre, le pilote peut créer un objet de périphérique physique (PDO) qui ne nécessite pas de pilote de fonction. Le pilote appelle WdfPdoInitAssignRawDevice et WdfDeviceInitAssignName pour chacun de ces appareils, et l’application peut identifier un appareil par son nom lorsqu’elle envoie un code de contrôle d’E/S personnalisé.)
Pilote pour un appareil qui ne prend pas en charge PnP.
Un tel pilote doit utiliser des objets d’appareil de contrôle, car les objets d’appareil pour ces appareils ne résident pas dans une pile d’appareils et ne fournissent pas de fonctionnalités PnP. Pour plus d’informations sur la prise en charge des appareils non PnP, consultez Utilisation de Kernel-Mode Driver Framework avec des pilotes non PnP.
Création d’un objet d’appareil de contrôle
Pour créer un objet de périphérique de contrôle, un pilote doit :
Appelez WdfControlDeviceInitAllocate pour obtenir une structure WDFDEVICE_INIT .
Appelez des méthodes d’initialisation d’objet, si nécessaire, pour initialiser la structure WDFDEVICE_INIT. Le pilote peut appeler uniquement les méthodes d’initialisation suivantes :
- WdfControlDeviceInitSetShutdownNotification
- WdfDeviceInitAssignName
- WdfDeviceInitAssignSDLString
- WdfDeviceInitAssignWdmIrpPreprocessCallback
- WdfDeviceInitSetCharacteristics
- WdfDeviceInitSetDeviceClass
- WdfDeviceInitSetExclusive
- WdfDeviceInitSetFileObjectConfig
- WdfDeviceInitSetIoInCallerContextCallback
- WdfDeviceInitSetIoType
- WdfDeviceInitSetRequestAttributes
Appelez WdfDeviceCreate, qui utilise le contenu de la structure WDFDEVICE_INIT pour créer un objet d’appareil framework.
Effectuez les opérations d’initialisation suivantes :
- Créez une file d’E/S par défaut pour l’appareil, le cas échéant.
- Si nécessaire, appelez WdfDeviceConfigureRequestDispatching.
- Appelez WdfDeviceCreateSymbolicLink pour créer un nom de lien symbolique que les applications peuvent utiliser pour accéder à l’appareil de contrôle.
Appelez WdfControlFinishInitializing.
Règles d’utilisation des objets d’appareil de contrôle
Les pilotes qui créent des objets d’appareil de contrôle doivent respecter les règles suivantes :
Les pilotes ne peuvent pas passer le handle de l’objet de périphérique de contrôle aux méthodes d’infrastructure qui énumèrent les appareils enfants.
Les pilotes ne peuvent pas passer le handle de l’objet de périphérique de contrôle aux méthodes d’infrastructure qui prennent en charge les interfaces de périphérique.
Les pilotes peuvent créer des files d’E/S et inscrire des gestionnaires de demandes pour les files d’attente, mais le framework n’autorise pas la gestion des files d’attente.
Les pilotes peuvent créer des objets de fichier pour les objets d’appareil de contrôle.
Nommage d’un objet d’appareil de contrôle
Tous les objets d’appareil de contrôle doivent être nommés. En règle générale, votre pilote appelle WdfDeviceInitAssignName pour attribuer un nom d’appareil, puis appelle WdfDeviceCreateSymbolicLink pour créer un nom de lien symbolique que les applications peuvent utiliser pour accéder à l’objet.
Si votre pilote n’appelle pas WdfDeviceInitAssignName pour attribuer un nom d’appareil, l’infrastructure génère automatiquement un nom pour les appareils de contrôle, mais votre pilote ne peut pas appeler WdfDeviceCreateSymbolicLink.
Votre pilote peut appeler WdfDeviceInitSetDeviceClass pour spécifier une classe de configuration d’appareil pour un périphérique de contrôle. La classe d’installation de l’appareil identifie une section du Registre qui contient des informations fournies par l’administrateur sur les appareils qui appartiennent à la classe d’installation. Pour plus d’informations sur l’appel de WdfDeviceInitSetDeviceClass, consultez Contrôle de l’accès des appareils dans les pilotes Framework-Based.
Réception d’une notification d’arrêt du système
Étant donné que les objets de périphérique de contrôle ne prennent pas en charge PnP, votre pilote ne peut pas inscrire les fonctions de rappel qui informent le pilote lorsque l’état d’alimentation d’un appareil change. Toutefois, le pilote peut appeler WdfControlDeviceInitSetShutdownNotification pour inscrire une fonction de rappel EvtDeviceShutdownNotification . Cette fonction de rappel informe le pilote lorsque le système est sur le point de perdre sa puissance.
Suppression d’un objet d’appareil de contrôle
Certains pilotes doivent supprimer leurs objets de périphérique de contrôle avant le déchargement du pilote, comme suit :
Si votre pilote crée des objets de périphérique de contrôle (qui ne prennent pas en charge PnP ou la gestion de l’alimentation), et si le pilote crée également des objets d’appareil framework qui prennent en charge pnP et la gestion de l’alimentation, le pilote doit finalement appeler WdfObjectDelete à IRQL = PASSIVE_LEVEL pour supprimer les objets d’appareil de contrôle.
Si le pilote crée les deux types d’objets d’appareil, le système d’exploitation ne peut pas décharger votre pilote tant que le pilote n’a pas supprimé les objets de périphérique de contrôle.
Toutefois, le pilote ne doit pas supprimer les objets de périphérique de contrôle tant qu’une fois que l’infrastructure n’a pas supprimé les autres objets d’appareil. Pour déterminer quand l’infrastructure a supprimé les autres objets d’appareil, votre pilote doit fournir des fonctions EvtCleanupCallback pour ces objets.
Si votre pilote crée des objets d’appareil de contrôle mais ne crée pas d’objets d’appareil framework qui prennent en charge pnP et la gestion de l’alimentation, le pilote n’a pas besoin de supprimer les objets de périphérique de contrôle.
Dans ce cas, l’infrastructure supprime les objets de périphérique de contrôle après le retour de la fonction de rappel EvtDriverUnload du pilote.