Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

USB_STRING_DESCRIPTOR (Structures)
 
.
Summary

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;

None.

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.

Notes:

typedef struct _USB_STRING_DESCRIPTOR {
   UCHAR bLength;
   UCHAR bDescriptorType;
   WCHAR bString[1];
} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;

There is no Marshal.MemSet method to zero-out the buffer prior to use, so you might consider the following hack

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.

string NullString = new string((char)0, BUFFER_SIZE / Marshal.SystemDefaultCharSize);
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);

There is no Marshal.MemSet method to zero-out the buffer prior to use, so you might consider the following hack

Documentation

string NullString = new string((char)0, BUFFER_SIZE / Marshal.SystemDefaultCharSize);
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);

Example:

if (PortDeviceDescriptor.iManufacturer > 0) {
   int nBytesReturned;
   int nBytes = BUFFER_SIZE;

Documentation

   // 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

Example:

if (PortDeviceDescriptor.iManufacturer > 0) {
   int nBytesReturned;
   int nBytes = BUFFER_SIZE;

   // 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);
   // 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, BUFFER_SIZE / 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);
}

Please edit this page!

Do you have...

  • helpful tips?
  • corrections to the existing content?
  • alternate definitions?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing any supporting types needed.

 
Access PInvoke.net directly from VS:
Terms of Use
Edit This Page
Find References
Show Printable Version
Revisions