Поделиться через


функция USBD_QueryUsbCapability (usbdlib.h)

Подпрограмма USBD_QueryUsbCapability вызывается драйвером клиента WDM, чтобы определить, поддерживает ли базовый стек USB-драйверов и оборудование контроллера узла определенную возможность. Примечание для драйверов Windows Driver Framework (WDF): Если драйвер клиента является драйвером WDF, то вместо USBD_QueryUsbCapabilityнеобходимо вызвать метод WdfUsbTargetDeviceQueryUsbCap ability.

Синтаксис

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

Параметры

[in] USBDHandle

UsbD-дескриптор, полученный драйвером клиента в предыдущем вызове подпрограммы USBD_CreateHandle.

[in] CapabilityType

Указатель на GUID, представляющий возможность, для которой драйвер клиента хочет получить сведения. Возможные значения PGUID приведены следующим образом:

  • 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

Длина буфера в байтах, на которую указывает OutputBuffer.

[in, out] OutputBuffer

Указатель на выделенный вызывающим буфером. Некоторые запросы возможностей возвращают дополнительные сведения в выходном буфере. Для этих запросов необходимо выделить буфер и указать указатель на буфер в параметре OutputBuffer. В настоящее время только запрос на статические потоки требует выходного буфера типа USHORT. Буфер заполняется USBD_QueryUsbCapability максимальным количеством потоков, поддерживаемых для каждой конечной точки.

Другие запросы возможностей не требуют выходного буфера. Для этих запросов необходимо задать OutputBuffer значение NULL и OutputBufferLength значение 0.

[out, optional] ResultLength

Указатель на переменную ULONG, которая получает фактическое количество байтов в буфере, на которое указывает OutputBuffer. Вызывающий объект может передать значение NULL в ResultLength. Если ResultLength не равно NULL, полученное значение меньше или равно значению OutputBufferLength.

Возвращаемое значение

Подпрограмма USBD_QueryUsbCapability возвращает код состояния NT.

Возможные значения включают, но не ограничиваются кодами состояния, перечисленными в следующей таблице.

Возвращаемый код Описание
STATUS_SUCCESS
Запрос выполнен успешно, и поддерживается указанная возможность.
STATUS_INVALID_PARAMETER
Вызывающий объект передал недопустимое значение параметра.
  • USBDHandle или CapabilityType имеет значение NULL.
  • OutputBuffer имеет значение NULL, но OutputBufferLength указывает ненулевое значение. И наоборот, вызывающий объект предоставил выходной буфер, но длина буфера равна 0.
STATUS_NOT_IMPLEMENTED
Указанная возможность не поддерживается базовым стеком USB-драйверов.
STATUS_NOT_SUPPORTED
Указанная возможность не поддерживается оборудованием контроллера узла или стеком USB-драйверов.

Замечания

Windows 8 включает новый стек USB-драйверов для поддержки устройств USB 3.0. Новый стек USB-драйверов предоставляет несколько новых возможностей, таких как, поддержка потоков и сетевые многомерные выражения, которые могут использоваться драйвером клиента.

Клиентский драйвер может определить версию базового стека USB-драйверов, вызвав подпрограмму IsInterfaceVersionSupported.

Драйвер клиента может использовать новые возможности только в том случае, если базовый стек USB-драйверов и их поддержку оборудования. Например, чтобы отправлять запросы ввода-вывода в конкретный поток, связанный с массовой конечной точкой, базовый стек USB-драйверов, конечная точка и оборудование контроллера узла должны поддерживать возможности статических потоков. Драйвер клиента не должен вызывать IsInterfaceVersionSupported и принимать возможности стека драйверов. Вместо этого драйвер клиента должен всегда вызывать USBD_QueryUsbCapability, чтобы определить, поддерживает ли стек драйверов USB и оборудование определенную возможность.

В следующей таблице описаны возможности, связанные с USB, которые драйвер клиента может запрашивать через вызов USBD_QueryUsbCapability.

GUID возможностей Описание
GUID_USB_CAPABILITY_CHAINED_MDLS Если стек USB-драйверов поддерживает цепочки многомерных выражений, драйвер клиента может предоставить данные передачи в виде цепочки многомерных выражений, которые ссылаются на сегментированные буферы в физической памяти. Дополнительные сведения см. в разделе MDL. Сетевые многомерные ключи исключают необходимость выделения и копирования памяти для создания практически смежных буферов и, следовательно, повышения эффективности передачи ввода-вывода. Дополнительные сведения см. в разделе Отправкасвязанных многомерных выражений.
GUID_USB_CAPABILITY_STATIC_STREAMS При поддержке драйвер клиента может отправлять запросы ввода-вывода в потоки в массовой конечной точке.

Для запроса статических потоков драйвер клиента должен предоставить выходной буфер (USHORT). После завершения вызова и поддержки возможностей статических потоков выходной буфер получает максимальное количество поддерживаемых потоков контроллером узла.

Выходное значение буфера не указывает максимальное количество потоков, поддерживаемых массовой конечной точкой на устройстве. Чтобы определить это число, драйвер клиента должен проверить дескриптор компаньона конечной точки.

Стек USB-драйверов в Windows 8 поддерживает до 255 потоков.

Если поддерживаются статические потоки, драйвер клиента может отправлять запросы ввода-вывода в первый поток (также называемый потоком по умолчанию) с помощью дескриптора канала, полученного с помощью запроса на выборку конфигурации. Для других потоков в конечной точке драйвер клиента должен открыть эти потоки и получить дескриптор канала для них, чтобы отправлять запросы ввода-вывода. Дополнительные сведения об открытии потоков см. в статье Как открыть и закрыть статические потоки вдля массовой загрузки USB.

GUID_USB_CAPABILITY_FUNCTION_SUSPEND Эта возможность определяет, поддерживает ли базовый стек USB-драйверов функции "Приостановка" и "Удаленная Wake-Up". В случае поддержки стек драйверов может обрабатывать сигнал возобновления (для удаленного пробуждения) из отдельной функции в составном устройстве USB 3.0. На основе этого сигнала отдельный драйвер функции может выйти из состояния функции с низкой мощностью.

Эта возможность предназначена для использования составным драйвером: драйвер, загруженный в качестве объекта устройства-функции (FDO) в стеке устройств для составного устройства. По умолчанию драйвер универсального родительского драйвера USB (Usbccgp.sys) предоставляется корпорацией Майкрософт в качестве FDO.

Если драйвер заменяет Usbccgp.sys, драйвер должен иметь возможность запросить удаленное пробуждение и распространить сигнал возобновления из стека USB-драйверов. Перед реализацией этой логики драйвер должен определить поддержку стека драйверов USB для функции приостановки, вызвав USBD_QueryUsbCapability. Usbccgp.sys в Windows 8 реализует приостановку функции.

Пример кода и дополнительные сведения о приостановке функции см. в разделе Реализация приостановки функции в составном драйвере.

GUID_USB_CAPABILITY_SELECTIVE_SUSPEND Определяет, поддерживает ли базовый стек USB-драйверов выборочную приостановку.

Сведения о выборочной приостановке см. в разделе выборочная приостановка USB.

GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE Определяет, работает ли шина с высокой скоростью или выше.
GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE Определяет, работает ли автобус в SuperSpeed или выше.
GUID_USB_CAPABILITY_TIME_SYNC Определяет, поддерживается ли номер кадра и функция сопоставления QPC на контроллере. 
 

Примеры

В фрагменте кода показано, как вызывать USBD_QueryUsbCapability для определения возможностей базового стека USB-драйверов.


/*++

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;

}

Требования

Требование Ценность
минимальные поддерживаемые клиентские Требуется WDK для Windows 8. Предназначено для Windows Vista и более поздних версий операционной системы Windows.
целевая платформа Настольный
заголовка usbdlib.h (include Usbdlib.h)
библиотеки Usbdex.lib
IRQL PASSIVE_LEVEL

См. также

справочник по программированию драйверов USB-устройств