fix processor display
[reactos.git] / reactos / dll / cpl / sysdm / general.c
1 /*
2 * PROJECT: ReactOS System Control Panel Applet
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/sysdm/general.c
5 * PURPOSE: General System Information
6 * COPYRIGHT: Copyright Thomas Weidenmueller <w3seek@reactos.org>
7 * Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
8 *
9 */
10
11
12 #include "precomp.h"
13
14 typedef struct _IMGINFO
15 {
16 HBITMAP hBitmap;
17 INT cxSource;
18 INT cySource;
19 } IMGINFO, *PIMGINFO;
20
21
22 void
23 ShowLastWin32Error(HWND hWndOwner)
24 {
25 LPTSTR lpMsg;
26 DWORD LastError;
27
28 LastError = GetLastError();
29
30 if((LastError == 0) ||
31 !FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
32 FORMAT_MESSAGE_FROM_SYSTEM,
33 NULL,
34 LastError,
35 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
36 (LPTSTR)&lpMsg,
37 0,
38 NULL))
39 {
40 return;
41 }
42
43 MessageBox(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR);
44
45 LocalFree((LPVOID)lpMsg);
46 }
47
48
49 static VOID
50 InitImageInfo(PIMGINFO ImgInfo)
51 {
52 BITMAP bitmap;
53
54 ZeroMemory(ImgInfo, sizeof(*ImgInfo));
55
56 ImgInfo->hBitmap = LoadImage(hApplet,
57 MAKEINTRESOURCE(IDB_ROSBMP),
58 IMAGE_BITMAP,
59 0,
60 0,
61 LR_DEFAULTCOLOR);
62
63 if (ImgInfo->hBitmap != NULL)
64 {
65 GetObject(ImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
66
67 ImgInfo->cxSource = bitmap.bmWidth;
68 ImgInfo->cySource = bitmap.bmHeight;
69 }
70 }
71
72
73 static VOID
74 SetRegTextData(HWND hwnd,
75 HKEY hKey,
76 LPTSTR Value,
77 UINT uID)
78 {
79 LPTSTR lpBuf = NULL;
80 DWORD BufSize = 0;
81 DWORD Type;
82
83 if (RegQueryValueEx(hKey,
84 Value,
85 NULL,
86 &Type,
87 NULL,
88 &BufSize) == ERROR_SUCCESS)
89 {
90 lpBuf = HeapAlloc(GetProcessHeap(),
91 0,
92 BufSize);
93 if (!lpBuf) return;
94
95 if (RegQueryValueEx(hKey,
96 Value,
97 NULL,
98 &Type,
99 (PBYTE)lpBuf,
100 &BufSize) == ERROR_SUCCESS)
101 {
102 SetDlgItemText(hwnd,
103 uID,
104 lpBuf);
105 }
106
107 HeapFree(GetProcessHeap(),
108 0,
109 lpBuf);
110 }
111 }
112
113 static VOID
114 SetProcSpeed(HWND hwnd,
115 HKEY hKey,
116 LPTSTR Value,
117 UINT uID)
118
119 {
120 TCHAR szBuf[64];
121 DWORD dwBuf;
122 DWORD BufSize = sizeof(DWORD);
123 DWORD Type = REG_SZ;
124
125 if (RegQueryValueEx(hKey,
126 Value,
127 NULL,
128 &Type,
129 (PBYTE)&dwBuf,
130 &BufSize) == ERROR_SUCCESS)
131 {
132 if (dwBuf < 1000)
133 {
134 _stprintf(szBuf, _T("%.2f MHz"), dwBuf);
135 }
136 else
137 {
138 double flt = dwBuf / 1000.0;
139 _stprintf(szBuf, _T("%.2f GHz"), flt);
140 }
141
142 SetDlgItemText(hwnd,
143 uID,
144 szBuf);
145 }
146 }
147
148 static VOID
149 GetSystemInformation(HWND hwnd)
150 {
151 HKEY hKey;
152 TCHAR ProcKey[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
153 MEMORYSTATUSEX MemStat;
154 TCHAR Buf[32];
155 INT Ret = 0;
156
157
158 /* Get Processor information *
159 * although undocumented, this information is being pulled
160 * directly out of the registry instead of via setupapi as it
161 * contains all the info we need, and should remain static
162 */
163 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
164 ProcKey,
165 0,
166 KEY_READ,
167 &hKey) == ERROR_SUCCESS)
168 {
169 SetRegTextData(hwnd,
170 hKey,
171 _T("VendorIdentifier"),
172 IDC_PROCESSORMANUFACTURER);
173
174 SetRegTextData(hwnd,
175 hKey,
176 _T("ProcessorNameString"),
177 IDC_PROCESSOR);
178
179 SetProcSpeed(hwnd,
180 hKey,
181 _T("~MHz"),
182 IDC_PROCESSORSPEED);
183 }
184
185
186 /* Get total physical RAM */
187 MemStat.dwLength = sizeof(MemStat);
188 if (GlobalMemoryStatusEx(&MemStat))
189 {
190 TCHAR szStr[32];
191 double dTotalPhys;
192 UINT i = 0;
193 static const UINT uStrId[] = {
194 IDS_MEGABYTE,
195 IDS_GIGABYTE,
196 IDS_TERABYTE,
197 IDS_PETABYTE
198 };
199
200 if (MemStat.ullTotalPhys > 1024 * 1024 * 1024)
201 {
202 /* We're dealing with GBs or more */
203 MemStat.ullTotalPhys /= 1024 * 1024;
204 i++;
205
206 if (MemStat.ullTotalPhys > 1024 * 1024)
207 {
208 /* We're dealing with TBs or more */
209 MemStat.ullTotalPhys /= 1024;
210 i++;
211
212 if (MemStat.ullTotalPhys > 1024 * 1024)
213 {
214 /* We're dealing with PBs or more */
215
216 MemStat.ullTotalPhys /= 1024;
217 i++;
218
219 dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
220 }
221 else
222 dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
223 }
224 else
225 dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
226 }
227 else
228 {
229 /* We're daling with MBs */
230 dTotalPhys = (double)MemStat.ullTotalPhys / 1024 / 1024;
231 }
232
233 if (LoadString(hApplet, uStrId[i], szStr, sizeof(szStr) / sizeof(szStr[0])))
234 {
235 Ret = _stprintf(Buf, _T("%.2f %s"), dTotalPhys, szStr);
236 }
237 }
238
239 if (Ret)
240 {
241 SetDlgItemText(hwnd,
242 IDC_SYSTEMMEMORY,
243 Buf);
244 }
245 }
246
247
248 /* Property page dialog callback */
249 INT_PTR CALLBACK
250 GeneralPageProc(HWND hwndDlg,
251 UINT uMsg,
252 WPARAM wParam,
253 LPARAM lParam)
254 {
255 static IMGINFO ImgInfo;
256
257 UNREFERENCED_PARAMETER(lParam);
258 UNREFERENCED_PARAMETER(wParam);
259
260 switch(uMsg)
261 {
262 case WM_INITDIALOG:
263 {
264 HWND hLink = GetDlgItem(hwndDlg, IDC_ROSHOMEPAGE_LINK);
265
266 TextToLink(hLink,
267 _T("http://www.reactos.org"),
268 NULL);
269
270 InitImageInfo(&ImgInfo);
271 GetSystemInformation(hwndDlg);
272 }
273 break;
274
275 case WM_COMMAND:
276 {
277 if (LOWORD(wParam) == IDC_LICENCE)
278 {
279 DialogBox(hApplet,
280 MAKEINTRESOURCE(IDD_LICENCE),
281 hwndDlg,
282 LicenceDlgProc);
283
284 return TRUE;
285 }
286 }
287 break;
288
289 case WM_DRAWITEM:
290 {
291 LPDRAWITEMSTRUCT lpDrawItem;
292 lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
293 if(lpDrawItem->CtlID == IDC_ROSIMG)
294 {
295 HDC hdcMem;
296 LONG left;
297
298 /* position image in centre of dialog */
299 left = (lpDrawItem->rcItem.right - ImgInfo.cxSource) / 2;
300
301 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
302 if (hdcMem != NULL)
303 {
304 SelectObject(hdcMem, ImgInfo.hBitmap);
305 BitBlt(lpDrawItem->hDC,
306 left,
307 lpDrawItem->rcItem.top,
308 lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
309 lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
310 hdcMem,
311 0,
312 0,
313 SRCCOPY);
314 DeleteDC(hdcMem);
315 }
316 }
317 return TRUE;
318 }
319
320 }
321
322 return FALSE;
323 }
324