Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programatically disable "Enhanced Power Management" for certain USB devices?

I'm working on software that interacts with a custom USB device. The device presents itself as a HID device and the software interacts with it via File I/O.

Due to changes in Windows 8.1 the OS keeps restarting the device and this is causing problems in the software.

According to this Knowledge Base article: http://support.microsoft.com/kb/2900614, Microsoft recommends disabling the Enhanced Power Management feature for a USB device if it is having this problem and after doing so manually the problem does go away.

Now, I'd like to modify the installer of the software to disable this setting for all of our devices, not just for a specific device instance.

Is there a way to accomplish that? Either via a Windows API call, or through a registry setting that would affect all instances of a particular ProductID / VendorID combination?

E.g. I'd like to modify all instances under:

  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_11AE&PID_07CE

Including any future instances that may be connected to the system, after the installer executes.

like image 979
Mike Dinescu Avatar asked Feb 04 '26 02:02

Mike Dinescu


1 Answers

Here is a sample script I wrote to disable power management on all Datalogic-brand USB devices (vendor ID 0x05F9). You can probably just change the "VID_05F9&" in the conditional down in the For Each loop to make it match the keys you need to modify. Note that the necessary UAC elevation is handled as well.

'Filename: USBPMFIX.VBS
'Author:   Matthew Mellon <[email protected]>
'Date:     2014-12-12
'Desc:     Disables enhanced power management on all Datalogic USB devices.
'License:  This source code is released into the public domain.    

'Checks if the script is running elevated (UAC)
function isElevated
  Set shell = CreateObject("WScript.Shell")
  Set whoami = shell.Exec("whoami /groups")
  Set whoamiOutput = whoami.StdOut
  strWhoamiOutput = whoamiOutput.ReadAll

  If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then 
    isElevated = True
  Else
      isElevated = False
  End If
end function

'Re-runs the process prompting for priv elevation on re-run
sub uacPrompt

  'Check if we need to run in C or W script
  interpreter = "wscript.exe"
  If Instr(1, WScript.FullName, "CScript", vbTextCompare) = 0 Then
    interpreter = "wscript.exe"
  else
    interpreter = "cscript.exe"
  end if

  'Start a new instance with an elevation prompt first
  Set shellApp = CreateObject("Shell.Application")
  shellApp.ShellExecute interpreter, Chr(34) & WScript.ScriptFullName & Chr(34) & " uac", "", "runas", 1

  'End the non-elevated instance
  WScript.Quit
end sub

if not isElevated Then uacPrompt

Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."

Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
 strComputer & "\root\default:StdRegProv")

strKeyPath = "SYSTEM\CurrentControlSet\Enum\USB"
objReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys

For Each Subkey in arrSubKeys
  If Left(Subkey,9) = "VID_05F9&" And Left(Right(Subkey,6),5) = "&MI_0" Then
    strKeyPath = "SYSTEM\CurrentControlSet\Enum\USB\"+Subkey
    objReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrInnerSubKeys
    For Each InnerSubkey in arrInnerSubKeys
      strFullKey = "SYSTEM\CurrentControlSet\Enum\USB\"+Subkey+"\"+InnerSubkey+"\Device Parameters"
      objReg.SetDWORDValue HKEY_LOCAL_MACHINE, strFullKey, "EnhancedPowerManagementEnabled", 0
    Next   
  End If
Next
like image 140
Matthew Mellon Avatar answered Feb 05 '26 15:02

Matthew Mellon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!