Leaked source code of windows server 2003
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.

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