@msdn=http://search.microsoft.com/search/results.aspx?qu=$$$ @pinvoke=http://pinvoke.net/$$$.htm Summary: Retrieve Manufacturer, Product, and SerialNumber strings from a USB device !!!!C# Definition: [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] struct USB_STRING_DESCRIPTOR { public byte bLength; public byte bDescriptorType; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXIMUM_USB_STRING_LENGTH)] public string bString; } !!!!VB Definition: Structure USB_STRING_DESCRIPTOR Public TODO End Structure !!!!User-Defined Field Types: const int MAXIMUM_USB_STRING_LENGTH = 255; const int USB_STRING_DESCRIPTOR_TYPE = 3; !!!!Notes: typedef struct _USB_STRING_DESCRIPTOR { UCHAR bLength; UCHAR bDescriptorType; WCHAR bString[1]; } USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR; You don't use an IOCTL call directly with a USB_STRING_DESCRIPTOR structure. Instead you use a USB_DESCRIPTOR_REQUEST "request packet" with IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION. The USB_STRING_DESCRIPTOR structure is returned at the very end of the request packet. The whole idea of "writing off the edge" of a structure is counter to the way C#/VB.Net was designed to work, so you'll have to make sure to allocate sufficient amount of memory to handle both the "request packet" and the USB_STRING_DESCRIPTOR structure. There is no Marshal.MemSet method to zero-out the buffer prior to use, so you might consider the following hack string NullString = new string((char)0, BUFFER_SIZE / Marshal.SystemDefaultCharSize); IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString); Documentation: USB_STRING_DESCRIPTOR@msdn on MSDN !!!!Example: if (PortDeviceDescriptor.iManufacturer > 0) { int nBytesReturned; int nBytes = BUFFER_SIZE; // build a request for string descriptor USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST(); Request.ConnectionIndex = PortPortNumber; Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iManufacturer); Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request)); Request.SetupPacket.wIndex = 0x409; // Language Code // Geez, I wish C# had a Marshal.MemSet() method string NullString = new string((char)0, nBytes / Marshal.SystemDefaultCharSize); IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString); Marshal.StructureToPtr(Request, ptrRequest, true); // Use an IOCTL call to request the String Descriptor if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero)) { // The location of the string descriptor is immediately after // the Request structure. Because this location is not "covered" // by the structure allocation, we're forced to zero out this // chunk of memory by using the StringToHGlobalAuto() hack above IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request)); USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR)); string DeviceManufacturer = StringDesc.bString; } Marshal.FreeHGlobal(ptrRequest); }
Edit Structures.USB_ST...
You do not have permission to change this page. If you feel this is in error, please send feedback with the contact link on the main page.