Aislamiento de paquetes de controladores
El aislamiento del paquete de controladores es un requisito para controladores de Windows que hace que los paquetes de controladores sean más resistentes a los cambios externos, más fáciles de actualizar y más sencillos de instalar.
Nota:
Aunque se requiere el aislamiento del paquete de controladores para controladores de Windows, los controladores de escritorio de Windows siguen beneficiándose de él a través de la resistencia y la capacidad de servicio mejoradas.
En la tabla siguiente se muestran algunos procedimientos de paquetes de controladores heredados de ejemplo que ya no están permitidos para controladores de Windows en la columna izquierda junto con el comportamiento necesario para controladores de Windows en la columna derecha.
Controlador no aislado | Controlador aislado |
---|---|
INF copia los archivos en %windir%\System32 o %windir%\System32\drivers | Los archivos de controlador se ejecutan desde el almacén de controladores |
Interactúa con pilas o controladores de dispositivos mediante rutas de acceso con codificación fija | Interactúa con pilas o controladores de dispositivos mediante funciones o interfaces de dispositivo proporcionadas por el sistema |
Codifica de forma fija la ruta de acceso a las ubicaciones globales del registro | Usa HKR y funciones proporcionadas por el sistema para la ubicación relativa del estado del registro y del archivo |
El archivo en tiempo de ejecución se escribe en cualquier ubicación | Los archivos se escriben en relación con las ubicaciones proporcionadas por el sistema operativo. |
Para ayudar a determinar si el paquete de controladores cumple los requisitos de aislamiento del paquete de controladores, consulte Validación de controladores de Windows. Para obtener ejemplos de cómo actualizar un INF para cumplir los requisitos de aislamiento del paquete de controladores, consulte Migración de un INF para seguir el aislamiento del paquete de controladores.
Ejecución desde el almacén de controladores
Todos los paquetes de controladores aislados dejan sus archivos de paquete de controladores en el almacén de controladores. Esto significa que especifican DIRID 13 en su INF para especificar la ubicación de los archivos de paquete de controladores en la instalación. Para obtener más información sobre cómo se usa esto en un paquete de controladores, consulte Ejecución desde el almacén de controladores.
Lectura y escritura de estado
Nota:
Si el componente usa propiedades de interfaz de dispositivo o dispositivo para almacenar el estado, siga usando ese método y las API del sistema operativo adecuadas para almacenar y acceder al estado. La siguiente guía para el estado del registro y del archivo es para otro estado que un componente debe almacenar.
El acceso a varios estados de registro y archivo debe realizarse mediante una llamada a funciones que proporcionan a un llamador la ubicación del estado y, a continuación, el estado se lee y escribe en relación con esa ubicación. No use rutas de acceso absolutas del registro ni rutas de acceso de archivo con codificación fija.
Esta sección contiene las siguientes subsecciones:
Estado del registro
Esta sección contiene las siguientes subsecciones:
Estado del registro del dispositivo PnP
Los paquetes de controladores aislados y los componentes en modo de usuario suelen usar una de estas dos ubicaciones para almacenar el estado del dispositivo en el registro. Son la clave de hardware (clave de dispositivo) para el dispositivo y la clave de software (clave de controlador) para el dispositivo. La clave de hardware suele ser para la configuración relacionada con el modo en que una instancia de dispositivo individual interactúa con el hardware. Por ejemplo, para habilitar una característica de hardware o colocar el hardware en un modo específico. La clave de software suele ser para la configuración relacionada con el modo en que una instancia de dispositivo individual interactúa con el sistema y con otro software. Por ejemplo, para configurar la ubicación de un archivo de datos, para interoperar con un marco o para acceder a la configuración de la aplicación para un dispositivo. Para recuperar un identificador de estas ubicaciones del registro, use una de las siguientes opciones:
IoOpenDeviceRegistryKey (WDM)
CM_Open_DevNode_Key (código en modo de usuario)
Directiva INF AddReg mediante entradas HKR reg-root en una add-registry-section a la que se hace referencia desde una sección INF DDInstall o DDInstall.HW, como se muestra a continuación:
[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg
[Example_DDInstall.AddReg]
HKR,,ExampleValue,,%13%\ExampleFile.dll
Estado del registro de la interfaz de dispositivo
Para leer y escribir el estado del registro de la interfaz de dispositivo, use una de las siguientes opciones:
CM_Open_Device_Interface_Key (código en modo de usuario)
Directiva INF AddReg mediante entradas reg-root en una add-registry-section a la que se hace referencia desde una sección add-interface-section
Estado del registro de servicio
El estado del servicio debe clasificarse en una de tres categorías.
Estado del registro de servicio inmutable
El estado del servicio inmutable es el estado proporcionado por el paquete de controladores que instala el servicio. Estos valores del registro establecidos por el INF para el controlador y los servicios Win32 deben almacenarse en la subclave "Parameters" del servicio proporcionando una línea HKR en una sección AddReg y, a continuación, haciendo referencia a esa sección en la sección de instalación del servicio en el INF. Por ejemplo:
[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
Para acceder a la ubicación de este estado desde el servicio en tiempo de ejecución, use una de estas funciones:
IoOpenDriverRegistryKey (WDM) con un DRIVER_REGKEY_TYPE de DriverRegKeyParameters
GetServiceRegistryStateKey (Win32 Services) con un SERVICE_REGISTRY_STATE_TYPE de ServiceRegistryStateParameters
Estos valores del registro proporcionados por el INF en la subclave "Parameters" para el servicio solo deben leerse en tiempo de ejecución y no modificarse. Deben tratarse como de solo lectura.
Si los valores del registro proporcionados por el INF son valores predeterminados que se pueden sobrescribir en tiempo de ejecución, los valores de invalidación deben escribirse en el estado del registro de servicio interno o en el estado del registro de servicio compartido para el servicio. Al recuperar la configuración, los valores se pueden buscar primero en el estado mutable. Si no existen allí, se pueden buscar en el estado inmutable. RtlQueryRegistryValueWithFallback se puede usar para ayudar a la configuración de consulta, como estas que tienen una invalidación y un valor predeterminado.
Estado del registro del servicio interno
El estado del servicio interno es el estado que se escribe en tiempo de ejecución y que solo es propiedad y está administrado por el propio servicio y solo es accesible para ese servicio. Para acceder a la ubicación del estado del servicio interno, use una de estas funciones desde el servicio:
IoOpenDriverRegistryKey (WDM) con un DRIVER_REGKEY_TYPE de DriverRegKeyPersistentState
GetServiceRegistryStateKey (Win32 Services) con un SERVICE_REGISTRY_STATE_TYPE de ServiceRegistryStatePersistent
Si el servicio quiere permitir que otros componentes modifiquen esta configuración, debe exponer una interfaz a la que otro componente pueda llamar y que indique al servicio cómo modificar esta configuración. Por ejemplo, un servicio Win32 podría exponer una interfaz COM o RPC y un servicio de controladores podría exponer una interfaz IOCTL a través de una interfaz de dispositivo.
Estado del registro del servicio compartido
El estado del servicio compartido es el estado que se escribe en tiempo de ejecución y se puede compartir con otros componentes en modo de usuario si tienen privilegios suficientes. Para acceder a la ubicación de este estado de servicio compartido, use una de estas funciones:
IoOpenDriverRegistryKey (WDM) con un DRIVER_REGKEY_TYPE de DriverRegKeySharedPersistentState
GetSharedServiceRegistryStateKey (Servicios Win32) con un SERVICE_SHARED_REGISTRY_STATE_TYPE de ServiceSharedRegistryPersistentState
Estado del archivo
Esta sección contiene las siguientes subsecciones:
Estado del archivo de dispositivo
Si los archivos relacionados con un dispositivo deben escribirse en tiempo de ejecución, esos archivos deben almacenarse en relación con un identificador o una ruta de acceso de archivo proporcionada a través de la API del sistema operativo. Los archivos de configuración específicos de ese dispositivo son un ejemplo de los tipos de archivos que se van a almacenar aquí. Para acceder a la ubicación de este estado, use una de estas funciones desde el servicio:
IoGetDeviceDirectory (WDM) con el parámetro DirectoryType establecido en DeviceDirectoryData
Estado del archivo de servicio
El estado del archivo del servicio se puede clasificar en una de tres categorías.
Estado del archivo de servicio inmutable
El estado del archivo de servicio inmutable corresponde a archivos que forman parte del paquete de controladores. Para obtener más información sobre cómo acceder a esos archivos, consulte Ejecución desde el almacén de controladores.
Estado del archivo de servicio interno
El estado del archivo del servicio interno es el estado que se escribe en tiempo de ejecución y que solo es propiedad y está administrado por el propio servicio y solo es accesible para ese servicio. Para acceder a la ubicación del estado del servicio interno, use una de estas funciones desde el servicio:
IoGetDriverDirectory (WDM, KMDF) con el parámetro DirectoryType establecido en DriverDirectoryData
GetServiceDirectory (Win32 Services) con el parámetro eDirectoryType establecido en ServiceDirectoryPersistentState
Si el servicio quiere permitir que otros componentes modifiquen esta configuración, debe exponer una interfaz a la que otro componente pueda llamar y que indique al servicio cómo modificar esta configuración. Por ejemplo, un servicio Win32 podría exponer una interfaz COM o RPC y un servicio de controladores podría exponer una interfaz IOCTL a través de una interfaz de dispositivo.
Estado del archivo de servicio compartido
El estado del archivo del servicio compartido es el estado que se escribe en tiempo de ejecución y se puede compartir con otros componentes en modo de usuario si tienen privilegios suficientes. Para acceder a la ubicación de este estado de servicio compartido, use una de estas funciones:
IoGetDriverDirectory (WDM, KMDF) con el parámetro DirectoryType establecido en DriverDirectorySharedData
GetSharedServiceDirectory (Win32 Services) con el parámetro DirectoryType establecido en ServiceSharedDirectoryPersistentState
DriverData y ProgramData
Los archivos que se pueden compartir con otros componentes pero que no entran en la categoría de estado de archivo de servicio compartido se pueden escribir en cualquiera de las ubicaciones DriverData
o ProgramData
.
Estas ubicaciones ofrecen a los componentes una ubicación para escribir el estado temporal o el estado destinado a ser consumido por otros componentes y potencialmente recopilados y copiados de un sistema que otro sistema va a procesar. Por ejemplo, los archivos de registro personalizados o los volcados de memoria se ajustan a esta descripción.
Evite escribir archivos en la raíz de los directorios DriverData
o ProgramData
. En su lugar, cree un subdirectorio con el nombre de la compañía y, a continuación, escriba archivos y otros subdirectorios dentro de ese directorio.
Por ejemplo, para un nombre de empresa de Contoso, un controlador en modo kernel podría escribir un registro personalizado en \DriverData\Contoso\Logs
y una aplicación en modo de usuario podría recopilar o analizar los archivos de registro de %DriverData%\Contoso\Logs
.
DriverData
El directorio DriverData
está disponible en Windows 10, versión 1803 y posteriores, y es accesible para los administradores y controladores UMDF.
Los controladores en modo kernel acceden al directorio DriverData
mediante un vínculo simbólico proporcionado por el sistema denominado \DriverData
.
Los programas en modo de usuario acceden al directorio DriverData
1mediante la variable de entorno %DriverData%
.
ProgramData
La variable de entorno en modo de usuario %ProgramData%
está disponible para que los componentes en modo de usuario la usen al almacenar datos.
Archivos temporales
Normalmente, los archivos temporales se usan en operaciones intermedias. Se pueden escribir en una subruta en las variables de entorno %TEMP%
o %TMP%
. Dado que se accede a estas ubicaciones a través de variables de entorno, esta capacidad se limita a los componentes en modo de usuario. No hay ninguna garantía sobre la duración o persistencia de estos archivos temporales después de que se cierren los identificadores. El sistema operativo o el usuario pueden quitarlos en cualquier momento y es posible que no persistan en un reinicio.
Evite escribir archivos en la raíz de los directorios %TEMP%
o %TMP%
. En su lugar, cree un subdirectorio con el nombre de la compañía y, a continuación, escriba archivos y otros subdirectorios dentro de ese directorio.
Estado de la propiedad
Tanto los dispositivos como las interfaces de dispositivo admiten el almacenamiento del estado a través del modelo de propiedades PnP. El modelo de propiedades permite almacenar los datos de propiedad estructurados en una interfaz de dispositivo o dispositivo. Esto está pensado para datos más pequeños que se ajustan razonablemente a los tipos de propiedad admitidos por el modelo de propiedades.
Para acceder a las propiedades del dispositivo, se pueden usar estas API:
Controladores de WDM
Controladores de WDF
Código en modo de usuario
Para acceder a las propiedades de interfaz del dispositivo, se pueden usar estas API:
Controladores de WDM
Controladores de WDF
Código en modo de usuario
Uso de interfaces de dispositivo
Si un controlador quiere permitir que otros componentes lean o modifiquen el estado interno del controlador, el controlador debe exponer una interfaz a la que otro componente pueda llamar en que indique al controlador qué configuración devolver o cómo modificar determinadas configuraciones. Por ejemplo, el servicio de controlador podría exponer una interfaz IOCTL a través de una interfaz de dispositivo.
Normalmente, el controlador que posee el estado expone una interfaz de dispositivo en una clase de interfaz de dispositivo personalizada. Cuando el controlador está listo para que otros componentes tengan acceso al estado, habilita la interfaz. Para recibir notificaciones cuando se habilita una interfaz de dispositivo, los componentes en modo de usuario pueden registrarse para recibir notificaciones de llegada de interfaz de dispositivo y los componentes en modo kernel pueden usar IoRegisterPlugPlayNotification. Para que estos componentes accedan al estado, el controlador que habilita la interfaz debe definir un contrato para su clase de interfaz de dispositivo personalizada. Este contrato suele ser de dos tipos:
Un contrato de E/S se puede asociar a esa clase de interfaz de dispositivo que proporciona un mecanismo para acceder al estado. Otros componentes usan la interfaz de dispositivo habilitada para enviar solicitudes de E/S que cumplan el contrato.
Una interfaz de llamada directa que se devuelve a través de una interfaz de consulta. Otros controladores podrían enviar IRP_MN_QUERY_INTERFACE para recuperar punteros de función del controlador a los que llamar.
Como alternativa, si el controlador que posee el estado permite el acceso directo al estado, otros controladores podrían acceder al estado mediante funciones proporcionadas por el sistema para acceder mediante programación al estado de la interfaz del dispositivo. Consulte Estado del registro de interfaz de dispositivo para obtener más información.
Estas interfaces o estado (según el método de uso compartido usado) deben tener una versión correcta para que el controlador que posee el estado se pueda atender independientemente de otros componentes que accedan a ese estado. Los proveedores de controladores no pueden depender de otros componentes que se atienden al mismo tiempo que el controlador y que permanecen en la misma versión.
Dado que los dispositivos y los controladores que controlan las interfaces aparecen y desaparecen, los controladores y las aplicaciones deben evitar llamar a IoGetDeviceInterfaces al inicio del componente para obtener una lista de las interfaces habilitadas. En su lugar, el procedimiento recomendado es registrarse para recibir notificaciones de llegada o eliminación de la interfaz de dispositivo y, a continuación, llamar a la función adecuada para obtener la lista de interfaces habilitadas existentes en la máquina.
Para obtener más información sobre las interfaces de dispositivo, consulte:
Referencia rápida de la compatibilidad del sistema operativo con las API de administración de estado
La mayoría de los paquetes de controladores necesitan admitir una variedad de versiones del sistema operativo. Consulte Compatibilidad con varias versiones del sistema operativo para obtener más información sobre cómo se consigue en un paquete de controladores. En las tablas siguientes se proporciona una referencia rápida de cuándo se agregó compatibilidad con el sistema operativo para varias API de administración de estado.
Controladores de WDM
Sistema operativo | Compatibilidad agregada |
---|---|
Windows 2000 | IoOpenDeviceRegistryKey IoOpenDeviceInterfaceRegistryKey |
Windows Vista | IoGetDevicePropertyData IoSetDevicePropertyData |
Windows 8 | IoGetDeviceInterfacePropertyData IoSetDeviceInterfacePropertyData |
Windows 8.1 | IoQueryFullDriverPath |
Windows 10 1803 | IoOpenDriverRegistryKey para RegKeyType de DriverRegKeyParameters y DriverRegKeyPersistentState IoGetDeviceDirectory IoGetDriverDirectory para DirectoryType de DriverDirectoryImage y DriverDirectoryData |
Windows 10 1809 | RtlQueryRegistryValueWithFallback |
Windows 11 21H2 | IoOpenDriverRegistryKey para RegKeyType de DriverRegKeySharedPersistentState IoGetDriverDirectory para DirectoryType de DriverDirectorySharedData |
Controladores de KMDF
Controladores de UMDF
Código en modo de usuario
Sistema operativo | Compatibilidad agregada |
---|---|
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 |