Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

720 lines
20 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1996
  4. *
  5. * TITLE: POWERCFG.C
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: ReedB
  10. *
  11. * DATE: 17 Oct, 1996
  12. *
  13. * DESCRIPTION:
  14. * Power management UI. Control panel applet.
  15. *
  16. *******************************************************************************/
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. #include <commctrl.h>
  22. #include <shlobj.h>
  23. #include <shlobjp.h>
  24. #include <shlwapi.h>
  25. #include <cpl.h>
  26. #include <help.h>
  27. #include <regstr.h>
  28. #include "powercfg.h"
  29. #include "pwrresid.h"
  30. #include <shfusion.h>
  31. /*******************************************************************************
  32. *
  33. * G L O B A L D A T A
  34. *
  35. *******************************************************************************/
  36. HINSTANCE g_hInstance; // Global instance handle of this DLL.
  37. UINT wHelpMessage; // Registered help message.
  38. // Registry path to optional top level powercfg pages.
  39. TCHAR g_szRegOptionalPages[] = REGSTR_PATH_CONTROLSFOLDER TEXT("\\Power");
  40. // Array which defines the property tabs/pages in the applet.
  41. // The contents of this array are built dynamically, since they
  42. // depend on the machine power management capabilities.
  43. POWER_PAGES g_TopLevelPages[MAX_PAGES] =
  44. {
  45. MAKEINTRESOURCE(IDS_APPNAME), NULL, 0, // Caption
  46. 0, NULL, 0,
  47. 0, NULL, 0,
  48. 0, NULL, 0,
  49. 0, NULL, 0,
  50. 0, NULL, 0,
  51. 0, NULL, 0,
  52. 0, NULL, 0,
  53. 0, NULL, 0,
  54. 0, NULL, 0,
  55. 0, NULL, 0,
  56. 0, NULL, 0,
  57. 0, NULL, 0,
  58. 0, NULL, 0,
  59. 0, NULL, 0,
  60. 0, NULL, 0,
  61. 0, NULL, 0,
  62. 0, NULL, 0
  63. };
  64. // Specifies which OS, filled in at init CPL time.
  65. BOOL g_bRunningUnderNT;
  66. // This structure is filled in by the Power Policy Manager at CPL_INIT time.
  67. SYSTEM_POWER_CAPABILITIES g_SysPwrCapabilities;
  68. // The following globals are derived from g_SysPwrCapabilities:
  69. DWORD g_dwNumSleepStates = 1; // Every one suports PowerSystemWorking.
  70. DWORD g_dwSleepStatesMaxMin; // Specs sleep states slider range.
  71. DWORD g_dwBattryLevelMaxMin; // Specs battery level slider range.
  72. DWORD g_dwFanThrottleMaxMin; // Specs fan throttle slider range.
  73. BOOL g_bVideoLowPowerSupported;// This will be moved to g_SysPwrCapabilities
  74. UINT g_uiVideoTimeoutMaxMin; // May be set from registry.
  75. UINT g_uiSpindownMaxMin; // May be set from registry.
  76. PUINT g_puiBatCount; // Number of displayable batteries.
  77. BOOL g_bIsUserAdministrator; // The current user has admin. privileges.
  78. // Static flags:
  79. UINT g_uiOverrideAppsFlag = POWER_ACTION_OVERRIDE_APPS;
  80. UINT g_uiDisableWakesFlag = POWER_ACTION_DISABLE_WAKES;
  81. int BuildPages(PSYSTEM_POWER_CAPABILITIES, PPOWER_PAGES);
  82. VOID SyncRegPPM(VOID);
  83. /*******************************************************************************
  84. *
  85. * P U B L I C E N T R Y P O I N T S
  86. *
  87. *******************************************************************************/
  88. /*******************************************************************************
  89. *
  90. * DllInitialize
  91. *
  92. * DESCRIPTION:
  93. * Library entry point
  94. *
  95. * PARAMETERS:
  96. *
  97. *******************************************************************************/
  98. BOOL DllInitialize(
  99. IN PVOID hmod,
  100. IN ULONG ulReason,
  101. IN PCONTEXT pctx OPTIONAL)
  102. {
  103. UNREFERENCED_PARAMETER(pctx);
  104. switch (ulReason) {
  105. case DLL_PROCESS_ATTACH:
  106. g_hInstance = hmod;
  107. DisableThreadLibraryCalls(g_hInstance);
  108. wHelpMessage = RegisterWindowMessage(TEXT("ShellHelp"));
  109. InitSchemesList();
  110. SHFusionInitializeFromModuleID(hmod, 124);
  111. break;
  112. case DLL_PROCESS_DETACH:
  113. SHFusionUninitialize();
  114. break;
  115. }
  116. return TRUE;
  117. }
  118. /*******************************************************************************
  119. *
  120. * CplApplet
  121. *
  122. * DESCRIPTION:
  123. * Called by control panel.
  124. *
  125. * PARAMETERS:
  126. *
  127. *******************************************************************************/
  128. LRESULT APIENTRY
  129. CPlApplet(
  130. HWND hCPLWnd,
  131. UINT Message,
  132. LPARAM wParam,
  133. LPARAM lParam
  134. )
  135. {
  136. LPNEWCPLINFO lpNewCPLInfo;
  137. LPCPLINFO lpCPlInfo;
  138. WNDCLASS cls;
  139. DWORD dwSize, dwSessionId, dwTry = 0;
  140. OSVERSIONINFO osvi;
  141. switch (Message) {
  142. case CPL_INIT: // Is there an applet ?
  143. // Set OS global.
  144. osvi.dwOSVersionInfoSize = sizeof(osvi);
  145. GetVersionEx(&osvi);
  146. g_bRunningUnderNT = (osvi.dwMajorVersion >= 5) &&
  147. (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT);
  148. // If we're running under NT don't allow power management UI
  149. // unless we have power management capabilities.
  150. if (g_bRunningUnderNT) {
  151. if (!PowerCapabilities()) {
  152. return FALSE;
  153. }
  154. }
  155. // Set global variables based on the machine capabilities.
  156. return InitCapabilities(&g_SysPwrCapabilities);
  157. case CPL_GETCOUNT: // PowerCfg.Cpl supports one applet.
  158. return 1;
  159. case CPL_INQUIRE: // Fill CplInfo structure
  160. lpCPlInfo = (LPCPLINFO)lParam;
  161. lpCPlInfo->idIcon = IDI_PWRMNG;
  162. lpCPlInfo->idName = IDS_APPNAME;
  163. lpCPlInfo->idInfo = IDS_INFO; // we have to use this in order to support infotips greater than 64 chars, which
  164. // is the max that the NEWCPLINFO struct supports
  165. lpCPlInfo->lData = 0;
  166. return 1;
  167. case CPL_NEWINQUIRE:
  168. lpNewCPLInfo = (LPNEWCPLINFO)lParam;
  169. memset(lpNewCPLInfo, 0, sizeof(NEWCPLINFO));
  170. lpNewCPLInfo->dwSize = sizeof(NEWCPLINFO);
  171. lpNewCPLInfo->hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_PWRMNG));
  172. LoadString(g_hInstance, IDS_APPNAME, lpNewCPLInfo->szName, sizeof(lpNewCPLInfo->szName));
  173. LoadString(g_hInstance, IDS_INFO, lpNewCPLInfo->szInfo, sizeof(lpNewCPLInfo->szInfo));
  174. lstrcpy(lpNewCPLInfo->szHelpFile, TEXT(""));
  175. return 1;
  176. case CPL_DBLCLK: // This applet has been chosen to run
  177. case CPL_STARTWPARMS: // Started from RUNDLL
  178. // Initialize the common controls.
  179. InitCommonControls();
  180. // Sync the current scheme registry and PPM.
  181. SyncRegPPM();
  182. // Build the displayed pages base on system capabilities.
  183. BuildPages(&g_SysPwrCapabilities, g_TopLevelPages);
  184. // Will return FALSE if we didn't display any pages.
  185. return DoPropSheetPages(hCPLWnd, &(g_TopLevelPages[0]),
  186. g_szRegOptionalPages);
  187. case CPL_EXIT: // This applet must die
  188. case CPL_STOP:
  189. break;
  190. case CPL_SELECT: // This applet has been selected
  191. break;
  192. }
  193. return FALSE;
  194. }
  195. /*******************************************************************************
  196. *
  197. * LoadDynamicString
  198. *
  199. * DESCRIPTION:
  200. * Wrapper for the FormatMessage function that loads a string from our
  201. * resource table into a dynamically allocated buffer, optionally filling
  202. * it with the variable arguments passed.
  203. *
  204. * PARAMETERS:
  205. * StringID, resource identifier of the string to use.
  206. * (optional), parameters to use to format the string message.
  207. *
  208. *******************************************************************************/
  209. LPTSTR CDECL LoadDynamicString( UINT StringID, ... )
  210. {
  211. va_list Marker;
  212. TCHAR Buffer[256];
  213. LPTSTR pStr;
  214. int iLen;
  215. // va_start is a macro...it breaks when you use it as an assign...on ALPHA.
  216. va_start(Marker, StringID);
  217. iLen = LoadString(g_hInstance, StringID, Buffer, ARRAYSIZE(Buffer));
  218. if (iLen == 0) {
  219. DebugPrint( "LoadDynamicString: LoadString on: %X failed", StringID);
  220. return NULL;
  221. }
  222. FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  223. (LPVOID) (LPTSTR) Buffer, 0, 0, (LPTSTR) &pStr, 0, &Marker);
  224. return pStr;
  225. }
  226. /*******************************************************************************
  227. *
  228. * DisplayFreeStr
  229. *
  230. * DESCRIPTION:
  231. *
  232. * PARAMETERS:
  233. *
  234. *******************************************************************************/
  235. LPTSTR DisplayFreeStr(HWND hWnd, UINT uID, LPTSTR pStr, BOOL bFree)
  236. {
  237. if (pStr) {
  238. SetDlgItemText(hWnd, uID, pStr);
  239. ShowWindow(GetDlgItem(hWnd, uID), SW_SHOWNOACTIVATE);
  240. if (bFree) {
  241. LocalFree(pStr);
  242. return NULL;
  243. }
  244. }
  245. else {
  246. ShowWindow(GetDlgItem(hWnd, uID), SW_HIDE);
  247. }
  248. return pStr;
  249. }
  250. /*******************************************************************************
  251. *
  252. * ValidateUISchemeFields
  253. *
  254. * DESCRIPTION:
  255. * Validate only the data values which are set by our UI.
  256. *
  257. * PARAMETERS:
  258. *
  259. *******************************************************************************/
  260. BOOLEAN ValidateUISchemeFields(PPOWER_POLICY ppp)
  261. {
  262. POWER_POLICY pp;
  263. static PGLOBAL_POWER_POLICY pgpp;
  264. memcpy(&pp, ppp, sizeof(pp));
  265. if (ValidatePowerPolicies(NULL, &pp)) {
  266. if (g_SysPwrCapabilities.HiberFilePresent) {
  267. ppp->mach.DozeS4TimeoutAc = pp.mach.DozeS4TimeoutAc;
  268. ppp->mach.DozeS4TimeoutDc = pp.mach.DozeS4TimeoutDc;
  269. }
  270. if (g_SysPwrCapabilities.SystemS1 ||
  271. g_SysPwrCapabilities.SystemS2 ||
  272. g_SysPwrCapabilities.SystemS3) {
  273. ppp->user.IdleTimeoutAc = pp.user.IdleTimeoutAc;
  274. ppp->user.IdleTimeoutDc = pp.user.IdleTimeoutDc;
  275. }
  276. if (g_bVideoLowPowerSupported) {
  277. ppp->user.VideoTimeoutAc = pp.user.VideoTimeoutAc;
  278. ppp->user.VideoTimeoutDc = pp.user.VideoTimeoutDc;
  279. }
  280. if (g_SysPwrCapabilities.DiskSpinDown) {
  281. ppp->user.SpindownTimeoutAc = pp.user.SpindownTimeoutAc;
  282. ppp->user.SpindownTimeoutDc = pp.user.SpindownTimeoutDc;
  283. }
  284. return TRUE;
  285. }
  286. return FALSE;
  287. }
  288. /*******************************************************************************
  289. *
  290. * GetGlobalPwrPolicy
  291. *
  292. * DESCRIPTION:
  293. * Read the global power policy and validate only the data values which are
  294. * set by our UI.
  295. *
  296. * PARAMETERS:
  297. *
  298. *******************************************************************************/
  299. BOOLEAN GetGlobalPwrPolicy(PGLOBAL_POWER_POLICY pgpp)
  300. {
  301. int i;
  302. GLOBAL_POWER_POLICY gpp;
  303. if (ReadGlobalPwrPolicy(pgpp)) {
  304. memcpy(&gpp, pgpp, sizeof(gpp));
  305. if (ValidatePowerPolicies(&gpp, NULL)) {
  306. if (g_SysPwrCapabilities.PowerButtonPresent &&
  307. !g_SysPwrCapabilities.SleepButtonPresent) {
  308. pgpp->user.PowerButtonAc = gpp.user.PowerButtonAc;
  309. pgpp->user.PowerButtonDc = gpp.user.PowerButtonDc;
  310. }
  311. if (g_SysPwrCapabilities.LidPresent) {
  312. pgpp->user.LidCloseAc = gpp.user.LidCloseAc;
  313. pgpp->user.LidCloseDc = gpp.user.LidCloseDc;
  314. }
  315. if (g_SysPwrCapabilities.SystemBatteriesPresent) {
  316. for (i = 0; i < NUM_DISCHARGE_POLICIES; i++) {
  317. pgpp->user.DischargePolicy[i] = gpp.user.DischargePolicy[i];
  318. }
  319. }
  320. pgpp->user.GlobalFlags = gpp.user.GlobalFlags;
  321. return TRUE;
  322. }
  323. }
  324. return FALSE;
  325. }
  326. /*******************************************************************************
  327. *
  328. * ErrorMsgBox
  329. *
  330. * DESCRIPTION:
  331. * Display a messag box for system message strings specified by dwErr and
  332. * title string specified by uiTitleID.
  333. *
  334. * PARAMETERS:
  335. *
  336. *******************************************************************************/
  337. int ErrorMsgBox(
  338. HWND hwnd,
  339. DWORD dwErr,
  340. UINT uiTitleID)
  341. {
  342. LPTSTR pszErr = NULL;
  343. LPTSTR pszTitle = NULL;
  344. TCHAR szUnknownErr[64];
  345. UINT idRet;
  346. if (dwErr == NO_ERROR)
  347. {
  348. dwErr = GetLastError();
  349. }
  350. pszTitle = LoadDynamicString(uiTitleID);
  351. if (dwErr != NO_ERROR)
  352. {
  353. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  354. NULL, dwErr, 0, (LPTSTR)&pszErr, 1, NULL);
  355. }
  356. if (NULL == pszErr)
  357. {
  358. LoadString(g_hInstance, IDS_UNKNOWN_ERROR, szUnknownErr, ARRAYSIZE(szUnknownErr));
  359. pszErr = szUnknownErr;
  360. }
  361. idRet = MessageBox(hwnd, pszErr, pszTitle, MB_ICONEXCLAMATION);
  362. if (pszTitle)
  363. LocalFree(pszTitle);
  364. if ((pszErr) && (pszErr != szUnknownErr))
  365. LocalFree(pszErr);
  366. return idRet;
  367. }
  368. /*******************************************************************************
  369. *
  370. * WritePwrSchemeReport
  371. *
  372. * DESCRIPTION:
  373. * Cover for WritePwrScheme with error reporting.
  374. *
  375. * PARAMETERS:
  376. *
  377. *******************************************************************************/
  378. BOOLEAN WritePwrSchemeReport(
  379. HWND hwnd,
  380. PUINT puiID,
  381. LPTSTR lpszSchemeName,
  382. LPTSTR lpszDescription,
  383. PPOWER_POLICY lpScheme
  384. )
  385. {
  386. if (WritePwrScheme(puiID, lpszSchemeName, lpszDescription, lpScheme)) {
  387. return TRUE;
  388. }
  389. else {
  390. ErrorMsgBox(hwnd, NO_ERROR, IDS_UNABLETOSETPOLICY);
  391. return FALSE;
  392. }
  393. }
  394. /*******************************************************************************
  395. *
  396. * WriteGlobalPwrPolicyReport
  397. *
  398. * DESCRIPTION:
  399. * Cover for WriteGlobalPwrPolicy with error reporting.
  400. *
  401. * PARAMETERS:
  402. *
  403. *******************************************************************************/
  404. BOOLEAN WriteGlobalPwrPolicyReport(
  405. HWND hwnd,
  406. PGLOBAL_POWER_POLICY pgpp,
  407. BOOL fDisplayErrorUI
  408. )
  409. {
  410. if (WriteGlobalPwrPolicy(pgpp))
  411. {
  412. return TRUE;
  413. }
  414. else
  415. {
  416. if (fDisplayErrorUI)
  417. {
  418. ErrorMsgBox(hwnd, NO_ERROR, IDS_UNABLETOSETGLOBALPOLICY);
  419. }
  420. return FALSE;
  421. }
  422. }
  423. /*******************************************************************************
  424. *
  425. * SetActivePwrSchemeReport
  426. *
  427. * DESCRIPTION:
  428. * Cover for WriteGlobalPwrPolicy with error reporting.
  429. *
  430. * PARAMETERS:
  431. *
  432. *******************************************************************************/
  433. BOOLEAN SetActivePwrSchemeReport(
  434. HWND hwnd,
  435. UINT uiID,
  436. PGLOBAL_POWER_POLICY pgpp,
  437. PPOWER_POLICY ppp)
  438. {
  439. if (SetActivePwrScheme(uiID, pgpp, ppp)) {
  440. return TRUE;
  441. }
  442. else {
  443. ErrorMsgBox(hwnd, NO_ERROR, IDS_UNABLETOSETACTIVEPOLICY);
  444. return FALSE;
  445. }
  446. }
  447. /*******************************************************************************
  448. *
  449. * P R I V A T E F U N C T I O N S
  450. *
  451. *******************************************************************************/
  452. /*******************************************************************************
  453. *
  454. * BuildPages
  455. *
  456. * DESCRIPTION:
  457. * Build the g_TopLevelPages array based on the machine capabilities. The
  458. * order of the tabs\pages is set here.
  459. *
  460. * PARAMETERS:
  461. *
  462. *******************************************************************************/
  463. int BuildPages(PSYSTEM_POWER_CAPABILITIES pspc, PPOWER_PAGES ppp)
  464. {
  465. int iPageCount = 1; // We always have at least the power scheme page.
  466. // Do we have system batteries? Different dialog templates will be used
  467. // depending on the answer to this question.
  468. if (pspc->SystemBatteriesPresent) {
  469. AppendPropSheetPage(ppp, IDD_POWERSCHEME, PowerSchemeDlgProc);
  470. AppendPropSheetPage(ppp, IDD_ALARMPOLICY, AlarmDlgProc);
  471. iPageCount++;
  472. // Is there a battery driver that the battery meter can query?
  473. if (BatMeterCapabilities(&g_puiBatCount)) {
  474. AppendPropSheetPage(ppp, IDD_BATMETERCFG, BatMeterCfgDlgProc);
  475. iPageCount++;
  476. }
  477. }
  478. else {
  479. // No battery pages.
  480. AppendPropSheetPage(ppp, IDD_POWERSCHEME_NOBAT, PowerSchemeDlgProc);
  481. }
  482. // Always show the Advanced page.
  483. AppendPropSheetPage(ppp, IDD_ADVANCEDPOLICY, AdvancedDlgProc);
  484. iPageCount++;
  485. // Can we put up the hibernate page?
  486. if (pspc->SystemS4) {
  487. AppendPropSheetPage(ppp, IDD_HIBERNATE, HibernateDlgProc);
  488. iPageCount++;
  489. }
  490. #ifdef WINNT
  491. if (pspc->ApmPresent) {
  492. //
  493. // Is APM present on the machine? This page is
  494. // not shown if ACPI is present
  495. //
  496. AppendPropSheetPage(ppp, IDD_APM, APMDlgProc);
  497. iPageCount++;
  498. }
  499. if (pspc->UpsPresent) {
  500. AppendPropSheetPage(ppp, IDD_UPS, UPSMainPageProc);
  501. iPageCount++;
  502. }
  503. #endif
  504. return iPageCount;
  505. }
  506. /*******************************************************************************
  507. *
  508. * InitCapabilities
  509. *
  510. * DESCRIPTION:
  511. * Call down to the PPM to get power management capabilities and set
  512. * global variables based on the results.
  513. *
  514. * PARAMETERS:
  515. *
  516. *******************************************************************************/
  517. BOOL InitCapabilities(PSYSTEM_POWER_CAPABILITIES pspc)
  518. {
  519. UINT i, uiGran = 0, uiMax, uiMin;
  520. ADMINISTRATOR_POWER_POLICY app;
  521. int dummy;
  522. // Set hard limits. These may be overridden by optional registry values.
  523. g_uiVideoTimeoutMaxMin = MAKELONG((short) MAX_VIDEO_TIMEOUT, (short) 1);
  524. g_uiSpindownMaxMin = MAKELONG((short) MAX_SPINDOWN_TIMEOUT,(short) 1);
  525. g_dwNumSleepStates = 0;
  526. if (!GetPwrCapabilities(pspc)) {
  527. return FALSE;
  528. }
  529. if (pspc->SystemS1) {
  530. g_dwNumSleepStates++;
  531. }
  532. if (pspc->SystemS2) {
  533. g_dwNumSleepStates++;
  534. }
  535. if (pspc->SystemS3) {
  536. g_dwNumSleepStates++;
  537. }
  538. if (pspc->SystemS4) {
  539. g_dwNumSleepStates++;
  540. }
  541. // Get administrator overrides if present.
  542. if (IsAdminOverrideActive(&app)) {
  543. if (app.MaxVideoTimeout > -1) {
  544. uiMin = LOWORD(g_uiVideoTimeoutMaxMin);
  545. uiMax = app.MaxVideoTimeout;
  546. g_uiVideoTimeoutMaxMin = MAKELONG((short) uiMax,(short) uiMin);
  547. }
  548. if (app.MaxSleep < PowerSystemHibernate) {
  549. g_dwNumSleepStates = (DWORD)app.MaxSleep;
  550. }
  551. }
  552. // Get the optional disk spindown timeout range.
  553. if (GetPwrDiskSpindownRange(&uiMax, &uiMin)) {
  554. g_uiSpindownMaxMin = MAKELONG((short) uiMax,(short) uiMin);
  555. }
  556. if (g_dwNumSleepStates > 1) {
  557. g_dwSleepStatesMaxMin =
  558. MAKELONG((short) 0, (short) g_dwNumSleepStates - 1);
  559. }
  560. g_dwBattryLevelMaxMin = MAKELONG((short)0, (short)100);
  561. g_dwFanThrottleMaxMin = MAKELONG((short)0, (short)100);
  562. // Call will fail if monitor or adapter don't support DPMS.
  563. g_bVideoLowPowerSupported = SystemParametersInfo(SPI_GETLOWPOWERACTIVE,
  564. 0, &dummy, 0);
  565. if (!g_bVideoLowPowerSupported) {
  566. g_bVideoLowPowerSupported = SystemParametersInfo(SPI_GETPOWEROFFACTIVE,
  567. 0, &dummy, 0);
  568. }
  569. #ifdef WINNT
  570. //
  571. // Check to see if APM is present
  572. //
  573. pspc->ApmPresent = IsNtApmPresent(pspc);
  574. pspc->UpsPresent = IsUpsPresent(pspc);
  575. #endif
  576. return TRUE;
  577. }
  578. /*******************************************************************************
  579. *
  580. * SyncRegPPM
  581. *
  582. * DESCRIPTION:
  583. * Call down to the PPM to get the current power policies and write them
  584. * to the registry. This is done in case the PPM is out of sync with the
  585. * PowerCfg registry settings. Requested by JVert.
  586. *
  587. * PARAMETERS:
  588. *
  589. *******************************************************************************/
  590. VOID SyncRegPPM(VOID)
  591. {
  592. GLOBAL_POWER_POLICY gpp;
  593. POWER_POLICY pp;
  594. UINT uiID, uiFlags = 0;
  595. if (ReadGlobalPwrPolicy(&gpp)) {
  596. uiFlags = gpp.user.GlobalFlags;
  597. }
  598. if (GetActivePwrScheme(&uiID)) {
  599. // Get the current PPM settings.
  600. if (GetCurrentPowerPolicies(&gpp, &pp)) {
  601. SetActivePwrScheme(uiID, &gpp, &pp);
  602. }
  603. }
  604. gpp.user.GlobalFlags |= uiFlags;
  605. }