USBD_QueryUsbCapability関数 (usbdlib.h)
USBD_QueryUsbCapability ルーチンは、基になる USB ドライバー スタックとホスト コントローラー ハードウェアが特定の機能をサポートしているかどうかを判断するために、WDM クライアント ドライバーによって呼び出されます。 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_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
OutputBuffer が指すバッファー内の実際のバイト数受け取る ULONG 変数へのポインター。 呼び出し元は ResultLength NULL を渡すことができます。 ResultLength NULL でない場合、受信した値は OutputBufferLength 値以下になります。
戻り値
USBD_QueryUsbCapability ルーチンは NT 状態コードを返します。
使用可能な値には、次の表に示す状態コードが含まれますが、これらに限定されません。
リターン コード | 形容 |
---|---|
|
要求が成功し、指定された機能がサポートされています。 |
|
呼び出し元が無効なパラメーター値を渡しました。
|
|
指定された機能は、基になる USB ドライバー スタックではサポートされていません。 |
|
指定された機能は、ホスト コントローラー ハードウェアまたは USB ドライバー スタックではサポートされていません。 |
備考
Windows 8 には、USB 3.0 デバイスをサポートする新しい USB ドライバー スタックが含まれています。 新しい 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 転送の効率が向上します。 詳細については、「チェーンされた MDLsを送信する方法」を参照してください。 |
GUID_USB_CAPABILITY_STATIC_STREAMS |
サポートされている場合、クライアント ドライバーは一括エンドポイント内のストリームに I/O 要求を送信できます。
静的ストリーム クエリ要求の場合、クライアント ドライバーは出力バッファー (USHORT) を提供する必要があります。 呼び出しが完了し、静的ストリーム機能がサポートされている場合、出力バッファーはホスト コントローラーによってサポートされるストリームの最大数を受け取ります。 出力バッファーの値は、デバイスの一括エンドポイントでサポートされるストリームの最大数を示していません。 その数を確認するには、クライアント ドライバーがエンドポイント コンパニオン記述子を検査する必要があります。 Windows 8 の USB ドライバー スタックでは、最大 255 のストリームがサポートされています。 静的ストリームがサポートされている場合、クライアント ドライバーは、select-configuration 要求によって取得されたパイプ ハンドルを使用して、最初のストリーム (既定のストリームとも呼ばれます) に 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 ドライバー スタックが選択的な中断をサポートするかどうかを決定します。 |
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 |