USB デバイス記述子

デバイス記述子には、USB デバイス全体に関する情報が含まれています。 このトピックでは、USB_DEVICE_DESCRIPTOR 構造体について説明し、クライアント ドライバーがデバイス記述子を取得する get 記述子要求を送信する方法に関する情報が含まれています。

すべてのユニバーサル シリアル バス (USB) デバイスは、デバイスに関する関連情報を含む単一のデバイス記述子を提供できる必要があります。 USB_DEVICE_DESCRIPTOR 構造体は、デバイス記述子を記述します。 Windows では、その情報を使用して、さまざまな情報セットを取得します。 たとえば、idVendor フィールドと idProduct フィールドでは、ベンダー識別子と製品識別子をそれぞれ指定します。 Windows では、これらのフィールド値を使用して、デバイスの ハードウェア ID を構築します。 特定のデバイスのハードウェア ID を表示するには、[デバイス マネージャー] を開き、デバイスのプロパティを表示します。 [詳細] タブの [ハードウェア ID] プロパティの値は、Windows によって生成されるハードウェア ID ("USB\XXX") を示します。 bcdUSB フィールドは、デバイスが準拠している USB 仕様のバージョンを示します。 たとえば、0x0200 は、デバイスが USB 2.0 仕様に従って設計されていることを示します。 bcdDevice 値は、デバイス定義のリビジョン番号を示します。 USB ドライバー スタックは、idVendoridProduct と共に bcdDevice を使用して、デバイスのハードウェア ID と互換性のある ID を生成します。 これらの識別子は、[デバイス マネージャー] で表示できます。 デバイス記述子は、デバイスがサポートする構成の合計数も示します。

デバイスがホスト コンピューターに高速で接続されている場合、デバイスが Full Speed で接続されている場合とは異なる情報がデバイス記述子で報告されることがあります。 デバイスは、電源状態の変更中を含め、接続の存続期間中、デバイス記述子に含まれる情報を変更してはなりません。

ホストは、コントロール転送を通じてデバイス記述子を取得します。 転送では、要求の種類は GET DESCRIPTOR で、受信者はデバイスです。 クライアント ドライバーは、フレームワーク USB ターゲット デバイス オブジェクトを使用するか、要求情報を含む URB を送信するという 2 つの方法のいずれかで転送を開始できます。

デバイス記述子の取得

Windows Driver Frameworks (WDF) クライアント ドライバーは、フレームワーク USB ターゲット デバイス オブジェクトが作成された後にのみデバイス記述子を取得できます。

KMDFドライバーは、WdfUsbTargetDeviceCreate を呼び出して、USBターゲット デバイス オブジェクトへの WDFUSBDEVICE ハンドルを取得する必要があります。 通常、クライアント ドライバーは、ドライバーの EvtDevicePrepareHardware コールバック実装で WdfUsbTargetDeviceCreate を呼び出します。 その後、クライアント ドライバーは WdfUsbTargetDeviceGetDeviceDescriptor メソッドを呼び出す必要があります。 呼び出しが完了すると、呼び出し元によって割り当てられた USB_DEVICE_DESCRIPTOR 構造体でデバイス記述子が受信されます。

UMDF ドライバーは、IWDFUsbTargetDevice ポインターのフレームワーク デバイス オブジェクトを照会し、IWDFUsbTargetDevice::RetrieveDescriptor メソッドを呼び出して、記述子の種類として USB_DEVICE_DESCRIPTOR_TYPE を指定する必要があります。

ホストは、URB を送信してデバイス記述子を取得することもできます。 このメソッドは、カーネル モード ドライバーにのみ適用されます。 ただし、ドライバーが Windows Driver Model (WDM) に基づいている場合を除き、クライアント ドライバーはこの種類の要求に対して URB を送信する必要はありません。 このようなドライバーは、URB 構造体を割り当て、UsbBuildGetDescriptorRequest マクロを呼び出して、要求の URB の形式を指定する必要があります。 ドライバーは、USB ドライバー スタックに URB を送信することによって要求を送信できます。 詳細については、「URB の送信方法」に関する記事を参照してください。

このコード例は、pURB が指すバッファを適切な URB でフォーマットする UsbBuildGetDescriptorRequest 呼び出しを示しています。

UsbBuildGetDescriptorRequest(
    pURB,                                                 // Points to the URB to be formatted
    sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
    USB_DEVICE_DESCRIPTOR_TYPE,
    0,                                                    // Not used for device descriptors
    0,                                                    // Not used for device descriptors
    pDescriptor,                                          // Points to a USB_DEVICE_DESCRIPTOR structure
    NULL,
    sizeof(USB_DEVICE_DESCRIPTOR),
    NULL
);

サンプル デバイス記述子

USBView アプリケーションを使用して取得した USB Web カメラ デバイスのデバイス記述子 (「USB デバイス レイアウト」を参照) の例を次に示します。

Device Descriptor:
bcdUSB:             0x0200
bDeviceClass:         0xEF
bDeviceSubClass:      0x02
bDeviceProtocol:      0x01
bMaxPacketSize0:      0x40 (64)
idVendor:           0x045E (Microsoft Corporation)
idProduct:          0x0728
bcdDevice:          0x0100
iManufacturer:        0x01
0x0409: "Microsoft"
iProduct:             0x02
0x0409: "Microsoft LifeCam VX-5000"
0x0409: "Microsoft LifeCam VX-5000"
iSerialNumber:        0x00
bNumConfigurations:   0x01

前の例では、デバイスが USB 仕様バージョン 2.0 に従って開発されていることがわかります。 bDeviceClassbDeviceSubClass、および bDeviceProtocol の値に注意してください。 これらの値は、機能ごとに複数のインターフェイスをグループ化するために使用できる 1 つ以上の USB インターフェイス関連付け記述子がデバイスに含まれていることを示します。 詳細については、「USB インターフェイスの関連付け記述子」を参照してください。

次に、bMaxPacketSize0 の値を参照してください。 この値は、既定のエンドポイントの最大パケット サイズを示します。 このサンプル デバイスは、既定のエンドポイントを通じて最大 64 バイトのデータを転送できます。

通常、デバイスを構成するために、クライアント ドライバーはデバイス記述子を取得した後、デバイスでサポートされている構成に関する情報を取得します。 デバイスがサポートする構成の数を確認するには、返された構造体の bNumConfigurations メンバーを調べます。 このデバイスは 1 つの構成をサポートします。 USB 構成に関する情報を取得するには、ドライバーが USB 構成記述子を取得する必要があります。