Jump to content
Sign in to follow this  
jaberwacky

DevicePowerEnumDevices (for want of a better name)

Recommended Posts

jaberwacky

I don't know about you but I hate going through Device Manager and clicking and clicking and clicking just to find out a few things. Now you don't have to click and click anymore. This script allows you to quickly and easily enable or disable your devices to wake your computer from standby in one convenient location. Let's pretend that you own a cat. You put your computer to sleep to go out for a few hours. You come back and your cat has slept on the keyboard. Just disable the keyboard from waking your computer out of sleep with this script. Or just use device manager.

This is my first script that uses DLLCall to call a windows function but here goes.

Anything less than Vista need not apply. Any server less than 2008 keep on truckin'.

I had to go to my motherboard and change two jumpers around before my USB devices would wake my computer from standby!

If anyone has a better name then please post it.

Tested on Windows 7 x64. The code is a mess.

Instructions:

1) Press the button labeled 'List Devices' to display a list of devices that are currently allowed to take the computer out of standby.

2) Highlight the desired device.

3) Click the 'Clear' button to disable that device from waking your computer.

4) Click the 'Set' button to enable that device to wake your computer.

Here's the code:

#RequireAdmin

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Au3Check_Stop_OnWarning=y
#AutoIt3Wrapper_Au3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -d
#AutoIt3Wrapper_Run_Tidy=y
#Tidy_Parameters=/tc 0 /kv 0 /reel
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GUIConstantsEx.au3>
#include <ListboxConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Array.au3>
#include <Memory.au3>
#include <Misc.au3>

_Singleton(@ScriptName)

CheckOsCompat() ; Minimum Supported: Windows Vista

HotKeySet("{ESC}", "term")
OnAutoItExitRegister("_exit")

#Region GUI
Global Const $title = GetUserName()
Global Const $GUI = GUICreate($title, 450, 470)
Global Const $listView = GUICtrlCreateList('', 10, 10, 430, 400, $LBS_SORT, $WS_EX_CLIENTEDGE)
Global Const $btnEnum = GUICtrlCreateButton("List Devices", 170, 415)
Global Const $btnClear = GUICtrlCreateButton("Clear", 260, 415)
Global Const $btnSet = GUICtrlCreateButton("Set", 295, 415)
Global Const $btnExit = GUICtrlCreateButton("Exit", 410, 415)
Global Const $radSet = GUICtrlCreateRadio("Devices that are set to wake.", 10, 405)
Global Const $set = 0x0001
Global Const $radClear = GUICtrlCreateRadio("All present devices.", 10, 425)
Global Const $clear = 0x0002
Global Const $commLabel = GUICtrlCreateLabel("DevicePowerEnumDevices", 10, 450, 430, 25)

GUICtrlSetState($radSet, $GUI_CHECKED)

GUISetState()
#EndRegion GUI

Global $PowrProf = DllOpen("PowrProf.dll")

DllCall($PowrProf, "bool", "DevicePowerOpen", "ulong", 0)

GUICtrlSetData($listView, EnumerateDevices())

Global $wake = $set

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $btnExit
            Exit

        Case $btnEnum
            If GUICtrlRead($radSet) = $GUI_CHECKED Then
                $wake = $set
            ElseIf GUICtrlRead($radClear) = $GUI_CHECKED Then
                $wake = $clear
            EndIf

            GUICtrlSetData($listView, '')
            GUICtrlSetData($listView, EnumerateDevices($wake))

        Case $btnClear
            ClearWakeEnabled()

        Case $btnSet
            SetWakeEnabled()
    EndSwitch
WEnd

; ===================================================================================================

Func CheckOsCompat()
    Switch @OSVersion
        Case Not "WIN_7" Or Not "WIN_VISTA"
            MsgBox(48, "Notice", "Minimum supported OS is 'Windows Vista'.")
            Exit
    EndSwitch
EndFunc   ;==>CheckOsCompat

; ===================================================================================================

Func EnumerateDevices(Const $edwake = $set)
    #Region PowrProf constants
    Local Const $HARDWAREID = 0x80000000
    Local Const $AND_OPERATION = 0x40000000
    Local Const $FILTER_ON_NAME = 0x02000000
    Local Const $FILTER_WAKEENABLED = 0x08000000
    Local Const $FILTER_DEVICES_PRESENT = 0x20000000

    Local Const $D0_SUPPORTED = 0x00000001
    Local Const $D1_SUPPORTED = 0x00000002
    Local Const $D2_SUPPORTED = 0x00000004
    Local Const $D3_SUPPORTED = 0x00000008

    Local Const $S0_SUPPORTED = 0x00010000
    Local Const $S1_SUPPORTED = 0x00020000
    Local Const $S2_SUPPORTED = 0x00040000
    Local Const $S3_SUPPORTED = 0x00080000
    Local Const $S4_SUPPORTED = 0x01000000
    Local Const $S5_SUPPORTED = 0x02000000

    Local Const $WARM_EJECT_SUPPORTED = 0x00000100

    Local Const $WAKE_FROM_D0 = 0x00000010
    Local Const $WAKE_FROM_D1 = 0x00000020
    Local Const $WAKE_FROM_D2 = 0x00000040
    Local Const $WAKE_FROM_D3 = 0x00000080

    Local Const $WAKE_FROM_S0 = 0x00100000
    Local Const $WAKE_FROM_S1 = 0x00200000
    Local Const $WAKE_FROM_S2 = 0x00400000
    Local Const $WAKE_FROM_S3 = 0x00800000
    #EndRegion PowrProf constants

    Local $queryInterpretationFlags

    If $edwake = $set Then
        $queryInterpretationFlags = $FILTER_WAKEENABLED
    Else
        $queryInterpretationFlags = $FILTER_DEVICES_PRESENT
    EndIf

    Local Const $queryFlags = BitOR($WAKE_FROM_S1, $WAKE_FROM_S2)

    Local Const $ReturnBuffer = DllStructCreate("ulong Buffer")
    DllStructSetData($ReturnBuffer, "Buffer", 2048)
    Local Const $pReturnBuffer = DllStructGetPtr($ReturnBuffer)

    Local $string = ''
    Local $queryIndex = 0
    Local $result = 0

    While 1
        $result = DllCall($PowrProf, "bool", "DevicePowerEnumDevices", _
                "uint", $queryIndex, _
                "uint", $queryInterpretationFlags, _
                "uint", $queryFlags, _
                "wstr", 0, _
                "ptr", $pReturnBuffer)

        If $result[0] = True Then
            $string &= $result[4] & '|'
            $queryIndex += 1
        Else
            ExitLoop
        EndIf
    WEnd

    $string = StringTrimRight($string, 1) ; strip off the trailing '|'

    Return $string
EndFunc   ;==>EnumerateDevices

; ===================================================================================================

Func ClearWakeEnabled()
    Local Const $CLEAR_WAKEENABLED = 0x00000002
    Local Const $DeviceDescription = GUICtrlRead($listView)

    Local Const $result = DllCall($PowrProf, "dword", "DevicePowerSetDeviceState", _
            "wstr", $DeviceDescription, _
            "ulong", $CLEAR_WAKEENABLED, _
            "ptr", 0)

    If Not @error Then
        Communicate("Device has been disabled from waking your computer out of sleep.")
    EndIf

    If Not $result[0] Then
        Return SetError(-1, 0, 1)
    EndIf
EndFunc   ;==>ClearWakeEnabled

; ===================================================================================================

Func SetWakeEnabled()
    Local Const $SET_WAKEENABLED = 0x00000001
    Local Const $DeviceDescription = GUICtrlRead($listView)

    Local Const $result = DllCall($PowrProf, "dword", "DevicePowerSetDeviceState", _
            "wstr", $DeviceDescription, _
            "uint", $SET_WAKEENABLED, _
            "ptr", 0)

    If Not @error Then
        Communicate("Device has been enabled to wake your computer out of sleep.")
    EndIf

    If Not $result[0] Then
        Return SetError(-1, 0, 1)
    EndIf
EndFunc   ;==>SetWakeEnabled

; ===================================================================================================

Func GetUserName()
    Local Const $Buffer = DllStructCreate("char lpBuffer[257]")
    DllStructSetData($Buffer, "lpBuffer", 257)
    Local Const $pBuffer = DllStructGetPtr($Buffer)

    Local Const $Size = DllStructCreate("dword lpnSize")
    DllStructSetData($Size, "lpnSize", 32767)
    Local Const $pSize = DllStructGetPtr($Size)

    Local $result = DllCall("Advapi32.dll", "bool", "GetUserNameW", _
            "wstr", $pBuffer, _
            "ptr", $pSize)

    Return $result[1]
EndFunc   ;==>GetUserName

; ===================================================================================================

Func Communicate(Const $Message)
    GUICtrlSetData($commLabel, $Message)
EndFunc   ;==>Communicate

; ===================================================================================================

Func _exit()
    GUIDelete($GUI)
    DllCall($PowrProf, "DevicePowerClose", "bool", "none", 0)
    DllClose($PowrProf)
EndFunc   ;==>_exit

; ===================================================================================================

Func term()
    Exit
EndFunc   ;==>term

[update: January/20/2011] -- Works now.

[Original: August/08/2011]

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites
kingsped

Update: see OP for details.

Nice! One Request: Can you add/modify a list to show only those devices capable of waking the system, even if they're currently set disabled??

Share this post


Link to post
Share on other sites
jaberwacky

Nice! One Request: Can you add/modify a list to show only those devices capable of waking the system, even if they're currently set disabled??

Thanks for the reply. I'll definately look into it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×