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
23 #define WIN32_NO_STATUS
25 #define NTOS_MODE_USER
26 #include <ndk/pofuncs.h>
27 #include <ndk/rtlfuncs.h>
28 #include <ndk/setypes.h>
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(powrprof
);
39 static const WCHAR szPowerCfgSubKey
[] =
40 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg";
41 static const WCHAR szUserPowerConfigSubKey
[] =
42 L
"Control Panel\\PowerCfg";
43 static const WCHAR szCurrentPowerPolicies
[] =
44 L
"CurrentPowerPolicy";
45 static const WCHAR szPolicies
[] = L
"Policies";
46 static const WCHAR szName
[] = L
"Name";
47 static const WCHAR szDescription
[] = L
"Description";
48 static const WCHAR szSemaphoreName
[] = L
"PowerProfileRegistrySemaphore";
49 static const WCHAR szDiskMax
[] = L
"DiskSpindownMax";
50 static const WCHAR szDiskMin
[] = L
"DiskSpindownMin";
51 static const WCHAR szLastID
[] = L
"LastID";
53 UINT g_LastID
= (UINT
)-1;
55 BOOLEAN WINAPI
WritePwrPolicy(PUINT puiID
, PPOWER_POLICY pPowerPolicy
);
57 HANDLE PPRegSemaphore
= NULL
;
60 CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel
,
62 ULONG nInputBufferSize
,
64 ULONG nOutputBufferSize
)
68 //Lohnegrim: In order to get the right results, we have to ajust our Privilegs
69 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
70 RtlAdjustPrivilege(SE_CREATE_PAGEFILE_PRIVILEGE
, TRUE
, FALSE
, &old
);
72 return NtPowerInformation(InformationLevel
,
80 CanUserWritePwrScheme(VOID
)
87 Ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
88 if (Ret
!= ERROR_SUCCESS
)
90 TRACE("RegOpenKeyEx failed: %d\n", Ret
);
100 DeletePwrScheme(UINT uiIndex
)
106 swprintf(Buf
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%d", uiIndex
);
108 if (!GetActivePwrScheme(&Current
))
111 if (Current
== uiIndex
)
113 SetLastError(ERROR_ACCESS_DENIED
);
117 Err
= RegDeleteKey(HKEY_CURRENT_USER
, (LPCTSTR
)Buf
);
118 if (Err
!= ERROR_SUCCESS
)
120 TRACE("RegDeleteKey failed: %d\n", Err
);
129 POWRPROF_GetUserPowerPolicy(LPWSTR szNum
,
130 PUSER_POWER_POLICY puserPwrPolicy
,
131 DWORD cchName
, LPWSTR szName
,
132 DWORD cchDesc
, LPWSTR szDesc
)
137 WCHAR szPath
[MAX_PATH
];
140 swprintf(szPath
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%s", szNum
);
142 Err
= RegOpenKeyExW(HKEY_CURRENT_USER
, szPath
, 0, KEY_READ
, &hSubKey
);
143 if (Err
!= ERROR_SUCCESS
)
145 ERR("RegOpenKeyExW failed: %d\n", Err
);
150 dwSize
= cchName
* sizeof(WCHAR
);
151 Err
= RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szName
, &dwSize
);
152 if (Err
!= ERROR_SUCCESS
)
154 ERR("RegQueryValueExW failed: %d\n", Err
);
159 dwSize
= cchDesc
* sizeof(WCHAR
);
160 Err
= RegQueryValueExW(hSubKey
, L
"Description", NULL
, NULL
, (LPBYTE
)szDesc
, &dwSize
);
161 if (Err
!= ERROR_SUCCESS
)
163 ERR("RegQueryValueExW failed: %d\n", Err
);
168 dwSize
= sizeof(USER_POWER_POLICY
);
169 Err
= RegQueryValueExW(hSubKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)puserPwrPolicy
, &dwSize
);
170 if (Err
!= ERROR_SUCCESS
)
172 ERR("RegQueryValueExW failed: %d\n", Err
);
180 RegCloseKey(hSubKey
);
186 POWRPROF_GetMachinePowerPolicy(LPWSTR szNum
, PMACHINE_POWER_POLICY pmachinePwrPolicy
)
190 WCHAR szPath
[MAX_PATH
];
193 swprintf(szPath
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%s", szNum
);
195 Err
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPath
, 0, KEY_READ
, &hKey
);
196 if (Err
!= ERROR_SUCCESS
)
198 ERR("RegOpenKeyExW failed: %d\n", Err
);
203 dwSize
= sizeof(MACHINE_POWER_POLICY
);
204 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)pmachinePwrPolicy
, &dwSize
);
206 if (Err
!= ERROR_SUCCESS
)
208 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
;
230 BOOLEAN bRet
= FALSE
;
232 if (!lpfnPwrSchemesEnumProc
)
234 SetLastError(ERROR_INVALID_PARAMETER
);
238 Err
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg\\PowerPolicies", 0, KEY_READ
, &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
,
256 WARN("POWRPROF_GetUserPowerPolicy failed\n");
260 if (!POWRPROF_GetMachinePowerPolicy(szNum
, &machinePwrPolicy
))
262 WARN("POWRPROF_GetMachinePowerPolicy failed\n");
266 memcpy(&PwrPolicy
.user
, &userPwrPolicy
, sizeof(USER_POWER_POLICY
));
267 memcpy(&PwrPolicy
.mach
, &machinePwrPolicy
, sizeof(MACHINE_POWER_POLICY
));
269 if (!lpfnPwrSchemesEnumProc(_wtoi(szNum
), dwNameSize
, szName
, dwDescSize
, szDesc
, &PwrPolicy
, lParam
))
274 dwSize
= sizeof(szNum
) / sizeof(WCHAR
);
280 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
286 GetActivePwrScheme(PUINT puiID
)
289 WCHAR szBuf
[MAX_PATH
];
293 TRACE("GetActivePwrScheme(%u)", puiID
);
295 Err
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg", 0, KEY_READ
, &hKey
);
296 if (Err
!= ERROR_SUCCESS
)
298 ERR("RegOpenKey failed: %d\n", Err
);
304 Err
= RegQueryValueExW(hKey
, L
"CurrentPowerPolicy",
306 (LPBYTE
)&szBuf
, &dwSize
);
307 if (Err
!= ERROR_SUCCESS
)
309 ERR("RegQueryValueEx failed: %d\n", Err
);
316 *puiID
= _wtoi(szBuf
);
322 GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
,
323 PPOWER_POLICY pPowerPolicy
)
326 SYSTEM_POWER_POLICY ACPower, DCPower;
328 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy, pPowerPolicy);
330 NtPowerInformation(SystemPowerPolicyAc, 0, 0, &ACPower, sizeof(SYSTEM_POWER_POLICY));
331 NtPowerInformation(SystemPowerPolicyDc, 0, 0, &DCPower, sizeof(SYSTEM_POWER_POLICY));
336 Lohnegrim: I dont know why this Function shoud call NtPowerInformation, becouse as far as i know,
337 it simply returns the GlobalPowerPolicy and the AktivPowerScheme!
341 if (pGlobalPowerPolicy
!= NULL
)
343 if (!ReadGlobalPwrPolicy(pGlobalPowerPolicy
))
346 if (pPowerPolicy
!= NULL
)
348 if (!GetActivePwrScheme(&uiID
))
351 if (!ReadPwrScheme(uiID
, pPowerPolicy
))
359 GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities
)
363 TRACE("(%p)\n", lpSystemPowerCapabilities
);
365 if (!lpSystemPowerCapabilities
)
367 SetLastError(ERROR_INVALID_PARAMETER
);
371 Status
= NtPowerInformation(SystemPowerCapabilities
, 0, 0, lpSystemPowerCapabilities
, sizeof(SYSTEM_POWER_CAPABILITIES
));
372 if(!NT_SUCCESS(Status
))
374 SetLastError(RtlNtStatusToDosError(Status
));
382 GetPwrDiskSpindownRange(PUINT RangeMax
, PUINT RangeMin
)
387 DWORD cbValue
= sizeof(lpValue
);
389 TRACE("(%p, %p)\n", RangeMax
, RangeMin
);
391 if (RangeMax
== NULL
|| RangeMin
== NULL
)
393 SetLastError(ERROR_INVALID_PARAMETER
);
397 WaitForSingleObject(PPRegSemaphore
, INFINITE
);
399 Ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
400 if (Ret
!= ERROR_SUCCESS
)
402 TRACE("RegOpenKeyEx failed: %d\n", Ret
);
403 TRACE("Using defaults: 3600, 3\n");
406 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
410 Ret
= RegQueryValueExW(hKey
, szDiskMax
, 0, 0, lpValue
, &cbValue
);
411 if (Ret
!= ERROR_SUCCESS
)
413 TRACE("Couldn't open DiskSpinDownMax: %d\n", Ret
);
414 TRACE("Using default: 3600\n");
419 *RangeMax
= _wtoi((LPCWSTR
)lpValue
);
422 cbValue
= sizeof(lpValue
);
424 Ret
= RegQueryValueExW(hKey
, szDiskMin
, 0, 0, lpValue
, &cbValue
);
425 if (Ret
!= ERROR_SUCCESS
)
427 TRACE("Couldn't open DiskSpinDownMin: %d\n", Ret
);
428 TRACE("Using default: 3\n");
433 *RangeMin
= _wtoi((LPCWSTR
)lpValue
);
438 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
444 IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p
)
446 FIXME("( %p) stub!\n", p
);
451 IsPwrHibernateAllowed(VOID
)
453 SYSTEM_POWER_CAPABILITIES PowerCaps
;
457 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
459 Status
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
460 if (!NT_SUCCESS(Status
))
462 SetLastError(RtlNtStatusToDosError(Status
));
466 return PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
; // IsHiberfilPresent();
470 IsPwrShutdownAllowed(VOID
)
472 SYSTEM_POWER_CAPABILITIES PowerCaps
;
476 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
478 Status
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
479 if (!NT_SUCCESS(Status
))
481 SetLastError(RtlNtStatusToDosError(Status
));
485 return PowerCaps
.SystemS5
;
489 IsPwrSuspendAllowed(VOID
)
491 SYSTEM_POWER_CAPABILITIES PowerCaps
;
495 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
497 Status
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
498 if (!NT_SUCCESS(Status
))
500 SetLastError(RtlNtStatusToDosError(Status
));
504 return PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
;
508 PowerGetActiveScheme(HKEY UserRootPowerKey
, GUID
**polguid
)
510 FIXME("(%p,%p) stub!\n", UserRootPowerKey
, polguid
);
511 return ERROR_CALL_NOT_IMPLEMENTED
;
515 PowerReadDCValue(HKEY RootPowerKey
, const GUID
*Scheme
, const GUID
*SubGroup
, const GUID
*PowerSettings
, PULONG Type
, PUCHAR Buffer
, DWORD
*BufferSize
)
517 FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey
, debugstr_guid(Scheme
), debugstr_guid(SubGroup
), debugstr_guid(PowerSettings
), Type
, Buffer
, BufferSize
);
518 return ERROR_CALL_NOT_IMPLEMENTED
;
522 ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
524 GLOBAL_MACHINE_POWER_POLICY glMachPwrPolicy
;
525 GLOBAL_USER_POWER_POLICY glUserPwrPolicy
;
531 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
533 // Getting user global power policy
534 Err
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ
, &hKey
);
535 if (Err
!= ERROR_SUCCESS
)
537 ERR("RegOpenKeyW failed: %d\n", Err
);
542 dwSize
= sizeof(glUserPwrPolicy
);
543 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)&glUserPwrPolicy
, &dwSize
);
544 if (Err
!= ERROR_SUCCESS
)
546 ERR("RegQueryValueExW failed: %d\n", Err
);
553 // Getting machine global power policy
554 Err
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ
, &hKey
);
555 if (Err
!= ERROR_SUCCESS
)
557 ERR("RegOpenKeyW failed: %d\n", Err
);
562 dwSize
= sizeof(glMachPwrPolicy
);
563 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)&glMachPwrPolicy
, &dwSize
);
564 if (Err
!= ERROR_SUCCESS
)
566 ERR("RegQueryValueExW failed: %d\n", Err
);
571 memcpy(&pGlobalPowerPolicy
->user
, &glUserPwrPolicy
, sizeof(GLOBAL_USER_POWER_POLICY
));
572 memcpy(&pGlobalPowerPolicy
->mach
, &glMachPwrPolicy
, sizeof(GLOBAL_MACHINE_POWER_POLICY
));
578 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
585 ReadProcessorPwrScheme(UINT uiID
,
586 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
589 WCHAR szPath
[MAX_PATH
];
590 DWORD dwSize
= sizeof(MACHINE_PROCESSOR_POWER_POLICY
);
592 swprintf(szPath
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", uiID
);
593 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
, szPath
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
596 if (RegQueryValueExW(hKey
, szPolicies
, NULL
, 0, (LPBYTE
)pMachineProcessorPowerPolicy
, &dwSize
) == ERROR_SUCCESS
)
604 return ReadProcessorPwrScheme(0, pMachineProcessorPowerPolicy
);
611 ReadPwrScheme(UINT uiID
,
612 PPOWER_POLICY pPowerPolicy
)
614 USER_POWER_POLICY userPwrPolicy
;
615 MACHINE_POWER_POLICY machinePwrPolicy
;
616 WCHAR szNum
[16]; // max number - 999
618 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
620 swprintf(szNum
, L
"%d", uiID
);
622 if (!POWRPROF_GetUserPowerPolicy(szNum
, &userPwrPolicy
, 0, NULL
, 0, NULL
))
624 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
628 if (!POWRPROF_GetMachinePowerPolicy(szNum
, &machinePwrPolicy
))
630 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
634 memcpy(&pPowerPolicy
->user
, &userPwrPolicy
, sizeof(userPwrPolicy
));
635 memcpy(&pPowerPolicy
->mach
, &machinePwrPolicy
, sizeof(machinePwrPolicy
));
637 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
643 SetActivePwrScheme(UINT uiID
,
644 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy
,
645 PPOWER_POLICY lpPowerPolicy
)
651 if (!ReadPwrScheme(uiID
, &tmp
))
654 if (RegOpenKeyEx(HKEY_CURRENT_USER
, szUserPowerConfigSubKey
, 0, KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
657 swprintf(Buf
, L
"%i", uiID
);
659 if (RegSetValueExW(hKey
, szCurrentPowerPolicies
, 0, REG_SZ
, (PBYTE
)Buf
, strlenW(Buf
)*sizeof(WCHAR
)) != ERROR_SUCCESS
)
666 if (lpGlobalPowerPolicy
!= NULL
|| lpPowerPolicy
!= NULL
)
668 if (!ValidatePowerPolicies(lpGlobalPowerPolicy
, lpPowerPolicy
))
671 if (lpGlobalPowerPolicy
!= NULL
&& !WriteGlobalPwrPolicy(lpGlobalPowerPolicy
))
674 if (lpPowerPolicy
!= NULL
&& !WritePwrPolicy(&uiID
,lpPowerPolicy
))
682 SetSuspendState(BOOLEAN Hibernate
,
683 BOOLEAN ForceCritical
,
684 BOOLEAN DisableWakeEvent
)
686 FIXME("(%d, %d, %d) stub!\n", Hibernate
, ForceCritical
, DisableWakeEvent
);
691 WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
694 GLOBAL_USER_POWER_POLICY gupp
;
695 GLOBAL_MACHINE_POWER_POLICY gmpp
;
697 gupp
= pGlobalPowerPolicy
->user
;
698 gmpp
= pGlobalPowerPolicy
->mach
;
700 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
701 L
"Control Panel\\PowerCfg\\GlobalPowerPolicy",
704 &hKey
) != ERROR_SUCCESS
)
707 if (RegSetValueExW(hKey
, szPolicies
, 0, REG_BINARY
, (PBYTE
)&gupp
, sizeof(gupp
)) != ERROR_SUCCESS
)
715 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
716 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy",
722 if (RegSetValueExW(hKey
,szPolicies
, 0, REG_BINARY
, (PBYTE
)&gmpp
, sizeof(gmpp
)) != ERROR_SUCCESS
)
733 WriteProcessorPwrScheme(UINT ID
,
734 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
739 swprintf(Buf
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", ID
);
741 if (RegCreateKey(HKEY_LOCAL_MACHINE
, Buf
, &hKey
) != ERROR_SUCCESS
)
744 RegSetValueExW(hKey
, szPolicies
, 0, REG_BINARY
, (PBYTE
)pMachineProcessorPowerPolicy
, sizeof(MACHINE_PROCESSOR_POWER_POLICY
));
755 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
759 &hKey
) != ERROR_SUCCESS
)
761 swprintf(Buf
, L
"%i", g_LastID
);
762 RegSetValueExW(hKey
, szLastID
, 0, REG_SZ
, (PBYTE
)Buf
, strlenW(Buf
)*sizeof(WCHAR
));
767 WritePwrScheme(PUINT puiID
,
769 LPWSTR lpszDescription
,
770 PPOWER_POLICY pPowerPolicy
)
782 swprintf(Buf
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID
);
784 if (RegCreateKey(HKEY_CURRENT_USER
, Buf
, &hKey
) != ERROR_SUCCESS
)
787 RegSetValueExW(hKey
, szName
, 0, REG_SZ
, (PBYTE
)lpszName
, strlenW(lpszName
)*sizeof(WCHAR
));
788 RegSetValueExW(hKey
, szDescription
, 0, REG_SZ
, (PBYTE
)lpszDescription
, strlenW(lpszDescription
)*sizeof(WCHAR
));
790 return WritePwrPolicy(puiID
, pPowerPolicy
);
794 CheckPowerActionPolicy(PPOWER_ACTION_POLICY pPAP
, SYSTEM_POWER_CAPABILITIES PowerCaps
)
797 Lohnegrim: this is an Helperfunction, it checks if the POWERACTIONPOLICY is valid
798 Also, if the System dosn't support Hipernation, then change the PowerAction
800 switch (pPAP
->Action
)
802 case PowerActionNone
:
804 case PowerActionReserved
:
805 if (PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
)
806 pPAP
->Action
= PowerActionSleep
;
808 pPAP
->Action
= PowerActionReserved
;
809 case PowerActionSleep
:
811 case PowerActionHibernate
:
812 if (!(PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
))
814 if (PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
)
815 pPAP
->Action
= PowerActionSleep
;
817 pPAP
->Action
= PowerActionReserved
;
819 case PowerActionShutdown
:
820 case PowerActionShutdownReset
:
821 case PowerActionShutdownOff
:
822 case PowerActionWarmEject
:
825 SetLastError(ERROR_INVALID_DATA
);
831 FixSystemPowerState(PSYSTEM_POWER_STATE Psps
, SYSTEM_POWER_CAPABILITIES PowerCaps
)
833 //Lohnegrim: If the System dosn't support the Powerstates, then we have to change them
834 if (!PowerCaps
.SystemS1
&& *Psps
== PowerSystemSleeping1
)
835 *Psps
= PowerSystemSleeping2
;
836 if (!PowerCaps
.SystemS2
&& *Psps
== PowerSystemSleeping2
)
837 *Psps
= PowerSystemSleeping3
;
838 if (!PowerCaps
.SystemS3
&& *Psps
== PowerSystemSleeping3
)
839 *Psps
= PowerSystemHibernate
;
840 if (!(PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
) && *Psps
== PowerSystemHibernate
)
841 *Psps
= PowerSystemSleeping2
;
842 if (!PowerCaps
.SystemS1
&& *Psps
== PowerSystemSleeping1
)
843 *Psps
= PowerSystemSleeping2
;
844 if (!PowerCaps
.SystemS2
&& *Psps
== PowerSystemSleeping2
)
845 *Psps
= PowerSystemSleeping3
;
846 if (!PowerCaps
.SystemS3
&& *Psps
== PowerSystemSleeping3
)
847 *Psps
= PowerSystemShutdown
;
852 ValidatePowerPolicies(PGLOBAL_POWER_POLICY pGPP
, PPOWER_POLICY pPP
)
854 SYSTEM_POWER_CAPABILITIES PowerCaps
;
858 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
859 ret
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
860 if (ret
!= STATUS_SUCCESS
)
862 SetLastError(RtlNtStatusToDosError(ret
));
868 if (pGPP
->user
.Revision
!= 1 || pGPP
->mach
.Revision
!= 1)
870 SetLastError(ERROR_REVISION_MISMATCH
);
873 if (pGPP
->mach
.LidOpenWakeAc
== PowerSystemUnspecified
)
875 SetLastError(ERROR_GEN_FAILURE
);
878 if ((int)pGPP
->mach
.LidOpenWakeAc
>= PowerSystemShutdown
)
880 SetLastError(ERROR_GEN_FAILURE
);
883 if (pGPP
->mach
.LidOpenWakeDc
< PowerSystemWorking
)
885 SetLastError(ERROR_GEN_FAILURE
);
888 if ((int)pGPP
->mach
.LidOpenWakeDc
>= PowerSystemShutdown
)
890 SetLastError(ERROR_GEN_FAILURE
);
893 //Lohnegrim: unneeded
894 /*if ((pGPP->mach.LidOpenWakeDc < PowerSystemWorking) || (pGPP->mach.LidOpenWakeDc >= PowerSystemMaximum))
896 SetLastError(ERROR_GEN_FAILURE);
899 if (!CheckPowerActionPolicy(&pGPP
->user
.LidCloseAc
,PowerCaps
))
903 if (!CheckPowerActionPolicy(&pGPP
->user
.LidCloseDc
,PowerCaps
))
907 if (!CheckPowerActionPolicy(&pGPP
->user
.PowerButtonAc
,PowerCaps
))
911 if (!CheckPowerActionPolicy(&pGPP
->user
.PowerButtonDc
,PowerCaps
))
915 if (!CheckPowerActionPolicy(&pGPP
->user
.SleepButtonAc
,PowerCaps
))
919 if (!CheckPowerActionPolicy(&pGPP
->user
.SleepButtonDc
,PowerCaps
))
923 //Lohnegrim: The BroadcastCapacityResolution presents the Powerlevel in Percent, if invalid set th 100 == FULL
924 if ((pGPP
->mach
.BroadcastCapacityResolution
< 0) || (pGPP
->mach
.BroadcastCapacityResolution
> 100))
925 pGPP
->mach
.BroadcastCapacityResolution
=100;
927 //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
928 //pGPP->user.DischargePolicy[1].PowerPolicy.EventCode = pGPP->user.DischargePolicy[1].PowerPolicy.EventCode | 0x010000;
929 //pGPP->user.DischargePolicy[2].PowerPolicy.EventCode = pGPP->user.DischargePolicy[2].PowerPolicy.EventCode | 0x020000;
930 //pGPP->user.DischargePolicy[3].PowerPolicy.EventCode = pGPP->user.DischargePolicy[3].PowerPolicy.EventCode | 0x030000;
932 FixSystemPowerState(&pGPP
->mach
.LidOpenWakeAc
,PowerCaps
);
933 FixSystemPowerState(&pGPP
->mach
.LidOpenWakeDc
,PowerCaps
);
939 if (pPP
->user
.Revision
!= 1 || pPP
->mach
.Revision
!= 1)
941 SetLastError(ERROR_REVISION_MISMATCH
);
945 //Lohnegrim: unneeded
946 //if (pPP->mach.MinSleepAc < PowerSystemWorking)
948 // SetLastError(ERROR_GEN_FAILURE);
951 if ((int)pPP
->mach
.MinSleepAc
>= PowerSystemShutdown
)
953 SetLastError(ERROR_GEN_FAILURE
);
956 //Lohnegrim: unneeded
957 //if (pPP->mach.MinSleepDc < PowerSystemWorking)
959 // SetLastError(ERROR_GEN_FAILURE);
962 if ((int)pPP
->mach
.MinSleepDc
>= PowerSystemShutdown
)
964 SetLastError(ERROR_GEN_FAILURE
);
967 if (pPP
->mach
.ReducedLatencySleepAc
== PowerSystemUnspecified
)
969 SetLastError(ERROR_GEN_FAILURE
);
972 if ((int)pPP
->mach
.ReducedLatencySleepAc
>= PowerSystemShutdown
)
974 SetLastError(ERROR_GEN_FAILURE
);
977 if (pPP
->mach
.ReducedLatencySleepDc
< PowerSystemWorking
)
979 SetLastError(ERROR_GEN_FAILURE
);
982 if ((int)pPP
->mach
.ReducedLatencySleepDc
>= PowerSystemShutdown
)
984 SetLastError(ERROR_GEN_FAILURE
);
988 if (!CheckPowerActionPolicy(&pPP
->mach
.OverThrottledAc
,PowerCaps
))
992 if (!CheckPowerActionPolicy(&pPP
->mach
.OverThrottledDc
,PowerCaps
))
996 if (!CheckPowerActionPolicy(&pPP
->user
.IdleAc
,PowerCaps
))
1000 if (!CheckPowerActionPolicy(&pPP
->user
.IdleDc
,PowerCaps
))
1004 if (pPP
->user
.MaxSleepAc
< PowerSystemWorking
)
1006 SetLastError(ERROR_GEN_FAILURE
);
1009 //Lohnegrim: unneeded
1010 /*if ((int)pPP->user.MaxSleepAc > PowerSystemShutdown)
1012 SetLastError(ERROR_GEN_FAILURE);
1015 if (pPP
->user
.MaxSleepDc
< PowerSystemWorking
)
1017 SetLastError(ERROR_GEN_FAILURE
);
1020 //Lohnegrim: unneeded
1021 /*if ((int)pPP->user.MaxSleepDc >= PowerSystemShutdown)
1023 SetLastError(ERROR_GEN_FAILURE);
1026 if (PowerCaps
.SystemS1
)
1028 pPP
->mach
.MinSleepAc
=PowerSystemSleeping1
;
1029 pPP
->mach
.MinSleepDc
=PowerSystemSleeping1
;
1031 else if (PowerCaps
.SystemS2
)
1033 pPP
->mach
.MinSleepAc
=PowerSystemSleeping2
;
1034 pPP
->mach
.MinSleepDc
=PowerSystemSleeping2
;
1036 else if (PowerCaps
.SystemS3
)
1038 pPP
->mach
.MinSleepAc
=PowerSystemSleeping3
;
1039 pPP
->mach
.MinSleepDc
=PowerSystemSleeping3
;
1042 if (PowerCaps
.SystemS4
)
1044 pPP
->user
.MaxSleepAc
=PowerSystemSleeping3
;
1045 pPP
->user
.MaxSleepDc
=PowerSystemSleeping3
;
1047 else if (PowerCaps
.SystemS3
)
1049 pPP
->user
.MaxSleepAc
=PowerSystemSleeping2
;
1050 pPP
->user
.MaxSleepDc
=PowerSystemSleeping2
;
1052 else if (PowerCaps
.SystemS1
)
1054 pPP
->user
.MaxSleepAc
=PowerSystemSleeping1
;
1055 pPP
->user
.MaxSleepDc
=PowerSystemSleeping1
;
1057 //Lohnegrim: I dont know where to get this info from, so i removed it
1058 //pPP->user.OptimizeForPowerAc=TRUE;
1059 //pPP->user.OptimizeForPowerDc=TRUE;
1061 FixSystemPowerState(&pPP
->mach
.ReducedLatencySleepAc
,PowerCaps
);
1062 FixSystemPowerState(&pPP
->mach
.ReducedLatencySleepDc
,PowerCaps
);
1065 SetLastError(ERROR_SUCCESS
);
1069 BOOLEAN WINAPI
WritePwrPolicy(PUINT puiID
, PPOWER_POLICY pPowerPolicy
)
1071 WCHAR Buf
[MAX_PATH
];
1074 swprintf(Buf
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID
);
1076 if (RegCreateKey(HKEY_CURRENT_USER
, Buf
, &hKey
) != ERROR_SUCCESS
)
1079 RegSetValueExW(hKey
, szPolicies
, 0, REG_BINARY
, (const unsigned char *)&pPowerPolicy
->user
, sizeof(USER_POWER_POLICY
));
1082 swprintf(Buf
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%i", *puiID
);
1084 if (RegCreateKey(HKEY_LOCAL_MACHINE
, Buf
, &hKey
) != ERROR_SUCCESS
)
1087 RegSetValueExW(hKey
, szPolicies
, 0, REG_BINARY
, (const unsigned char *)&pPowerPolicy
->mach
, sizeof(MACHINE_POWER_POLICY
));
1094 DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1098 case DLL_PROCESS_ATTACH
:
1103 DisableThreadLibraryCalls(hinstDLL
);
1105 Err
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
1107 if (Err
!= ERROR_SUCCESS
)
1109 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
1113 WCHAR lpValue
[MAX_PATH
];
1114 DWORD cbValue
= sizeof(lpValue
);
1116 Err
= RegQueryValueExW(hKey
, szLastID
, 0, 0, (BYTE
*)lpValue
, &cbValue
);
1117 if (Err
== ERROR_SUCCESS
)
1119 g_LastID
= _wtoi(lpValue
);
1123 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
1128 PPRegSemaphore
= CreateSemaphoreW(NULL
, 1, 1, szSemaphoreName
);
1129 if (PPRegSemaphore
== NULL
)
1131 ERR("Couldn't create Semaphore: %d\n", GetLastError());
1136 case DLL_PROCESS_DETACH
:
1137 CloseHandle(PPRegSemaphore
);