PORTS Forum
Ports and Interfaces => USB => Topic started by: lcpoon on July 19, 2012, 01:03:02 am
-
I have more than two WinUSB devices connected to the PC where each has dedicated serial number. What is the function used to communicate with dedicated device at one time?
-
This might help:
http://www.osronline.com/showthread.cfm?link=154789
Jan
-
Hi,
From FindDeviceFromGuid function:
'Call SetupDiGetDeviceInterfaceDetail again.
'This time, pass a pointer to DetailDataBuffer
'and the returned required buffer size.
success = SetupDiGetDeviceInterfaceDetail _
(deviceInfoSet, _
myDeviceInterfaceData, _
detailDataBuffer, _
bufferSize, _
bufferSize, _
IntPtr.Zero)
'Skip over cbsize (4 bytes) to get the address of the devicePathName.
pdevicePathName = New IntPtr(detailDataBuffer.ToInt32 + 4)
'Get the String containing the devicePathName.
devicePathName = Marshal.PtrToStringAuto(pdevicePathName)
devicePathName = "\\?\usb#vid_0957&pid_a118#my87654321#{400b501e-5a37-472d-b4a7-998bf4e9a7cd}"
I am using this to detect the device s/n to communicate with.
If I am using Microsoft USB device viewer to check the USB information, I can iManufacturer, iProduct and iSerialNumber. What is the WinUSB function used to read the iProduct info?
-
Use WinUsb_ControlTransfer to request the device descriptor.
Jan
-
Can you show me how to add WinUsb_ControlTransfer codes into FindDeviceFromGuid in order to retrieve the device descriptor info?
-
These may help:
http://www.lvr.com/hidpage.htm#MyExampleCode
http://msdn.microsoft.com/en-us/library/windows/hardware/ff540219%28v=vs.85%29.aspx
USB 2.0 spec, section 9.4.3
Jan
-
I still not manage to read the USB product name using WinUSB API, hope you can help.
-
Post a code excerpt of what you've tried.
-
I added in these codes to
<DllImport("winusb.dll", SetLastError:=True)> Friend Shared Function WinUsb_GetDescriptor _
(ByVal InterfaceHandle As IntPtr, _
ByVal DescriptorType As Byte, _
ByVal Index As Byte, _
ByVal LanguageID As UShort, _
ByVal bufferptr As IntPtr, _
ByVal BufferLength As Integer, _
ByRef DescriptorLengthptr As Integer) _
As Boolean
End Function
-
I am not familiar with WinUSB and do not know how to proceed then.
-
I added this to the WinUsbDeviceApi too:
Friend Structure USB_DEVICE_DESCRIPTOR
Friend bLength As Byte
Friend bDescriptorType As Byte
Friend bcdUSB As UInt16
Friend bDeviceClass As Byte
Friend bDeviceSubClass As Byte
Friend bDeviceProtocol As Byte
Friend bMaxPacketSize0 As Byte
Friend idVendor As UInt16
Friend idProduct As UInt16
Friend bcdDevice As UInt16
Friend iManufacturer As Byte
Friend iProduct As Byte
Friend iSerialNumber As Byte
Friend bNumConfigurations As Byte
End Structure
I added in some lines after SetupDiGetDeviceInterfaceDetail to see if I managed to run WinUsb_GetDescriptor. However, WinUsbDevice.WinUsb_GetDescriptor returns false.
'Skip over cbsize (4 bytes) to get the address of the devicePathName.
pdevicePathName = New IntPtr(detailDataBuffer.ToInt32 + 4)
'Get the String containing the devicePathName.
DevicePathName = Marshal.PtrToStringAuto(pdevicePathName)
'Free the memory allocated previously by AllocHGlobal.
Marshal.FreeHGlobal(detailDataBuffer)
deviceFound = True
Dim mydevicedescriptor As New WinUsbDevice.USB_DEVICE_DESCRIPTOR
Dim ReadDescriptorLength As Integer
Dim DescriptorBufferSize As Integer = Marshal.SizeOf(mydevicedescriptor)
Dim bufferptr As IntPtr = Marshal.AllocHGlobal(DescriptorBufferSize)
Dim myWinUsbDevice As New WinUsbDevice()
Marshal.AllocHGlobal(Marshal.SizeOf(mydevicedescriptor))
success = WinUsbDevice.WinUsb_GetDescriptor(pdevicePathName, _
Convert.ToByte(1), _
Convert.ToByte(0), _
Convert.ToUInt16(&H409), _
bufferptr, _
DescriptorBufferSize, _
ReadDescriptorLength)
mydevicedescriptor = CType(Marshal.PtrToStructure(bufferptr, GetType(WinUsbDevice.USB_DEVICE_DESCRIPTOR)), WinUsbDevice.USB_DEVICE_DESCRIPTOR)
Marshal.FreeHGlobal(bufferptr)
-
This might help though you'll have to convert from VC# to VB:
http://winusbnet.googlecode.com/svn-history/r15/trunk/WinUSBNet/API/WinUSBDevice.cs
This and similar tools can help:
http://www.developerfusion.com/tools/convert/csharp-to-vb/
-
I tried to leverage the C# codes from the given link to VB.net but not working.
I added in these codes into WinUsbDeviceApi.vb:
Structure USB_DEVICE_DESCRIPTOR
Public bLength As Byte
Public bDescriptorType As Byte
Public bcdUSB As UShort
Public bDeviceClass As Byte
Public bDeviceSubClass As Byte
Public bDeviceProtocol As Byte
Public bMaxPacketSize0 As Byte
Public idVendor As UShort
Public idProduct As UShort
Public bcdDevice As UShort
Public iManufacturer As Byte
Public iProduct As Byte
Public iSerialNumber As Byte
Public bNumConfigurations As Byte
End Structure
<DllImport("winusb.dll", SetLastError:=True)> Private Shared Function WinUsb_GetDescriptor _
(ByVal InterfaceHandle As IntPtr, _
ByVal DescriptorType As Byte, _
ByVal Index As Byte, _
ByVal LanguageID As Byte, _
ByRef deviceDesc As USB_DEVICE_DESCRIPTOR, _
ByVal BufferLength As UInt32, _
ByRef LengthTransfered As UInt32) _
As Boolean
End Function
I added these codes into WinUsbDevice.vb
VB.net does not allow me to convert buffer to USB_DEVICE_DESCRIPTOR, how to solve this?
Error 1 Value of type '1-dimensional array of Byte' cannot be converted to 'WinUsbDemo.WinUsbDemo.WinUsbDevice.USB_DEVICE_DESCRIPTOR'. D:\Visual Basic Stuffs\VB 2008\U7227 - WinUSB\WinUsbDevice.vb 619
Private Function GetDeviceDescriptor() As USB_DEVICE_DESCRIPTOR
Dim deviceDesc As USB_DEVICE_DESCRIPTOR
Dim transfered As UInteger
Dim size As UInteger = CUInt(Marshal.SizeOf(GetType(USB_DEVICE_DESCRIPTOR)))
Dim success As Boolean = WinUsb_GetDescriptor(myDevInfo.winUsbHandle, 1, 0, 0, deviceDesc, size, transfered)
Return deviceDesc
End Function
Public Function GetStringDescriptor(ByVal index As Byte) As String
Dim buffer As Byte() = New Byte(255) {}
Dim transfered As UInteger
Dim success As Boolean = WinUsb_GetDescriptor(myDevInfo.winUsbHandle, 1, index, 0, buffer, CUInt(buffer.Length), transfered)
Dim length As Integer = buffer(0) - 2
If length <= 0 Then
Return Nothing
End If
Dim chars As Char() = System.Text.Encoding.Unicode.GetChars(buffer, 2, length)
Return New String(chars)
End Function
-
I fixed the VB error by adding in 2 more WinUsb_GetDescriptor functions.
<DllImport("winusb.dll", SetLastError:=True)> Private Shared Function WinUsb_GetDescriptor _
(ByVal InterfaceHandle As IntPtr, _
ByVal DescriptorType As Byte, _
ByVal Index As Byte, _
ByVal LanguageID As Byte, _
ByVal Buffer As Byte(), _
ByVal BufferLength As UInt32, _
ByRef LengthTransfered As UInt32) _
As Boolean
End Function
<DllImport("winusb.dll", SetLastError:=True)> Private Shared Function WinUsb_GetDescriptor _
(ByVal InterfaceHandle As IntPtr, _
ByVal DescriptorType As Byte, _
ByVal Index As Byte, _
ByVal LanguageID As Byte, _
ByRef deviceDesc As USB_DEVICE_DESCRIPTOR, _
ByVal BufferLength As UInt32, _
ByRef LengthTransfered As UInt32) _
As Boolean
End Function
<DllImport("winusb.dll", SetLastError:=True)> Private Shared Function WinUsb_GetDescriptor _
(ByVal InterfaceHandle As IntPtr, _
ByVal DescriptorType As Byte, _
ByVal Index As Byte, _
ByVal LanguageID As Byte, _
ByRef deviceDesc As USB_CONFIGURATION_DESCRIPTOR, _
ByVal BufferLength As UInt32, _
ByRef LengthTransfered As UInt32) _
As Boolean
End Function
Now, I need to leverage the subroutine below to the VB codes.
private static USBDeviceDescriptor GetDeviceDescriptor(string devicePath)
{
try
{
USBDeviceDescriptor descriptor;
using (API.WinUSBDevice wuDevice = new API.WinUSBDevice())
{
wuDevice.OpenDevice(devicePath);
API.USB_DEVICE_DESCRIPTOR deviceDesc = wuDevice.GetDeviceDescriptor();
// string q = wuDevice.GetStringDescriptor(0);
// TODO: use language id properly
string manufacturer = null, product = null, serialNumber = null;
byte idx = 0;
idx = deviceDesc.iManufacturer;
if (idx > 0)
manufacturer = wuDevice.GetStringDescriptor(idx);
idx = deviceDesc.iProduct;
if (idx > 0)
product = wuDevice.GetStringDescriptor(idx);
idx = deviceDesc.iSerialNumber;
if (idx > 0)
serialNumber = wuDevice.GetStringDescriptor(idx);
descriptor = new USBDeviceDescriptor(devicePath, deviceDesc, manufacturer, product, serialNumber);
}
return descriptor;
}
catch (API.APIException e)
{
throw new USBException("Failed to retrieve device descriptor.", e);
}
}
}
-
Here is what http://www.carlosag.net/Tools/CodeTranslator gives:
Private Shared Function GetDeviceDescriptor(ByVal devicePath As String) As USBDeviceDescriptor
Try
Dim descriptor As USBDeviceDescriptor
Dim wuDevice As API.WinUSBDevice = New API.WinUSBDevice
wuDevice.OpenDevice(devicePath)
Dim deviceDesc As API.USB_DEVICE_DESCRIPTOR = wuDevice.GetDeviceDescriptor
' string q = wuDevice.GetStringDescriptor(0);
' TODO: use language id properly
Dim serialNumber As String = Nothing
Dim manufacturer As String = Nothing
Dim product As String = Nothing
Dim idx As Byte = 0
idx = deviceDesc.iManufacturer
If (idx > 0) Then
manufacturer = wuDevice.GetStringDescriptor(idx)
End If
idx = deviceDesc.iProduct
If (idx > 0) Then
product = wuDevice.GetStringDescriptor(idx)
End If
idx = deviceDesc.iSerialNumber
If (idx > 0) Then
serialNumber = wuDevice.GetStringDescriptor(idx)
End If
descriptor = New USBDeviceDescriptor(devicePath, deviceDesc, manufacturer, product, serialNumber)
Return descriptor
Catch e As API.APIException
Throw New USBException("Failed to retrieve device descriptor.", e)
End Try
End Function