1 /*
2 * Copyright (C) 2005 Benjamin Cutler
3 * Copyright (C) 2008 Dmitry Chapyshev
4 *
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.
9 *
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.
14 *
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
18 */
19
20
21 #include <stdarg.h>
22
23 #define WIN32_NO_STATUS
24 #include <windef.h>
25 #include <winbase.h>
26 #include <winreg.h>
27 #define NTOS_MODE_USER
28 #include <ndk/pofuncs.h>
29 #include <ndk/rtlfuncs.h>
30 #include <ndk/setypes.h>
31 #include <powrprof.h>
32 #include <wine/debug.h>
33 #include <wine/unicode.h>
34
35 WINE_DEFAULT_DEBUG_CHANNEL(powrprof);
36
37
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";
51
52 UINT g_LastID = (UINT)-1;
53
54 BOOLEAN WINAPI WritePwrPolicy(PUINT puiID, PPOWER_POLICY pPowerPolicy);
55
56 HANDLE PPRegSemaphore = NULL;
57
58 NTSTATUS WINAPI
CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel,PVOID lpInputBuffer,ULONG nInputBufferSize,PVOID lpOutputBuffer,ULONG nOutputBufferSize)59 CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel,
60 PVOID lpInputBuffer,
61 ULONG nInputBufferSize,
62 PVOID lpOutputBuffer,
63 ULONG nOutputBufferSize)
64 {
65 BOOLEAN old;
66
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);
70
71 return NtPowerInformation(InformationLevel,
72 lpInputBuffer,
73 nInputBufferSize,
74 lpOutputBuffer,
75 nOutputBufferSize);
76 }
77
78 BOOLEAN WINAPI
CanUserWritePwrScheme(VOID)79 CanUserWritePwrScheme(VOID)
80 {
81 HKEY hKey = NULL;
82 LONG Ret;
83
84 TRACE("()\n");
85
86 Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ | KEY_WRITE, &hKey);
87 if (Ret != ERROR_SUCCESS)
88 {
89 TRACE("RegOpenKeyEx failed: %d\n", Ret);
90 SetLastError(Ret);
91 return FALSE;
92 }
93
94 RegCloseKey(hKey);
95 return TRUE;
96 }
97
98 BOOLEAN WINAPI
DeletePwrScheme(UINT uiIndex)99 DeletePwrScheme(UINT uiIndex)
100 {
101 WCHAR Buf[MAX_PATH];
102 UINT Current;
103 LONG Err;
104
105 swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%d", uiIndex);
106
107 if (!GetActivePwrScheme(&Current))
108 return FALSE;
109
110 if (Current == uiIndex)
111 {
112 SetLastError(ERROR_ACCESS_DENIED);
113 return FALSE;
114 }
115
116 Err = RegDeleteKey(HKEY_CURRENT_USER, (LPCTSTR)Buf);
117 if (Err != ERROR_SUCCESS)
118 {
119 TRACE("RegDeleteKey failed: %d\n", Err);
120 SetLastError(Err);
121 return FALSE;
122 }
123
124 return TRUE;
125 }
126
127 static BOOLEAN
POWRPROF_GetUserPowerPolicy(LPWSTR szNum,PUSER_POWER_POLICY puserPwrPolicy,DWORD cchName,LPWSTR szName,DWORD cchDesc,LPWSTR szDesc)128 POWRPROF_GetUserPowerPolicy(LPWSTR szNum,
129 PUSER_POWER_POLICY puserPwrPolicy,
130 DWORD cchName, LPWSTR szName,
131 DWORD cchDesc, LPWSTR szDesc)
132 {
133 HKEY hSubKey = NULL;
134 DWORD dwSize;
135 LONG Err;
136 WCHAR szPath[MAX_PATH];
137 BOOL bRet = FALSE;
138
139 swprintf(szPath, L"Control Panel\\PowerCfg\\PowerPolicies\\%s", szNum);
140
141 Err = RegOpenKeyExW(HKEY_CURRENT_USER, szPath, 0, KEY_READ, &hSubKey);
142 if (Err != ERROR_SUCCESS)
143 {
144 ERR("RegOpenKeyExW failed: %d\n", Err);
145 SetLastError(Err);
146 return FALSE;
147 }
148
149 dwSize = cchName * sizeof(WCHAR);
150 Err = RegQueryValueExW(hSubKey, L"Name", NULL, NULL, (LPBYTE)szName, &dwSize);
151 if (Err != ERROR_SUCCESS)
152 {
153 ERR("RegQueryValueExW failed: %d\n", Err);
154 SetLastError(Err);
155 goto cleanup;
156 }
157
158 dwSize = cchDesc * sizeof(WCHAR);
159 Err = RegQueryValueExW(hSubKey, L"Description", NULL, NULL, (LPBYTE)szDesc, &dwSize);
160 if (Err != ERROR_SUCCESS)
161 {
162 ERR("RegQueryValueExW failed: %d\n", Err);
163 SetLastError(Err);
164 goto cleanup;
165 }
166
167 dwSize = sizeof(USER_POWER_POLICY);
168 Err = RegQueryValueExW(hSubKey, L"Policies", NULL, NULL, (LPBYTE)puserPwrPolicy, &dwSize);
169 if (Err != ERROR_SUCCESS)
170 {
171 ERR("RegQueryValueExW failed: %d\n", Err);
172 SetLastError(Err);
173 goto cleanup;
174 }
175
176 bRet = TRUE;
177
178 cleanup:
179 RegCloseKey(hSubKey);
180
181 return bRet;
182 }
183
184 static BOOLEAN
POWRPROF_GetMachinePowerPolicy(LPWSTR szNum,PMACHINE_POWER_POLICY pmachinePwrPolicy)185 POWRPROF_GetMachinePowerPolicy(LPWSTR szNum, PMACHINE_POWER_POLICY pmachinePwrPolicy)
186 {
187 HKEY hKey;
188 LONG Err;
189 WCHAR szPath[MAX_PATH];
190 DWORD dwSize;
191
192 swprintf(szPath, L"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%s", szNum);
193
194 Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey);
195 if (Err != ERROR_SUCCESS)
196 {
197 ERR("RegOpenKeyExW failed: %d\n", Err);
198 SetLastError(Err);
199 return FALSE;
200 }
201
202 dwSize = sizeof(MACHINE_POWER_POLICY);
203 Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)pmachinePwrPolicy, &dwSize);
204
205 if (Err != ERROR_SUCCESS)
206 {
207 ERR("RegQueryValueExW failed: %d\n", Err);
208 SetLastError(Err);
209 RegCloseKey(hKey);
210 return FALSE;
211 }
212
213 RegCloseKey(hKey);
214
215 return TRUE;
216 }
217
218 BOOLEAN WINAPI
EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc,LPARAM lParam)219 EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc,
220 LPARAM lParam)
221 {
222 HKEY hKey;
223 LONG Err;
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;
230
231 if (!lpfnPwrSchemesEnumProc)
232 {
233 SetLastError(ERROR_INVALID_PARAMETER);
234 return FALSE;
235 }
236
237 Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg\\PowerPolicies", 0, KEY_READ, &hKey);
238 if (Err != ERROR_SUCCESS)
239 {
240 ERR("RegOpenKeyW failed: %d\n", Err);
241 SetLastError(Err);
242 return FALSE;
243 }
244
245 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
246
247 dwSize = sizeof(szNum) / sizeof(WCHAR);
248
249 while (RegEnumKeyExW(hKey, dwIndex, szNum, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
250 {
251 if (!POWRPROF_GetUserPowerPolicy(szNum, &userPwrPolicy,
252 dwNameSize, szName,
253 dwDescSize, szDesc))
254 {
255 WARN("POWRPROF_GetUserPowerPolicy failed\n");
256 goto cleanup;
257 }
258
259 if (!POWRPROF_GetMachinePowerPolicy(szNum, &machinePwrPolicy))
260 {
261 WARN("POWRPROF_GetMachinePowerPolicy failed\n");
262 goto cleanup;
263 }
264
265 memcpy(&PwrPolicy.user, &userPwrPolicy, sizeof(USER_POWER_POLICY));
266 memcpy(&PwrPolicy.mach, &machinePwrPolicy, sizeof(MACHINE_POWER_POLICY));
267
268 if (!lpfnPwrSchemesEnumProc(_wtoi(szNum), (wcslen(szName) + 1) * sizeof(WCHAR), szName, (wcslen(szDesc) + 1) * sizeof(WCHAR), szDesc, &PwrPolicy, lParam))
269 goto cleanup;
270 else
271 bRet = TRUE;
272
273 dwSize = sizeof(szNum) / sizeof(WCHAR);
274 dwIndex++;
275 }
276
277 cleanup:
278 RegCloseKey(hKey);
279 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
280
281 return bRet;
282 }
283
284 BOOLEAN WINAPI
GetActivePwrScheme(PUINT puiID)285 GetActivePwrScheme(PUINT puiID)
286 {
287 HKEY hKey;
288 WCHAR szBuf[MAX_PATH];
289 DWORD dwSize;
290 LONG Err;
291
292 TRACE("GetActivePwrScheme(%u)", puiID);
293
294 Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg", 0, KEY_READ, &hKey);
295 if (Err != ERROR_SUCCESS)
296 {
297 ERR("RegOpenKey failed: %d\n", Err);
298 SetLastError(Err);
299 return FALSE;
300 }
301
302 dwSize = sizeof(szBuf);
303 Err = RegQueryValueExW(hKey, L"CurrentPowerPolicy",
304 NULL, NULL,
305 (LPBYTE)&szBuf, &dwSize);
306 if (Err != ERROR_SUCCESS)
307 {
308 ERR("RegQueryValueEx failed: %d\n", Err);
309 RegCloseKey(hKey);
310 SetLastError(Err);
311 return FALSE;
312 }
313
314 RegCloseKey(hKey);
315 *puiID = _wtoi(szBuf);
316
317 return TRUE;
318 }
319
320 BOOLEAN WINAPI
GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pGlobalPowerPolicy,PPOWER_POLICY pPowerPolicy)321 GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pGlobalPowerPolicy,
322 PPOWER_POLICY pPowerPolicy)
323 {
324 /*
325 SYSTEM_POWER_POLICY ACPower, DCPower;
326
327 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy, pPowerPolicy);
328
329 NtPowerInformation(SystemPowerPolicyAc, 0, 0, &ACPower, sizeof(SYSTEM_POWER_POLICY));
330 NtPowerInformation(SystemPowerPolicyDc, 0, 0, &DCPower, sizeof(SYSTEM_POWER_POLICY));
331
332 return FALSE;
333 */
334 /*
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!
337 */
338 UINT uiID;
339
340 if (pGlobalPowerPolicy != NULL)
341 {
342 if (!ReadGlobalPwrPolicy(pGlobalPowerPolicy))
343 return FALSE;
344 }
345 if (pPowerPolicy != NULL)
346 {
347 if (!GetActivePwrScheme(&uiID))
348 return FALSE;
349
350 if (!ReadPwrScheme(uiID, pPowerPolicy))
351 return FALSE;
352 }
353
354 return TRUE;
355 }
356
357 BOOLEAN WINAPI
GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities)358 GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities)
359 {
360 NTSTATUS Status;
361
362 TRACE("(%p)\n", lpSystemPowerCapabilities);
363
364 if (!lpSystemPowerCapabilities)
365 {
366 SetLastError(ERROR_INVALID_PARAMETER);
367 return FALSE;
368 }
369
370 Status = NtPowerInformation(SystemPowerCapabilities, 0, 0, lpSystemPowerCapabilities, sizeof(SYSTEM_POWER_CAPABILITIES));
371 if(!NT_SUCCESS(Status))
372 {
373 SetLastError(RtlNtStatusToDosError(Status));
374 return FALSE;
375 }
376
377 return TRUE;
378 }
379
380 BOOLEAN WINAPI
GetPwrDiskSpindownRange(PUINT RangeMax,PUINT RangeMin)381 GetPwrDiskSpindownRange(PUINT RangeMax, PUINT RangeMin)
382 {
383 HKEY hKey;
384 BYTE lpValue[40];
385 LONG Ret;
386 DWORD cbValue = sizeof(lpValue);
387
388 TRACE("(%p, %p)\n", RangeMax, RangeMin);
389
390 if (RangeMax == NULL || RangeMin == NULL)
391 {
392 SetLastError(ERROR_INVALID_PARAMETER);
393 return FALSE;
394 }
395
396 WaitForSingleObject(PPRegSemaphore, INFINITE);
397
398 Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ, &hKey);
399 if (Ret != ERROR_SUCCESS)
400 {
401 TRACE("RegOpenKeyEx failed: %d\n", Ret);
402 TRACE("Using defaults: 3600, 3\n");
403 *RangeMax = 3600;
404 *RangeMin = 3;
405 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
406 return TRUE;
407 }
408
409 Ret = RegQueryValueExW(hKey, szDiskMax, 0, 0, lpValue, &cbValue);
410 if (Ret != ERROR_SUCCESS)
411 {
412 TRACE("Couldn't open DiskSpinDownMax: %d\n", Ret);
413 TRACE("Using default: 3600\n");
414 *RangeMax = 3600;
415 }
416 else
417 {
418 *RangeMax = _wtoi((LPCWSTR)lpValue);
419 }
420
421 cbValue = sizeof(lpValue);
422
423 Ret = RegQueryValueExW(hKey, szDiskMin, 0, 0, lpValue, &cbValue);
424 if (Ret != ERROR_SUCCESS)
425 {
426 TRACE("Couldn't open DiskSpinDownMin: %d\n", Ret);
427 TRACE("Using default: 3\n");
428 *RangeMin = 3;
429 }
430 else
431 {
432 *RangeMin = _wtoi((LPCWSTR)lpValue);
433 }
434
435 RegCloseKey(hKey);
436
437 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
438
439 return TRUE;
440 }
441
442 BOOLEAN WINAPI
IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p)443 IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p)
444 {
445 FIXME("( %p) stub!\n", p);
446 return FALSE;
447 }
448
449 BOOLEAN WINAPI
IsPwrHibernateAllowed(VOID)450 IsPwrHibernateAllowed(VOID)
451 {
452 SYSTEM_POWER_CAPABILITIES PowerCaps;
453 NTSTATUS Status;
454 BOOLEAN old;
455
456 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
457
458 Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps));
459 if (!NT_SUCCESS(Status))
460 {
461 SetLastError(RtlNtStatusToDosError(Status));
462 return FALSE;
463 }
464
465 return PowerCaps.SystemS4 && PowerCaps.HiberFilePresent; // IsHiberfilPresent();
466 }
467
468 BOOLEAN WINAPI
IsPwrShutdownAllowed(VOID)469 IsPwrShutdownAllowed(VOID)
470 {
471 SYSTEM_POWER_CAPABILITIES PowerCaps;
472 NTSTATUS Status;
473 BOOLEAN old;
474
475 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
476
477 Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps));
478 if (!NT_SUCCESS(Status))
479 {
480 SetLastError(RtlNtStatusToDosError(Status));
481 return FALSE;
482 }
483
484 return PowerCaps.SystemS5;
485 }
486
487 BOOLEAN WINAPI
IsPwrSuspendAllowed(VOID)488 IsPwrSuspendAllowed(VOID)
489 {
490 SYSTEM_POWER_CAPABILITIES PowerCaps;
491 NTSTATUS Status;
492 BOOLEAN old;
493
494 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
495
496 Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps));
497 if (!NT_SUCCESS(Status))
498 {
499 SetLastError(RtlNtStatusToDosError(Status));
500 return FALSE;
501 }
502
503 return PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3;
504 }
505
506 DWORD WINAPI
PowerGetActiveScheme(HKEY UserRootPowerKey,GUID ** polguid)507 PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid)
508 {
509 FIXME("(%p,%p) stub!\n", UserRootPowerKey, polguid);
510 return ERROR_CALL_NOT_IMPLEMENTED;
511 }
512
PowerSetActiveScheme(HKEY UserRootPowerKey,GUID * polguid)513 DWORD WINAPI PowerSetActiveScheme(HKEY UserRootPowerKey, GUID *polguid)
514 {
515 FIXME("(%p,%s) stub!\n", UserRootPowerKey, wine_dbgstr_guid(polguid));
516 return ERROR_SUCCESS;
517 }
518
519 DWORD WINAPI
PowerReadDCValue(HKEY RootPowerKey,const GUID * Scheme,const GUID * SubGroup,const GUID * PowerSettings,PULONG Type,PUCHAR Buffer,DWORD * BufferSize)520 PowerReadDCValue(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, const GUID *PowerSettings, PULONG Type, PUCHAR Buffer, DWORD *BufferSize)
521 {
522 FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey, debugstr_guid(Scheme), debugstr_guid(SubGroup), debugstr_guid(PowerSettings), Type, Buffer, BufferSize);
523 return ERROR_CALL_NOT_IMPLEMENTED;
524 }
525
PowerReadFriendlyName(HKEY RootPowerKey,const GUID * Scheme,const GUID * SubGroup,const GUID * PowerSettings,UCHAR * Buffer,DWORD * BufferSize)526 DWORD WINAPI PowerReadFriendlyName(HKEY RootPowerKey, const GUID *Scheme,
527 const GUID *SubGroup, const GUID *PowerSettings, UCHAR *Buffer,
528 DWORD *BufferSize)
529 {
530 FIXME("(%p,%s,%s,%s,%p,%p) stub!\n", RootPowerKey, debugstr_guid(Scheme), debugstr_guid(SubGroup), debugstr_guid(PowerSettings), Buffer, BufferSize);
531 return ERROR_CALL_NOT_IMPLEMENTED;
532 }
533
PowerDeterminePlatformRole(void)534 POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRole(void)
535 {
536 FIXME("stub\n");
537 return PlatformRoleDesktop;
538 }
539
PowerDeterminePlatformRoleEx(ULONG version)540 POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRoleEx(ULONG version)
541 {
542 FIXME("%lu stub.\n", version);
543 return PlatformRoleDesktop;
544 }
545
PowerEnumerate(HKEY key,const GUID * scheme,const GUID * subgroup,POWER_DATA_ACCESSOR flags,ULONG index,UCHAR * buffer,DWORD * buffer_size)546 DWORD WINAPI PowerEnumerate(HKEY key, const GUID *scheme, const GUID *subgroup, POWER_DATA_ACCESSOR flags,
547 ULONG index, UCHAR *buffer, DWORD *buffer_size)
548 {
549 FIXME("(%p,%s,%s,%d,%ld,%p,%p) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup),
550 flags, index, buffer, buffer_size);
551 return ERROR_CALL_NOT_IMPLEMENTED;
552 }
553
PowerRegisterSuspendResumeNotification(DWORD flags,HANDLE recipient,PHPOWERNOTIFY handle)554 DWORD WINAPI PowerRegisterSuspendResumeNotification(DWORD flags, HANDLE recipient, PHPOWERNOTIFY handle)
555 {
556 FIXME("(0x%08lx,%p,%p) stub!\n", flags, recipient, handle);
557 *handle = (HPOWERNOTIFY)0xdeadbeef;
558 return ERROR_SUCCESS;
559 }
560
PowerUnregisterSuspendResumeNotification(HPOWERNOTIFY handle)561 DWORD WINAPI PowerUnregisterSuspendResumeNotification(HPOWERNOTIFY handle)
562 {
563 FIXME("(%p) stub!\n", handle);
564 return ERROR_SUCCESS;
565 }
566
PowerSettingRegisterNotification(const GUID * setting,DWORD flags,HANDLE recipient,PHPOWERNOTIFY handle)567 DWORD WINAPI PowerSettingRegisterNotification(const GUID *setting, DWORD flags, HANDLE recipient, PHPOWERNOTIFY handle)
568 {
569 FIXME("(%s,0x%08lx,%p,%p) stub!\n", debugstr_guid(setting), flags, recipient, handle);
570 *handle = (PHPOWERNOTIFY)0xdeadbeef;
571 return ERROR_SUCCESS;
572 }
573
PowerSettingUnregisterNotification(HPOWERNOTIFY handle)574 DWORD WINAPI PowerSettingUnregisterNotification(HPOWERNOTIFY handle)
575 {
576 FIXME("(%p) stub!\n", handle);
577 return ERROR_SUCCESS;
578 }
579
PowerWriteACValueIndex(HKEY key,const GUID * scheme,const GUID * subgroup,const GUID * setting,DWORD index)580 DWORD WINAPI PowerWriteACValueIndex(HKEY key, const GUID *scheme, const GUID *subgroup, const GUID *setting, DWORD index)
581 {
582 FIXME("(%p,%s,%s,%s,0x%08lx) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), debugstr_guid(setting), index);
583 return ERROR_SUCCESS;
584 }
585
586 #ifdef __REACTOS__
PowerWriteDCValueIndex(HKEY key,const GUID * scheme,const GUID * subgroup,const GUID * setting,DWORD index)587 DWORD WINAPI PowerWriteDCValueIndex(
588 HKEY key,
589 const GUID *scheme,
590 const GUID *subgroup,
591 const GUID *setting,
592 DWORD index
593 )
594 {
595 FIXME("(%p,%s,%s,%s,0x%08lx) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), debugstr_guid(setting), index);
596 return ERROR_SUCCESS;
597 }
598
PowerReadACValueIndex(HKEY key,const GUID * scheme,const GUID * subgroup,const GUID * setting,LPDWORD AcValueIndex)599 DWORD WINAPI PowerReadACValueIndex(
600 HKEY key,
601 const GUID *scheme,
602 const GUID *subgroup,
603 const GUID *setting,
604 LPDWORD AcValueIndex
605 )
606 {
607 FIXME("(%p,%s,%s,%s,0x%08lx) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), debugstr_guid(setting));
608 return ERROR_SUCCESS;
609 }
610
PowerReadDCValueIndex(HKEY key,const GUID * scheme,const GUID * subgroup,const GUID * setting,LPDWORD DcValuetIndex)611 DWORD WINAPI PowerReadDCValueIndex(
612 HKEY key,
613 const GUID *scheme,
614 const GUID *subgroup,
615 const GUID *setting,
616 LPDWORD DcValuetIndex
617 )
618 {
619 FIXME("(%p,%s,%s,%s,0x%08lx) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), debugstr_guid(setting));
620 return ERROR_SUCCESS;
621 }
622
623 DWORD WINAPI
PowerReadACValue(HKEY RootPowerKey,const GUID * Scheme,const GUID * SubGroup,const GUID * PowerSettings,PULONG Type,PUCHAR Buffer,DWORD * BufferSize)624 PowerReadACValue(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, const GUID *PowerSettings, PULONG Type, PUCHAR Buffer, DWORD *BufferSize)
625 {
626 FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey, debugstr_guid(Scheme), debugstr_guid(SubGroup), debugstr_guid(PowerSettings), Type, Buffer, BufferSize);
627 return ERROR_CALL_NOT_IMPLEMENTED;
628 }
629 #endif
630
631 BOOLEAN WINAPI
ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy)632 ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy)
633 {
634 GLOBAL_MACHINE_POWER_POLICY glMachPwrPolicy;
635 GLOBAL_USER_POWER_POLICY glUserPwrPolicy;
636 HKEY hKey = NULL;
637 DWORD dwSize;
638 LONG Err;
639 BOOL bRet = FALSE;
640
641 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
642
643 // Getting user global power policy
644 Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ, &hKey);
645 if (Err != ERROR_SUCCESS)
646 {
647 ERR("RegOpenKeyW failed: %d\n", Err);
648 SetLastError(Err);
649 goto cleanup;
650 }
651
652 dwSize = sizeof(glUserPwrPolicy);
653 Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)&glUserPwrPolicy, &dwSize);
654 if (Err != ERROR_SUCCESS)
655 {
656 ERR("RegQueryValueExW failed: %d\n", Err);
657 SetLastError(Err);
658 goto cleanup;
659 }
660
661 RegCloseKey(hKey);
662
663 // Getting machine global power policy
664 Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ, &hKey);
665 if (Err != ERROR_SUCCESS)
666 {
667 ERR("RegOpenKeyW failed: %d\n", Err);
668 SetLastError(Err);
669 goto cleanup;
670 }
671
672 dwSize = sizeof(glMachPwrPolicy);
673 Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)&glMachPwrPolicy, &dwSize);
674 if (Err != ERROR_SUCCESS)
675 {
676 ERR("RegQueryValueExW failed: %d\n", Err);
677 SetLastError(Err);
678 goto cleanup;
679 }
680
681 memcpy(&pGlobalPowerPolicy->user, &glUserPwrPolicy, sizeof(GLOBAL_USER_POWER_POLICY));
682 memcpy(&pGlobalPowerPolicy->mach, &glMachPwrPolicy, sizeof(GLOBAL_MACHINE_POWER_POLICY));
683 bRet = TRUE;
684
685 cleanup:
686 if(hKey)
687 RegCloseKey(hKey);
688 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
689
690 return bRet;
691 }
692
693
694 BOOLEAN WINAPI
ReadProcessorPwrScheme(UINT uiID,PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy)695 ReadProcessorPwrScheme(UINT uiID,
696 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy)
697 {
698 HKEY hKey;
699 WCHAR szPath[MAX_PATH];
700 DWORD dwSize = sizeof(MACHINE_PROCESSOR_POWER_POLICY);
701
702 swprintf(szPath, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", uiID);
703 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
704 return FALSE;
705
706 if (RegQueryValueExW(hKey, szPolicies, NULL, 0, (LPBYTE)pMachineProcessorPowerPolicy, &dwSize) == ERROR_SUCCESS)
707 {
708 RegCloseKey(hKey);
709 return TRUE;
710 }
711
712 RegCloseKey(hKey);
713 if (uiID != 0)
714 return ReadProcessorPwrScheme(0, pMachineProcessorPowerPolicy);
715
716 return FALSE;
717 }
718
719
720 BOOLEAN WINAPI
ReadPwrScheme(UINT uiID,PPOWER_POLICY pPowerPolicy)721 ReadPwrScheme(UINT uiID,
722 PPOWER_POLICY pPowerPolicy)
723 {
724 USER_POWER_POLICY userPwrPolicy;
725 MACHINE_POWER_POLICY machinePwrPolicy;
726 WCHAR szNum[16]; // max number - 999
727
728 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
729
730 swprintf(szNum, L"%d", uiID);
731
732 if (!POWRPROF_GetUserPowerPolicy(szNum, &userPwrPolicy, 0, NULL, 0, NULL))
733 {
734 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
735 return FALSE;
736 }
737
738 if (!POWRPROF_GetMachinePowerPolicy(szNum, &machinePwrPolicy))
739 {
740 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
741 return FALSE;
742 }
743
744 memcpy(&pPowerPolicy->user, &userPwrPolicy, sizeof(userPwrPolicy));
745 memcpy(&pPowerPolicy->mach, &machinePwrPolicy, sizeof(machinePwrPolicy));
746
747 ReleaseSemaphore(PPRegSemaphore, 1, NULL);
748
749 return TRUE;
750 }
751
752 BOOLEAN WINAPI
SetActivePwrScheme(UINT uiID,PGLOBAL_POWER_POLICY lpGlobalPowerPolicy,PPOWER_POLICY lpPowerPolicy)753 SetActivePwrScheme(UINT uiID,
754 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy,
755 PPOWER_POLICY lpPowerPolicy)
756 {
757 POWER_POLICY tmp;
758 HKEY hKey;
759 WCHAR Buf[16];
760
761 if (!ReadPwrScheme(uiID, &tmp))
762 return FALSE;
763
764 if (RegOpenKeyEx(HKEY_CURRENT_USER, szUserPowerConfigSubKey, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
765 return FALSE;
766
767 swprintf(Buf, L"%i", uiID);
768
769 if (RegSetValueExW(hKey, szCurrentPowerPolicies, 0, REG_SZ, (PBYTE)Buf, strlenW(Buf)*sizeof(WCHAR)) != ERROR_SUCCESS)
770 {
771 RegCloseKey(hKey);
772 return FALSE;
773 }
774 RegCloseKey(hKey);
775
776 if (lpGlobalPowerPolicy != NULL || lpPowerPolicy != NULL)
777 {
778 if (!ValidatePowerPolicies(lpGlobalPowerPolicy, lpPowerPolicy))
779 return FALSE;
780
781 if (lpGlobalPowerPolicy != NULL && !WriteGlobalPwrPolicy(lpGlobalPowerPolicy))
782 return FALSE;
783
784 if (lpPowerPolicy != NULL && !WritePwrPolicy(&uiID,lpPowerPolicy))
785 return FALSE;
786 }
787
788 return TRUE;
789 }
790
791 BOOLEAN WINAPI
SetSuspendState(BOOLEAN Hibernate,BOOLEAN ForceCritical,BOOLEAN DisableWakeEvent)792 SetSuspendState(BOOLEAN Hibernate,
793 BOOLEAN ForceCritical,
794 BOOLEAN DisableWakeEvent)
795 {
796 FIXME("(%d, %d, %d) stub!\n", Hibernate, ForceCritical, DisableWakeEvent);
797 return TRUE;
798 }
799
800 BOOLEAN WINAPI
WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy)801 WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy)
802 {
803 HKEY hKey;
804 GLOBAL_USER_POWER_POLICY gupp;
805 GLOBAL_MACHINE_POWER_POLICY gmpp;
806
807 gupp = pGlobalPowerPolicy->user;
808 gmpp = pGlobalPowerPolicy->mach;
809
810 if (RegOpenKeyEx(HKEY_CURRENT_USER,
811 L"Control Panel\\PowerCfg\\GlobalPowerPolicy",
812 0,
813 KEY_WRITE,
814 &hKey) != ERROR_SUCCESS)
815 return FALSE;
816
817 if (RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (PBYTE)&gupp, sizeof(gupp)) != ERROR_SUCCESS)
818 {
819 RegCloseKey(hKey);
820 return FALSE;
821 }
822
823 RegCloseKey(hKey);
824
825 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
826 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy",
827 0,
828 KEY_ALL_ACCESS,
829 &hKey))
830 return FALSE;
831
832 if (RegSetValueExW(hKey,szPolicies, 0, REG_BINARY, (PBYTE)&gmpp, sizeof(gmpp)) != ERROR_SUCCESS)
833 {
834 RegCloseKey(hKey);
835 return FALSE;
836 }
837
838 RegCloseKey(hKey);
839 return TRUE;
840 }
841
842 BOOLEAN WINAPI
WriteProcessorPwrScheme(UINT ID,PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy)843 WriteProcessorPwrScheme(UINT ID,
844 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy)
845 {
846 WCHAR Buf[MAX_PATH];
847 HKEY hKey;
848
849 swprintf(Buf, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", ID);
850
851 if (RegCreateKey(HKEY_LOCAL_MACHINE, Buf, &hKey) != ERROR_SUCCESS)
852 return FALSE;
853
854 RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (PBYTE)pMachineProcessorPowerPolicy, sizeof(MACHINE_PROCESSOR_POWER_POLICY));
855 RegCloseKey(hKey);
856 return TRUE;
857 }
858
859 static VOID
SetLastID(VOID)860 SetLastID(VOID)
861 {
862 WCHAR Buf[16];
863 HKEY hKey;
864
865 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
866 szPowerCfgSubKey,
867 0,
868 KEY_WRITE,
869 &hKey) != ERROR_SUCCESS)
870 return;
871 swprintf(Buf, L"%i", g_LastID);
872 RegSetValueExW(hKey, szLastID, 0, REG_SZ, (PBYTE)Buf, strlenW(Buf)*sizeof(WCHAR));
873 RegCloseKey(hKey);
874 }
875
876 BOOLEAN WINAPI
WritePwrScheme(PUINT puiID,LPWSTR lpszName,LPWSTR lpszDescription,PPOWER_POLICY pPowerPolicy)877 WritePwrScheme(PUINT puiID,
878 LPWSTR lpszName,
879 LPWSTR lpszDescription,
880 PPOWER_POLICY pPowerPolicy)
881 {
882 WCHAR Buf[MAX_PATH];
883 HKEY hKey;
884
885 if (*puiID == -1)
886 {
887 g_LastID++;
888 *puiID = g_LastID;
889 SetLastID();
890 }
891
892 swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID);
893
894 if (RegCreateKey(HKEY_CURRENT_USER, Buf, &hKey) != ERROR_SUCCESS)
895 return FALSE;
896
897 RegSetValueExW(hKey, szName, 0, REG_SZ, (PBYTE)lpszName, strlenW(lpszName)*sizeof(WCHAR));
898 RegSetValueExW(hKey, szDescription, 0, REG_SZ, (PBYTE)lpszDescription, strlenW(lpszDescription)*sizeof(WCHAR));
899 RegCloseKey(hKey);
900 return WritePwrPolicy(puiID, pPowerPolicy);
901 }
902
903 static BOOLEAN
CheckPowerActionPolicy(PPOWER_ACTION_POLICY pPAP,SYSTEM_POWER_CAPABILITIES PowerCaps)904 CheckPowerActionPolicy(PPOWER_ACTION_POLICY pPAP, SYSTEM_POWER_CAPABILITIES PowerCaps)
905 {
906 /*
907 Lohnegrim: this is an Helper function, it checks if the POWERACTIONPOLICY is valid
908 Also, if the System doesn't support Hibernation, then change the PowerAction
909 */
910 switch (pPAP->Action)
911 {
912 case PowerActionNone:
913 return TRUE;
914 case PowerActionReserved:
915 if (PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3)
916 pPAP->Action = PowerActionSleep;
917 else
918 pPAP->Action = PowerActionReserved;
919 case PowerActionSleep:
920 return TRUE;
921 case PowerActionHibernate:
922 if (!(PowerCaps.SystemS4 && PowerCaps.HiberFilePresent))
923 {
924 if (PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3)
925 pPAP->Action = PowerActionSleep;
926 else
927 pPAP->Action = PowerActionReserved;
928 }
929 case PowerActionShutdown:
930 case PowerActionShutdownReset:
931 case PowerActionShutdownOff:
932 case PowerActionWarmEject:
933 return TRUE;
934 default:
935 SetLastError(ERROR_INVALID_DATA);
936 return FALSE;
937 };
938 }
939
940 /**
941 * @brief
942 * Creates a security descriptor for the power
943 * management registry semaphore.
944 *
945 * @param[out] PowrProfSd
946 * A pointer to an allocated security descriptor
947 * for the semaphore.
948 *
949 * @return
950 * Returns TRUE if the function succeeds, otherwise
951 * FALSE is returned.
952 *
953 * @remarks
954 * Authenticated users are only given a subset of specific
955 * rights for the semaphore access, local system and admins
956 * have full power.
957 */
958 static BOOLEAN
CreatePowrProfSemaphoreSecurity(_Out_ PSECURITY_DESCRIPTOR * PowrProfSd)959 CreatePowrProfSemaphoreSecurity(_Out_ PSECURITY_DESCRIPTOR *PowrProfSd)
960 {
961 BOOLEAN Success = FALSE;
962 PACL Dacl;
963 ULONG DaclSize, RelSDSize = 0;
964 PSID AuthenticatedUsersSid = NULL, SystemSid = NULL, AdminsSid = NULL;
965 SECURITY_DESCRIPTOR AbsSd;
966 PSECURITY_DESCRIPTOR RelSd = NULL;
967 static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
968
969 if (!AllocateAndInitializeSid(&NtAuthority,
970 1,
971 SECURITY_AUTHENTICATED_USER_RID,
972 0, 0, 0, 0, 0, 0, 0,
973 &AuthenticatedUsersSid))
974 {
975 return FALSE;
976 }
977
978 if (!AllocateAndInitializeSid(&NtAuthority,
979 1,
980 SECURITY_LOCAL_SYSTEM_RID,
981 0, 0, 0, 0, 0, 0, 0,
982 &SystemSid))
983 {
984 goto Quit;
985 }
986
987 if (!AllocateAndInitializeSid(&NtAuthority,
988 2,
989 SECURITY_BUILTIN_DOMAIN_RID,
990 DOMAIN_ALIAS_RID_ADMINS,
991 0, 0, 0, 0, 0, 0,
992 &AdminsSid))
993 {
994 goto Quit;
995 }
996
997 if (!InitializeSecurityDescriptor(&AbsSd, SECURITY_DESCRIPTOR_REVISION))
998 {
999 goto Quit;
1000 }
1001
1002 DaclSize = sizeof(ACL) +
1003 sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(AuthenticatedUsersSid) +
1004 sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(SystemSid) +
1005 sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(AdminsSid);
1006
1007 Dacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DaclSize);
1008 if (!Dacl)
1009 {
1010 goto Quit;
1011 }
1012
1013 if (!InitializeAcl(Dacl, DaclSize, ACL_REVISION))
1014 {
1015 goto Quit;
1016 }
1017
1018 if (!AddAccessAllowedAce(Dacl,
1019 ACL_REVISION,
1020 SYNCHRONIZE | STANDARD_RIGHTS_READ | 0x3,
1021 AuthenticatedUsersSid))
1022 {
1023 goto Quit;
1024 }
1025
1026 if (!AddAccessAllowedAce(Dacl,
1027 ACL_REVISION,
1028 SEMAPHORE_ALL_ACCESS,
1029 SystemSid))
1030 {
1031 goto Quit;
1032 }
1033
1034 if (!AddAccessAllowedAce(Dacl,
1035 ACL_REVISION,
1036 SEMAPHORE_ALL_ACCESS,
1037 AdminsSid))
1038 {
1039 goto Quit;
1040 }
1041
1042 if (!SetSecurityDescriptorDacl(&AbsSd, TRUE, Dacl, FALSE))
1043 {
1044 goto Quit;
1045 }
1046
1047 if (!SetSecurityDescriptorOwner(&AbsSd, AdminsSid, FALSE))
1048 {
1049 goto Quit;
1050 }
1051
1052 if (!SetSecurityDescriptorGroup(&AbsSd, SystemSid, FALSE))
1053 {
1054 goto Quit;
1055 }
1056
1057 if (!MakeSelfRelativeSD(&AbsSd, NULL, &RelSDSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1058 {
1059 RelSd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, RelSDSize);
1060 if (RelSd == NULL)
1061 {
1062 goto Quit;
1063 }
1064
1065 if (!MakeSelfRelativeSD(&AbsSd, RelSd, &RelSDSize))
1066 {
1067 goto Quit;
1068 }
1069 }
1070
1071 *PowrProfSd = RelSd;
1072 Success = TRUE;
1073
1074 Quit:
1075 if (AuthenticatedUsersSid)
1076 {
1077 FreeSid(AuthenticatedUsersSid);
1078 }
1079
1080 if (SystemSid)
1081 {
1082 FreeSid(SystemSid);
1083 }
1084
1085 if (AdminsSid)
1086 {
1087 FreeSid(AdminsSid);
1088 }
1089
1090 if (Dacl)
1091 {
1092 HeapFree(GetProcessHeap(), 0, Dacl);
1093 }
1094
1095 if (!Success)
1096 {
1097 if (RelSd)
1098 {
1099 HeapFree(GetProcessHeap(), 0, RelSd);
1100 }
1101 }
1102
1103 return Success;
1104 }
1105
1106 static VOID
FixSystemPowerState(PSYSTEM_POWER_STATE Psps,SYSTEM_POWER_CAPABILITIES PowerCaps)1107 FixSystemPowerState(PSYSTEM_POWER_STATE Psps, SYSTEM_POWER_CAPABILITIES PowerCaps)
1108 {
1109 //Lohnegrim: If the System doesn't support the Powerstates, then we have to change them
1110 if (!PowerCaps.SystemS1 && *Psps == PowerSystemSleeping1)
1111 *Psps = PowerSystemSleeping2;
1112 if (!PowerCaps.SystemS2 && *Psps == PowerSystemSleeping2)
1113 *Psps = PowerSystemSleeping3;
1114 if (!PowerCaps.SystemS3 && *Psps == PowerSystemSleeping3)
1115 *Psps = PowerSystemHibernate;
1116 if (!(PowerCaps.SystemS4 && PowerCaps.HiberFilePresent) && *Psps == PowerSystemHibernate)
1117 *Psps = PowerSystemSleeping2;
1118 if (!PowerCaps.SystemS1 && *Psps == PowerSystemSleeping1)
1119 *Psps = PowerSystemSleeping2;
1120 if (!PowerCaps.SystemS2 && *Psps == PowerSystemSleeping2)
1121 *Psps = PowerSystemSleeping3;
1122 if (!PowerCaps.SystemS3 && *Psps == PowerSystemSleeping3)
1123 *Psps = PowerSystemShutdown;
1124
1125 }
1126
1127 BOOLEAN WINAPI
ValidatePowerPolicies(PGLOBAL_POWER_POLICY pGPP,PPOWER_POLICY pPP)1128 ValidatePowerPolicies(PGLOBAL_POWER_POLICY pGPP, PPOWER_POLICY pPP)
1129 {
1130 SYSTEM_POWER_CAPABILITIES PowerCaps;
1131 NTSTATUS ret;
1132 BOOLEAN old;
1133
1134 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
1135 ret = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps));
1136 if (ret != STATUS_SUCCESS)
1137 {
1138 SetLastError(RtlNtStatusToDosError(ret));
1139 return FALSE;
1140 }
1141
1142 if (pGPP)
1143 {
1144 if (pGPP->user.Revision != 1 || pGPP->mach.Revision != 1)
1145 {
1146 SetLastError(ERROR_REVISION_MISMATCH);
1147 return FALSE;
1148 }
1149 if (pGPP->mach.LidOpenWakeAc == PowerSystemUnspecified)
1150 {
1151 SetLastError(ERROR_GEN_FAILURE);
1152 return FALSE;
1153 }
1154 if ((int)pGPP->mach.LidOpenWakeAc > PowerSystemShutdown)
1155 {
1156 SetLastError(ERROR_GEN_FAILURE);
1157 return FALSE;
1158 }
1159 if (pGPP->mach.LidOpenWakeDc < PowerSystemWorking)
1160 {
1161 SetLastError(ERROR_GEN_FAILURE);
1162 return FALSE;
1163 }
1164 if ((int)pGPP->mach.LidOpenWakeDc > PowerSystemShutdown)
1165 {
1166 SetLastError(ERROR_GEN_FAILURE);
1167 return FALSE;
1168 }
1169 //Lohnegrim: unneeded
1170 /*if ((pGPP->mach.LidOpenWakeDc < PowerSystemWorking) || (pGPP->mach.LidOpenWakeDc >= PowerSystemMaximum))
1171 {
1172 SetLastError(ERROR_GEN_FAILURE);
1173 return FALSE;
1174 }*/
1175 if (!CheckPowerActionPolicy(&pGPP->user.LidCloseAc,PowerCaps))
1176 {
1177 return FALSE;
1178 }
1179 if (!CheckPowerActionPolicy(&pGPP->user.LidCloseDc,PowerCaps))
1180 {
1181 return FALSE;
1182 }
1183 if (!CheckPowerActionPolicy(&pGPP->user.PowerButtonAc,PowerCaps))
1184 {
1185 return FALSE;
1186 }
1187 if (!CheckPowerActionPolicy(&pGPP->user.PowerButtonDc,PowerCaps))
1188 {
1189 return FALSE;
1190 }
1191 if (!CheckPowerActionPolicy(&pGPP->user.SleepButtonAc,PowerCaps))
1192 {
1193 return FALSE;
1194 }
1195 if (!CheckPowerActionPolicy(&pGPP->user.SleepButtonDc,PowerCaps))
1196 {
1197 return FALSE;
1198 }
1199 //Lohnegrim: The BroadcastCapacityResolution presents the Powerlevel in Percent, if invalid set th 100 == FULL
1200 if (pGPP->mach.BroadcastCapacityResolution > 100)
1201 pGPP->mach.BroadcastCapacityResolution = 100;
1202
1203 //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
1204 //pGPP->user.DischargePolicy[1].PowerPolicy.EventCode = pGPP->user.DischargePolicy[1].PowerPolicy.EventCode | 0x010000;
1205 //pGPP->user.DischargePolicy[2].PowerPolicy.EventCode = pGPP->user.DischargePolicy[2].PowerPolicy.EventCode | 0x020000;
1206 //pGPP->user.DischargePolicy[3].PowerPolicy.EventCode = pGPP->user.DischargePolicy[3].PowerPolicy.EventCode | 0x030000;
1207
1208 FixSystemPowerState(&pGPP->mach.LidOpenWakeAc,PowerCaps);
1209 FixSystemPowerState(&pGPP->mach.LidOpenWakeDc,PowerCaps);
1210
1211 }
1212
1213 if (pPP)
1214 {
1215 if (pPP->user.Revision != 1 || pPP->mach.Revision != 1)
1216 {
1217 SetLastError(ERROR_REVISION_MISMATCH);
1218 return FALSE;
1219 }
1220
1221 //Lohnegrim: unneeded
1222 //if (pPP->mach.MinSleepAc < PowerSystemWorking)
1223 //{
1224 // SetLastError(ERROR_GEN_FAILURE);
1225 // return FALSE;
1226 //}
1227 if ((int)pPP->mach.MinSleepAc >= PowerSystemShutdown)
1228 {
1229 SetLastError(ERROR_GEN_FAILURE);
1230 return FALSE;
1231 }
1232 //Lohnegrim: unneeded
1233 //if (pPP->mach.MinSleepDc < PowerSystemWorking)
1234 //{
1235 // SetLastError(ERROR_GEN_FAILURE);
1236 // return FALSE;
1237 //}
1238 if ((int)pPP->mach.MinSleepDc >= PowerSystemShutdown)
1239 {
1240 SetLastError(ERROR_GEN_FAILURE);
1241 return FALSE;
1242 }
1243 if ((int)pPP->mach.ReducedLatencySleepAc == PowerSystemUnspecified)
1244 {
1245 SetLastError(ERROR_GEN_FAILURE);
1246 return FALSE;
1247 }
1248 if ((int)pPP->mach.ReducedLatencySleepAc > PowerSystemShutdown)
1249 {
1250 SetLastError(ERROR_GEN_FAILURE);
1251 return FALSE;
1252 }
1253 if ((int)pPP->mach.ReducedLatencySleepDc < PowerSystemWorking)
1254 {
1255 SetLastError(ERROR_GEN_FAILURE);
1256 return FALSE;
1257 }
1258 if ((int)pPP->mach.ReducedLatencySleepDc > PowerSystemShutdown)
1259 {
1260 SetLastError(ERROR_GEN_FAILURE);
1261 return FALSE;
1262 }
1263
1264 if (!CheckPowerActionPolicy(&pPP->mach.OverThrottledAc,PowerCaps))
1265 {
1266 return FALSE;
1267 }
1268 if (!CheckPowerActionPolicy(&pPP->mach.OverThrottledDc,PowerCaps))
1269 {
1270 return FALSE;
1271 }
1272 if (!CheckPowerActionPolicy(&pPP->user.IdleAc,PowerCaps))
1273 {
1274 return FALSE;
1275 }
1276 if (!CheckPowerActionPolicy(&pPP->user.IdleDc,PowerCaps))
1277 {
1278 return FALSE;
1279 }
1280 if (pPP->user.MaxSleepAc < PowerSystemWorking)
1281 {
1282 SetLastError(ERROR_GEN_FAILURE);
1283 return FALSE;
1284 }
1285 //Lohnegrim: unneeded
1286 /*if ((int)pPP->user.MaxSleepAc > PowerSystemShutdown)
1287 {
1288 SetLastError(ERROR_GEN_FAILURE);
1289 return FALSE;
1290 }*/
1291 if (pPP->user.MaxSleepDc < PowerSystemWorking)
1292 {
1293 SetLastError(ERROR_GEN_FAILURE);
1294 return FALSE;
1295 }
1296 //Lohnegrim: unneeded
1297 /*if ((int)pPP->user.MaxSleepDc >= PowerSystemShutdown)
1298 {
1299 SetLastError(ERROR_GEN_FAILURE);
1300 return FALSE;
1301 }*/
1302 if (PowerCaps.SystemS1)
1303 {
1304 pPP->mach.MinSleepAc=PowerSystemSleeping1;
1305 pPP->mach.MinSleepDc=PowerSystemSleeping1;
1306 }
1307 else if (PowerCaps.SystemS2)
1308 {
1309 pPP->mach.MinSleepAc=PowerSystemSleeping2;
1310 pPP->mach.MinSleepDc=PowerSystemSleeping2;
1311 }
1312 else if (PowerCaps.SystemS3)
1313 {
1314 pPP->mach.MinSleepAc=PowerSystemSleeping3;
1315 pPP->mach.MinSleepDc=PowerSystemSleeping3;
1316 }
1317
1318 if (PowerCaps.SystemS4)
1319 {
1320 pPP->user.MaxSleepAc=PowerSystemSleeping3;
1321 pPP->user.MaxSleepDc=PowerSystemSleeping3;
1322 }
1323 else if (PowerCaps.SystemS3)
1324 {
1325 pPP->user.MaxSleepAc=PowerSystemSleeping2;
1326 pPP->user.MaxSleepDc=PowerSystemSleeping2;
1327 }
1328 else if (PowerCaps.SystemS1)
1329 {
1330 pPP->user.MaxSleepAc=PowerSystemSleeping1;
1331 pPP->user.MaxSleepDc=PowerSystemSleeping1;
1332 }
1333 //Lohnegrim: I don't know where to get this info from, so I removed it
1334 //pPP->user.OptimizeForPowerAc=TRUE;
1335 //pPP->user.OptimizeForPowerDc=TRUE;
1336
1337 FixSystemPowerState(&pPP->mach.ReducedLatencySleepAc,PowerCaps);
1338 FixSystemPowerState(&pPP->mach.ReducedLatencySleepDc,PowerCaps);
1339 }
1340
1341 SetLastError(ERROR_SUCCESS);
1342 return TRUE;
1343 }
1344
WritePwrPolicy(PUINT puiID,PPOWER_POLICY pPowerPolicy)1345 BOOLEAN WINAPI WritePwrPolicy(PUINT puiID, PPOWER_POLICY pPowerPolicy)
1346 {
1347 WCHAR Buf[MAX_PATH];
1348 HKEY hKey;
1349
1350 swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID);
1351
1352 if (RegCreateKey(HKEY_CURRENT_USER, Buf, &hKey) != ERROR_SUCCESS)
1353 return FALSE;
1354
1355 RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (const unsigned char *)&pPowerPolicy->user, sizeof(USER_POWER_POLICY));
1356 RegCloseKey(hKey);
1357
1358 swprintf(Buf, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%i", *puiID);
1359
1360 if (RegCreateKey(HKEY_LOCAL_MACHINE, Buf, &hKey) != ERROR_SUCCESS)
1361 return FALSE;
1362
1363 RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (const unsigned char *)&pPowerPolicy->mach, sizeof(MACHINE_POWER_POLICY));
1364 RegCloseKey(hKey);
1365
1366 return TRUE;
1367 }
1368
1369 BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)1370 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1371 {
1372 switch(fdwReason)
1373 {
1374 case DLL_PROCESS_ATTACH:
1375 {
1376 HKEY hKey;
1377 LONG Err;
1378 SECURITY_ATTRIBUTES SecAttrs;
1379 PSECURITY_DESCRIPTOR Sd;
1380
1381 DisableThreadLibraryCalls(hinstDLL);
1382
1383 Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ, &hKey);
1384
1385 if (Err != ERROR_SUCCESS)
1386 {
1387 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey));
1388 }
1389 else
1390 {
1391 WCHAR lpValue[MAX_PATH];
1392 DWORD cbValue = sizeof(lpValue);
1393
1394 Err = RegQueryValueExW(hKey, szLastID, 0, 0, (BYTE*)lpValue, &cbValue);
1395 if (Err == ERROR_SUCCESS)
1396 {
1397 g_LastID = _wtoi(lpValue);
1398 }
1399 else
1400 {
1401 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey));
1402 }
1403 RegCloseKey(hKey);
1404 }
1405
1406 if (!CreatePowrProfSemaphoreSecurity(&Sd))
1407 {
1408 ERR("Couldn't create POWRPROF semaphore security descriptor!\n");
1409 return FALSE;
1410 }
1411
1412 SecAttrs.nLength = sizeof(SECURITY_ATTRIBUTES);
1413 SecAttrs.lpSecurityDescriptor = Sd;
1414 SecAttrs.bInheritHandle = FALSE;
1415
1416 PPRegSemaphore = CreateSemaphoreW(&SecAttrs, 1, 1, szSemaphoreName);
1417 HeapFree(GetProcessHeap(), 0, Sd);
1418 if (PPRegSemaphore == NULL)
1419 {
1420 ERR("Couldn't create Semaphore: %d\n", GetLastError());
1421 return FALSE;
1422 }
1423 break;
1424 }
1425 case DLL_PROCESS_DETACH:
1426 CloseHandle(PPRegSemaphore);
1427 break;
1428 }
1429 return TRUE;
1430 }
1431