Isolation du package de pilotes
L’isolation des packages de pilotes est une exigence pour les pilotes Windows qui rend les packages de pilotes plus résilients aux modifications externes, plus faciles à mettre à jour et plus simples à installer.
Notes
Bien que l’isolation des packages de pilotes soit requise pour les pilotes Windows, les pilotes de bureau Windows en bénéficient toujours grâce à une résilience et une facilité de maintenance améliorées.
Le tableau suivant présente des exemples de pratiques de package de pilotes héritées qui ne sont plus autorisées pour les pilotes Windows dans la colonne de gauche, ainsi que le comportement requis pour les pilotes Windows dans la colonne de droite.
Pilote non isolé | Pilote isolé |
---|---|
INF copie les fichiers dans %windir%\System32 ou %windir%\System32\drivers | Les fichiers de pilote sont exécutés à partir du magasin de pilotes |
Interagit avec les piles/pilotes de périphériques à l’aide de chemins codés en dur | Interagit avec les piles/pilotes de périphériques à l’aide de fonctions ou d’interfaces de périphérique fournies par le système |
Code en dur le chemin d’accès aux emplacements du Registre global | Utilise HKR et les fonctions fournies par le système pour l’emplacement relatif de l’état du registre et du fichier |
Écritures de fichiers runtime dans n’importe quel emplacement | Les fichiers sont écrits par rapport aux emplacements fournis par le système d’exploitation |
Pour obtenir de l’aide pour déterminer si votre package de pilotes répond aux exigences d’isolation du package de pilotes, consultez Validation des pilotes Windows. Pour obtenir des exemples de mise à jour d’un inf pour répondre aux exigences d’isolation du package de pilotes, consultez Portage d’un inf pour suivre l’isolation du package de pilotes.
Exécuter à partir du magasin de pilotes
Tous les packages de pilotes isolés laissent leurs fichiers de package de pilotes dans le magasin de pilotes. Cela signifie qu’ils spécifient DIRID 13 dans leur INF pour spécifier l’emplacement des fichiers de package de pilotes lors de l’installation. Pour plus d’informations sur la façon de l’utiliser dans un package de pilotes, consultez Exécuter à partir d’un magasin de pilotes.
État de lecture et d’écriture
Notes
Si votre composant utilise les propriétés de l’appareil ou de l’interface d’appareil pour stocker l’état, continuez à utiliser cette méthode et les API de système d’exploitation appropriées pour stocker et accéder à l’état. Les conseils suivants pour l’état du registre et du fichier concernent les autres états qui doivent être stockés par un composant.
L’accès à différents états de registre et de fichier doit être effectué en appelant des fonctions qui fournissent à un appelant l’emplacement de l’état, puis l’état est en lecture/écriture par rapport à cet emplacement. N’utilisez pas de chemins d’accès de Registre absolus et de chemins d’accès aux fichiers codés en dur.
Cette section comporte les sous-sections suivantes :
État du Registre
Cette section comporte les sous-sections suivantes :
État du registre des appareils PnP
Les packages de pilotes isolés et les composants en mode utilisateur utilisent généralement l’un des deux emplacements pour stocker l’état de l’appareil dans le Registre. Il s’agit de la clé matérielle (clé de périphérique) de l’appareil et de la clé logicielle (clé de pilote) de l’appareil. La clé matérielle est généralement destinée aux paramètres liés à la façon dont un appareil individuel instance interagit avec le matériel. Par exemple, pour activer une fonctionnalité matérielle ou placer le matériel dans un mode spécifique. La clé logicielle est généralement destinée aux paramètres liés à la façon dont un appareil individuel instance interagit avec le système et d’autres logiciels. Par exemple, pour configurer l’emplacement d’un fichier de données, pour interagir avec une infrastructure ou pour accéder aux paramètres d’application d’un appareil. Pour récupérer un handle à ces emplacements de Registre, utilisez l’une des options suivantes :
IoOpenDeviceRegistryKey (WDM)
CM_Open_DevNode_Key (code en mode utilisateur)
Directive INF AddReg utilisant des entrées reg-root HKR dans une section add-registry référencée à partir d’une section INF DDInstall ou DDInstall.HW , comme indiqué ci-dessous :
[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg
[Example_DDInstall.AddReg]
HKR,,ExampleValue,,%13%\ExampleFile.dll
État du registre de l’interface d’appareil
Pour lire et écrire l’état du registre de l’interface d’appareil, utilisez l’une des options suivantes :
CM_Open_Device_Interface_Key (code en mode utilisateur)
Directive Inf AddReg utilisant des entrées reg-root HKR dans une section add-registry référencée à partir d’une section add-interface-section
État du registre des services
L’état du service doit être classé dans l’une des 3 catégories suivantes
État immuable du registre du service
L’état du service immuable est l’état fourni par le package de pilotes qui installe le service. Ces valeurs de Registre définies par l’INF pour les services driver et Win32 doivent être stockées sous la sous-clé « Parameters » du service en fournissant une ligne HKR dans une section AddReg , puis en référençant cette section dans la section d’installation du service dans l’INF. Par exemple :
[ExampleDDInstall.Services]
Addservice = ExampleService, 0x2, Example_Service_Inst
[Example_Service_Inst]
DisplayName = %ExampleService.SvcDesc%
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %13%\ExampleService.sys
AddReg=Example_Service_Inst.AddReg
[Example_Service_Inst.AddReg]
HKR, Parameters, ExampleValue, 0x00010001, 1
Pour accéder à l’emplacement de cet état à partir du service au moment de l’exécution, utilisez l’une des fonctions suivantes :
IoOpenDriverRegistryKey (WDM) avec un DRIVER_REGKEY_TYPE de DriverRegKeyParameters
GetServiceRegistryStateKey (Win32 Services) avec un SERVICE_REGISTRY_STATE_TYPE de ServiceRegistryStateParameters
Ces valeurs de Registre fournies par l’INF dans la sous-clé « Parameters » pour le service doivent être lues uniquement au moment de l’exécution et non modifiées. Ils doivent être traités en lecture seule.
Si les valeurs de Registre fournies par l’inf sont des paramètres par défaut qui peuvent être remplacés au moment de l’exécution, les valeurs de remplacement doivent être écrites dans l’état du registre de service interne ou dans l’état du registre du service partagé pour le service. Lors de la récupération des paramètres, vous pouvez d’abord rechercher le paramètre dans l’état mutable. S’il n’existe pas ici, le paramètre peut être recherché dans l’état immuable. RtlQueryRegistryValueWithFallback peut être utilisé pour aider à interroger des paramètres tels que ceux-ci qui ont un remplacement et une valeur par défaut.
État du registre de service interne
L’état du service interne est un état écrit au moment de l’exécution, détenu et géré par le service lui-même et accessible uniquement à ce service. Pour accéder à l’emplacement de l’état du service interne, utilisez l’une des fonctions suivantes à partir du service :
IoOpenDriverRegistryKey (WDM) avec un DRIVER_REGKEY_TYPE de DriverRegKeyPersistentState
GetServiceRegistryStateKey (Win32 Services) avec une SERVICE_REGISTRY_STATE_TYPE de ServiceRegistryStatePersistent
Si le service souhaite autoriser d’autres composants à modifier ces paramètres, le service doit exposer une interface qu’un autre composant peut appeler et qui indique au service comment modifier ces paramètres. Par exemple, un service Win32 peut exposer une interface COM ou RPC et un service de pilote peut exposer une interface IOCTL via une interface d’appareil.
État du registre de services partagés
L’état du service partagé est un état écrit au moment de l’exécution et qui peut être partagé avec d’autres composants du mode utilisateur s’ils sont suffisamment privilégiés. Pour accéder à l’emplacement de cet état de service partagé, utilisez l’une des fonctions suivantes :
IoOpenDriverRegistryKey (WDM) avec un DRIVER_REGKEY_TYPE de DriverRegKeySharedPersistentState
GetSharedServiceRegistryStateKey (Win32 Services) avec un SERVICE_SHARED_REGISTRY_STATE_TYPE de ServiceSharedRegistryPersistentState
État du fichier
Cette section comporte les sous-sections suivantes :
État du fichier de l’appareil
Si des fichiers liés à un appareil doivent être écrits au moment de l’exécution, ces fichiers doivent être stockés par rapport à un handle ou à un chemin de fichier fourni via les API du système d’exploitation. Les fichiers de configuration spécifiques à cet appareil sont un exemple des types de fichiers à stocker ici. Pour accéder à l’emplacement de cet état, utilisez l’une des fonctions suivantes à partir du service :
IoGetDeviceDirectory (WDM) avec le paramètre DirectoryType défini sur DeviceDirectoryData
État du fichier de service
L’état du fichier de service peut être classé dans l’une des trois catégories suivantes :
État du fichier de service immuable
L’état immuable du fichier de service est des fichiers qui font partie du package de pilotes. Pour plus d’informations sur l’accès à ces fichiers, consultez Exécuter à partir du magasin de pilotes.
État du fichier de service interne
L’état du fichier de service interne est un état écrit au moment de l’exécution, détenu et géré uniquement par le service lui-même et accessible uniquement à ce service. Pour accéder à l’emplacement de l’état du service interne, utilisez l’une des fonctions suivantes à partir du service :
IoGetDriverDirectory (WDM, KMDF) avec le paramètre DirectoryType défini sur DriverDirectoryData
GetServiceDirectory (Win32 Services) avec le paramètre eDirectoryType défini sur ServiceDirectoryPersistentState
Si le service souhaite autoriser d’autres composants à modifier ces paramètres, le service doit exposer une interface qu’un autre composant peut appeler et qui indique au service comment modifier ces paramètres. Par exemple, un service Win32 peut exposer une interface COM ou RPC et un service de pilote peut exposer une interface IOCTL via une interface d’appareil.
État du fichier de service partagé
L’état du fichier de service partagé est un état écrit au moment de l’exécution et qui peut être partagé avec d’autres composants du mode utilisateur s’ils sont suffisamment privilégiés. Pour accéder à l’emplacement de cet état de service partagé, utilisez l’une des fonctions suivantes :
IoGetDriverDirectory (WDM, KMDF) avec le paramètre DirectoryType défini sur DriverDirectorySharedData
GetSharedServiceDirectory (Win32 Services) avec le paramètre DirectoryType défini sur ServiceSharedDirectoryPersistentState
DriverData et ProgramData
Les fichiers qui peuvent être partagés avec d’autres composants, mais qui ne correspondent pas à DriverData
la catégorie d’état de fichier de service partagé peuvent être écrits dans les emplacements ou ProgramData
.
Ces emplacements offrent aux composants un emplacement pour écrire un état temporaire destiné à être consommé par d’autres composants et éventuellement collecté et copié à partir d’un système pour être traité par un autre système. Par exemple, les fichiers journaux personnalisés ou les vidages sur incident correspondent à cette description.
Évitez d’écrire des fichiers à la racine des DriverData
répertoires ou ProgramData
. Au lieu de cela, créez un sous-répertoire avec le nom de votre entreprise, puis écrivez des fichiers et d’autres sous-répertoires dans ce répertoire.
Par exemple, pour un nom d’entreprise de Contoso, un pilote en mode noyau peut écrire un journal \DriverData\Contoso\Logs
personnalisé dans et une application en mode utilisateur peut collecter ou analyser les fichiers journaux à partir de %DriverData%\Contoso\Logs
.
DriverData
Le DriverData
répertoire est disponible dans Windows 10, version 1803 et ultérieure, et est accessible aux administrateurs et aux pilotes UMDF.
Les pilotes en mode noyau accèdent au répertoire à l’aide DriverData
d’un lien symbolique fourni par le système appelé \DriverData
.
Les programmes en mode utilisateur accèdent au répertoire à l’aide DriverData
de la variable %DriverData%
d’environnement .
ProgramData
La %ProgramData%
variable d’environnement en mode utilisateur est disponible pour les composants en mode utilisateur à utiliser lors du stockage des données.
Fichiers temporaires
Les fichiers temporaires sont généralement utilisés dans les opérations intermédiaires. Ceux-ci peuvent être écrits dans un sous-chemin sous les variables d’environnement %TEMP%
ou %TMP%
. Étant donné que ces emplacements sont accessibles via des variables d’environnement, cette fonctionnalité est limitée aux composants du mode utilisateur. Il n’existe aucune garantie sur la durée de vie ou la persistance de ces fichiers temporaires après la fermeture des handles qu’ils contiennent. Le système d’exploitation ou l’utilisateur peut les supprimer à tout moment et elles peuvent ne pas être conservées pendant un redémarrage.
Évitez d’écrire des fichiers à la racine des %TEMP%
répertoires ou %TMP%
. Au lieu de cela, créez un sous-répertoire avec le nom de votre entreprise, puis écrivez des fichiers et d’autres sous-répertoires dans ce répertoire.
État de la propriété
Les appareils et les interfaces d’appareil prennent en charge le stockage de l’état via le modèle de propriété PnP. Le modèle de propriété permet de stocker des données de propriété structurées sur un appareil ou une interface d’appareil. Cela est destiné aux données plus petites qui s’intègrent raisonnablement dans les types de propriétés pris en charge par le modèle de propriété.
Pour accéder aux propriétés de l’appareil, vous pouvez utiliser ces API :
Pilotes WDM
Pilotes WDF
Code du mode utilisateur
Pour accéder aux propriétés de l’interface de l’appareil, vous pouvez utiliser ces API :
Pilotes WDM
Pilotes WDF
Code du mode utilisateur
Utilisation des interfaces d’appareil
Si un pilote souhaite autoriser d’autres composants à lire ou modifier l’état interne du pilote, il doit exposer une interface qu’un autre composant peut appeler pour indiquer au pilote quels paramètres retourner ou comment modifier des paramètres particuliers. Par exemple, le service de pilote peut exposer une interface IOCTL via une interface de périphérique.
En règle générale, le pilote propriétaire de l’état expose une interface de périphérique dans une classe d’interface de périphérique personnalisée. Lorsque le pilote est prêt pour que d’autres composants aient accès à l’état, il active l’interface. Pour être averti lorsqu’une interface d’appareil est activée, les composants en mode utilisateur peuvent s’inscrire aux notifications d’arrivée de l’interface de l’appareil et les composants en mode noyau peuvent utiliser IoRegisterPlugPlayNotification. Pour que ces composants accèdent à l’état, le pilote qui active l’interface doit définir un contrat pour sa classe d’interface de périphérique personnalisée. Ce contrat est généralement de deux types :
Un contrat d’E/S peut être associé à cette classe d’interface d’appareil qui fournit un mécanisme d’accès à l’état. D’autres composants utilisent l’interface d’appareil activée pour envoyer des demandes d’E/S conformes au contrat.
Interface d’appel direct qui est retournée via une interface de requête. D’autres pilotes peuvent envoyer des IRP_MN_QUERY_INTERFACE pour récupérer des pointeurs de fonction à partir du pilote à appeler.
Sinon, si le pilote propriétaire de l’état autorise l’accès direct à l’état, d’autres pilotes peuvent accéder à l’état à l’aide de fonctions fournies par le système pour l’accès par programmation à l’état de l’interface de périphérique. Pour plus d’informations, consultez État du registre de l’interface d’appareil.
Ces interfaces ou ces états (en fonction de la méthode de partage utilisée) doivent être correctement versionnés afin que le pilote propriétaire de l’état puisse être géré indépendamment des autres composants qui accèdent à cet état. Les fournisseurs de pilotes ne peuvent pas s’appuyer sur d’autres composants qui sont pris en charge en même temps que le pilote et restent à la même version.
Étant donné que les appareils et les pilotes contrôlant les interfaces vont et viennent, les pilotes et les applications doivent éviter d’appeler IoGetDeviceInterfaces au démarrage du composant pour obtenir la liste des interfaces activées. Au lieu de cela, la meilleure pratique consiste à s’inscrire aux notifications d’arrivée ou de suppression de l’interface de l’appareil, puis d’appeler la fonction appropriée pour obtenir la liste des interfaces activées existantes sur l’ordinateur.
Pour plus d’informations sur les interfaces d’appareil, consultez :
Inscription à la notification de l’arrivée et de la suppression de l’appareil
Inscription à la notification de modification de l’interface d’appareil
Référence rapide de la prise en charge du système d’exploitation pour les API de gestion d’état
La plupart des packages de pilotes doivent prendre en charge une gamme de versions de système d’exploitation. Pour plus d’informations sur la façon d’y parvenir dans un package de pilotes, consultez Prise en charge de plusieurs versions de système d’exploitation . Les tableaux suivants fournissent une référence rapide du moment où la prise en charge du système d’exploitation a été ajoutée pour diverses API de gestion d’état.
Pilotes WDM
Système d’exploitation | Prise en charge ajoutée |
---|---|
Windows 2000 |
IoOpenDeviceRegistryKey IoOpenDeviceInterfaceRegistryKey |
Windows Vista |
IoGetDevicePropertyData IoSetDevicePropertyData |
Windows 8 |
IoGetDeviceInterfacePropertyData IoSetDeviceInterfacePropertyData |
Windows 8.1 | IoQueryFullDriverPath |
Windows 10 1803 |
IoOpenDriverRegistryKey pour RegKeyType de DriverRegKeyParameters et DriverRegKeyPersistentState IoGetDeviceDirectory IoGetDriverDirectory pour DirectoryType de DriverDirectoryImage et DriverDirectoryData |
Windows 10 1809 | RtlQueryRegistryValueWithFallback |
Windows 11 21H2 |
IoOpenDriverRegistryKey pour RegKeyType de DriverRegKeySharedPersistentState IoGetDriverDirectory pour DirectoryType de DriverDirectorySharedData |
Pilotes KMDF
Pilotes UMDF
Code du mode utilisateur
Système d’exploitation | Prise en charge ajoutée |
---|---|
Windows 2000 | CM_Open_DevNode_Key |
Windows Vista |
CM_Open_Device_Interface_Key CM_Get_DevNode_Property CM_Set_DevNode_Property CM_Get_Device_Interface_Property CM_Set_Device_Interface_Property |
Windows 10 2004 |
GetServiceRegistryStateKey GetServiceDirectory |
Windows 11 21H2 |
GetSharedServiceRegistryStateKey GetSharedServiceDirectory |