функция 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.
Возможные значения включают, но не ограничиваются кодами состояния, перечисленными в следующей таблице.
Возвращаемый код | Описание |
---|---|
|
Запрос выполнен успешно, и поддерживается указанная возможность. |
|
Вызывающий объект передал недопустимое значение параметра.
|
|
Указанная возможность не поддерживается базовым стеком USB-драйверов. |
|
Указанная возможность не поддерживается оборудованием контроллера узла или стеком 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 |