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

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

Синтаксис

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 потоков.

Если поддерживаются статические потоки, драйвер клиента может отправлять запросы ввода-вывода в первый поток (также называемый потоком по умолчанию) с помощью дескриптора канала, полученного с помощью запроса select-configuration. Для других потоков в конечной точке драйвер клиента должен открыть эти потоки и получить для них дескрипторы канала, чтобы отправлять запросы ввода-вывода. Дополнительные сведения об открытии потоков см. в статье Открытие и закрытие статических потоков в массовой конечной точке 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 реализует функцию suspend.

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

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 (включая Usbdlib.h)
Библиотека Usbdex.lib
IRQL PASSIVE_LEVEL

См. также раздел

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