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"
33 WINE_DEFAULT_DEBUG_CHANNEL(powrprof
);
36 static const WCHAR szPowerCfgSubKey
[] =
37 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg";
38 static const WCHAR szPolicies
[] = L
"Policies";
39 static const WCHAR szSemaphoreName
[] = L
"PowerProfileRegistrySemaphore";
40 static const WCHAR szDiskMax
[] = L
"DiskSpindownMax";
41 static const WCHAR szDiskMin
[] = L
"DiskSpindownMin";
42 static const WCHAR szLastID
[] = L
"LastID";
44 HANDLE PPRegSemaphore
= NULL
;
47 CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel
,
49 ULONG nInputBufferSize
,
51 ULONG nOutputBufferSize
)
53 return NtPowerInformation(InformationLevel
,
62 CanUserWritePwrScheme(VOID
)
66 BOOLEAN bSuccess
= TRUE
;
70 Ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
72 if (Ret
!= ERROR_SUCCESS
)
74 TRACE("RegOpenKeyEx failed: %d\n", Ret
);
85 DeletePwrScheme(UINT uiIndex
)
91 swprintf(Buf
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%d", uiIndex
);
93 if (GetActivePwrScheme(&Current
))
95 if (Current
== uiIndex
)
97 SetLastError(ERROR_ACCESS_DENIED
);
102 Err
= RegDeleteKey(HKEY_CURRENT_USER
, (LPCTSTR
) Buf
);
103 if (Err
!= ERROR_SUCCESS
)
105 TRACE("RegDeleteKey failed: %d\n", Err
);
111 SetLastError(ERROR_SUCCESS
);
122 POWRPROF_GetUserPowerPolicy(LPWSTR szNum
,
123 PUSER_POWER_POLICY puserPwrPolicy
,
124 DWORD dwName
, LPWSTR szName
,
125 DWORD dwDesc
, LPWSTR szDesc
)
130 WCHAR szPath
[MAX_PATH
];
132 swprintf(szPath
, L
"Control Panel\\PowerCfg\\PowerPolicies\\%s", szNum
);
134 Err
= RegOpenKeyW(HKEY_CURRENT_USER
, szPath
, &hSubKey
);
135 if (Err
!= ERROR_SUCCESS
)
137 ERR("RegOpenKeyW failed: %d\n", Err
);
142 dwName
= MAX_PATH
* sizeof(WCHAR
);
143 Err
= RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szName
, &dwName
);
144 if (Err
!= ERROR_SUCCESS
)
146 ERR("RegQueryValueExW failed: %d\n", Err
);
151 dwDesc
= MAX_PATH
* sizeof(WCHAR
);
152 Err
= RegQueryValueExW(hSubKey
, L
"Description", NULL
, NULL
, (LPBYTE
)szDesc
, &dwDesc
);
153 if (Err
!= ERROR_SUCCESS
)
155 ERR("RegQueryValueExW failed: %d\n", Err
);
160 dwSize
= sizeof(USER_POWER_POLICY
);
161 Err
= RegQueryValueExW(hSubKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)puserPwrPolicy
, &dwSize
);
162 if (Err
!= ERROR_SUCCESS
)
164 ERR("RegQueryValueExW failed: %d\n", Err
);
173 POWRPROF_GetMachinePowerPolicy(LPWSTR szNum
, PMACHINE_POWER_POLICY pmachinePwrPolicy
)
177 WCHAR szPath
[MAX_PATH
];
180 swprintf(szPath
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%s", szNum
);
182 Err
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szPath
, &hKey
);
183 if (Err
!= ERROR_SUCCESS
)
185 ERR("RegOpenKeyW failed: %d\n", Err
);
190 dwSize
= sizeof(MACHINE_POWER_POLICY
);
191 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)pmachinePwrPolicy
, &dwSize
);
192 if (Err
!= ERROR_SUCCESS
)
194 ERR("RegQueryValueExW failed: %d\n", Err
);
203 EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc
,
208 DWORD dwSize
, dwNameSize
= MAX_PATH
, dwDescSize
= MAX_PATH
, dwIndex
= 0;
209 WCHAR szNum
[3 + 1], szName
[MAX_PATH
], szDesc
[MAX_PATH
];
210 POWER_POLICY PwrPolicy
;
211 USER_POWER_POLICY userPwrPolicy
;
212 MACHINE_POWER_POLICY machinePwrPolicy
;
215 if (!lpfnPwrSchemesEnumProc
)
217 SetLastError(ERROR_INVALID_PARAMETER
);
221 Err
= RegOpenKeyW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg\\PowerPolicies", &hKey
);
222 if (Err
!= ERROR_SUCCESS
)
224 ERR("RegOpenKeyW failed: %d\n", Err
);
229 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
231 dwSize
= sizeof(szNum
) / sizeof(WCHAR
);
233 while (RegEnumKeyExW(hKey
, dwIndex
, szNum
, &dwSize
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
235 if (!POWRPROF_GetUserPowerPolicy(szNum
, &userPwrPolicy
,
240 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
244 if (!POWRPROF_GetMachinePowerPolicy(szNum
, &machinePwrPolicy
))
247 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
251 memcpy(&PwrPolicy
.user
, &userPwrPolicy
, sizeof(USER_POWER_POLICY
));
252 memcpy(&PwrPolicy
.mach
, &machinePwrPolicy
, sizeof(MACHINE_POWER_POLICY
));
254 if (!lpfnPwrSchemesEnumProc(_wtoi(szNum
), dwNameSize
, szName
, dwDescSize
, szDesc
, &PwrPolicy
, lParam
))
257 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
265 dwSize
= sizeof(szNum
) / sizeof(WCHAR
);
270 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
271 SetLastError(ERROR_SUCCESS
);
278 GetActivePwrScheme(PUINT puiID
)
281 WCHAR szBuf
[MAX_PATH
];
285 TRACE("GetActivePwrScheme(%u)", puiID
);
287 Err
= RegOpenKeyW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg", &hKey
);
288 if (Err
!= ERROR_SUCCESS
)
290 ERR("RegOpenKey failed: %d\n", Err
);
296 Err
= RegQueryValueExW(hKey
, L
"CurrentPowerPolicy",
298 (LPBYTE
)&szBuf
, &dwSize
);
299 if (Err
!= ERROR_SUCCESS
)
301 ERR("RegQueryValueEx failed: %d\n", Err
);
307 *puiID
= _wtoi(szBuf
);
310 SetLastError(ERROR_SUCCESS
);
316 GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
,
317 PPOWER_POLICY pPowerPolicy
)
320 SYSTEM_POWER_POLICY ACPower, DCPower;
322 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy, pPowerPolicy);
324 NtPowerInformation(SystemPowerPolicyAc, 0, 0, &ACPower, sizeof(SYSTEM_POWER_POLICY));
325 NtPowerInformation(SystemPowerPolicyDc, 0, 0, &DCPower, sizeof(SYSTEM_POWER_POLICY));
330 Lohnegrim: I dont know why this Function shoud call NtPowerInformation, becouse as far as i know,
331 it simply returns the GlobalPowerPolicy and the AktivPowerScheme!
336 if (pGlobalPowerPolicy
!= NULL
)
338 ret
= ReadGlobalPwrPolicy(pGlobalPowerPolicy
);
344 if (pPowerPolicy
!= NULL
)
346 ret
= GetActivePwrScheme(&uiID
);
351 ret
= ReadPwrScheme(uiID
,pPowerPolicy
);
362 GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities
)
366 TRACE("(%p)\n", lpSystemPowerCapabilities
);
368 if (!lpSystemPowerCapabilities
)
370 SetLastError(ERROR_INVALID_PARAMETER
);
374 Ret
= NtPowerInformation(SystemPowerCapabilities
, 0, 0, lpSystemPowerCapabilities
, sizeof(SYSTEM_POWER_CAPABILITIES
));
376 SetLastError(RtlNtStatusToDosError(Ret
));
378 if (Ret
== STATUS_SUCCESS
)
386 GetPwrDiskSpindownRange(PUINT RangeMax
, PUINT RangeMin
)
391 DWORD cbValue
= sizeof(lpValue
);
393 TRACE("(%p, %p)\n", RangeMax
, RangeMin
);
395 if (RangeMax
== NULL
|| RangeMin
== NULL
)
397 SetLastError(ERROR_INVALID_PARAMETER
);
401 SetLastError(ERROR_SUCCESS
);
403 WaitForSingleObject(PPRegSemaphore
, INFINITE
);
405 Ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
406 if (Ret
!= ERROR_SUCCESS
)
408 TRACE("RegOpenKeyEx failed: %d\n", Ret
);
409 TRACE("Using defaults: 3600, 3\n");
412 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
416 Ret
= RegQueryValueExW(hKey
, szDiskMax
, 0, 0, lpValue
, &cbValue
);
417 if (Ret
!= ERROR_SUCCESS
)
419 TRACE("Couldn't open DiskSpinDownMax: %d\n", Ret
);
420 TRACE("Using default: 3600\n");
425 *RangeMax
= _wtoi((LPCWSTR
)lpValue
);
428 cbValue
= sizeof(lpValue
);
430 Ret
= RegQueryValueExW(hKey
, szDiskMin
, 0, 0, lpValue
, &cbValue
);
431 if (Ret
!= ERROR_SUCCESS
)
433 TRACE("Couldn't open DiskSpinDownMin: %d\n", Ret
);
434 TRACE("Using default: 3\n");
439 *RangeMin
= _wtoi((LPCWSTR
)lpValue
);
444 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
445 SetLastError(ERROR_SUCCESS
);
452 IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p
)
454 FIXME("( %p) stub!\n", p
);
460 IsPwrHibernateAllowed(VOID
)
462 SYSTEM_POWER_CAPABILITIES PowerCaps
;
464 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
470 IsPwrShutdownAllowed(VOID
)
472 SYSTEM_POWER_CAPABILITIES PowerCaps
;
474 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
480 IsPwrSuspendAllowed(VOID
)
482 SYSTEM_POWER_CAPABILITIES PowerCaps
;
484 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
490 ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
492 GLOBAL_MACHINE_POWER_POLICY glMachPwrPolicy
;
493 GLOBAL_USER_POWER_POLICY glUserPwrPolicy
;
498 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
500 // Getting user global power policy
501 Err
= RegOpenKeyW(HKEY_CURRENT_USER
, L
"Control Panel\\PowerCfg\\GlobalPowerPolicy", &hKey
);
502 if (Err
!= ERROR_SUCCESS
)
504 ERR("RegOpenKeyW failed: %d\n", Err
);
505 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
510 dwSize
= sizeof(glUserPwrPolicy
);
511 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)&glUserPwrPolicy
, &dwSize
);
512 if (Err
!= ERROR_SUCCESS
)
514 ERR("RegQueryValueExW failed: %d\n", Err
);
515 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
522 // Getting machine global power policy
523 Err
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy", &hKey
);
524 if (Err
!= ERROR_SUCCESS
)
526 ERR("RegOpenKeyW failed: %d\n", Err
);
527 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
532 dwSize
= sizeof(glMachPwrPolicy
);
533 Err
= RegQueryValueExW(hKey
, L
"Policies", NULL
, NULL
, (LPBYTE
)&glMachPwrPolicy
, &dwSize
);
534 if (Err
!= ERROR_SUCCESS
)
536 ERR("RegQueryValueExW failed: %d\n", Err
);
537 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
544 memcpy(&pGlobalPowerPolicy
->user
, &glUserPwrPolicy
, sizeof(GLOBAL_USER_POWER_POLICY
));
545 memcpy(&pGlobalPowerPolicy
->mach
, &glMachPwrPolicy
, sizeof(GLOBAL_MACHINE_POWER_POLICY
));
547 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
548 SetLastError(ERROR_SUCCESS
);
555 ReadProcessorPwrScheme(UINT uiID
,
556 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
558 FIXME("(%d, %p) stub!\n", uiID
, pMachineProcessorPowerPolicy
);
559 SetLastError(ERROR_FILE_NOT_FOUND
);
565 ReadPwrScheme(UINT uiID
,
566 PPOWER_POLICY pPowerPolicy
)
568 USER_POWER_POLICY userPwrPolicy
;
569 MACHINE_POWER_POLICY machinePwrPolicy
;
570 WCHAR szNum
[3 + 1]; // max number - 999
572 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
574 swprintf(szNum
, L
"%d", uiID
);
576 if (!POWRPROF_GetUserPowerPolicy(szNum
, &userPwrPolicy
, 0, NULL
, 0, NULL
))
578 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
582 if (!POWRPROF_GetMachinePowerPolicy(szNum
, &machinePwrPolicy
))
584 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
588 memcpy(&pPowerPolicy
->user
, &userPwrPolicy
, sizeof(USER_POWER_POLICY
));
589 memcpy(&pPowerPolicy
->mach
, &machinePwrPolicy
, sizeof(MACHINE_POWER_POLICY
));
591 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
592 SetLastError(ERROR_SUCCESS
);
599 SetActivePwrScheme(UINT uiID
,
600 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy
,
601 PPOWER_POLICY lpPowerPolicy
)
603 FIXME("(%d, %p, %p) stub!\n", uiID
, lpGlobalPowerPolicy
, lpPowerPolicy
);
604 SetLastError(ERROR_FILE_NOT_FOUND
);
610 SetSuspendState(BOOLEAN Hibernate
,
611 BOOLEAN ForceCritical
,
612 BOOLEAN DisableWakeEvent
)
614 FIXME("(%d, %d, %d) stub!\n", Hibernate
, ForceCritical
, DisableWakeEvent
);
620 WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
623 GLOBAL_USER_POWER_POLICY gupp
;
624 GLOBAL_MACHINE_POWER_POLICY gmpp
;
626 gupp
= pGlobalPowerPolicy
->user
;
627 gmpp
= pGlobalPowerPolicy
->mach
;
629 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
630 L
"Control Panel\\PowerCfg\\GlobalPowerPolicy",
636 if (RegSetValueExW(hKey
,szPolicies
,(DWORD
)NULL
,REG_BINARY
,(const unsigned char *)&gupp
,sizeof(GLOBAL_USER_POWER_POLICY
)) == ERROR_SUCCESS
)
640 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
641 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy",
647 if (RegSetValueExW(hKey
,szPolicies
,(DWORD
)NULL
,REG_BINARY
,(const unsigned char *)&gmpp
,sizeof(GLOBAL_MACHINE_POWER_POLICY
)) == ERROR_SUCCESS
)
666 WriteProcessorPwrScheme(UINT ID
,
667 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
669 FIXME("(%d, %p) stub!\n", ID
, pMachineProcessorPowerPolicy
);
670 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
676 WritePwrScheme(PUINT puiID
,
678 LPWSTR lpszDescription
,
679 PPOWER_POLICY pPowerPolicy
)
681 FIXME("(%p, %s, %s, %p) stub!\n", puiID
, debugstr_w(lpszName
), debugstr_w(lpszDescription
), pPowerPolicy
);
682 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
688 ValidatePowerPolicies(PGLOBAL_POWER_POLICY pGPP
, PPOWER_POLICY pPP
)
690 GLOBAL_POWER_POLICY pGlobalPowerPolicy
;
691 POWER_POLICY pPowerPolicy
;
693 FIXME("(%p, %p) not fully implemented\n", pGPP
, pPP
);
695 if (!GetCurrentPowerPolicies(&pGlobalPowerPolicy
, &pPowerPolicy
))
697 ERR("GetCurrentPowerPolicies(%p, %p) failed\n", pGPP
, pPP
);
703 //memcpy(&pGPP, &pGlobalPowerPolicy, sizeof(GLOBAL_POWER_POLICY));
708 //memcpy(&pPP, &pPowerPolicy, sizeof(POWER_POLICY));
711 SetLastError(ERROR_SUCCESS
);
716 DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
718 FIXME("(%p, %d, %p) not fully implemented\n", hinstDLL
, fdwReason
, lpvReserved
);
722 case DLL_PROCESS_ATTACH
:
728 DisableThreadLibraryCalls(hinstDLL
);
730 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
732 if (r
!= ERROR_SUCCESS
)
734 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
739 DWORD cbValue
= sizeof(lpValue
);
740 r
= RegQueryValueExW(hKey
, szLastID
, 0, 0, lpValue
, &cbValue
);
741 if (r
!= ERROR_SUCCESS
)
743 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
748 PPRegSemaphore
= CreateSemaphoreW(NULL
, 1, 1, szSemaphoreName
);
749 if (PPRegSemaphore
== NULL
)
751 ERR("Couldn't create Semaphore: %d\n", GetLastError());
756 case DLL_PROCESS_DETACH
:
757 CloseHandle(PPRegSemaphore
);