2 * Copyright (C) 2005 Benjamin Cutler
3 * Copyright (C) 2008 Dmitry Chapyshev
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WIN32_NO_STATUS
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(powrprof
);
37 static const WCHAR szPowerCfgSubKey
[] =
38 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg";
39 static const WCHAR szUserPowerConfigSubKey
[] =
40 L
"Control Panel\\PowerCfg";
41 static const WCHAR szCurrentPowerPolicies
[] =
42 L
"CurrentPowerPolicy";
43 static const WCHAR szPolicies
[] = L
"Policies";
44 static const WCHAR szName
[] = L
"Name";
45 static const WCHAR szDescription
[] = L
"Description";
46 static const WCHAR szSemaphoreName
[] = L
"PowerProfileRegistrySemaphore";
47 static const WCHAR szDiskMax
[] = L
"DiskSpindownMax";
48 static const WCHAR szDiskMin
[] = L
"DiskSpindownMin";
49 static const WCHAR szLastID
[] = L
"LastID";
53 BOOLEAN WINAPI
WritePwrPolicy(PUINT puiID
, PPOWER_POLICY pPowerPolicy
);
55 HANDLE PPRegSemaphore
= NULL
;
58 CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel
,
60 ULONG nInputBufferSize
,
62 ULONG nOutputBufferSize
)
66 //Lohnegrim: In order to get the right results, we have to ajust our Privilegs
67 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
68 RtlAdjustPrivilege(SE_CREATE_PAGEFILE_PRIVILEGE
, TRUE
, FALSE
, &old
);
70 return NtPowerInformation(InformationLevel
,
79 CanUserWritePwrScheme(VOID
)
83 BOOLEAN bSuccess
= TRUE
;
87 Ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
89 if (Ret
!= ERROR_SUCCESS
)
91 TRACE("RegOpenKeyEx failed: %d\n", Ret
);
102 DeletePwrScheme(UINT uiIndex
)
108 swprintf(Buf
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%d", uiIndex
);
110 if (GetActivePwrScheme(&Current
))
112 if (Current
== uiIndex
)
114 SetLastError(ERROR_ACCESS_DENIED
);
119 Err
= RegDeleteKey(HKEY_CURRENT_USER
, (LPCTSTR
) Buf
);
120 if (Err
!= ERROR_SUCCESS
)
122 TRACE("RegDeleteKey failed: %d\n", Err
);
128 SetLastError(ERROR_SUCCESS
);
139 POWRPROF_GetUserPowerPolicy(LPWSTR szNum
,
140 PUSER_POWER_POLICY puserPwrPolicy
,
141 DWORD dwName
, LPWSTR szName
,
142 DWORD dwDesc
, LPWSTR szDesc
)
147 WCHAR szPath
[MAX_PATH
];
149 swprintf(szPath
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%s", szNum
);
151 Err
= RegOpenKeyW(HKEY_CURRENT_USER
, szPath
, &hSubKey
);
152 if (Err
!= ERROR_SUCCESS
)
154 ERR("RegOpenKeyW failed: %d\n", Err
);
159 dwName
= MAX_PATH
* sizeof(WCHAR
);
160 Err
= RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szName
, &dwName
);
161 if (Err
!= ERROR_SUCCESS
)
163 ERR("RegQueryValueExW failed: %d\n", Err
);
168 dwDesc
= MAX_PATH
* sizeof(WCHAR
);
169 Err
= RegQueryValueExW(hSubKey
, L
"Description", NULL
, NULL
, (LPBYTE
)szDesc
, &dwDesc
);
170 if (Err
!= ERROR_SUCCESS
)
172 ERR("RegQueryValueExW failed: %d\n", Err
);
177 dwSize
= sizeof(USER_POWER_POLICY
);
178 Err
= RegQueryValueExW(hSubKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)puserPwrPolicy
, &dwSize
);
179 if (Err
!= ERROR_SUCCESS
)
181 ERR("RegQueryValueExW failed: %d\n", Err
);
190 POWRPROF_GetMachinePowerPolicy(LPWSTR szNum
, PMACHINE_POWER_POLICY pmachinePwrPolicy
)
194 WCHAR szPath
[MAX_PATH
];
197 swprintf(szPath
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%s", szNum
);
199 Err
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szPath
, &hKey
);
200 if (Err
!= ERROR_SUCCESS
)
202 ERR("RegOpenKeyW failed: %d\n", Err
);
207 dwSize
= sizeof(MACHINE_POWER_POLICY
);
208 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)pmachinePwrPolicy
, &dwSize
);
209 if (Err
!= ERROR_SUCCESS
)
211 ERR("RegQueryValueExW failed: %d\n", Err
);
220 EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc
,
225 DWORD dwSize
, dwNameSize
= MAX_PATH
, dwDescSize
= MAX_PATH
, dwIndex
= 0;
226 WCHAR szNum
[3 + 1], szName
[MAX_PATH
], szDesc
[MAX_PATH
];
227 POWER_POLICY PwrPolicy
;
228 USER_POWER_POLICY userPwrPolicy
;
229 MACHINE_POWER_POLICY machinePwrPolicy
;
232 if (!lpfnPwrSchemesEnumProc
)
234 SetLastError(ERROR_INVALID_PARAMETER
);
238 Err
= RegOpenKeyW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg\\PowerPolicies", &hKey
);
239 if (Err
!= ERROR_SUCCESS
)
241 ERR("RegOpenKeyW failed: %d\n", Err
);
246 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
248 dwSize
= sizeof(szNum
) / sizeof(WCHAR
);
250 while (RegEnumKeyExW(hKey
, dwIndex
, szNum
, &dwSize
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
252 if (!POWRPROF_GetUserPowerPolicy(szNum
, &userPwrPolicy
,
257 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
261 if (!POWRPROF_GetMachinePowerPolicy(szNum
, &machinePwrPolicy
))
264 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
268 memcpy(&PwrPolicy
.user
, &userPwrPolicy
, sizeof(USER_POWER_POLICY
));
269 memcpy(&PwrPolicy
.mach
, &machinePwrPolicy
, sizeof(MACHINE_POWER_POLICY
));
271 if (!lpfnPwrSchemesEnumProc(_wtoi(szNum
), dwNameSize
, szName
, dwDescSize
, szDesc
, &PwrPolicy
, lParam
))
274 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
282 dwSize
= sizeof(szNum
) / sizeof(WCHAR
);
287 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
288 SetLastError(ERROR_SUCCESS
);
295 GetActivePwrScheme(PUINT puiID
)
298 WCHAR szBuf
[MAX_PATH
];
302 TRACE("GetActivePwrScheme(%u)", puiID
);
304 Err
= RegOpenKeyW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg", &hKey
);
305 if (Err
!= ERROR_SUCCESS
)
307 ERR("RegOpenKey failed: %d\n", Err
);
313 Err
= RegQueryValueExW(hKey
, L
"CurrentPowerPolicy",
315 (LPBYTE
)&szBuf
, &dwSize
);
316 if (Err
!= ERROR_SUCCESS
)
318 ERR("RegQueryValueEx failed: %d\n", Err
);
324 *puiID
= _wtoi(szBuf
);
327 SetLastError(ERROR_SUCCESS
);
333 GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
,
334 PPOWER_POLICY pPowerPolicy
)
337 SYSTEM_POWER_POLICY ACPower, DCPower;
339 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy, pPowerPolicy);
341 NtPowerInformation(SystemPowerPolicyAc, 0, 0, &ACPower, sizeof(SYSTEM_POWER_POLICY));
342 NtPowerInformation(SystemPowerPolicyDc, 0, 0, &DCPower, sizeof(SYSTEM_POWER_POLICY));
347 Lohnegrim: I dont know why this Function shoud call NtPowerInformation, becouse as far as i know,
348 it simply returns the GlobalPowerPolicy and the AktivPowerScheme!
353 if (pGlobalPowerPolicy
!= NULL
)
355 ret
= ReadGlobalPwrPolicy(pGlobalPowerPolicy
);
361 if (pPowerPolicy
!= NULL
)
363 ret
= GetActivePwrScheme(&uiID
);
368 ret
= ReadPwrScheme(uiID
,pPowerPolicy
);
379 GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities
)
383 TRACE("(%p)\n", lpSystemPowerCapabilities
);
385 if (!lpSystemPowerCapabilities
)
387 SetLastError(ERROR_INVALID_PARAMETER
);
391 Ret
= NtPowerInformation(SystemPowerCapabilities
, 0, 0, lpSystemPowerCapabilities
, sizeof(SYSTEM_POWER_CAPABILITIES
));
393 SetLastError(RtlNtStatusToDosError(Ret
));
395 if (Ret
== STATUS_SUCCESS
)
403 GetPwrDiskSpindownRange(PUINT RangeMax
, PUINT RangeMin
)
408 DWORD cbValue
= sizeof(lpValue
);
410 TRACE("(%p, %p)\n", RangeMax
, RangeMin
);
412 if (RangeMax
== NULL
|| RangeMin
== NULL
)
414 SetLastError(ERROR_INVALID_PARAMETER
);
418 SetLastError(ERROR_SUCCESS
);
420 WaitForSingleObject(PPRegSemaphore
, INFINITE
);
422 Ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
423 if (Ret
!= ERROR_SUCCESS
)
425 TRACE("RegOpenKeyEx failed: %d\n", Ret
);
426 TRACE("Using defaults: 3600, 3\n");
429 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
433 Ret
= RegQueryValueExW(hKey
, szDiskMax
, 0, 0, lpValue
, &cbValue
);
434 if (Ret
!= ERROR_SUCCESS
)
436 TRACE("Couldn't open DiskSpinDownMax: %d\n", Ret
);
437 TRACE("Using default: 3600\n");
442 *RangeMax
= _wtoi((LPCWSTR
)lpValue
);
445 cbValue
= sizeof(lpValue
);
447 Ret
= RegQueryValueExW(hKey
, szDiskMin
, 0, 0, lpValue
, &cbValue
);
448 if (Ret
!= ERROR_SUCCESS
)
450 TRACE("Couldn't open DiskSpinDownMin: %d\n", Ret
);
451 TRACE("Using default: 3\n");
456 *RangeMin
= _wtoi((LPCWSTR
)lpValue
);
461 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
462 SetLastError(ERROR_SUCCESS
);
469 IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p
)
471 FIXME("( %p) stub!\n", p
);
476 IsPwrHibernateAllowed(VOID
)
478 SYSTEM_POWER_CAPABILITIES PowerCaps
;
482 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
483 ret
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
484 if (ret
== STATUS_SUCCESS
)
486 return PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
; // IsHiberfilPresent();
490 SetLastError(RtlNtStatusToDosError(ret
));
497 IsPwrShutdownAllowed(VOID
)
499 SYSTEM_POWER_CAPABILITIES PowerCaps
;
503 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
504 ret
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
505 if (ret
== STATUS_SUCCESS
)
507 return PowerCaps
.SystemS5
;
511 SetLastError(RtlNtStatusToDosError(ret
));
518 IsPwrSuspendAllowed(VOID
)
520 SYSTEM_POWER_CAPABILITIES PowerCaps
;
524 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
525 ret
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
526 if (ret
== STATUS_SUCCESS
)
528 return PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
;
532 SetLastError(RtlNtStatusToDosError(ret
));
539 ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
541 GLOBAL_MACHINE_POWER_POLICY glMachPwrPolicy
;
542 GLOBAL_USER_POWER_POLICY glUserPwrPolicy
;
547 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
549 // Getting user global power policy
550 Err
= RegOpenKeyW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg\\GlobalPowerPolicy", &hKey
);
551 if (Err
!= ERROR_SUCCESS
)
553 ERR("RegOpenKeyW failed: %d\n", Err
);
554 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
559 dwSize
= sizeof(glUserPwrPolicy
);
560 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)&glUserPwrPolicy
, &dwSize
);
561 if (Err
!= ERROR_SUCCESS
)
563 ERR("RegQueryValueExW failed: %d\n", Err
);
564 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
571 // Getting machine global power policy
572 Err
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy", &hKey
);
573 if (Err
!= ERROR_SUCCESS
)
575 ERR("RegOpenKeyW failed: %d\n", Err
);
576 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
581 dwSize
= sizeof(glMachPwrPolicy
);
582 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)&glMachPwrPolicy
, &dwSize
);
583 if (Err
!= ERROR_SUCCESS
)
585 ERR("RegQueryValueExW failed: %d\n", Err
);
586 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
593 memcpy(&pGlobalPowerPolicy
->user
, &glUserPwrPolicy
, sizeof(GLOBAL_USER_POWER_POLICY
));
594 memcpy(&pGlobalPowerPolicy
->mach
, &glMachPwrPolicy
, sizeof(GLOBAL_MACHINE_POWER_POLICY
));
596 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
597 SetLastError(ERROR_SUCCESS
);
604 ReadProcessorPwrScheme(UINT uiID
,
605 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
608 WCHAR szPath
[MAX_PATH
];
609 DWORD len
=sizeof(MACHINE_PROCESSOR_POWER_POLICY
);
611 swprintf(szPath
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", uiID
);
612 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
616 &hKey
) == ERROR_SUCCESS
)
618 if (RegQueryValueExW(hKey
,szPolicies
,NULL
,0,(LPBYTE
)pMachineProcessorPowerPolicy
,&len
) == ERROR_SUCCESS
)
628 return ReadProcessorPwrScheme(0,pMachineProcessorPowerPolicy
);
646 ReadPwrScheme(UINT uiID
,
647 PPOWER_POLICY pPowerPolicy
)
649 USER_POWER_POLICY userPwrPolicy
;
650 MACHINE_POWER_POLICY machinePwrPolicy
;
651 WCHAR szNum
[3 + 1]; // max number - 999
653 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
655 swprintf(szNum
, L
"%d", uiID
);
657 if (!POWRPROF_GetUserPowerPolicy(szNum
, &userPwrPolicy
, 0, NULL
, 0, NULL
))
659 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
663 if (!POWRPROF_GetMachinePowerPolicy(szNum
, &machinePwrPolicy
))
665 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
669 memcpy(&pPowerPolicy
->user
, &userPwrPolicy
, sizeof(USER_POWER_POLICY
));
670 memcpy(&pPowerPolicy
->mach
, &machinePwrPolicy
, sizeof(MACHINE_POWER_POLICY
));
672 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
673 SetLastError(ERROR_SUCCESS
);
680 SetActivePwrScheme(UINT uiID
,
681 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy
,
682 PPOWER_POLICY lpPowerPolicy
)
689 if (ReadPwrScheme(uiID
,&tmp
))
691 if (RegOpenKeyEx(HKEY_CURRENT_USER
,szUserPowerConfigSubKey
,0,KEY_ALL_ACCESS
,&hKey
) != ERROR_SUCCESS
)
695 swprintf(Buf
,L
"%i",uiID
);
697 if (RegSetValueExW(hKey
,szCurrentPowerPolicies
,0,REG_SZ
,(CONST BYTE
*)Buf
,strlenW(Buf
)*sizeof(WCHAR
)) == ERROR_SUCCESS
)
700 if ((lpGlobalPowerPolicy
!= NULL
) || (lpPowerPolicy
!= NULL
))
702 ret
= ValidatePowerPolicies(lpGlobalPowerPolicy
,lpPowerPolicy
);
706 if (lpGlobalPowerPolicy
!= NULL
)
708 ret
= WriteGlobalPwrPolicy(lpGlobalPowerPolicy
);
710 if (ret
&& lpPowerPolicy
!= NULL
)
712 ret
= WritePwrPolicy(&uiID
,lpPowerPolicy
);
736 SetSuspendState(BOOLEAN Hibernate
,
737 BOOLEAN ForceCritical
,
738 BOOLEAN DisableWakeEvent
)
740 FIXME("(%d, %d, %d) stub!\n", Hibernate
, ForceCritical
, DisableWakeEvent
);
746 WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
749 GLOBAL_USER_POWER_POLICY gupp
;
750 GLOBAL_MACHINE_POWER_POLICY gmpp
;
752 gupp
= pGlobalPowerPolicy
->user
;
753 gmpp
= pGlobalPowerPolicy
->mach
;
755 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
756 L
"Control Panel\\PowerCfg\\GlobalPowerPolicy",
762 if (RegSetValueExW(hKey
,szPolicies
,0,REG_BINARY
,(const unsigned char *)&gupp
,sizeof(GLOBAL_USER_POWER_POLICY
)) == ERROR_SUCCESS
)
766 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
767 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy",
773 if (RegSetValueExW(hKey
,szPolicies
,0,REG_BINARY
,(const unsigned char *)&gmpp
,sizeof(GLOBAL_MACHINE_POWER_POLICY
)) == ERROR_SUCCESS
)
792 WriteProcessorPwrScheme(UINT ID
,
793 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
798 swprintf(Buf
,L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i",ID
);
800 if (RegCreateKey(HKEY_LOCAL_MACHINE
,Buf
, &hKey
) == ERROR_SUCCESS
)
802 RegSetValueExW(hKey
,szPolicies
,0,REG_BINARY
,(const unsigned char *)pMachineProcessorPowerPolicy
,sizeof(MACHINE_PROCESSOR_POWER_POLICY
));
817 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
821 &hKey
) != ERROR_SUCCESS
)
823 swprintf(Buf
,L
"%i",g_LastID
);
824 RegSetValueExW(hKey
,szLastID
,0,REG_SZ
,(CONST BYTE
*)Buf
,strlenW(Buf
)*sizeof(WCHAR
));
829 WritePwrScheme(PUINT puiID
,
831 LPWSTR lpszDescription
,
832 PPOWER_POLICY pPowerPolicy
)
844 swprintf(Buf
,L
"Control Panel\\PowerCfg\\PowerPolicies\\%i",*puiID
);
846 if (RegCreateKey(HKEY_CURRENT_USER
,Buf
,&hKey
) == ERROR_SUCCESS
)
848 RegSetValueExW(hKey
,szName
,0,REG_SZ
,(const unsigned char *)lpszName
,strlenW((const char *)lpszName
)*sizeof(WCHAR
));
849 RegSetValueExW(hKey
,szDescription
,0,REG_SZ
,(const unsigned char *)lpszDescription
,strlenW((const char *)lpszDescription
)*sizeof(WCHAR
));
851 return WritePwrPolicy(puiID
,pPowerPolicy
);
860 BOOLEAN
CheckPowerActionPolicy(PPOWER_ACTION_POLICY pPAP
, SYSTEM_POWER_CAPABILITIES PowerCaps
)
863 Lohnegrim: this is an Helperfunction, it checks if the POWERACTIONPOLICY is valid
864 Also, if the System dosn't support Hipernation, then change the PowerAction
866 switch (pPAP
->Action
)
868 case PowerActionNone
:
870 case PowerActionReserved
:
871 if (PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
)
872 pPAP
->Action
= PowerActionSleep
;
874 pPAP
->Action
= PowerActionReserved
;
875 case PowerActionSleep
:
877 case PowerActionHibernate
:
878 if (!(PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
))
880 if (PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
)
881 pPAP
->Action
= PowerActionSleep
;
883 pPAP
->Action
= PowerActionReserved
;
885 case PowerActionShutdown
:
886 case PowerActionShutdownReset
:
887 case PowerActionShutdownOff
:
888 case PowerActionWarmEject
:
891 SetLastError(ERROR_INVALID_DATA
);
896 VOID
FixSystemPowerState(PSYSTEM_POWER_STATE Psps
, SYSTEM_POWER_CAPABILITIES PowerCaps
)
899 //Lohnegrim: If the System dosn't support the Powerstates, then we have to change them
900 if (!PowerCaps
.SystemS1
&& *Psps
== PowerSystemSleeping1
)
901 *Psps
= PowerSystemSleeping2
;
902 if (!PowerCaps
.SystemS2
&& *Psps
== PowerSystemSleeping2
)
903 *Psps
= PowerSystemSleeping3
;
904 if (!PowerCaps
.SystemS3
&& *Psps
== PowerSystemSleeping3
)
905 *Psps
= PowerSystemHibernate
;
906 if (!(PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
) && *Psps
== PowerSystemHibernate
)
907 *Psps
= PowerSystemSleeping2
;
908 if (!PowerCaps
.SystemS1
&& *Psps
== PowerSystemSleeping1
)
909 *Psps
= PowerSystemSleeping2
;
910 if (!PowerCaps
.SystemS2
&& *Psps
== PowerSystemSleeping2
)
911 *Psps
= PowerSystemSleeping3
;
912 if (!PowerCaps
.SystemS3
&& *Psps
== PowerSystemSleeping3
)
913 *Psps
= PowerSystemShutdown
;
919 ValidatePowerPolicies(PGLOBAL_POWER_POLICY pGPP
, PPOWER_POLICY pPP
)
921 SYSTEM_POWER_CAPABILITIES PowerCaps
;
925 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
926 ret
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
927 if (ret
!= STATUS_SUCCESS
)
929 SetLastError(RtlNtStatusToDosError(ret
));
935 if (pGPP
->user
.Revision
!= 1 || pGPP
->mach
.Revision
!= 1)
937 SetLastError(ERROR_REVISION_MISMATCH
);
940 if (pGPP
->mach
.LidOpenWakeAc
== PowerSystemUnspecified
)
942 SetLastError(ERROR_GEN_FAILURE
);
945 if ((int)pGPP
->mach
.LidOpenWakeAc
>= PowerSystemShutdown
)
947 SetLastError(ERROR_GEN_FAILURE
);
950 if (pGPP
->mach
.LidOpenWakeDc
< PowerSystemWorking
)
952 SetLastError(ERROR_GEN_FAILURE
);
955 if ((int)pGPP
->mach
.LidOpenWakeDc
>= PowerSystemShutdown
)
957 SetLastError(ERROR_GEN_FAILURE
);
960 //Lohnegrim: unneeded
961 /*if ((pGPP->mach.LidOpenWakeDc < PowerSystemWorking) || (pGPP->mach.LidOpenWakeDc >= PowerSystemMaximum))
963 SetLastError(ERROR_GEN_FAILURE);
966 if (!CheckPowerActionPolicy(&pGPP
->user
.LidCloseAc
,PowerCaps
))
970 if (!CheckPowerActionPolicy(&pGPP
->user
.LidCloseDc
,PowerCaps
))
974 if (!CheckPowerActionPolicy(&pGPP
->user
.PowerButtonAc
,PowerCaps
))
978 if (!CheckPowerActionPolicy(&pGPP
->user
.PowerButtonDc
,PowerCaps
))
982 if (!CheckPowerActionPolicy(&pGPP
->user
.SleepButtonAc
,PowerCaps
))
986 if (!CheckPowerActionPolicy(&pGPP
->user
.SleepButtonDc
,PowerCaps
))
990 //Lohnegrim: The BroadcastCapacityResolution presents the Powerlevel in Percent, if invalid set th 100 == FULL
991 if ((pGPP
->mach
.BroadcastCapacityResolution
< 0) || (pGPP
->mach
.BroadcastCapacityResolution
> 100))
992 pGPP
->mach
.BroadcastCapacityResolution
=100;
994 //Lohnegrim: I have no idear, if they are realy needed, or if they are spezific for my System, or what they mean, so i removed them
995 //pGPP->user.DischargePolicy[1].PowerPolicy.EventCode = pGPP->user.DischargePolicy[1].PowerPolicy.EventCode | 0x010000;
996 //pGPP->user.DischargePolicy[2].PowerPolicy.EventCode = pGPP->user.DischargePolicy[2].PowerPolicy.EventCode | 0x020000;
997 //pGPP->user.DischargePolicy[3].PowerPolicy.EventCode = pGPP->user.DischargePolicy[3].PowerPolicy.EventCode | 0x030000;
999 FixSystemPowerState(&pGPP
->mach
.LidOpenWakeAc
,PowerCaps
);
1000 FixSystemPowerState(&pGPP
->mach
.LidOpenWakeDc
,PowerCaps
);
1006 if (pPP
->user
.Revision
!= 1 || pPP
->mach
.Revision
!= 1)
1008 SetLastError(ERROR_REVISION_MISMATCH
);
1012 //Lohnegrim: unneeded
1013 //if (pPP->mach.MinSleepAc < PowerSystemWorking)
1015 // SetLastError(ERROR_GEN_FAILURE);
1018 if ((int)pPP
->mach
.MinSleepAc
>= PowerSystemShutdown
)
1020 SetLastError(ERROR_GEN_FAILURE
);
1023 //Lohnegrim: unneeded
1024 //if (pPP->mach.MinSleepDc < PowerSystemWorking)
1026 // SetLastError(ERROR_GEN_FAILURE);
1029 if ((int)pPP
->mach
.MinSleepDc
>= PowerSystemShutdown
)
1031 SetLastError(ERROR_GEN_FAILURE
);
1034 if (pPP
->mach
.ReducedLatencySleepAc
== PowerSystemUnspecified
)
1036 SetLastError(ERROR_GEN_FAILURE
);
1039 if ((int)pPP
->mach
.ReducedLatencySleepAc
>= PowerSystemShutdown
)
1041 SetLastError(ERROR_GEN_FAILURE
);
1044 if (pPP
->mach
.ReducedLatencySleepDc
< PowerSystemWorking
)
1046 SetLastError(ERROR_GEN_FAILURE
);
1049 if ((int)pPP
->mach
.ReducedLatencySleepDc
>= PowerSystemShutdown
)
1051 SetLastError(ERROR_GEN_FAILURE
);
1055 if (!CheckPowerActionPolicy(&pPP
->mach
.OverThrottledAc
,PowerCaps
))
1059 if (!CheckPowerActionPolicy(&pPP
->mach
.OverThrottledDc
,PowerCaps
))
1063 if (!CheckPowerActionPolicy(&pPP
->user
.IdleAc
,PowerCaps
))
1067 if (!CheckPowerActionPolicy(&pPP
->user
.IdleDc
,PowerCaps
))
1071 if (pPP
->user
.MaxSleepAc
< PowerSystemWorking
)
1073 SetLastError(ERROR_GEN_FAILURE
);
1076 //Lohnegrim: unneeded
1077 /*if ((int)pPP->user.MaxSleepAc > PowerSystemShutdown)
1079 SetLastError(ERROR_GEN_FAILURE);
1082 if (pPP
->user
.MaxSleepDc
< PowerSystemWorking
)
1084 SetLastError(ERROR_GEN_FAILURE
);
1087 //Lohnegrim: unneeded
1088 /*if ((int)pPP->user.MaxSleepDc >= PowerSystemShutdown)
1090 SetLastError(ERROR_GEN_FAILURE);
1093 if (PowerCaps
.SystemS1
)
1095 pPP
->mach
.MinSleepAc
=PowerSystemSleeping1
;
1096 pPP
->mach
.MinSleepDc
=PowerSystemSleeping1
;
1098 else if (PowerCaps
.SystemS2
)
1100 pPP
->mach
.MinSleepAc
=PowerSystemSleeping2
;
1101 pPP
->mach
.MinSleepDc
=PowerSystemSleeping2
;
1103 else if (PowerCaps
.SystemS3
)
1105 pPP
->mach
.MinSleepAc
=PowerSystemSleeping3
;
1106 pPP
->mach
.MinSleepDc
=PowerSystemSleeping3
;
1109 if (PowerCaps
.SystemS4
)
1111 pPP
->user
.MaxSleepAc
=PowerSystemSleeping3
;
1112 pPP
->user
.MaxSleepDc
=PowerSystemSleeping3
;
1114 else if (PowerCaps
.SystemS3
)
1116 pPP
->user
.MaxSleepAc
=PowerSystemSleeping2
;
1117 pPP
->user
.MaxSleepDc
=PowerSystemSleeping2
;
1119 else if (PowerCaps
.SystemS1
)
1121 pPP
->user
.MaxSleepAc
=PowerSystemSleeping1
;
1122 pPP
->user
.MaxSleepDc
=PowerSystemSleeping1
;
1124 //Lohnegrim: I dont know where to get this info from, so i removed it
1125 //pPP->user.OptimizeForPowerAc=TRUE;
1126 //pPP->user.OptimizeForPowerDc=TRUE;
1128 FixSystemPowerState(&pPP
->mach
.ReducedLatencySleepAc
,PowerCaps
);
1129 FixSystemPowerState(&pPP
->mach
.ReducedLatencySleepDc
,PowerCaps
);
1132 SetLastError(ERROR_SUCCESS
);
1136 BOOLEAN WINAPI
WritePwrPolicy(PUINT puiID
, PPOWER_POLICY pPowerPolicy
)
1139 WCHAR Buf
[MAX_PATH
];
1142 swprintf(Buf
,L
"Control Panel\\PowerCfg\\PowerPolicies\\%i",*puiID
);
1144 if (RegCreateKey(HKEY_CURRENT_USER
,Buf
,&hKey
) == ERROR_SUCCESS
)
1146 RegSetValueExW(hKey
,szPolicies
,0,REG_BINARY
,(const unsigned char *)&pPowerPolicy
->user
,sizeof(USER_POWER_POLICY
));
1148 swprintf(Buf
,L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%i",*puiID
);
1150 if (RegCreateKey(HKEY_LOCAL_MACHINE
,Buf
,&hKey
) == ERROR_SUCCESS
)
1152 RegSetValueExW(hKey
,szPolicies
,0,REG_BINARY
,(const unsigned char *)&pPowerPolicy
->mach
,sizeof(MACHINE_POWER_POLICY
));
1167 DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1169 FIXME("(%p, %d, %p) not fully implemented\n", hinstDLL
, fdwReason
, lpvReserved
);
1173 case DLL_PROCESS_ATTACH
:
1179 DisableThreadLibraryCalls(hinstDLL
);
1181 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
1183 if (r
!= ERROR_SUCCESS
)
1185 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
1189 WCHAR lpValue
[MAX_PATH
];
1190 DWORD cbValue
= sizeof(lpValue
);
1191 r
= RegQueryValueExW(hKey
, szLastID
, 0, 0, (BYTE
*)lpValue
, &cbValue
);
1192 if (r
== ERROR_SUCCESS
)
1194 g_LastID
= _wtoi(lpValue
);
1198 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
1203 PPRegSemaphore
= CreateSemaphoreW(NULL
, 1, 1, szSemaphoreName
);
1204 if (PPRegSemaphore
== NULL
)
1206 ERR("Couldn't create Semaphore: %d\n", GetLastError());
1211 case DLL_PROCESS_DETACH
:
1212 CloseHandle(PPRegSemaphore
);