次の方法で共有


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 転送の効率が向上します。 詳細については、「チェーンされた 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 ドライバー スタックが選択的な中断をサポートするかどうかを決定します。

選択的一時停止の詳細については、「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

関連項目

USB デバイス ドライバー プログラミング リファレンス