Compartir a través de


Cómo escribir el primer controlador de cliente USB (UMDF)

En este artículo, usará la plantilla Controlador de modo de usuario, USB (UMDF V2) proporcionada con Microsoft Visual Studio 2022 para escribir un controlador de cliente basado en un marco de controlador en modo usuario (UMDF). Después de compilar e instalar el controlador cliente, verá el controlador cliente en Administrador de dispositivos y verá la salida del controlador en un depurador.

UMDF (denominado marco de este artículo) se basa en el modelo de objetos de componentes (COM). Cada objeto de marco debe implementar IUnknown y sus métodos, QueryInterface, AddRef y Release, de forma predeterminada. Los métodos AddRef y Release administran la duración del objeto, por lo que el controlador de cliente no necesita mantener el recuento de referencias. El método QueryInterface permite al controlador cliente obtener punteros de interfaz a otros objetos de marco en el modelo de objetos de Windows Driver Frameworks (WDF). Los objetos framework realizan tareas de controlador complicadas e interactúan con Windows. Algunos objetos de marco exponen interfaces que permiten que un controlador de cliente interactúe con el marco.

Un controlador de cliente basado en UMDF se implementa como un servidor COM (DLL) en proceso y C++ es el lenguaje preferido para escribir un controlador cliente para un dispositivo USB. Normalmente, el controlador de cliente implementa varias interfaces expuestas por el marco de trabajo. En este artículo se hace referencia a una clase definida por el controlador de cliente que implementa interfaces de marco como una clase de devolución de llamada. Una vez que se crean instancias de estas clases, los objetos de devolución de llamada resultantes se asocian con determinados objetos de marco. Esta asociación ofrece al controlador de cliente la oportunidad de responder a eventos relacionados con el dispositivo o el sistema notificados por el marco. Cada vez que Windows notifica al marco sobre determinados eventos, el marco invoca la devolución de llamada del controlador cliente, si hay alguna disponible. De lo contrario, el marco continúa con el procesamiento predeterminado del evento. El código de plantilla define las clases de devolución de llamada de controlador, dispositivo y cola.

Para obtener una explicación sobre el código fuente generado por la plantilla, consulte Descripción del código de plantilla de UMDF para el controlador de cliente USB.

Antes de empezar

Para desarrollar, depurar e instalar un controlador en modo de usuario, necesita dos equipos:

  • Un equipo host que ejecuta Windows 10 o una versión posterior del sistema operativo Windows. El equipo host es el entorno de desarrollo, donde se escribe y depura el controlador.
  • Un equipo de destino que ejecute la versión del sistema operativo en el que desea probar el controlador, por ejemplo, Windows 11, versión 22H2. El equipo de destino tiene el controlador en modo de usuario que desea depurar y uno de los depuradores.

En algunos casos, donde el host y los equipos de destino ejecutan la misma versión de Windows, puede tener solo un equipo que ejecute Windows 10 o una versión posterior de Windows. En este artículo se da por supuesto que usa dos equipos para desarrollar, depurar e instalar el controlador en modo de usuario.

Antes de comenzar, asegúrese de cumplir los siguientes requisitos:

Requisitos de software

  • El equipo host tiene Visual Studio 2022.

  • El equipo host tiene el kit de controladores de Windows (WDK) más reciente para Windows 11, versión 22H2.

    El kit incluye encabezados, bibliotecas, herramientas, documentación y las herramientas de depuración necesarias para desarrollar, compilar y depurar un controlador de cliente USB. Puede obtener la versión más reciente del WDK de Cómo obtener el WDK.

  • El equipo host tiene la versión más reciente de las herramientas de depuración para Windows. Puede obtener la versión más reciente de WDK o puede descargar e instalar herramientas de depuración para Windows.

  • Si usa dos equipos, debe configurar los equipos host y de destino para la depuración en modo de usuario. Para obtener más información, vea Configuración de User-Mode depuración en Visual Studio.

Requisitos de hardware

Obtenga un dispositivo USB para el que escribirá el controlador de cliente. En la mayoría de los casos, se le proporciona un dispositivo USB y su especificación de hardware. La especificación describe las funcionalidades del dispositivo y los comandos de proveedor admitidos. Utilice la especificación para determinar la funcionalidad del controlador USB y las decisiones de diseño relacionadas.

Si no está familiarizado con el desarrollo de controladores USB, use el kit de aprendizaje de OSR USB FX2 para estudiar muestras USB incluidas con el WDK. Contiene el dispositivo USB FX2 y todas las especificaciones de hardware necesarias para implementar un controlador cliente.

Paso 1: Generar el código del controlador

Para obtener más información sobre cómo escribir código de controlador UMDF, consulte Escritura de un controlador UMDF basado en una plantilla.

Para código específico de USB, seleccione las siguientes opciones en Visual Studio 2022.

  1. En el cuadro de diálogo Nuevo proyecto , en el cuadro de búsqueda de la parte superior, escriba USB.
  2. En el panel central, seleccione Controlador de modo de usuario, USB (UMDF V2) .
  3. Seleccione Next (Siguiente).
  4. Escriba un nombre de proyecto, elija una ubicación de guardado y seleccione Crear.

En las capturas de pantalla siguientes se muestra el cuadro de diálogo Nuevo proyecto para la plantilla USB User-Mode Driver .

Captura de pantalla de las opciones de creación del proyecto de Visual Studio.

Captura de pantalla de la pantalla de configuración de creación de proyectos de Visual Studio.

En este artículo se supone que el nombre del proyecto es MyUSBDriver_UMDF_. Contiene los archivos siguientes:

Archivos Descripción
Driver.h; Driver.c Contiene la implementación del punto de entrada del módulo de controlador. DriverEntry y WDFDRIVER funcionalidades relacionadas y devoluciones de llamada.
Device.h; Device.c WDFDEVICE y WDFUSBDEVICE funcionalidad relacionada y devoluciones de llamada.
Queue.h; Queue.c Funcionalidad relacionada con WDFQUEUE y devoluciones de llamada.
Trace.h Define el GUID de la interfaz del dispositivo. También declara funciones y macros de seguimiento.
<Nombre del proyecto.inf> Archivo INF necesario para instalar el controlador cliente en el equipo de destino.

Paso 2: Agregar información sobre el dispositivo

Antes de compilar el controlador, debe agregar información sobre el dispositivo, específicamente el identificador de hardware. Para proporcionar el identificador de hardware:

  1. En la ventana Explorador de soluciones, haga clic con el botón derecho en MyUSBDriver_UMDF_ y elija Propiedades.
  2. En la ventana MyUSBDriver_UMDF_ páginas de propiedades , vaya a Configuración Propiedades > De instalación > de la implementación del controlador, como se muestra aquí. Captura de pantalla de la ventana de páginas de propiedades de Visual Studio 2022.
  3. Active Quitar versiones anteriores del controlador antes de la implementación.
  4. En Nombre del dispositivo de destino, seleccione el nombre del equipo que configuró para probar y depurar.
  5. Seleccione Hardware ID Driver Update (Actualización del controlador de identificador de hardware) y escriba el identificador de hardware del controlador. En este ejercicio, el identificador de hardware es Root\MyUSBDriver_UMDF_. Seleccione Aceptar.

Nota

En este ejercicio, el identificador de hardware no identifica un elemento real de hardware. Identifica un dispositivo imaginario que se asignará a un lugar en el árbol de dispositivos como elemento secundario del nodo raíz. Para hardware real, no seleccione Hardware ID Driver Update (Actualización del controlador de identificador de hardware). En su lugar, seleccione Instalar y comprobar. Puede ver el identificador de hardware en el archivo de información del controlador (INF). En la ventana Explorador de soluciones, vaya a MyUSBDriver_UMDF_ > Archivos de controlador y haga doble clic en MyUSBDriver_UMDF_.inf. El identificador de hardware está en [Standard.NT$ARCH$].

Todos los controladores de cliente USB basados en UMDF requieren dos controladores proporcionados por Microsoft, el reflector y WinUSB.

  • Reflector: si el controlador se carga correctamente, el reflector se carga como el controlador superior en la pila del modo kernel. El reflector debe ser el controlador superior de la pila del modo kernel. Para cumplir este requisito, el archivo INF de la plantilla especifica el reflector como servicio y WinUSB como un controlador de filtro inferior en inf:

    [MyDevice_Install.NT.Services]
    AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall  ; flag 0x2 sets this as the service for the device
    AddService=WinUsb,0x000001f8,WinUsb_ServiceInstall  ; this service is installed because its a filter.
    
  • WinUSB: el paquete de instalación debe contener coinstaladores para Winusb.sys porque para el controlador cliente, WinUSB es la puerta de enlace a la pila de controladores USB en modo kernel. Otro componente que se carga es un archivo DLL en modo de usuario, denominado WinUsb.dll, en el proceso de host del controlador cliente (Wudfhost.exe). Winusb.dll expone funciones de WinUSB que simplifican el proceso de comunicación entre el controlador cliente y WinUSB.

Paso 3: Compilación del código del controlador de cliente USB

Para compilar el controlador:

  1. Abra el proyecto de controlador o la solución en Visual Studio 2022.
  2. Haga clic con el botón derecho en la solución en el Explorador de soluciones y seleccione Configuration Manager.
  3. En el Configuration Manager, seleccione la configuración de la solución activa (por ejemplo, Depuración o versión) y la Plataforma de soluciones activas (por ejemplo, x64) que corresponden al tipo de compilación que le interesa.
  4. Compruebe que el GUID de la interfaz del dispositivo es preciso en todo el proyecto.
    • El GUID de la interfaz de dispositivo se define en Trace.h y se hace referencia a él desde MyUSBDriverUMDFCreateDevice en Device.c. Al crear el proyecto con el nombre MyUSBDriver_UMDF_, Visual Studio 2022 define el GUID de la interfaz de dispositivo con el nombre GUID_DEVINTERFACE_MyUSBDriver_UMDF_ , pero llama WdfDeviceCreateDeviceInterface a con el parámetro &GUID_DEVINTERFACE_MyUSBDriverUMDFincorrecto . Reemplace el parámetro incorrecto por el nombre definido en Trace.h para asegurarse de que el controlador se compila correctamente.
  5. En el menú Compilar, seleccione Compilar solución.

Para obtener más información, consulte Creación de un controlador.

Paso 4: Configurar un equipo para probar y depurar

Para probar y depurar un controlador, ejecute el depurador en el equipo host y el controlador en el equipo de destino. Hasta ahora, ha usado Visual Studio en el equipo host para compilar un controlador. A continuación, debe configurar un equipo de destino. Para configurar un equipo de destino, siga las instrucciones de Aprovisionamiento de un equipo para la implementación y las pruebas de controladores.

Paso 5: Habilitación del seguimiento para la depuración de kernel

El código de plantilla contiene varios mensajes de seguimiento (TraceEvents) que pueden ayudarle a realizar un seguimiento de las llamadas de función. Todas las funciones del código fuente contienen mensajes de seguimiento que marcan la entrada y salida de una rutina. En el caso de los errores, el mensaje de seguimiento contiene el código de error y una cadena significativa. Dado que el seguimiento de WPP está habilitado para el proyecto de controlador, el archivo de símboloS PDB creado durante el proceso de compilación contiene instrucciones de formato de mensaje de seguimiento. Si configura los equipos host y de destino para el seguimiento de WPP, el controlador puede enviar mensajes de seguimiento a un archivo o al depurador.

Para configurar el equipo host para el seguimiento de WPP

  1. Cree archivos de formato de mensaje de seguimiento (TMF) mediante la extracción de instrucciones de formato de mensaje de seguimiento del archivo de símbolos de PDB.

    Puede usar Tracepdb.exe para crear archivos TMF. La herramienta se encuentra en la <carpeta> de instalaciónWindows Kits\10\bin\<architecture> de WDK. El siguiente comando crea archivos TMF para el proyecto de controlador.

    tracepdb -f <PDBFiles> -p <TMFDirectory>
    

    La opción -f especifica la ubicación y el nombre del archivo de símbolos PDB. La opción -p especifica la ubicación de los archivos TMF creados por Tracepdb. Para obtener más información, vea Comandos tracepdb.

    Hay tres archivos en la ubicación especificada, uno por archivo de código de C en el proyecto. Se les asignan nombres de archivo GUID.

  2. En el depurador, escriba los siguientes comandos:

    .load Wmitrace
    .chain
    !wmitrace.searchpath + <TMF file location>
    

Estos comandos:

  • Cargue la extensión Wmitrace.dll.
  • Comprueba que se carga la extensión del depurador.
  • Agrega la ubicación de los archivos TMF a la ruta de búsqueda de la extensión del depurador.

La salida será similar a esta:

Trace Format search path is: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE;c:\drivers\tmf

Para configurar el equipo de destino para el seguimiento de WPP

  1. Asegúrese de que tiene la herramienta Tracelog en el equipo de destino. La herramienta se encuentra en la <carpeta install_folder>Windows Kits\10\Tools\<arch> del WDK. Para obtener más información, vea Sintaxis del comando tracelog.

  2. Abra una ventana de comandos y ejecute como administrador.

  3. Escriba el siguiente comando:

    tracelog -start MyTrace -guid \#c918ee71-68c7-4140-8f7d-c907abbcb05d -flag 0xFFFF -level 7-rt -kd
    

El comando inicia una sesión de seguimiento denominada MyTrace.

El argumento guid especifica el GUID del proveedor de seguimiento, que es el controlador de cliente. Puede obtener el GUID de Trace.h en el proyecto de Visual Studio 2022. Como otra opción, puede escribir el siguiente comando y especificar el GUID en un archivo .guid. El archivo contiene el GUID en formato de guion:

tracelog -start MyTrace -guid c:\\drivers\\Provider.guid -flag 0xFFFF -level 7-rt -kd

Para detener la sesión de seguimiento, escriba el siguiente comando:

tracelog -stop MyTrace

Paso 6: Implementar el controlador en el equipo de destino

  1. En la ventana Explorador de soluciones, haga clic con el botón derecho en el nombre del proyecto (MyUSBDriver_UMDF_) y elija Propiedades.
  2. En el panel izquierdo, vaya a Propiedades de configuración > Instalación de la implementación del controlador>.
  3. En Nombre del dispositivo de destino, especifique el nombre del equipo de destino.
  4. Seleccione Instalar o reinstalar y Comprobar.
  5. Seleccione Aceptar.
  6. En el menú Depurar , elija Iniciar depuración o presione F5 en el teclado.

Nota:

No especifique el identificador de hardware del dispositivo en Actualización del controlador de identificador de hardware. El identificador de hardware solo debe especificarse en el archivo de información del controlador (INF).

Paso 7: Ver el controlador en Administrador de dispositivos

  1. Escriba el siguiente comando para abrir Administrador de dispositivos.

    devmgmt
    
  2. Compruebe que Administrador de dispositivos muestra el siguiente nodo.

    Dispositivo USB

    MyUSBDriver_UMDF_Device

Paso 8: Ver la salida en el depurador

Compruebe que los mensajes de seguimiento aparecen en la ventana Inmediato del depurador en el equipo host.

La salida debe ser similar a la siguiente:

[0]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::OnPrepareHardware Entry
[0]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::OnPrepareHardware Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::CreateInstanceAndInitialize Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::Initialize Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::Initialize Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::CreateInstanceAndInitialize Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::Configure Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyIoQueue::CreateInstanceAndInitialize Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyIoQueue::Initialize Entry
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyIoQueue::Initialize Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyIoQueue::CreateInstanceAndInitialize Exit
[1]0744.05F0::00/00/0000-00:00:00.000 [MyUSBDriver_UMDF_]CMyDevice::Configure Exit

Comentarios

Echemos un vistazo a cómo funcionan conjuntamente el marco y el controlador de cliente para interactuar con Windows y controlar las solicitudes enviadas al dispositivo USB. En esta ilustración se muestran los módulos cargados en el sistema para un controlador de cliente USB basado en UMDF.

Diagrama de la arquitectura del controlador de cliente en modo de usuario.

El propósito de cada módulo se describe aquí:

  • Aplicación: un proceso en modo de usuario que emite solicitudes de E/S para comunicarse con el dispositivo USB.
  • Administrador de E/S: un componente de Windows que crea paquetes de solicitud de E/S (IRP) para representar las solicitudes de aplicación recibidas y los reenvía a la parte superior de la pila de dispositivos en modo kernel para el dispositivo de destino.
  • Reflector: un controlador en modo kernel proporcionado por Microsoft instalado en la parte superior de la pila de dispositivos en modo kernel (WUDFRd.sys). El reflector redirige los IRP recibidos del administrador de E/S al proceso de host del controlador de cliente. Después de recibir la solicitud, el marco y el controlador cliente controlan la solicitud.
  • Proceso de host: el proceso en el que se ejecuta el controlador en modo de usuario (Wudfhost.exe). También hospeda el marco y el distribuidor de E/S.
  • Controlador de cliente: controlador de función en modo de usuario para el dispositivo USB.
  • UMDF: el módulo de marco que controla la mayoría de las interacciones con Windows en nombre del controlador cliente. Expone las interfaces de controlador de dispositivo (DDIs) en modo de usuario que el controlador cliente puede usar para realizar tareas comunes del controlador.
  • Distribuidor: mecanismo que se ejecuta en el proceso de host; determina cómo reenviar una solicitud al modo kernel después de que los controladores del modo de usuario los procesen y haya alcanzado la parte inferior de la pila del modo de usuario. En la ilustración, el distribuidor reenvía la solicitud al archivo DLL en modo de usuario, Winusb.dll.
  • Winusb.dll: un archivo DLL de modo usuario proporcionado por Microsoft que expone funciones de WinUSB que simplifican el proceso de comunicación entre el controlador cliente y WinUSB (Winusb.sys, cargado en modo kernel).
  • Winusb.sys: un controlador proporcionado por Microsoft que requiere todos los controladores de cliente UMDF para dispositivos USB. El controlador debe instalarse debajo del reflector y actúa como puerta de enlace a la pila del controlador USB en el modo kernel. Para obtener más información, consulte WinUSB.
  • Pila de controladores USB: un conjunto de controladores, proporcionados por Microsoft, que controlan la comunicación de nivel de protocolo con el dispositivo USB. Para obtener más información, consulte Controladores del lado host USB en Windows.

Cada vez que una aplicación realiza una solicitud para la pila de controladores USB, el administrador de E/S de Windows envía la solicitud al reflector, que lo dirige al controlador cliente en modo de usuario. El controlador cliente controla la solicitud llamando a métodos UMDF específicos, que llaman internamente a Funciones winUSB para enviar la solicitud a WinUSB. Al recibir la solicitud, WinUSB procesa la solicitud o la reenvía a la pila del controlador USB.