/// <summary>
 /// Attempts to enable or disable a device driver.
 /// </summary>
 /// <param name="deviceInfoSet">Pointer to device.</param>
 /// <param name="deviceInfoData"></param>
 /// <param name="bEnable"></param>
 /// <returns>State of success.</returns>
 /// <remarks>
 /// IMPORTANT NOTE!!!
 /// This code currently does not check the reboot flag.
 /// Some devices require you reboot the OS for the change
 /// to take affect.  If this describes your device, you 
 /// will need to look at the SDK call:
 /// SetupDiGetDeviceInstallParams.  You can call it 
 /// directly after ChangeIt to see whether or not you need 
 /// to reboot the OS for you change to go into effect.
 /// Errors:   This method may throw the following exceptions.
 ///           Unable to change device state!
 /// </remarks>
 private static bool SetDeviceState(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, bool bEnable)
 {
     try
     {
         SP_CLASSINSTALL_HEADER header = new SP_CLASSINSTALL_HEADER();
         header.cbSize = (UInt32)Marshal.SizeOf(header);
         header.InstallFunction = DIF_PROPERTYCHANGE;
         SP_PROPCHANGE_PARAMS classInstallParams = new SP_PROPCHANGE_PARAMS();
         classInstallParams.ClassInstallHeader = header;
         classInstallParams.StateChange = bEnable ? DICS_ENABLE : DICS_DISABLE;
         classInstallParams.Scope = DICS_FLAG_GLOBAL;
         classInstallParams.HwProfile = 0;
         var classInstallParamsSize = (UInt32)Marshal.SizeOf(classInstallParams);
         bool result = SetupDiSetClassInstallParams(deviceInfoSet, ref deviceInfoData, classInstallParams, classInstallParamsSize);
         if (result) result = SetupDiChangeState(deviceInfoSet, ref deviceInfoData);
         if (!result)
         {
             var ex = new Win32Exception();
             SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, deviceInfoSet, ref deviceInfoData);
         }
         return result;
     }
     catch (Exception)
     {
         return false;
     }
 }
 public static Win32Exception RemoveDevice(string deviceId, int method, out bool needReboot)
 {
     Guid classGuid = System.Guid.Empty;
     IntPtr deviceInfoSet = SetupDiGetClassDevs(classGuid, null, IntPtr.Zero, DIGCF.DIGCF_ALLCLASSES);
     Win32Exception ex = null;
     needReboot = false;
     var success = false;
     if (deviceInfoSet.ToInt32() != ERROR_INVALID_HANDLE_VALUE)
     {
         var deviceInfoData = GetDeviceInfo(deviceInfoSet, deviceId);
         if (deviceInfoData.HasValue)
         {
             var di = deviceInfoData.Value;
             switch (method)
             {
                 case 1:
                     SP_CLASSINSTALL_HEADER header = new SP_CLASSINSTALL_HEADER();
                     header.cbSize = (UInt32)Marshal.SizeOf(header);
                     header.InstallFunction = DIF_REMOVE;
                     var classInstallParams = new SP_REMOVEDEVICE_PARAMS();
                     classInstallParams.ClassInstallHeader = header;
                     classInstallParams.Scope = DICS_FLAG_GLOBAL;
                     classInstallParams.HwProfile = 0;
                     var classInstallParamsSize = (UInt32)Marshal.SizeOf(classInstallParams);
                     success = SetupDiSetClassInstallParams(deviceInfoSet, ref di, classInstallParams, classInstallParamsSize);
                     if (success)
                     {
                         success = SetupDiSetSelectedDevice(deviceInfoSet, ref di);
                         if (success)
                         {
                             success = SetupDiCallClassInstaller(DIF_REMOVE, deviceInfoSet, ref di);
                             // ex.ErrorCode = 0xE0000235: SetupDiCallClassInstaller throws ERROR_IN_WOW64 when compiled for 32 bit on a 64 bit machine.
                             if (!success) ex = new Win32Exception();
                         }
                         else ex = new Win32Exception();
                     }
                     else ex = new Win32Exception();
                     break;
                 case 2:
                     success = SetupDiRemoveDevice(deviceInfoSet, ref di);
                     if (!success) ex = new Win32Exception();
                     break;
                 case 3:
                     success = DiUninstallDevice(IntPtr.Zero, deviceInfoSet, ref di, 0, out needReboot);
                     if (!success) ex = new Win32Exception();
                     break;
                 default:
                     break;
             }
         }
         SetupDiDestroyDeviceInfoList(deviceInfoSet);
     }
     else
     {
         ex = new Win32Exception();
     }
     return ex;
 }