Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpowrprof.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2005 Benjamin Cutler 00003 * Copyright (C) 2008 Dmitry Chapyshev 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 00021 #include <stdarg.h> 00022 00023 #define WIN32_NO_STATUS 00024 #include <windows.h> 00025 #define NTOS_MODE_USER 00026 #include <ndk/pofuncs.h> 00027 #include <ndk/rtlfuncs.h> 00028 #include <ndk/setypes.h> 00029 #include <powrprof.h> 00030 #include <wchar.h> 00031 #include <stdio.h> 00032 00033 #include "wine/debug.h" 00034 #include "wine/unicode.h" 00035 00036 WINE_DEFAULT_DEBUG_CHANNEL(powrprof); 00037 00038 00039 static const WCHAR szPowerCfgSubKey[] = 00040 L"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg"; 00041 static const WCHAR szUserPowerConfigSubKey[] = 00042 L"Control Panel\\PowerCfg"; 00043 static const WCHAR szCurrentPowerPolicies[] = 00044 L"CurrentPowerPolicy"; 00045 static const WCHAR szPolicies[] = L"Policies"; 00046 static const WCHAR szName[] = L"Name"; 00047 static const WCHAR szDescription[] = L"Description"; 00048 static const WCHAR szSemaphoreName[] = L"PowerProfileRegistrySemaphore"; 00049 static const WCHAR szDiskMax[] = L"DiskSpindownMax"; 00050 static const WCHAR szDiskMin[] = L"DiskSpindownMin"; 00051 static const WCHAR szLastID[] = L"LastID"; 00052 00053 UINT g_LastID = (UINT)-1; 00054 00055 BOOLEAN WINAPI WritePwrPolicy(PUINT puiID, PPOWER_POLICY pPowerPolicy); 00056 00057 HANDLE PPRegSemaphore = NULL; 00058 00059 NTSTATUS WINAPI 00060 CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel, 00061 PVOID lpInputBuffer, 00062 ULONG nInputBufferSize, 00063 PVOID lpOutputBuffer, 00064 ULONG nOutputBufferSize) 00065 { 00066 BOOLEAN old; 00067 00068 //Lohnegrim: In order to get the right results, we have to ajust our Privilegs 00069 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old); 00070 RtlAdjustPrivilege(SE_CREATE_PAGEFILE_PRIVILEGE, TRUE, FALSE, &old); 00071 00072 return NtPowerInformation(InformationLevel, 00073 lpInputBuffer, 00074 nInputBufferSize, 00075 lpOutputBuffer, 00076 nOutputBufferSize); 00077 } 00078 00079 BOOLEAN WINAPI 00080 CanUserWritePwrScheme(VOID) 00081 { 00082 HKEY hKey = NULL; 00083 LONG Ret; 00084 00085 TRACE("()\n"); 00086 00087 Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ | KEY_WRITE, &hKey); 00088 if (Ret != ERROR_SUCCESS) 00089 { 00090 TRACE("RegOpenKeyEx failed: %d\n", Ret); 00091 SetLastError(Ret); 00092 return FALSE; 00093 } 00094 00095 RegCloseKey(hKey); 00096 return TRUE; 00097 } 00098 00099 BOOLEAN WINAPI 00100 DeletePwrScheme(UINT uiIndex) 00101 { 00102 WCHAR Buf[MAX_PATH]; 00103 UINT Current; 00104 LONG Err; 00105 00106 swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%d", uiIndex); 00107 00108 if (!GetActivePwrScheme(&Current)) 00109 return FALSE; 00110 00111 if (Current == uiIndex) 00112 { 00113 SetLastError(ERROR_ACCESS_DENIED); 00114 return FALSE; 00115 } 00116 00117 Err = RegDeleteKey(HKEY_CURRENT_USER, (LPCTSTR)Buf); 00118 if (Err != ERROR_SUCCESS) 00119 { 00120 TRACE("RegDeleteKey failed: %d\n", Err); 00121 SetLastError(Err); 00122 return FALSE; 00123 } 00124 00125 return TRUE; 00126 } 00127 00128 static BOOLEAN 00129 POWRPROF_GetUserPowerPolicy(LPWSTR szNum, 00130 PUSER_POWER_POLICY puserPwrPolicy, 00131 DWORD cchName, LPWSTR szName, 00132 DWORD cchDesc, LPWSTR szDesc) 00133 { 00134 HKEY hSubKey = NULL; 00135 DWORD dwSize; 00136 LONG Err; 00137 WCHAR szPath[MAX_PATH]; 00138 BOOL bRet = FALSE; 00139 00140 swprintf(szPath, L"Control Panel\\PowerCfg\\PowerPolicies\\%s", szNum); 00141 00142 Err = RegOpenKeyExW(HKEY_CURRENT_USER, szPath, 0, KEY_READ, &hSubKey); 00143 if (Err != ERROR_SUCCESS) 00144 { 00145 ERR("RegOpenKeyExW failed: %d\n", Err); 00146 SetLastError(Err); 00147 return FALSE; 00148 } 00149 00150 dwSize = cchName * sizeof(WCHAR); 00151 Err = RegQueryValueExW(hSubKey, L"Name", NULL, NULL, (LPBYTE)szName, &dwSize); 00152 if (Err != ERROR_SUCCESS) 00153 { 00154 ERR("RegQueryValueExW failed: %d\n", Err); 00155 SetLastError(Err); 00156 goto cleanup; 00157 } 00158 00159 dwSize = cchDesc * sizeof(WCHAR); 00160 Err = RegQueryValueExW(hSubKey, L"Description", NULL, NULL, (LPBYTE)szDesc, &dwSize); 00161 if (Err != ERROR_SUCCESS) 00162 { 00163 ERR("RegQueryValueExW failed: %d\n", Err); 00164 SetLastError(Err); 00165 goto cleanup; 00166 } 00167 00168 dwSize = sizeof(USER_POWER_POLICY); 00169 Err = RegQueryValueExW(hSubKey, L"Policies", NULL, NULL, (LPBYTE)puserPwrPolicy, &dwSize); 00170 if (Err != ERROR_SUCCESS) 00171 { 00172 ERR("RegQueryValueExW failed: %d\n", Err); 00173 SetLastError(Err); 00174 goto cleanup; 00175 } 00176 00177 bRet = TRUE; 00178 00179 cleanup: 00180 RegCloseKey(hSubKey); 00181 00182 return bRet; 00183 } 00184 00185 static BOOLEAN 00186 POWRPROF_GetMachinePowerPolicy(LPWSTR szNum, PMACHINE_POWER_POLICY pmachinePwrPolicy) 00187 { 00188 HKEY hKey; 00189 LONG Err; 00190 WCHAR szPath[MAX_PATH]; 00191 DWORD dwSize; 00192 00193 swprintf(szPath, L"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%s", szNum); 00194 00195 Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey); 00196 if (Err != ERROR_SUCCESS) 00197 { 00198 ERR("RegOpenKeyExW failed: %d\n", Err); 00199 SetLastError(Err); 00200 return FALSE; 00201 } 00202 00203 dwSize = sizeof(MACHINE_POWER_POLICY); 00204 Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)pmachinePwrPolicy, &dwSize); 00205 00206 if (Err != ERROR_SUCCESS) 00207 { 00208 ERR("RegQueryValueExW failed: %d\n", Err); 00209 SetLastError(Err); 00210 RegCloseKey(hKey); 00211 return FALSE; 00212 } 00213 00214 RegCloseKey(hKey); 00215 00216 return TRUE; 00217 } 00218 00219 BOOLEAN WINAPI 00220 EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc, 00221 LPARAM lParam) 00222 { 00223 HKEY hKey; 00224 LONG Err; 00225 DWORD dwSize, dwNameSize = MAX_PATH, dwDescSize = MAX_PATH, dwIndex = 0; 00226 WCHAR szNum[3 + 1], szName[MAX_PATH], szDesc[MAX_PATH]; 00227 POWER_POLICY PwrPolicy; 00228 USER_POWER_POLICY userPwrPolicy; 00229 MACHINE_POWER_POLICY machinePwrPolicy; 00230 BOOLEAN bRet = FALSE; 00231 00232 if (!lpfnPwrSchemesEnumProc) 00233 { 00234 SetLastError(ERROR_INVALID_PARAMETER); 00235 return FALSE; 00236 } 00237 00238 Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg\\PowerPolicies", 0, KEY_READ, &hKey); 00239 if (Err != ERROR_SUCCESS) 00240 { 00241 ERR("RegOpenKeyW failed: %d\n", Err); 00242 SetLastError(Err); 00243 return FALSE; 00244 } 00245 00246 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00247 00248 dwSize = sizeof(szNum) / sizeof(WCHAR); 00249 00250 while (RegEnumKeyExW(hKey, dwIndex, szNum, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) 00251 { 00252 if (!POWRPROF_GetUserPowerPolicy(szNum, &userPwrPolicy, 00253 dwNameSize, szName, 00254 dwDescSize, szDesc)) 00255 { 00256 WARN("POWRPROF_GetUserPowerPolicy failed\n"); 00257 goto cleanup; 00258 } 00259 00260 if (!POWRPROF_GetMachinePowerPolicy(szNum, &machinePwrPolicy)) 00261 { 00262 WARN("POWRPROF_GetMachinePowerPolicy failed\n"); 00263 goto cleanup; 00264 } 00265 00266 memcpy(&PwrPolicy.user, &userPwrPolicy, sizeof(USER_POWER_POLICY)); 00267 memcpy(&PwrPolicy.mach, &machinePwrPolicy, sizeof(MACHINE_POWER_POLICY)); 00268 00269 if (!lpfnPwrSchemesEnumProc(_wtoi(szNum), dwNameSize, szName, dwDescSize, szDesc, &PwrPolicy, lParam)) 00270 goto cleanup; 00271 else 00272 bRet = TRUE; 00273 00274 dwSize = sizeof(szNum) / sizeof(WCHAR); 00275 dwIndex++; 00276 } 00277 00278 cleanup: 00279 RegCloseKey(hKey); 00280 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00281 00282 return bRet; 00283 } 00284 00285 BOOLEAN WINAPI 00286 GetActivePwrScheme(PUINT puiID) 00287 { 00288 HKEY hKey; 00289 WCHAR szBuf[MAX_PATH]; 00290 DWORD dwSize; 00291 LONG Err; 00292 00293 TRACE("GetActivePwrScheme(%u)", puiID); 00294 00295 Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg", 0, KEY_READ, &hKey); 00296 if (Err != ERROR_SUCCESS) 00297 { 00298 ERR("RegOpenKey failed: %d\n", Err); 00299 SetLastError(Err); 00300 return FALSE; 00301 } 00302 00303 dwSize = MAX_PATH; 00304 Err = RegQueryValueExW(hKey, L"CurrentPowerPolicy", 00305 NULL, NULL, 00306 (LPBYTE)&szBuf, &dwSize); 00307 if (Err != ERROR_SUCCESS) 00308 { 00309 ERR("RegQueryValueEx failed: %d\n", Err); 00310 RegCloseKey(hKey); 00311 SetLastError(Err); 00312 return FALSE; 00313 } 00314 00315 RegCloseKey(hKey); 00316 *puiID = _wtoi(szBuf); 00317 00318 return TRUE; 00319 } 00320 00321 BOOLEAN WINAPI 00322 GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pGlobalPowerPolicy, 00323 PPOWER_POLICY pPowerPolicy) 00324 { 00325 /* 00326 SYSTEM_POWER_POLICY ACPower, DCPower; 00327 00328 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy, pPowerPolicy); 00329 00330 NtPowerInformation(SystemPowerPolicyAc, 0, 0, &ACPower, sizeof(SYSTEM_POWER_POLICY)); 00331 NtPowerInformation(SystemPowerPolicyDc, 0, 0, &DCPower, sizeof(SYSTEM_POWER_POLICY)); 00332 00333 return FALSE; 00334 */ 00335 /* 00336 Lohnegrim: I dont know why this Function shoud call NtPowerInformation, becouse as far as i know, 00337 it simply returns the GlobalPowerPolicy and the AktivPowerScheme! 00338 */ 00339 UINT uiID; 00340 00341 if (pGlobalPowerPolicy != NULL) 00342 { 00343 if (!ReadGlobalPwrPolicy(pGlobalPowerPolicy)) 00344 return FALSE; 00345 } 00346 if (pPowerPolicy != NULL) 00347 { 00348 if (!GetActivePwrScheme(&uiID)) 00349 return FALSE; 00350 00351 if (!ReadPwrScheme(uiID, pPowerPolicy)) 00352 return FALSE; 00353 } 00354 00355 return TRUE; 00356 } 00357 00358 BOOLEAN WINAPI 00359 GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities) 00360 { 00361 NTSTATUS Status; 00362 00363 TRACE("(%p)\n", lpSystemPowerCapabilities); 00364 00365 if (!lpSystemPowerCapabilities) 00366 { 00367 SetLastError(ERROR_INVALID_PARAMETER); 00368 return FALSE; 00369 } 00370 00371 Status = NtPowerInformation(SystemPowerCapabilities, 0, 0, lpSystemPowerCapabilities, sizeof(SYSTEM_POWER_CAPABILITIES)); 00372 if(!NT_SUCCESS(Status)) 00373 { 00374 SetLastError(RtlNtStatusToDosError(Status)); 00375 return FALSE; 00376 } 00377 00378 return TRUE; 00379 } 00380 00381 BOOLEAN WINAPI 00382 GetPwrDiskSpindownRange(PUINT RangeMax, PUINT RangeMin) 00383 { 00384 HKEY hKey; 00385 BYTE lpValue[40]; 00386 LONG Ret; 00387 DWORD cbValue = sizeof(lpValue); 00388 00389 TRACE("(%p, %p)\n", RangeMax, RangeMin); 00390 00391 if (RangeMax == NULL || RangeMin == NULL) 00392 { 00393 SetLastError(ERROR_INVALID_PARAMETER); 00394 return FALSE; 00395 } 00396 00397 WaitForSingleObject(PPRegSemaphore, INFINITE); 00398 00399 Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ, &hKey); 00400 if (Ret != ERROR_SUCCESS) 00401 { 00402 TRACE("RegOpenKeyEx failed: %d\n", Ret); 00403 TRACE("Using defaults: 3600, 3\n"); 00404 *RangeMax = 3600; 00405 *RangeMin = 3; 00406 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00407 return TRUE; 00408 } 00409 00410 Ret = RegQueryValueExW(hKey, szDiskMax, 0, 0, lpValue, &cbValue); 00411 if (Ret != ERROR_SUCCESS) 00412 { 00413 TRACE("Couldn't open DiskSpinDownMax: %d\n", Ret); 00414 TRACE("Using default: 3600\n"); 00415 *RangeMax = 3600; 00416 } 00417 else 00418 { 00419 *RangeMax = _wtoi((LPCWSTR)lpValue); 00420 } 00421 00422 cbValue = sizeof(lpValue); 00423 00424 Ret = RegQueryValueExW(hKey, szDiskMin, 0, 0, lpValue, &cbValue); 00425 if (Ret != ERROR_SUCCESS) 00426 { 00427 TRACE("Couldn't open DiskSpinDownMin: %d\n", Ret); 00428 TRACE("Using default: 3\n"); 00429 *RangeMin = 3; 00430 } 00431 else 00432 { 00433 *RangeMin = _wtoi((LPCWSTR)lpValue); 00434 } 00435 00436 RegCloseKey(hKey); 00437 00438 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00439 00440 return TRUE; 00441 } 00442 00443 BOOLEAN WINAPI 00444 IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p) 00445 { 00446 FIXME("( %p) stub!\n", p); 00447 return FALSE; 00448 } 00449 00450 BOOLEAN WINAPI 00451 IsPwrHibernateAllowed(VOID) 00452 { 00453 SYSTEM_POWER_CAPABILITIES PowerCaps; 00454 NTSTATUS Status; 00455 BOOLEAN old; 00456 00457 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old); 00458 00459 Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps)); 00460 if (!NT_SUCCESS(Status)) 00461 { 00462 SetLastError(RtlNtStatusToDosError(Status)); 00463 return FALSE; 00464 } 00465 00466 return PowerCaps.SystemS4 && PowerCaps.HiberFilePresent; // IsHiberfilPresent(); 00467 } 00468 00469 BOOLEAN WINAPI 00470 IsPwrShutdownAllowed(VOID) 00471 { 00472 SYSTEM_POWER_CAPABILITIES PowerCaps; 00473 NTSTATUS Status; 00474 BOOLEAN old; 00475 00476 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old); 00477 00478 Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps)); 00479 if (!NT_SUCCESS(Status)) 00480 { 00481 SetLastError(RtlNtStatusToDosError(Status)); 00482 return FALSE; 00483 } 00484 00485 return PowerCaps.SystemS5; 00486 } 00487 00488 BOOLEAN WINAPI 00489 IsPwrSuspendAllowed(VOID) 00490 { 00491 SYSTEM_POWER_CAPABILITIES PowerCaps; 00492 NTSTATUS Status; 00493 BOOLEAN old; 00494 00495 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old); 00496 00497 Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps)); 00498 if (!NT_SUCCESS(Status)) 00499 { 00500 SetLastError(RtlNtStatusToDosError(Status)); 00501 return FALSE; 00502 } 00503 00504 return PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3; 00505 } 00506 00507 DWORD WINAPI 00508 PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid) 00509 { 00510 FIXME("(%p,%p) stub!\n", UserRootPowerKey, polguid); 00511 return ERROR_CALL_NOT_IMPLEMENTED; 00512 } 00513 00514 DWORD WINAPI 00515 PowerReadDCValue(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, const GUID *PowerSettings, PULONG Type, PUCHAR Buffer, DWORD *BufferSize) 00516 { 00517 FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey, debugstr_guid(Scheme), debugstr_guid(SubGroup), debugstr_guid(PowerSettings), Type, Buffer, BufferSize); 00518 return ERROR_CALL_NOT_IMPLEMENTED; 00519 } 00520 00521 BOOLEAN WINAPI 00522 ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy) 00523 { 00524 GLOBAL_MACHINE_POWER_POLICY glMachPwrPolicy; 00525 GLOBAL_USER_POWER_POLICY glUserPwrPolicy; 00526 HKEY hKey = NULL; 00527 DWORD dwSize; 00528 LONG Err; 00529 BOOL bRet = FALSE; 00530 00531 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00532 00533 // Getting user global power policy 00534 Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ, &hKey); 00535 if (Err != ERROR_SUCCESS) 00536 { 00537 ERR("RegOpenKeyW failed: %d\n", Err); 00538 SetLastError(Err); 00539 goto cleanup; 00540 } 00541 00542 dwSize = sizeof(glUserPwrPolicy); 00543 Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)&glUserPwrPolicy, &dwSize); 00544 if (Err != ERROR_SUCCESS) 00545 { 00546 ERR("RegQueryValueExW failed: %d\n", Err); 00547 SetLastError(Err); 00548 goto cleanup; 00549 } 00550 00551 RegCloseKey(hKey); 00552 00553 // Getting machine global power policy 00554 Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ, &hKey); 00555 if (Err != ERROR_SUCCESS) 00556 { 00557 ERR("RegOpenKeyW failed: %d\n", Err); 00558 SetLastError(Err); 00559 goto cleanup; 00560 } 00561 00562 dwSize = sizeof(glMachPwrPolicy); 00563 Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)&glMachPwrPolicy, &dwSize); 00564 if (Err != ERROR_SUCCESS) 00565 { 00566 ERR("RegQueryValueExW failed: %d\n", Err); 00567 SetLastError(Err); 00568 goto cleanup; 00569 } 00570 00571 memcpy(&pGlobalPowerPolicy->user, &glUserPwrPolicy, sizeof(GLOBAL_USER_POWER_POLICY)); 00572 memcpy(&pGlobalPowerPolicy->mach, &glMachPwrPolicy, sizeof(GLOBAL_MACHINE_POWER_POLICY)); 00573 bRet = TRUE; 00574 00575 cleanup: 00576 if(hKey) 00577 RegCloseKey(hKey); 00578 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00579 00580 return bRet; 00581 } 00582 00583 00584 BOOLEAN WINAPI 00585 ReadProcessorPwrScheme(UINT uiID, 00586 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy) 00587 { 00588 HKEY hKey; 00589 WCHAR szPath[MAX_PATH]; 00590 DWORD dwSize = sizeof(MACHINE_PROCESSOR_POWER_POLICY); 00591 00592 swprintf(szPath, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", uiID); 00593 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 00594 return FALSE; 00595 00596 if (RegQueryValueExW(hKey, szPolicies, NULL, 0, (LPBYTE)pMachineProcessorPowerPolicy, &dwSize) == ERROR_SUCCESS) 00597 { 00598 RegCloseKey(hKey); 00599 return TRUE; 00600 } 00601 00602 RegCloseKey(hKey); 00603 if (uiID != 0) 00604 return ReadProcessorPwrScheme(0, pMachineProcessorPowerPolicy); 00605 00606 return FALSE; 00607 } 00608 00609 00610 BOOLEAN WINAPI 00611 ReadPwrScheme(UINT uiID, 00612 PPOWER_POLICY pPowerPolicy) 00613 { 00614 USER_POWER_POLICY userPwrPolicy; 00615 MACHINE_POWER_POLICY machinePwrPolicy; 00616 WCHAR szNum[16]; // max number - 999 00617 00618 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00619 00620 swprintf(szNum, L"%d", uiID); 00621 00622 if (!POWRPROF_GetUserPowerPolicy(szNum, &userPwrPolicy, 0, NULL, 0, NULL)) 00623 { 00624 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00625 return FALSE; 00626 } 00627 00628 if (!POWRPROF_GetMachinePowerPolicy(szNum, &machinePwrPolicy)) 00629 { 00630 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00631 return FALSE; 00632 } 00633 00634 memcpy(&pPowerPolicy->user, &userPwrPolicy, sizeof(userPwrPolicy)); 00635 memcpy(&pPowerPolicy->mach, &machinePwrPolicy, sizeof(machinePwrPolicy)); 00636 00637 ReleaseSemaphore(PPRegSemaphore, 1, NULL); 00638 00639 return TRUE; 00640 } 00641 00642 BOOLEAN WINAPI 00643 SetActivePwrScheme(UINT uiID, 00644 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy, 00645 PPOWER_POLICY lpPowerPolicy) 00646 { 00647 POWER_POLICY tmp; 00648 HKEY hKey; 00649 WCHAR Buf[16]; 00650 00651 if (!ReadPwrScheme(uiID, &tmp)) 00652 return FALSE; 00653 00654 if (RegOpenKeyEx(HKEY_CURRENT_USER, szUserPowerConfigSubKey, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS) 00655 return FALSE; 00656 00657 swprintf(Buf, L"%i", uiID); 00658 00659 if (RegSetValueExW(hKey, szCurrentPowerPolicies, 0, REG_SZ, (PBYTE)Buf, strlenW(Buf)*sizeof(WCHAR)) != ERROR_SUCCESS) 00660 { 00661 RegCloseKey(hKey); 00662 return FALSE; 00663 } 00664 RegCloseKey(hKey); 00665 00666 if (lpGlobalPowerPolicy != NULL || lpPowerPolicy != NULL) 00667 { 00668 if (!ValidatePowerPolicies(lpGlobalPowerPolicy, lpPowerPolicy)) 00669 return FALSE; 00670 00671 if (lpGlobalPowerPolicy != NULL && !WriteGlobalPwrPolicy(lpGlobalPowerPolicy)) 00672 return FALSE; 00673 00674 if (lpPowerPolicy != NULL && !WritePwrPolicy(&uiID,lpPowerPolicy)) 00675 return FALSE; 00676 } 00677 00678 return TRUE; 00679 } 00680 00681 BOOLEAN WINAPI 00682 SetSuspendState(BOOLEAN Hibernate, 00683 BOOLEAN ForceCritical, 00684 BOOLEAN DisableWakeEvent) 00685 { 00686 FIXME("(%d, %d, %d) stub!\n", Hibernate, ForceCritical, DisableWakeEvent); 00687 return TRUE; 00688 } 00689 00690 BOOLEAN WINAPI 00691 WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy) 00692 { 00693 HKEY hKey; 00694 GLOBAL_USER_POWER_POLICY gupp; 00695 GLOBAL_MACHINE_POWER_POLICY gmpp; 00696 00697 gupp = pGlobalPowerPolicy->user; 00698 gmpp = pGlobalPowerPolicy->mach; 00699 00700 if (RegOpenKeyEx(HKEY_CURRENT_USER, 00701 L"Control Panel\\PowerCfg\\GlobalPowerPolicy", 00702 0, 00703 KEY_WRITE, 00704 &hKey) != ERROR_SUCCESS) 00705 return FALSE; 00706 00707 if (RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (PBYTE)&gupp, sizeof(gupp)) != ERROR_SUCCESS) 00708 { 00709 RegCloseKey(hKey); 00710 return FALSE; 00711 } 00712 00713 RegCloseKey(hKey); 00714 00715 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00716 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy", 00717 0, 00718 KEY_ALL_ACCESS, 00719 &hKey)) 00720 return FALSE; 00721 00722 if (RegSetValueExW(hKey,szPolicies, 0, REG_BINARY, (PBYTE)&gmpp, sizeof(gmpp)) != ERROR_SUCCESS) 00723 { 00724 RegCloseKey(hKey); 00725 return FALSE; 00726 } 00727 00728 RegCloseKey(hKey); 00729 return TRUE; 00730 } 00731 00732 BOOLEAN WINAPI 00733 WriteProcessorPwrScheme(UINT ID, 00734 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy) 00735 { 00736 WCHAR Buf[MAX_PATH]; 00737 HKEY hKey; 00738 00739 swprintf(Buf, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", ID); 00740 00741 if (RegCreateKey(HKEY_LOCAL_MACHINE, Buf, &hKey) != ERROR_SUCCESS) 00742 return FALSE; 00743 00744 RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (PBYTE)pMachineProcessorPowerPolicy, sizeof(MACHINE_PROCESSOR_POWER_POLICY)); 00745 RegCloseKey(hKey); 00746 return TRUE; 00747 } 00748 00749 static VOID 00750 SetLastID(VOID) 00751 { 00752 WCHAR Buf[16]; 00753 HKEY hKey; 00754 00755 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00756 szPowerCfgSubKey, 00757 0, 00758 KEY_WRITE, 00759 &hKey) != ERROR_SUCCESS) 00760 return; 00761 swprintf(Buf, L"%i", g_LastID); 00762 RegSetValueExW(hKey, szLastID, 0, REG_SZ, (PBYTE)Buf, strlenW(Buf)*sizeof(WCHAR)); 00763 RegCloseKey(hKey); 00764 } 00765 00766 BOOLEAN WINAPI 00767 WritePwrScheme(PUINT puiID, 00768 LPWSTR lpszName, 00769 LPWSTR lpszDescription, 00770 PPOWER_POLICY pPowerPolicy) 00771 { 00772 WCHAR Buf[MAX_PATH]; 00773 HKEY hKey; 00774 00775 if (*puiID == -1) 00776 { 00777 g_LastID++; 00778 *puiID = g_LastID; 00779 SetLastID(); 00780 } 00781 00782 swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID); 00783 00784 if (RegCreateKey(HKEY_CURRENT_USER, Buf, &hKey) != ERROR_SUCCESS) 00785 return FALSE; 00786 00787 RegSetValueExW(hKey, szName, 0, REG_SZ, (PBYTE)lpszName, strlenW(lpszName)*sizeof(WCHAR)); 00788 RegSetValueExW(hKey, szDescription, 0, REG_SZ, (PBYTE)lpszDescription, strlenW(lpszDescription)*sizeof(WCHAR)); 00789 RegCloseKey(hKey); 00790 return WritePwrPolicy(puiID, pPowerPolicy); 00791 } 00792 00793 static BOOLEAN 00794 CheckPowerActionPolicy(PPOWER_ACTION_POLICY pPAP, SYSTEM_POWER_CAPABILITIES PowerCaps) 00795 { 00796 /* 00797 Lohnegrim: this is an Helperfunction, it checks if the POWERACTIONPOLICY is valid 00798 Also, if the System dosn't support Hipernation, then change the PowerAction 00799 */ 00800 switch (pPAP->Action) 00801 { 00802 case PowerActionNone: 00803 return TRUE; 00804 case PowerActionReserved: 00805 if (PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3) 00806 pPAP->Action = PowerActionSleep; 00807 else 00808 pPAP->Action = PowerActionReserved; 00809 case PowerActionSleep: 00810 return TRUE; 00811 case PowerActionHibernate: 00812 if (!(PowerCaps.SystemS4 && PowerCaps.HiberFilePresent)) 00813 { 00814 if (PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3) 00815 pPAP->Action = PowerActionSleep; 00816 else 00817 pPAP->Action = PowerActionReserved; 00818 } 00819 case PowerActionShutdown: 00820 case PowerActionShutdownReset: 00821 case PowerActionShutdownOff: 00822 case PowerActionWarmEject: 00823 return TRUE; 00824 default: 00825 SetLastError(ERROR_INVALID_DATA); 00826 return FALSE; 00827 }; 00828 } 00829 00830 static VOID 00831 FixSystemPowerState(PSYSTEM_POWER_STATE Psps, SYSTEM_POWER_CAPABILITIES PowerCaps) 00832 { 00833 //Lohnegrim: If the System dosn't support the Powerstates, then we have to change them 00834 if (!PowerCaps.SystemS1 && *Psps == PowerSystemSleeping1) 00835 *Psps = PowerSystemSleeping2; 00836 if (!PowerCaps.SystemS2 && *Psps == PowerSystemSleeping2) 00837 *Psps = PowerSystemSleeping3; 00838 if (!PowerCaps.SystemS3 && *Psps == PowerSystemSleeping3) 00839 *Psps = PowerSystemHibernate; 00840 if (!(PowerCaps.SystemS4 && PowerCaps.HiberFilePresent) && *Psps == PowerSystemHibernate) 00841 *Psps = PowerSystemSleeping2; 00842 if (!PowerCaps.SystemS1 && *Psps == PowerSystemSleeping1) 00843 *Psps = PowerSystemSleeping2; 00844 if (!PowerCaps.SystemS2 && *Psps == PowerSystemSleeping2) 00845 *Psps = PowerSystemSleeping3; 00846 if (!PowerCaps.SystemS3 && *Psps == PowerSystemSleeping3) 00847 *Psps = PowerSystemShutdown; 00848 00849 } 00850 00851 BOOLEAN WINAPI 00852 ValidatePowerPolicies(PGLOBAL_POWER_POLICY pGPP, PPOWER_POLICY pPP) 00853 { 00854 SYSTEM_POWER_CAPABILITIES PowerCaps; 00855 NTSTATUS ret; 00856 BOOLEAN old; 00857 00858 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old); 00859 ret = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps)); 00860 if (ret != STATUS_SUCCESS) 00861 { 00862 SetLastError(RtlNtStatusToDosError(ret)); 00863 return FALSE; 00864 } 00865 00866 if (pGPP) 00867 { 00868 if (pGPP->user.Revision != 1 || pGPP->mach.Revision != 1) 00869 { 00870 SetLastError(ERROR_REVISION_MISMATCH); 00871 return FALSE; 00872 } 00873 if (pGPP->mach.LidOpenWakeAc == PowerSystemUnspecified) 00874 { 00875 SetLastError(ERROR_GEN_FAILURE); 00876 return FALSE; 00877 } 00878 if ((int)pGPP->mach.LidOpenWakeAc >= PowerSystemShutdown) 00879 { 00880 SetLastError(ERROR_GEN_FAILURE); 00881 return FALSE; 00882 } 00883 if (pGPP->mach.LidOpenWakeDc < PowerSystemWorking) 00884 { 00885 SetLastError(ERROR_GEN_FAILURE); 00886 return FALSE; 00887 } 00888 if ((int)pGPP->mach.LidOpenWakeDc >= PowerSystemShutdown) 00889 { 00890 SetLastError(ERROR_GEN_FAILURE); 00891 return FALSE; 00892 } 00893 //Lohnegrim: unneeded 00894 /*if ((pGPP->mach.LidOpenWakeDc < PowerSystemWorking) || (pGPP->mach.LidOpenWakeDc >= PowerSystemMaximum)) 00895 { 00896 SetLastError(ERROR_GEN_FAILURE); 00897 return FALSE; 00898 }*/ 00899 if (!CheckPowerActionPolicy(&pGPP->user.LidCloseAc,PowerCaps)) 00900 { 00901 return FALSE; 00902 } 00903 if (!CheckPowerActionPolicy(&pGPP->user.LidCloseDc,PowerCaps)) 00904 { 00905 return FALSE; 00906 } 00907 if (!CheckPowerActionPolicy(&pGPP->user.PowerButtonAc,PowerCaps)) 00908 { 00909 return FALSE; 00910 } 00911 if (!CheckPowerActionPolicy(&pGPP->user.PowerButtonDc,PowerCaps)) 00912 { 00913 return FALSE; 00914 } 00915 if (!CheckPowerActionPolicy(&pGPP->user.SleepButtonAc,PowerCaps)) 00916 { 00917 return FALSE; 00918 } 00919 if (!CheckPowerActionPolicy(&pGPP->user.SleepButtonDc,PowerCaps)) 00920 { 00921 return FALSE; 00922 } 00923 //Lohnegrim: The BroadcastCapacityResolution presents the Powerlevel in Percent, if invalid set th 100 == FULL 00924 if ((pGPP->mach.BroadcastCapacityResolution < 0) || (pGPP->mach.BroadcastCapacityResolution > 100)) 00925 pGPP->mach.BroadcastCapacityResolution=100; 00926 00927 //Lohnegrim: I have no idear, if they are realy needed, or if they are spezific for my System, or what they mean, so i removed them 00928 //pGPP->user.DischargePolicy[1].PowerPolicy.EventCode = pGPP->user.DischargePolicy[1].PowerPolicy.EventCode | 0x010000; 00929 //pGPP->user.DischargePolicy[2].PowerPolicy.EventCode = pGPP->user.DischargePolicy[2].PowerPolicy.EventCode | 0x020000; 00930 //pGPP->user.DischargePolicy[3].PowerPolicy.EventCode = pGPP->user.DischargePolicy[3].PowerPolicy.EventCode | 0x030000; 00931 00932 FixSystemPowerState(&pGPP->mach.LidOpenWakeAc,PowerCaps); 00933 FixSystemPowerState(&pGPP->mach.LidOpenWakeDc,PowerCaps); 00934 00935 } 00936 00937 if (pPP) 00938 { 00939 if (pPP->user.Revision != 1 || pPP->mach.Revision != 1) 00940 { 00941 SetLastError(ERROR_REVISION_MISMATCH); 00942 return FALSE; 00943 } 00944 00945 //Lohnegrim: unneeded 00946 //if (pPP->mach.MinSleepAc < PowerSystemWorking) 00947 //{ 00948 // SetLastError(ERROR_GEN_FAILURE); 00949 // return FALSE; 00950 //} 00951 if ((int)pPP->mach.MinSleepAc >= PowerSystemShutdown) 00952 { 00953 SetLastError(ERROR_GEN_FAILURE); 00954 return FALSE; 00955 } 00956 //Lohnegrim: unneeded 00957 //if (pPP->mach.MinSleepDc < PowerSystemWorking) 00958 //{ 00959 // SetLastError(ERROR_GEN_FAILURE); 00960 // return FALSE; 00961 //} 00962 if ((int)pPP->mach.MinSleepDc >= PowerSystemShutdown) 00963 { 00964 SetLastError(ERROR_GEN_FAILURE); 00965 return FALSE; 00966 } 00967 if (pPP->mach.ReducedLatencySleepAc == PowerSystemUnspecified) 00968 { 00969 SetLastError(ERROR_GEN_FAILURE); 00970 return FALSE; 00971 } 00972 if ((int)pPP->mach.ReducedLatencySleepAc >= PowerSystemShutdown) 00973 { 00974 SetLastError(ERROR_GEN_FAILURE); 00975 return FALSE; 00976 } 00977 if (pPP->mach.ReducedLatencySleepDc < PowerSystemWorking) 00978 { 00979 SetLastError(ERROR_GEN_FAILURE); 00980 return FALSE; 00981 } 00982 if ((int)pPP->mach.ReducedLatencySleepDc >= PowerSystemShutdown) 00983 { 00984 SetLastError(ERROR_GEN_FAILURE); 00985 return FALSE; 00986 } 00987 00988 if (!CheckPowerActionPolicy(&pPP->mach.OverThrottledAc,PowerCaps)) 00989 { 00990 return FALSE; 00991 } 00992 if (!CheckPowerActionPolicy(&pPP->mach.OverThrottledDc,PowerCaps)) 00993 { 00994 return FALSE; 00995 } 00996 if (!CheckPowerActionPolicy(&pPP->user.IdleAc,PowerCaps)) 00997 { 00998 return FALSE; 00999 } 01000 if (!CheckPowerActionPolicy(&pPP->user.IdleDc,PowerCaps)) 01001 { 01002 return FALSE; 01003 } 01004 if (pPP->user.MaxSleepAc < PowerSystemWorking) 01005 { 01006 SetLastError(ERROR_GEN_FAILURE); 01007 return FALSE; 01008 } 01009 //Lohnegrim: unneeded 01010 /*if ((int)pPP->user.MaxSleepAc > PowerSystemShutdown) 01011 { 01012 SetLastError(ERROR_GEN_FAILURE); 01013 return FALSE; 01014 }*/ 01015 if (pPP->user.MaxSleepDc < PowerSystemWorking) 01016 { 01017 SetLastError(ERROR_GEN_FAILURE); 01018 return FALSE; 01019 } 01020 //Lohnegrim: unneeded 01021 /*if ((int)pPP->user.MaxSleepDc >= PowerSystemShutdown) 01022 { 01023 SetLastError(ERROR_GEN_FAILURE); 01024 return FALSE; 01025 }*/ 01026 if (PowerCaps.SystemS1) 01027 { 01028 pPP->mach.MinSleepAc=PowerSystemSleeping1; 01029 pPP->mach.MinSleepDc=PowerSystemSleeping1; 01030 } 01031 else if (PowerCaps.SystemS2) 01032 { 01033 pPP->mach.MinSleepAc=PowerSystemSleeping2; 01034 pPP->mach.MinSleepDc=PowerSystemSleeping2; 01035 } 01036 else if (PowerCaps.SystemS3) 01037 { 01038 pPP->mach.MinSleepAc=PowerSystemSleeping3; 01039 pPP->mach.MinSleepDc=PowerSystemSleeping3; 01040 } 01041 01042 if (PowerCaps.SystemS4) 01043 { 01044 pPP->user.MaxSleepAc=PowerSystemSleeping3; 01045 pPP->user.MaxSleepDc=PowerSystemSleeping3; 01046 } 01047 else if (PowerCaps.SystemS3) 01048 { 01049 pPP->user.MaxSleepAc=PowerSystemSleeping2; 01050 pPP->user.MaxSleepDc=PowerSystemSleeping2; 01051 } 01052 else if (PowerCaps.SystemS1) 01053 { 01054 pPP->user.MaxSleepAc=PowerSystemSleeping1; 01055 pPP->user.MaxSleepDc=PowerSystemSleeping1; 01056 } 01057 //Lohnegrim: I dont know where to get this info from, so i removed it 01058 //pPP->user.OptimizeForPowerAc=TRUE; 01059 //pPP->user.OptimizeForPowerDc=TRUE; 01060 01061 FixSystemPowerState(&pPP->mach.ReducedLatencySleepAc,PowerCaps); 01062 FixSystemPowerState(&pPP->mach.ReducedLatencySleepDc,PowerCaps); 01063 } 01064 01065 SetLastError(ERROR_SUCCESS); 01066 return TRUE; 01067 } 01068 01069 BOOLEAN WINAPI WritePwrPolicy(PUINT puiID, PPOWER_POLICY pPowerPolicy) 01070 { 01071 WCHAR Buf[MAX_PATH]; 01072 HKEY hKey; 01073 01074 swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID); 01075 01076 if (RegCreateKey(HKEY_CURRENT_USER, Buf, &hKey) != ERROR_SUCCESS) 01077 return FALSE; 01078 01079 RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (const unsigned char *)&pPowerPolicy->user, sizeof(USER_POWER_POLICY)); 01080 RegCloseKey(hKey); 01081 01082 swprintf(Buf, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%i", *puiID); 01083 01084 if (RegCreateKey(HKEY_LOCAL_MACHINE, Buf, &hKey) != ERROR_SUCCESS) 01085 return FALSE; 01086 01087 RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (const unsigned char *)&pPowerPolicy->mach, sizeof(MACHINE_POWER_POLICY)); 01088 RegCloseKey(hKey); 01089 01090 return TRUE; 01091 } 01092 01093 BOOL WINAPI 01094 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 01095 { 01096 switch(fdwReason) 01097 { 01098 case DLL_PROCESS_ATTACH: 01099 { 01100 HKEY hKey; 01101 LONG Err; 01102 01103 DisableThreadLibraryCalls(hinstDLL); 01104 01105 Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ, &hKey); 01106 01107 if (Err != ERROR_SUCCESS) 01108 { 01109 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey)); 01110 } 01111 else 01112 { 01113 WCHAR lpValue[MAX_PATH]; 01114 DWORD cbValue = sizeof(lpValue); 01115 01116 Err = RegQueryValueExW(hKey, szLastID, 0, 0, (BYTE*)lpValue, &cbValue); 01117 if (Err == ERROR_SUCCESS) 01118 { 01119 g_LastID = _wtoi(lpValue); 01120 } 01121 else 01122 { 01123 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey)); 01124 } 01125 RegCloseKey(hKey); 01126 } 01127 01128 PPRegSemaphore = CreateSemaphoreW(NULL, 1, 1, szSemaphoreName); 01129 if (PPRegSemaphore == NULL) 01130 { 01131 ERR("Couldn't create Semaphore: %d\n", GetLastError()); 01132 return FALSE; 01133 } 01134 break; 01135 } 01136 case DLL_PROCESS_DETACH: 01137 CloseHandle(PPRegSemaphore); 01138 break; 01139 } 01140 return TRUE; 01141 } Generated on Sun May 27 2012 04:25:52 for ReactOS by
1.7.6.1
|