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 de 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 valores PGUID posibles 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 mediante 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 en el 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 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
La funcionalidad especificada no es compatible con el hardware del controlador de host ni la pila de controladores USB.

Comentarios

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 IsInterfaceVersionSupported .

El controlador cliente puede usar las nuevas funcionalidades solo si la pila de controladores USB subyacente y el hardware los admiten. 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 llamar a IsInterfaceVersionSupported y asumir las funcionalidades de la pila de controladores. En su lugar, el controlador cliente siempre debe llamar 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, consulte 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 Cómo enviar MDL encadenados.
GUID_USB_CAPABILITY_STATIC_STREAMS Si se admite, el controlador de cliente puede enviar solicitudes de E/S a flujos 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 de 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. En el caso de otras secuencias del punto de conexión, el controlador de cliente debe abrir esos flujos y obtener identificadores de canalización para ellos con el fin de 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 las 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 (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 está funcionando 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 Value
Cliente mínimo compatible Requiere WDK para Windows 8. Tiene como destino Windows Vista y versiones posteriores del sistema operativo Windows.
Plataforma de destino Escritorio
Encabezado usbdlib.h (incluye Usbdlib.h)
Library Usbdex.lib
IRQL PASSIVE_LEVEL

Consulte también

Referencia de programación del controlador de dispositivo USB