예제 #1
0
        public static string GetDevRegPropertyStr(
            SetupApi.DeviceInfoSet devInfoSet,
            SetupApi.SP_DEVINFO_DATA devInfoData,
            SetupApi.SPDRP property)
        // Use this function for any 'Device Registry
        // Property' that returns a string,
        // e.g. SPDRP_CLASSGUID
        {
            int propertyRegDataType;
            int requiredSize;

            // 'buffer' is 1KB  but Unicode chars are 2 bytes,
            // hence 'buffer' can hold up to 512 chars
            const int BUFFER_SIZE = 1024;

            byte[] buffer = new byte[BUFFER_SIZE];

            SetupApi.SetupDiGetDeviceRegistryProperty(
                devInfoSet.Get(),
                devInfoData,
                property,
                out propertyRegDataType,
                buffer,
                BUFFER_SIZE,
                out requiredSize
                );

            return(System.Text.Encoding.Unicode.GetString(
                       buffer,
                       0,
                       requiredSize
                       ));
        }
예제 #2
0
        public static string[] GetDevRegPropertyMultiStr(
            SetupApi.DeviceInfoSet devInfoSet,
            SetupApi.SP_DEVINFO_DATA devInfoData,
            SetupApi.SPDRP property)
        // Use this function for any 'Device Registry
        // Property' that returns 'REG_MULTI_SZ',
        // e.g. SPDRP_HARDWAREID
        {
            int propertyRegDataType;
            int requiredSize;

            // 'buffer' is 4KB  but Unicode chars are 2 bytes,
            // hence 'buffer' can hold up to 2K chars
            const int BUFFER_SIZE = 4096;

            byte[] buffer = new byte[BUFFER_SIZE];

            SetupApi.SetupDiGetDeviceRegistryProperty(
                devInfoSet.Get(),
                devInfoData,
                property,
                out propertyRegDataType,
                buffer,
                BUFFER_SIZE,
                out requiredSize
                );

            return(Helpers.StringArrayFromMultiSz(buffer));
        }
예제 #3
0
 public Byte[] GetProperty(SPDRP property)
 {
     using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) {
         if (dis.IsInvalid)
         {
             throw new Win32Exception();
         }
         SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true);
         if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd))
         {
             return(null);
         }
         RegistryValueKind propertyType;
         byte[]            propBuffer = new byte[256];
         int requiredSize;
         if (!SetupApi.SetupDiGetDeviceRegistryProperty(dis, ref dd, property, out propertyType, propBuffer, propBuffer.Length, out requiredSize))
         {
             return(null);
         }
         if (requiredSize > propBuffer.Length)
         {
             propBuffer = new Byte[requiredSize];
             if (!SetupApi.SetupDiGetDeviceRegistryProperty(dis, ref dd, property, out propertyType, propBuffer, propBuffer.Length, out requiredSize))
             {
                 throw new Win32Exception();
             }
         }
         if (requiredSize < propBuffer.Length)
         {
             Array.Resize(ref propBuffer, requiredSize);
         }
         return(propBuffer);
     }
 }
예제 #4
0
        public static string GetInstanceIDByKeyName(string driverKeyName)
        {
            var result = string.Empty;

            var h = SetupApi.SetupDiGetClassDevs(default(int), UsbConstants.REGSTR_KEY_USB, IntPtr.Zero, UsbConstants.DIGCF_PRESENT | UsbConstants.DIGCF_ALLCLASSES);

            if (h.ToInt32() != UsbConstants.INVALID_HANDLE_VALUE)
            {
                var ptrBuf  = Marshal.AllocHGlobal(UsbConstants.BUFFER_SIZE);
                var keyName = string.Empty;

                var i       = default(int);
                var success = default(bool);
                do
                {
                    var da = new SpDevinfoData();
                    da.cbSize = Marshal.SizeOf(da);

                    success = SetupApi.SetupDiEnumDeviceInfo(h, i, ref da);
                    if (success)
                    {
                        var regType      = UsbConstants.REG_SZ;
                        var requiredSize = default(int);

                        keyName = string.Empty;
                        if (SetupApi.SetupDiGetDeviceRegistryProperty(h, ref da, UsbConstants.SPDRP_DRIVER, ref regType, ptrBuf, UsbConstants.BUFFER_SIZE, ref requiredSize))
                        {
                            keyName = Marshal.PtrToStringAuto(ptrBuf);
                        }

                        if (keyName == driverKeyName)
                        {
                            var nBytes = UsbConstants.BUFFER_SIZE;
                            var sb     = new StringBuilder(nBytes);
                            SetupApi.SetupDiGetDeviceInstanceId(h, ref da, sb, nBytes, out requiredSize);
                            result = sb.ToString();
                            break;
                        }
                    }
                    i++;
                } while (success);

                Marshal.FreeHGlobal(ptrBuf);
                SetupApi.SetupDiDestroyDeviceInfoList(h);
            }

            return(result);
        }
예제 #5
0
        private static void GetRegistryProperties(SerialPortInfo spiq, IntPtr hDeviceInfoSet, SetupApi.SpDevInfoData deviceInfoData)
        {
            var        propertyBuffer  = new StringBuilder(256);
            const uint propRegDataType = 0;
            var        length          = (uint)propertyBuffer.Capacity;
            bool       success         = SetupApi.SetupDiGetDeviceRegistryProperty(hDeviceInfoSet, deviceInfoData, (int)SetupApi.SPDRP.SPDRP_DEVICEDESC,
                                                                                   propRegDataType, propertyBuffer, length, out length);

            //if (!success) throw new Exception("Can not read registry for device " + deviceInfoData.ClassGuid);
            if (success)
            {
                spiq.Description = propertyBuffer.ToString();
            }

            propertyBuffer = new StringBuilder(256);
            length         = (uint)propertyBuffer.Capacity;
            success        = SetupApi.SetupDiGetDeviceRegistryProperty(hDeviceInfoSet, deviceInfoData, (int)SetupApi.SPDRP.SPDRP_HARDWAREID,
                                                                       propRegDataType, propertyBuffer, length, out length);
            if (success)
            {
                spiq.HardwareID = propertyBuffer.ToString();
            }
        }
예제 #6
0
        public static int EnumerateDevices(DeviceEnumeratorInfo deviceEnumeratorInfo)
        {
            int devIndex;

            const uint CM_PROB_PHANTOM = (0x0000002D);   // The devinst currently exists only in the registry

            // Initialize the SP_DEVINFO_DATA structure
            SetupApi.SP_DEVINFO_DATA devInfoData = new SetupApi.SP_DEVINFO_DATA();
            devInfoData.cbSize = (uint)Marshal.SizeOf(typeof(SetupApi.SP_DEVINFO_DATA));

            // Used to parse the DeviceID tokens.
            RegHardwareID regHardwareID = RegHardwareID.GlobalInstance;

            // Used as a buffer for:
            // * SetupDiGetDeviceRegistryProperty
            // * CM_Get_Device_ID
            // * SetupDiGetCustomDeviceProperty
            // * SetupDiGetDeviceProperty
            byte[] propBuffer = new byte[1024];

            // List all connected USB devices
            IntPtr pDevInfo = SetupApi.SetupDiGetClassDevs(0, "USB", deviceEnumeratorInfo.Hwnd, deviceEnumeratorInfo.DICFGFlags);

            if (pDevInfo == IntPtr.Zero || pDevInfo == new IntPtr(-1))
            {
                InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Win32Error, "SetupDiGetClassDevs Failed!");
                return(-1);
            }

            for (devIndex = 0;; devIndex++)
            {
                if (!SetupApi.SetupDiEnumDeviceInfo(pDevInfo, devIndex, ref devInfoData))
                {
                    // Reached the end of the eviceInfo list.
                    InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Info, "device enumeration complete.");
                    break;
                }
                DeviceItem deviceItem = new DeviceItem();

                // SPDRP_DRIVER seems to do a better job at detecting driverless devices than
                // SPDRP_INSTALL_STATE
                RegistryValueKind propertyType;
                int requiredSize;
                if (SetupApi.SetupDiGetDeviceRegistryProperty(pDevInfo,
                                                              ref devInfoData,
                                                              SetupApi.SPDRP.DRIVER,
                                                              out propertyType,
                                                              propBuffer,
                                                              propBuffer.Length,
                                                              out requiredSize))
                {
                    deviceItem.mDriverless = false;

                    // Read all string values from the registry driver key
                    IntPtr hKey = SetupApi.SetupDiOpenDevRegKey(pDevInfo,
                                                                ref devInfoData,
                                                                1,
                                                                0,
                                                                DevKeyType.DRV,
                                                                (int)RegistryKeyPermissionCheck.ReadSubTree);
                    if (hKey != IntPtr.Zero && hKey != new IntPtr(-1))
                    {
                        int index      = 0;
                        int nameLength = 255;
                        int dataLength = 1023;

                        deviceItem.mDriverRegistryList = new Dictionary <string, object>();

                        StringBuilder     sbName  = new StringBuilder(nameLength + 1);
                        StringBuilder     sbValue = new StringBuilder(dataLength + 1);
                        RegistryValueKind regValueType;

                        while (SetupApi.RegEnumValue(hKey, index, sbName, ref nameLength, IntPtr.Zero, out regValueType, sbValue, ref dataLength) == 0)
                        {
                            if (regValueType == RegistryValueKind.String)
                            {
                                deviceItem.mDriverRegistryList.Add(sbName.ToString(), sbValue.ToString());
                            }

                            // Get next key/value index
                            index++;

                            // Reset max lengths
                            nameLength = 255;
                            dataLength = 1023;
                        }
                        SetupApi.RegCloseKey(hKey);
                    }
                }
                else
                {
                    deviceItem.mDriverless = true;
                }

                // [trobinson] patch
                uint status;
                uint pbmNumber;
                deviceItem.mIsConnected = (SetupApi.CM_Get_DevNode_Status(out status, out pbmNumber, devInfoData.DevInst, 0) != SetupApi.CR.NO_SUCH_DEVNODE);
                if (deviceItem.mIsConnected)
                {
                    deviceItem.mIsConnected = ((pbmNumber & CM_PROB_PHANTOM) != CM_PROB_PHANTOM);
                }

                //if (deviceItem.mDriverless && !deviceItem.mIsConnected)
                //    deviceItem.mDriverless = false;

                // Find only the ones that are driverless
                if (deviceEnumeratorInfo.DriverlessOnly && !deviceItem.mDriverless)
                {
                    InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Info, "skipping non driverless device.");
                    continue;
                }

                // Driverless devices will return an error
                InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Info, "driverless device found.");


                // Eliminate USB hubs by checking the driver string
                if (!SetupApi.SetupDiGetDeviceRegistryProperty(pDevInfo,
                                                               ref devInfoData,
                                                               SetupApi.SPDRP.SERVICE,
                                                               out propertyType,
                                                               propBuffer,
                                                               propBuffer.Length,
                                                               out requiredSize))
                {
                    InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Warning, "failed getting SPDRP.SERVICE");
                    deviceItem.mServiceName = String.Empty;
                }
                else
                {
                    deviceItem.mServiceName = GetAsAutoString(propBuffer);
                }

                bool bContinue = true;
                foreach (string skipServiceName in mSkipServiceNames)
                {
                    if (deviceItem.mServiceName.Trim().ToLower() == skipServiceName)
                    {
                        bContinue = false;
                        break;
                    }
                }
                if (!bContinue && deviceEnumeratorInfo.SkipWindowsServices)
                {
                    continue;
                }
                //if (!bContinue)
                //    continue;

                deviceItem.mIsSkipServiceName = !bContinue;

                string[] saHardwareIDs;

                // Retrieve the hardware ID
                if (!SetupApi.SetupDiGetDeviceRegistryProperty(out saHardwareIDs,
                                                               pDevInfo,
                                                               ref devInfoData,
                                                               SetupApi.SPDRP.HARDWAREID))
                {
                    InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Win32Error, "failed getting SPDRP.HARDWAREID");
                    continue;
                }

                if (saHardwareIDs.Length == 0)
                {
                    InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Error, "device does not have any hardware ids");
                    continue;
                }

                for (int hwid = 0; hwid < saHardwareIDs.Length; hwid++)
                {
                    InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Info, "found hardware ID ({0}/{1}): {2}", hwid + 1, saHardwareIDs.Length, saHardwareIDs[hwid]);
                }

                // Get Device ID
                SetupApi.CR r = SetupApi.CM_Get_Device_ID(devInfoData.DevInst, propBuffer, propBuffer.Length, 0);
                if (r != SetupApi.CR.SUCCESS)
                {
                    InfWizardStatus.Log(CategoryType.EnumerateDevices,
                                        StatusType.Error,
                                        "CM_Get_Device_ID:Failed retrieving simple path for device index: {0} HWID:{1} CR error {2}",
                                        devIndex,
                                        saHardwareIDs[0],
                                        r);
                    continue;
                }
                deviceItem.mDeviceId = GetAsAutoString(propBuffer);

                InfWizardStatus.Log(CategoryType.EnumerateDevices,
                                    StatusType.Info,
                                    "{0} USB device {1}: {2}",
                                    deviceItem.mDriverless ? "Driverless" : deviceItem.mServiceName,
                                    devIndex,
                                    deviceItem.mDeviceId);


                string sDeviceDescription;
                if (SetupApi.WindowsVersion < WindowsVersionType.WINDOWS_7)
                {
                    // On Vista and earlier, we can use SPDRP_DEVICEDESC
                    bContinue = SetupApi.SetupDiGetDeviceRegistryProperty(out sDeviceDescription,
                                                                          pDevInfo,
                                                                          ref devInfoData,
                                                                          SetupApi.SPDRP.DEVICEDESC);

                    if (!bContinue)
                    {
                        sDeviceDescription = string.Empty;
                    }
                }
                else
                {
                    // On Windows 7, the information we want ("Bus reported device description") is
                    // accessed through DEVPKEY_Device_BusReportedDeviceDesc
                    try
                    {
                        bContinue = SetupApi.SetupDiGetDeviceProperty(pDevInfo,
                                                                      ref devInfoData,
                                                                      SetupApi.DEVPKEY_Device_BusReportedDeviceDesc,
                                                                      out propertyType,
                                                                      propBuffer,
                                                                      propBuffer.Length,
                                                                      out requiredSize,
                                                                      0);
                    }
                    catch (DllNotFoundException)
                    {
                        //if (SetupDiGetDeviceProperty == NULL)
                        InfWizardStatus.Log(CategoryType.EnumerateDevices,
                                            StatusType.Warning,
                                            "Failed to locate SetupDiGetDeviceProperty() is Setupapi.dll");
                        bContinue = false;
                    }
                    if (bContinue)
                    {
                        sDeviceDescription = GetAsAutoString(propBuffer);
                    }
                    else
                    {
                        // fallback to SPDRP_DEVICEDESC (USB husb still use it)
                        bContinue = SetupApi.SetupDiGetDeviceRegistryProperty(out sDeviceDescription,
                                                                              pDevInfo,
                                                                              ref devInfoData,
                                                                              SetupApi.SPDRP.DEVICEDESC);
                        if (!bContinue)
                        {
                            sDeviceDescription = string.Empty;
                        }
                    }
                }
                if (!bContinue)
                {
                    InfWizardStatus.Log(CategoryType.EnumerateDevices,
                                        StatusType.Warning | StatusType.Win32Error,
                                        "Failed reading read device description for {0}: {1}",
                                        devIndex,
                                        deviceItem.mDeviceId);
                }

                deviceItem.DeviceDescription = sDeviceDescription;
                deviceItem.BaseFilename      = sDeviceDescription;
                MatchCollection matches = regHardwareID.Matches(saHardwareIDs[0]);
                foreach (Match match in matches)
                {
                    foreach (NamedGroup namedGroup in RegHardwareID.NAMED_GROUPS)
                    {
                        RegHardwareID.ENamedGroups groupEnum = (RegHardwareID.ENamedGroups)namedGroup.GroupNumber;
                        Group group = match.Groups[(int)groupEnum];
                        if (!group.Success)
                        {
                            continue;
                        }

                        switch (groupEnum)
                        {
                        case RegHardwareID.ENamedGroups.Vid:
                            deviceItem.VendorID = group.Value;
                            break;

                        case RegHardwareID.ENamedGroups.Pid:
                            deviceItem.ProductID = group.Value;
                            break;

                        case RegHardwareID.ENamedGroups.Rev:
                            //deviceItem.Rev = group.Value;
                            break;

                        case RegHardwareID.ENamedGroups.MI:
                            deviceItem.MI = group.Value;
                            if (deviceItem.MI != string.Empty)
                            {
                                deviceItem.DeviceDescription += String.Format(" (Interface #{0})", deviceItem.mMI);
                            }
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                }
                if (deviceItem.mVid == 0 && deviceItem.mPid == 0)
                {
                    continue;
                }

                string sManufacturer;
                if (!SetupApi.SetupDiGetDeviceRegistryProperty(out sManufacturer,
                                                               pDevInfo,
                                                               ref devInfoData,
                                                               SetupApi.SPDRP.MFG))
                {
                    sManufacturer = string.Empty;
                }
                deviceItem.Manufacturer = sManufacturer;

                string[] deviceInterfaceGuids = new string[0];
                if (SetupApi.SetupDiGetCustomDeviceProperty(pDevInfo,
                                                            ref devInfoData,
                                                            "DeviceInterfaceGUIDs",
                                                            SetupApi.DICUSTOMDEVPROP.NONE,
                                                            out propertyType,
                                                            propBuffer,
                                                            propBuffer.Length,
                                                            out requiredSize))
                {
                    deviceInterfaceGuids = GetAsAutoStringArray(propBuffer, requiredSize);
                }

                if (deviceInterfaceGuids.Length > 0)
                {
                    deviceItem.DeviceInterfaceGuid = deviceInterfaceGuids[0];
                }

                if (!deviceEnumeratorInfo.DeviceFound(deviceItem, pDevInfo, ref devInfoData))
                {
                    break;
                }

                InfWizardStatus.Log(CategoryType.EnumerateDevices, StatusType.Info, "device description: {0}", deviceItem.DeviceDescription);
            }

            SetupApi.SetupDiDestroyDeviceInfoList(pDevInfo);
            return(devIndex);
        }
예제 #7
0
        private string FindDevicePath()
        {
            var hidGuid        = HidGuid;
            var deviceInfoList = SetupApi.SetupDiGetClassDevs(ref hidGuid, null, IntPtr.Zero, DIGCF.DeviceInterface | DIGCF.Present);

            if (IntPtr.Zero == deviceInfoList)
            {
                return(null);
            }

            try {
                for (uint i = 0; ; i++)
                {
                    var deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
                    deviceInterfaceData.cbSize = (uint)Marshal.SizeOf(deviceInterfaceData);
                    if (!SetupApi.SetupDiEnumDeviceInterfaces(deviceInfoList, IntPtr.Zero, ref hidGuid, i, ref deviceInterfaceData))
                    {
                        break;                         // end of the list
                    }
                    var deviceInfoData = new SP_DEVINFO_DATA();
                    deviceInfoData.cbSize = (uint)Marshal.SizeOf(deviceInfoData);
                    if (!SetupApi.SetupDiEnumDeviceInfo(deviceInfoList, i, ref deviceInfoData))
                    {
                        continue;
                    }

                    const uint bufferSize     = 1048;
                    var        propertyBuffer = Marshal.AllocHGlobal((int)bufferSize);
                    try {
                        uint requiredSize;
                        uint propRegDataType;
                        if (!SetupApi.SetupDiGetDeviceRegistryProperty(
                                deviceInfoList, ref deviceInfoData, SPDRP.HardwareId, out propRegDataType,
                                propertyBuffer, bufferSize, out requiredSize)
                            )
                        {
                            continue;
                        }

                        var deviceId = Marshal.PtrToStringAuto(propertyBuffer, (int)requiredSize);
                        if (String.IsNullOrEmpty(deviceId) ||
                            !deviceId.ToUpperInvariant().Contains(_deviceIdUpper)
                            )
                        {
                            continue;
                        }

                        var deviceInterfaceDetailData = new SP_DEVICE_INTERFACE_DETAIL_DATA {
                            cbSize = IntPtr.Size == 8 ? 8 : (uint)(4 + Marshal.SystemDefaultCharSize)
                        };
                        var interfaceDetailOk = SetupApi.SetupDiGetDeviceInterfaceDetail(
                            deviceInfoList, ref deviceInterfaceData, ref deviceInterfaceDetailData,
                            SP_DEVICE_INTERFACE_DETAIL_DATA.BUFFER_SIZE, out requiredSize, ref deviceInfoData);

                        if (interfaceDetailOk)
                        {
                            return(deviceInterfaceDetailData.devicePath);
                        }
                    }
                    finally {
                        Marshal.FreeHGlobal(propertyBuffer);
                    }
                }
            }
            finally {
                SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoList);
            }
            return(null);
        }
예제 #8
0
        /// <summary>
        /// Force re-enumeration of a device (force installation)
        /// TODO: allow root re-enum
        /// </summary>
        public static int UpdateDriver(string deviceHardwareID)
        {
            int  devIndex;
            int  refreshed = 0;
            bool bSuccess;

            // Initialize the SP_DEVINFO_DATA structure
            SetupApi.SP_DEVINFO_DATA devInfoData = new SetupApi.SP_DEVINFO_DATA();

            // List all connected USB devices
            IntPtr pDevInfo = SetupApi.SetupDiGetClassDevs(0, "USB", IntPtr.Zero, SetupApi.DICFG.ALLCLASSES);

            if (pDevInfo == IntPtr.Zero || pDevInfo == new IntPtr(-1))
            {
                return(refreshed);
            }
            for (devIndex = 0;; devIndex++)
            {
                devInfoData.cbSize = (uint)Marshal.SizeOf(typeof(SetupApi.SP_DEVINFO_DATA));
                bSuccess           = SetupApi.SetupDiEnumDeviceInfo(pDevInfo, devIndex, ref devInfoData);

                // Reached the end of the deviceInfo list.
                if (!bSuccess)
                {
                    break;
                }

                // Find the hardware ID
                string[] saHardwareIDs;
                bSuccess = SetupApi.SetupDiGetDeviceRegistryProperty(out saHardwareIDs,
                                                                     pDevInfo,
                                                                     ref devInfoData,
                                                                     SetupApi.SPDRP.HARDWAREID);

                // Failed getting hardware id
                if (!bSuccess)
                {
                    break;
                }

                // Failed getting hardware id
                if (saHardwareIDs.Length == 0)
                {
                    continue;
                }

                // Check all hardwareids for a match
                bool bFound = false;
                foreach (string s in saHardwareIDs)
                {
                    if (s.Trim().ToLower() == deviceHardwareID.Trim().ToLower())
                    {
                        bFound = true;
                        break;
                    }
                }

                // Hardware did not match; goto next device
                if (!bFound)
                {
                    continue;
                }

                // Re-enumerate the device node
                SetupApi.CR status = SetupApi.CM_Reenumerate_DevNode((int)devInfoData.DevInst,
                                                                     SetupApi.CM.REENUMERATE_RETRY_INSTALLATION);
                if (status == SetupApi.CR.SUCCESS)
                {
                    InfWizardStatus.Log(CategoryType.RefreshDriver, StatusType.Success, "re-enumeration of {0} succeeded...", deviceHardwareID);
                }
                else if (status == SetupApi.CR.INVALID_DEVNODE)
                {
                    continue;
                }
                else
                {
                    InfWizardStatus.Log(CategoryType.RefreshDriver, StatusType.Warning, "failed to re-enumerate device node: CR code {0}", status);
                    continue;
                }



                refreshed++;
            }
            // return the number of devices that were re-enumerated.
            return(refreshed);
        }
예제 #9
0
        /// <summary>
        /// Flag phantom/removed devices for reinstallation.
        /// See: http://msdn.microsoft.com/en-us/library/aa906206.aspx
        /// </summary>
        public static int CheckRemoved(string deviceHardwareID)
        {
            int  devIndex;
            int  removed = 0;
            bool bSuccess;

            // Initialize the SP_DEVINFO_DATA structure
            SetupApi.SP_DEVINFO_DATA devInfoData = new SetupApi.SP_DEVINFO_DATA();
            devInfoData.cbSize = (uint)Marshal.SizeOf(typeof(SetupApi.SP_DEVINFO_DATA));

            // List all connected USB devices
            IntPtr pDevInfo = SetupApi.SetupDiGetClassDevs(0, "USB", IntPtr.Zero, SetupApi.DICFG.ALLCLASSES);

            if (pDevInfo == IntPtr.Zero || pDevInfo == new IntPtr(-1))
            {
                return(removed);
            }
            for (devIndex = 0;; devIndex++)
            {
                bSuccess = SetupApi.SetupDiEnumDeviceInfo(pDevInfo, devIndex, ref devInfoData);

                // Reached the end of the deviceInfo list.
                if (!bSuccess)
                {
                    break;
                }

                // Find the hardware ID
                string[] saHardwareIDs;
                bSuccess = SetupApi.SetupDiGetDeviceRegistryProperty(out saHardwareIDs,
                                                                     pDevInfo,
                                                                     ref devInfoData,
                                                                     SetupApi.SPDRP.HARDWAREID);

                // Failed getting hardware id
                if (!bSuccess)
                {
                    break;
                }

                // Failed getting hardware id
                if (saHardwareIDs.Length == 0)
                {
                    continue;
                }

                // Check all hardwareids for a match
                bool bFound = false;
                foreach (string s in saHardwareIDs)
                {
                    if (s.Trim().ToLower() == deviceHardwareID.Trim().ToLower())
                    {
                        bFound = true;
                        break;
                    }
                }

                // Hardware did not match; goto next device
                if (!bFound)
                {
                    continue;
                }

                uint status;
                uint pbmNumber;

                // If not Unplugged.
                bSuccess = (SetupApi.CM_Get_DevNode_Status(out status, out pbmNumber, devInfoData.DevInst, 0) == SetupApi.CR.NO_SUCH_DEVNODE);
                if (!bSuccess)
                {
                    continue;
                }

                // Flag for reinstall on next plugin
                uint configFlags;
                bSuccess = SetupApi.SetupDiGetDeviceRegistryProperty(out configFlags, pDevInfo, ref devInfoData, SetupApi.SPDRP.CONFIGFLAGS);
                if (!bSuccess)
                {
                    InfWizardStatus.Log(CategoryType.CheckRemoved,
                                        StatusType.Warning,
                                        "could not read SPDRP_CONFIGFLAGS for phantom device {0}",
                                        deviceHardwareID);
                    continue;
                }

                // Mark for re-installation
                configFlags |= (uint)SetupApi.CONFIGFLAG.REINSTALL;
                uint[] flags = new uint[] { configFlags };
                bSuccess = SetupApi.SetupDiSetDeviceRegistryProperty(pDevInfo,
                                                                     ref devInfoData,
                                                                     SetupApi.SPDRP.CONFIGFLAGS,
                                                                     flags,
                                                                     Marshal.SizeOf(typeof(uint)));
                if (!bSuccess)
                {
                    InfWizardStatus.Log(CategoryType.CheckRemoved,
                                        StatusType.Warning,
                                        "could not write SPDRP_CONFIGFLAGS for phantom device {0}",
                                        deviceHardwareID);
                    continue;
                }
                removed++;
            }

            if (removed > 0)
            {
                InfWizardStatus.Log(CategoryType.CheckRemoved, StatusType.Info, "flagged {0} removed devices for reinstallation", removed);
            }

            SetupApi.SetupDiDestroyDeviceInfoList(pDevInfo);

            return(removed);
        }
예제 #10
0
        public static IEnumerable <UsbController> GetControllers()
        {
            var hostGUID = new Guid(UsbConstants.GUID_DEVINTERFACE_HUBCONTROLLER);

            var h = SetupApi.SetupDiGetClassDevs(ref hostGUID, default(int), IntPtr.Zero, UsbConstants.DIGCF_PRESENT | UsbConstants.DIGCF_DEVICEINTERFACE);

            if (h.ToInt32() != UsbConstants.INVALID_HANDLE_VALUE)
            {
                var ptrBuf = Marshal.AllocHGlobal(UsbConstants.BUFFER_SIZE);

                var i       = default(int);
                var success = default(bool);
                do
                {
                    var host = new UsbController(null)
                    {
                        ControllerIndex = i,
                    };

                    var dia = new SpDeviceInterfaceData();
                    dia.cbSize = Marshal.SizeOf(dia);

                    success = SetupApi.SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref hostGUID, i, ref dia);
                    if (success)
                    {
                        var da = new SpDevinfoData();
                        da.cbSize = Marshal.SizeOf(da);

                        var didd = new SpDeviceInterfaceDetailData
                        {
                            cbSize = 4 + Marshal.SystemDefaultCharSize,
                        };

                        var nRequiredSize = default(int);
                        var nBytes        = UsbConstants.BUFFER_SIZE;

                        if (SetupApi.SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da))
                        {
                            host.ControllerDevicePath = didd.DevicePath;

                            var requiredSize = default(int);
                            var regType      = UsbConstants.REG_SZ;

                            if (SetupApi.SetupDiGetDeviceRegistryProperty(h, ref da, UsbConstants.SPDRP_DEVICEDESC, ref regType, ptrBuf, UsbConstants.BUFFER_SIZE, ref requiredSize))
                            {
                                host.ControllerDeviceDesc = Marshal.PtrToStringAuto(ptrBuf);
                            }
                            if (SetupApi.SetupDiGetDeviceRegistryProperty(h, ref da, UsbConstants.SPDRP_DRIVER, ref regType, ptrBuf, UsbConstants.BUFFER_SIZE, ref requiredSize))
                            {
                                host.ControllerDriverKeyName = Marshal.PtrToStringAuto(ptrBuf);
                            }
                        }

                        yield return(host);
                    }
                    i++;
                }while (success);

                Marshal.FreeHGlobal(ptrBuf);
                SetupApi.SetupDiDestroyDeviceInfoList(h);
            }
        }
예제 #11
0
        public static IEnumerable <string> GetPresentedUsbHardwareIds()
        {
            logger.Verb("GetPresentedUsbHardwareIds()");

            List <string> hardwareIds = new List <string>();

            IntPtr    deviceInfoSet        = IntPtr.Zero;
            long      lastError            = 0;
            const int INVALID_HANDLE_VALUE = -1;
            string    devEnum = "USB";

            try
            {
                deviceInfoSet = SetupApi.SetupDiGetClassDevs(IntPtr.Zero, devEnum, IntPtr.Zero, (int)(DIGCF.DIGCF_PRESENT | DIGCF.DIGCF_ALLCLASSES));
                if ((deviceInfoSet != (IntPtr)INVALID_HANDLE_VALUE))
                {
                    bool res         = false;
                    uint deviceIndex = 0;
                    do
                    {
                        SP_DEVINFO_DATA devInfoData = new SP_DEVINFO_DATA();
                        devInfoData.cbSize = (uint)Marshal.SizeOf(devInfoData);
                        res = SetupApi.SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, ref devInfoData);
                        if (!res)
                        {
                            lastError = Marshal.GetLastWin32Error();

                            if (lastError == (long)HResult.WIN32_ERROR_NO_MORE_ITEMS)
                            {
                                break;
                            }

                            logger.Error("SetupDiEnumDeviceInfo() " + lastError);
                            break;
                        }


                        uint   regType      = 0;
                        IntPtr propBuffer   = IntPtr.Zero;
                        uint   bufSize      = 1024;
                        uint   requiredSize = 0;

                        try
                        {
                            propBuffer = Marshal.AllocHGlobal((int)bufSize);

                            do
                            {
                                res = SetupApi.SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref devInfoData, (UInt32)SPDRP.SPDRP_HARDWAREID,
                                                                                ref regType, propBuffer, (uint)bufSize, ref requiredSize);

                                if (!res)
                                {
                                    lastError = Marshal.GetLastWin32Error();

                                    if (lastError == (long)HResult.WIN32_ERROR_INSUFFICIENT_BUFFER)
                                    {
                                        bufSize = requiredSize;

                                        if (propBuffer != IntPtr.Zero)
                                        {
                                            Marshal.FreeHGlobal(propBuffer);
                                        }

                                        propBuffer = Marshal.AllocHGlobal((int)bufSize);
                                        continue;
                                    }
                                    else
                                    {
                                        logger.Error("SetupDiGetDeviceRegistryProperty() " + lastError);
                                        break;
                                    }
                                }

                                string hardwareId = Marshal.PtrToStringAuto(propBuffer);
                                logger.Debug(hardwareId);

                                hardwareIds.Add(hardwareId);
                            }while (false);
                        }
                        finally
                        {
                            if (propBuffer != IntPtr.Zero)
                            {
                                Marshal.FreeHGlobal(propBuffer);
                            }
                        }

                        deviceIndex++;
                    }while (true);
                }
                else
                {
                    lastError = Marshal.GetLastWin32Error();
                    logger.Error("SetupDiGetClassDevs() " + lastError);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                if (deviceInfoSet != IntPtr.Zero)
                {
                    SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoSet);
                }
            }
            return(hardwareIds);
        }