Aislamiento del paquete de controladores

El aislamiento del paquete de controladores es un requisito para los controladores de Windows que hace que los paquetes de controladores sean más resistentes a los cambios externos, sean más fáciles de actualizar y sean más sencillos de instalar.

Nota

Aunque el aislamiento del paquete de controladores es necesario para los controladores de Windows, los controladores de escritorio de Windows siguen beneficiándose de él a través de una mejor resistencia y capacidad de servicio.

En la tabla siguiente se muestran algunos procedimientos de paquetes de controladores heredados de ejemplo que ya no se permiten para controladores de Windows en la columna izquierda junto con el comportamiento necesario para los controladores de Windows en la columna derecha.

Controlador no aislado Controlador aislado
INF copia archivos en %windir%\System32 o %windir%\System32\drivers Los archivos de controlador se ejecutan desde el almacén de controladores
Interactúa con pilas de dispositivos o controladores mediante rutas de acceso codificadas de forma rígida Interactúa con pilas de dispositivos o controladores mediante funciones proporcionadas por el sistema o interfaces de dispositivo
Codifica de forma rígida 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 escribe en cualquier ubicación Los archivos se escriben en relación con las ubicaciones proporcionadas por el sistema operativo.

Para obtener ayuda para 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 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 al instalar. Para obtener más información sobre cómo usar esto en un paquete de controladores, vea Ejecutar desde el almacén de controladores.

Lectura y escritura del 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 de sistema operativo adecuadas para almacenar y acceder al estado. Las instrucciones siguientes para el registro y el estado de archivo son para otro estado que un componente debe almacenar.

El acceso a varios registros y estados de archivo debe realizarse mediante una llamada a funciones que proporcionan un llamador con 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 y rutas de acceso de archivo codificadas de forma rígida.

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 las dos ubicaciones para almacenar el estado del dispositivo en el registro. Estas son la clave de hardware (clave de dispositivo) para el dispositivo y la clave de software (clave de controlador) del dispositivo. La clave de hardware suele ser para la configuración relacionada con cómo interactúa una instancia de dispositivo individual 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 cómo interactúa una instancia de dispositivo individual con el sistema y 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 de un dispositivo. Para recuperar un identificador de estas ubicaciones del Registro, use una de las siguientes opciones:

[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:

Estado del Registro del servicio

El estado del servicio debe clasificarse en una de las tres categorías

Estado del registro del 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 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 de la sección de instalación del servicio en 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:

Estos valores del Registro proporcionados por el INF en la subclave "Parameters" del 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 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, el valor se puede buscar primero en el estado mutable. Si no existe allí, se puede buscar la configuración en el estado inmutable. RtlQueryRegistryValueWithFallback se puede usar para ayudar a consultar valores como estos que tienen una invalidación y un valor predeterminado.

Estado interno del registro del servicio

El estado interno del servicio es el estado que se escribe en tiempo de ejecución y es propiedad y se administra solo mediante el propio servicio y solo es accesible para ese servicio. Para acceder a la ubicación del estado interno del servicio, use una de estas funciones desde el servicio:

Si el servicio quiere permitir que otros componentes modifiquen esta configuración, el servicio debe exponer una interfaz a la que otro componente pueda llamar a 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 controlador 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 del modo de usuario si tienen privilegios suficientes. Para acceder a la ubicación de este estado de servicio compartido, use una de estas funciones:

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 se deben almacenar en relación con una ruta de acceso de identificador o 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 qué tipos de archivos se almacenarán aquí. Para acceder a la ubicación de este estado, use una de estas funciones desde el servicio:

Estado del archivo de servicio

El estado del archivo de servicio se puede clasificar en una de las tres categorías

Estado de archivo de servicio inmutable

El estado del archivo de servicio inmutable son archivos que forman parte del paquete de controladores. Para obtener más información sobre el acceso a esos archivos, consulte Ejecutar desde el almacén de controladores.

Estado interno del archivo de servicio

El estado interno del archivo de servicio es el estado que se escribe en tiempo de ejecución y es propiedad y se administra solo por el propio servicio y solo es accesible para ese servicio. Para acceder a la ubicación del estado interno del servicio, use una de estas funciones desde el servicio:

Si el servicio quiere permitir que otros componentes modifiquen esta configuración, el servicio debe exponer una interfaz a la que otro componente pueda llamar a 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 controlador podría exponer una interfaz IOCTL a través de una interfaz de dispositivo.

Estado del archivo de servicio compartido

El estado del archivo de servicio compartido es el estado que se escribe en tiempo de ejecución y se puede compartir con otros componentes del 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 caben en la categoría de estado de archivo de servicio compartido se pueden escribir en cualquiera de las DriverData ubicaciones o ProgramData .

Estas ubicaciones ofrecen a los componentes una ubicación para escribir el estado temporal o el estado que está pensado para 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 DriverData directorios o ProgramData . En su lugar, cree un subdirectorio con el nombre de la empresa y, a continuación, escriba archivos y subdirectorios adicionales 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 DriverData directorio está disponible en Windows 10, versión 1803 y posteriores, y es accesible para administradores y controladores UMDF.

Los controladores en modo kernel acceden al directorio mediante un vínculo simbólico proporcionado por el DriverData sistema denominado \DriverData.

Los programas en modo de usuario acceden al DriverData directorio mediante la variable %DriverData%de entorno .

ProgramData

La %ProgramData% variable de entorno en modo de usuario está disponible para que los componentes en modo de usuario se usen al almacenar datos.

Archivos temporales

Los archivos temporales se suelen usar en operaciones intermedias. Se pueden escribir en una subruta en las %TEMP% variables de entorno o %TMP% . Puesto que se accede a estas ubicaciones a través de variables de entorno, esta capacidad se limita a los componentes del 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 %TEMP% directorios o %TMP% . En su lugar, cree un subdirectorio con el nombre de la empresa y, a continuación, escriba archivos y subdirectorios adicionales dentro de ese directorio.

Estado de la propiedad

Tanto los dispositivos como las interfaces de dispositivo admiten el almacenamiento de estado a través del modelo de propiedades PnP. El modelo de propiedades permite almacenar 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 propiedad.

Para acceder a las propiedades del dispositivo, se pueden usar estas API:

Para acceder a las propiedades de la interfaz de dispositivo, se pueden usar estas API:

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 que indique al controlador qué configuración devolver o cómo modificar una configuración determinada. Por ejemplo, el servicio de controladores 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 del modo de usuario pueden registrarse para las notificaciones de llegada de la interfaz de dispositivo y los componentes del 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 uno 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.

  • 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 propietario del estado permite el acceso directo al estado, otros controladores podrían acceder al estado mediante funciones proporcionadas por el sistema para el acceso mediante programación al estado de la interfaz del dispositivo. Consulte Estado del Registro de la interfaz de dispositivo para obtener más información.

Estas interfaces o estados (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 tengan acceso a ese estado. Los proveedores de controladores no pueden confiar en otros componentes que se atenden al mismo tiempo que el controlador y permanezcan en la misma versión.

Dado que los dispositivos y controladores que controlan las interfaces vienen y van, los controladores y las aplicaciones deben evitar llamar a IoGetDeviceInterfaces en el inicio del componente para obtener una lista de 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 deben 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 lograrlo 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 WDM

Sistema operativo Se ha agregado compatibilidad
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 for DirectoryType of DriverDirectoryImage and DriverDirectoryData
Windows 10 1809 RtlQueryRegistryValueWithFallback
Windows 11 21H2 IoOpenDriverRegistryKey para RegKeyType de DriverRegKeySharedPersistentState
IoGetDriverDirectory for DirectoryType of DriverDirectorySharedData

Controladores kmdf

Versión de KMDF Se ha agregado compatibilidad
1.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
1.13 WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
1,25 WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)

Controladores de UMDF

Versión de UMDF Se ha agregado compatibilidad
2.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
WdfDeviceQueryInterfaceProperty (Windows 8.1)
WdfDeviceAllocAndQueryInterfaceProperty (Windows 8.1)
WdfDeviceAssignInterfaceProperty (Windows 8.1)
2.25 WdfDeviceRetrieveDeviceDirectoryString
WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)
2,27 WdfDriverRetrieveDriverDataDirectoryString

Código en modo de usuario

Sistema operativo Se ha agregado compatibilidad
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