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 転送の効率が高まります。 詳細については、「 チェーンされた MDL を送信する方法」を参照してください。 |
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 ドライバー スタックから再開信号を伝達できる必要があります。 そのロジックを実装する前に、ドライバーは、usb ドライバー スタックの関数のサポートを決定する必要がありますUSBD_QueryUsbCapabilityを呼び出すことによって機能 を中断します。 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 オペレーティング システムを対象としています。 |
対象プラットフォーム | デスクトップ |
Header | usbdlib.h (Usbdlib.h を含む) |
Library | Usbdex.lib |
IRQL | PASSIVE_LEVEL |