2006-06-15 04:19:30 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <tlhelp32.h>
|
2007-02-20 21:16:34 +00:00
|
|
|
#include <boost/lexical_cast.hpp>
|
2008-04-05 03:38:53 +00:00
|
|
|
#include "Types.h"
|
2007-02-20 21:16:34 +00:00
|
|
|
#include "string_cast.h"
|
2006-06-15 04:19:30 +00:00
|
|
|
#include "SysInfoWnd.h"
|
|
|
|
#include "PtrMacro.h"
|
|
|
|
#include "win32/LayoutWindow.h"
|
2006-06-19 05:43:51 +00:00
|
|
|
#ifdef AMD64
|
2006-07-18 12:08:40 +00:00
|
|
|
#include "../amd64/CPUID.h"
|
2006-06-19 05:43:51 +00:00
|
|
|
#endif
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2007-02-20 21:16:34 +00:00
|
|
|
#define CLSNAME _T("SysInfoWnd")
|
2006-06-15 04:19:30 +00:00
|
|
|
#define WNDSTYLE (WS_CAPTION | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU)
|
|
|
|
#define WNDSTYLEEX (WS_EX_DLGMODALFRAME)
|
|
|
|
#define CPUFREQDELAY (250)
|
|
|
|
|
|
|
|
using namespace Framework;
|
2007-02-20 21:16:34 +00:00
|
|
|
using namespace boost;
|
|
|
|
using namespace std;
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2007-02-20 21:16:34 +00:00
|
|
|
const TCHAR* CSysInfoWnd::m_sFeature[32] =
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
2007-02-20 21:16:34 +00:00
|
|
|
_T("FPU"),
|
|
|
|
_T("VME"),
|
|
|
|
_T("DE"),
|
|
|
|
_T("PSE"),
|
|
|
|
_T("TSC"),
|
|
|
|
_T("MSR"),
|
|
|
|
_T("PAE"),
|
|
|
|
_T("MCE"),
|
|
|
|
_T("CX8"),
|
|
|
|
_T("APIC"),
|
|
|
|
_T("*RESERVED*"),
|
|
|
|
_T("SEP"),
|
|
|
|
_T("MTRR"),
|
|
|
|
_T("PGE"),
|
|
|
|
_T("MCA"),
|
|
|
|
_T("CMOV"),
|
|
|
|
_T("PAT"),
|
|
|
|
_T("PSE36"),
|
|
|
|
_T("PSN"),
|
|
|
|
_T("CLFL"),
|
|
|
|
_T("*RESERVED*"),
|
|
|
|
_T("DTES"),
|
|
|
|
_T("ACPI"),
|
|
|
|
_T("MMX"),
|
|
|
|
_T("FXSR"),
|
|
|
|
_T("SSE"),
|
|
|
|
_T("SSE2"),
|
|
|
|
_T("SS"),
|
|
|
|
_T("HTT"),
|
|
|
|
_T("TM"),
|
|
|
|
_T("IA-64"),
|
|
|
|
_T("PBE")
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
2008-10-09 01:59:56 +00:00
|
|
|
CSysInfoWnd::CSysInfoWnd(HWND hParent) :
|
|
|
|
Win32::CModalWindow(hParent)
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
|
|
|
RECT rc;
|
|
|
|
|
|
|
|
if(!DoesWindowClassExist(CLSNAME))
|
|
|
|
{
|
|
|
|
WNDCLASSEX w;
|
|
|
|
memset(&w, 0, sizeof(WNDCLASSEX));
|
|
|
|
w.cbSize = sizeof(WNDCLASSEX);
|
|
|
|
w.lpfnWndProc = CWindow::WndProc;
|
|
|
|
w.lpszClassName = CLSNAME;
|
|
|
|
w.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
|
|
|
|
w.hInstance = GetModuleHandle(NULL);
|
|
|
|
w.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
RegisterClassEx(&w);
|
|
|
|
}
|
|
|
|
|
|
|
|
SetRect(&rc, 0, 0, 200, 270);
|
|
|
|
|
|
|
|
if(hParent != NULL)
|
|
|
|
{
|
|
|
|
EnableWindow(hParent, FALSE);
|
|
|
|
}
|
|
|
|
|
2007-02-20 21:16:34 +00:00
|
|
|
Create(WNDSTYLEEX, CLSNAME, _T("System Information"), WNDSTYLE, &rc, hParent, NULL);
|
2006-06-15 04:19:30 +00:00
|
|
|
SetClassPtr();
|
|
|
|
|
|
|
|
SetRect(&rc, 0, 0, 1, 1);
|
|
|
|
|
2007-02-20 21:16:34 +00:00
|
|
|
m_pProcessor = new Win32::CStatic(m_hWnd, _T(""));
|
|
|
|
m_pProcesses = new Win32::CStatic(m_hWnd, _T(""));
|
|
|
|
m_pThreads = new Win32::CStatic(m_hWnd, _T(""));
|
2007-03-03 19:24:42 +00:00
|
|
|
m_pFeatures = new Win32::CListBox(m_hWnd, &rc, WS_VSCROLL | LBS_SORT);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-12 16:02:19 +00:00
|
|
|
m_pLayout = CVerticalLayout::Create();
|
2007-03-03 19:24:42 +00:00
|
|
|
m_pLayout->InsertObject(Win32::CLayoutWindow::CreateTextBoxBehavior(100, 20, m_pProcesses));
|
|
|
|
m_pLayout->InsertObject(Win32::CLayoutWindow::CreateTextBoxBehavior(100, 20, m_pThreads));
|
|
|
|
m_pLayout->InsertObject(Win32::CLayoutWindow::CreateTextBoxBehavior(100, 20, new Win32::CStatic(m_hWnd, _T("Processor:"))));
|
|
|
|
m_pLayout->InsertObject(Win32::CLayoutWindow::CreateTextBoxBehavior(100, 20, m_pProcessor));
|
|
|
|
m_pLayout->InsertObject(Win32::CLayoutWindow::CreateTextBoxBehavior(100, 20, new Win32::CStatic(m_hWnd, _T("Processor Features:"))));
|
2008-04-12 16:02:19 +00:00
|
|
|
m_pLayout->InsertObject(Win32::CLayoutWindow::CreateCustomBehavior(200, 200, 1, 1, m_pFeatures));
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
m_nRDTSCThread = NULL;
|
|
|
|
|
|
|
|
UpdateSchedulerInfo();
|
|
|
|
UpdateProcessorFeatures();
|
|
|
|
UpdateProcessor();
|
|
|
|
|
|
|
|
SetTimer(m_hWnd, 0, 2000, NULL);
|
|
|
|
|
|
|
|
RefreshLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
CSysInfoWnd::~CSysInfoWnd()
|
|
|
|
{
|
|
|
|
WaitForSingleObject(m_nRDTSCThread, INFINITE);
|
|
|
|
}
|
|
|
|
|
|
|
|
long CSysInfoWnd::OnTimer()
|
|
|
|
{
|
|
|
|
UpdateSchedulerInfo();
|
|
|
|
//UpdateProcessor();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSysInfoWnd::UpdateSchedulerInfo()
|
|
|
|
{
|
|
|
|
int nThreads, nProcesses;
|
|
|
|
HANDLE hSnapshot;
|
|
|
|
THREADENTRY32 ti;
|
|
|
|
PROCESSENTRY32 pi;
|
|
|
|
|
|
|
|
nThreads = 0;
|
|
|
|
nProcesses = 0;
|
|
|
|
|
|
|
|
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
|
|
|
|
|
|
|
|
pi.dwSize = sizeof(PROCESSENTRY32);
|
|
|
|
if(Process32First(hSnapshot, &pi))
|
|
|
|
{
|
|
|
|
nProcesses++;
|
|
|
|
while(Process32Next(hSnapshot, &pi))
|
|
|
|
{
|
|
|
|
nProcesses++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ti.dwSize = sizeof(THREADENTRY32);
|
|
|
|
if(Thread32First(hSnapshot, &ti))
|
|
|
|
{
|
|
|
|
nThreads++;
|
|
|
|
while(Thread32Next(hSnapshot, &ti))
|
|
|
|
{
|
|
|
|
nThreads++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-20 21:16:34 +00:00
|
|
|
m_pProcesses->SetText((lexical_cast<tstring>(nProcesses) + _T(" processes running.")).c_str());
|
|
|
|
m_pThreads->SetText((lexical_cast<tstring>(nThreads) + _T(" threads running.")).c_str());
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSysInfoWnd::UpdateProcessorFeatures()
|
|
|
|
{
|
|
|
|
uint32 nFeatures;
|
|
|
|
int i;
|
|
|
|
|
2006-06-19 05:43:51 +00:00
|
|
|
#ifdef AMD64
|
|
|
|
|
|
|
|
nFeatures = _cpuid_GetCpuFeatures();
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov eax, 0x00000001;
|
|
|
|
cpuid;
|
|
|
|
mov dword ptr[nFeatures], edx
|
|
|
|
}
|
|
|
|
|
2006-06-19 05:43:51 +00:00
|
|
|
#endif
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
m_pFeatures->ResetContent();
|
|
|
|
|
|
|
|
for(i = 0; i < 32; i++)
|
|
|
|
{
|
|
|
|
//Reserved features
|
|
|
|
if(i == 10) continue;
|
|
|
|
if(i == 20) continue;
|
|
|
|
|
|
|
|
if((nFeatures & (1 << i)) != 0)
|
|
|
|
{
|
|
|
|
m_pFeatures->AddString(m_sFeature[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSysInfoWnd::UpdateProcessor()
|
|
|
|
{
|
|
|
|
unsigned long nTID;
|
|
|
|
if(WaitForSingleObject(m_nRDTSCThread, 0) == WAIT_TIMEOUT)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_nRDTSCThread = CreateThread(NULL, NULL, ThreadRDTSC, this, NULL, &nTID);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long WINAPI CSysInfoWnd::ThreadRDTSC(void* pParam)
|
|
|
|
{
|
|
|
|
CSysInfoWnd* pWnd;
|
|
|
|
HANDLE hThread;
|
|
|
|
LARGE_INTEGER nTime;
|
|
|
|
uint64 nStamp1, nStamp2, nDeltaStamp, nDeltaTime, nDone;
|
|
|
|
char sCpu[13];
|
2007-02-20 21:16:34 +00:00
|
|
|
TCHAR sTemp[256];
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
hThread = GetCurrentThread();
|
|
|
|
SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
|
|
|
|
|
|
|
|
QueryPerformanceFrequency(&nTime);
|
|
|
|
nDeltaTime = (nTime.QuadPart * CPUFREQDELAY) / 1000;
|
|
|
|
|
2006-06-19 05:43:51 +00:00
|
|
|
#ifdef AMD64
|
|
|
|
|
|
|
|
nStamp1 = 0;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
__asm
|
|
|
|
{
|
|
|
|
rdtsc;
|
|
|
|
mov dword ptr[nStamp1 + 0x00], eax;
|
|
|
|
mov dword ptr[nStamp1 + 0x04], edx;
|
|
|
|
}
|
|
|
|
|
2006-06-19 05:43:51 +00:00
|
|
|
#endif
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
QueryPerformanceCounter(&nTime);
|
|
|
|
nDone = nTime.QuadPart + nDeltaTime;
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
QueryPerformanceCounter(&nTime);
|
|
|
|
if((uint64)nTime.QuadPart >= nDone) break;
|
|
|
|
}
|
|
|
|
|
2006-06-19 05:43:51 +00:00
|
|
|
#ifdef AMD64
|
|
|
|
|
|
|
|
nStamp2 = 0;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
__asm
|
|
|
|
{
|
|
|
|
rdtsc;
|
|
|
|
mov dword ptr[nStamp2 + 0x00], eax;
|
|
|
|
mov dword ptr[nStamp2 + 0x04], edx;
|
|
|
|
}
|
|
|
|
|
2006-06-19 05:43:51 +00:00
|
|
|
#endif
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
nDeltaStamp = 1000 * (nStamp2 - nStamp1) / CPUFREQDELAY;
|
|
|
|
|
|
|
|
SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL);
|
|
|
|
|
2006-06-19 05:43:51 +00:00
|
|
|
#ifdef AMD64
|
|
|
|
|
|
|
|
_cpuid_GetCpuIdString(sCpu);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov eax, 0x00000000;
|
|
|
|
cpuid;
|
|
|
|
mov dword ptr[sCpu + 0], ebx;
|
|
|
|
mov dword ptr[sCpu + 4], edx;
|
|
|
|
mov dword ptr[sCpu + 8], ecx;
|
|
|
|
}
|
2006-06-19 05:43:51 +00:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
sCpu[12] = '\0';
|
2006-06-19 05:43:51 +00:00
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
pWnd = (CSysInfoWnd*)pParam;
|
|
|
|
|
2007-02-20 21:16:34 +00:00
|
|
|
_sntprintf(sTemp, countof(sTemp), _T("%s @ ~%i MHz"), string_cast<tstring>(sCpu).c_str(), nDeltaStamp / 1000000);
|
2006-06-15 04:19:30 +00:00
|
|
|
pWnd->m_pProcessor->SetText(sTemp);
|
|
|
|
|
|
|
|
return 0xDEADBEEF;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSysInfoWnd::RefreshLayout()
|
|
|
|
{
|
|
|
|
RECT rc;
|
|
|
|
|
|
|
|
GetClientRect(&rc);
|
|
|
|
|
|
|
|
SetRect(&rc, rc.left + 10, rc.top + 10, rc.right - 10, rc.bottom - 10);
|
|
|
|
|
|
|
|
m_pLayout->SetRect(rc.left, rc.top, rc.right, rc.bottom);
|
|
|
|
m_pLayout->RefreshGeometry();
|
|
|
|
|
|
|
|
Redraw();
|
|
|
|
}
|