示例#1
0
        public override void Run(SwitchOptions Options)
        {
            string id   = Options.ID.ToLower();
            string name = Options.Name.ToLower();

            Func <VideoCard, bool> predicate = string.IsNullOrEmpty(id)
                ? new Func <VideoCard, bool>(x => x.Name.ToLower().Contains(name))
                : x => x.ID.ToLower().Contains(id) || id.Contains(x.ID.ToLower());

            VideoCard card = VideoCard.EnumerateVideoCards().FirstOrDefault(predicate);

            if (card is null)
            {
                if (!string.IsNullOrEmpty(Options.ID))
                {
                    try
                    {
                        SetupAPI.ChangeDeviceState(VideoCard.VideoAdaptersClass, Options.ID, !Options.Disable);
                        return;
                    } catch { }
                }
                PrintException("The specified video card was not found");
            }
            else
            {
                try
                {
                    if (Options.Disable)
                    {
                        card.Disable();
                    }
                    else
                    {
                        card.Enable();
                    }
                }
                catch (Exception e)
                {
                    PrintException(e);
                }
            }
        }
示例#2
0
        public static string FindDfrDevice()
        {
            string instancePath = null;
            var    bResult      = true;
            uint   i            = 0;

            var h = SetupAPI.SetupDiGetClassDevs(
                ref DfrDisplayInterfaceGuid,
                IntPtr.Zero,
                IntPtr.Zero,
                SetupAPI.DIGCF_PRESENT | SetupAPI.DIGCF_DEVICEINTERFACE
                );

            if (h != IntPtr.Zero)
            {
                // https://www.pinvoke.net/default.aspx/setupapi.setupdienumdeviceinterfaces
                while (bResult)
                {
                    SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
                    dia.cbSize = (uint)Marshal.SizeOf(dia);

                    bResult = SetupAPI.SetupDiEnumDeviceInterfaces(h, IntPtr.Zero,
                                                                   ref DfrDisplayInterfaceGuid, i, dia);
                    if (bResult)
                    {
                        SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
                        da.cbSize = (uint)Marshal.SizeOf(da);

                        if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(h, dia, IntPtr.Zero, 0, out uint nRequiredSize, null))
                        {
                            // ERROR_INSUFFICIENT_BUFFER
                            if (Marshal.GetLastWin32Error() != 122)
                            {
                                throw new Win32Exception(Marshal.GetLastWin32Error());
                            }

                            var deviceInterfaceDetailData = Marshal.AllocHGlobal((int)nRequiredSize);

                            try
                            {
                                Marshal.WriteInt32(deviceInterfaceDetailData,
                                                   (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
                                if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(h, dia,
                                                                              deviceInterfaceDetailData, nRequiredSize, out uint _, null))
                                {
                                    throw new Win32Exception(Marshal.GetLastWin32Error());
                                }

                                IntPtr pDevicePathName = new IntPtr(deviceInterfaceDetailData.ToInt64() + 4);
                                return(Marshal.PtrToStringAuto(pDevicePathName));
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(deviceInterfaceDetailData);
                            }
                        }
                    }

                    i++;
                }
            }

            return(instancePath);
        }
示例#3
0
    public static InterfaceDetails[] getConnectedDevices()
    {
        InterfaceDetails[] devices = new InterfaceDetails[0];

        //Create structs to hold interface information
        SP_DEVINFO_DATA          devInfo  = new SP_DEVINFO_DATA();
        SP_DEVICE_INTERFACE_DATA devIface = new SP_DEVICE_INTERFACE_DATA();

        devInfo.cbSize  = (uint)Marshal.SizeOf(devInfo);
        devIface.cbSize = (uint)(Marshal.SizeOf(devIface));

        Guid G = new Guid();

        HID.HidD_GetHidGuid(ref G); //Get the guid of the HID device class

        IntPtr i = SetupAPI.SetupDiGetClassDevs(ref G, IntPtr.Zero, IntPtr.Zero, SetupAPI.DIGCF_DEVICEINTERFACE | SetupAPI.DIGCF_PRESENT);

        //Loop through all available entries in the device list, until false
        SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();

        if (IntPtr.Size == 8) // for 64 bit operating systems
        {
            didd.cbSize = 8;
        }
        else
        {
            didd.cbSize = 4 + Marshal.SystemDefaultCharSize;             // for 32 bit systems
        }

        int            j = -1;
        bool           b = true;
        SafeFileHandle tempHandle;

        while (b)
        {
            ++j;
            b = SetupAPI.SetupDiEnumDeviceInterfaces(i, IntPtr.Zero, ref G, (uint)j, ref devIface);
            if (b == false)
            {
                break;
            }

            uint requiredSize = 0;
            SetupAPI.SetupDiGetDeviceInterfaceDetail(i, ref devIface, ref didd, 256, out requiredSize, ref devInfo);
            string devicePath = didd.DevicePath;

            //create file handles using CT_CreateFile
            tempHandle = Kernel32.CreateFile(devicePath, Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE,
                                             IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero);

            //get capabilites - use getPreParsedData, and getCaps
            //store the reportlengths
            IntPtr ptrToPreParsedData = new IntPtr();
            bool   ppdSucsess         = HID.HidD_GetPreparsedData(tempHandle, ref ptrToPreParsedData);
            if (ppdSucsess == false)
            {
                continue;
            }

            HIDP_CAPS capabilities = new HIDP_CAPS();
            HID.HidP_GetCaps(ptrToPreParsedData, ref capabilities);

            HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES();
            HID.HidD_GetAttributes(tempHandle, ref attributes);

            string productName = "";
            string SN          = "";
            string manfString  = "";
            IntPtr buffer      = Marshal.AllocHGlobal(126);//max alloc for string;
            if (HID.HidD_GetProductString(tempHandle, buffer, 126))
            {
                productName = Marshal.PtrToStringAuto(buffer);
            }
            if (HID.HidD_GetSerialNumberString(tempHandle, buffer, 126))
            {
                SN = Marshal.PtrToStringAuto(buffer);
            }
            if (HID.HidD_GetManufacturerString(tempHandle, buffer, 126))
            {
                manfString = Marshal.PtrToStringAuto(buffer);
            }
            Marshal.FreeHGlobal(buffer);

            //Call freePreParsedData to release some stuff
            HID.HidD_FreePreparsedData(ref ptrToPreParsedData);

            //If connection was sucsessful, record the values in a global struct
            InterfaceDetails productInfo = new InterfaceDetails();
            productInfo.devicePath           = devicePath;
            productInfo.manufacturer         = manfString;
            productInfo.product              = productName;
            productInfo.PID                  = (ushort)attributes.ProductID;
            productInfo.VID                  = (ushort)attributes.VendorID;
            productInfo.versionNumber        = (ushort)attributes.VersionNumber;
            productInfo.IN_reportByteLength  = (int)capabilities.InputReportByteLength;
            productInfo.OUT_reportByteLength = (int)capabilities.OutputReportByteLength;
            productInfo.serialNumber         = SN; //Check that serial number is actually a number

            int newSize = devices.Length + 1;
            Array.Resize(ref devices, newSize);
            devices[newSize - 1] = productInfo;
        }
        SetupAPI.SetupDiDestroyDeviceInfoList(i);

        return(devices);
    }
示例#4
0
 public void Disable() => SetupAPI.ChangeDeviceState(VideoAdaptersClass, ID, false);
示例#5
0
 public void Enable() => SetupAPI.ChangeDeviceState(VideoAdaptersClass, ID, true);
示例#6
0
        /// <summary>
        /// Scans the computer for any USB devices matching th specified VID/PID DeviceID.
        /// Throws an exception if none are found
        /// </summary>
        public void Connect()
        {
            var deviceInterfaceDetailData = new SetupAPI.SP_DEVICE_INTERFACE_DETAIL_DATA();
            var deviceInterfaceData       = new SetupAPI.SP_DEVICE_INTERFACE_DATA();
            var deviceInfoData            = new SetupAPI.SP_DEVINFO_DATA();

            UInt32 interfaceIndex = 0;
            UInt32 dwRegType;
            UInt32 dwRegSize;
            UInt32 structureSize = 0;
            bool   matchFound    = false;

            //First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID.
            IntPtr pDeviceInfoTable = SetupAPI.SetupDiGetClassDevs(
                ref InterfaceClassGuid,
                null,
                IntPtr.Zero,
                SetupAPI.DIGCF_PRESENT | SetupAPI.DIGCF_DEVICEINTERFACE
                );

            try
            {
                //Now look through the list we just populated.  We are trying to see if any of them match our device.
                while (true)
                {
                    deviceInterfaceData.cbSize = (UInt32)Marshal.SizeOf(typeof(SetupAPI.SP_DEVICE_INTERFACE_DATA));

                    if (!SetupAPI.SetupDiEnumDeviceInterfaces(pDeviceInfoTable, IntPtr.Zero, ref InterfaceClassGuid, interfaceIndex, ref deviceInterfaceData))
                    {
                        int error = Marshal.GetLastWin32Error();
                        if (error == SetupAPI.ERROR_NO_MORE_ITEMS)
                        {
                            throw new HidDeviceException(String.Format("No HID devices found matching {0}", this.DeviceId));
                        }
                        else
                        {
                            throw new Win32Exception(error);
                        }
                    }

                    //Now retrieve the hardware ID from the registry.  The hardware ID contains the VID and PID, which we will then
                    //check to see if it is the correct device or not.

                    //Initialize an appropriate SP_DEVINFO_DATA structure.  We need this structure for SetupDiGetDeviceRegistryProperty().
                    deviceInfoData.cbSize = (UInt32)Marshal.SizeOf(typeof(SetupAPI.SP_DEVINFO_DATA));
                    if (!SetupAPI.SetupDiEnumDeviceInfo(pDeviceInfoTable, interfaceIndex, ref deviceInfoData))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    //Retrieve the hardware IDs for the current device we are looking at.  PropertyValueBuffer gets filled with a
                    //REG_MULTI_SZ (array of null terminated strings).  To find a device, we only care about the very first string in the
                    //buffer, which will be the "device ID".  The device ID is a string which contains the VID and PID, in the example
                    //format "Vid_04d8&Pid_003f".
                    String deviceIdFromRegistry = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_HARDWAREID);
                    if (deviceIdFromRegistry == null)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    //Now check if the first string in the hardware ID matches the device ID of my USB device.

                    //Convert both strings to lower case.  This makes the code more robust/portable across OS Versions
                    deviceIdFromRegistry = deviceIdFromRegistry.ToLowerInvariant();
                    var deviceIdToFind = this.DeviceId.ToLowerInvariant();

                    //Now check if the hardware ID we are looking at contains the correct VID/PID
                    matchFound = deviceIdFromRegistry.Contains(deviceIdToFind);
                    if (matchFound == true)
                    {
                        //Device must have been found.  (Goal: Open read and write handles)  In order to do this, we will need the actual device path first.
                        //We can get the path by calling SetupDiGetDeviceInterfaceDetail(), however, we have to call this function twice:  The first
                        //time to get the size of the required structure/buffer to hold the detailed interface data, then a second time to actually
                        //get the structure (after we have allocated enough memory for the structure.)
                        deviceInterfaceDetailData = new SetupAPI.SP_DEVICE_INTERFACE_DETAIL_DATA();

                        if (IntPtr.Size == 8) // for 64 bit operating systems
                        {
                            deviceInterfaceDetailData.cbSize = 8;
                        }
                        else
                        {
                            deviceInterfaceDetailData.cbSize = (UInt32)(4 + Marshal.SystemDefaultCharSize); // for 32 bit systems
                        }
                        UInt32 bufferSize = 1000;
                        if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(pDeviceInfoTable, ref deviceInterfaceData, ref deviceInterfaceDetailData, bufferSize, out structureSize, ref deviceInfoData))
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        // Finally set the devicePath
                        this.DevicePath = deviceInterfaceDetailData.DevicePath;

                        // Also get the device description
                        this.DeviceDescription = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_FRIENDLYNAME);
                        if (this.DeviceDescription == null)
                        {
                            this.DeviceDescription = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_DEVICEDESC);
                        }
                        return;
                    }

                    interfaceIndex++;
                    if (interfaceIndex == 10000000)                     //Surely there aren't more than 10 million interfaces attached to a single PC.
                    {
                        //If execution gets to here, it is probably safe to assume some kind of unanticipated problem occurred.
                        //In this case, bug out, to avoid infinite blocking while(true) loop.
                        throw new Exception("Unknown Error in HidDevice.Open()");
                    }

                    //Keep looping until we either find a device with matching VID and PID, or until we run out of items, or some error is encountered.
                }
            }
            finally
            {
                //Clean up the old structure we no longer need.
                SetupAPI.SetupDiDestroyDeviceInfoList(pDeviceInfoTable);
            }
        }
示例#7
0
        /// <summary>
        /// Modifies the device registry entry to use the specified name
        /// in the windows device manager.
        /// REQUIRES ADMINISTRATOR PRIVILEGE
        /// </summary>
        /// <param name="name">The name to display in the windows device manager</param>
        public void SetFriendlyName(string name)
        {
            WindowsIdentity  identity  = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);

            if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
            {
                throw new Exception("This function requires administrator privileges");
            }

            var deviceInterfaceData = new SetupAPI.SP_DEVICE_INTERFACE_DATA();
            var deviceInfoData      = new SetupAPI.SP_DEVINFO_DATA();

            UInt32 interfaceIndex = 0;

            // Populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID.
            IntPtr pDeviceInfoTable = SetupAPI.SetupDiGetClassDevs(
                ref InterfaceClassGuid,
                null,
                IntPtr.Zero,
                SetupAPI.DIGCF_PRESENT | SetupAPI.DIGCF_DEVICEINTERFACE
                );

            try
            {
                while (true)
                {
                    deviceInterfaceData.cbSize = (UInt32)Marshal.SizeOf(typeof(SetupAPI.SP_DEVICE_INTERFACE_DATA));

                    if (!SetupAPI.SetupDiEnumDeviceInterfaces(pDeviceInfoTable, IntPtr.Zero, ref InterfaceClassGuid, interfaceIndex, ref deviceInterfaceData))
                    {
                        int error = Marshal.GetLastWin32Error();
                        if (error == SetupAPI.ERROR_NO_MORE_ITEMS)
                        {
                            return;
                        }
                        else
                        {
                            throw new Win32Exception(error);
                        }
                    }

                    //Initialize an appropriate SP_DEVINFO_DATA structure.  We need this structure for SetupDiGetDeviceRegistryProperty().
                    deviceInfoData.cbSize = (UInt32)Marshal.SizeOf(typeof(SetupAPI.SP_DEVINFO_DATA));
                    if (!SetupAPI.SetupDiEnumDeviceInfo(pDeviceInfoTable, interfaceIndex, ref deviceInfoData))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    String deviceIdFromRegistry = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_HARDWAREID);
                    if (deviceIdFromRegistry != null)
                    {
                        deviceIdFromRegistry = deviceIdFromRegistry.ToLowerInvariant();;
                        String deviceIdToFind = this.DeviceId.ToLowerInvariant();

                        if (deviceIdFromRegistry.Contains(deviceIdToFind))
                        {
                            // Set the friendly name that's displayed in the device manager
                            SetupAPI.SetupDiSetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_FRIENDLYNAME, name);

                            this.DeviceDescription = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_FRIENDLYNAME);
                            if (this.DeviceDescription == null)
                            {
                                this.DeviceDescription = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_DEVICEDESC);
                            }
                        }
                    }


                    interfaceIndex++;
                    if (interfaceIndex == 10000000)     //Surely there aren't more than 10 million interfaces attached to a single PC.
                    {
                        return;
                    }
                }
            }
            finally
            {
                //Clean up the old structure we no longer need.
                SetupAPI.SetupDiDestroyDeviceInfoList(pDeviceInfoTable);
            }
        }
示例#8
0
    public static InterfaceDetails[] getConnectedDevices()
    {
        InterfaceDetails[] devices = new InterfaceDetails[0];

        //Create structs to hold interface information
        SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA();

        devInfo.cbSize = (uint)Marshal.SizeOf(devInfo);
        SP_DEVICE_INTERFACE_DATA devIface = new SP_DEVICE_INTERFACE_DATA();

        devIface.cbSize = (uint)(Marshal.SizeOf(devIface));

        Guid G = Guid.Empty;

        HID.HidD_GetHidGuid(ref G); //Get the guid of the HID device class

        IntPtr deviceInfo = SetupAPI.SetupDiGetClassDevs(ref G, IntPtr.Zero, IntPtr.Zero, SetupAPI.DIGCF_DEVICEINTERFACE | SetupAPI.DIGCF_PRESENT);
        //Loop through all available entries in the device list, until false
        int j = 0;

        while (true)
        {
            if (!SetupAPI.SetupDiEnumDeviceInterfaces(deviceInfo, IntPtr.Zero, ref G, (uint)j, ref devIface))
            {
                break;
            }
            uint   requiredSize = 0;
            IntPtr detailMemory = Marshal.AllocHGlobal((int)requiredSize);
            SP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = (SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(detailMemory, Typeof <SP_DEVICE_INTERFACE_DETAIL_DATA>());
            functionClassDeviceData.cbSize = Marshal.SizeOf(functionClassDeviceData);
            if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(deviceInfo, ref devIface, ref functionClassDeviceData, requiredSize, out requiredSize, ref devInfo))
            {
                Marshal.FreeHGlobal(detailMemory);
                break;
            }
            string devicePath = functionClassDeviceData.DevicePath;
            Marshal.FreeHGlobal(detailMemory);

            //create file handles using CT_CreateFile
            uint           desiredAccess = Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE;
            uint           shareMode     = Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE;
            SafeFileHandle tempHandle    = Kernel32.CreateFile(devicePath, desiredAccess, shareMode,
                                                               IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero);
            //get capabilites - use getPreParsedData, and getCaps
            //store the reportlengths
            IntPtr ptrToPreParsedData = new IntPtr();
            bool   ppdSucsess         = HID.HidD_GetPreparsedData(tempHandle, ref ptrToPreParsedData);
            if (!ppdSucsess)
            {
                continue;
            }

            HIDP_CAPS capability = new HIDP_CAPS();
            HID.HidP_GetCaps(ptrToPreParsedData, ref capability);

            HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES();
            HID.HidD_GetAttributes(tempHandle, ref attributes);

            string    productName = EMPTY;
            string    SN          = EMPTY;
            string    manfString  = EMPTY;
            const int bufferLen   = 128;
            IntPtr    buffer      = Marshal.AllocHGlobal(bufferLen);
            if (HID.HidD_GetProductString(tempHandle, buffer, bufferLen))
            {
                productName = Marshal.PtrToStringAuto(buffer);
            }
            if (HID.HidD_GetSerialNumberString(tempHandle, buffer, bufferLen))
            {
                SN = Marshal.PtrToStringAuto(buffer);
            }
            if (HID.HidD_GetManufacturerString(tempHandle, buffer, bufferLen))
            {
                manfString = Marshal.PtrToStringAuto(buffer);
            }
            Marshal.FreeHGlobal(buffer);

            //Call freePreParsedData to release some stuff
            HID.HidD_FreePreparsedData(ref ptrToPreParsedData);

            //If connection was sucsessful, record the values in a global struct
            InterfaceDetails productInfo = new InterfaceDetails();
            productInfo.devicePath           = devicePath;
            productInfo.manufacturer         = manfString;
            productInfo.product              = productName;
            productInfo.PID                  = (ushort)attributes.ProductID;
            productInfo.VID                  = (ushort)attributes.VendorID;
            productInfo.versionNumber        = (ushort)attributes.VersionNumber;
            productInfo.IN_reportByteLength  = capability.InputReportByteLength;
            productInfo.OUT_reportByteLength = capability.OutputReportByteLength;
            productInfo.serialNumber         = SN; //Check that serial number is actually a number

            int newSize = devices.Length + 1;
            Array.Resize(ref devices, newSize);
            devices[newSize - 1] = productInfo;
            ++j;
        }
        SetupAPI.SetupDiDestroyDeviceInfoList(deviceInfo);
        return(devices);
    }
示例#9
0
        private static uint GetDrivesDevInstByDeviceNumber(long DeviceNumber, Kernel32.DRIVE_TYPE DriveType)
        {
            Guid Type_Guid;

            switch (DriveType)
            {
            case Kernel32.DRIVE_TYPE.DRIVE_REMOVABLE:
            case Kernel32.DRIVE_TYPE.DRIVE_FIXED:
            {
                Type_Guid = new Guid(GUID_DEVINTERFACE_DISK);
                break;
            }

            case Kernel32.DRIVE_TYPE.DRIVE_CDROM:
            {
                Type_Guid = new Guid(GUID_DEVINTERFACE_CDROM);
                break;
            }

            default:
            {
                throw new ArgumentException("Parameter is invalid", nameof(DriveType));
            }
            }

            using (SetupAPI.SafeHDEVINFO hDevInfo = SetupAPI.SetupDiGetClassDevs(Type_Guid, Flags: SetupAPI.DIGCF.DIGCF_PRESENT | SetupAPI.DIGCF.DIGCF_DEVICEINTERFACE))
            {
                if (hDevInfo.IsInvalid || hDevInfo.IsNull)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                for (uint Index = 0; ; Index++)
                {
                    SetupAPI.SP_DEVICE_INTERFACE_DATA Interface_Data = new SetupAPI.SP_DEVICE_INTERFACE_DATA
                    {
                        cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(SetupAPI.SP_DEVICE_INTERFACE_DATA)))
                    };

                    if (!SetupAPI.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, Type_Guid, Index, ref Interface_Data))
                    {
                        int Error = Marshal.GetLastWin32Error();

                        if (Error != Win32Error.ERROR_NO_MORE_ITEMS)
                        {
                            throw new Win32Exception(Error);
                        }

                        break;
                    }

                    SetupAPI.SP_DEVINFO_DATA devData = new SetupAPI.SP_DEVINFO_DATA
                    {
                        cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(SetupAPI.SP_DEVINFO_DATA)))
                    };

                    if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(hDevInfo, Interface_Data, IntPtr.Zero, 0, out uint Size, ref devData))
                    {
                        int Error = Marshal.GetLastWin32Error();

                        if (Error != Win32Error.ERROR_INSUFFICIENT_BUFFER)
                        {
                            throw new Win32Exception(Error);
                        }
                    }

                    IntPtr Buffer = Marshal.AllocHGlobal(Convert.ToInt32(Size));

                    try
                    {
                        SetupAPI.SP_DEVICE_INTERFACE_DETAIL_DATA Interface_Detail_Data = new SetupAPI.SP_DEVICE_INTERFACE_DETAIL_DATA
                        {
                            cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(SetupAPI.SP_DEVICE_INTERFACE_DETAIL_DATA)))
                        };

                        Marshal.StructureToPtr(Interface_Detail_Data, Buffer, false);

                        if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(hDevInfo, Interface_Data, Buffer, Size, out _, ref devData))
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        string DevicePath = Marshal.PtrToStringAuto((IntPtr)(Buffer.ToInt64() + Marshal.SizeOf(typeof(int))));

                        using (Kernel32.SafeHFILE hDrive = Kernel32.CreateFile(DevicePath, 0, FileShare.ReadWrite, null, FileMode.Open, FileFlagsAndAttributes.SECURITY_ANONYMOUS))
                        {
                            if (!hDrive.IsInvalid && !hDrive.IsNull && DeviceNumber == GetDeviceNumber(hDrive))
                            {
                                return(devData.DevInst);
                            }
                        }
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(Buffer);
                    }
                }
            }

            return(0);
        }