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 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 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 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 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 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 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 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 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 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 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 443 IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p) 444 { 445 FIXME("( %p) stub!\n", p); 446 return FALSE; 447 } 448 449 BOOLEAN WINAPI 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 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 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 507 PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid) 508 { 509 FIXME("(%p,%p) stub!\n", UserRootPowerKey, polguid); 510 return ERROR_CALL_NOT_IMPLEMENTED; 511 } 512 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 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 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 534 POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRole(void) 535 { 536 FIXME("stub\n"); 537 return PlatformRoleDesktop; 538 } 539 540 POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRoleEx(ULONG version) 541 { 542 FIXME("%lu stub.\n", version); 543 return PlatformRoleDesktop; 544 } 545 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 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 561 DWORD WINAPI PowerUnregisterSuspendResumeNotification(HPOWERNOTIFY handle) 562 { 563 FIXME("(%p) stub!\n", handle); 564 return ERROR_SUCCESS; 565 } 566 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 574 DWORD WINAPI PowerSettingUnregisterNotification(HPOWERNOTIFY handle) 575 { 576 FIXME("(%p) stub!\n", handle); 577 return ERROR_SUCCESS; 578 } 579 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__ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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