Asignación y creación de URB

Un controlador cliente USB puede usar rutinas de controladores de Modelo de controlador de Windows (WDM) para asignar y dar formato a un URB antes de enviar la solicitud a la pila de controladores USB proporcionados por Microsoft.

El controlador cliente usa un URB para empaquetar toda la información requerida por los controladores inferiores de la pila de controladores USB para procesar la solicitud. En el sistema operativo Windows, se describe un URB en una estructura URB.

Microsoft proporciona una biblioteca de rutinas para controladores de cliente USB. Mediante esas rutinas, los controladores de cliente USB pueden crear solicitudes URB para determinadas operaciones especificadas y reenviarlas hacia abajo por la pila USB. Si lo prefiere, puede diseñar el controlador cliente para llamar a las rutinas de biblioteca para las operaciones admitidas en lugar de crear sus propias solicitudes URB.

Asignación de URB en Windows 7 y versiones anteriores

Para enviar una solicitud USB mediante rutinas incluidas en el Kit para controladores de Windows (WDK) para Windows 7 y versiones anteriores de Windows, un controlador cliente normalmente asigna y rellena una estructura URB, asocia la estructura URB con un nuevo IRP y envía el IRP a la pila de controladores USB.

Para determinados tipos de solicitudes, Microsoft proporciona rutinas auxiliares (exportadas por Usbd.sys) que asignan y da formato a la estructura URB. Por ejemplo, la rutina USBD_CreateConfigurationRequestEx asigna memoria para una estructura URB, da formato al URB para una solicitud de selección de configuración y devuelve la dirección de la estructura URB al controlador cliente. Sin embargo, las rutinas auxiliares no se pueden usar para todos los tipos de solicitudes.

Microsoft también proporciona macros que dan formato a los URB para algunos tipos de solicitudes. Para esas macros, el controlador de cliente debe asignar la estructura URB llamando a ExAllocatePoolWithTag o asignando la estructura en la pila. Por ejemplo, después de que el controlador cliente asigne un URB, el controlador puede llamar a UsbBuildSelectConfigurationRequest para dar formato al URB para una solicitud de selección de configuración o para borrar la configuración.

Para otras solicitudes, el controlador cliente debe asignar y dar formato manualmente al URB estableciendo varios miembros de la estructura URB, en función del tipo de solicitud.

Cuando se completa una solicitud USB, el controlador cliente debe liberar la estructura URB. Si el URB se asigna en la pila, se libera el URB cuando sale del ámbito. Si el URB se asigna en un grupo no paginado, el controlador cliente debe llamar a ExFreePool para liberar el URB.

Asignación de URB en Windows 8

El WDK para Windows 8 proporciona una nueva biblioteca estática, Usbdex.lib, que exporta rutinas para asignar, dar formato y liberar URB. Además, hay una nueva forma de asociar un URB con un IRP. Un controlador de cliente que tiene como destino Windows Vista y versiones posteriores de Windows puede llamar a las nuevas rutinas.

Un controlador cliente que se ejecuta en Windows Vista y versiones posteriores debe usar las nuevas rutinas para que la pila de controladores USB subyacente pueda usar ciertas mejoras de rendimiento y confiabilidad. Estas mejoras se aplican a la nueva pila de controladores USB introducida en Windows 8 para admitir dispositivos USB 3.0 y controladores host. En el caso de los controladores de host USB 2.0, Windows carga una versión anterior de la pila de controladores que no admite las mejoras. Independientemente de la versión de la pila de controladores subyacente o de la versión del protocolo compatible con el controlador host, siempre debe llamar a las nuevas rutinas URB.

Antes de llamar a cualquiera de las nuevas rutinas, asegúrese de que tiene un controlador USBD para el registro del controlador cliente con la pila de controladores USB. Para obtener un identificador USBD, llame a USBD_CreateHandle.

Las siguientes rutinas están disponibles con WDK para Windows 8. Estas rutinas se definen en Usbdlib.h.

Las rutinas de asignación de la lista anterior devuelven un puntero a una nueva estructura URB, que la pila del controlador USB asigna. Dependiendo de la versión de la pila de controladores USB cargada por Windows, la estructura URB se puede emparejar con un contexto URB opaco. Un contexto URB es un bloque de información sobre el URB. No puede ver el contenido del encabezado URB; la información está pensada para ser utilizada internamente por la pila del controlador USB para mejorar el seguimiento y el procesamiento de URB. La pila de controladores USB solo usa el contexto URB para Windows 8. Si el contexto URB está disponible, la pila del controlador USB la usa para que el procesamiento de URB sea más seguro y eficaz. Por ejemplo, la pila del controlador USB debe asegurarse de que el controlador cliente no envía un URB y, a continuación, intenta reutilizar ese mismo URB antes de que se haya completado la primera solicitud. Para detectar ese tipo de error, la pila del controlador USB almacena información de estado en el contexto urb. Sin la información de estado, la pila del controlador USB tendría que comparar el URB entrante con todas las direcciones URL actualmente en curso. La pila de controladores USB también usa la información de estado cuando el controlador cliente intenta liberar el URB. Antes de liberar el URB, la pila del controlador USB comprueba el estado para asegurarse de que el URB no está pendiente.

El contexto URB proporciona un mecanismo oficial para almacenar información adicional de URB. Es preferible usar el contexto URB para asignar memoria adicional según sea necesario o almacenar información adicional en miembros reservados de la estructura URB. La pila de controladores USB asigna URB y su contexto de URB asociado en un grupo no paginado, de modo que en el futuro, si se necesita un contexto URB mayor, el único ajuste necesario será el tamaño de una asignación de grupo.

Migración rutinaria de URB

En la tabla siguiente se resumen los cambios en las rutinas de URB.

Caso de uso Disponible en WDK para Windows 7 y versiones anteriores Disponible en WDK para Windows 8 y versiones posteriores
  Tiene como destino Windows 7 y versiones anteriores del sistema operativo Tiene como destino Windows 8 y versiones posteriores del sistema operativo
Para crear un URB... El controlador cliente asigna una estructura URB y da formato a la estructura en función de la solicitud.

El controlador cliente asigna la estructura URB de la pila o el controlador asigna la estructura en un grupo no paginado llamando a ExAllocatePoolWithTag.
El controlador cliente llama a USBD_UrbAllocate y recibe un puntero a la nueva estructura URB, que la pila de controladores USB asigna. Es posible que el URB esté asociado a un contexto URB, en función de la versión de la interfaz USBD de la pila de controladores USB subyacente.
Para crear un URB para una solicitud de configuración de selección... El controlador cliente llama a la rutina USBD_CreateConfigurationRequestEx, que devuelve un puntero al nuevo URB que se crea y da formato a la pila de controladores USB. El controlador cliente llama a USBD_SelectConfigUrbAllocateAndBuild y recibe un puntero a la nueva estructura URB, que se asigna y da formato (para la solicitud de configuración de selección) mediante la pila de controladores USB. Es posible que el URB esté asociado a un contexto URB, en función de la versión de la interfaz USBD de la pila de controladores USB subyacente.
Para crear un URB para una solicitud de interfaz de selección... El controlador cliente asigna una estructura URB y usa la estructura _URB_SELECT_INTERFACE para definir el formato de un comando de interfaz de selección para un dispositivo USB. El controlador cliente llama a USBD_SelectInterfaceUrbAllocateAndBuild y recibe un puntero a la nueva estructura URB, que se asigna y da formato (para la solicitud de interfaz de selección) mediante la pila de controladores USB. Es posible que el URB esté asociado a un contexto URB, en función de la versión de la interfaz USBD de la pila de controladores USB subyacente.
Para asociar un URB con un IRP... El controlador cliente obtiene un puntero a la siguiente ubicación de la pila IRP mediante una llamada a IoGetNextIrpStackLocation. A continuación, el controlador cliente establece manualmente el miembro Parameters.Others.Argument1 de la ubicación de la pila en la dirección de la estructura URB. El controlador cliente obtiene un puntero a la siguiente ubicación de la pila IRP mediante una llamada a IoGetNextIrpStackLocation. A continuación, el controlador cliente llama a USBD_AssignUrbToIoStackLocation para asociar el URB a la ubicación de la pila.
Para liberar un URB... Si el controlador cliente asigna un URB en la pila, la variable sale del ámbito una vez completada la solicitud.

Para liberar una estructura URB que el controlador cliente o la pila de controladores USB asignados en un grupo no paginado, el controlador cliente llama a ExFreePool.
El controlador cliente llama a USBD_UrbFree.