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 * Copyright 2006-2007 Colin Finck <mail@colinfinck.de>
15 typedef struct _IMGINFO
24 ShowLastWin32Error(HWND hWndOwner
)
29 LastError
= GetLastError();
31 if ((LastError
== 0) ||
32 !FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
33 FORMAT_MESSAGE_FROM_SYSTEM
,
36 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
44 MessageBox(hWndOwner
, lpMsg
, NULL
, MB_OK
| MB_ICONERROR
);
46 LocalFree((LPVOID
)lpMsg
);
51 InitImageInfo(PIMGINFO ImgInfo
)
55 ZeroMemory(ImgInfo
, sizeof(*ImgInfo
));
57 ImgInfo
->hBitmap
= LoadImage(hApplet
,
58 MAKEINTRESOURCE(IDB_ROSBMP
),
64 if (ImgInfo
->hBitmap
!= NULL
)
66 GetObject(ImgInfo
->hBitmap
, sizeof(BITMAP
), &bitmap
);
68 ImgInfo
->cxSource
= bitmap
.bmWidth
;
69 ImgInfo
->cySource
= bitmap
.bmHeight
;
75 SetRegTextData(HWND hwnd
,
84 if (RegQueryValueEx(hKey
,
89 &BufSize
) == ERROR_SUCCESS
)
91 lpBuf
= HeapAlloc(GetProcessHeap(),
97 if (RegQueryValueEx(hKey
,
102 &BufSize
) == ERROR_SUCCESS
)
109 HeapFree(GetProcessHeap(),
116 SetProcNameString(HWND hwnd
,
130 if (RegQueryValueEx(hKey
,
135 &BufSize
) == ERROR_SUCCESS
)
137 lpBuf
= HeapAlloc(GetProcessHeap(),
143 if (RegQueryValueEx(hKey
,
148 &BufSize
) == ERROR_SUCCESS
)
150 if (BufSize
> ((30 + 1) * sizeof(TCHAR
)))
152 /* Wrap the Processor Name String like XP does: *
153 * - Take the first 30 characters and look for the last space. *
154 * Then wrap the string after this space. *
155 * - If no space is found, wrap the string after character 30. *
157 * For example the Processor Name String of a Pentium 4 is right-aligned. *
158 * With this wrapping the first line looks centered. */
160 _tcsncpy(szBuf
, lpBuf
, 30);
162 szLastSpace
= _tcsrchr(szBuf
, ' ');
164 if (szLastSpace
== 0)
170 LastSpace
= (szLastSpace
- szBuf
);
171 szBuf
[LastSpace
] = 0;
174 _tcsncpy(szBuf
, lpBuf
, LastSpace
);
184 /* Return the number of used lines */
197 HeapFree(GetProcessHeap(),
206 MakeFloatValueString(double* dFloatValue
,
210 TCHAR szDecimalSeparator
[4];
212 /* Get the decimal separator for the current locale */
213 if (GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_SDECIMAL
, szDecimalSeparator
, sizeof(szDecimalSeparator
) / sizeof(TCHAR
)) > 0)
218 /* Show the value with two decimals */
219 uIntegral
= (UINT
)*dFloatValue
;
220 uDecimals
= (UCHAR
)((UINT
)(*dFloatValue
* 100) - uIntegral
* 100);
222 wsprintf(szOutput
, _T("%u%s%02u %s"), uIntegral
, szDecimalSeparator
, uDecimals
, szAppend
);
227 SetProcSpeed(HWND hwnd
,
233 DWORD BufSize
= sizeof(DWORD
);
235 PROCESSOR_POWER_INFORMATION ppi
;
240 if ((CallNtPowerInformation(ProcessorInformation
,
244 sizeof(ppi
)) == STATUS_SUCCESS
&&
245 ppi
.CurrentMhz
!= 0) ||
246 RegQueryValueEx(hKey
,
250 (PBYTE
)&ppi
.CurrentMhz
,
251 &BufSize
) == ERROR_SUCCESS
)
253 if (ppi
.CurrentMhz
< 1000)
255 wsprintf(szBuf
, _T("%lu MHz"), ppi
.CurrentMhz
);
259 double flt
= ppi
.CurrentMhz
/ 1000.0;
260 MakeFloatValueString(&flt
, szBuf
, _T("GHz"));
270 GetSystemInformation(HWND hwnd
)
273 TCHAR ProcKey
[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
274 MEMORYSTATUSEX MemStat
;
276 INT CurMachineLine
= IDC_MACHINELINE1
;
279 * Get Processor information
280 * although undocumented, this information is being pulled
281 * directly out of the registry instead of via setupapi as it
282 * contains all the info we need, and should remain static
284 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
288 &hKey
) == ERROR_SUCCESS
)
292 _T("VendorIdentifier"),
296 CurMachineLine
+= SetProcNameString(hwnd
,
298 _T("ProcessorNameString"),
310 /* Get total physical RAM */
311 MemStat
.dwLength
= sizeof(MemStat
);
312 if (GlobalMemoryStatusEx(&MemStat
))
317 if (MemStat
.ullTotalPhys
> 1024 * 1024 * 1024)
320 static const UINT uStrId
[] = {
326 // We're dealing with GBs or more
327 MemStat
.ullTotalPhys
/= 1024 * 1024;
329 if (MemStat
.ullTotalPhys
> 1024 * 1024)
331 // We're dealing with TBs or more
332 MemStat
.ullTotalPhys
/= 1024;
335 if (MemStat
.ullTotalPhys
> 1024 * 1024)
337 // We're dealing with PBs or more
338 MemStat
.ullTotalPhys
/= 1024;
341 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
345 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
350 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
353 LoadString(hApplet
, uStrId
[i
], szStr
, sizeof(szStr
) / sizeof(TCHAR
));
354 MakeFloatValueString(&dTotalPhys
, Buf
, szStr
);
358 // We're dealing with MBs, don't show any decimals
359 LoadString(hApplet
, IDS_MEGABYTE
, szStr
, sizeof(szStr
) / sizeof(TCHAR
));
360 wsprintf(Buf
, _T("%u %s"), (UINT
)MemStat
.ullTotalPhys
/ 1024 / 1024, szStr
);
363 SetDlgItemText(hwnd
, CurMachineLine
, Buf
);
368 /* Property page dialog callback */
370 GeneralPageProc(HWND hwndDlg
,
377 UNREFERENCED_PARAMETER(lParam
);
378 UNREFERENCED_PARAMETER(wParam
);
380 pImgInfo
= (PIMGINFO
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
385 pImgInfo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IMGINFO
));
386 if (pImgInfo
== NULL
)
388 EndDialog(hwndDlg
, 0);
392 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pImgInfo
);
394 InitImageInfo(pImgInfo
);
395 GetSystemInformation(hwndDlg
);
399 HeapFree(GetProcessHeap(), 0, pImgInfo
);
403 if (LOWORD(wParam
) == IDC_LICENCE
)
406 MAKEINTRESOURCE(IDD_LICENCE
),
416 LPDRAWITEMSTRUCT lpDrawItem
;
417 lpDrawItem
= (LPDRAWITEMSTRUCT
) lParam
;
418 if (lpDrawItem
->CtlID
== IDC_ROSIMG
)
423 /* position image in centre of dialog */
424 left
= (lpDrawItem
->rcItem
.right
- pImgInfo
->cxSource
) / 2;
426 hdcMem
= CreateCompatibleDC(lpDrawItem
->hDC
);
429 SelectObject(hdcMem
, pImgInfo
->hBitmap
);
430 BitBlt(lpDrawItem
->hDC
,
432 lpDrawItem
->rcItem
.top
,
433 lpDrawItem
->rcItem
.right
- lpDrawItem
->rcItem
.left
,
434 lpDrawItem
->rcItem
.bottom
- lpDrawItem
->rcItem
.top
,
447 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
449 if (nmhdr
->idFrom
== IDC_ROSHOMEPAGE_LINK
&& nmhdr
->code
== NM_CLICK
)
451 PNMLINK nml
= (PNMLINK
)nmhdr
;
453 ShellExecuteW(hwndDlg
,