Uso de interfaces de dispositivo en controladores UMDF
Advertencia
UMDF 2 es la versión más reciente de UMDF y sustituye a UMDF 1. Todos los controladores UMDF nuevos deben escribirse con UMDF 2. No se agregan nuevas características a UMDF 1 y hay compatibilidad limitada con UMDF 1 en versiones más recientes de Windows 10. Los controladores universales de Windows deben usar UMDF 2.
Los ejemplos de UMDF 1 archivados se pueden encontrar en la Windows 11, versión 22H2 : actualización de ejemplos de controladores de mayo de 2022.
Para obtener más información, consulta Introducción con UMDF.
Una interfaz de dispositivo es un vínculo simbólico a un dispositivo Plug and Play (PnP) que una aplicación puede usar para acceder al dispositivo. Una aplicación en modo de usuario puede pasar el nombre de vínculo simbólico de la interfaz a un elemento de API, como la función CreateFile de Microsoft Win32. Para obtener el nombre de vínculo simbólico de una interfaz de dispositivo, la aplicación en modo de usuario puede llamar a funciones SetupDi . Para obtener más información sobre las funciones SetupDi, vea Funciones de la interfaz de dispositivo SetupDi.
Cada interfaz de dispositivo pertenece a una clase de interfaz de dispositivo. Por ejemplo, una pila de controladores para un dispositivo CD-ROM podría proporcionar una interfaz que pertenezca a la clase GUID_DEVINTERFACE_CDROM. Uno de los controladores del dispositivo CD-ROM registraría una instancia de la clase GUID_DEVINTERFACE_CDROM para informar al sistema y las aplicaciones de que un dispositivo CD-ROM está disponible. Para obtener más información sobre las clases de interfaz de dispositivo, consulte Introducción a las interfaces de dispositivo.
Registro de una interfaz de dispositivo
Para registrar una instancia de una clase de interfaz de dispositivo, un controlador basado en UMDF puede llamar a IWDFDevice::CreateDeviceInterface desde su función de devolución de llamada IDriverEntry::OnDeviceAdd . Si el controlador admite varias instancias de la interfaz, puede asignar una cadena de referencia única a cada instancia.
Habilitación y deshabilitación de una interfaz de dispositivo
Si la creación se realiza correctamente, el marco habilita y deshabilita automáticamente la interfaz en función del estado PnP del dispositivo.
Además, un controlador puede deshabilitar y volver a habilitar una interfaz de dispositivo según sea necesario. Por ejemplo, si un controlador determina que su dispositivo ha dejado de responder, el controlador puede llamar a IWDFDevice::AssignDeviceInterfaceState para deshabilitar las interfaces del dispositivo y prohibir que las aplicaciones obtengan nuevos identificadores a la interfaz. (Los identificadores existentes de la interfaz no se ven afectados). Si el dispositivo está disponible más adelante, el controlador puede volver a llamar a IWDFDevice::AssignDeviceInterfaceState para volver a habilitar las interfaces.
Recepción de solicitudes para acceder a una interfaz de dispositivo
Cuando una aplicación solicita acceso a la interfaz de dispositivo de un controlador, el marco llama a la función de devolución de llamada IQueueCallbackCreate::OnCreateFile del controlador. El controlador puede llamar a IWDFFile::RetrieveFileName para obtener el nombre del dispositivo o archivo al que accede la aplicación. Si el controlador especificó una cadena de referencia cuando registró la interfaz del dispositivo, el sistema operativo incluye la cadena de referencia en el archivo o el nombre del dispositivo que devuelve IWDFFile::RetrieveFileName .
Creación de eventos de dispositivo
El controlador basado en UMDF puede crear eventos personalizados específicos del dispositivo ( denominados eventos de dispositivo) llamando a IWDFDevice::P ostEvent. Un controlador que se ha registrado para usar cualquiera de las interfaces del dispositivo puede recibir notificaciones de los eventos personalizados de un dispositivo. Los controladores basados en UMDF reciben estas notificaciones proporcionando una función de devolución de llamada IRemoteInterfaceCallbackEvent::OnRemoteInterfaceEvent .
Los eventos personalizados son únicos para el dispositivo. Tanto el desarrollador del controlador que crea el evento como el desarrollador del controlador que recibe el evento deben comprender el significado del evento.
Acceso a la interfaz de dispositivo de otro controlador
Si desea que el controlador basado en UMDF envíe solicitudes de E/S a una interfaz de dispositivo que proporciona otro controlador, puede crear un destino de E/S remoto que represente la interfaz del dispositivo.
En primer lugar, el controlador debe registrarse para recibir una notificación cuando haya disponible una interfaz de dispositivo. Siga estos pasos:
Cuando el controlador llama a IWDFDriver::CreateDevice, el controlador puede proporcionar una interfaz IPnpCallbackRemoteInterfaceNotification . La función de devolución de llamada IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival de esta interfaz informa al controlador cuando hay interfaces de dispositivo disponibles.
Después de que el controlador llame a IWDFDriver::CreateDevice, puede llamar a IWDFDevice2::RegisterRemoteInterfaceNotification para cada interfaz de dispositivo que usará el controlador.
Posteriormente, el marco llama a la función de devolución de llamada IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival cada vez que haya disponible una interfaz de dispositivo especificada. La función de devolución de llamada puede llamar a IWDFRemoteInterfaceInitialize::GetInterfaceGuid e IWDFRemoteInterfaceInitialize::RetrieveSymbolicLink para determinar qué interfaz de dispositivo ha llegado.
La función de devolución de llamada IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival normalmente debe hacer lo siguiente:
Llame a IWDFDevice2::CreateRemoteInterface para crear un objeto de interfaz remota, proporcionando opcionalmente interfaces IRemoteInterfaceCallbackEvent e IRemoteInterfaceCallbackRemoval .
Llame a IWDFDevice2::CreateRemoteTarget para crear un objeto de destino remoto, proporcionando opcionalmente una interfaz IRemoteTargetCallbackRemoval .
Llame a IWDFRemoteTarget::OpenRemoteInterface para conectar la interfaz del dispositivo al destino remoto.
Si la interfaz del dispositivo es la que crea el enumerador de dispositivos de software SWENUM, el controlador debe llamar a OpenRemoteInterface desde un elemento de trabajo. (Por ejemplo, consulte la función QueueUserWorkItem en Windows SDK).
Ahora el controlador puede dar formato y enviar solicitudes de E/S al destino de E/S remoto.
Además de la función de devolución de llamada IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival , un controlador basado en UMDF puede proporcionar dos funciones de devolución de llamada adicionales para recibir notificaciones de eventos de interfaz de dispositivo:
La función de devolución de llamada IRemoteInterfaceCallbackRemoval::OnRemoteInterfaceRemoval notifica al controlador cuando se quita una interfaz de dispositivo.
La función de devolución de llamada IRemoteInterfaceCallbackEvent::OnRemoteInterfaceEvent notifica al controlador cuándo llegan los eventos personalizados de un dispositivo.