#ifndef _POWRPROF_H
#define _POWRPROF_H

/* Power Policy Applicator definitions */

#if __POCC__ >= 500
#pragma once
#endif

#if defined(WIN32_DEFAULT_LIBS)
#pragma comment(lib, "powrprof.lib")
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _GLOBAL_MACHINE_POWER_POLICY {
    ULONG Revision;
    SYSTEM_POWER_STATE LidOpenWakeAc;
    SYSTEM_POWER_STATE LidOpenWakeDc;
    ULONG BroadcastCapacityResolution;
} GLOBAL_MACHINE_POWER_POLICY, *PGLOBAL_MACHINE_POWER_POLICY;

typedef struct _GLOBAL_USER_POWER_POLICY {
    ULONG Revision;
    POWER_ACTION_POLICY PowerButtonAc;
    POWER_ACTION_POLICY PowerButtonDc;
    POWER_ACTION_POLICY SleepButtonAc;
    POWER_ACTION_POLICY SleepButtonDc;
    POWER_ACTION_POLICY LidCloseAc;
    POWER_ACTION_POLICY LidCloseDc;
    SYSTEM_POWER_LEVEL DischargePolicy[NUM_DISCHARGE_POLICIES];
    ULONG GlobalFlags;
} GLOBAL_USER_POWER_POLICY, *PGLOBAL_USER_POWER_POLICY;

typedef struct _GLOBAL_POWER_POLICY {
    GLOBAL_USER_POWER_POLICY user;
    GLOBAL_MACHINE_POWER_POLICY mach;
} GLOBAL_POWER_POLICY, *PGLOBAL_POWER_POLICY;

typedef struct _MACHINE_POWER_POLICY {
    ULONG Revision;
    SYSTEM_POWER_STATE MinSleepAc;
    SYSTEM_POWER_STATE MinSleepDc;
    SYSTEM_POWER_STATE ReducedLatencySleepAc;
    SYSTEM_POWER_STATE ReducedLatencySleepDc;
    ULONG DozeTimeoutAc;
    ULONG DozeTimeoutDc;
    ULONG DozeS4TimeoutAc;
    ULONG DozeS4TimeoutDc;
    UCHAR MinThrottleAc;
    UCHAR MinThrottleDc;
    UCHAR pad1[2];
    POWER_ACTION_POLICY OverThrottledAc;
    POWER_ACTION_POLICY OverThrottledDc;
} MACHINE_POWER_POLICY, *PMACHINE_POWER_POLICY;

#if (NTDDI_VERSION >= NTDDI_WINXP)
typedef struct _MACHINE_PROCESSOR_POWER_POLICY {
    ULONG Revision;
    PROCESSOR_POWER_POLICY ProcessorPolicyAc;
    PROCESSOR_POWER_POLICY ProcessorPolicyDc;
} MACHINE_PROCESSOR_POWER_POLICY, *PMACHINE_PROCESSOR_POWER_POLICY;
#endif /* NTDDI_VERSION >= NTDDI_WINXP */

typedef struct _USER_POWER_POLICY {
    ULONG Revision;
    POWER_ACTION_POLICY IdleAc;
    POWER_ACTION_POLICY IdleDc;
    ULONG IdleTimeoutAc;
    ULONG IdleTimeoutDc;
    UCHAR IdleSensitivityAc;
    UCHAR IdleSensitivityDc;
    UCHAR ThrottlePolicyAc;
    UCHAR ThrottlePolicyDc;
    SYSTEM_POWER_STATE MaxSleepAc;
    SYSTEM_POWER_STATE MaxSleepDc;
    ULONG Reserved[2];
    ULONG VideoTimeoutAc;
    ULONG VideoTimeoutDc;
    ULONG SpindownTimeoutAc;
    ULONG SpindownTimeoutDc;
    BOOLEAN OptimizeForPowerAc;
    BOOLEAN OptimizeForPowerDc;
    UCHAR FanThrottleToleranceAc;
    UCHAR FanThrottleToleranceDc;
    UCHAR ForcedThrottleAc;
    UCHAR ForcedThrottleDc;
} USER_POWER_POLICY, *PUSER_POWER_POLICY;

typedef struct _POWER_POLICY {
    USER_POWER_POLICY user;
    MACHINE_POWER_POLICY mach;
} POWER_POLICY, *PPOWER_POLICY;

#define EnableSysTrayBatteryMeter  0x01
#define EnableMultiBatteryDisplay  0x02
#define EnablePasswordLogon  0x04
#define EnableWakeOnRing  0x08
#define EnableVideoDimDisplay  0x10

#define POWER_ATTRIBUTE_HIDE  0x00000001
#define POWER_ATTRIBUTE_SHOW_AOAC  0x00000002

#define NEWSCHEME  (UINT)-1

typedef BOOLEAN CALLBACK PWRSCHEMESENUMPROC_V1(UINT, DWORD, LPTSTR, DWORD, LPTSTR, PPOWER_POLICY, LPARAM);
typedef BOOLEAN CALLBACK PWRSCHEMESENUMPROC_V2(UINT, DWORD, LPWSTR, DWORD, LPWSTR, PPOWER_POLICY, LPARAM);
#if (NTDDI_VERSION >= NTDDI_VISTA)
typedef PWRSCHEMESENUMPROC_V2 *PWRSCHEMESENUMPROC;
#else /* NTDDI_VERSION < NTDDI_VISTA */
typedef PWRSCHEMESENUMPROC_V1 *PWRSCHEMESENUMPROC;
#endif /* NTDDI_VERSION < NTDDI_VISTA */

typedef BOOLEAN (CALLBACK* PFNNTINITIATEPWRACTION)(POWER_ACTION, SYSTEM_POWER_STATE, ULONG, BOOLEAN);  // ?

BOOLEAN WINAPI GetPwrDiskSpindownRange(PUINT, PUINT);
BOOLEAN WINAPI EnumPwrSchemes(PWRSCHEMESENUMPROC, LPARAM);
BOOLEAN WINAPI ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY);
BOOLEAN WINAPI ReadPwrScheme(UINT, PPOWER_POLICY);
BOOLEAN WINAPI WritePwrScheme(PUINT, LPCWSTR, LPCWSTR, PPOWER_POLICY);
BOOLEAN WINAPI WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY);
BOOLEAN WINAPI DeletePwrScheme(UINT);
BOOLEAN WINAPI GetActivePwrScheme(PUINT);
BOOLEAN WINAPI SetActivePwrScheme(UINT, PGLOBAL_POWER_POLICY, PPOWER_POLICY);
BOOLEAN WINAPI GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES);  // ?
BOOLEAN WINAPI IsPwrSuspendAllowed(VOID);
BOOLEAN WINAPI IsPwrHibernateAllowed(VOID);
BOOLEAN WINAPI IsPwrShutdownAllowed(VOID);
BOOLEAN WINAPI IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY);
BOOLEAN WINAPI SetSuspendState(BOOLEAN, BOOLEAN, BOOLEAN);
BOOLEAN WINAPI GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY, PPOWER_POLICY);
BOOLEAN WINAPI CanUserWritePwrScheme(VOID);
#if (NTDDI_VERSION >= NTDDI_WINXP)
BOOLEAN WINAPI ReadProcessorPwrScheme(UINT, PMACHINE_PROCESSOR_POWER_POLICY);
BOOLEAN WINAPI WriteProcessorPwrScheme(UINT, PMACHINE_PROCESSOR_POWER_POLICY);
#endif /* NTDDI_VERSION >= NTDDI_WINXP */
BOOLEAN WINAPI ValidatePowerPolicies(PGLOBAL_POWER_POLICY, PPOWER_POLICY);

#ifndef NT_SUCCESS
#define NTSTATUS  LONG
#define _OVERRIDE_NTSTATUS_
#endif

NTSTATUS WINAPI CallNtPowerInformation(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG);

#ifdef _OVERRIDE_NTSTATUS_
#undef NTSTATUS
#endif

#if (NTDDI_VERSION >= NTDDI_VISTA)
typedef enum _POWER_DATA_ACCESSOR {
    ACCESS_AC_POWER_SETTING_INDEX = 0,
    ACCESS_DC_POWER_SETTING_INDEX,
    ACCESS_FRIENDLY_NAME,
    ACCESS_DESCRIPTION,
    ACCESS_POSSIBLE_POWER_SETTING,
    ACCESS_POSSIBLE_POWER_SETTING_FRIENDLY_NAME,
    ACCESS_POSSIBLE_POWER_SETTING_DESCRIPTION,
    ACCESS_DEFAULT_AC_POWER_SETTING,
    ACCESS_DEFAULT_DC_POWER_SETTING,
    ACCESS_POSSIBLE_VALUE_MIN,
    ACCESS_POSSIBLE_VALUE_MAX,
    ACCESS_POSSIBLE_VALUE_INCREMENT,
    ACCESS_POSSIBLE_VALUE_UNITS,
    ACCESS_ICON_RESOURCE,
    ACCESS_DEFAULT_SECURITY_DESCRIPTOR,
    ACCESS_ATTRIBUTES,
    ACCESS_SCHEME,
    ACCESS_SUBGROUP,
    ACCESS_INDIVIDUAL_SETTING,
    ACCESS_ACTIVE_SCHEME,
    ACCESS_CREATE_SCHEME,
    ACCESS_AC_POWER_SETTING_MAX,
    ACCESS_DC_POWER_SETTING_MAX,
    ACCESS_AC_POWER_SETTING_MIN,
    ACCESS_DC_POWER_SETTING_MIN,
} POWER_DATA_ACCESSOR, *PPOWER_DATA_ACCESSOR;

#define DEVICE_NOTIFY_CALLBACK  2

typedef ULONG DEVICE_NOTIFY_CALLBACK_ROUTINE(PVOID, ULONG, PVOID);
typedef DEVICE_NOTIFY_CALLBACK_ROUTINE* PDEVICE_NOTIFY_CALLBACK_ROUTINE;

typedef struct _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS {
    PDEVICE_NOTIFY_CALLBACK_ROUTINE Callback;
    PVOID Context;
} DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS, *PDEVICE_NOTIFY_SUBSCRIBE_PARAMETERS;

#if (NTDDI_VERSION >= NTDDI_WIN7)
BOOLEAN PowerIsSettingRangeDefined(CONST GUID *, CONST GUID *);
DWORD PowerSettingAccessCheckEx(POWER_DATA_ACCESSOR, CONST GUID *, REGSAM);
#endif /* NTDDI_VERSION >= NTDDI_WIN7 */
STDAPI_(DWORD) PowerSettingAccessCheck(POWER_DATA_ACCESSOR, CONST GUID *);
STDAPI_(DWORD) PowerReadACValueIndex(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, LPDWORD);
STDAPI_(DWORD) PowerReadDCValueIndex(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, LPDWORD);
STDAPI_(DWORD) PowerReadFriendlyName(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, PUCHAR, LPDWORD);
STDAPI_(DWORD) PowerReadDescription(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, PUCHAR, LPDWORD);
STDAPI_(DWORD) PowerReadPossibleValue(HKEY, CONST GUID *, CONST GUID *, PULONG, ULONG, PUCHAR, LPDWORD);
STDAPI_(DWORD) PowerReadPossibleFriendlyName(HKEY, CONST GUID *, CONST GUID *, ULONG, PUCHAR, LPDWORD);
STDAPI_(DWORD) PowerReadPossibleDescription(HKEY, CONST GUID *, CONST GUID *, ULONG, PUCHAR, LPDWORD);
STDAPI_(DWORD) PowerReadValueMin(HKEY, CONST GUID *, CONST GUID *, LPDWORD);
STDAPI_(DWORD) PowerReadValueMax(HKEY, CONST GUID *, CONST GUID *, LPDWORD);
STDAPI_(DWORD) PowerReadValueIncrement(HKEY, CONST GUID *, CONST GUID *, LPDWORD);
STDAPI_(DWORD) PowerReadValueUnitsSpecifier(HKEY, CONST GUID *, CONST GUID *, UCHAR *, LPDWORD);
STDAPI_(DWORD) PowerReadACDefaultIndex(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, LPDWORD);
STDAPI_(DWORD) PowerReadDCDefaultIndex(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, LPDWORD);
STDAPI_(DWORD) PowerReadIconResourceSpecifier(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, PUCHAR, LPDWORD);
STDAPI_(DWORD) PowerReadSettingAttributes(CONST GUID *, CONST GUID *);
STDAPI_(DWORD) PowerWriteFriendlyName(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, UCHAR *, DWORD);
STDAPI_(DWORD) PowerWriteDescription(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, UCHAR *, DWORD);
STDAPI_(DWORD) PowerWritePossibleValue(HKEY, CONST GUID *, CONST GUID *, ULONG, ULONG, UCHAR *, DWORD);
STDAPI_(DWORD) PowerWritePossibleFriendlyName(HKEY, CONST GUID *, CONST GUID *, ULONG, UCHAR *, DWORD);
STDAPI_(DWORD) PowerWritePossibleDescription(HKEY, CONST GUID *, CONST GUID *, ULONG, UCHAR *, DWORD);
STDAPI_(DWORD) PowerWriteValueMin(HKEY, CONST GUID *, CONST GUID *, DWORD);
STDAPI_(DWORD) PowerWriteValueMax(HKEY, CONST GUID *, CONST GUID *, DWORD);
STDAPI_(DWORD) PowerWriteValueIncrement(HKEY, CONST GUID *, CONST GUID *, DWORD);
STDAPI_(DWORD) PowerWriteValueUnitsSpecifier(HKEY, CONST GUID *, CONST GUID *, UCHAR *, DWORD);
STDAPI_(DWORD) PowerWriteACDefaultIndex(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, DWORD);
STDAPI_(DWORD) PowerWriteDCDefaultIndex(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, DWORD);
STDAPI_(DWORD) PowerWriteIconResourceSpecifier(HKEY, CONST GUID *, CONST GUID *, CONST GUID *, UCHAR *, DWORD);
STDAPI_(DWORD) PowerWriteSettingAttributes(CONST GUID *, CONST GUID *, DWORD);
STDAPI_(DWORD) PowerDuplicateScheme(HKEY, const GUID *, GUID **);
STDAPI_(DWORD) PowerImportPowerScheme(HKEY, LPCWSTR, GUID **);
STDAPI_(DWORD) PowerDeleteScheme(HKEY, CONST GUID *);
STDAPI_(DWORD) PowerRemovePowerSetting(CONST GUID *, CONST GUID *);
STDAPI_(DWORD) PowerCreateSetting(HKEY, CONST GUID *, CONST GUID *);
STDAPI_(DWORD) PowerCreatePossibleSetting(HKEY, CONST GUID *, CONST GUID *, ULONG);
STDAPI_(DWORD) PowerEnumerate(HKEY, CONST GUID *, CONST GUID *, POWER_DATA_ACCESSOR, ULONG, UCHAR *, DWORD *);
STDAPI_(DWORD) PowerOpenUserPowerKey(HKEY *, REGSAM, BOOL);
STDAPI_(DWORD) PowerOpenSystemPowerKey(HKEY *, REGSAM, BOOL);
STDAPI_(DWORD) PowerCanRestoreIndividualDefaultPowerScheme(CONST GUID *);
STDAPI_(DWORD) PowerRestoreIndividualDefaultPowerScheme(CONST GUID *);
STDAPI_(DWORD) PowerRestoreDefaultPowerSchemes(VOID);
STDAPI_(DWORD) PowerReplaceDefaultPowerSchemes(VOID);
STDAPI_(POWER_PLATFORM_ROLE) PowerDeterminePlatformRole(VOID);
#endif /* NTDDI_VERSION >= NTDDI_VISTA */

#if (NTDDI_VERSION >= NTDDI_WS03)

#define DEVICEPOWER_HARDWAREID  (0x80000000)
#define DEVICEPOWER_AND_OPERATION  (0x40000000)
#define DEVICEPOWER_FILTER_DEVICES_PRESENT  (0x20000000)
#define DEVICEPOWER_FILTER_HARDWARE  (0x10000000)
#define DEVICEPOWER_FILTER_WAKEENABLED  (0x08000000)
#define DEVICEPOWER_FILTER_WAKEPROGRAMMABLE  (0x04000000)
#define DEVICEPOWER_FILTER_ON_NAME  (0x02000000)
#define DEVICEPOWER_SET_WAKEENABLED  (0x00000001)
#define DEVICEPOWER_CLEAR_WAKEENABLED  (0x00000002)

#define PDCAP_S0_SUPPORTED  0x00010000
#define PDCAP_S1_SUPPORTED  0x00020000
#define PDCAP_S2_SUPPORTED  0x00040000
#define PDCAP_S3_SUPPORTED  0x00080000
#define PDCAP_WAKE_FROM_S0_SUPPORTED  0x00100000
#define PDCAP_WAKE_FROM_S1_SUPPORTED  0x00200000
#define PDCAP_WAKE_FROM_S2_SUPPORTED  0x00400000
#define PDCAP_WAKE_FROM_S3_SUPPORTED  0x00800000
#define PDCAP_S4_SUPPORTED  0x01000000
#define PDCAP_S5_SUPPORTED  0x02000000

BOOLEAN WINAPI DevicePowerEnumDevices(ULONG, ULONG, ULONG, PBYTE, PULONG);
DWORD WINAPI DevicePowerSetDeviceState(LPCWSTR, ULONG, PVOID);
BOOLEAN WINAPI DevicePowerOpen(ULONG);
BOOLEAN WINAPI DevicePowerClose(VOID);

#endif /* NTDDI_VERSION >= NTDDI_WS03 */

#if (NTDDI_VERSION >= NTDDI_WIN7)
#ifndef _HPOWERNOTIFY_DEFINED_
#define _HPOWERNOTIFY_DEFINED_
typedef PVOID HPOWERNOTIFY;
typedef HPOWERNOTIFY *PHPOWERNOTIFY;
#endif /* _HPOWERNOTIFY_DEFINED_ */

DWORD WINAPI PowerSettingRegisterNotification(LPCGUID,DWORD,HANDLE,PHPOWERNOTIFY);
DWORD WINAPI PowerSettingUnregisterNotification(HPOWERNOTIFY);
#endif /* NTDDI_VERSION >= NTDDI_WIN7 */

#if (NTDDI_VERSION >= NTDDI_WINBLUE)

#define THERMAL_EVENT_VERSION  1

typedef struct _THERMAL_EVENT {
    ULONG Version;
    ULONG Size;
    ULONG Type;
    ULONG Temperature;
    ULONG TripPointTemperature;
    LPWSTR Initiator; 
} THERMAL_EVENT, *PTHERMAL_EVENT; 

DWORD PowerReportThermalEvent(PTHERMAL_EVENT);
#endif /* NTDDI_VERSION >= NTDDI_WINBLUE */

#ifdef __cplusplus
}
#endif

#endif /* _POWRPROF_H */
