Compartir a través de


función USBD_QueryUsbCapability (usbdlib.h)

Un controlador cliente WDM llama a la rutina USBD_QueryUsbCapability para determinar si la pila de controladores USB subyacente y el hardware del controlador host admiten una funcionalidad específica. Nota para controladores de Windows Driver Framework (WDF): Si el controlador cliente es un controlador basado en WDF, debe llamar al método WdfUsbTargetDeviceQueryUsbCapability en lugar de USBD_QueryUsbCapability.

Sintaxis

NTSTATUS USBD_QueryUsbCapability(
  [in]            USBD_HANDLE USBDHandle,
  [in]            const GUID  *CapabilityType,
  [in]            ULONG       OutputBufferLength,
  [in, out]       PUCHAR      OutputBuffer,
  [out, optional] PULONG      ResultLength
);

Parámetros

[in] USBDHandle

Identificador USBD recuperado por el controlador cliente en una llamada anterior a la rutina USBD_CreateHandle.

[in] CapabilityType

Puntero a un GUID que representa la funcionalidad para la que el controlador cliente desea recuperar información. Los posibles valores PGUID son los siguientes:

  • GUID_USB_CAPABILITY_CHAINED_MDLS
  • GUID_USB_CAPABILITY_STATIC_STREAMS
  • GUID_USB_CAPABILITY_SELECTIVE_SUSPEND
  • GUID_USB_CAPABILITY_FUNCTION_SUSPEND
  • GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE
  • GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE
  • GUID_USB_CAPABILITY_TIME_SYNC

[in] OutputBufferLength

Longitud, en bytes, del búfer al que apunta OutputBuffer.

[in, out] OutputBuffer

Puntero a un búfer asignado por el autor de la llamada. Ciertas solicitudes de funcionalidad devuelven información adicional en un búfer de salida. Para esas solicitudes, debe asignar el búfer y proporcionar un puntero al búfer en el parámetro outputBuffer . Actualmente, solo la solicitud de funcionalidad de flujos estáticos requiere un búfer de salida del tipo USHORT. El búfer se rellena USBD_QueryUsbCapability con el número máximo de secuencias admitidas por punto de conexión.

Otras solicitudes de funcionalidad no requieren un búfer de salida. Para esas solicitudes, debe establecer OutputBuffer en NULL y outputBufferLength en 0.

[out, optional] ResultLength

Puntero a una variable ULONG que recibe el número real de bytes del búfer al que apunta OutputBuffer. El autor de la llamada puede pasar NULL en ResultLength. Si ResultLength no es NULL, el valor recibido es menor o igual que el valor de outputBufferLength.

Valor devuelto

La rutina USBD_QueryUsbCapability devuelve un código de estado NT.

Entre los valores posibles se incluyen, entre otros, los códigos de estado enumerados en la tabla siguiente.

Código devuelto Descripción
STATUS_SUCCESS
La solicitud se realizó correctamente y se admite la funcionalidad especificada.
STATUS_INVALID_PARAMETER
El autor de la llamada pasó un valor de parámetro no válido.
  • USBDHandle o CapabilityType es NULL.
  • outputBuffer es NULL, pero outputBufferLength indica un valor distinto de cero. Por el contrario, el autor de la llamada proporcionó un búfer de salida, pero la longitud del búfer es 0.
STATUS_NOT_IMPLEMENTED
La funcionalidad especificada no es compatible con la pila de controladores USB subyacente.
STATUS_NOT_SUPPORTED
El hardware del controlador de host o la pila de controladores USB no admiten la funcionalidad especificada.

Observaciones

Windows 8 incluye una nueva pila de controladores USB para admitir dispositivos USB 3.0. La nueva pila de controladores USB proporciona varias funcionalidades nuevas definidas, como, compatibilidad con secuencias y MDL encadenadas que un controlador cliente puede usar.

Un controlador cliente puede determinar la versión de la pila de controladores USB subyacente llamando a la rutina de IsInterfaceVersionSupported.

El controlador cliente puede usar las nuevas funcionalidades solo si la pila de controladores USB subyacente y hardware los admite. Por ejemplo, para enviar solicitudes de E/S a un flujo determinado asociado a un punto de conexión masivo, la pila de controladores USB subyacente, el punto de conexión y el hardware del controlador de host deben admitir la funcionalidad de secuencias estáticas. El controlador cliente no debe llamada a IsInterfaceVersionSupported y asumir las funcionalidades de la pila de controladores. En su lugar, el controlador cliente debe llamar siempre a USBD_QueryUsbCapability para determinar si la pila de controladores USB y el hardware admiten una funcionalidad determinada.

En la tabla siguiente se describen las funcionalidades específicas de USB que un controlador cliente puede consultar a través de una llamada USBD_QueryUsbCapability.

GUID de funcionalidad Descripción
GUID_USB_CAPABILITY_CHAINED_MDLS Si la pila de controladores USB admite MDL encadenadas, el controlador cliente puede proporcionar los datos de transferencia como una cadena de MDL que hacen referencia a búferes segmentados en memoria física. Para obtener más información, vea MDL. Las MDL encadenadas impiden la necesidad de asignar y copiar memoria para crear búferes prácticamente contiguos y, por tanto, hacer que las transferencias de E/S sean más eficaces. Para obtener más información, vea How to Send Chained MDLs.
GUID_USB_CAPABILITY_STATIC_STREAMS Si se admite, el controlador cliente puede enviar solicitudes de E/S a secuencias en un punto de conexión masivo.

Para la solicitud de consulta de secuencias estáticas, se requiere el controlador de cliente para proporcionar un búfer de salida (USHORT). Una vez completada la llamada y si se admite la funcionalidad de secuencias estáticas, el búfer de salida recibe el número máximo de secuencias admitidas por el controlador de host.

El valor del búfer de salida no indica el número máximo de flujos admitidos por el punto de conexión masivo en el dispositivo. Para determinar ese número, el controlador cliente debe inspeccionar el descriptor complementario del punto de conexión.

La pila de controladores USB en Windows 8 admite hasta 255 secuencias.

Si se admiten secuencias estáticas, el controlador cliente puede enviar solicitudes de E/S a la primera secuencia (también denominada secuencia predeterminada) mediante el identificador de canalización obtenido a través de una solicitud de configuración de selección. Para otras secuencias del punto de conexión, el controlador cliente debe abrir esas secuencias y obtener identificadores de canalización para ellos para poder enviar solicitudes de E/S. Para obtener más información sobre cómo abrir secuencias, vea Cómo abrir y cerrar secuencias estáticas en un punto de conexión masivo USB.

GUID_USB_CAPABILITY_FUNCTION_SUSPEND Esta funcionalidad determina si la pila de controladores USB subyacente admite características de suspensión de función USB y Wake-Up remota. Si se admite, la pila de controladores puede procesar una señal de reanudación (para reactivación remota) desde una función individual en un dispositivo compuesto USB 3.0. En función de esa señal, un controlador de función individual puede salir del estado de baja potencia de su función.

La funcionalidad está pensada para que la use un controlador compuesto: el controlador que se carga como objeto de dispositivo de función (FDO) en la pila de dispositivos para el dispositivo compuesto. De forma predeterminada, el controlador primario genérico genérico (Usbccgp.sys) proporcionado por Microsoft se carga como FDO.

Si el controlador reemplaza Usbccgp.sys, el controlador debe poder solicitar reactivación remota y propagar la señal de reanudación desde la pila del controlador USB. Antes de implementar esa lógica, el controlador debe determinar la compatibilidad de la pila de controladores USB con la funcionalidad de suspensión de la función llamando a USBD_QueryUsbCapability. Usbccgp.sys en Windows 8 implementa la suspensión de funciones.

Para obtener un ejemplo de código y más información sobre la suspensión de funciones, vea How to Implement Function Suspend in a Composite Driver.

GUID_USB_CAPABILITY_SELECTIVE_SUSPEND Determina si la pila de controladores USB subyacente admite la suspensión selectiva.

Para obtener información sobre la suspensión selectiva, consulte suspensión selectiva usb.

GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE Determina si el bus funciona a alta velocidad o superior.
GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE Determina si el autobús funciona en SuperSpeed o superior.
GUID_USB_CAPABILITY_TIME_SYNC Determina si el número de fotograma y la característica de asociación de QPC se admiten en el controlador. 
 

Ejemplos

El fragmento de código muestra cómo llamar a USBD_QueryUsbCapability para determinar las funcionalidades de la pila de controladores USB subyacente.


/*++

Routine Description:
This helper routine queries the underlying USB driver stack
for specific capabilities. This code snippet assumes that 
USBD handle was retrieved by the client driver in a 
previous call to the USBD_CreateHandle routine.

Parameters:

fdo: Pointer to the device object that is the current top
of the stack as reported by IoAttachDeviceToDeviceStack.

Return Value: VOID
--*/

VOID QueryUsbDriverStackCaps (PDEVICE_OBJECT fdo)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;   
    PDEVICE_EXTENSION deviceExtension;

    deviceExtension = (PDEVICE_EXTENSION)fdo->DeviceExtension;

    if (!deviceExtension->UsbdHandle)
    {
        return;
    }

    // Check if the underlying USB driver stack
    // supports USB 3.0 devices.

    if (!USBD_IsInterfaceVersionSupported(
        deviceExtension->UsbdHandle,                                       
        USBD_INTERFACE_VERSION_602))
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Old USB stack loaded.\n" ));
    }
    else
    {
        // Call USBD_QueryUsbCapability to determine 
        // function suspend support.     
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "New USB stack loaded.\n" ));
        ntStatus = USBD_QueryUsbCapability ( deviceExtension->UsbdHandle,  
            (GUID*)&GUID_USB_CAPABILITY_FUNCTION_SUSPEND,  
            0,  
            NULL,
            NULL);

        if (NT_SUCCESS(ntStatus)) 
        {
            deviceExtension->FunctionSuspendSupported = TRUE;
            KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Function suspend supported.\n" ));
        } 
        else 
        {
            deviceExtension->FunctionSuspendSupported  = FALSE;
            ntStatus = STATUS_SUCCESS;
            KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Function suspend not supported.\n" ));
        }
    }

    // Call USBD_QueryUsbCapability to determine 
    // chained MDL support. 

    ntStatus = USBD_QueryUsbCapability(
        deviceExtension->UsbdHandle,
        (GUID*)&GUID_USB_CAPABILITY_CHAINED_MDLS,
        0,
        NULL,
        NULL);

    if (NT_SUCCESS(ntStatus)) 
    {
        deviceExtension->ChainedMDLSupport = TRUE;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Chained MDLs supported.\n" ));
    } 
    else 
    {
        deviceExtension->ChainedMDLSupport = FALSE;
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Chained MDLs not supported.\n" ));
    }

    // Call USBD_QueryUsbCapability to determine 
    // stream support. 

    ntStatus = USBD_QueryUsbCapability (deviceExtension->UsbdHandle, 
        (GUID*)&GUID_USB_CAPABILITY_STATIC_STREAMS, 
        sizeof(ULONG), 
        (PUCHAR) &deviceExtension->MaxSupportedStreams, 
        NULL);  


    if (!NT_SUCCESS(ntStatus)) 
    {
        deviceExtension->MaxSupportedStreams = 0;
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Static streams not supported.\n" ));
    }

    // Call USBD_QueryUsbCapability to determine 
    // selective suspend support. 

    ntStatus = USBD_QueryUsbCapability (deviceExtension->UsbdHandle, 
        (GUID*)&GUID_USB_CAPABILITY_SELECTIVE_SUSPEND, 
        0, 
        NULL, 
        NULL);

    if (!NT_SUCCESS(ntStatus)) 
    {
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Selective suspend not supported.\n" ));
    }
    else
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Selective suspend supported.\n" ));
    }

    // Call USBD_QueryUsbCapability to determine 
    // device speed. 
    ntStatus = USBD_QueryUsbCapability (deviceExtension->UsbdHandle, 
        (GUID*)&GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE, 
        0, 
        NULL, 
        NULL);

    if (!NT_SUCCESS(ntStatus)) 
    {
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "The device is operating at full speed or lower.\n The device can operate at high speed or higher." ));
    }
    else
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "The device is operating at high speed or higher.\n" ));
    }

    // Call USBD_QueryUsbCapability to determine 
    // device speed. 
    ntStatus = USBD_QueryUsbCapability (deviceExtension->UsbdHandle, 
        (GUID*)&GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE, 
        0, 
        NULL, 
        NULL);

    if (!NT_SUCCESS(ntStatus)) 
    {
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "The device is operating at high speed or lower.\n The device can operate at Superspeed or higher." ));
    }
    else
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "The device is operating at SuperSpeed or higher.\n" ));
    }

    return;

}

Requisitos

Requisito Valor
cliente mínimo admitido Requiere WDK para Windows 8. Tiene como destino Windows Vista y versiones posteriores del sistema operativo Windows.
de la plataforma de destino de Escritorio
encabezado de usbdlib.h (include Usbdlib.h)
biblioteca de Usbdex.lib
irQL PASSIVE_LEVEL

Consulte también

referencia de programación del controlador de dispositivo USB