Jump to content

Drive(s) Power Status


Ascend4nt
 Share

Recommended Posts

For those of us with more than one hard drive, and with power management options enabled for disks, you might find yourself in the same situation as I've been in - asking the question 'Is that drive really powered down?'. I coded up the below example to get that information to you. Note that it reads power states for ALL drives, and the status information for removable & virtual drives will either show up as 'Unknown' or Powered-On.

As a courtesy, please be sure to credit me or keep the UDF header intact if you use the code :unsure:

; ===============================================================================================================================
; <DrivesPowerStatus.au3>
;
; Reports the Power status for all drives.
;
; Functions:
;   _DriveGetPowerState()   ; Returns a boolean indicating drive status (True=active, False=low power or powered-off)
;
; Author: Ascend4nt
; ===============================================================================================================================
#include <Array.au3>
 
Local $aDrives,$aDevInfo
 
$aDrives=DriveGetDrive("ALL")   ; returns array of 'drive:' with lower-case letters
If @error Then Exit
 
; Create 2D array - 2nd column will carry the Power State info, 3rd Drive Type
Dim $aDriveStates[$aDrives[0]+1][3]
 
; Copy over drives and get Power States
For $i=1 To $aDrives[0]
    $aDriveStates[$i][0]=StringUpper($aDrives[$i])
    $aDriveStates[$i][1]=_DriveGetPowerState($aDrives[$i])
    If @error Then $aDriveStates[$i][1]="Unknown"
    $aDriveStates[$i][2]=DriveGetType($aDrives[$i])
Next
$aDriveStates[0][0]="Drive"
$aDriveStates[0][1]="Active Power State?"
$aDriveStates[0][2]="Drive Type"
_ArrayDisplay($aDriveStates,"Drives Power Status")
 
 
; ===================================================================================================================
; Func _DriveGetPowerState($sDrive)
;
; Returns a boolean representing the active power state of the given drive.
;   True = Active (powered on, active), False = Inactive (either powered off, or in a low power state)
;
; $sDrive = Drive letter, or full path (only the Drive letter is extracted from the string)
;
; Returns:
;   Success: True/False
;   Failure: -1, with @error set:
;       @error = 1 = invalid parameter
;       @error = 2 = DLLCall error. @extended contains DLLCall error code (see AutoIt Help)
;       @error = 3 = API call error. Call 'GetLastError' for more info
;
; Author: Ascend4nt
; ===================================================================================================================
 
Func _DriveGetPowerState($sDrive)
    $sDrive=StringLeft($sDrive,1)
    If StringIsAlpha($sDrive)=0 Then Return SetError(1,0,-1)
    ; Device path for logical drives: '\\.\C:'
    Local $iErr,$aRet,$hDisk,$sDevicePath='\\.\'&$sDrive&':'
#cs
    ; API call params: [0 Access (for metadata & device info),3 ShareMode for 'Read'+'Write',
    ;   0 (NULL) SecurityAttribs (i.e. none),3 CreationDisposition for 'OpenExisting',0 Flags,0 (NULL) TemplateFile]
    ; *We could also use _WinAPI_CreateFile($sDevicePath,2,8,6), but there's no guarantee that '8' as the 3rd param
    ;   will continue to work (its currently a sort of 'hack' to work around the limitations of the UDF [to force AccessMode to 0])
#ce
    $aRet=DllCall('kernel32.dll','handle','CreateFileW','wstr',$sDevicePath,'dword',0,'dword',3,'ptr',0,'dword',3,'dword',0,'ptr',0)
    If @error Then Return SetError(2,@error,-1)
    If $aRet[0]=-1 Then Return SetError(3,0,-1)
    $hDisk=$aRet[0]
;~  ConsoleWrite("Handle for Drive '"&$sDrive&":' = "&$hDisk&@CRLF)
    $aRet=DllCall('kernel32.dll','bool','GetDevicePowerState','handle',$hDisk,'bool*',0)
    $iErr=@error
    ; We don't worry about whether this is successful, since there's nothing we can do about it:
    DllCall('kernel32.dll','bool','CloseHandle','handle',$hDisk)
    ; Error with GetDevicePowerState call?
    If $iErr Then Return SetError(2,$iErr,-1)
    If Not $aRet[0] Then Return SetError(3,0,-1)
;~  ConsoleWrite("$aRet[2]="&$aRet[2]&@CRLF)
    Return ($aRet[2]<>0)
EndFunc
Edited by Ascend4nt
Link to comment
Share on other sites

Cool script :unsure:

[0]|Drive|Active Power State?|Drive Type

[1]|A:|True|Removable

[2]|C:|True|Fixed

[3]|D:|True|Fixed

[4]|E:|True|Fixed

[5]|F:|True|Fixed

[6]|G:|True|Fixed

[7]|H:|True|Fixed

[8]|I:|True|CDROM

[9]|J:|True|Removable

[10]|K:|True|Removable

[11]|L:|True|Removable

[12]|M:|True|Removable

[13]|O:|True|CDROM

[14]|Q:|True|CDROM

Also, I'm gonna run out of letters soon :>
Link to comment
Share on other sites

Agreed nice Function.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Thx guys. I noticed an issue with a 4-bay external enclosure where it reports 'False' for active power state, no matter if the drives in the enclosure were powered up or down.. perhaps its just not possible to detect power states in those situations. (I've noticed S.M.A.R.T. info is unavailable through USB also)

Link to comment
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
 Share

×
×
  • Create New...