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 状態コードを返します。

使用できる値には、次の表に示す状態コードが含まれますが、これらに限定されません。

リターン コード 説明
STATUS_SUCCESS
要求が成功し、指定された機能がサポートされています。
STATUS_INVALID_PARAMETER
呼び出し元が無効なパラメーター値を渡しました。
  • USBDHandle または CapabilityType が NULL です。
  • OutputBuffer は NULL ですが、 OutputBufferLength は 0 以外の値を示します。 逆に、呼び出し元は出力バッファーを提供しましたが、バッファー長は 0 です。
STATUS_NOT_IMPLEMENTED
指定された機能は、基になる USB ドライバー スタックではサポートされていません。
STATUS_NOT_SUPPORTED
指定された機能は、ホスト コントローラー ハードウェアまたは 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

こちらもご覧ください

USB デバイス ドライバーのプログラミング参照