5

SetupAPI を使用して USB デバイスを列挙することができました。また、WDK から usbview アプリケーションを調べましたが、まだUSB_DEVICE_DESCRIPTORを取得する方法がわかりません。

  • WMI の使用は避けたいと思います。
  • DeviceIoControlは、サンプル アプリ usbview が使用するものですが、実際にはハブでデバイスを列挙している場合にのみ機能します。デバイス パス (または ID) を指定して親ハブ (およびポート) にアクセスできる場合、この方法は機能する可能性がありますが、これを行う方法も特定できませんでした。
  • 記述子を取得したいデバイスが混在しています。これらの一部は HID であり、一部は WinUsb.sys デバイスである可能性があります。それらが WinUsb デバイスの場合、 WinUsb_GetDescriptor を使用できます、HIDでは機能しません (そして、Id または Path...Interface クラスからそれらの違いを見分ける方法がわかりません)。
  • SetupDiGetDeviceRegistryPropertyを使用できますが、使用可能なプロパティのリストに製造元の文字列は表示されますが、ベンダー ID は表示されません。
  • デバイス パスまたはデバイス ID からこの値を解析できる可能性がありますが、それは一種のハックのようです。それはただ人々がすることですか?また、Manufacturer のような他のフィールドが必要な場合は、他のメソッドに行く必要があります。USB_DEVICE_DESCRIPTOR 全体を取得できれば、必要なものはすべて揃っていると思います。
  • LibUsb.Net は明らかに WinUsb デバイスのみをサポートしています。それが記述子を取得する方法です。
  • どうやら WinRT にはいくつかの新しい API があるため、Windows ストア アプリには記述子を取得する優れた方法があります。しかし、これは間違いなく Windows ストア アプリではありません。また、新しい API を使用する別の方法があるかどうかもわかりません。

誰かが私を正しい方向に向けることができますか? ハブから開始しないと、WinAPI からこの情報を適切な方法で取得することはできないのでしょうか?

4

1 に答える 1

1

最善の策は、デバイス パスから情報を抽出し、SetupDi 関数を使用してその他の断片を取得することです。私の知る限り、デバイス パスは常に同じ規則に従います。すなわち:

"\\?\usb#vid_ 0000 &pid_ 111​​1 # SERIAL #{ GUID }" 0000 は VID、1111 は 16 進文字列としての PID ですSERIAL は、ハードウェアによって提供されるシリアルか、OS によって割り当てられたシリアル値のいずれかです。

私は個人的に、シリアルをそのようにプルするためにデバイス記述子を絶対に取得したいインスタンスを見つけました。場合によっては、OS がハードウェアから提供されたシリアル番号を認識していませんでした。ハードウェア側でそれを修正しましたが、それでも PC 側で古いハードウェアに対応したかったのです。以下は私のアプローチです。もっと良いものがあるかもしれませんが、これは今のところ私が思いついた最高のものです。ただし、それでも「ハックっぽい」と考えるかもしれません。

  1. SetupDiGetClassDevs() を呼び出して、目的の DeviceInfoSet をセットアップします
  2. SetupDiEnumDeviceInfo() を使用してデバイス情報データを取得します
  3. 位置情報を取得するには、SPDRP_LOCATION_INFORMATION を指定して SetupDiGetDeviceRegistryProperty() を呼び出します。この文字列は、「Port_#0001.Hub_#0001」のようになります。この文字列を解析して、デバイスが配置されているポート番号を取得します。(この値は 10 進数だと思いますが、まだ検証していません)
  4. CM_Get_Parent() を呼び出して、親 (ハブ) のデバイス ノード ポインター値を取得します。
  5. {0xf18a0e88, 0xc30c, 0x11d0, {0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8}} の GUID で SetupDiGetClassDevs() を呼び出して、システム上のすべてのハブを取得します。その GUID は、usbiodef.h で GUID_DEVINTERFACE_USB_HUB として定義する必要があります。
  6. SetupDiEnumDeviceInfo() を使用して、デバイスのリストを反復処理します。DevInst が手順 4 で取得した値と等しくなったら停止します。
  7. 手順 6 で見つかったインデックスで SetupDiGetDeviceInterfaceDetail() を呼び出します。
  8. 手順 7 で取得した DevicePath で CreateFile() を呼び出します。
  9. 手順 8 で作成したファイルと、手順 3 で取得したポート番号を接続インデックスとして使用して、DeviceIoControl() を呼び出します。

-編集-

Ben がコメントで指摘したように、手順 4 で取得した親の dev ノードで CM_Get_Device_ID を使用して、手順 5、6、および 7 をスキップできます。この文字列のスラッシュ (\) をポンド (#) に変更します。「\\?\」を先頭に追加し、「#{f18a0e88-c30c-11d0-8815-00a0c906bed8}」を追加します。これをステップ 8 のデバイス パスとして使用します。これにより、システム上のすべてのハブ デバイスを反復処理する必要がなくなります :)

于 2015-09-17T22:47:23.353 に答える