private static DeviceDetails GetDeviceDetails(string devicePath, IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData)
        {
            DeviceDetails details = new DeviceDetails();

            details.DevicePath        = devicePath;
            details.DeviceDescription = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_DEVICEDESC);
            details.Manufacturer      = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_MFG);
            string[] hardwareIDs = GetMultiStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_HARDWAREID);

            Regex regex       = new Regex("^USB\\\\VID_([0-9A-F]{4})&PID_([0-9A-F]{4})", RegexOptions.IgnoreCase);
            bool  foundVidPid = false;

            foreach (string hardwareID in hardwareIDs)
            {
                Match match = regex.Match(hardwareID);
                if (match.Success)
                {
                    details.VID = ushort.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.AllowHexSpecifier);
                    details.PID = ushort.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.AllowHexSpecifier);
                    foundVidPid = true;
                    break;
                }
            }

            if (!foundVidPid)
            {
                throw new APIException("Failed to find VID and PID for USB device. No hardware ID could be parsed.");
            }

            return(details);
        }
 internal USBDeviceInfo(API.DeviceDetails details)
 {
     _details = details;
 }
        public static DeviceDetails[] FindDevicesFromGuid(Guid guid)
        {
            IntPtr deviceInfoSet            = IntPtr.Zero;
            List <DeviceDetails> deviceList = new List <DeviceDetails>();

            try
            {
                deviceInfoSet = SetupDiGetClassDevs(ref guid, IntPtr.Zero, IntPtr.Zero,
                                                    DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
                if (deviceInfoSet == FileIO.INVALID_HANDLE_VALUE)
                {
                    throw APIException.Win32("Failed to enumerate devices.");
                }
                int memberIndex = 0;
                while (true)
                {
                    // Begin with 0 and increment through the device information set until
                    // no more devices are available.
                    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();

                    // The cbSize element of the deviceInterfaceData structure must be set to
                    // the structure's size in bytes.
                    // The size is 28 bytes for 32-bit code and 32 bytes for 64-bit code.
                    deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData);

                    bool success;

                    success = SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref guid, memberIndex, ref deviceInterfaceData);

                    // Find out if a device information set was retrieved.
                    if (!success)
                    {
                        int lastError = Marshal.GetLastWin32Error();
                        if (lastError == ERROR_NO_MORE_ITEMS)
                        {
                            break;
                        }

                        throw APIException.Win32("Failed to get device interface.");
                    }
                    // A device is present.

                    int bufferSize = 0;

                    success = SetupDiGetDeviceInterfaceDetail
                                  (deviceInfoSet,
                                  ref deviceInterfaceData,
                                  IntPtr.Zero,
                                  0,
                                  ref bufferSize,
                                  IntPtr.Zero);

                    if (!success)
                    {
                        if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
                        {
                            throw APIException.Win32("Failed to get interface details buffer size.");
                        }
                    }

                    IntPtr detailDataBuffer = IntPtr.Zero;
                    try
                    {
                        // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size.
                        detailDataBuffer = Marshal.AllocHGlobal(bufferSize);

                        // Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems.

                        Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);

                        // Call SetupDiGetDeviceInterfaceDetail again.
                        // This time, pass a pointer to DetailDataBuffer
                        // and the returned required buffer size.

                        // build a DevInfo Data structure
                        SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
                        da.cbSize = Marshal.SizeOf(da);


                        success = SetupDiGetDeviceInterfaceDetail
                                      (deviceInfoSet,
                                      ref deviceInterfaceData,
                                      detailDataBuffer,
                                      bufferSize,
                                      ref bufferSize,
                                      ref da);

                        if (!success)
                        {
                            throw APIException.Win32("Failed to get device interface details.");
                        }


                        // Skip over cbsize (4 bytes) to get the address of the devicePathName.

                        IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4);
                        string pathName        = Marshal.PtrToStringUni(pDevicePathName);

                        // Get the String containing the devicePathName.

                        DeviceDetails details = GetDeviceDetails(pathName, deviceInfoSet, da);


                        deviceList.Add(details);
                    }
                    finally
                    {
                        if (detailDataBuffer != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(detailDataBuffer);
                            detailDataBuffer = IntPtr.Zero;
                        }
                    }
                    memberIndex++;
                }
            }
            finally
            {
                if (deviceInfoSet != IntPtr.Zero && deviceInfoSet != FileIO.INVALID_HANDLE_VALUE)
                {
                    SetupDiDestroyDeviceInfoList(deviceInfoSet);
                }
            }
            return(deviceList.ToArray());
        }