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 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(),
96 if (RegQueryValueEx(hKey
,
101 &BufSize
) == ERROR_SUCCESS
)
108 HeapFree(GetProcessHeap(),
115 SetProcNameString(HWND hwnd
,
129 if (RegQueryValueEx(hKey
,
134 &BufSize
) == ERROR_SUCCESS
)
136 lpBuf
= HeapAlloc(GetProcessHeap(),
139 if (!lpBuf
) return 0;
141 if (RegQueryValueEx(hKey
,
146 &BufSize
) == ERROR_SUCCESS
)
148 if(BufSize
> ((30 + 1) * sizeof(TCHAR
)))
150 /* Wrap the Processor Name String like XP does: *
151 * - Take the first 30 characters and look for the last space. *
152 * Then wrap the string after this space. *
153 * - If no space is found, wrap the string after character 30. *
155 * For example the Processor Name String of a Pentium 4 is right-aligned. *
156 * With this wrapping the first line looks centered. */
158 _tcsncpy(szBuf
, lpBuf
, 30);
159 szLastSpace
= _tcsrchr(szBuf
, ' ');
164 LastSpace
= (szLastSpace
- szBuf
);
166 _tcsncpy(szBuf
, lpBuf
, LastSpace
);
167 szBuf
[LastSpace
] = 0;
177 /* Return the number of used lines */
190 HeapFree(GetProcessHeap(),
201 SetProcSpeed(HWND hwnd
,
208 DWORD BufSize
= sizeof(DWORD
);
210 PROCESSOR_POWER_INFORMATION ppi
;
215 if ((CallNtPowerInformation(ProcessorInformation
,
219 sizeof(ppi
)) == STATUS_SUCCESS
&&
220 ppi
.CurrentMhz
!= 0) ||
221 RegQueryValueEx(hKey
,
225 (PBYTE
)&ppi
.CurrentMhz
,
226 &BufSize
) == ERROR_SUCCESS
)
228 if (ppi
.CurrentMhz
< 1000)
230 _stprintf(szBuf
, _T("%lu MHz"), ppi
.CurrentMhz
);
234 double flt
= ppi
.CurrentMhz
/ 1000.0;
235 _stprintf(szBuf
, _T("%.2f GHz"), flt
);
245 GetSystemInformation(HWND hwnd
)
248 TCHAR ProcKey
[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
249 MEMORYSTATUSEX MemStat
;
252 INT CurMachineLine
= IDC_MACHINELINE1
;
255 /* Get Processor information *
256 * although undocumented, this information is being pulled
257 * directly out of the registry instead of via setupapi as it
258 * contains all the info we need, and should remain static
260 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
264 &hKey
) == ERROR_SUCCESS
)
268 _T("VendorIdentifier"),
272 Ret
= SetProcNameString(hwnd
,
274 _T("ProcessorNameString"),
277 CurMachineLine
+= Ret
;
287 /* Get total physical RAM */
288 MemStat
.dwLength
= sizeof(MemStat
);
289 if (GlobalMemoryStatusEx(&MemStat
))
294 static const UINT uStrId
[] = {
301 if (MemStat
.ullTotalPhys
> 1024 * 1024 * 1024)
303 /* We're dealing with GBs or more */
304 MemStat
.ullTotalPhys
/= 1024 * 1024;
307 if (MemStat
.ullTotalPhys
> 1024 * 1024)
309 /* We're dealing with TBs or more */
310 MemStat
.ullTotalPhys
/= 1024;
313 if (MemStat
.ullTotalPhys
> 1024 * 1024)
315 /* We're dealing with PBs or more */
317 MemStat
.ullTotalPhys
/= 1024;
320 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
323 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
326 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
330 /* We're daling with MBs */
331 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024 / 1024;
334 if (LoadString(hApplet
, uStrId
[i
], szStr
, sizeof(szStr
) / sizeof(szStr
[0])))
336 Ret
= _stprintf(Buf
, _T("%.2f %s"), dTotalPhys
, szStr
);
349 /* Property page dialog callback */
351 GeneralPageProc(HWND hwndDlg
,
356 static IMGINFO ImgInfo
;
358 UNREFERENCED_PARAMETER(lParam
);
359 UNREFERENCED_PARAMETER(wParam
);
365 InitImageInfo(&ImgInfo
);
366 GetSystemInformation(hwndDlg
);
372 if (LOWORD(wParam
) == IDC_LICENCE
)
375 MAKEINTRESOURCE(IDD_LICENCE
),
386 LPDRAWITEMSTRUCT lpDrawItem
;
387 lpDrawItem
= (LPDRAWITEMSTRUCT
) lParam
;
388 if(lpDrawItem
->CtlID
== IDC_ROSIMG
)
393 /* position image in centre of dialog */
394 left
= (lpDrawItem
->rcItem
.right
- ImgInfo
.cxSource
) / 2;
396 hdcMem
= CreateCompatibleDC(lpDrawItem
->hDC
);
399 SelectObject(hdcMem
, ImgInfo
.hBitmap
);
400 BitBlt(lpDrawItem
->hDC
,
402 lpDrawItem
->rcItem
.top
,
403 lpDrawItem
->rcItem
.right
- lpDrawItem
->rcItem
.left
,
404 lpDrawItem
->rcItem
.bottom
- lpDrawItem
->rcItem
.top
,
417 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
419 if (nmhdr
->idFrom
== IDC_ROSHOMEPAGE_LINK
&& nmhdr
->code
== NM_CLICK
)
421 PNMLINK nml
= (PNMLINK
)nmhdr
;
423 ShellExecuteW(hwndDlg
,