Ejemplo n.º 1
0
    public static string GetManufact(IntPtr h, USB_DEVICE_DESCRIPTOR PortDeviceDescriptor, int PortPortNumber)
    {
        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));
                return(StringDesc.bString);
            }
            Marshal.FreeHGlobal(ptrRequest);
        }

        return("");
    }
Ejemplo n.º 2
0
        private string GetSerialNumber()
        {
            if (_usbConnectInfomation.DeviceDescriptor.iSerialNumber <= 0)
            {
                return(string.Empty);
            }

            var request = new USB_DESCRIPTOR_REQUEST
            {
                ConnectionIndex = _portNo,
                SetupPacket     =
                {
                    wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) +
                                     _usbConnectInfomation.DeviceDescriptor.iSerialNumber)
                }
            };

            request.SetupPacket.wLength = (short)Marshal.SizeOf(request);
            // Language Code
            request.SetupPacket.wIndex = 0x409;

            var usbDescriptorRequest = DeviceIoControlInvoker.Invoke(
                _hubHandle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, request);

            return(usbDescriptorRequest.StringDescriptor.bString);
        }
Ejemplo n.º 3
0
Archivo: USB.cs Proyecto: rambom/Source
        /// <summary>
        /// 获取字符串描述符
        /// </summary>
        /// <param name="hHubDevice">USB Hub设备句柄</param>
        /// <param name="ConnectionIndex">连接索引号</param>
        /// <param name="DescriptorIndex">描述符索引号</param>
        /// <param name="LanguageID">语言ID</param>
        /// <returns>字符串描述符</returns>
        public static String GetStringDescriptor(IntPtr hHubDevice, Int32 ConnectionIndex, Byte DescriptorIndex, UInt16 LanguageID)
        {
            USB_DESCRIPTOR_REQUEST Buffer = new USB_DESCRIPTOR_REQUEST();

            Buffer.ConnectionIndex     = ConnectionIndex;
            Buffer.SetupPacket.wValue  = (UInt16)((USB_STRING_DESCRIPTOR_TYPE << 8) | DescriptorIndex);
            Buffer.SetupPacket.wIndex  = LanguageID;
            Buffer.SetupPacket.wLength = MAXIMUM_USB_STRING_LENGTH;
            Int32   nBytesReturned;
            Boolean Status = DeviceIoControl(hHubDevice,
                                             IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
                                             ref Buffer,
                                             Marshal.SizeOf(Buffer),
                                             ref Buffer,
                                             Marshal.SizeOf(Buffer),
                                             out nBytesReturned,
                                             IntPtr.Zero);

            if (Status)
            {
                return(Buffer.Data.bString);
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 4
0
 internal static extern Boolean DeviceIoControl(
     IntPtr hFile,
     Int32 dwIoControlCode,
     ref USB_DESCRIPTOR_REQUEST lpInBuffer,
     Int32 nInBufferSize,
     ref USB_DESCRIPTOR_REQUEST lpOutBuffer,
     Int32 nOutBufferSize,
     out Int32 lpBytesReturned,
     IntPtr lpOverlapped
     );
Ejemplo n.º 5
0
 public int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length)
 {
     using (SafeFileHandle handle = Parent.OpenHandle()) {
         int szRequest = Marshal.SizeOf(typeof(USB_DESCRIPTOR_REQUEST));
         USB_DESCRIPTOR_REQUEST request = new USB_DESCRIPTOR_REQUEST();
         request.ConnectionIndex    = AdapterNumber;
         request.SetupPacket.Value  = (short)((descriptorType << 8) + index);
         request.SetupPacket.Index  = (short)langId;
         request.SetupPacket.Length = (short)length;
         int    nBytes    = length + szRequest;
         Byte[] bigbuffer = new Byte[nBytes];
         if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ref request, Marshal.SizeOf(typeof(USB_DESCRIPTOR_REQUEST)), bigbuffer, nBytes, out nBytes, IntPtr.Zero))
         {
             if (descriptorType == (Byte)UsbDescriptorType.Device && index == 0 && langId == 0)
             {
                 Byte[] descbytes = DeviceDescriptor.GetBytes();
                 length = Math.Min(descbytes.Length, length);
                 Array.Copy(descbytes, 0, buffer, 0, length);
                 return(length);
             }
             int err = Marshal.GetLastWin32Error();
             if (err != 31)
             {
                 throw new Win32Exception(err);
             }
             return(0);
         }
         nBytes -= szRequest;
         if (nBytes > length)
         {
             nBytes = length;
         }
         if (nBytes < 0)
         {
             return(0);
         }
         if (nBytes > 0)
         {
             Buffer.BlockCopy(bigbuffer, szRequest, buffer, offset, nBytes);
         }
         return(nBytes);
     }
 }
Ejemplo n.º 6
0
        public USBDevice GetDevice()
        {
            if (!this.PortIsDeviceConnected)
            {
                return(null);
            }
            USBDevice uSBDevice = new USBDevice();

            uSBDevice.DevicePortNumber    = this.PortPortNumber;
            uSBDevice.DeviceHubDevicePath = this.PortHubDevicePath;
            uSBDevice.DeviceDescriptor    = this.PortDeviceDescriptor;
            uSBDevice.DeviceVID           = this.PortDeviceDescriptor.idVendor;
            uSBDevice.DevicePID           = this.PortDeviceDescriptor.idProduct;
            IntPtr intPtr = Acer_USB_Library.CreateFile(this.PortHubDevicePath, 1073741824, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);

            if (intPtr.ToInt32() != -1)
            {
                int    num  = 2048;
                string s    = new string('\0', 2048 / Marshal.SystemDefaultCharSize);
                int    num2 = default(int);
                if (this.PortDeviceDescriptor.iManufacturer > 0)
                {
                    USB_DESCRIPTOR_REQUEST structure = default(USB_DESCRIPTOR_REQUEST);
                    structure.ConnectionIndex     = this.PortPortNumber;
                    structure.SetupPacket.wValue  = (short)(768 + this.PortDeviceDescriptor.iManufacturer);
                    structure.SetupPacket.wLength = (short)(num - Marshal.SizeOf(structure));
                    structure.SetupPacket.wIndex  = 1033;
                    IntPtr intPtr2 = Marshal.StringToHGlobalAuto(s);
                    Marshal.StructureToPtr(structure, intPtr2, true);
                    if (Acer_USB_Library.DeviceIoControl(intPtr, 2229264, intPtr2, num, intPtr2, num, out num2, IntPtr.Zero))
                    {
                        USB_STRING_DESCRIPTOR uSB_STRING_DESCRIPTOR = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(new IntPtr(intPtr2.ToInt32() + Marshal.SizeOf(structure)), typeof(USB_STRING_DESCRIPTOR));
                        uSBDevice.DeviceManufacturer = uSB_STRING_DESCRIPTOR.bString;
                    }
                    Marshal.FreeHGlobal(intPtr2);
                }
                if (this.PortDeviceDescriptor.iProduct > 0)
                {
                    USB_DESCRIPTOR_REQUEST structure2 = default(USB_DESCRIPTOR_REQUEST);
                    structure2.ConnectionIndex     = this.PortPortNumber;
                    structure2.SetupPacket.wValue  = (short)(768 + this.PortDeviceDescriptor.iProduct);
                    structure2.SetupPacket.wLength = (short)(num - Marshal.SizeOf(structure2));
                    structure2.SetupPacket.wIndex  = 1033;
                    IntPtr intPtr3 = Marshal.StringToHGlobalAuto(s);
                    Marshal.StructureToPtr(structure2, intPtr3, true);
                    if (Acer_USB_Library.DeviceIoControl(intPtr, 2229264, intPtr3, num, intPtr3, num, out num2, IntPtr.Zero))
                    {
                        USB_STRING_DESCRIPTOR uSB_STRING_DESCRIPTOR2 = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(new IntPtr(intPtr3.ToInt32() + Marshal.SizeOf(structure2)), typeof(USB_STRING_DESCRIPTOR));
                        uSBDevice.DeviceProduct = uSB_STRING_DESCRIPTOR2.bString;
                    }
                    Marshal.FreeHGlobal(intPtr3);
                }
                if (this.PortDeviceDescriptor.iSerialNumber > 0)
                {
                    USB_DESCRIPTOR_REQUEST structure3 = default(USB_DESCRIPTOR_REQUEST);
                    structure3.ConnectionIndex     = this.PortPortNumber;
                    structure3.SetupPacket.wValue  = (short)(768 + this.PortDeviceDescriptor.iSerialNumber);
                    structure3.SetupPacket.wLength = (short)(num - Marshal.SizeOf(structure3));
                    structure3.SetupPacket.wIndex  = 1033;
                    IntPtr intPtr4 = Marshal.StringToHGlobalAuto(s);
                    Marshal.StructureToPtr(structure3, intPtr4, true);
                    if (Acer_USB_Library.DeviceIoControl(intPtr, 2229264, intPtr4, num, intPtr4, num, out num2, IntPtr.Zero))
                    {
                        USB_STRING_DESCRIPTOR uSB_STRING_DESCRIPTOR3 = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(new IntPtr(intPtr4.ToInt32() + Marshal.SizeOf(structure3)), typeof(USB_STRING_DESCRIPTOR));
                        uSBDevice.DeviceSerialNumber = uSB_STRING_DESCRIPTOR3.bString;
                    }
                    Marshal.FreeHGlobal(intPtr4);
                }
                USB_NODE_CONNECTION_DRIVERKEY_NAME uSB_NODE_CONNECTION_DRIVERKEY_NAME = default(USB_NODE_CONNECTION_DRIVERKEY_NAME);
                uSB_NODE_CONNECTION_DRIVERKEY_NAME.ConnectionIndex = this.PortPortNumber;
                num = Marshal.SizeOf(uSB_NODE_CONNECTION_DRIVERKEY_NAME);
                IntPtr intPtr5 = Marshal.AllocHGlobal(num);
                Marshal.StructureToPtr(uSB_NODE_CONNECTION_DRIVERKEY_NAME, intPtr5, true);
                if (Acer_USB_Library.DeviceIoControl(intPtr, 2229280, intPtr5, num, intPtr5, num, out num2, IntPtr.Zero))
                {
                    uSB_NODE_CONNECTION_DRIVERKEY_NAME = (USB_NODE_CONNECTION_DRIVERKEY_NAME)Marshal.PtrToStructure(intPtr5, typeof(USB_NODE_CONNECTION_DRIVERKEY_NAME));
                    uSBDevice.DeviceDriverKey          = uSB_NODE_CONNECTION_DRIVERKEY_NAME.DriverKeyName;
                    uSBDevice.DeviceName       = Acer_USB_Library.GetDescriptionByKeyName(uSBDevice.DeviceDriverKey);
                    uSBDevice.DeviceInstanceID = Acer_USB_Library.GetInstanceIDByKeyName(uSBDevice.DeviceDriverKey);
                }
                Marshal.FreeHGlobal(intPtr5);
                Acer_USB_Library.CloseHandle(intPtr);
            }
            return(uSBDevice);
        }
Ejemplo n.º 7
0
            // return a down stream external hub
            public USBDevice GetDevice()
            {
                if (!PortIsDeviceConnected)
                {
                    return null;
                }
                USBDevice Device = new USBDevice();

                // Copy over some values from the Port class
                // Ya know, I've given some thought about making Device a derived class...
                Device.DevicePortNumber = PortPortNumber;
                Device.DeviceHubDevicePath = PortHubDevicePath;
                Device.DeviceDescriptor = PortDeviceDescriptor;

                // Open a handle to the Hub device
                IntPtr h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
                if (h.ToInt32() != INVALID_HANDLE_VALUE)
                {
                    int nBytesReturned;
                    int nBytes = BUFFER_SIZE;
                    // We use this to zero fill a buffer
                    string NullString = new string((char)0, BUFFER_SIZE / Marshal.SystemDefaultCharSize);

                    // The iManufacturer, iProduct and iSerialNumber entries in the
                    // Device Descriptor are really just indexes.  So, we have to
                    // request a String Descriptor to get the values for those strings.

                    if (PortDeviceDescriptor.iManufacturer > 0)
                    {
                        // 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
                        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));
                            Device.DeviceManufacturer = StringDesc.bString;
                        }
                        Marshal.FreeHGlobal(ptrRequest);
                    }
                    if (PortDeviceDescriptor.iProduct > 0)
                    {
                        // 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.iProduct);
                        Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
                        Request.SetupPacket.wIndex = 0x409; // Language Code
                        // Geez, I wish C# had a Marshal.MemSet() method
                        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
                            IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
                            USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
                            Device.DeviceProduct = StringDesc.bString;
                        }
                        Marshal.FreeHGlobal(ptrRequest);
                    }
                    if (PortDeviceDescriptor.iSerialNumber > 0)
                    {
                        // 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.iSerialNumber);
                        Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
                        Request.SetupPacket.wIndex = 0x409; // Language Code
                        // Geez, I wish C# had a Marshal.MemSet() method
                        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
                            IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
                            USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
                            Device.DeviceSerialNumber = StringDesc.bString;
                        }
                        Marshal.FreeHGlobal(ptrRequest);
                    }

                    // Get the Driver Key Name (usefull in locating a device)
                    USB_NODE_CONNECTION_DRIVERKEY_NAME DriverKey = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
                    DriverKey.ConnectionIndex = PortPortNumber;
                    nBytes = Marshal.SizeOf(DriverKey);
                    IntPtr ptrDriverKey = Marshal.AllocHGlobal(nBytes);
                    Marshal.StructureToPtr(DriverKey, ptrDriverKey, true);

                    // Use an IOCTL call to request the Driver Key Name
                    if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ptrDriverKey, nBytes, ptrDriverKey, nBytes, out nBytesReturned, IntPtr.Zero))
                    {
                        DriverKey = (USB_NODE_CONNECTION_DRIVERKEY_NAME)Marshal.PtrToStructure(ptrDriverKey, typeof(USB_NODE_CONNECTION_DRIVERKEY_NAME));
                        Device.DeviceDriverKey = DriverKey.DriverKeyName;

                        // use the DriverKeyName to get the Device Description and Instance ID
                        Device.DeviceName = GetDescriptionByKeyName(Device.DeviceDriverKey);
                        Device.DeviceInstanceID = GetInstanceIDByKeyName(Device.DeviceDriverKey);
                    }
                    Marshal.FreeHGlobal(ptrDriverKey);
                    CloseHandle(h);
                }
                return Device;
            }
Ejemplo n.º 8
0
 internal static extern Boolean DeviceIoControl(
     IntPtr hFile,
     Int32 dwIoControlCode,
     ref USB_DESCRIPTOR_REQUEST lpInBuffer,
     Int32 nInBufferSize,
     ref USB_DESCRIPTOR_REQUEST lpOutBuffer,
     Int32 nOutBufferSize,
     out Int32 lpBytesReturned,
     IntPtr lpOverlapped
     );
Ejemplo n.º 9
0
 /// <summary>
 /// 获取字符串描述符
 /// </summary>
 /// <param name="hHubDevice">USB Hub设备句柄</param>
 /// <param name="ConnectionIndex">连接索引号</param>
 /// <param name="DescriptorIndex">描述符索引号</param>
 /// <param name="LanguageID">语言ID</param>
 /// <returns>字符串描述符</returns>
 public static String GetStringDescriptor(IntPtr hHubDevice, Int32 ConnectionIndex, Byte DescriptorIndex, UInt16 LanguageID)
 {
     USB_DESCRIPTOR_REQUEST Buffer = new USB_DESCRIPTOR_REQUEST();
     Buffer.ConnectionIndex = ConnectionIndex;
     Buffer.SetupPacket.wValue = (UInt16)((USB_STRING_DESCRIPTOR_TYPE << 8) | DescriptorIndex);
     Buffer.SetupPacket.wIndex = LanguageID;
     Buffer.SetupPacket.wLength = MAXIMUM_USB_STRING_LENGTH;
     Int32 nBytesReturned;
     Boolean Status = DeviceIoControl(hHubDevice,
             IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
             ref Buffer,
             Marshal.SizeOf(Buffer),
             ref Buffer,
             Marshal.SizeOf(Buffer),
             out nBytesReturned,
             IntPtr.Zero);
     if (Status)
         return Buffer.Data.bString;
     else
         return null;
 }
Ejemplo n.º 10
0
            // return a down stream external hub
            public USBDevice GetDevice()
            {
                if (!PortIsDeviceConnected)
                {
                    return(null);
                }

                // Copy over some values from the Port class
                // Ya know, I've given some thought about making Device a derived class...
                var Device = new USBDevice
                {
                    DevicePortNumber    = PortPortNumber,
                    DeviceHubDevicePath = PortHubDevicePath,
                    DeviceDescriptor    = PortDeviceDescriptor
                };

                // Open a handle to the Hub device
                var h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

                if (h.ToInt32() == INVALID_HANDLE_VALUE)
                {
                    return(Device);
                }

                int nBytesReturned;
                var nBytes = BUFFER_SIZE;
                // We use this to zero fill a buffer
                var NullString = new string((char)0, BUFFER_SIZE / Marshal.SystemDefaultCharSize);

                // The iManufacturer, iProduct and iSerialNumber entries in the
                // Device Descriptor are really just indexes.  So, we have to
                // request a String Descriptor to get the values for those strings.

                if (PortDeviceDescriptor.iManufacturer > 0)
                {
                    // build a request for string descriptor
                    var Request = new USB_DESCRIPTOR_REQUEST
                    {
                        ConnectionIndex = PortPortNumber,
                        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
                    var 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
                        var ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
                        var StringDesc    = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
                        Device.DeviceManufacturer = StringDesc.bString;
                    }
                    Marshal.FreeHGlobal(ptrRequest);
                }
                if (PortDeviceDescriptor.iProduct > 0)
                {
                    // build a request for string descriptor
                    var Request = new USB_DESCRIPTOR_REQUEST
                    {
                        ConnectionIndex = PortPortNumber,
                        SetupPacket     =
                        {
                            wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iProduct)
                        }
                    };
                    Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
                    Request.SetupPacket.wIndex  = 0x409; // Language Code
                    // Geez, I wish C# had a Marshal.MemSet() method
                    var 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
                        var ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
                        var StringDesc    = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
                        Device.DeviceProduct = StringDesc.bString;
                    }
                    Marshal.FreeHGlobal(ptrRequest);
                }
                if (PortDeviceDescriptor.iSerialNumber > 0)
                {
                    // build a request for string descriptor
                    var Request = new USB_DESCRIPTOR_REQUEST
                    {
                        ConnectionIndex = PortPortNumber,
                        SetupPacket     =
                        {
                            wValue =
                                (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iSerialNumber)
                        }
                    };
                    Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
                    Request.SetupPacket.wIndex  = 0x409; // Language Code
                    // Geez, I wish C# had a Marshal.MemSet() method
                    var 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
                        var ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
                        var StringDesc    = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
                        Device.DeviceSerialNumber = StringDesc.bString;
                    }
                    Marshal.FreeHGlobal(ptrRequest);
                }

                // Get the Driver Key Name (usefull in locating a device)
                var DriverKey = new USB_NODE_CONNECTION_DRIVERKEY_NAME {
                    ConnectionIndex = PortPortNumber
                };

                nBytes = Marshal.SizeOf(DriverKey);
                var ptrDriverKey = Marshal.AllocHGlobal(nBytes);

                Marshal.StructureToPtr(DriverKey, ptrDriverKey, true);

                // Use an IOCTL call to request the Driver Key Name
                if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ptrDriverKey, nBytes, ptrDriverKey, nBytes, out nBytesReturned, IntPtr.Zero))
                {
                    DriverKey = (USB_NODE_CONNECTION_DRIVERKEY_NAME)Marshal.PtrToStructure(ptrDriverKey, typeof(USB_NODE_CONNECTION_DRIVERKEY_NAME));
                    Device.DeviceDriverKey = DriverKey.DriverKeyName;

                    // use the DriverKeyName to get the Device Description and Instance ID
                    Device.DeviceName       = GetDescriptionByKeyName(Device.DeviceDriverKey);
                    Device.DeviceInstanceID = GetInstanceIDByKeyName(Device.DeviceDriverKey);
                }
                Marshal.FreeHGlobal(ptrDriverKey);
                CloseHandle(h);
                return(Device);
            }