USBD_QueryUsbCapability函式 (usbdlib.h)
WDM 用戶端驅動程式會呼叫 USBD_QueryUsbCapability 例程,以判斷基礎 USB 驅動程式堆疊和主機控制器硬體是否支援特定功能。 Windows Driver Framework (WDF) 驅動程式的注意事項:如果您的用戶端驅動程式是以 WDF 為基礎的驅動程式,則您必須呼叫 WdfUsbTargetDeviceQueryUsbCapability 方法,而不是 USBD_QueryUsbCapability。
語法
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_CreateHandle 例程時擷取的 USBD 句柄。
[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 所指向之緩衝區中實際位元組數目。 呼叫端可以在 resultLength 中傳遞 NULL。 如果 resultLength 不是 NULL,則收到的值小於或等於 outputBufferLength 值。
傳回值
USBD_QueryUsbCapability 例程會傳回NT狀態代碼。
可能的值包括但不限於下表所列的狀態代碼。
傳回碼 | 描述 |
---|---|
|
要求成功且支援指定的功能。 |
|
呼叫端傳遞了無效的參數值。
|
|
基礎 USB 驅動程式堆疊不支援指定的功能。 |
|
主機控制器硬體或 USB 驅動程式堆疊不支援指定的功能。 |
言論
Windows 8 包含新的 USB 驅動程式堆疊,可支援 USB 3.0 裝置。 新的 USB 驅動程式堆疊提供數個定義新功能,例如串流支援和用戶端驅動程式可以使用的鏈結 MDL。
用戶端驅動程式可以呼叫 IsInterfaceVersionSupported 例程來判斷基礎 USB 驅動程式堆疊的版本。
只有在 基礎 USB 驅動程式堆疊 並 硬體支援時,用戶端驅動程式才能使用新功能。 例如,若要將 I/O 要求傳送至與大量端點相關聯的特定數據流,基礎 USB 驅動程式堆疊、端點和主機控制器硬體必須支援靜態數據流功能。 客戶端驅動程式 不得 呼叫 isInterfaceVersionSupported ,並假設驅動程式堆疊的功能。 相反地,用戶端驅動程式 必須 一律呼叫 USBD_QueryUsbCapability,以判斷 USB 驅動程式堆疊和硬體是否支援特定功能。
下表描述客戶端驅動程式可透過 USBD_QueryUsbCapability 呼叫查詢的 USB 特定功能。
功能 GUID | 描述 |
---|---|
GUID_USB_CAPABILITY_CHAINED_MDLS | 如果 USB 驅動程式堆疊支援鏈結的 MDL,則用戶端驅動程式可以提供傳輸數據做為參考實體記憶體中分段緩衝區的 MDL 鏈結。 如需詳細資訊,請參閱 MDL。 鏈結的 MDL 排除配置和複製記憶體以建立幾乎連續緩衝區的需求,因此讓 I/O 傳輸更有效率。 如需詳細資訊,請參閱 如何傳送鏈結的 MDL。 |
GUID_USB_CAPABILITY_STATIC_STREAMS |
如果支援,客戶端驅動程式可以將I/O要求傳送至大量端點中的數據流。
針對靜態數據流查詢要求,用戶端驅動程序必須提供輸出緩衝區 (USHORT)。 呼叫完成後,如果支援靜態數據流功能,輸出緩衝區會接收主機控制器所支持數據流的最大數目。 輸出緩衝區值不會指出裝置中大量端點所支持的數據流數目上限。 若要判斷該數位,用戶端驅動程式必須檢查端點隨附描述元。 Windows 8 中的 USB 驅動程式堆疊最多可支援 255 個數據流。 如果支援靜態數據流,用戶端驅動程式可以使用透過選取組態要求取得的管道句柄,將 I/O 要求傳送至第一個數據流(也稱為 預設數據流)。 對於端點中的其他數據流,用戶端驅動程式必須開啟這些數據流,並取得這些數據流的管道句柄,才能傳送 I/O 要求。 如需開啟資料流的詳細資訊,請參閱 如何在 USB 大量端點中開啟和關閉靜態資料流。 |
GUID_USB_CAPABILITY_FUNCTION_SUSPEND |
此功能會判斷基礎 USB 驅動程式堆疊是否支援 USB 函式暫止和遠端 Wake-Up 功能。 如果支援,驅動程式堆疊可以從USB 3.0複合裝置中的個別函式處理繼續訊號(適用於遠端喚醒)。 根據該訊號,個別函式驅動程式可以結束其函式的低功率狀態。
此功能供複合驅動程式使用:載入為複合裝置裝置堆疊中函式裝置物件 (FDO) 的驅動程式。 根據預設,Microsoft提供的 USB 泛型父驅動程式 (Usbccgp.sys) 會載入為 FDO。 如果您的驅動程式取代 Usbccgp.sys,驅動程式必須能夠要求遠端喚醒,並從 USB 驅動程式堆疊傳播繼續訊號。 實作該邏輯之前,驅動程式必須呼叫 USBD_QueryUsbCapability來判斷USB驅動程式堆疊對函式暫停功能的支援。 Windows 8 中的 Usbccgp.sys 會實作函式暫停。 如需程式代碼範例和函式暫停的詳細資訊,請參閱 如何在複合驅動程式中實作函式暫止。 |
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;
}
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | 需要適用於 Windows 8 的 WDK。 以 Windows Vista 和更新版本的 Windows作系統為目標。 |
目標平臺 | 桌面 |
標頭 | usbdlib.h (包括 Usbdlib.h) |
連結庫 | Usbdex.lib |
IRQL | PASSIVE_LEVEL |