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
27 #define NTOS_MODE_USER
28 #include <ndk/pofuncs.h>
29 #include <ndk/rtlfuncs.h>
30 #include <ndk/setypes.h>
32 #include <wine/debug.h>
33 #include <wine/unicode.h>
35 WINE_DEFAULT_DEBUG_CHANNEL(powrprof
);
38 static const WCHAR szPowerCfgSubKey
[] =
39 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg";
40 static const WCHAR szUserPowerConfigSubKey
[] =
41 L
"Control Panel\\PowerCfg";
42 static const WCHAR szCurrentPowerPolicies
[] =
43 L
"CurrentPowerPolicy";
44 static const WCHAR szPolicies
[] = L
"Policies";
45 static const WCHAR szName
[] = L
"Name";
46 static const WCHAR szDescription
[] = L
"Description";
47 static const WCHAR szSemaphoreName
[] = L
"PowerProfileRegistrySemaphore";
48 static const WCHAR szDiskMax
[] = L
"DiskSpindownMax";
49 static const WCHAR szDiskMin
[] = L
"DiskSpindownMin";
50 static const WCHAR szLastID
[] = L
"LastID";
52 UINT g_LastID
= (UINT
)-1;
54 BOOLEAN WINAPI
WritePwrPolicy(PUINT puiID
, PPOWER_POLICY pPowerPolicy
);
56 HANDLE PPRegSemaphore
= NULL
;
59 CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel
,
61 ULONG nInputBufferSize
,
63 ULONG nOutputBufferSize
)
67 //Lohnegrim: In order to get the right results, we have to adjust our Privileges
68 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
69 RtlAdjustPrivilege(SE_CREATE_PAGEFILE_PRIVILEGE
, TRUE
, FALSE
, &old
);
71 return NtPowerInformation(InformationLevel
,
79 CanUserWritePwrScheme(VOID
)
86 Ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
87 if (Ret
!= ERROR_SUCCESS
)
89 TRACE("RegOpenKeyEx failed: %d\n", Ret
);
99 DeletePwrScheme(UINT uiIndex
)
105 swprintf(Buf
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%d", uiIndex
);
107 if (!GetActivePwrScheme(&Current
))
110 if (Current
== uiIndex
)
112 SetLastError(ERROR_ACCESS_DENIED
);
116 Err
= RegDeleteKey(HKEY_CURRENT_USER
, (LPCTSTR
)Buf
);
117 if (Err
!= ERROR_SUCCESS
)
119 TRACE("RegDeleteKey failed: %d\n", Err
);
128 POWRPROF_GetUserPowerPolicy(LPWSTR szNum
,
129 PUSER_POWER_POLICY puserPwrPolicy
,
130 DWORD cchName
, LPWSTR szName
,
131 DWORD cchDesc
, LPWSTR szDesc
)
136 WCHAR szPath
[MAX_PATH
];
139 swprintf(szPath
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%s", szNum
);
141 Err
= RegOpenKeyExW(HKEY_CURRENT_USER
, szPath
, 0, KEY_READ
, &hSubKey
);
142 if (Err
!= ERROR_SUCCESS
)
144 ERR("RegOpenKeyExW failed: %d\n", Err
);
149 dwSize
= cchName
* sizeof(WCHAR
);
150 Err
= RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szName
, &dwSize
);
151 if (Err
!= ERROR_SUCCESS
)
153 ERR("RegQueryValueExW failed: %d\n", Err
);
158 dwSize
= cchDesc
* sizeof(WCHAR
);
159 Err
= RegQueryValueExW(hSubKey
, L
"Description", NULL
, NULL
, (LPBYTE
)szDesc
, &dwSize
);
160 if (Err
!= ERROR_SUCCESS
)
162 ERR("RegQueryValueExW failed: %d\n", Err
);
167 dwSize
= sizeof(USER_POWER_POLICY
);
168 Err
= RegQueryValueExW(hSubKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)puserPwrPolicy
, &dwSize
);
169 if (Err
!= ERROR_SUCCESS
)
171 ERR("RegQueryValueExW failed: %d\n", Err
);
179 RegCloseKey(hSubKey
);
185 POWRPROF_GetMachinePowerPolicy(LPWSTR szNum
, PMACHINE_POWER_POLICY pmachinePwrPolicy
)
189 WCHAR szPath
[MAX_PATH
];
192 swprintf(szPath
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%s", szNum
);
194 Err
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPath
, 0, KEY_READ
, &hKey
);
195 if (Err
!= ERROR_SUCCESS
)
197 ERR("RegOpenKeyExW failed: %d\n", Err
);
202 dwSize
= sizeof(MACHINE_POWER_POLICY
);
203 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)pmachinePwrPolicy
, &dwSize
);
205 if (Err
!= ERROR_SUCCESS
)
207 ERR("RegQueryValueExW failed: %d\n", Err
);
219 EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc
,
224 DWORD dwSize
, dwNameSize
= MAX_PATH
, dwDescSize
= MAX_PATH
, dwIndex
= 0;
225 WCHAR szNum
[3 + 1], szName
[MAX_PATH
], szDesc
[MAX_PATH
];
226 POWER_POLICY PwrPolicy
;
227 USER_POWER_POLICY userPwrPolicy
;
228 MACHINE_POWER_POLICY machinePwrPolicy
;
229 BOOLEAN bRet
= FALSE
;
231 if (!lpfnPwrSchemesEnumProc
)
233 SetLastError(ERROR_INVALID_PARAMETER
);
237 Err
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg\\PowerPolicies", 0, KEY_READ
, &hKey
);
238 if (Err
!= ERROR_SUCCESS
)
240 ERR("RegOpenKeyW failed: %d\n", Err
);
245 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
247 dwSize
= sizeof(szNum
) / sizeof(WCHAR
);
249 while (RegEnumKeyExW(hKey
, dwIndex
, szNum
, &dwSize
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
251 if (!POWRPROF_GetUserPowerPolicy(szNum
, &userPwrPolicy
,
255 WARN("POWRPROF_GetUserPowerPolicy failed\n");
259 if (!POWRPROF_GetMachinePowerPolicy(szNum
, &machinePwrPolicy
))
261 WARN("POWRPROF_GetMachinePowerPolicy failed\n");
265 memcpy(&PwrPolicy
.user
, &userPwrPolicy
, sizeof(USER_POWER_POLICY
));
266 memcpy(&PwrPolicy
.mach
, &machinePwrPolicy
, sizeof(MACHINE_POWER_POLICY
));
268 if (!lpfnPwrSchemesEnumProc(_wtoi(szNum
), dwNameSize
, szName
, dwDescSize
, szDesc
, &PwrPolicy
, lParam
))
273 dwSize
= sizeof(szNum
) / sizeof(WCHAR
);
279 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
285 GetActivePwrScheme(PUINT puiID
)
288 WCHAR szBuf
[MAX_PATH
];
292 TRACE("GetActivePwrScheme(%u)", puiID
);
294 Err
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg", 0, KEY_READ
, &hKey
);
295 if (Err
!= ERROR_SUCCESS
)
297 ERR("RegOpenKey failed: %d\n", Err
);
303 Err
= RegQueryValueExW(hKey
, L
"CurrentPowerPolicy",
305 (LPBYTE
)&szBuf
, &dwSize
);
306 if (Err
!= ERROR_SUCCESS
)
308 ERR("RegQueryValueEx failed: %d\n", Err
);
315 *puiID
= _wtoi(szBuf
);
321 GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
,
322 PPOWER_POLICY pPowerPolicy
)
325 SYSTEM_POWER_POLICY ACPower, DCPower;
327 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy, pPowerPolicy);
329 NtPowerInformation(SystemPowerPolicyAc, 0, 0, &ACPower, sizeof(SYSTEM_POWER_POLICY));
330 NtPowerInformation(SystemPowerPolicyDc, 0, 0, &DCPower, sizeof(SYSTEM_POWER_POLICY));
335 Lohnegrim: I don't know why this Function should call NtPowerInformation, because as far as I know,
336 it simply returns the GlobalPowerPolicy and the AktivPowerScheme!
340 if (pGlobalPowerPolicy
!= NULL
)
342 if (!ReadGlobalPwrPolicy(pGlobalPowerPolicy
))
345 if (pPowerPolicy
!= NULL
)
347 if (!GetActivePwrScheme(&uiID
))
350 if (!ReadPwrScheme(uiID
, pPowerPolicy
))
358 GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities
)
362 TRACE("(%p)\n", lpSystemPowerCapabilities
);
364 if (!lpSystemPowerCapabilities
)
366 SetLastError(ERROR_INVALID_PARAMETER
);
370 Status
= NtPowerInformation(SystemPowerCapabilities
, 0, 0, lpSystemPowerCapabilities
, sizeof(SYSTEM_POWER_CAPABILITIES
));
371 if(!NT_SUCCESS(Status
))
373 SetLastError(RtlNtStatusToDosError(Status
));
381 GetPwrDiskSpindownRange(PUINT RangeMax
, PUINT RangeMin
)
386 DWORD cbValue
= sizeof(lpValue
);
388 TRACE("(%p, %p)\n", RangeMax
, RangeMin
);
390 if (RangeMax
== NULL
|| RangeMin
== NULL
)
392 SetLastError(ERROR_INVALID_PARAMETER
);
396 WaitForSingleObject(PPRegSemaphore
, INFINITE
);
398 Ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
399 if (Ret
!= ERROR_SUCCESS
)
401 TRACE("RegOpenKeyEx failed: %d\n", Ret
);
402 TRACE("Using defaults: 3600, 3\n");
405 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
409 Ret
= RegQueryValueExW(hKey
, szDiskMax
, 0, 0, lpValue
, &cbValue
);
410 if (Ret
!= ERROR_SUCCESS
)
412 TRACE("Couldn't open DiskSpinDownMax: %d\n", Ret
);
413 TRACE("Using default: 3600\n");
418 *RangeMax
= _wtoi((LPCWSTR
)lpValue
);
421 cbValue
= sizeof(lpValue
);
423 Ret
= RegQueryValueExW(hKey
, szDiskMin
, 0, 0, lpValue
, &cbValue
);
424 if (Ret
!= ERROR_SUCCESS
)
426 TRACE("Couldn't open DiskSpinDownMin: %d\n", Ret
);
427 TRACE("Using default: 3\n");
432 *RangeMin
= _wtoi((LPCWSTR
)lpValue
);
437 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
443 IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p
)
445 FIXME("( %p) stub!\n", p
);
450 IsPwrHibernateAllowed(VOID
)
452 SYSTEM_POWER_CAPABILITIES PowerCaps
;
456 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
458 Status
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
459 if (!NT_SUCCESS(Status
))
461 SetLastError(RtlNtStatusToDosError(Status
));
465 return PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
; // IsHiberfilPresent();
469 IsPwrShutdownAllowed(VOID
)
471 SYSTEM_POWER_CAPABILITIES PowerCaps
;
475 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
477 Status
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
478 if (!NT_SUCCESS(Status
))
480 SetLastError(RtlNtStatusToDosError(Status
));
484 return PowerCaps
.SystemS5
;
488 IsPwrSuspendAllowed(VOID
)
490 SYSTEM_POWER_CAPABILITIES PowerCaps
;
494 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
496 Status
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
497 if (!NT_SUCCESS(Status
))
499 SetLastError(RtlNtStatusToDosError(Status
));
503 return PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
;
507 PowerGetActiveScheme(HKEY UserRootPowerKey
, GUID
**polguid
)
509 FIXME("(%p,%p) stub!\n", UserRootPowerKey
, polguid
);
510 return ERROR_CALL_NOT_IMPLEMENTED
;
514 PowerReadDCValue(HKEY RootPowerKey
, const GUID
*Scheme
, const GUID
*SubGroup
, const GUID
*PowerSettings
, PULONG Type
, PUCHAR Buffer
, DWORD
*BufferSize
)
516 FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey
, debugstr_guid(Scheme
), debugstr_guid(SubGroup
), debugstr_guid(PowerSettings
), Type
, Buffer
, BufferSize
);
517 return ERROR_CALL_NOT_IMPLEMENTED
;
521 ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
523 GLOBAL_MACHINE_POWER_POLICY glMachPwrPolicy
;
524 GLOBAL_USER_POWER_POLICY glUserPwrPolicy
;
530 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
532 // Getting user global power policy
533 Err
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ
, &hKey
);
534 if (Err
!= ERROR_SUCCESS
)
536 ERR("RegOpenKeyW failed: %d\n", Err
);
541 dwSize
= sizeof(glUserPwrPolicy
);
542 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)&glUserPwrPolicy
, &dwSize
);
543 if (Err
!= ERROR_SUCCESS
)
545 ERR("RegQueryValueExW failed: %d\n", Err
);
552 // Getting machine global power policy
553 Err
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ
, &hKey
);
554 if (Err
!= ERROR_SUCCESS
)
556 ERR("RegOpenKeyW failed: %d\n", Err
);
561 dwSize
= sizeof(glMachPwrPolicy
);
562 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)&glMachPwrPolicy
, &dwSize
);
563 if (Err
!= ERROR_SUCCESS
)
565 ERR("RegQueryValueExW failed: %d\n", Err
);
570 memcpy(&pGlobalPowerPolicy
->user
, &glUserPwrPolicy
, sizeof(GLOBAL_USER_POWER_POLICY
));
571 memcpy(&pGlobalPowerPolicy
->mach
, &glMachPwrPolicy
, sizeof(GLOBAL_MACHINE_POWER_POLICY
));
577 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
584 ReadProcessorPwrScheme(UINT uiID
,
585 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
588 WCHAR szPath
[MAX_PATH
];
589 DWORD dwSize
= sizeof(MACHINE_PROCESSOR_POWER_POLICY
);
591 swprintf(szPath
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", uiID
);
592 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
, szPath
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
595 if (RegQueryValueExW(hKey
, szPolicies
, NULL
, 0, (LPBYTE
)pMachineProcessorPowerPolicy
, &dwSize
) == ERROR_SUCCESS
)
603 return ReadProcessorPwrScheme(0, pMachineProcessorPowerPolicy
);
610 ReadPwrScheme(UINT uiID
,
611 PPOWER_POLICY pPowerPolicy
)
613 USER_POWER_POLICY userPwrPolicy
;
614 MACHINE_POWER_POLICY machinePwrPolicy
;
615 WCHAR szNum
[16]; // max number - 999
617 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
619 swprintf(szNum
, L
"%d", uiID
);
621 if (!POWRPROF_GetUserPowerPolicy(szNum
, &userPwrPolicy
, 0, NULL
, 0, NULL
))
623 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
627 if (!POWRPROF_GetMachinePowerPolicy(szNum
, &machinePwrPolicy
))
629 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
633 memcpy(&pPowerPolicy
->user
, &userPwrPolicy
, sizeof(userPwrPolicy
));
634 memcpy(&pPowerPolicy
->mach
, &machinePwrPolicy
, sizeof(machinePwrPolicy
));
636 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
642 SetActivePwrScheme(UINT uiID
,
643 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy
,
644 PPOWER_POLICY lpPowerPolicy
)
650 if (!ReadPwrScheme(uiID
, &tmp
))
653 if (RegOpenKeyEx(HKEY_CURRENT_USER
, szUserPowerConfigSubKey
, 0, KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
656 swprintf(Buf
, L
"%i", uiID
);
658 if (RegSetValueExW(hKey
, szCurrentPowerPolicies
, 0, REG_SZ
, (PBYTE
)Buf
, strlenW(Buf
)*sizeof(WCHAR
)) != ERROR_SUCCESS
)
665 if (lpGlobalPowerPolicy
!= NULL
|| lpPowerPolicy
!= NULL
)
667 if (!ValidatePowerPolicies(lpGlobalPowerPolicy
, lpPowerPolicy
))
670 if (lpGlobalPowerPolicy
!= NULL
&& !WriteGlobalPwrPolicy(lpGlobalPowerPolicy
))
673 if (lpPowerPolicy
!= NULL
&& !WritePwrPolicy(&uiID
,lpPowerPolicy
))
681 SetSuspendState(BOOLEAN Hibernate
,
682 BOOLEAN ForceCritical
,
683 BOOLEAN DisableWakeEvent
)
685 FIXME("(%d, %d, %d) stub!\n", Hibernate
, ForceCritical
, DisableWakeEvent
);
690 WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
693 GLOBAL_USER_POWER_POLICY gupp
;
694 GLOBAL_MACHINE_POWER_POLICY gmpp
;
696 gupp
= pGlobalPowerPolicy
->user
;
697 gmpp
= pGlobalPowerPolicy
->mach
;
699 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
700 L
"Control Panel\\PowerCfg\\GlobalPowerPolicy",
703 &hKey
) != ERROR_SUCCESS
)
706 if (RegSetValueExW(hKey
, szPolicies
, 0, REG_BINARY
, (PBYTE
)&gupp
, sizeof(gupp
)) != ERROR_SUCCESS
)
714 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
715 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy",
721 if (RegSetValueExW(hKey
,szPolicies
, 0, REG_BINARY
, (PBYTE
)&gmpp
, sizeof(gmpp
)) != ERROR_SUCCESS
)
732 WriteProcessorPwrScheme(UINT ID
,
733 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
738 swprintf(Buf
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", ID
);
740 if (RegCreateKey(HKEY_LOCAL_MACHINE
, Buf
, &hKey
) != ERROR_SUCCESS
)
743 RegSetValueExW(hKey
, szPolicies
, 0, REG_BINARY
, (PBYTE
)pMachineProcessorPowerPolicy
, sizeof(MACHINE_PROCESSOR_POWER_POLICY
));
754 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
758 &hKey
) != ERROR_SUCCESS
)
760 swprintf(Buf
, L
"%i", g_LastID
);
761 RegSetValueExW(hKey
, szLastID
, 0, REG_SZ
, (PBYTE
)Buf
, strlenW(Buf
)*sizeof(WCHAR
));
766 WritePwrScheme(PUINT puiID
,
768 LPWSTR lpszDescription
,
769 PPOWER_POLICY pPowerPolicy
)
781 swprintf(Buf
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID
);
783 if (RegCreateKey(HKEY_CURRENT_USER
, Buf
, &hKey
) != ERROR_SUCCESS
)
786 RegSetValueExW(hKey
, szName
, 0, REG_SZ
, (PBYTE
)lpszName
, strlenW(lpszName
)*sizeof(WCHAR
));
787 RegSetValueExW(hKey
, szDescription
, 0, REG_SZ
, (PBYTE
)lpszDescription
, strlenW(lpszDescription
)*sizeof(WCHAR
));
789 return WritePwrPolicy(puiID
, pPowerPolicy
);
793 CheckPowerActionPolicy(PPOWER_ACTION_POLICY pPAP
, SYSTEM_POWER_CAPABILITIES PowerCaps
)
796 Lohnegrim: this is an Helper function, it checks if the POWERACTIONPOLICY is valid
797 Also, if the System doesn't support Hibernation, then change the PowerAction
799 switch (pPAP
->Action
)
801 case PowerActionNone
:
803 case PowerActionReserved
:
804 if (PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
)
805 pPAP
->Action
= PowerActionSleep
;
807 pPAP
->Action
= PowerActionReserved
;
808 case PowerActionSleep
:
810 case PowerActionHibernate
:
811 if (!(PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
))
813 if (PowerCaps
.SystemS1
|| PowerCaps
.SystemS2
|| PowerCaps
.SystemS3
)
814 pPAP
->Action
= PowerActionSleep
;
816 pPAP
->Action
= PowerActionReserved
;
818 case PowerActionShutdown
:
819 case PowerActionShutdownReset
:
820 case PowerActionShutdownOff
:
821 case PowerActionWarmEject
:
824 SetLastError(ERROR_INVALID_DATA
);
830 FixSystemPowerState(PSYSTEM_POWER_STATE Psps
, SYSTEM_POWER_CAPABILITIES PowerCaps
)
832 //Lohnegrim: If the System doesn't support the Powerstates, then we have to change them
833 if (!PowerCaps
.SystemS1
&& *Psps
== PowerSystemSleeping1
)
834 *Psps
= PowerSystemSleeping2
;
835 if (!PowerCaps
.SystemS2
&& *Psps
== PowerSystemSleeping2
)
836 *Psps
= PowerSystemSleeping3
;
837 if (!PowerCaps
.SystemS3
&& *Psps
== PowerSystemSleeping3
)
838 *Psps
= PowerSystemHibernate
;
839 if (!(PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
) && *Psps
== PowerSystemHibernate
)
840 *Psps
= PowerSystemSleeping2
;
841 if (!PowerCaps
.SystemS1
&& *Psps
== PowerSystemSleeping1
)
842 *Psps
= PowerSystemSleeping2
;
843 if (!PowerCaps
.SystemS2
&& *Psps
== PowerSystemSleeping2
)
844 *Psps
= PowerSystemSleeping3
;
845 if (!PowerCaps
.SystemS3
&& *Psps
== PowerSystemSleeping3
)
846 *Psps
= PowerSystemShutdown
;
851 ValidatePowerPolicies(PGLOBAL_POWER_POLICY pGPP
, PPOWER_POLICY pPP
)
853 SYSTEM_POWER_CAPABILITIES PowerCaps
;
857 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &old
);
858 ret
= NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
859 if (ret
!= STATUS_SUCCESS
)
861 SetLastError(RtlNtStatusToDosError(ret
));
867 if (pGPP
->user
.Revision
!= 1 || pGPP
->mach
.Revision
!= 1)
869 SetLastError(ERROR_REVISION_MISMATCH
);
872 if (pGPP
->mach
.LidOpenWakeAc
== PowerSystemUnspecified
)
874 SetLastError(ERROR_GEN_FAILURE
);
877 if ((int)pGPP
->mach
.LidOpenWakeAc
>= PowerSystemShutdown
)
879 SetLastError(ERROR_GEN_FAILURE
);
882 if (pGPP
->mach
.LidOpenWakeDc
< PowerSystemWorking
)
884 SetLastError(ERROR_GEN_FAILURE
);
887 if ((int)pGPP
->mach
.LidOpenWakeDc
>= PowerSystemShutdown
)
889 SetLastError(ERROR_GEN_FAILURE
);
892 //Lohnegrim: unneeded
893 /*if ((pGPP->mach.LidOpenWakeDc < PowerSystemWorking) || (pGPP->mach.LidOpenWakeDc >= PowerSystemMaximum))
895 SetLastError(ERROR_GEN_FAILURE);
898 if (!CheckPowerActionPolicy(&pGPP
->user
.LidCloseAc
,PowerCaps
))
902 if (!CheckPowerActionPolicy(&pGPP
->user
.LidCloseDc
,PowerCaps
))
906 if (!CheckPowerActionPolicy(&pGPP
->user
.PowerButtonAc
,PowerCaps
))
910 if (!CheckPowerActionPolicy(&pGPP
->user
.PowerButtonDc
,PowerCaps
))
914 if (!CheckPowerActionPolicy(&pGPP
->user
.SleepButtonAc
,PowerCaps
))
918 if (!CheckPowerActionPolicy(&pGPP
->user
.SleepButtonDc
,PowerCaps
))
922 //Lohnegrim: The BroadcastCapacityResolution presents the Powerlevel in Percent, if invalid set th 100 == FULL
923 if (pGPP
->mach
.BroadcastCapacityResolution
> 100)
924 pGPP
->mach
.BroadcastCapacityResolution
= 100;
926 //Lohnegrim: I have no idea, if they are really needed, or if they are specific for my System, or what they mean, so I removed them
927 //pGPP->user.DischargePolicy[1].PowerPolicy.EventCode = pGPP->user.DischargePolicy[1].PowerPolicy.EventCode | 0x010000;
928 //pGPP->user.DischargePolicy[2].PowerPolicy.EventCode = pGPP->user.DischargePolicy[2].PowerPolicy.EventCode | 0x020000;
929 //pGPP->user.DischargePolicy[3].PowerPolicy.EventCode = pGPP->user.DischargePolicy[3].PowerPolicy.EventCode | 0x030000;
931 FixSystemPowerState(&pGPP
->mach
.LidOpenWakeAc
,PowerCaps
);
932 FixSystemPowerState(&pGPP
->mach
.LidOpenWakeDc
,PowerCaps
);
938 if (pPP
->user
.Revision
!= 1 || pPP
->mach
.Revision
!= 1)
940 SetLastError(ERROR_REVISION_MISMATCH
);
944 //Lohnegrim: unneeded
945 //if (pPP->mach.MinSleepAc < PowerSystemWorking)
947 // SetLastError(ERROR_GEN_FAILURE);
950 if ((int)pPP
->mach
.MinSleepAc
>= PowerSystemShutdown
)
952 SetLastError(ERROR_GEN_FAILURE
);
955 //Lohnegrim: unneeded
956 //if (pPP->mach.MinSleepDc < PowerSystemWorking)
958 // SetLastError(ERROR_GEN_FAILURE);
961 if ((int)pPP
->mach
.MinSleepDc
>= PowerSystemShutdown
)
963 SetLastError(ERROR_GEN_FAILURE
);
966 if (pPP
->mach
.ReducedLatencySleepAc
== PowerSystemUnspecified
)
968 SetLastError(ERROR_GEN_FAILURE
);
971 if ((int)pPP
->mach
.ReducedLatencySleepAc
>= PowerSystemShutdown
)
973 SetLastError(ERROR_GEN_FAILURE
);
976 if (pPP
->mach
.ReducedLatencySleepDc
< PowerSystemWorking
)
978 SetLastError(ERROR_GEN_FAILURE
);
981 if ((int)pPP
->mach
.ReducedLatencySleepDc
>= PowerSystemShutdown
)
983 SetLastError(ERROR_GEN_FAILURE
);
987 if (!CheckPowerActionPolicy(&pPP
->mach
.OverThrottledAc
,PowerCaps
))
991 if (!CheckPowerActionPolicy(&pPP
->mach
.OverThrottledDc
,PowerCaps
))
995 if (!CheckPowerActionPolicy(&pPP
->user
.IdleAc
,PowerCaps
))
999 if (!CheckPowerActionPolicy(&pPP
->user
.IdleDc
,PowerCaps
))
1003 if (pPP
->user
.MaxSleepAc
< PowerSystemWorking
)
1005 SetLastError(ERROR_GEN_FAILURE
);
1008 //Lohnegrim: unneeded
1009 /*if ((int)pPP->user.MaxSleepAc > PowerSystemShutdown)
1011 SetLastError(ERROR_GEN_FAILURE);
1014 if (pPP
->user
.MaxSleepDc
< PowerSystemWorking
)
1016 SetLastError(ERROR_GEN_FAILURE
);
1019 //Lohnegrim: unneeded
1020 /*if ((int)pPP->user.MaxSleepDc >= PowerSystemShutdown)
1022 SetLastError(ERROR_GEN_FAILURE);
1025 if (PowerCaps
.SystemS1
)
1027 pPP
->mach
.MinSleepAc
=PowerSystemSleeping1
;
1028 pPP
->mach
.MinSleepDc
=PowerSystemSleeping1
;
1030 else if (PowerCaps
.SystemS2
)
1032 pPP
->mach
.MinSleepAc
=PowerSystemSleeping2
;
1033 pPP
->mach
.MinSleepDc
=PowerSystemSleeping2
;
1035 else if (PowerCaps
.SystemS3
)
1037 pPP
->mach
.MinSleepAc
=PowerSystemSleeping3
;
1038 pPP
->mach
.MinSleepDc
=PowerSystemSleeping3
;
1041 if (PowerCaps
.SystemS4
)
1043 pPP
->user
.MaxSleepAc
=PowerSystemSleeping3
;
1044 pPP
->user
.MaxSleepDc
=PowerSystemSleeping3
;
1046 else if (PowerCaps
.SystemS3
)
1048 pPP
->user
.MaxSleepAc
=PowerSystemSleeping2
;
1049 pPP
->user
.MaxSleepDc
=PowerSystemSleeping2
;
1051 else if (PowerCaps
.SystemS1
)
1053 pPP
->user
.MaxSleepAc
=PowerSystemSleeping1
;
1054 pPP
->user
.MaxSleepDc
=PowerSystemSleeping1
;
1056 //Lohnegrim: I don't know where to get this info from, so I removed it
1057 //pPP->user.OptimizeForPowerAc=TRUE;
1058 //pPP->user.OptimizeForPowerDc=TRUE;
1060 FixSystemPowerState(&pPP
->mach
.ReducedLatencySleepAc
,PowerCaps
);
1061 FixSystemPowerState(&pPP
->mach
.ReducedLatencySleepDc
,PowerCaps
);
1064 SetLastError(ERROR_SUCCESS
);
1068 BOOLEAN WINAPI
WritePwrPolicy(PUINT puiID
, PPOWER_POLICY pPowerPolicy
)
1070 WCHAR Buf
[MAX_PATH
];
1073 swprintf(Buf
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID
);
1075 if (RegCreateKey(HKEY_CURRENT_USER
, Buf
, &hKey
) != ERROR_SUCCESS
)
1078 RegSetValueExW(hKey
, szPolicies
, 0, REG_BINARY
, (const unsigned char *)&pPowerPolicy
->user
, sizeof(USER_POWER_POLICY
));
1081 swprintf(Buf
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%i", *puiID
);
1083 if (RegCreateKey(HKEY_LOCAL_MACHINE
, Buf
, &hKey
) != ERROR_SUCCESS
)
1086 RegSetValueExW(hKey
, szPolicies
, 0, REG_BINARY
, (const unsigned char *)&pPowerPolicy
->mach
, sizeof(MACHINE_POWER_POLICY
));
1093 DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1097 case DLL_PROCESS_ATTACH
:
1102 DisableThreadLibraryCalls(hinstDLL
);
1104 Err
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
1106 if (Err
!= ERROR_SUCCESS
)
1108 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
1112 WCHAR lpValue
[MAX_PATH
];
1113 DWORD cbValue
= sizeof(lpValue
);
1115 Err
= RegQueryValueExW(hKey
, szLastID
, 0, 0, (BYTE
*)lpValue
, &cbValue
);
1116 if (Err
== ERROR_SUCCESS
)
1118 g_LastID
= _wtoi(lpValue
);
1122 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
1127 PPRegSemaphore
= CreateSemaphoreW(NULL
, 1, 1, szSemaphoreName
);
1128 if (PPRegSemaphore
== NULL
)
1130 ERR("Couldn't create Semaphore: %d\n", GetLastError());
1135 case DLL_PROCESS_DETACH
:
1136 CloseHandle(PPRegSemaphore
);