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.

2480 lines
64 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. powercfg.c
  5. Abstract:
  6. Allows users to view and modify power schemes and system power settings
  7. from the command line. May be useful in unattended configuration and
  8. for headless systems.
  9. Author:
  10. Ben Hertzberg (t-benher) 1-Jun-2001
  11. Revision History:
  12. Ben Hertzberg (t-benher) 15-Jun-2001 - CPU throttle added
  13. Ben Hertzberg (t-benher) 4-Jun-2001 - import/export added
  14. Ben Hertzberg (t-benher) 1-Jun-2001 - created it.
  15. --*/
  16. // standard win includes
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. // app-specific includes
  22. #include <stdio.h>
  23. #include "cmdline.h"
  24. #include "cmdlineres.h"
  25. #include "powrprof.h"
  26. #include "powercfg.h"
  27. #include "resource.h"
  28. // app-specific structures
  29. // structure to manage the scheme list information.
  30. // note that descriptions are currently not visible in the
  31. // GUI tool (as of 6-1-2001), so they are not visible in this
  32. // app either, although the framework is already there if
  33. // someone decides to add the descriptions at a later date.
  34. typedef struct _SCHEME_LIST
  35. {
  36. LIST_ENTRY le;
  37. UINT uiID;
  38. LPTSTR lpszName;
  39. LPTSTR lpszDesc;
  40. PPOWER_POLICY ppp;
  41. PMACHINE_PROCESSOR_POWER_POLICY pmppp;
  42. } SCHEME_LIST, *PSCHEME_LIST;
  43. // structure to manage the change parameters
  44. typedef struct _CHANGE_PARAM
  45. {
  46. BOOL bVideoTimeoutAc;
  47. ULONG ulVideoTimeoutAc;
  48. BOOL bVideoTimeoutDc;
  49. ULONG ulVideoTimeoutDc;
  50. BOOL bSpindownTimeoutAc;
  51. ULONG ulSpindownTimeoutAc;
  52. BOOL bSpindownTimeoutDc;
  53. ULONG ulSpindownTimeoutDc;
  54. BOOL bIdleTimeoutAc;
  55. ULONG ulIdleTimeoutAc;
  56. BOOL bIdleTimeoutDc;
  57. ULONG ulIdleTimeoutDc;
  58. BOOL bDozeS4TimeoutAc;
  59. ULONG ulDozeS4TimeoutAc;
  60. BOOL bDozeS4TimeoutDc;
  61. ULONG ulDozeS4TimeoutDc;
  62. BOOL bDynamicThrottleAc;
  63. LPTSTR lpszDynamicThrottleAc;
  64. BOOL bDynamicThrottleDc;
  65. LPTSTR lpszDynamicThrottleDc;
  66. } CHANGE_PARAM, *PCHANGE_PARAM;
  67. // forward decl's
  68. BOOL
  69. DoList();
  70. BOOL
  71. DoQuery(
  72. LPCTSTR lpszName,
  73. BOOL bNameSpecified
  74. );
  75. BOOL
  76. DoCreate(
  77. LPTSTR lpszName
  78. );
  79. BOOL
  80. DoDelete(
  81. LPCTSTR lpszName
  82. );
  83. BOOL
  84. DoSetActive(
  85. LPCTSTR lpszName
  86. );
  87. BOOL
  88. DoChange(
  89. LPCTSTR lpszName,
  90. PCHANGE_PARAM pcp
  91. );
  92. BOOL
  93. DoHibernate(
  94. LPCTSTR lpszBoolStr
  95. );
  96. BOOL
  97. DoExport(
  98. LPCTSTR lpszName,
  99. LPCTSTR lpszFile
  100. );
  101. BOOL
  102. DoImport(
  103. LPCTSTR lpszName,
  104. LPCTSTR lpszFile
  105. );
  106. BOOL
  107. DoUsage();
  108. // global data
  109. LPCTSTR g_lpszErr = NULL_STRING; // string holding const error description
  110. LPTSTR g_lpszErr2 = NULL; // string holding dyn-alloc error msg
  111. TCHAR g_lpszBuf[256]; // formatting buffer
  112. BOOL g_bHiberFileSupported = FALSE; // true iff hiberfile supported
  113. BOOL g_bHiberTimerSupported = FALSE; // true iff hibertimer supported
  114. BOOL g_bStandbySupported = FALSE; // true iff standby supported
  115. BOOL g_bMonitorPowerSupported = FALSE; // true iff has power support
  116. BOOL g_bDiskPowerSupported = FALSE; // true iff has power support
  117. BOOL g_bThrottleSupported = FALSE; // true iff has throttle support
  118. // functions
  119. DWORD _cdecl
  120. _tmain(
  121. DWORD argc,
  122. LPCTSTR argv[]
  123. )
  124. /*++
  125. Routine Description:
  126. This routine is the main function. It parses parameters and takes
  127. apprpriate action.
  128. Arguments:
  129. argc - indicates the number of arguments
  130. argv - array of null terminated strings indicating arguments. See usage
  131. for actual meaning of arguments.
  132. Return Value:
  133. EXIT_SUCCESS if successful
  134. EXIT_FAILURE if something goes wrong
  135. --*/
  136. {
  137. // command line flags
  138. BOOL bList = FALSE;
  139. BOOL bQuery = FALSE;
  140. BOOL bCreate = FALSE;
  141. BOOL bDelete = FALSE;
  142. BOOL bSetActive = FALSE;
  143. BOOL bChange = FALSE;
  144. BOOL bHibernate = FALSE;
  145. BOOL bImport = FALSE;
  146. BOOL bExport = FALSE;
  147. BOOL bFile = FALSE;
  148. BOOL bUsage = FALSE;
  149. // error status
  150. BOOL bFail = FALSE;
  151. // dummy
  152. INT iDummy = 1;
  153. // parse result value vars
  154. LPTSTR lpszName = NULL;
  155. LPTSTR lpszBoolStr = NULL;
  156. LPTSTR lpszFile = NULL;
  157. LPTSTR lpszThrottleAcStr = NULL;
  158. LPTSTR lpszThrottleDcStr = NULL;
  159. CHANGE_PARAM tChangeParam;
  160. // parser info struct
  161. TCMDPARSER cmdOptions[NUM_CMDS];
  162. // system power caps struct
  163. SYSTEM_POWER_CAPABILITIES SysPwrCapabilities;
  164. // determine upper bound on input string length
  165. UINT uiMaxInLen = 0;
  166. DWORD dwIdx;
  167. for(dwIdx=1; dwIdx<argc; dwIdx++)
  168. {
  169. UINT uiCurLen = lstrlen(argv[dwIdx]);
  170. if (uiCurLen > uiMaxInLen)
  171. {
  172. uiMaxInLen = uiCurLen;
  173. }
  174. }
  175. // allocate space for scheme name and boolean string
  176. lpszName = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR));
  177. if (!lpszName)
  178. {
  179. DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY));
  180. return EXIT_FAILURE;
  181. }
  182. lpszBoolStr = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR));
  183. if (!lpszBoolStr)
  184. {
  185. LocalFree(lpszName);
  186. DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY));
  187. return EXIT_FAILURE;
  188. }
  189. if (uiMaxInLen < (UINT)lstrlen(GetResString(IDS_DEFAULT_FILENAME)))
  190. {
  191. lpszFile = LocalAlloc(LPTR,(lstrlen(GetResString(IDS_DEFAULT_FILENAME))+1)*sizeof(TCHAR));
  192. }
  193. else
  194. {
  195. lpszFile = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR));
  196. }
  197. if (!lpszFile)
  198. {
  199. LocalFree(lpszName);
  200. LocalFree(lpszBoolStr);
  201. DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY));
  202. return EXIT_FAILURE;
  203. }
  204. lpszThrottleAcStr = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR));
  205. if (!lpszThrottleAcStr)
  206. {
  207. LocalFree(lpszName);
  208. LocalFree(lpszBoolStr);
  209. LocalFree(lpszFile);
  210. DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY));
  211. return EXIT_FAILURE;
  212. }
  213. lpszThrottleDcStr = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR));
  214. if (!lpszThrottleDcStr)
  215. {
  216. LocalFree(lpszThrottleAcStr);
  217. LocalFree(lpszName);
  218. LocalFree(lpszBoolStr);
  219. LocalFree(lpszFile);
  220. DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY));
  221. return EXIT_FAILURE;
  222. }
  223. // initialize the allocated strings
  224. lstrcpy(lpszName,NULL_STRING);
  225. lstrcpy(lpszBoolStr,NULL_STRING);
  226. lstrcpy(lpszFile,GetResString(IDS_DEFAULT_FILENAME));
  227. lstrcpy(lpszThrottleAcStr,NULL_STRING);
  228. lstrcpy(lpszThrottleDcStr,NULL_STRING);
  229. // determine system capabilities
  230. if (GetPwrCapabilities(&SysPwrCapabilities))
  231. {
  232. g_bHiberFileSupported = SysPwrCapabilities.SystemS4;
  233. g_bHiberTimerSupported =
  234. (SysPwrCapabilities.RtcWake >= PowerSystemHibernate);
  235. g_bStandbySupported = SysPwrCapabilities.SystemS1 |
  236. SysPwrCapabilities.SystemS2 |
  237. SysPwrCapabilities.SystemS3;
  238. g_bDiskPowerSupported = SysPwrCapabilities.DiskSpinDown;
  239. g_bThrottleSupported = SysPwrCapabilities.ProcessorThrottle;
  240. g_bMonitorPowerSupported = SystemParametersInfo(
  241. SPI_GETLOWPOWERACTIVE,
  242. 0,
  243. &iDummy,
  244. 0
  245. );
  246. if (!g_bMonitorPowerSupported ) {
  247. g_bMonitorPowerSupported = SystemParametersInfo(
  248. SPI_GETPOWEROFFACTIVE,
  249. 0,
  250. &iDummy,
  251. 0
  252. );
  253. }
  254. }
  255. else
  256. {
  257. g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
  258. return EXIT_FAILURE;
  259. }
  260. //fill in the TCMDPARSER array
  261. // option 'list'
  262. cmdOptions[CMDINDEX_LIST].dwFlags = CP_MAIN_OPTION;
  263. cmdOptions[CMDINDEX_LIST].dwCount = 1;
  264. cmdOptions[CMDINDEX_LIST].dwActuals = 0;
  265. cmdOptions[CMDINDEX_LIST].pValue = &bList;
  266. cmdOptions[CMDINDEX_LIST].pFunction = NULL;
  267. cmdOptions[CMDINDEX_LIST].pFunctionData = NULL;
  268. lstrcpy(
  269. cmdOptions[CMDINDEX_LIST].szOption,
  270. CMDOPTION_LIST
  271. );
  272. lstrcpy(
  273. cmdOptions[CMDINDEX_LIST].szValues,
  274. NULL_STRING
  275. );
  276. // option 'query'
  277. cmdOptions[CMDINDEX_QUERY].dwFlags = CP_TYPE_TEXT |
  278. CP_VALUE_OPTIONAL |
  279. CP_MAIN_OPTION;
  280. cmdOptions[CMDINDEX_QUERY].dwCount = 1;
  281. cmdOptions[CMDINDEX_QUERY].dwActuals = 0;
  282. cmdOptions[CMDINDEX_QUERY].pValue = lpszName;
  283. cmdOptions[CMDINDEX_QUERY].pFunction = NULL;
  284. cmdOptions[CMDINDEX_QUERY].pFunctionData = NULL;
  285. lstrcpy(
  286. cmdOptions[CMDINDEX_QUERY].szOption,
  287. CMDOPTION_QUERY
  288. );
  289. lstrcpy(
  290. cmdOptions[CMDINDEX_QUERY].szValues,
  291. NULL_STRING
  292. );
  293. // option 'create'
  294. cmdOptions[CMDINDEX_CREATE].dwFlags = CP_TYPE_TEXT |
  295. CP_VALUE_MANDATORY |
  296. CP_MAIN_OPTION;
  297. cmdOptions[CMDINDEX_CREATE].dwCount = 1;
  298. cmdOptions[CMDINDEX_CREATE].dwActuals = 0;
  299. cmdOptions[CMDINDEX_CREATE].pValue = lpszName;
  300. cmdOptions[CMDINDEX_CREATE].pFunction = NULL;
  301. cmdOptions[CMDINDEX_CREATE].pFunctionData = NULL;
  302. lstrcpy(
  303. cmdOptions[CMDINDEX_CREATE].szOption,
  304. CMDOPTION_CREATE
  305. );
  306. lstrcpy(
  307. cmdOptions[CMDINDEX_CREATE].szValues,
  308. NULL_STRING
  309. );
  310. // option 'delete'
  311. cmdOptions[CMDINDEX_DELETE].dwFlags = CP_TYPE_TEXT |
  312. CP_VALUE_MANDATORY |
  313. CP_MAIN_OPTION;
  314. cmdOptions[CMDINDEX_DELETE].dwCount = 1;
  315. cmdOptions[CMDINDEX_DELETE].dwActuals = 0;
  316. cmdOptions[CMDINDEX_DELETE].pValue = lpszName;
  317. cmdOptions[CMDINDEX_DELETE].pFunction = NULL;
  318. cmdOptions[CMDINDEX_DELETE].pFunctionData = NULL;
  319. lstrcpy(
  320. cmdOptions[CMDINDEX_DELETE].szOption,
  321. CMDOPTION_DELETE
  322. );
  323. lstrcpy(
  324. cmdOptions[CMDINDEX_DELETE].szValues,
  325. NULL_STRING
  326. );
  327. // option 'setactive'
  328. cmdOptions[CMDINDEX_SETACTIVE].dwFlags = CP_TYPE_TEXT |
  329. CP_VALUE_MANDATORY |
  330. CP_MAIN_OPTION;
  331. cmdOptions[CMDINDEX_SETACTIVE].dwCount = 1;
  332. cmdOptions[CMDINDEX_SETACTIVE].dwActuals = 0;
  333. cmdOptions[CMDINDEX_SETACTIVE].pValue = lpszName;
  334. cmdOptions[CMDINDEX_SETACTIVE].pFunction = NULL;
  335. cmdOptions[CMDINDEX_SETACTIVE].pFunctionData = NULL;
  336. lstrcpy(
  337. cmdOptions[CMDINDEX_SETACTIVE].szOption,
  338. CMDOPTION_SETACTIVE
  339. );
  340. lstrcpy(
  341. cmdOptions[CMDINDEX_SETACTIVE].szValues,
  342. NULL_STRING
  343. );
  344. // option 'change'
  345. cmdOptions[CMDINDEX_CHANGE].dwFlags = CP_TYPE_TEXT |
  346. CP_VALUE_MANDATORY |
  347. CP_MAIN_OPTION;
  348. cmdOptions[CMDINDEX_CHANGE].dwCount = 1;
  349. cmdOptions[CMDINDEX_CHANGE].dwActuals = 0;
  350. cmdOptions[CMDINDEX_CHANGE].pValue = lpszName;
  351. cmdOptions[CMDINDEX_CHANGE].pFunction = NULL;
  352. cmdOptions[CMDINDEX_CHANGE].pFunctionData = NULL;
  353. lstrcpy(
  354. cmdOptions[CMDINDEX_CHANGE].szOption,
  355. CMDOPTION_CHANGE
  356. );
  357. lstrcpy(
  358. cmdOptions[CMDINDEX_CHANGE].szValues,
  359. NULL_STRING
  360. );
  361. // option 'hibernate'
  362. cmdOptions[CMDINDEX_HIBERNATE].dwFlags = CP_TYPE_TEXT |
  363. CP_VALUE_MANDATORY |
  364. CP_MAIN_OPTION;
  365. cmdOptions[CMDINDEX_HIBERNATE].dwCount = 1;
  366. cmdOptions[CMDINDEX_HIBERNATE].dwActuals = 0;
  367. cmdOptions[CMDINDEX_HIBERNATE].pValue = lpszBoolStr;
  368. cmdOptions[CMDINDEX_HIBERNATE].pFunction = NULL;
  369. cmdOptions[CMDINDEX_HIBERNATE].pFunctionData = NULL;
  370. lstrcpy(
  371. cmdOptions[CMDINDEX_HIBERNATE].szOption,
  372. CMDOPTION_HIBERNATE
  373. );
  374. lstrcpy(
  375. cmdOptions[CMDINDEX_HIBERNATE].szValues,
  376. NULL_STRING
  377. );
  378. // option 'export'
  379. cmdOptions[CMDINDEX_EXPORT].dwFlags = CP_TYPE_TEXT |
  380. CP_VALUE_MANDATORY |
  381. CP_MAIN_OPTION;
  382. cmdOptions[CMDINDEX_EXPORT].dwCount = 1;
  383. cmdOptions[CMDINDEX_EXPORT].dwActuals = 0;
  384. cmdOptions[CMDINDEX_EXPORT].pValue = lpszName;
  385. cmdOptions[CMDINDEX_EXPORT].pFunction = NULL;
  386. cmdOptions[CMDINDEX_EXPORT].pFunctionData = NULL;
  387. lstrcpy(
  388. cmdOptions[CMDINDEX_EXPORT].szOption,
  389. CMDOPTION_EXPORT
  390. );
  391. lstrcpy(
  392. cmdOptions[CMDINDEX_EXPORT].szValues,
  393. NULL_STRING
  394. );
  395. // option 'import'
  396. cmdOptions[CMDINDEX_IMPORT].dwFlags = CP_TYPE_TEXT |
  397. CP_VALUE_MANDATORY |
  398. CP_MAIN_OPTION;
  399. cmdOptions[CMDINDEX_IMPORT].dwCount = 1;
  400. cmdOptions[CMDINDEX_IMPORT].dwActuals = 0;
  401. cmdOptions[CMDINDEX_IMPORT].pValue = lpszName;
  402. cmdOptions[CMDINDEX_IMPORT].pFunction = NULL;
  403. cmdOptions[CMDINDEX_IMPORT].pFunctionData = NULL;
  404. lstrcpy(
  405. cmdOptions[CMDINDEX_IMPORT].szOption,
  406. CMDOPTION_IMPORT
  407. );
  408. lstrcpy(
  409. cmdOptions[CMDINDEX_IMPORT].szValues,
  410. NULL_STRING
  411. );
  412. // option 'usage'
  413. cmdOptions[CMDINDEX_USAGE].dwFlags = CP_USAGE |
  414. CP_MAIN_OPTION;
  415. cmdOptions[CMDINDEX_USAGE].dwCount = 1;
  416. cmdOptions[CMDINDEX_USAGE].dwActuals = 0;
  417. cmdOptions[CMDINDEX_USAGE].pValue = &bUsage;
  418. cmdOptions[CMDINDEX_USAGE].pFunction = NULL;
  419. cmdOptions[CMDINDEX_USAGE].pFunctionData = NULL;
  420. lstrcpy(
  421. cmdOptions[CMDINDEX_USAGE].szOption,
  422. CMDOPTION_USAGE
  423. );
  424. lstrcpy(
  425. cmdOptions[CMDINDEX_USAGE].szValues,
  426. NULL_STRING
  427. );
  428. // sub-option 'monitor-timeout-ac'
  429. cmdOptions[CMDINDEX_MONITOR_OFF_AC].dwFlags = CP_TYPE_UNUMERIC |
  430. CP_VALUE_MANDATORY;
  431. cmdOptions[CMDINDEX_MONITOR_OFF_AC].dwCount = 1;
  432. cmdOptions[CMDINDEX_MONITOR_OFF_AC].dwActuals = 0;
  433. cmdOptions[CMDINDEX_MONITOR_OFF_AC].pValue =
  434. &tChangeParam.ulVideoTimeoutAc;
  435. cmdOptions[CMDINDEX_MONITOR_OFF_AC].pFunction = NULL;
  436. cmdOptions[CMDINDEX_MONITOR_OFF_AC].pFunctionData = NULL;
  437. lstrcpy(
  438. cmdOptions[CMDINDEX_MONITOR_OFF_AC].szOption,
  439. CMDOPTION_MONITOR_OFF_AC
  440. );
  441. lstrcpy(
  442. cmdOptions[CMDINDEX_MONITOR_OFF_AC].szValues,
  443. NULL_STRING
  444. );
  445. // sub-option 'monitor-timeout-dc'
  446. cmdOptions[CMDINDEX_MONITOR_OFF_DC].dwFlags = CP_TYPE_UNUMERIC |
  447. CP_VALUE_MANDATORY;
  448. cmdOptions[CMDINDEX_MONITOR_OFF_DC].dwCount = 1;
  449. cmdOptions[CMDINDEX_MONITOR_OFF_DC].dwActuals = 0;
  450. cmdOptions[CMDINDEX_MONITOR_OFF_DC].pValue =
  451. &tChangeParam.ulVideoTimeoutDc;
  452. cmdOptions[CMDINDEX_MONITOR_OFF_DC].pFunction = NULL;
  453. cmdOptions[CMDINDEX_MONITOR_OFF_DC].pFunctionData = NULL;
  454. lstrcpy(
  455. cmdOptions[CMDINDEX_MONITOR_OFF_DC].szOption,
  456. CMDOPTION_MONITOR_OFF_DC
  457. );
  458. lstrcpy(
  459. cmdOptions[CMDINDEX_MONITOR_OFF_DC].szValues,
  460. NULL_STRING
  461. );
  462. // sub-option 'disk-timeout-ac'
  463. cmdOptions[CMDINDEX_DISK_OFF_AC].dwFlags = CP_TYPE_UNUMERIC |
  464. CP_VALUE_MANDATORY;
  465. cmdOptions[CMDINDEX_DISK_OFF_AC].dwCount = 1;
  466. cmdOptions[CMDINDEX_DISK_OFF_AC].dwActuals = 0;
  467. cmdOptions[CMDINDEX_DISK_OFF_AC].pValue =
  468. &tChangeParam.ulSpindownTimeoutAc;
  469. cmdOptions[CMDINDEX_DISK_OFF_AC].pFunction = NULL;
  470. cmdOptions[CMDINDEX_DISK_OFF_AC].pFunctionData = NULL;
  471. lstrcpy(
  472. cmdOptions[CMDINDEX_DISK_OFF_AC].szOption,
  473. CMDOPTION_DISK_OFF_AC
  474. );
  475. lstrcpy(
  476. cmdOptions[CMDINDEX_DISK_OFF_AC].szValues,
  477. NULL_STRING
  478. );
  479. // sub-option 'disk-timeout-dc'
  480. cmdOptions[CMDINDEX_DISK_OFF_DC].dwFlags = CP_TYPE_UNUMERIC |
  481. CP_VALUE_MANDATORY;
  482. cmdOptions[CMDINDEX_DISK_OFF_DC].dwCount = 1;
  483. cmdOptions[CMDINDEX_DISK_OFF_DC].dwActuals = 0;
  484. cmdOptions[CMDINDEX_DISK_OFF_DC].pValue =
  485. &tChangeParam.ulSpindownTimeoutDc;
  486. cmdOptions[CMDINDEX_DISK_OFF_DC].pFunction = NULL;
  487. cmdOptions[CMDINDEX_DISK_OFF_DC].pFunctionData = NULL;
  488. lstrcpy(
  489. cmdOptions[CMDINDEX_DISK_OFF_DC].szOption,
  490. CMDOPTION_DISK_OFF_DC
  491. );
  492. lstrcpy(
  493. cmdOptions[CMDINDEX_DISK_OFF_DC].szValues,
  494. NULL_STRING
  495. );
  496. // sub-option 'standby-timeout-ac'
  497. cmdOptions[CMDINDEX_STANDBY_AC].dwFlags = CP_TYPE_UNUMERIC |
  498. CP_VALUE_MANDATORY;
  499. cmdOptions[CMDINDEX_STANDBY_AC].dwCount = 1;
  500. cmdOptions[CMDINDEX_STANDBY_AC].dwActuals = 0;
  501. cmdOptions[CMDINDEX_STANDBY_AC].pValue =
  502. &tChangeParam.ulIdleTimeoutAc;
  503. cmdOptions[CMDINDEX_STANDBY_AC].pFunction = NULL;
  504. cmdOptions[CMDINDEX_STANDBY_AC].pFunctionData = NULL;
  505. lstrcpy(
  506. cmdOptions[CMDINDEX_STANDBY_AC].szOption,
  507. CMDOPTION_STANDBY_AC
  508. );
  509. lstrcpy(
  510. cmdOptions[CMDINDEX_STANDBY_AC].szValues,
  511. NULL_STRING
  512. );
  513. // sub-option 'standby-timeout-dc'
  514. cmdOptions[CMDINDEX_STANDBY_DC].dwFlags = CP_TYPE_UNUMERIC |
  515. CP_VALUE_MANDATORY;
  516. cmdOptions[CMDINDEX_STANDBY_DC].dwCount = 1;
  517. cmdOptions[CMDINDEX_STANDBY_DC].dwActuals = 0;
  518. cmdOptions[CMDINDEX_STANDBY_DC].pValue =
  519. &tChangeParam.ulIdleTimeoutDc;
  520. cmdOptions[CMDINDEX_STANDBY_DC].pFunction = NULL;
  521. cmdOptions[CMDINDEX_STANDBY_DC].pFunctionData = NULL;
  522. lstrcpy(
  523. cmdOptions[CMDINDEX_STANDBY_DC].szOption,
  524. CMDOPTION_STANDBY_DC
  525. );
  526. lstrcpy(
  527. cmdOptions[CMDINDEX_STANDBY_DC].szValues,
  528. NULL_STRING
  529. );
  530. // sub-option 'hibernate-timeout-ac'
  531. cmdOptions[CMDINDEX_HIBER_AC].dwFlags = CP_TYPE_UNUMERIC |
  532. CP_VALUE_MANDATORY;
  533. cmdOptions[CMDINDEX_HIBER_AC].dwCount = 1;
  534. cmdOptions[CMDINDEX_HIBER_AC].dwActuals = 0;
  535. cmdOptions[CMDINDEX_HIBER_AC].pValue =
  536. &tChangeParam.ulDozeS4TimeoutAc;
  537. cmdOptions[CMDINDEX_HIBER_AC].pFunction = NULL;
  538. cmdOptions[CMDINDEX_HIBER_AC].pFunctionData = NULL;
  539. lstrcpy(
  540. cmdOptions[CMDINDEX_HIBER_AC].szOption,
  541. CMDOPTION_HIBER_AC
  542. );
  543. lstrcpy(
  544. cmdOptions[CMDINDEX_HIBER_AC].szValues,
  545. NULL_STRING
  546. );
  547. // sub-option 'hibernate-timeout-dc'
  548. cmdOptions[CMDINDEX_HIBER_DC].dwFlags = CP_TYPE_UNUMERIC |
  549. CP_VALUE_MANDATORY;
  550. cmdOptions[CMDINDEX_HIBER_DC].dwCount = 1;
  551. cmdOptions[CMDINDEX_HIBER_DC].dwActuals = 0;
  552. cmdOptions[CMDINDEX_HIBER_DC].pValue =
  553. &tChangeParam.ulDozeS4TimeoutDc;
  554. cmdOptions[CMDINDEX_HIBER_DC].pFunction = NULL;
  555. cmdOptions[CMDINDEX_HIBER_DC].pFunctionData = NULL;
  556. lstrcpy(
  557. cmdOptions[CMDINDEX_HIBER_DC].szOption,
  558. CMDOPTION_HIBER_DC
  559. );
  560. lstrcpy(
  561. cmdOptions[CMDINDEX_HIBER_DC].szValues,
  562. NULL_STRING
  563. );
  564. // sub-option 'processor-throttle-ac'
  565. cmdOptions[CMDINDEX_THROTTLE_AC].dwFlags = CP_TYPE_TEXT |
  566. CP_VALUE_MANDATORY;
  567. cmdOptions[CMDINDEX_THROTTLE_AC].dwCount = 1;
  568. cmdOptions[CMDINDEX_THROTTLE_AC].dwActuals = 0;
  569. cmdOptions[CMDINDEX_THROTTLE_AC].pValue = lpszThrottleAcStr;
  570. cmdOptions[CMDINDEX_THROTTLE_AC].pFunction = NULL;
  571. cmdOptions[CMDINDEX_THROTTLE_AC].pFunctionData = NULL;
  572. lstrcpy(
  573. cmdOptions[CMDINDEX_THROTTLE_AC].szOption,
  574. CMDOPTION_THROTTLE_AC
  575. );
  576. lstrcpy(
  577. cmdOptions[CMDINDEX_THROTTLE_AC].szValues,
  578. NULL_STRING
  579. );
  580. // sub-option 'processor-throttle-dc'
  581. cmdOptions[CMDINDEX_THROTTLE_DC].dwFlags = CP_TYPE_TEXT |
  582. CP_VALUE_MANDATORY;
  583. cmdOptions[CMDINDEX_THROTTLE_DC].dwCount = 1;
  584. cmdOptions[CMDINDEX_THROTTLE_DC].dwActuals = 0;
  585. cmdOptions[CMDINDEX_THROTTLE_DC].pValue = lpszThrottleDcStr;
  586. cmdOptions[CMDINDEX_THROTTLE_DC].pFunction = NULL;
  587. cmdOptions[CMDINDEX_THROTTLE_DC].pFunctionData = NULL;
  588. lstrcpy(
  589. cmdOptions[CMDINDEX_THROTTLE_DC].szOption,
  590. CMDOPTION_THROTTLE_DC
  591. );
  592. lstrcpy(
  593. cmdOptions[CMDINDEX_THROTTLE_DC].szValues,
  594. NULL_STRING
  595. );
  596. // sub-option 'file'
  597. cmdOptions[CMDINDEX_FILE].dwFlags = CP_TYPE_TEXT |
  598. CP_VALUE_MANDATORY;
  599. cmdOptions[CMDINDEX_FILE].dwCount = 1;
  600. cmdOptions[CMDINDEX_FILE].dwActuals = 0;
  601. cmdOptions[CMDINDEX_FILE].pValue = lpszFile;
  602. cmdOptions[CMDINDEX_FILE].pFunction = NULL;
  603. cmdOptions[CMDINDEX_FILE].pFunctionData = NULL;
  604. lstrcpy(
  605. cmdOptions[CMDINDEX_FILE].szOption,
  606. CMDOPTION_FILE
  607. );
  608. lstrcpy(
  609. cmdOptions[CMDINDEX_FILE].szValues,
  610. NULL_STRING
  611. );
  612. // parse parameters, take appropriate action
  613. if(DoParseParam(argc,argv,NUM_CMDS,cmdOptions))
  614. {
  615. // make sure only one command issued
  616. DWORD dwCmdCount = 0;
  617. DWORD dwParamCount = 0;
  618. for(dwIdx=0;dwIdx<NUM_CMDS;dwIdx++)
  619. {
  620. if (dwIdx < NUM_MAIN_CMDS)
  621. {
  622. dwCmdCount += cmdOptions[dwIdx].dwActuals;
  623. }
  624. else
  625. {
  626. dwParamCount += cmdOptions[dwIdx].dwActuals;
  627. }
  628. }
  629. // determine other flags
  630. bQuery = (cmdOptions[CMDINDEX_QUERY].dwActuals != 0);
  631. bCreate = (cmdOptions[CMDINDEX_CREATE].dwActuals != 0);
  632. bDelete = (cmdOptions[CMDINDEX_DELETE].dwActuals != 0);
  633. bSetActive = (cmdOptions[CMDINDEX_SETACTIVE].dwActuals != 0);
  634. bChange = (cmdOptions[CMDINDEX_CHANGE].dwActuals != 0);
  635. bHibernate = (cmdOptions[CMDINDEX_HIBERNATE].dwActuals != 0);
  636. bExport = (cmdOptions[CMDINDEX_EXPORT].dwActuals != 0);
  637. bImport = (cmdOptions[CMDINDEX_IMPORT].dwActuals != 0);
  638. bFile = (cmdOptions[CMDINDEX_FILE].dwActuals != 0);
  639. tChangeParam.bVideoTimeoutAc =
  640. (cmdOptions[CMDINDEX_MONITOR_OFF_AC].dwActuals != 0);
  641. tChangeParam.bVideoTimeoutDc =
  642. (cmdOptions[CMDINDEX_MONITOR_OFF_DC].dwActuals != 0);
  643. tChangeParam.bSpindownTimeoutAc =
  644. (cmdOptions[CMDINDEX_DISK_OFF_AC].dwActuals != 0);
  645. tChangeParam.bSpindownTimeoutDc =
  646. (cmdOptions[CMDINDEX_DISK_OFF_DC].dwActuals != 0);
  647. tChangeParam.bIdleTimeoutAc =
  648. (cmdOptions[CMDINDEX_STANDBY_AC].dwActuals != 0);
  649. tChangeParam.bIdleTimeoutDc =
  650. (cmdOptions[CMDINDEX_STANDBY_DC].dwActuals != 0);
  651. tChangeParam.bDozeS4TimeoutAc =
  652. (cmdOptions[CMDINDEX_HIBER_AC].dwActuals != 0);
  653. tChangeParam.bDozeS4TimeoutDc =
  654. (cmdOptions[CMDINDEX_HIBER_DC].dwActuals != 0);
  655. tChangeParam.bDynamicThrottleAc =
  656. (cmdOptions[CMDINDEX_THROTTLE_AC].dwActuals != 0);
  657. tChangeParam.bDynamicThrottleDc =
  658. (cmdOptions[CMDINDEX_THROTTLE_DC].dwActuals != 0);
  659. tChangeParam.lpszDynamicThrottleAc = lpszThrottleAcStr;
  660. tChangeParam.lpszDynamicThrottleDc = lpszThrottleDcStr;
  661. if ((dwCmdCount == 1) &&
  662. ((dwParamCount == 0) ||
  663. (bChange && (dwParamCount > 0) && (!bFile)) ||
  664. ((bImport || bExport) && bFile && (dwParamCount == 1))))
  665. {
  666. // check flags, take appropriate action
  667. if(bList)
  668. {
  669. DoList();
  670. }
  671. else if (bQuery)
  672. {
  673. bFail = !DoQuery(lpszName,(lstrlen(lpszName) != 0));
  674. }
  675. else if (bCreate)
  676. {
  677. bFail = !DoCreate(lpszName);
  678. }
  679. else if (bDelete)
  680. {
  681. bFail = !DoDelete(lpszName);
  682. }
  683. else if (bSetActive)
  684. {
  685. bFail = !DoSetActive(lpszName);
  686. }
  687. else if (bChange)
  688. {
  689. bFail = !DoChange(lpszName,&tChangeParam);
  690. }
  691. else if (bHibernate)
  692. {
  693. bFail = !DoHibernate(lpszBoolStr);
  694. }
  695. else if (bExport)
  696. {
  697. bFail = !DoExport(lpszName,lpszFile);
  698. }
  699. else if (bImport)
  700. {
  701. bFail = !DoImport(lpszName,lpszFile);
  702. }
  703. else if (bUsage)
  704. {
  705. DoUsage();
  706. }
  707. else
  708. {
  709. if(lstrlen(g_lpszErr) == 0)
  710. g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM);
  711. bFail = TRUE;
  712. }
  713. }
  714. else
  715. {
  716. // handle error conditions
  717. if(lstrlen(g_lpszErr) == 0)
  718. {
  719. g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM);
  720. }
  721. bFail = TRUE;
  722. }
  723. }
  724. else
  725. {
  726. g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM);
  727. bFail = TRUE;
  728. }
  729. // check error status, display msg if needed
  730. if(bFail)
  731. {
  732. if(g_lpszErr2)
  733. {
  734. DISPLAY_MESSAGE(stderr,g_lpszErr2);
  735. }
  736. else
  737. {
  738. DISPLAY_MESSAGE(stderr,g_lpszErr);
  739. }
  740. }
  741. // clean up allocs
  742. LocalFree(lpszBoolStr);
  743. LocalFree(lpszName);
  744. LocalFree(lpszFile);
  745. LocalFree(lpszThrottleAcStr);
  746. LocalFree(lpszThrottleDcStr);
  747. if (g_lpszErr2)
  748. {
  749. LocalFree(g_lpszErr2);
  750. }
  751. // return appropriate result code
  752. if(bFail)
  753. {
  754. return EXIT_FAILURE;
  755. }
  756. else
  757. {
  758. return EXIT_SUCCESS;
  759. }
  760. }
  761. BOOL
  762. FreeScheme(
  763. PSCHEME_LIST psl
  764. )
  765. /*++
  766. Routine Description:
  767. Frees the memory associated with a scheme list entry.
  768. Arguments:
  769. psl - the PSCHEME_LIST to be freed
  770. Return Value:
  771. Always returns TRUE, indicating success.
  772. --*/
  773. {
  774. LocalFree(psl->lpszName);
  775. LocalFree(psl->lpszDesc);
  776. LocalFree(psl->ppp);
  777. LocalFree(psl->pmppp);
  778. LocalFree(psl);
  779. return TRUE;
  780. }
  781. BOOL
  782. FreeSchemeList(
  783. PSCHEME_LIST psl,
  784. PSCHEME_LIST pslExcept
  785. )
  786. /*++
  787. Routine Description:
  788. Deallocates all power schemes in a linked-list of power schemes, except
  789. for the one pointed to by pslExcept
  790. Arguments:
  791. psl - the power scheme list to deallocate
  792. pslExcept - a scheme not to deallocate (null to deallocate all)
  793. Return Value:
  794. Always returns TRUE, indicating success.
  795. --*/
  796. {
  797. PSCHEME_LIST cur = psl;
  798. PSCHEME_LIST next;
  799. while (cur != NULL)
  800. {
  801. next = CONTAINING_RECORD(
  802. cur->le.Flink,
  803. SCHEME_LIST,
  804. le
  805. );
  806. if (cur != pslExcept)
  807. {
  808. FreeScheme(cur);
  809. }
  810. else
  811. {
  812. cur->le.Flink = NULL;
  813. cur->le.Blink = NULL;
  814. }
  815. cur = next;
  816. }
  817. return TRUE;
  818. }
  819. PSCHEME_LIST
  820. CreateScheme(
  821. UINT uiID,
  822. DWORD dwNameSize,
  823. LPCTSTR lpszName,
  824. DWORD dwDescSize,
  825. LPCTSTR lpszDesc,
  826. PPOWER_POLICY ppp
  827. )
  828. /*++
  829. Routine Description:
  830. Builds a policy list entry. Note that the scheme is allocated and must
  831. be freed when done.
  832. Arguments:
  833. uiID - the numerical ID of the scheme
  834. dwNameSize - the number of bytes needed to store lpszName
  835. lpszName - the name of the scheme
  836. dwDescSize - the number of bytes needed to store lpszDesc
  837. lpszDesc - the description of the scheme
  838. ppp - the power policy for this scheme, may be NULL
  839. Return Value:
  840. A PSCHEME_LIST entry containing the specified values, with the next
  841. entry field set to NULL
  842. --*/
  843. {
  844. PSCHEME_LIST psl = (PSCHEME_LIST)LocalAlloc(LPTR,sizeof(SCHEME_LIST));
  845. if (psl)
  846. {
  847. // deal with potentially null input strings
  848. if(lpszName == NULL)
  849. {
  850. lpszName = NULL_STRING;
  851. }
  852. if(lpszDesc == NULL)
  853. {
  854. lpszDesc = NULL_STRING;
  855. }
  856. // allocate fields
  857. psl->ppp = (PPOWER_POLICY)LocalAlloc(LPTR,sizeof(POWER_POLICY));
  858. if (!psl->ppp)
  859. {
  860. g_lpszErr = GetResString(IDS_OUT_OF_MEMORY);
  861. return NULL;
  862. }
  863. psl->pmppp = (PMACHINE_PROCESSOR_POWER_POLICY)LocalAlloc(
  864. LPTR,
  865. sizeof(MACHINE_PROCESSOR_POWER_POLICY)
  866. );
  867. if (!psl->pmppp)
  868. {
  869. LocalFree(psl->ppp);
  870. g_lpszErr = GetResString(IDS_OUT_OF_MEMORY);
  871. return NULL;
  872. }
  873. psl->lpszName = (LPTSTR)LocalAlloc(LPTR,dwNameSize);
  874. if (!psl->lpszName)
  875. {
  876. LocalFree(psl->ppp);
  877. LocalFree(psl->pmppp);
  878. g_lpszErr = GetResString(IDS_OUT_OF_MEMORY);
  879. return NULL;
  880. }
  881. psl->lpszDesc = (LPTSTR)LocalAlloc(LPTR,dwDescSize);
  882. if (!psl->lpszDesc)
  883. {
  884. LocalFree(psl->ppp);
  885. LocalFree(psl->pmppp);
  886. LocalFree(psl->lpszName);
  887. g_lpszErr = GetResString(IDS_OUT_OF_MEMORY);
  888. return NULL;
  889. }
  890. // initialize structure
  891. psl->uiID = uiID;
  892. memcpy(psl->lpszName,lpszName,dwNameSize);
  893. memcpy(psl->lpszDesc,lpszDesc,dwDescSize);
  894. if (ppp)
  895. {
  896. memcpy(psl->ppp,ppp,sizeof(POWER_POLICY));
  897. }
  898. psl->le.Flink = NULL;
  899. psl->le.Blink = NULL;
  900. }
  901. else
  902. {
  903. g_lpszErr = GetResString(IDS_OUT_OF_MEMORY);
  904. }
  905. return psl;
  906. }
  907. BOOLEAN CALLBACK
  908. PowerSchemeEnumProc(
  909. UINT uiID,
  910. DWORD dwNameSize,
  911. LPTSTR lpszName,
  912. DWORD dwDescSize,
  913. LPTSTR lpszDesc,
  914. PPOWER_POLICY ppp,
  915. LPARAM lParam
  916. )
  917. /*++
  918. Routine Description:
  919. This is a callback used in retrieving the policy list.
  920. Arguments:
  921. uiID - the numerical ID of the scheme
  922. dwNameSize - the number of bytes needed to store lpszName
  923. lpszName - the name of the scheme
  924. dwDescSize - the number of bytes needed to store lpszDesc
  925. lpszDesc - the description of the scheme
  926. ppp - the power policy for this scheme
  927. lParam - used to hold a pointer to the head-of-list pointer, allowing
  928. for insertions at the head of the list
  929. Return Value:
  930. TRUE to continue enumeration
  931. FALSE to abort enumeration
  932. --*/
  933. {
  934. PSCHEME_LIST psl;
  935. // Allocate and initalize a policies element.
  936. if ((psl = CreateScheme(
  937. uiID,
  938. dwNameSize,
  939. lpszName,
  940. dwDescSize,
  941. lpszDesc,
  942. ppp
  943. )) != NULL)
  944. {
  945. // add the element to the head of the linked list
  946. psl->le.Flink = *((PLIST_ENTRY *)lParam);
  947. if(*((PLIST_ENTRY *)lParam))
  948. {
  949. (*((PLIST_ENTRY *)lParam))->Blink = &(psl->le);
  950. }
  951. (*(PLIST_ENTRY *)lParam) = &(psl->le);
  952. return TRUE;
  953. }
  954. return FALSE;
  955. }
  956. PSCHEME_LIST
  957. CreateSchemeList()
  958. /*++
  959. Routine Description:
  960. Creates a linked list of existing power schemes.
  961. Arguments:
  962. None
  963. Return Value:
  964. A pointer to the head of the list.
  965. NULL would correspond to an empty list.
  966. --*/
  967. {
  968. PLIST_ENTRY ple = NULL;
  969. PSCHEME_LIST psl;
  970. EnumPwrSchemes(PowerSchemeEnumProc, (LPARAM)(&ple));
  971. if(ple)
  972. {
  973. PSCHEME_LIST res = CONTAINING_RECORD(
  974. ple,
  975. SCHEME_LIST,
  976. le
  977. );
  978. psl = res;
  979. while(psl != NULL)
  980. {
  981. if(!ReadProcessorPwrScheme(psl->uiID,psl->pmppp))
  982. {
  983. FreeSchemeList(res,NULL);
  984. g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
  985. return NULL;
  986. }
  987. psl = CONTAINING_RECORD(
  988. psl->le.Flink,
  989. SCHEME_LIST,
  990. le);
  991. }
  992. return res;
  993. }
  994. else
  995. {
  996. return NULL;
  997. }
  998. }
  999. PSCHEME_LIST
  1000. FindScheme(
  1001. LPCTSTR lpszName,
  1002. UINT uiID
  1003. )
  1004. /*++
  1005. Routine Description:
  1006. Finds the policy with the matching name
  1007. Arguments:
  1008. lpszName - the name of the scheme to find
  1009. Return Value:
  1010. the matching scheme list entry, null if none
  1011. --*/
  1012. {
  1013. PSCHEME_LIST psl = CreateSchemeList();
  1014. PSCHEME_LIST pslRes = NULL;
  1015. // find scheme entry
  1016. while(psl != NULL)
  1017. {
  1018. // check for match
  1019. if (((lpszName != NULL) && (!lstrcmpi(lpszName, psl->lpszName))) ||
  1020. ((lpszName == NULL) && (uiID == psl->uiID)))
  1021. {
  1022. pslRes = psl;
  1023. break;
  1024. }
  1025. // traverse list
  1026. psl = CONTAINING_RECORD(
  1027. psl->le.Flink,
  1028. SCHEME_LIST,
  1029. le
  1030. );
  1031. }
  1032. FreeSchemeList(psl,pslRes); // all except for pslRes
  1033. if (pslRes == NULL)
  1034. g_lpszErr = GetResString(IDS_SCHEME_NOT_FOUND);
  1035. return pslRes;
  1036. }
  1037. BOOL
  1038. MyWriteScheme(
  1039. PSCHEME_LIST psl
  1040. )
  1041. /*++
  1042. Routine Description:
  1043. Writes a power scheme -- both user/machine power policies and
  1044. processor power policy. The underlying powrprof.dll does not
  1045. treat the processor power policy as part of the power policy
  1046. because the processor power policies were added at a later
  1047. date and backwards compatibility must be maintained.
  1048. Arguments:
  1049. psl - The scheme list entry to write
  1050. Return Value:
  1051. TRUE if successful, otherwise FALSE
  1052. --*/
  1053. {
  1054. g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
  1055. if(WritePwrScheme(
  1056. &psl->uiID,
  1057. psl->lpszName,
  1058. psl->lpszDesc,
  1059. psl->ppp))
  1060. {
  1061. return WriteProcessorPwrScheme(
  1062. psl->uiID,
  1063. psl->pmppp
  1064. );
  1065. }
  1066. else
  1067. {
  1068. return FALSE;
  1069. }
  1070. }
  1071. BOOL
  1072. MapIdleValue(
  1073. ULONG ulVal,
  1074. PULONG pulIdle,
  1075. PULONG pulHiber,
  1076. PPOWER_ACTION ppapIdle
  1077. )
  1078. /*++
  1079. Routine Description:
  1080. Modifies Idle and Hibernation settings to reflect the desired idle
  1081. timeout. See GUI tool's PWRSCHEM.C MapHiberTimer for logic.
  1082. Arguments:
  1083. ulVal - the new idle timeout
  1084. pulIdle - the idle timeout variable to be updated
  1085. pulHiber - the hiber timeout variable to be updated
  1086. Return Value:
  1087. TRUE if successful
  1088. FALSE if failed
  1089. --*/
  1090. {
  1091. // if previously, hiber was enabled and standby wasn't, standby timer
  1092. // takes over the hibernation timer's role
  1093. if (*ppapIdle == PowerActionHibernate)
  1094. {
  1095. if (ulVal > 0)
  1096. { // enable standby
  1097. *pulHiber = *pulIdle + ulVal;
  1098. *pulIdle = ulVal;
  1099. *ppapIdle = PowerActionSleep;
  1100. }
  1101. else { // standby already disabled, no change
  1102. }
  1103. }
  1104. else // standby timer actually being used for standby (not hiber)
  1105. {
  1106. if (ulVal > 0)
  1107. { // enable standby
  1108. if ((*pulHiber) != 0)
  1109. {
  1110. *pulHiber = *pulHiber + ulVal - *pulIdle;
  1111. }
  1112. *pulIdle = ulVal;
  1113. if (ulVal > 0)
  1114. {
  1115. *ppapIdle = PowerActionSleep;
  1116. }
  1117. else
  1118. {
  1119. *ppapIdle = PowerActionNone;
  1120. }
  1121. }
  1122. else
  1123. { // disable standby
  1124. if ((*pulHiber) != 0)
  1125. {
  1126. *pulIdle = *pulHiber;
  1127. *pulHiber = 0;
  1128. *ppapIdle = PowerActionHibernate;
  1129. }
  1130. else
  1131. {
  1132. *pulIdle = 0;
  1133. *ppapIdle = PowerActionNone;
  1134. }
  1135. }
  1136. }
  1137. return TRUE;
  1138. }
  1139. BOOL
  1140. MapHiberValue(
  1141. ULONG ulVal,
  1142. PULONG pulIdle,
  1143. PULONG pulHiber,
  1144. PPOWER_ACTION ppapIdle
  1145. )
  1146. /*++
  1147. Routine Description:
  1148. Modifies Idle and Hibernation settings to reflect the desired hibernation
  1149. timeout. See GUI tool's PWRSCHEM.C MapHiberTimer for logic.
  1150. Arguments:
  1151. ulVal - the new hibernation timeout
  1152. pulIdle - the idle timeout variable to be updated
  1153. pulHiber - the hiber timeout variable to be updated
  1154. Return Value:
  1155. TRUE if successful
  1156. FALSE if failed
  1157. --*/
  1158. {
  1159. // check valid input
  1160. if (ulVal < (*pulIdle))
  1161. {
  1162. g_lpszErr = GetResString(IDS_HIBER_OUT_OF_RANGE);
  1163. return FALSE;
  1164. }
  1165. // check for disable-hibernation
  1166. if (ulVal == 0)
  1167. {
  1168. if (((*ppapIdle) == PowerActionHibernate) || (!g_bStandbySupported))
  1169. {
  1170. *pulIdle = 0;
  1171. *pulHiber = 0;
  1172. *ppapIdle = PowerActionNone;
  1173. }
  1174. else
  1175. {
  1176. *pulHiber = 0;
  1177. if ((*pulIdle) == 0) {
  1178. *ppapIdle = PowerActionNone;
  1179. }
  1180. else
  1181. {
  1182. *ppapIdle = PowerActionSleep;
  1183. }
  1184. }
  1185. }
  1186. else // enabled hibernation
  1187. {
  1188. if (((*ppapIdle) == PowerActionHibernate) || (!g_bStandbySupported))
  1189. {
  1190. *pulHiber = 0;
  1191. *pulIdle = ulVal;
  1192. *ppapIdle = PowerActionHibernate;
  1193. }
  1194. else
  1195. {
  1196. *pulHiber = *pulHiber + ulVal - *pulIdle;
  1197. *ppapIdle = PowerActionSleep;
  1198. }
  1199. }
  1200. return TRUE;
  1201. }
  1202. BOOL
  1203. DoList()
  1204. /*++
  1205. Routine Description:
  1206. Lists the existing power schemes on stdout
  1207. Arguments:
  1208. none
  1209. Return Value:
  1210. TRUE if successful
  1211. FALSE if failed
  1212. --*/
  1213. {
  1214. PSCHEME_LIST psl = CreateSchemeList();
  1215. if (psl != NULL)
  1216. {
  1217. DISPLAY_MESSAGE(stdout,GetResString(IDS_LIST_HEADER1));
  1218. DISPLAY_MESSAGE(stdout,GetResString(IDS_LIST_HEADER2));
  1219. }
  1220. else
  1221. {
  1222. return FALSE;
  1223. }
  1224. while(psl != NULL)
  1225. {
  1226. DISPLAY_MESSAGE(stdout, psl->lpszName);
  1227. DISPLAY_MESSAGE(stdout, L"\n");
  1228. psl = CONTAINING_RECORD(
  1229. psl->le.Flink,
  1230. SCHEME_LIST,
  1231. le
  1232. );
  1233. }
  1234. FreeSchemeList(psl,NULL); // free all entries
  1235. return TRUE;
  1236. }
  1237. BOOL
  1238. DoQuery(
  1239. LPCTSTR lpszName,
  1240. BOOL bNameSpecified
  1241. )
  1242. /*++
  1243. Routine Description:
  1244. Show details of an existing scheme
  1245. Arguments:
  1246. lpszName - the name of the scheme
  1247. Return Value:
  1248. TRUE if successful
  1249. FALSE if failed
  1250. --*/
  1251. {
  1252. PSCHEME_LIST psl;
  1253. // check if querying specific scheme or active scheme and deal w/it
  1254. if (bNameSpecified)
  1255. {
  1256. psl = FindScheme(lpszName,0);
  1257. }
  1258. else // fetch the active scheme
  1259. {
  1260. POWER_POLICY pp;
  1261. UINT uiID;
  1262. if (GetActivePwrScheme(&uiID))
  1263. {
  1264. psl = FindScheme(NULL,uiID);
  1265. }
  1266. else
  1267. {
  1268. g_lpszErr = GetResString(IDS_ACTIVE_SCHEME_INVALID);
  1269. return FALSE;
  1270. }
  1271. }
  1272. // display info
  1273. if (psl)
  1274. {
  1275. // header
  1276. DISPLAY_MESSAGE(stdout, GetResString(IDS_QUERY_HEADER1));
  1277. DISPLAY_MESSAGE(stdout, GetResString(IDS_QUERY_HEADER2));
  1278. // name
  1279. DISPLAY_MESSAGE1(
  1280. stdout,
  1281. g_lpszBuf,
  1282. GetResString(IDS_SCHEME_NAME),
  1283. psl->lpszName
  1284. );
  1285. // monitor timeout AC
  1286. DISPLAY_MESSAGE(stdout, GetResString(IDS_MONITOR_TIMEOUT_AC));
  1287. if (!g_bMonitorPowerSupported)
  1288. {
  1289. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1290. }
  1291. else if (psl->ppp->user.VideoTimeoutAc == 0) {
  1292. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED));
  1293. }
  1294. else
  1295. {
  1296. DISPLAY_MESSAGE1(
  1297. stdout,
  1298. g_lpszBuf,
  1299. GetResString(IDS_MINUTES),
  1300. psl->ppp->user.VideoTimeoutAc/60
  1301. );
  1302. }
  1303. // monitor timeout DC
  1304. DISPLAY_MESSAGE(stdout, GetResString(IDS_MONITOR_TIMEOUT_DC));
  1305. if (!g_bMonitorPowerSupported)
  1306. {
  1307. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1308. }
  1309. else if (psl->ppp->user.VideoTimeoutDc == 0)
  1310. {
  1311. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED));
  1312. }
  1313. else
  1314. {
  1315. DISPLAY_MESSAGE1(
  1316. stdout,
  1317. g_lpszBuf,
  1318. GetResString(IDS_MINUTES),
  1319. psl->ppp->user.VideoTimeoutDc/60
  1320. );
  1321. }
  1322. // disk timeout AC
  1323. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISK_TIMEOUT_AC));
  1324. if (!g_bDiskPowerSupported)
  1325. {
  1326. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1327. }
  1328. else if (psl->ppp->user.SpindownTimeoutAc == 0)
  1329. {
  1330. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED));
  1331. }
  1332. else
  1333. {
  1334. DISPLAY_MESSAGE1(
  1335. stdout,
  1336. g_lpszBuf,
  1337. GetResString(IDS_MINUTES),
  1338. psl->ppp->user.SpindownTimeoutAc/60
  1339. );
  1340. }
  1341. // disk timeout DC
  1342. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISK_TIMEOUT_DC));
  1343. if (!g_bDiskPowerSupported)
  1344. {
  1345. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1346. }
  1347. else if (psl->ppp->user.SpindownTimeoutDc == 0)
  1348. {
  1349. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED));
  1350. }
  1351. else
  1352. {
  1353. DISPLAY_MESSAGE1(
  1354. stdout,
  1355. g_lpszBuf,
  1356. GetResString(IDS_MINUTES),
  1357. psl->ppp->user.SpindownTimeoutDc/60
  1358. );
  1359. }
  1360. // standby timeout AC
  1361. DISPLAY_MESSAGE(stdout, GetResString(IDS_STANDBY_TIMEOUT_AC));
  1362. if (!g_bStandbySupported)
  1363. {
  1364. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1365. }
  1366. else if (psl->ppp->user.IdleAc.Action != PowerActionSleep)
  1367. {
  1368. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED));
  1369. }
  1370. else
  1371. {
  1372. DISPLAY_MESSAGE1(
  1373. stdout,
  1374. g_lpszBuf,
  1375. GetResString(IDS_MINUTES),
  1376. psl->ppp->user.IdleTimeoutAc/60
  1377. );
  1378. }
  1379. // standby timeout DC
  1380. DISPLAY_MESSAGE(stdout, GetResString(IDS_STANDBY_TIMEOUT_DC));
  1381. if (!g_bStandbySupported)
  1382. {
  1383. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1384. }
  1385. else if (psl->ppp->user.IdleDc.Action != PowerActionSleep)
  1386. {
  1387. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED));
  1388. }
  1389. else
  1390. {
  1391. DISPLAY_MESSAGE1(
  1392. stdout,
  1393. g_lpszBuf,
  1394. GetResString(IDS_MINUTES),
  1395. psl->ppp->user.IdleTimeoutDc/60
  1396. );
  1397. }
  1398. // hibernate timeout AC
  1399. DISPLAY_MESSAGE(stdout, GetResString(IDS_HIBER_TIMEOUT_AC));
  1400. if (!g_bHiberTimerSupported)
  1401. {
  1402. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1403. }
  1404. else if ((psl->ppp->mach.DozeS4TimeoutAc == 0) &&
  1405. ((psl->ppp->user.IdleAc.Action != PowerActionHibernate) ||
  1406. (psl->ppp->user.IdleTimeoutAc == 0)))
  1407. {
  1408. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED));
  1409. }
  1410. else
  1411. {
  1412. DISPLAY_MESSAGE1(
  1413. stdout,
  1414. g_lpszBuf,
  1415. GetResString(IDS_MINUTES),
  1416. (psl->ppp->mach.DozeS4TimeoutAc +
  1417. psl->ppp->user.IdleTimeoutAc)/60
  1418. );
  1419. }
  1420. // hibernate timeout DC
  1421. DISPLAY_MESSAGE(stdout, GetResString(IDS_HIBER_TIMEOUT_DC));
  1422. if (!g_bHiberTimerSupported)
  1423. {
  1424. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1425. }
  1426. else if ((psl->ppp->mach.DozeS4TimeoutDc == 0) &&
  1427. ((psl->ppp->user.IdleDc.Action != PowerActionHibernate) ||
  1428. (psl->ppp->user.IdleTimeoutDc == 0)))
  1429. {
  1430. DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED));
  1431. }
  1432. else
  1433. {
  1434. DISPLAY_MESSAGE1(
  1435. stdout,
  1436. g_lpszBuf,
  1437. GetResString(IDS_MINUTES),
  1438. (psl->ppp->mach.DozeS4TimeoutDc +
  1439. psl->ppp->user.IdleTimeoutDc)/60
  1440. );
  1441. }
  1442. // throttle policy AC
  1443. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_AC));
  1444. if (!g_bThrottleSupported)
  1445. {
  1446. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1447. }
  1448. else
  1449. {
  1450. switch(psl->pmppp->ProcessorPolicyAc.DynamicThrottle)
  1451. {
  1452. case PO_THROTTLE_NONE:
  1453. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_NONE));
  1454. break;
  1455. case PO_THROTTLE_CONSTANT:
  1456. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_CONSTANT));
  1457. break;
  1458. case PO_THROTTLE_DEGRADE:
  1459. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_DEGRADE));
  1460. break;
  1461. case PO_THROTTLE_ADAPTIVE:
  1462. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_ADAPTIVE));
  1463. break;
  1464. default:
  1465. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_UNKNOWN));
  1466. break;
  1467. }
  1468. }
  1469. // throttle policy DC
  1470. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_DC));
  1471. if (!g_bThrottleSupported)
  1472. {
  1473. DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED));
  1474. }
  1475. else
  1476. {
  1477. switch(psl->pmppp->ProcessorPolicyDc.DynamicThrottle) {
  1478. case PO_THROTTLE_NONE:
  1479. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_NONE));
  1480. break;
  1481. case PO_THROTTLE_CONSTANT:
  1482. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_CONSTANT));
  1483. break;
  1484. case PO_THROTTLE_DEGRADE:
  1485. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_DEGRADE));
  1486. break;
  1487. case PO_THROTTLE_ADAPTIVE:
  1488. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_ADAPTIVE));
  1489. break;
  1490. default:
  1491. DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_UNKNOWN));
  1492. break;
  1493. }
  1494. }
  1495. FreeScheme(psl);
  1496. return TRUE;
  1497. }
  1498. else
  1499. {
  1500. return FALSE;
  1501. }
  1502. }
  1503. BOOL DoCreate(
  1504. LPTSTR lpszName
  1505. )
  1506. /*++
  1507. Routine Description:
  1508. Adds a new power scheme
  1509. The description will match the name
  1510. All other details are copied from the active power scheme
  1511. Fails if scheme already exists
  1512. Arguments:
  1513. lpszName - the name of the scheme
  1514. Return Value:
  1515. TRUE if successful
  1516. FALSE if failed
  1517. --*/
  1518. {
  1519. PSCHEME_LIST psl = FindScheme(lpszName,0);
  1520. UINT uiID;
  1521. POWER_POLICY pp;
  1522. BOOL bRes;
  1523. LPTSTR lpszNewName;
  1524. LPTSTR lpszNewDesc;
  1525. if(psl) // already existed -> fail
  1526. {
  1527. FreeScheme(psl);
  1528. g_lpszErr = GetResString(IDS_SCHEME_ALREADY_EXISTS);
  1529. return FALSE;
  1530. }
  1531. // create a new scheme
  1532. if(GetActivePwrScheme(&uiID))
  1533. {
  1534. psl = FindScheme(NULL,uiID);
  1535. if(!psl)
  1536. {
  1537. g_lpszErr = GetResString(IDS_SCHEME_CREATE_FAIL);
  1538. return FALSE;
  1539. }
  1540. lpszNewName = LocalAlloc(LPTR,(lstrlen(lpszName)+1)*sizeof(TCHAR));
  1541. if(!lpszNewName)
  1542. {
  1543. FreeScheme(psl);
  1544. g_lpszErr = GetResString(IDS_OUT_OF_MEMORY);
  1545. return FALSE;
  1546. }
  1547. lpszNewDesc = LocalAlloc(LPTR,(lstrlen(lpszName)+1)*sizeof(TCHAR));
  1548. if(!lpszNewDesc)
  1549. {
  1550. LocalFree(lpszNewName);
  1551. FreeScheme(psl);
  1552. g_lpszErr = GetResString(IDS_OUT_OF_MEMORY);
  1553. return FALSE;
  1554. }
  1555. lstrcpy(lpszNewName,lpszName);
  1556. lstrcpy(lpszNewDesc,lpszName);
  1557. LocalFree(psl->lpszName);
  1558. LocalFree(psl->lpszDesc);
  1559. psl->lpszName = lpszNewName;
  1560. psl->lpszDesc = lpszNewDesc;
  1561. psl->uiID = NEWSCHEME;
  1562. g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
  1563. bRes = MyWriteScheme(psl);
  1564. FreeScheme(psl);
  1565. return bRes;
  1566. }
  1567. g_lpszErr = GetResString(IDS_SCHEME_CREATE_FAIL);
  1568. return FALSE;
  1569. }
  1570. BOOL DoDelete(
  1571. LPCTSTR lpszName
  1572. )
  1573. /*++
  1574. Routine Description:
  1575. Deletes an existing scheme
  1576. Arguments:
  1577. lpszName - the name of the scheme
  1578. Return Value:
  1579. TRUE if successful
  1580. FALSE if failed
  1581. --*/
  1582. {
  1583. PSCHEME_LIST psl = FindScheme(lpszName,0);
  1584. if (psl)
  1585. {
  1586. BOOL bRes = DeletePwrScheme(psl->uiID);
  1587. FreeScheme(psl);
  1588. g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
  1589. return bRes;
  1590. }
  1591. else
  1592. {
  1593. return FALSE;
  1594. }
  1595. }
  1596. BOOL DoSetActive(
  1597. LPCTSTR lpszName
  1598. )
  1599. /*++
  1600. Routine Description:
  1601. Sets the active scheme
  1602. Arguments:
  1603. lpszName - the name of the scheme
  1604. Return Value:
  1605. TRUE if successful
  1606. FALSE if failed
  1607. --*/
  1608. {
  1609. PSCHEME_LIST psl = FindScheme(lpszName,0);
  1610. if (psl)
  1611. {
  1612. BOOL bRes = SetActivePwrScheme(
  1613. psl->uiID,
  1614. NULL,
  1615. NULL
  1616. );
  1617. FreeScheme(psl);
  1618. g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
  1619. return bRes;
  1620. }
  1621. else
  1622. {
  1623. return FALSE;
  1624. }
  1625. }
  1626. BOOL
  1627. DoChange(
  1628. LPCTSTR lpszName,
  1629. PCHANGE_PARAM pcp
  1630. )
  1631. /*++
  1632. Routine Description:
  1633. Modifies an existing scheme
  1634. Arguments:
  1635. lpszName - the name of the scheme
  1636. pcp - PCHANGE_PARAM pointing to the parameter structure,
  1637. indicates which variable(s) to change
  1638. Return Value:
  1639. TRUE if successful
  1640. FALSE if failed
  1641. --*/
  1642. {
  1643. BOOL bRes = TRUE;
  1644. PSCHEME_LIST psl = FindScheme(lpszName,0);
  1645. if (psl)
  1646. {
  1647. // check for feature support
  1648. if ((pcp->bIdleTimeoutAc ||
  1649. pcp->bIdleTimeoutDc) &&
  1650. !g_bStandbySupported)
  1651. {
  1652. DISPLAY_MESSAGE(stderr, GetResString(IDS_STANDBY_WARNING));
  1653. }
  1654. if ((pcp->bDozeS4TimeoutAc ||
  1655. pcp->bDozeS4TimeoutDc) &&
  1656. !g_bHiberTimerSupported)
  1657. {
  1658. DISPLAY_MESSAGE(stderr, GetResString(IDS_HIBER_WARNING));
  1659. }
  1660. if ((pcp->bVideoTimeoutAc ||
  1661. pcp->bVideoTimeoutDc) &&
  1662. !g_bMonitorPowerSupported)
  1663. {
  1664. DISPLAY_MESSAGE(stderr, GetResString(IDS_MONITOR_WARNING));
  1665. }
  1666. if ((pcp->bSpindownTimeoutAc ||
  1667. pcp->bSpindownTimeoutDc) &&
  1668. !g_bDiskPowerSupported)
  1669. {
  1670. DISPLAY_MESSAGE(stderr, GetResString(IDS_DISK_WARNING));
  1671. }
  1672. // change params
  1673. if (pcp->bVideoTimeoutAc)
  1674. {
  1675. psl->ppp->user.VideoTimeoutAc = pcp->ulVideoTimeoutAc*60;
  1676. }
  1677. if (pcp->bVideoTimeoutDc)
  1678. {
  1679. psl->ppp->user.VideoTimeoutDc = pcp->ulVideoTimeoutDc*60;
  1680. }
  1681. if (pcp->bSpindownTimeoutAc)
  1682. {
  1683. psl->ppp->user.SpindownTimeoutAc = pcp->ulSpindownTimeoutAc*60;
  1684. }
  1685. if (pcp->bSpindownTimeoutDc)
  1686. {
  1687. psl->ppp->user.SpindownTimeoutDc = pcp->ulSpindownTimeoutDc*60;
  1688. }
  1689. if (pcp->bIdleTimeoutAc)
  1690. {
  1691. bRes = bRes & MapIdleValue(
  1692. pcp->ulIdleTimeoutAc*60,
  1693. &psl->ppp->user.IdleTimeoutAc,
  1694. &psl->ppp->mach.DozeS4TimeoutAc,
  1695. &psl->ppp->user.IdleAc.Action
  1696. );
  1697. }
  1698. if (pcp->bIdleTimeoutDc)
  1699. {
  1700. bRes = bRes & MapIdleValue(
  1701. pcp->ulIdleTimeoutDc*60,
  1702. &psl->ppp->user.IdleTimeoutDc,
  1703. &psl->ppp->mach.DozeS4TimeoutDc,
  1704. &psl->ppp->user.IdleDc.Action
  1705. );
  1706. }
  1707. if (pcp->bDozeS4TimeoutAc)
  1708. {
  1709. bRes = bRes & MapHiberValue(
  1710. pcp->ulDozeS4TimeoutAc*60,
  1711. &psl->ppp->user.IdleTimeoutAc,
  1712. &psl->ppp->mach.DozeS4TimeoutAc,
  1713. &psl->ppp->user.IdleAc.Action
  1714. );
  1715. }
  1716. if (pcp->bDozeS4TimeoutDc)
  1717. {
  1718. bRes = bRes & MapHiberValue(
  1719. pcp->ulDozeS4TimeoutDc*60,
  1720. &psl->ppp->user.IdleTimeoutDc,
  1721. &psl->ppp->mach.DozeS4TimeoutDc,
  1722. &psl->ppp->user.IdleDc.Action
  1723. );
  1724. }
  1725. if (pcp->bDynamicThrottleAc)
  1726. {
  1727. if(lstrcmpi(
  1728. pcp->lpszDynamicThrottleAc,
  1729. _T("NONE")
  1730. ) == 0)
  1731. {
  1732. psl->pmppp->ProcessorPolicyAc.DynamicThrottle =
  1733. PO_THROTTLE_NONE;
  1734. } else if(lstrcmpi(
  1735. pcp->lpszDynamicThrottleAc,
  1736. _T("CONSTANT")
  1737. ) == 0)
  1738. {
  1739. psl->pmppp->ProcessorPolicyAc.DynamicThrottle =
  1740. PO_THROTTLE_CONSTANT;
  1741. } else if(lstrcmpi(
  1742. pcp->lpszDynamicThrottleAc,
  1743. _T("DEGRADE")
  1744. ) == 0)
  1745. {
  1746. psl->pmppp->ProcessorPolicyAc.DynamicThrottle =
  1747. PO_THROTTLE_DEGRADE;
  1748. } else if(lstrcmpi(
  1749. pcp->lpszDynamicThrottleAc,
  1750. _T("ADAPTIVE")
  1751. ) == 0)
  1752. {
  1753. psl->pmppp->ProcessorPolicyAc.DynamicThrottle =
  1754. PO_THROTTLE_ADAPTIVE;
  1755. } else {
  1756. g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM);
  1757. bRes = FALSE;
  1758. }
  1759. }
  1760. if (pcp->bDynamicThrottleDc)
  1761. {
  1762. if(lstrcmpi(
  1763. pcp->lpszDynamicThrottleDc,
  1764. _T("NONE")
  1765. ) == 0)
  1766. {
  1767. psl->pmppp->ProcessorPolicyDc.DynamicThrottle =
  1768. PO_THROTTLE_NONE;
  1769. } else if(lstrcmpi(
  1770. pcp->lpszDynamicThrottleDc,
  1771. _T("CONSTANT")
  1772. ) == 0)
  1773. {
  1774. psl->pmppp->ProcessorPolicyDc.DynamicThrottle =
  1775. PO_THROTTLE_CONSTANT;
  1776. } else if(lstrcmpi(
  1777. pcp->lpszDynamicThrottleDc,
  1778. _T("DEGRADE")
  1779. ) == 0)
  1780. {
  1781. psl->pmppp->ProcessorPolicyDc.DynamicThrottle =
  1782. PO_THROTTLE_DEGRADE;
  1783. } else if(lstrcmpi(
  1784. pcp->lpszDynamicThrottleDc,
  1785. _T("ADAPTIVE")
  1786. ) == 0)
  1787. {
  1788. psl->pmppp->ProcessorPolicyDc.DynamicThrottle =
  1789. PO_THROTTLE_ADAPTIVE;
  1790. } else {
  1791. g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM);
  1792. bRes = FALSE;
  1793. }
  1794. }
  1795. if (bRes)
  1796. {
  1797. // attempt to update power scheme
  1798. g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
  1799. bRes = MyWriteScheme(psl);
  1800. // keep active power scheme consistent
  1801. if (bRes)
  1802. {
  1803. UINT uiIDactive;
  1804. if (GetActivePwrScheme(&uiIDactive) &&
  1805. (psl->uiID == uiIDactive))
  1806. {
  1807. bRes = SetActivePwrScheme(psl->uiID,NULL,NULL);
  1808. }
  1809. }
  1810. FreeScheme(psl);
  1811. return bRes;
  1812. }
  1813. else
  1814. {
  1815. return FALSE;
  1816. }
  1817. }
  1818. else
  1819. {
  1820. return FALSE;
  1821. }
  1822. }
  1823. BOOL
  1824. DoExport(
  1825. LPCTSTR lpszName,
  1826. LPCTSTR lpszFile
  1827. )
  1828. /*++
  1829. Routine Description:
  1830. Exports a power scheme
  1831. Arguments:
  1832. lpszName - the name of the scheme
  1833. lpszFile - the file to hold the scheme
  1834. Return Value:
  1835. TRUE if successful
  1836. FALSE if failed
  1837. --*/
  1838. {
  1839. DWORD res; // write result value
  1840. HANDLE f; // file handle
  1841. // find scheme
  1842. PSCHEME_LIST psl = FindScheme(lpszName,0);
  1843. if(!psl) {
  1844. return FALSE;
  1845. }
  1846. // write to file
  1847. f = CreateFile(
  1848. lpszFile,
  1849. GENERIC_WRITE,
  1850. 0,
  1851. NULL,
  1852. CREATE_ALWAYS,
  1853. FILE_ATTRIBUTE_NORMAL,
  1854. NULL
  1855. );
  1856. if (f == INVALID_HANDLE_VALUE)
  1857. {
  1858. FormatMessage(
  1859. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1860. FORMAT_MESSAGE_FROM_SYSTEM |
  1861. FORMAT_MESSAGE_IGNORE_INSERTS,
  1862. NULL,
  1863. GetLastError(),
  1864. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1865. (LPTSTR)&g_lpszErr2,
  1866. 0,
  1867. NULL
  1868. );
  1869. FreeScheme(psl);
  1870. return FALSE;
  1871. }
  1872. if (!WriteFile(
  1873. f,
  1874. psl->ppp,
  1875. sizeof(POWER_POLICY),
  1876. &res,
  1877. NULL
  1878. ))
  1879. {
  1880. FormatMessage(
  1881. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1882. FORMAT_MESSAGE_FROM_SYSTEM |
  1883. FORMAT_MESSAGE_IGNORE_INSERTS,
  1884. NULL,
  1885. GetLastError(),
  1886. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1887. (LPTSTR)&g_lpszErr2,
  1888. 0,
  1889. NULL
  1890. );
  1891. CloseHandle(f);
  1892. FreeScheme(psl);
  1893. return FALSE;
  1894. }
  1895. if (!WriteFile(
  1896. f,
  1897. psl->pmppp,
  1898. sizeof(MACHINE_PROCESSOR_POWER_POLICY),
  1899. &res,
  1900. NULL
  1901. ))
  1902. {
  1903. FormatMessage(
  1904. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1905. FORMAT_MESSAGE_FROM_SYSTEM |
  1906. FORMAT_MESSAGE_IGNORE_INSERTS,
  1907. NULL,
  1908. GetLastError(),
  1909. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1910. (LPTSTR)&g_lpszErr2,
  1911. 0,
  1912. NULL
  1913. );
  1914. CloseHandle(f);
  1915. FreeScheme(psl);
  1916. return FALSE;
  1917. }
  1918. CloseHandle(f);
  1919. FreeScheme(psl);
  1920. return TRUE;
  1921. }
  1922. BOOL
  1923. DoImport(
  1924. LPCTSTR lpszName,
  1925. LPCTSTR lpszFile
  1926. )
  1927. /*++
  1928. Routine Description:
  1929. Imports a power scheme
  1930. If the scheme already exists, overwrites it
  1931. Arguments:
  1932. lpszName - the name of the scheme
  1933. lpszFile - the file that holds the scheme
  1934. Return Value:
  1935. TRUE if successful
  1936. FALSE if failed
  1937. --*/
  1938. {
  1939. DWORD res; // write result value
  1940. HANDLE f; // file handle
  1941. UINT uiIDactive; // active ID
  1942. PSCHEME_LIST psl;
  1943. // check for pre-existing scheme
  1944. psl = FindScheme(lpszName,0);
  1945. // if didn't exist, create it
  1946. if (!psl)
  1947. {
  1948. psl = CreateScheme(
  1949. NEWSCHEME,
  1950. (lstrlen(lpszName)+1)*sizeof(TCHAR),
  1951. lpszName,
  1952. (lstrlen(lpszName)+1)*sizeof(TCHAR),
  1953. lpszName,
  1954. NULL // psl->ppp will be allocated but uninitialized
  1955. );
  1956. // check for successful alloc
  1957. if(!psl) {
  1958. return FALSE;
  1959. }
  1960. }
  1961. // open file
  1962. f = CreateFile(
  1963. lpszFile,
  1964. GENERIC_READ,
  1965. FILE_SHARE_READ,
  1966. NULL,
  1967. OPEN_EXISTING,
  1968. FILE_ATTRIBUTE_NORMAL,
  1969. NULL
  1970. );
  1971. if (f == INVALID_HANDLE_VALUE)
  1972. {
  1973. FormatMessage(
  1974. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1975. FORMAT_MESSAGE_FROM_SYSTEM |
  1976. FORMAT_MESSAGE_IGNORE_INSERTS,
  1977. NULL,
  1978. GetLastError(),
  1979. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1980. (LPTSTR)&g_lpszErr2,
  1981. 0,
  1982. NULL
  1983. );
  1984. FreeScheme(psl);
  1985. return FALSE;
  1986. }
  1987. // read scheme
  1988. if (!ReadFile(
  1989. f,
  1990. psl->ppp,
  1991. sizeof(POWER_POLICY),
  1992. &res,
  1993. NULL
  1994. ))
  1995. {
  1996. FormatMessage(
  1997. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1998. FORMAT_MESSAGE_FROM_SYSTEM |
  1999. FORMAT_MESSAGE_IGNORE_INSERTS,
  2000. NULL,
  2001. GetLastError(),
  2002. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  2003. (LPTSTR)&g_lpszErr2,
  2004. 0,
  2005. NULL
  2006. );
  2007. CloseHandle(f);
  2008. FreeScheme(psl);
  2009. return FALSE;
  2010. }
  2011. if (!ReadFile(
  2012. f,
  2013. psl->pmppp,
  2014. sizeof(MACHINE_PROCESSOR_POWER_POLICY),
  2015. &res,
  2016. NULL
  2017. ))
  2018. {
  2019. FormatMessage(
  2020. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  2021. FORMAT_MESSAGE_FROM_SYSTEM |
  2022. FORMAT_MESSAGE_IGNORE_INSERTS,
  2023. NULL,
  2024. GetLastError(),
  2025. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  2026. (LPTSTR)&g_lpszErr2,
  2027. 0,
  2028. NULL
  2029. );
  2030. CloseHandle(f);
  2031. FreeScheme(psl);
  2032. return FALSE;
  2033. }
  2034. CloseHandle(f);
  2035. g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
  2036. // save scheme
  2037. if (!MyWriteScheme(psl))
  2038. {
  2039. FreeScheme(psl);
  2040. return FALSE;
  2041. }
  2042. // check against active scheme
  2043. if (!GetActivePwrScheme(&uiIDactive))
  2044. {
  2045. return FALSE;
  2046. }
  2047. if (uiIDactive == psl->uiID)
  2048. {
  2049. if (!SetActivePwrScheme(psl->uiID,NULL,NULL))
  2050. {
  2051. return FALSE;
  2052. }
  2053. }
  2054. FreeScheme(psl);
  2055. return TRUE;
  2056. }
  2057. BOOL
  2058. DoHibernate(
  2059. LPCTSTR lpszBoolStr
  2060. )
  2061. /*++
  2062. Routine Description:
  2063. Enables/Disables hibernation
  2064. NOTE: this functionality pretty much taken verbatim from the test program
  2065. "base\ntos\po\tests\ehib\ehib.c"
  2066. Arguments:
  2067. lpszBoolStr - "on" or "off"
  2068. Return Value:
  2069. TRUE if successful
  2070. FALSE if failed
  2071. --*/
  2072. {
  2073. BOOLEAN bEnable; // doesn't work with a BOOL, apparently
  2074. NTSTATUS Status;
  2075. HANDLE hToken;
  2076. TOKEN_PRIVILEGES tkp;
  2077. // adjust privilege to allow hiber enable/disable
  2078. if( NT_SUCCESS( OpenProcessToken(
  2079. GetCurrentProcess(),
  2080. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  2081. &hToken
  2082. )))
  2083. {
  2084. if( NT_SUCCESS( LookupPrivilegeValue(
  2085. NULL,
  2086. SE_CREATE_PAGEFILE_NAME,
  2087. &tkp.Privileges[0].Luid
  2088. )))
  2089. {
  2090. tkp.PrivilegeCount = 1;
  2091. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  2092. if ( !NT_SUCCESS( AdjustTokenPrivileges(
  2093. hToken,
  2094. FALSE,
  2095. &tkp,
  2096. 0,
  2097. NULL,
  2098. 0
  2099. )))
  2100. {
  2101. g_lpszErr = GetResString(IDS_HIBER_PRIVILEGE);
  2102. return FALSE;
  2103. }
  2104. } else {
  2105. g_lpszErr = GetResString(IDS_HIBER_PRIVILEGE);
  2106. return FALSE;
  2107. }
  2108. } else {
  2109. g_lpszErr = GetResString(IDS_HIBER_PRIVILEGE);
  2110. return FALSE;
  2111. }
  2112. // parse enable/disable state
  2113. if (!lstrcmpi(lpszBoolStr,GetResString(IDS_ON))) {
  2114. bEnable = TRUE;
  2115. } else if (!lstrcmpi(lpszBoolStr,GetResString(IDS_OFF))) {
  2116. bEnable = FALSE;
  2117. } else {
  2118. g_lpszErr = GetResString(IDS_HIBER_INVALID_STATE);
  2119. return FALSE;
  2120. }
  2121. // enable/disable hibernation
  2122. if (!g_bHiberFileSupported) {
  2123. g_lpszErr = GetResString(IDS_HIBER_UNSUPPORTED);
  2124. return FALSE;
  2125. } else {
  2126. Status = NtPowerInformation(
  2127. SystemReserveHiberFile,
  2128. &bEnable,
  2129. sizeof(bEnable),
  2130. NULL,
  2131. 0
  2132. );
  2133. if (!NT_SUCCESS(Status)) {
  2134. FormatMessage(
  2135. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  2136. FORMAT_MESSAGE_FROM_SYSTEM |
  2137. FORMAT_MESSAGE_IGNORE_INSERTS,
  2138. NULL,
  2139. RtlNtStatusToDosError(Status),
  2140. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  2141. (LPTSTR)&g_lpszErr2,
  2142. 0,
  2143. NULL
  2144. );
  2145. return FALSE;
  2146. }
  2147. }
  2148. return TRUE;
  2149. }
  2150. BOOL
  2151. DoUsage()
  2152. /*++
  2153. Routine Description:
  2154. Displays usage information
  2155. Arguments:
  2156. none
  2157. Return Value:
  2158. TRUE if successful
  2159. FALSE if failed
  2160. --*/
  2161. {
  2162. ULONG ulIdx;
  2163. for(ulIdx=IDS_USAGE_START;ulIdx<=IDS_USAGE_END;ulIdx++)
  2164. DISPLAY_MESSAGE(stdout, GetResString(ulIdx));
  2165. return TRUE;
  2166. }