992 lines
22 KiB
C
992 lines
22 KiB
C
/*
|
||
TZTool - Thermal Zone Information Tool
|
||
tztool.c
|
||
This the MAIN TZTool - C file.
|
||
|
||
Copyright (c) 1999 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
TZTool - TZTool.c
|
||
|
||
Abstract:
|
||
|
||
TZTool - Thermal Zone Information Tool
|
||
|
||
Author:
|
||
|
||
Vincent Geglia (VincentG)
|
||
|
||
Notes:
|
||
|
||
Revision History:
|
||
|
||
1.0 - Original version
|
||
|
||
|
||
*/
|
||
|
||
// Includes
|
||
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
#include <windows.h>
|
||
#include <ole2.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <ntpoapi.h>
|
||
#include <commctrl.h>
|
||
#include "resource.h"
|
||
#include "wmium.h"
|
||
|
||
// Definitions
|
||
|
||
#define THERMAL_ZONE_GUID {0xa1bc18c0, 0xa7c8, 0x11d1, {0xbf, 0x3c, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10} }
|
||
#define COOLING_PASSIVE 0
|
||
#define COOLING_ACTIVE 1
|
||
#define COOLING_UPDATE_TZONE 2
|
||
#define TIMER_ID 1
|
||
#define TIMER_POLL_INTERVAL 500
|
||
#define MAX_ACTIVE_COOLING_LEVELS 10
|
||
#define MAX_THERMAL_ZONES 10
|
||
|
||
#define K_TO_F(_deg_) (((_deg_) - 2731) * 9 / 5 + 320)
|
||
|
||
GUID ThermalZoneGuid = THERMAL_ZONE_GUID;
|
||
|
||
// Structures
|
||
|
||
typedef struct _THERMAL_INFORMATION {
|
||
ULONG ThermalStamp;
|
||
ULONG ThermalConstant1;
|
||
ULONG ThermalConstant2;
|
||
KAFFINITY Processors;
|
||
ULONG SamplingPeriod;
|
||
ULONG CurrentTemperature;
|
||
ULONG PassiveTripPoint;
|
||
ULONG CriticalTripPoint;
|
||
UCHAR ActiveTripPointCount;
|
||
ULONG ActiveTripPoint[MAX_ACTIVE_COOLING_LEVELS];
|
||
} THERMAL_INFORMATION, *PTHERMAL_INFORMATION;
|
||
|
||
typedef struct _TZONE_INFO {
|
||
|
||
THERMAL_INFORMATION ThermalInfo;
|
||
ULONG64 TimeStamp;
|
||
ULONG TZoneIndex;
|
||
UCHAR TZoneName[100];
|
||
} TZONE_INFO, *PTZONE_INFO;
|
||
|
||
// Global variables
|
||
|
||
PTZONE_INFO g_TZonePtr = 0;
|
||
WMIHANDLE g_WmiHandle;
|
||
INT g_PollTz = 0;
|
||
BOOL g_Fahrenheit = FALSE;
|
||
|
||
// Function declarations
|
||
|
||
INT WINAPI
|
||
WinMain (
|
||
IN HINSTANCE hInstance,
|
||
IN HINSTANCE hPrevInstance,
|
||
IN PSTR CmdLine,
|
||
IN INT CmdShow
|
||
);
|
||
|
||
INT_PTR CALLBACK
|
||
TZoneDlgProc (
|
||
IN HWND wnd,
|
||
IN UINT Msg,
|
||
IN WPARAM wParam,
|
||
IN LPARAM lParam
|
||
);
|
||
|
||
ULONG
|
||
UpdateTZoneData (
|
||
IN OUT PTZONE_INFO ReturnedTZoneInfo,
|
||
IN WMIHANDLE *Handle
|
||
);
|
||
|
||
ULONG64
|
||
SystemTimeToUlong (
|
||
IN LPSYSTEMTIME SysTime
|
||
);
|
||
|
||
VOID
|
||
SetCoolingMode (
|
||
IN UCHAR Mode
|
||
);
|
||
|
||
VOID
|
||
UpgradePrivileges (
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
UpdateTZoneListBox (
|
||
IN HANDLE wnd
|
||
);
|
||
|
||
VOID
|
||
UpdateTZoneDetails (
|
||
IN HANDLE wnd
|
||
);
|
||
|
||
VOID
|
||
UpdateTZoneGauge (
|
||
IN HANDLE wnd
|
||
);
|
||
|
||
VOID
|
||
UpdateCPUGauge(
|
||
IN HWND hwnd
|
||
);
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Windows application Entry Point
|
||
|
||
Arguments:
|
||
|
||
<standard winmain arguments>
|
||
|
||
Return Value:
|
||
|
||
0 if successful, otherwise error status
|
||
|
||
--*/
|
||
|
||
INT WINAPI
|
||
WinMain (
|
||
IN HINSTANCE hInstance,
|
||
IN HINSTANCE hPrevInstance,
|
||
IN PSTR CmdLine,
|
||
IN INT CmdShow
|
||
)
|
||
|
||
{
|
||
|
||
UCHAR text [200];
|
||
INITCOMMONCONTROLSEX CommonCtl;
|
||
TZONE_INFO TZones [MAX_THERMAL_ZONES];
|
||
ULONG status = 0;
|
||
|
||
|
||
// Initialize TZ structures
|
||
|
||
ZeroMemory (&TZones, sizeof (TZones));
|
||
g_TZonePtr = (PTZONE_INFO) &TZones;
|
||
|
||
// Initialize Common Controls DLL for gauge control
|
||
|
||
CommonCtl.dwSize = sizeof (CommonCtl);
|
||
CommonCtl.dwICC = ICC_PROGRESS_CLASS;
|
||
|
||
InitCommonControlsEx (&CommonCtl);
|
||
|
||
// Open WMI data source for the TZs
|
||
|
||
status = WmiOpenBlock ((LPGUID) &ThermalZoneGuid,
|
||
GENERIC_READ,
|
||
&g_WmiHandle);
|
||
|
||
if (status != ERROR_SUCCESS) {
|
||
|
||
sprintf (text,
|
||
"Unable to open thermal zone GUIDs. This computer may not be equipped with thermal zones, or may not be in ACPI mode.\nError: %d",
|
||
status);
|
||
|
||
MessageBox (NULL,
|
||
text,
|
||
"Fatal Error",
|
||
MB_ICONERROR | MB_OK);
|
||
|
||
return status;
|
||
}
|
||
|
||
// In order to change the policies, we need greater access privileges
|
||
|
||
UpgradePrivileges ();
|
||
|
||
// Show the main dialog box
|
||
|
||
DialogBox (hInstance,
|
||
MAKEINTRESOURCE (IDD_TZDLG),
|
||
NULL,
|
||
TZoneDlgProc);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Standard Windows Dialog Message Loop
|
||
|
||
Arguments:
|
||
|
||
<standard dialog message loop arguments>
|
||
|
||
Return Value:
|
||
|
||
FALSE if message not handled, TRUE if message handled
|
||
|
||
--*/
|
||
|
||
INT_PTR CALLBACK
|
||
TZoneDlgProc (
|
||
IN HWND wnd,
|
||
IN UINT Msg,
|
||
IN WPARAM wParam,
|
||
IN LPARAM lParam
|
||
)
|
||
{
|
||
ULONG Count = 0;
|
||
LRESULT RetVal = 0;
|
||
switch (Msg) {
|
||
|
||
case WM_TIMER:
|
||
|
||
if (g_PollTz) {
|
||
SetCoolingMode (COOLING_UPDATE_TZONE);
|
||
}
|
||
|
||
if (UpdateTZoneData (g_TZonePtr, g_WmiHandle)) {
|
||
UpdateTZoneDetails (wnd);
|
||
UpdateTZoneGauge (wnd);
|
||
}
|
||
UpdateCPUGauge(wnd);
|
||
return TRUE;
|
||
|
||
case WM_INITDIALOG:
|
||
|
||
// Fill TZ structure with initial values
|
||
|
||
UpdateTZoneData (g_TZonePtr, g_WmiHandle);
|
||
|
||
// Initialize all controls
|
||
|
||
UpdateTZoneListBox (wnd);
|
||
UpdateTZoneDetails (wnd);
|
||
UpdateTZoneGauge (wnd);
|
||
UpdateCPUGauge(wnd);
|
||
|
||
// Initialize polling timer
|
||
|
||
SetTimer (wnd,
|
||
TIMER_ID,
|
||
TIMER_POLL_INTERVAL,
|
||
NULL);
|
||
|
||
// Set gauge colors
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_TZTEMP1,
|
||
PBM_SETBARCOLOR,
|
||
0,
|
||
(LPARAM) (COLORREF) (0x0000FF));
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_TZTEMP1,
|
||
PBM_SETBKCOLOR,
|
||
0,
|
||
(LPARAM) (COLORREF) (0x000000));
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_THROTTLE,
|
||
PBM_SETBARCOLOR,
|
||
0,
|
||
(LPARAM) (COLORREF) (0x0000FF));
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_THROTTLE,
|
||
PBM_SETBKCOLOR,
|
||
0,
|
||
(LPARAM) (COLORREF) (0x000000));
|
||
|
||
|
||
return TRUE;
|
||
|
||
case WM_COMMAND:
|
||
switch (LOWORD (wParam)) {
|
||
|
||
|
||
// Cleanup and exit
|
||
|
||
case IDOK:
|
||
KillTimer (wnd, TIMER_ID);
|
||
EndDialog (wnd, 0);
|
||
return TRUE;
|
||
|
||
// Check to see if user selected a new TZ
|
||
|
||
case IDC_TZSELECT:
|
||
if (HIWORD (wParam) == CBN_SELCHANGE) {
|
||
UpdateTZoneDetails (wnd);
|
||
UpdateTZoneGauge (wnd);
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_POLLTZ:
|
||
|
||
// Check to see if user changed the TZ Polling setting
|
||
|
||
if (HIWORD (wParam) == BN_CLICKED) {
|
||
|
||
RetVal = SendDlgItemMessage (wnd,
|
||
IDC_POLLTZ,
|
||
BM_GETCHECK,
|
||
(WPARAM)0,
|
||
(LPARAM)0);
|
||
|
||
if (!g_PollTz && RetVal == BST_CHECKED) {
|
||
g_PollTz = TRUE;
|
||
}
|
||
|
||
if (g_PollTz && RetVal == BST_UNCHECKED) {
|
||
g_PollTz = FALSE;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case IDC_FAHR:
|
||
|
||
// Check to see if user changed the Fahrenheit setting
|
||
|
||
if (HIWORD(wParam) == BN_CLICKED) {
|
||
RetVal = SendDlgItemMessage(wnd,
|
||
IDC_FAHR,
|
||
BM_GETCHECK,
|
||
0,
|
||
0);
|
||
if (!g_Fahrenheit && RetVal == BST_CHECKED) {
|
||
g_Fahrenheit = TRUE;
|
||
SetDlgItemText(wnd, IDC_MINTEMP, "37F");
|
||
UpdateTZoneDetails(wnd);
|
||
UpdateTZoneGauge(wnd);
|
||
} else if (g_Fahrenheit && RetVal == BST_UNCHECKED) {
|
||
g_Fahrenheit = FALSE;
|
||
SetDlgItemText(wnd, IDC_MINTEMP, "276K");
|
||
UpdateTZoneDetails(wnd);
|
||
UpdateTZoneGauge(wnd);
|
||
}
|
||
}
|
||
|
||
|
||
default:
|
||
break;
|
||
|
||
}
|
||
|
||
default:
|
||
break;
|
||
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Issue WMI call to update TZ structures
|
||
|
||
Arguments:
|
||
|
||
ReturnedTZoneInfo - Pointer to array of TZ structures
|
||
Handle - Handle to WMI
|
||
|
||
Return Value:
|
||
|
||
FALSE if no TZs were updated, TRUE if one or more TZs have an update
|
||
|
||
--*/
|
||
|
||
ULONG
|
||
UpdateTZoneData (
|
||
IN OUT PTZONE_INFO ReturnedTZoneInfo,
|
||
IN WMIHANDLE *Handle
|
||
)
|
||
{
|
||
ULONG status = 0;
|
||
ULONG BufferSize = 0;
|
||
PWNODE_ALL_DATA WmiAllData;
|
||
PTHERMAL_INFORMATION ThermalInfo;
|
||
ULONG Offset = 0;
|
||
UCHAR *AllDataBuffer = 0;
|
||
UCHAR *InstanceName = 0;
|
||
ULONG TZCount = 0;
|
||
ULONG Temp = 0;
|
||
SYSTEMTIME SysTime;
|
||
BOOL Updated = FALSE;
|
||
|
||
status = WmiQueryAllData (Handle,
|
||
&BufferSize,
|
||
0);
|
||
|
||
if (status != ERROR_INSUFFICIENT_BUFFER) {
|
||
return FALSE;
|
||
}
|
||
|
||
AllDataBuffer = malloc (BufferSize);
|
||
|
||
if (!AllDataBuffer) {
|
||
|
||
return FALSE;
|
||
|
||
}
|
||
|
||
status = WmiQueryAllData (Handle,
|
||
&BufferSize,
|
||
AllDataBuffer);
|
||
|
||
if (status != ERROR_SUCCESS) {
|
||
free (AllDataBuffer);
|
||
return FALSE;
|
||
}
|
||
|
||
// BUG BUG Assuming Thermal GUID only has one instance
|
||
|
||
while (TZCount < MAX_THERMAL_ZONES) {
|
||
|
||
WmiAllData = (PWNODE_ALL_DATA) AllDataBuffer;
|
||
|
||
if (WmiAllData->WnodeHeader.Flags & WNODE_FLAG_FIXED_INSTANCE_SIZE) {
|
||
|
||
ThermalInfo = (PTHERMAL_INFORMATION) &AllDataBuffer[WmiAllData->DataBlockOffset];
|
||
} else {
|
||
|
||
ThermalInfo = (PTHERMAL_INFORMATION) &AllDataBuffer[WmiAllData->OffsetInstanceDataAndLength[0].OffsetInstanceData];
|
||
}
|
||
|
||
Offset = (ULONG) AllDataBuffer[WmiAllData->OffsetInstanceNameOffsets];
|
||
|
||
InstanceName = (UCHAR *) &AllDataBuffer[Offset + 2];
|
||
|
||
// Update TZone structure if timestamp has changed
|
||
|
||
if (!ReturnedTZoneInfo[TZCount].TZoneIndex || (ThermalInfo->ThermalStamp != ReturnedTZoneInfo[TZCount].ThermalInfo.ThermalStamp)) {
|
||
|
||
strcpy (ReturnedTZoneInfo[TZCount].TZoneName, InstanceName);
|
||
GetSystemTime (&SysTime);
|
||
ReturnedTZoneInfo[TZCount].TimeStamp = SystemTimeToUlong (&SysTime);
|
||
ReturnedTZoneInfo[TZCount].TZoneIndex = TZCount + 1;
|
||
memcpy (&ReturnedTZoneInfo[TZCount].ThermalInfo,
|
||
ThermalInfo,
|
||
sizeof (THERMAL_INFORMATION));
|
||
Updated = TRUE;
|
||
}
|
||
|
||
if (!WmiAllData->WnodeHeader.Linkage) {
|
||
|
||
break;
|
||
}
|
||
|
||
AllDataBuffer += WmiAllData->WnodeHeader.Linkage;
|
||
|
||
TZCount ++;
|
||
}
|
||
|
||
free (AllDataBuffer);
|
||
|
||
return Updated;
|
||
}
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert a system time structure to a 64bit ULONG
|
||
|
||
Arguments:
|
||
|
||
SysTime - Pointer to system time structure to compare against current time
|
||
|
||
Return Value:
|
||
|
||
Number of elapsed seconds between SysTime and current time
|
||
|
||
--*/
|
||
|
||
ULONG64
|
||
SystemTimeToUlong (
|
||
IN LPSYSTEMTIME SysTime
|
||
)
|
||
|
||
{
|
||
ULONG64 TimeCount = 0;
|
||
|
||
// BUG BUG Doesn't account for leap year
|
||
|
||
TimeCount += SysTime->wYear * 31536000;
|
||
TimeCount += SysTime->wMonth * 2628000;
|
||
TimeCount += SysTime->wDay * 86400;
|
||
TimeCount += SysTime->wHour * 3600;
|
||
TimeCount += SysTime->wMinute * 60;
|
||
TimeCount += SysTime->wSecond;
|
||
|
||
return TimeCount;
|
||
}
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Sets the cooling mode to ACTIVE, PASSIVE, or UPDATE ONLY. This is accomplished by
|
||
changing the FanThrottleTolerance value in the power policy. Setting it to maxthrottle
|
||
effectively puts the system into PASSIVE cooling mode. Setting it to 100% will put
|
||
the system in ACTIVE cooling mode UNLESS the current temperature exceeds the passive
|
||
cooling trip points.
|
||
|
||
Arguments:
|
||
|
||
Mode - Value to select the new cooling mode
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
VOID
|
||
SetCoolingMode (
|
||
IN UCHAR Mode
|
||
)
|
||
|
||
{
|
||
SYSTEM_POWER_POLICY SysPolicy;
|
||
ULONG Status = 0;
|
||
UCHAR TempFanThrottleTolerance = 0;
|
||
|
||
// BUG BUG - This mechanism will currently only for while the machine is on AC.
|
||
|
||
Status = NtPowerInformation(
|
||
SystemPowerPolicyAc,
|
||
0,
|
||
0,
|
||
&SysPolicy,
|
||
sizeof (SysPolicy)
|
||
);
|
||
|
||
if (Status != ERROR_SUCCESS) {
|
||
|
||
return;
|
||
}
|
||
|
||
switch (Mode) {
|
||
|
||
case COOLING_PASSIVE:
|
||
SysPolicy.FanThrottleTolerance = SysPolicy.MinThrottle;
|
||
break;
|
||
|
||
case COOLING_ACTIVE:
|
||
SysPolicy.FanThrottleTolerance = 100;
|
||
break;
|
||
|
||
case COOLING_UPDATE_TZONE:
|
||
TempFanThrottleTolerance = SysPolicy.FanThrottleTolerance;
|
||
SysPolicy.FanThrottleTolerance = SysPolicy.FanThrottleTolerance != SysPolicy.MinThrottle ? SysPolicy.MinThrottle : 100;
|
||
break;
|
||
|
||
default:
|
||
return;
|
||
}
|
||
|
||
Status = NtPowerInformation(
|
||
SystemPowerPolicyAc,
|
||
&SysPolicy,
|
||
sizeof (SysPolicy),
|
||
&SysPolicy,
|
||
sizeof (SysPolicy)
|
||
);
|
||
|
||
if (Status != ERROR_SUCCESS) {
|
||
|
||
return;
|
||
}
|
||
|
||
if (Mode == COOLING_UPDATE_TZONE) {
|
||
|
||
SysPolicy.FanThrottleTolerance = TempFanThrottleTolerance;
|
||
|
||
Status = NtPowerInformation(
|
||
SystemPowerPolicyAc,
|
||
&SysPolicy,
|
||
sizeof (SysPolicy),
|
||
&SysPolicy,
|
||
sizeof (SysPolicy)
|
||
);
|
||
|
||
if (Status != ERROR_SUCCESS) {
|
||
|
||
return;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Upgrades the process's access permission to change system power policy
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
|
||
VOID
|
||
UpgradePrivileges (
|
||
VOID
|
||
)
|
||
{
|
||
TOKEN_PRIVILEGES tkp;
|
||
HANDLE hToken;
|
||
|
||
OpenProcessToken (GetCurrentProcess(),
|
||
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
||
&hToken);
|
||
|
||
LookupPrivilegeValue (NULL,
|
||
SE_SHUTDOWN_NAME,
|
||
&tkp.Privileges[0].Luid);
|
||
|
||
tkp.PrivilegeCount = 1;
|
||
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||
|
||
AdjustTokenPrivileges (hToken,
|
||
FALSE,
|
||
&tkp,
|
||
0,
|
||
NULL,
|
||
0);
|
||
|
||
}
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Updates the entries presented in the TZ selection combo box
|
||
|
||
Arguments:
|
||
|
||
wnd - A handle to the control's window
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
|
||
VOID
|
||
UpdateTZoneListBox (
|
||
IN HANDLE wnd
|
||
)
|
||
|
||
{
|
||
ULONG Count = 0;
|
||
|
||
// Reset the contents
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_TZSELECT,
|
||
CB_RESETCONTENT,
|
||
0,
|
||
0);
|
||
|
||
while (Count < MAX_THERMAL_ZONES) {
|
||
|
||
if (g_TZonePtr[Count].TZoneIndex) {
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_TZSELECT,
|
||
CB_ADDSTRING,
|
||
0,
|
||
(LPARAM) g_TZonePtr[Count].TZoneName);
|
||
} else {
|
||
|
||
break;
|
||
}
|
||
|
||
Count ++;
|
||
}
|
||
|
||
// Automatically select first TZone
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_TZSELECT,
|
||
CB_SETCURSEL,
|
||
0,
|
||
0);
|
||
|
||
}
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Updates the details for the currently selected TZ
|
||
|
||
Arguments:
|
||
|
||
wnd - A handle to the control's window
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
VOID
|
||
UpdateTZoneDetails (
|
||
IN HANDLE wnd
|
||
)
|
||
{
|
||
UCHAR text[1000], texttmp [1000];
|
||
UCHAR CurrentTZone = 0;
|
||
LRESULT RetVal = 0;
|
||
UCHAR Count = 0;
|
||
ULONG Fahrenheit;
|
||
|
||
RetVal = SendDlgItemMessage (wnd,
|
||
IDC_TZSELECT,
|
||
CB_GETCURSEL,
|
||
0,
|
||
0);
|
||
|
||
if (RetVal == CB_ERR) {
|
||
|
||
return;
|
||
}
|
||
|
||
if (g_Fahrenheit) {
|
||
Fahrenheit = K_TO_F(g_TZonePtr[RetVal].ThermalInfo.PassiveTripPoint);
|
||
sprintf (text,
|
||
"Passive Trip Point:\t%d.%dF\nThermal Constant 1:\t%d\nThermal Constant 2:\t%d",
|
||
Fahrenheit / 10,
|
||
Fahrenheit % 10,
|
||
g_TZonePtr[RetVal].ThermalInfo.ThermalConstant1,
|
||
g_TZonePtr[RetVal].ThermalInfo.ThermalConstant2);
|
||
|
||
} else {
|
||
sprintf (text,
|
||
"Passive Trip Point:\t%d.%dK\nThermal Constant 1:\t%d\nThermal Constant 2:\t%d",
|
||
g_TZonePtr[RetVal].ThermalInfo.PassiveTripPoint / 10,
|
||
g_TZonePtr[RetVal].ThermalInfo.PassiveTripPoint % 10,
|
||
g_TZonePtr[RetVal].ThermalInfo.ThermalConstant1,
|
||
g_TZonePtr[RetVal].ThermalInfo.ThermalConstant2);
|
||
}
|
||
|
||
SetDlgItemText (wnd,
|
||
IDC_PSVDETAILS,
|
||
text);
|
||
|
||
ZeroMemory (&text, sizeof (text));
|
||
|
||
while (Count < g_TZonePtr[RetVal].ThermalInfo.ActiveTripPointCount) {
|
||
if (g_Fahrenheit) {
|
||
Fahrenheit = K_TO_F(g_TZonePtr[RetVal].ThermalInfo.ActiveTripPoint[Count]);
|
||
sprintf (texttmp,
|
||
"Active Trip Point #%d:\t%d.%dF\n",
|
||
Count,
|
||
Fahrenheit / 10,
|
||
Fahrenheit % 10);
|
||
} else {
|
||
sprintf (texttmp,
|
||
"Active Trip Point #%d:\t%d.%dK\n",
|
||
Count,
|
||
g_TZonePtr[RetVal].ThermalInfo.ActiveTripPoint[Count] / 10,
|
||
g_TZonePtr[RetVal].ThermalInfo.ActiveTripPoint[Count] % 10);
|
||
}
|
||
|
||
strcat (text, texttmp);
|
||
Count ++;
|
||
}
|
||
|
||
SetDlgItemText (wnd,
|
||
IDC_ACXDETAILS,
|
||
text);
|
||
|
||
}
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Updates the progress bar control (temp gauge) for the currently selected TZ
|
||
|
||
Arguments:
|
||
|
||
wnd - A handle to the control's window
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
VOID
|
||
UpdateTZoneGauge (
|
||
IN HANDLE wnd
|
||
)
|
||
|
||
{
|
||
UCHAR CurrentTZone = 0;
|
||
LRESULT RetVal = 0;
|
||
UCHAR text[20];
|
||
ULONG Fahrenheit;
|
||
|
||
RetVal = SendDlgItemMessage (wnd,
|
||
IDC_TZSELECT,
|
||
CB_GETCURSEL,
|
||
0,
|
||
0);
|
||
|
||
if (RetVal == CB_ERR) {
|
||
|
||
return;
|
||
}
|
||
|
||
if (g_Fahrenheit) {
|
||
|
||
Fahrenheit = K_TO_F(g_TZonePtr[RetVal].ThermalInfo.CriticalTripPoint);
|
||
sprintf (text,
|
||
"%d.%dF",
|
||
Fahrenheit / 10,
|
||
Fahrenheit % 10);
|
||
|
||
} else {
|
||
sprintf (text,
|
||
"%d.%dK",
|
||
g_TZonePtr[RetVal].ThermalInfo.CriticalTripPoint / 10,
|
||
g_TZonePtr[RetVal].ThermalInfo.CriticalTripPoint % 10);
|
||
}
|
||
|
||
SetDlgItemText (wnd,
|
||
IDC_CRTTEMP,
|
||
text);
|
||
|
||
if (g_Fahrenheit) {
|
||
|
||
Fahrenheit = K_TO_F(g_TZonePtr[RetVal].ThermalInfo.CurrentTemperature);
|
||
sprintf (text,
|
||
"Current: %d.%dF",
|
||
Fahrenheit / 10,
|
||
Fahrenheit % 10);
|
||
|
||
} else {
|
||
sprintf (text,
|
||
"Current: %d.%dK",
|
||
g_TZonePtr[RetVal].ThermalInfo.CurrentTemperature / 10,
|
||
g_TZonePtr[RetVal].ThermalInfo.CurrentTemperature % 10);
|
||
|
||
}
|
||
SetDlgItemText (wnd,
|
||
IDC_CURTEMP,
|
||
text);
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_TZTEMP1,
|
||
PBM_SETRANGE,
|
||
0,
|
||
MAKELPARAM(2760, g_TZonePtr[RetVal].ThermalInfo.CriticalTripPoint));
|
||
|
||
SendDlgItemMessage (wnd,
|
||
IDC_TZTEMP1,
|
||
PBM_SETPOS,
|
||
(INT) g_TZonePtr[RetVal].ThermalInfo.CurrentTemperature,
|
||
0);
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
UpdateCPUGauge(
|
||
IN HWND hwnd
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Updates the current CPU throttling gauge
|
||
|
||
Arguments:
|
||
|
||
hwnd - Supplies the parent dialog hwnd
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
PROCESSOR_POWER_INFORMATION ProcInfo;
|
||
NTSTATUS Status;
|
||
UCHAR text[40];
|
||
|
||
Status = NtPowerInformation(ProcessorInformation,
|
||
NULL,
|
||
0,
|
||
&ProcInfo,
|
||
sizeof(ProcInfo));
|
||
if (NT_SUCCESS(Status)) {
|
||
sprintf(text, "%d MHz", ProcInfo.MaxMhz);
|
||
SetDlgItemText(hwnd, IDC_MAXTHROTTLE, text);
|
||
|
||
sprintf(text,
|
||
"Current %d MHz (%d %%)",
|
||
ProcInfo.CurrentMhz,
|
||
ProcInfo.CurrentMhz*100/ProcInfo.MaxMhz);
|
||
SetDlgItemText(hwnd, IDC_CURTHROTTLE, text);
|
||
|
||
//
|
||
// update throttle gauge
|
||
//
|
||
SendDlgItemMessage (hwnd,
|
||
IDC_THROTTLE,
|
||
PBM_SETRANGE,
|
||
0,
|
||
MAKELPARAM(0, ProcInfo.MaxMhz));
|
||
|
||
SendDlgItemMessage (hwnd,
|
||
IDC_THROTTLE,
|
||
PBM_SETPOS,
|
||
(INT) ProcInfo.CurrentMhz,
|
||
0);
|
||
|
||
//
|
||
// update idle information
|
||
//
|
||
sprintf(text, "C%d", ProcInfo.MaxIdleState);
|
||
SetDlgItemText(hwnd, IDC_MAXIDLE, text);
|
||
|
||
//
|
||
// The current idle state reporting ranges from 0-2
|
||
// the max idle state reporting ranges from 1-3
|
||
// probably current is wrong and should be 0-3 representing C0-C3
|
||
// for now add one and don't run this on an MP machine!
|
||
//
|
||
sprintf(text, "C%d", ProcInfo.CurrentIdleState + 1);
|
||
SetDlgItemText(hwnd, IDC_CURIDLE, text);
|
||
|
||
}
|
||
|
||
|
||
}
|