/// <summary>
 /// Set device state.
 /// </summary>
 /// <param name="match"></param>
 /// <param name="enable"></param>
 /// <returns>Success state.</returns>
 /// <remarks>
 /// This is nearly identical to the method above except it
 /// tries to match the hardware description against the criteria
 /// passed in.  If a match is found, that device will the be
 /// enabled or disabled based on bEnable.
 /// Errors:   This method may throw the following exceptions.
 ///           Failed to enumerate device tree!
 /// </remarks>
 public static bool SetDeviceState(string deviceId, bool enable)
 {
     try
     {
         Guid myGUID = System.Guid.Empty;
         IntPtr deviceInfoSet = SetupDiGetClassDevs(myGUID, null, IntPtr.Zero, DIGCF.DIGCF_ALLCLASSES | DIGCF.DIGCF_PRESENT);
         if (deviceInfoSet.ToInt32() == INVALID_HANDLE_VALUE)
         {
             return false;
         }
         var deviceInfoData = new SP_DEVINFO_DATA();
         deviceInfoData.Initialize();
         deviceInfoData.DevInst = 0;
         deviceInfoData.ClassGuid = System.Guid.Empty;
         deviceInfoData.Reserved = IntPtr.Zero;
         for (var i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++)
         {
             var currentDeviceId = GetDeviceId(deviceInfoData.DevInst);
             if (deviceId == currentDeviceId)
             {
                 SetDeviceState(deviceInfoSet, deviceInfoData, enable);
             }
         }
         SetupDiDestroyDeviceInfoList(deviceInfoSet);
     }
     catch (Exception ex)
     {
         throw new Exception("Failed to enumerate device tree!", ex);
         //return false;
     }
     return true;
 }
 public static DeviceInfo[] GetDevices(Guid classGuid, DIGCF flags, string deviceId, int vid, int pid, int rev)
 {
     lock (GetDevicesLock)
     {
         IntPtr deviceInfoSet = SetupDiGetClassDevs(classGuid, null, IntPtr.Zero, flags); //  | DIGCF.DIGCF_PRESENT
         if (deviceInfoSet.ToInt32() == ERROR_INVALID_HANDLE_VALUE)
         {
             throw new Exception("Invalid Handle");
         }
         var list = new List<DeviceInfo>();
         var deviceInfoData = new SP_DEVINFO_DATA();
         deviceInfoData.Initialize();
         int i;
         for (i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++)
         {
             var currentDeviceId = GetDeviceId(deviceInfoData.DevInst);
             if (!string.IsNullOrEmpty(deviceId) && deviceId != currentDeviceId) continue;
             var device = GetDeviceInfo(deviceInfoSet, deviceInfoData, deviceId);
             if (vid > 0 && device.VendorId != vid) continue;
             if (pid > 0 && device.ProductId != pid) continue;
             if (rev > 0 && device.Revision != rev) continue;
             list.Add(device);
         }
         SetupDiDestroyDeviceInfoList(deviceInfoSet);
         return list.OrderBy(x => x.ClassDescription).ThenBy(x => x.Description).ToArray();
     }
 }
 public static DeviceInfo GetParentDevice(Guid classGuid, DIGCF flags, string deviceId)
 {
     lock (GetDevicesLock)
     {
         IntPtr deviceInfoSet = SetupDiGetClassDevs(classGuid, null, IntPtr.Zero, flags); //  | DIGCF.DIGCF_PRESENT
         if (deviceInfoSet.ToInt32() == ERROR_INVALID_HANDLE_VALUE)
         {
             throw new Exception("Invalid Handle");
         }
         DeviceInfo device = null;
         var deviceInfoData = new SP_DEVINFO_DATA();
         deviceInfoData.Initialize();
         int i;
         for (i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++)
         {
             if (deviceId == GetDeviceId(deviceInfoData.DevInst))
             {
                 uint parentDeviceInstance = 0;
                 var CRResult = CM_Get_Parent(out parentDeviceInstance, deviceInfoData.DevInst, 0);
                 if (CRResult == CR.CR_NO_SUCH_DEVNODE) break;
                 if (CRResult != CR.CR_SUCCESS) break;
                 var parentDeviceId = GetDeviceId(parentDeviceInstance);
                 device = GetDevice(classGuid, flags, parentDeviceId);
                 break;
             }
         }
         SetupDiDestroyDeviceInfoList(deviceInfoSet);
         return device;
     }
 }
 public static SP_DEVINFO_DATA? GetDeviceInfo(IntPtr deviceInfoSet, string deviceInstanceId)
 {
     var da = new SP_DEVINFO_DATA();
     da.Initialize();
     var result = SetupDiOpenDeviceInfo(deviceInfoSet, deviceInstanceId, IntPtr.Zero, 0, ref da);
     if (!result) return null;
     return da;
 }