USB Power Management query

Windows specific forum
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

USB Power Management query

Post by ozzie »

When viewing the properties of USB Hubs in Windows Device Manager, under Power Management the checkbox 'allow the computer to turn off this device to save power' is set by default. This sometimes causes a problem when an audio interface device is connected to that USB hub, especially if the computer is left idle for a long time but with the audio playback program loaded and ready to go.

Is there some Windows API I can call from PureBasic to at least check the state of this property in all USB hubs? I could then warn the user if the property is set.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: USB Power Management query

Post by RASHAD »

Hi
Run as Admin

Code: Select all

Procedure USB_CB(hwnd, uMsg, wParam, lParam)
 result = #PB_ProcessPureBasicEvents
    Select uMsg
      Case #WM_DEVICECHANGE
        Select wParam
          Case #DBT_DEVICEARRIVAL
              MessageRequester("USB Status :","USB Device Inserted",#PB_MessageRequester_Ok)
                
          Case #DBT_DEVICEREMOVECOMPLETE
              MessageRequester("USB Status :","USB Device Removed",#PB_MessageRequester_Ok)
                
          Case #DBT_CONFIGCHANGED
              MessageRequester("USB Status :","USB Device Configuration Changed",#PB_MessageRequester_Ok)
              
          Case #DBT_DEVICETYPESPECIFIC
          
          Case #DBT_QUERYCHANGECONFIG            
                
          EndSelect
   EndSelect
ProcedureReturn result 
EndProcedure

OpenWindow(0,0,0,300,300,"Test",#PB_Window_SystemMenu| #PB_Window_Minimize)

SetWindowCallback(@USB_CB())

Repeat
  Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
   EndSelect
Until Quit = 1
Egypt my love
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: USB Power Management query

Post by ozzie »

Thanks, RASHAD. That code detects when a USB device is connected or disconnected, but what I'm looking for is to know whether or not the Power Management is set to turn off power to the hub (for a device that's already connected). On further investigation I've found there's a Power Plan setting for 'Selective Suspend'. But I can't find any reference to a Windows API that will return the current setting of that either.
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: USB Power Management query

Post by breeze4me »

try this.

Code: Select all

;Getting current USB power state
;https://stackoverflow.com/questions/51725639/getting-current-usb-power-state

#DIGCF_PRESENT = $00000002
#DIGCF_ALLCLASSES = $00000004
#DIGCF_PROFILE = $00000008
#DIGCF_DEVICEINTERFACE = $00000010

#SPDRP_DEVICE_POWER_DATA = $0000001E
#SPDRP_FRIENDLYNAME = $0000000C
#SPDRP_DEVICEDESC = 0
;#SPDRP_DRIVER = $00000009

#POWER_SYSTEM_MAXIMUM = 7

Enumeration
  #PowerDeviceUnspecified
  #PowerDeviceD0
  #PowerDeviceD1
  #PowerDeviceD2
  #PowerDeviceD3
EndEnumeration




Structure SP_DEVINFO_DATA Align #PB_Structure_AlignC
  cbSize.l
  ClassGuid.GUID
  DevInst.l
  Reserved.i
EndStructure


Structure CM_POWER_DATA
  PD_Size.l
  PD_MostRecentPowerState.l                     ;DEVICE_POWER_STATE
  PD_Capabilities.l
  PD_D1Latency.l
  PD_D2Latency.l
  PD_D3Latency.l
  PD_PowerStateMapping.l[#POWER_SYSTEM_MAXIMUM] ;DEVICE_POWER_STATE
  PD_DeepestSystemWake.l                        ;SYSTEM_POWER_STATE
EndStructure

Procedure.s GUIDtoString(*guid)
  Protected res.s{48}
  
  If StringFromGUID2_(*guid, @res, 40)
    ProcedureReturn res
  EndIf
  
EndProcedure


Define Text.s{1024}

Define PowerData.CM_POWER_DATA\PD_Size = SizeOf(CM_POWER_DATA)

;hDevinfo = SetupDiGetClassDevs_(?GUID_DEVINTERFACE_USB_DEVICE, 0, 0, #DIGCF_PRESENT | #DIGCF_DEVICEINTERFACE)
hDevinfo = SetupDiGetClassDevs_(?GUID_DEVINTERFACE_USB_HUB, 0, 0, #DIGCF_PRESENT | #DIGCF_DEVICEINTERFACE)

If hDevinfo <> #INVALID_HANDLE_VALUE
  
  Define di.SP_DEVINFO_DATA\cbSize = SizeOf(SP_DEVINFO_DATA)
  
  Repeat
    
    If SetupDiEnumDeviceInfo_(hDevinfo, idx, di) = 0 And GetLastError_() = #ERROR_NO_MORE_ITEMS
      Break
    Else
      
      ;If SetupDiGetDeviceRegistryProperty_(hDevinfo, di, #SPDRP_FRIENDLYNAME, @PropertyRegDataType, @Text, 1020, 0)
      If SetupDiGetDeviceRegistryProperty_(hDevinfo, di, #SPDRP_DEVICEDESC, @PropertyRegDataType, @Text, 1020, 0)
        Debug Text
      EndIf
      
      If SetupDiGetDeviceRegistryProperty_(hDevinfo, di, #SPDRP_DEVICE_POWER_DATA, @PropertyRegDataType, @PowerData, SizeOf(CM_POWER_DATA), 0)
        Debug GUIDtoString(di\ClassGuid)
        
        ;USB Device Power States
        ;https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/comparing-usb-device-states-to-wdm-device-states
        ;https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/device-power-states
        
        Select PowerData\PD_MostRecentPowerState
          Case #PowerDeviceD0
            Debug "D0 - The working state. The device is fully powered."
            
          Case #PowerDeviceD1, #PowerDeviceD2
            Debug "D1/D2 - The intermediate sleep states. These states allow the device to be armed for remote wakeup."
            
          Case #PowerDeviceD3
            Debug "D3 - The deepest sleep state. Devices in state D3 cannot be armed for remote wakeup."
            
          Default
            Debug "#PowerDeviceUnspecified"
            
        EndSelect
        
        Debug "-------------------------------------"
        
      EndIf
      
    EndIf
    
    idx + 1
    
  ForEver
  
  SetupDiDestroyDeviceInfoList_(hDevinfo)
EndIf



DataSection
  
  GUID_DEVINTERFACE_USB_DEVICE: ; {A5DCBF10-6530-11D2-901F-00C04FB951ED}
  Data.l $A5DCBF10
  Data.w $6530, $11D2
  Data.b $90, $1F, $00, $C0, $4F, $B9, $51, $ED
  
  
  GUID_DEVINTERFACE_USB_HUB: ; {F18A0E88-C30C-11D0-8815-00A0C906BED8}
  Data.l $F18A0E88
  Data.w $C30C, $11D0
  Data.b $88, $15, $00, $A0, $C9, $06, $BE, $D8
  
EndDataSection
Last edited by breeze4me on Tue Nov 20, 2018 12:00 pm, edited 1 time in total.
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: USB Power Management query

Post by ozzie »

Thanks - that's just what I need! The links are also helpful.
Post Reply