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.

1064 lines
24 KiB

  1. /*
  2. TZTool - Thermal Zone Information Tool
  3. tztool.c
  4. This the MAIN TZTool - C file.
  5. Copyright (c) 1999 Microsoft Corporation
  6. Module Name:
  7. TZTool - TZTool.c
  8. Abstract:
  9. TZTool - Thermal Zone Information Tool
  10. Author:
  11. Vincent Geglia (VincentG)
  12. Notes:
  13. Revision History:
  14. 1.2 - (VincentG) Port to Win64
  15. 1.1 - (JVert) add Kelvin to Farenheit conversion. Add throttling gauge.
  16. 1.0 - Original version
  17. */
  18. // Includes
  19. #include <nt.h>
  20. #include <ntrtl.h>
  21. #include <nturtl.h>
  22. #include <windows.h>
  23. #include <ole2.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <ntpoapi.h>
  27. #include <commctrl.h>
  28. #include "resource.h"
  29. #include "wmium.h"
  30. // Definitions
  31. #define THERMAL_ZONE_GUID {0xa1bc18c0, 0xa7c8, 0x11d1, {0xbf, 0x3c, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10} }
  32. #define COOLING_PASSIVE 0
  33. #define COOLING_ACTIVE 1
  34. #define COOLING_UPDATE_TZONE 2
  35. #define TIMER_ID 1
  36. #define TIMER_POLL_INTERVAL 500
  37. #define MAX_ACTIVE_COOLING_LEVELS 10
  38. #define MAX_THERMAL_ZONES 10
  39. #define K_TO_F(_deg_) (((_deg_) - 2731) * 9 / 5 + 320)
  40. GUID ThermalZoneGuid = THERMAL_ZONE_GUID;
  41. // Structures
  42. typedef struct _THERMAL_INFORMATION {
  43. ULONG ThermalStamp;
  44. ULONG ThermalConstant1;
  45. ULONG ThermalConstant2;
  46. KAFFINITY Processors;
  47. ULONG SamplingPeriod;
  48. ULONG CurrentTemperature;
  49. ULONG PassiveTripPoint;
  50. ULONG CriticalTripPoint;
  51. UCHAR ActiveTripPointCount;
  52. ULONG ActiveTripPoint[MAX_ACTIVE_COOLING_LEVELS];
  53. } THERMAL_INFORMATION, *PTHERMAL_INFORMATION;
  54. typedef struct _TZONE_INFO {
  55. THERMAL_INFORMATION ThermalInfo;
  56. ULONG64 TimeStamp;
  57. ULONG TZoneIndex;
  58. UCHAR TZoneName[100];
  59. } TZONE_INFO, *PTZONE_INFO;
  60. // Global variables
  61. PTZONE_INFO g_TZonePtr = 0;
  62. WMIHANDLE g_WmiHandle;
  63. INT g_PollTz = 0;
  64. BOOL g_Fahrenheit = FALSE;
  65. // Function declarations
  66. WINAPI
  67. WinMain (
  68. IN HINSTANCE hInstance,
  69. IN HINSTANCE hPrevInstance,
  70. IN PSTR CmdLine,
  71. IN INT CmdShow
  72. );
  73. INT_PTR CALLBACK
  74. TZoneDlgProc (
  75. IN HWND wnd,
  76. IN UINT Msg,
  77. IN WPARAM wParam,
  78. IN LPARAM lParam
  79. );
  80. ULONG
  81. UpdateTZoneData (
  82. IN OUT PTZONE_INFO ReturnedTZoneInfo,
  83. IN WMIHANDLE *Handle
  84. );
  85. ULONG64
  86. SystemTimeToUlong (
  87. IN LPSYSTEMTIME SysTime
  88. );
  89. VOID
  90. SetCoolingMode (
  91. IN UCHAR Mode
  92. );
  93. VOID
  94. UpgradePrivileges (
  95. VOID
  96. );
  97. VOID
  98. UpdateTZoneListBox (
  99. IN HANDLE wnd
  100. );
  101. VOID
  102. UpdateTZoneDetails (
  103. IN HANDLE wnd
  104. );
  105. VOID
  106. UpdateTZoneGauge (
  107. IN HANDLE wnd
  108. );
  109. VOID
  110. UpdateCPUGauge(
  111. IN HWND hwnd
  112. );
  113. VOID
  114. UpdateCoolingMode (
  115. IN HWND hwnd
  116. );
  117. /*++
  118. Routine Description:
  119. Windows application Entry Point
  120. Arguments:
  121. <standard winmain arguments>
  122. Return Value:
  123. 0 if successful, otherwise error status
  124. --*/
  125. WINAPI
  126. WinMain (
  127. IN HINSTANCE hInstance,
  128. IN HINSTANCE hPrevInstance,
  129. IN PSTR CmdLine,
  130. IN INT CmdShow
  131. )
  132. {
  133. UCHAR text [200];
  134. INITCOMMONCONTROLSEX CommonCtl;
  135. TZONE_INFO TZones [MAX_THERMAL_ZONES];
  136. ULONG status = 0;
  137. INT64 RetVal = 0;
  138. // Initialize TZ structures
  139. ZeroMemory (&TZones, sizeof (TZones));
  140. g_TZonePtr = (PTZONE_INFO) &TZones;
  141. // Initialize Common Controls DLL for gauge control
  142. CommonCtl.dwSize = sizeof (CommonCtl);
  143. CommonCtl.dwICC = ICC_PROGRESS_CLASS;
  144. InitCommonControlsEx (&CommonCtl);
  145. // Open WMI data source for the TZs
  146. status = WmiOpenBlock ((LPGUID) &ThermalZoneGuid,
  147. GENERIC_READ,
  148. &g_WmiHandle);
  149. if (status != ERROR_SUCCESS) {
  150. sprintf (text,
  151. "Unable to open thermal zone GUIDs. This computer may not be equipped with thermal zones, or may not be in ACPI mode.\nError: %d",
  152. status);
  153. MessageBox (NULL,
  154. text,
  155. "Fatal Error",
  156. MB_ICONERROR | MB_OK);
  157. return status;
  158. }
  159. // In order to change the policies, we need greater access privileges
  160. UpgradePrivileges ();
  161. // Show the main dialog box
  162. DialogBox (hInstance,
  163. MAKEINTRESOURCE (IDD_TZDLG),
  164. NULL,
  165. TZoneDlgProc);
  166. return 0;
  167. }
  168. /*++
  169. Routine Description:
  170. Standard Windows Dialog Message Loop
  171. Arguments:
  172. <standard dialog message loop arguments>
  173. Return Value:
  174. FALSE if message not handled, TRUE if message handled
  175. --*/
  176. INT_PTR CALLBACK
  177. TZoneDlgProc (
  178. IN HWND wnd,
  179. IN UINT Msg,
  180. IN WPARAM wParam,
  181. IN LPARAM lParam
  182. )
  183. {
  184. ULONG Count = 0;
  185. INT_PTR RetVal = 0;
  186. switch (Msg) {
  187. case WM_TIMER:
  188. if (g_PollTz) {
  189. SetCoolingMode (COOLING_UPDATE_TZONE);
  190. }
  191. if (UpdateTZoneData (g_TZonePtr, g_WmiHandle)) {
  192. UpdateCoolingMode (wnd);
  193. UpdateTZoneDetails (wnd);
  194. UpdateTZoneGauge (wnd);
  195. }
  196. UpdateCPUGauge(wnd);
  197. return TRUE;
  198. case WM_INITDIALOG:
  199. // Fill TZ structure with initial values
  200. UpdateTZoneData (g_TZonePtr, g_WmiHandle);
  201. // Initialize all controls
  202. UpdateTZoneListBox (wnd);
  203. UpdateTZoneDetails (wnd);
  204. UpdateTZoneGauge (wnd);
  205. UpdateCPUGauge(wnd);
  206. UpdateCoolingMode(wnd);
  207. // Initialize polling timer
  208. SetTimer (wnd,
  209. TIMER_ID,
  210. TIMER_POLL_INTERVAL,
  211. NULL);
  212. // Set gauge colors
  213. SendDlgItemMessage (wnd,
  214. IDC_TZTEMP1,
  215. PBM_SETBARCOLOR,
  216. 0,
  217. (LPARAM) (COLORREF) (0x0000FF));
  218. SendDlgItemMessage (wnd,
  219. IDC_TZTEMP1,
  220. PBM_SETBKCOLOR,
  221. 0,
  222. (LPARAM) (COLORREF) (0x000000));
  223. SendDlgItemMessage (wnd,
  224. IDC_THROTTLE,
  225. PBM_SETBARCOLOR,
  226. 0,
  227. (LPARAM) (COLORREF) (0x0000FF));
  228. SendDlgItemMessage (wnd,
  229. IDC_THROTTLE,
  230. PBM_SETBKCOLOR,
  231. 0,
  232. (LPARAM) (COLORREF) (0x000000));
  233. return TRUE;
  234. case WM_COMMAND:
  235. switch (LOWORD (wParam)) {
  236. // Cleanup and exit
  237. case IDOK:
  238. KillTimer (wnd, TIMER_ID);
  239. EndDialog (wnd, 0);
  240. return TRUE;
  241. // Check to see if user selected a new TZ
  242. case IDC_TZSELECT:
  243. if (HIWORD (wParam) == CBN_SELCHANGE) {
  244. UpdateTZoneDetails (wnd);
  245. UpdateTZoneGauge (wnd);
  246. return TRUE;
  247. }
  248. break;
  249. case IDC_POLLTZ:
  250. // Check to see if user changed the TZ Polling setting
  251. if (HIWORD (wParam) == BN_CLICKED) {
  252. RetVal = SendDlgItemMessage (wnd,
  253. IDC_POLLTZ,
  254. BM_GETCHECK,
  255. 0,
  256. 0);
  257. if (!g_PollTz && RetVal == BST_CHECKED) {
  258. g_PollTz = TRUE;
  259. }
  260. if (g_PollTz && RetVal == BST_UNCHECKED) {
  261. g_PollTz = FALSE;
  262. }
  263. }
  264. break;
  265. case IDC_FAHR:
  266. // Check to see if user changed the Fahrenheit setting
  267. if (HIWORD(wParam) == BN_CLICKED) {
  268. RetVal = SendDlgItemMessage(wnd,
  269. IDC_FAHR,
  270. BM_GETCHECK,
  271. 0,
  272. 0);
  273. if (!g_Fahrenheit && RetVal == BST_CHECKED) {
  274. g_Fahrenheit = TRUE;
  275. SetDlgItemText(wnd, IDC_MINTEMP, "37F");
  276. UpdateTZoneDetails(wnd);
  277. UpdateTZoneGauge(wnd);
  278. } else if (g_Fahrenheit && RetVal == BST_UNCHECKED) {
  279. g_Fahrenheit = FALSE;
  280. SetDlgItemText(wnd, IDC_MINTEMP, "276K");
  281. UpdateTZoneDetails(wnd);
  282. UpdateTZoneGauge(wnd);
  283. }
  284. }
  285. break;
  286. default:
  287. break;
  288. }
  289. break;
  290. case WM_CLOSE:
  291. KillTimer (wnd, TIMER_ID);
  292. EndDialog (wnd, 0);
  293. break;
  294. case WM_DESTROY:
  295. PostQuitMessage(0);
  296. break;
  297. default:
  298. break;
  299. }
  300. return 0;
  301. }
  302. /*++
  303. Routine Description:
  304. Issue WMI call to update TZ structures
  305. Arguments:
  306. ReturnedTZoneInfo - Pointer to array of TZ structures
  307. Handle - Handle to WMI
  308. Return Value:
  309. FALSE if no TZs were updated, TRUE if one or more TZs have an update
  310. --*/
  311. ULONG
  312. UpdateTZoneData (
  313. IN OUT PTZONE_INFO ReturnedTZoneInfo,
  314. IN WMIHANDLE *Handle
  315. )
  316. {
  317. ULONG status = 0;
  318. ULONG BufferSize = 0;
  319. PWNODE_ALL_DATA WmiAllData;
  320. PTHERMAL_INFORMATION ThermalInfo;
  321. ULONG Offset = 0;
  322. UCHAR *AllDataBuffer = 0;
  323. UCHAR *AllDataBufferSave = 0;
  324. UCHAR *OrigDataBuffer = 0;
  325. UCHAR *InstanceName = 0;
  326. ULONG TZCount = 0;
  327. ULONG Temp = 0;
  328. SYSTEMTIME SysTime;
  329. BOOL Updated = FALSE;
  330. status = WmiQueryAllData (Handle,
  331. &BufferSize,
  332. 0);
  333. if (status != ERROR_INSUFFICIENT_BUFFER) {
  334. return FALSE;
  335. }
  336. AllDataBuffer = malloc (BufferSize);
  337. if (!AllDataBuffer) {
  338. return FALSE;
  339. }
  340. //
  341. // Save original pointer to use with free()
  342. //
  343. OrigDataBuffer = AllDataBuffer;
  344. status = WmiQueryAllData (Handle,
  345. &BufferSize,
  346. AllDataBuffer);
  347. if (status != ERROR_SUCCESS) {
  348. free (AllDataBuffer);
  349. return FALSE;
  350. }
  351. // BUG BUG Assuming Thermal GUID only has one instance
  352. // Save away the buffer pointer as it wll get moved in the following while loop
  353. AllDataBufferSave = AllDataBuffer;
  354. while (TZCount < MAX_THERMAL_ZONES) {
  355. WmiAllData = (PWNODE_ALL_DATA) AllDataBuffer;
  356. if (WmiAllData->WnodeHeader.Flags & WNODE_FLAG_FIXED_INSTANCE_SIZE) {
  357. ThermalInfo = (PTHERMAL_INFORMATION) &AllDataBuffer[WmiAllData->DataBlockOffset];
  358. } else {
  359. ThermalInfo = (PTHERMAL_INFORMATION) &AllDataBuffer[WmiAllData->OffsetInstanceDataAndLength[0].OffsetInstanceData];
  360. }
  361. Offset = (ULONG) AllDataBuffer[WmiAllData->OffsetInstanceNameOffsets];
  362. InstanceName = (UCHAR *) &AllDataBuffer[Offset + 2];
  363. // Update TZone structure if timestamp has changed
  364. if (!ReturnedTZoneInfo[TZCount].TZoneIndex || (ThermalInfo->ThermalStamp != ReturnedTZoneInfo[TZCount].ThermalInfo.ThermalStamp)) {
  365. strcpy (ReturnedTZoneInfo[TZCount].TZoneName, InstanceName);
  366. GetSystemTime (&SysTime);
  367. ReturnedTZoneInfo[TZCount].TimeStamp = SystemTimeToUlong (&SysTime);
  368. ReturnedTZoneInfo[TZCount].TZoneIndex = TZCount + 1;
  369. memcpy (&ReturnedTZoneInfo[TZCount].ThermalInfo,
  370. ThermalInfo,
  371. sizeof (THERMAL_INFORMATION));
  372. Updated = TRUE;
  373. }
  374. if (!WmiAllData->WnodeHeader.Linkage) {
  375. break;
  376. }
  377. AllDataBuffer += WmiAllData->WnodeHeader.Linkage;
  378. TZCount ++;
  379. }
  380. // Restore the buffer pointer to the orginal location
  381. AllDataBuffer = AllDataBufferSave;
  382. free (OrigDataBuffer);
  383. return Updated;
  384. }
  385. /*++
  386. Routine Description:
  387. Convert a system time structure to a 64bit ULONG
  388. Arguments:
  389. SysTime - Pointer to system time structure to compare against current time
  390. Return Value:
  391. Number of elapsed seconds between SysTime and current time
  392. --*/
  393. ULONG64
  394. SystemTimeToUlong (
  395. IN LPSYSTEMTIME SysTime
  396. )
  397. {
  398. ULONG64 TimeCount = 0;
  399. // BUG BUG Doesn't account for leap year
  400. TimeCount += SysTime->wYear * 31536000;
  401. TimeCount += SysTime->wMonth * 2628000;
  402. TimeCount += SysTime->wDay * 86400;
  403. TimeCount += SysTime->wHour * 3600;
  404. TimeCount += SysTime->wMinute * 60;
  405. TimeCount += SysTime->wSecond;
  406. return TimeCount;
  407. }
  408. /*++
  409. Routine Description:
  410. Sets the cooling mode to ACTIVE, PASSIVE, or UPDATE ONLY. This is accomplished by
  411. changing the FanThrottleTolerance value in the power policy. Setting it to maxthrottle
  412. effectively puts the system into PASSIVE cooling mode. Setting it to 100% will put
  413. the system in ACTIVE cooling mode UNLESS the current temperature exceeds the passive
  414. cooling trip points.
  415. Arguments:
  416. Mode - Value to select the new cooling mode
  417. Return Value:
  418. None
  419. --*/
  420. VOID
  421. SetCoolingMode (
  422. IN UCHAR Mode
  423. )
  424. {
  425. SYSTEM_POWER_POLICY SysPolicy;
  426. ULONG Status = 0;
  427. UCHAR TempFanThrottleTolerance = 0;
  428. // BUG BUG - This mechanism will currently only for while the machine is on AC.
  429. Status = NtPowerInformation(
  430. SystemPowerPolicyAc,
  431. 0,
  432. 0,
  433. &SysPolicy,
  434. sizeof (SysPolicy)
  435. );
  436. if (Status != ERROR_SUCCESS) {
  437. return;
  438. }
  439. switch (Mode) {
  440. case COOLING_PASSIVE:
  441. SysPolicy.FanThrottleTolerance = SysPolicy.MinThrottle;
  442. break;
  443. case COOLING_ACTIVE:
  444. SysPolicy.FanThrottleTolerance = 100;
  445. break;
  446. case COOLING_UPDATE_TZONE:
  447. TempFanThrottleTolerance = SysPolicy.FanThrottleTolerance;
  448. SysPolicy.FanThrottleTolerance = SysPolicy.FanThrottleTolerance != SysPolicy.MinThrottle ? SysPolicy.MinThrottle : 100;
  449. break;
  450. default:
  451. return;
  452. }
  453. Status = NtPowerInformation(
  454. SystemPowerPolicyAc,
  455. &SysPolicy,
  456. sizeof (SysPolicy),
  457. &SysPolicy,
  458. sizeof (SysPolicy)
  459. );
  460. if (Status != ERROR_SUCCESS) {
  461. return;
  462. }
  463. if (Mode == COOLING_UPDATE_TZONE) {
  464. SysPolicy.FanThrottleTolerance = TempFanThrottleTolerance;
  465. Status = NtPowerInformation(
  466. SystemPowerPolicyAc,
  467. &SysPolicy,
  468. sizeof (SysPolicy),
  469. &SysPolicy,
  470. sizeof (SysPolicy)
  471. );
  472. if (Status != ERROR_SUCCESS) {
  473. return;
  474. }
  475. }
  476. }
  477. /*++
  478. Routine Description:
  479. Upgrades the process's access permission to change system power policy
  480. Arguments:
  481. None
  482. Return Value:
  483. None
  484. --*/
  485. VOID
  486. UpgradePrivileges (
  487. VOID
  488. )
  489. {
  490. TOKEN_PRIVILEGES tkp;
  491. HANDLE hToken;
  492. OpenProcessToken (GetCurrentProcess(),
  493. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  494. &hToken);
  495. LookupPrivilegeValue (NULL,
  496. SE_SHUTDOWN_NAME,
  497. &tkp.Privileges[0].Luid);
  498. tkp.PrivilegeCount = 1;
  499. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  500. AdjustTokenPrivileges (hToken,
  501. FALSE,
  502. &tkp,
  503. 0,
  504. NULL,
  505. 0);
  506. }
  507. /*++
  508. Routine Description:
  509. Updates the entries presented in the TZ selection combo box
  510. Arguments:
  511. wnd - A handle to the control's window
  512. Return Value:
  513. None
  514. --*/
  515. VOID
  516. UpdateTZoneListBox (
  517. IN HANDLE wnd
  518. )
  519. {
  520. ULONG Count = 0;
  521. // Reset the contents
  522. SendDlgItemMessage (wnd,
  523. IDC_TZSELECT,
  524. CB_RESETCONTENT,
  525. 0,
  526. 0);
  527. while (Count < MAX_THERMAL_ZONES) {
  528. if (g_TZonePtr[Count].TZoneIndex) {
  529. SendDlgItemMessage (wnd,
  530. IDC_TZSELECT,
  531. CB_ADDSTRING,
  532. 0,
  533. (LPARAM) g_TZonePtr[Count].TZoneName);
  534. } else {
  535. break;
  536. }
  537. Count ++;
  538. }
  539. // Automatically select first TZone
  540. SendDlgItemMessage (wnd,
  541. IDC_TZSELECT,
  542. CB_SETCURSEL,
  543. 0,
  544. 0);
  545. }
  546. /*++
  547. Routine Description:
  548. Updates the details for the currently selected TZ
  549. Arguments:
  550. wnd - A handle to the control's window
  551. Return Value:
  552. None
  553. --*/
  554. VOID
  555. UpdateTZoneDetails (
  556. IN HANDLE wnd
  557. )
  558. {
  559. UCHAR text[1000], texttmp [1000];
  560. UCHAR CurrentTZone = 0;
  561. INT_PTR RetVal = 0;
  562. UCHAR Count = 0;
  563. ULONG Fahrenheit;
  564. RetVal = SendDlgItemMessage (wnd,
  565. IDC_TZSELECT,
  566. CB_GETCURSEL,
  567. 0,
  568. 0);
  569. if (RetVal == CB_ERR) {
  570. return;
  571. }
  572. if (g_Fahrenheit) {
  573. Fahrenheit = K_TO_F(g_TZonePtr[RetVal].ThermalInfo.PassiveTripPoint);
  574. sprintf (text,
  575. "Passive Trip Point:\t%d.%dF\nThermal Constant 1:\t%d\nThermal Constant 2:\t%d",
  576. Fahrenheit / 10,
  577. Fahrenheit % 10,
  578. g_TZonePtr[RetVal].ThermalInfo.ThermalConstant1,
  579. g_TZonePtr[RetVal].ThermalInfo.ThermalConstant2);
  580. } else {
  581. sprintf (text,
  582. "Passive Trip Point:\t%d.%dK\nThermal Constant 1:\t%d\nThermal Constant 2:\t%d",
  583. g_TZonePtr[RetVal].ThermalInfo.PassiveTripPoint / 10,
  584. g_TZonePtr[RetVal].ThermalInfo.PassiveTripPoint % 10,
  585. g_TZonePtr[RetVal].ThermalInfo.ThermalConstant1,
  586. g_TZonePtr[RetVal].ThermalInfo.ThermalConstant2);
  587. }
  588. SetDlgItemText (wnd,
  589. IDC_PSVDETAILS,
  590. text);
  591. ZeroMemory (&text, sizeof (text));
  592. while (Count < g_TZonePtr[RetVal].ThermalInfo.ActiveTripPointCount) {
  593. if (g_Fahrenheit) {
  594. Fahrenheit = K_TO_F(g_TZonePtr[RetVal].ThermalInfo.ActiveTripPoint[Count]);
  595. sprintf (texttmp,
  596. "Active Trip Point #%d:\t%d.%dF\n",
  597. Count,
  598. Fahrenheit / 10,
  599. Fahrenheit % 10);
  600. } else {
  601. sprintf (texttmp,
  602. "Active Trip Point #%d:\t%d.%dK\n",
  603. Count,
  604. g_TZonePtr[RetVal].ThermalInfo.ActiveTripPoint[Count] / 10,
  605. g_TZonePtr[RetVal].ThermalInfo.ActiveTripPoint[Count] % 10);
  606. }
  607. strcat (text, texttmp);
  608. Count ++;
  609. }
  610. SetDlgItemText (wnd,
  611. IDC_ACXDETAILS,
  612. text);
  613. }
  614. /*++
  615. Routine Description:
  616. Updates the progress bar control (temp gauge) for the currently selected TZ
  617. Arguments:
  618. wnd - A handle to the control's window
  619. Return Value:
  620. None
  621. --*/
  622. VOID
  623. UpdateTZoneGauge (
  624. IN HANDLE wnd
  625. )
  626. {
  627. UCHAR CurrentTZone = 0;
  628. INT_PTR RetVal = 0;
  629. UCHAR text[20];
  630. ULONG Fahrenheit;
  631. RetVal = SendDlgItemMessage (wnd,
  632. IDC_TZSELECT,
  633. CB_GETCURSEL,
  634. 0,
  635. 0);
  636. if (RetVal == CB_ERR) {
  637. return;
  638. }
  639. if (g_Fahrenheit) {
  640. Fahrenheit = K_TO_F(g_TZonePtr[RetVal].ThermalInfo.CriticalTripPoint);
  641. sprintf (text,
  642. "%d.%dF",
  643. Fahrenheit / 10,
  644. Fahrenheit % 10);
  645. } else {
  646. sprintf (text,
  647. "%d.%dK",
  648. g_TZonePtr[RetVal].ThermalInfo.CriticalTripPoint / 10,
  649. g_TZonePtr[RetVal].ThermalInfo.CriticalTripPoint % 10);
  650. }
  651. SetDlgItemText (wnd,
  652. IDC_CRTTEMP,
  653. text);
  654. if (g_Fahrenheit) {
  655. Fahrenheit = K_TO_F(g_TZonePtr[RetVal].ThermalInfo.CurrentTemperature);
  656. sprintf (text,
  657. "Current: %d.%dF",
  658. Fahrenheit / 10,
  659. Fahrenheit % 10);
  660. } else {
  661. sprintf (text,
  662. "Current: %d.%dK",
  663. g_TZonePtr[RetVal].ThermalInfo.CurrentTemperature / 10,
  664. g_TZonePtr[RetVal].ThermalInfo.CurrentTemperature % 10);
  665. }
  666. SetDlgItemText (wnd,
  667. IDC_CURTEMP,
  668. text);
  669. SendDlgItemMessage (wnd,
  670. IDC_TZTEMP1,
  671. PBM_SETRANGE,
  672. 0,
  673. MAKELPARAM(2760, g_TZonePtr[RetVal].ThermalInfo.CriticalTripPoint));
  674. SendDlgItemMessage (wnd,
  675. IDC_TZTEMP1,
  676. PBM_SETPOS,
  677. (INT) g_TZonePtr[RetVal].ThermalInfo.CurrentTemperature,
  678. 0);
  679. return;
  680. }
  681. VOID
  682. UpdateCPUGauge(
  683. IN HWND hwnd
  684. )
  685. /*++
  686. Routine Description:
  687. Updates the current CPU throttling gauge
  688. Arguments:
  689. hwnd - Supplies the parent dialog hwnd
  690. Return Value:
  691. None
  692. --*/
  693. {
  694. PROCESSOR_POWER_INFORMATION ProcInfo;
  695. NTSTATUS Status;
  696. UCHAR text[40];
  697. Status = NtPowerInformation(ProcessorInformation,
  698. NULL,
  699. 0,
  700. &ProcInfo,
  701. sizeof(ProcInfo));
  702. if (NT_SUCCESS(Status)) {
  703. sprintf(text, "%d MHz", ProcInfo.MaxMhz);
  704. SetDlgItemText(hwnd, IDC_MAXTHROTTLE, text);
  705. sprintf(text,
  706. "Current %d MHz (%d %%)",
  707. ProcInfo.CurrentMhz,
  708. ProcInfo.CurrentMhz*100/ProcInfo.MaxMhz);
  709. SetDlgItemText(hwnd, IDC_CURTHROTTLE, text);
  710. //
  711. // update throttle gauge
  712. //
  713. SendDlgItemMessage (hwnd,
  714. IDC_THROTTLE,
  715. PBM_SETRANGE,
  716. 0,
  717. MAKELPARAM(0, ProcInfo.MaxMhz));
  718. SendDlgItemMessage (hwnd,
  719. IDC_THROTTLE,
  720. PBM_SETPOS,
  721. (INT) ProcInfo.CurrentMhz,
  722. 0);
  723. //
  724. // update idle information
  725. //
  726. sprintf(text, "C%d", ProcInfo.MaxIdleState);
  727. SetDlgItemText(hwnd, IDC_MAXIDLE, text);
  728. //
  729. // BUGBUG John Vert (jvert) 9/16/1999
  730. // the current idle state reporting ranges from 0-2
  731. // the max idle state reporting ranges from 1-3
  732. // probably current is wrong and should be 0-3 representing C0-C3
  733. // for now add one and don't run this on an MP machine!
  734. //
  735. sprintf(text, "C%d", ProcInfo.CurrentIdleState + 1);
  736. SetDlgItemText(hwnd, IDC_CURIDLE, text);
  737. }
  738. }
  739. VOID
  740. UpdateCoolingMode ( IN HWND hwnd )
  741. {
  742. SYSTEM_POWER_INFORMATION SystemInformation;
  743. UCHAR uCoolingMode;
  744. UCHAR text[50];
  745. NTSTATUS Status;
  746. Status = NtPowerInformation(SystemPowerInformation,
  747. NULL,
  748. 0,
  749. &SystemInformation,
  750. sizeof(SystemInformation));
  751. uCoolingMode = SystemInformation.CoolingMode;
  752. // 0 = Active Mode
  753. // 1 = Passive Mode
  754. switch (uCoolingMode)
  755. {
  756. case 0:
  757. SetDlgItemText(hwnd, IDC_COOLINGMODE, "Active");
  758. break;
  759. case 1:
  760. SetDlgItemText(hwnd, IDC_COOLINGMODE, "Passive");
  761. break;
  762. default:
  763. SetDlgItemText(hwnd, IDC_COOLINGMODE, "Error!");
  764. }
  765. }