2016-04-05 76 views
1

C#またはC++でUSBデバイスディスクリプタ(デバイスはハードドライブではなく、ヘッドセットのような外部デバイス)から製品文字列を取得するにはどうすればよいですか?私は "私のヘッドセット"の文字列を取得する必要があります。USBデバイスの製品文字列を取得する(C#/ C++)

 ======================== USB Device ======================== 

     +++++++++++++++++ Device Information ++++++++++++++++++ 
Device Description  : USB Composite Device 
Device Path    : \\?\usb#vid_2ae2&pid_1388#abcdef#{a5dcbf10-6530-11d2-901f-00c04fb951ed} 
Device ID    : USB\VID_2AE2&PID_1388\ABCDEF
Driver KeyName   : {36fc9e60-c465-11cf-8056-444553540000}\0018 (GUID_DEVCLASS_USB) 
Driver     : C:\Windows\System32\drivers\usbccgp.sys (Version: 6.3.9600.17238 Date: 2014-07-24) 
Driver Inf    : C:\Windows\inf\usb.inf 
Legacy BusType   : PNPBus 
Class     : USB 
Service     : usbccgp 
Enumerator    : USB 
Location Info   : Port_#0006.Hub_#0003 
Location IDs    : PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(6), ACPI(_SB_)#ACPI(PCI0)#ACPI(XHC_)#ACPI(RHUB)#ACPI(HS06) 
Container ID    : {acb9ebb8-b976-57c5-b90d-5ecc5e96e487} 
Manufacturer Info  : (Standard USB Host Controller) 
Capabilities    : 0x94 (Removable, UniqueID, SurpriseRemovalOK) 
Address     : 6 
Problem Code    : 0 
Power State    : D0 (supported: D0, D3, wake from D0) 
Child Device 1   : USB Input Device 
    Device ID    : USB\VID_2AE2&PID_1388&MI_03\6&12E75DA&0&0003 
    Class     : HIDClass 
    Child Device 1  : HID-compliant consumer control device 
    Device ID   : HID\VID_2AE2&PID_1388&MI_03\7&178A021A&0&0000 
    Class    : HIDClass 
Child Device 2   : USB Audio Device 
    Device ID    : USB\VID_2AE2&PID_1388&MI_00\6&12E75DA&0&0000 
    Class     : MEDIA 
    Child Device 1  : Audio Endpoint 
    Device ID   : SWD\MMDEVAPI\{0.0.1.00000000}.{0B0B6598-290C-495B-A4E1-D6A633F61574} 
    Class    : AudioEndpoint 
    Child Device 2  : Audio Endpoint 
    Device ID   : SWD\MMDEVAPI\{0.0.0.00000000}.{E3ADC851-586E-4FF8-BBF3-0EBF7E72FBDA} 
    Class    : AudioEndpoint 

     ------------------ Device Descriptor ------------------ 
bLength     : 0x12 (18 bytes) 
bDescriptorType   : 0x01 (Device Descriptor) 
bcdUSB     : 0x200 (USB Version 2.00) 
bDeviceClass    : 0x00 (defined by the interface descriptors) 
bDeviceSubClass   : 0x00 
bDeviceProtocol   : 0x00 
bMaxPacketSize0   : 0x40 (64 bytes) 
idVendor     : 0x2AE2 
idProduct    : 0x1388 
bcdDevice    : 0x1393 
iManufacturer   : 0x00 (No String Descriptor) 
iProduct     : 0x02 (String Descriptor 2) 
Language 0x0409   : "My Headset" 
iSerialNumber   : 0x03 (String Descriptor 3) 
Language 0x0409   : "ABCDEF" 
bNumConfigurations  : 0x01 

は現在、私は、製品の文字列を取得するには、このコードサンプルを使用し、私はハブを開いて、このハブに接続されている私のデバイスの製品文字列を取得するためにIOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTIONでのDeviceIoControlを呼び出しますが、このコードは時々ハブので、随時作品他の誰かによって開かれたとのCreateFileは(hubPath ...)失敗している:

// Open Hub 
IntPtr handle = CreateFile(hubPath, FileAccess.ReadWrite, FileShare.ReadWrite, 
    IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); 

if (handle.ToInt32() != INVALID_HANDLE_VALUE) 
{ 
    // 1. Load connection properties to get Device descriptor indexes 
    LogWriter.Debug("checking device, load hub connection properties..."); 

    USB_NODE_CONNECTION_INFORMATION_EX connectionInfo = new USB_NODE_CONNECTION_INFORMATION_EX(); 
    connectionInfo.ConnectionIndex = port; 

    // memset 
    string NullString = new string((char)0, nBytes/Marshal.SystemDefaultCharSize); 
    IntPtr connectionInfoBuffer = Marshal.StringToHGlobalAuto(NullString); 
    Marshal.StructureToPtr(connectionInfo, connectionInfoBuffer, true); 
    int iProductIndex = -1; 

    int ioBytes = Marshal.SizeOf(connectionInfo); 
    int nBytesReturned = 0; 

    if (DeviceIoControl(handle, 
     IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, 
     connectionInfoBuffer, 
     ioBytes, 
     connectionInfoBuffer, 
     ioBytes, 
     out nBytesReturned, 
     IntPtr.Zero) != 0) 
    { 
     LogWriter.Debug("checking device, hub connection properties loaded"); 

     USB_NODE_CONNECTION_INFORMATION_EX nodeConnection = (USB_NODE_CONNECTION_INFORMATION_EX)Marshal.PtrToStructure(connectionInfoBuffer, typeof(USB_NODE_CONNECTION_INFORMATION_EX)); 

     if (nodeConnection.DeviceIsHub == 0) 
     { 
      iProductIndex = nodeConnection.DeviceDescriptor.iProduct; 
      LogWriter.Debug(String.Format("GetDeviceProperties() Checking device, iProductIndex = {0}", iProductIndex)); 
     } 
    } 
    else 
    { 
     CheckError("DeviceIoControl"); 
    } 

    // 2. Load iProduct descriptor 
    USB_DESCRIPTOR_REQUEST stringDescReq = new USB_DESCRIPTOR_REQUEST(); 

    int bufSize = Marshal.SizeOf(stringDescReq) + MAXIMUM_USB_STRING_LENGTH; 

    stringDescReq.ConnectionIndex = port; 
    stringDescReq.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) | iProductIndex); 
    stringDescReq.SetupPacket.wIndex = 1033; // Language code 
    stringDescReq.SetupPacket.wLength = (short)(bufSize - Marshal.SizeOf(stringDescReq)); 

    // типа memset 
    IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString); 
    Marshal.StructureToPtr(stringDescReq, ptrRequest, true); 

    int nBytesRet = 0; 

    LogWriter.Debug(String.Format("checking device, load USB descriptor({0}, {1}, {2})", 
     stringDescReq.SetupPacket.wValue, 
     stringDescReq.SetupPacket.wIndex, 
     stringDescReq.SetupPacket.wLength)); 

    if (DeviceIoControl(handle, 
     IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, 
     ptrRequest, 
     bufSize, 
     ptrRequest, 
     bufSize, 
     out nBytesRet, 
     IntPtr.Zero) != 0) 
    { 
     int ptrSize = ptrRequest.ToInt32(); 

     LogWriter.Debug(String.Format("checking device, USB descriptor loaded({0}, {1})", 
      ptrSize, 
      Marshal.SizeOf(stringDescReq))); 

     IntPtr ptrStringDesc = new IntPtr(ptrSize + Marshal.SizeOf(stringDescReq)); 
     USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR)); 
     prop.ProductName = StringDesc.bString; 

     if (prop.ProductName != null) 
     { 
      LogWriter.Debug("ProductName = " + prop.ProductName); 
     } 
    } 
    else 
    { 
     LogWriter.Warn("DeviceIoControl failed"); 
     CheckError("DeviceIoControl"); 
    } 

    CloseHandle(handle); 
} 

だから私は安定動作する製品の文字列を取得するための他の方法が必要です。

メモ:現在のデバイスはHIDなので、HIDの機能を使用することはできますが、私はHID以外のUSBデバイスも持っています。ソリューションがHIDとHID以外のデバイス時間。私は年前にHidD_GetProductStringルーチンを試しましたが、空のバッファが返ってきたことを覚えています(HIDに子デバイスがあり、問題が正しいデバイスパスを取得する方法であるため、デバイスパスが正しくない可能性があります)。

+0

は'失敗:あなたはHidLibraryを使用して、そしてHidDevice _deviceを持っている場合は、(メーカーが同じように動作します)、このような製品の文字列を取得することができますハブに直接照会することはできません。そのような単純な。情報がレジストリのような別の場所で利用できない場合は、運が悪いです。 –

+0

これを見てください:http://stackoverflow.com/questions/3331043/get-list-of-connected-usb-devices – Gusman

+0

私はWMIを試みましたが、usb製品の文字列を返しませんでした。クラスがあります)。 – Evgeniy

答えて

0

HidD_GetProductStringは、HIDデバイスに行く方法です。前に他のすべてのバイトで\0が発生した可能性があります。あなたは、他の誰かがオープンし、ハブ `のCreateFile()を持っている場合

byte[] bs; 
_device.ReadProduct(out bs); 
string ps = ""; 
foreach (byte b in bs) { 
    if (b > 0) 
     ps += ((char)b).ToString(); 
} 
+0

他のすべてのバイトが0である理由は、おそらくそれがUTF-16文字列であるためです。したがって、それを処理する方法は、非ASCII文字列を誤って処理します。 – rdb

関連する問題