1 /*
2 * PROJECT: ReactX Diagnosis Application
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/dxdiag/system.c
5 * PURPOSE: ReactX diagnosis system page
6 * COPYRIGHT: Copyright 2008 Johannes Anderwald
7 *
8 */
9
10 #include "precomp.h"
11
12 typedef BOOL (WINAPI *ISWOW64PROC) (HANDLE, PBOOL);
13
14 BOOL
GetRegValue(HKEY hBaseKey,LPWSTR SubKey,LPWSTR ValueName,DWORD Type,LPWSTR Result,DWORD Size)15 GetRegValue(HKEY hBaseKey, LPWSTR SubKey, LPWSTR ValueName, DWORD Type, LPWSTR Result, DWORD Size)
16 {
17 HKEY hKey;
18 LONG res;
19 DWORD dwType;
20 DWORD dwSize;
21
22 if (RegOpenKeyExW(hBaseKey, SubKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
23 return FALSE;
24
25 dwSize = Size;
26 res = RegQueryValueExW(hKey, ValueName, NULL, &dwType, (LPBYTE)Result, &dwSize);
27 RegCloseKey(hKey);
28
29 if (res != ERROR_SUCCESS)
30 return FALSE;
31
32 if (dwType != Type)
33 return FALSE;
34
35 if (Size == sizeof(DWORD))
36 return TRUE;
37
38 Result[(Size / sizeof(WCHAR))-1] = L'\0';
39 return TRUE;
40 }
41
42
43 static
44 BOOL
GetDirectXVersion(WCHAR * szBuffer)45 GetDirectXVersion(WCHAR * szBuffer)
46 {
47 WCHAR szVer[20];
48
49 if (!GetRegValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\DirectX", L"Version", REG_SZ, szVer, sizeof(szVer)))
50 return FALSE;
51
52 if(!wcscmp(szVer, L"4.02.0095"))
53 wcscpy(szBuffer, L"1.0");
54 else if (!wcscmp(szVer, L"4.03.00.1096"))
55 wcscpy(szBuffer, L"2.0");
56 else if (!wcscmp(szVer, L"4.04.0068"))
57 wcscpy(szBuffer, L"3.0");
58 else if (!wcscmp(szVer, L"4.04.0069"))
59 wcscpy(szBuffer, L"3.0");
60 else if (!wcscmp(szVer, L"4.05.00.0155"))
61 wcscpy(szBuffer, L"5.0");
62 else if (!wcscmp(szVer, L"4.05.01.1721"))
63 wcscpy(szBuffer, L"5.0");
64 else if (!wcscmp(szVer, L"4.05.01.1998"))
65 wcscpy(szBuffer, L"5.0");
66 else if (!wcscmp(szVer, L"4.06.02.0436"))
67 wcscpy(szBuffer, L"6.0");
68 else if (!wcscmp(szVer, L"4.07.00.0700"))
69 wcscpy(szBuffer, L"7.0");
70 else if (!wcscmp(szVer, L"4.07.00.0716"))
71 wcscpy(szBuffer, L"7.0a");
72 else if (!wcscmp(szVer, L"4.08.00.0400"))
73 wcscpy(szBuffer, L"8.0");
74 else if (!wcscmp(szVer, L"4.08.01.0881"))
75 wcscpy(szBuffer, L"8.1");
76 else if (!wcscmp(szVer, L"4.08.01.0810"))
77 wcscpy(szBuffer, L"8.1");
78 else if (!wcscmp(szVer, L"4.09.0000.0900"))
79 wcscpy(szBuffer, L"9.0");
80 else if (!wcscmp(szVer, L"4.09.00.0900"))
81 wcscpy(szBuffer, L"9.0");
82 else if (!wcscmp(szVer, L"4.09.0000.0901"))
83 wcscpy(szBuffer, L"9.0a");
84 else if (!wcscmp(szVer, L"4.09.00.0901"))
85 wcscpy(szBuffer, L"9.0a");
86 else if (!wcscmp(szVer, L"4.09.0000.0902"))
87 wcscpy(szBuffer, L"9.0b");
88 else if (!wcscmp(szVer, L"4.09.00.0902"))
89 wcscpy(szBuffer, L"9.0b");
90 else if (!wcscmp(szVer, L"4.09.00.0904"))
91 wcscpy(szBuffer, L"9.0c");
92 else if (!wcscmp(szVer, L"4.09.0000.0904"))
93 wcscpy(szBuffer, L"9.0c");
94 else
95 return FALSE;
96
97 return TRUE;
98 }
99
GetSystemCPU(WCHAR * szBuffer)100 VOID GetSystemCPU(WCHAR *szBuffer)
101 {
102 SYSTEM_INFO archInfo;
103 ISWOW64PROC fnIsWow64Process;
104 BOOL isWow64 = FALSE;
105
106 /* Find out if the program is running through WOW64 or not. Apparently,
107 IsWow64Process() is not available on all versions of Windows, so the function
108 has to be imported at runtime. If the function cannot be found, then assume
109 the program is not running in WOW64. */
110 fnIsWow64Process = (ISWOW64PROC)GetProcAddress(
111 GetModuleHandleW(L"kernel32"), "IsWow64Process");
112
113 if (fnIsWow64Process != NULL)
114 fnIsWow64Process(GetCurrentProcess(), &isWow64);
115
116 /* If the program is compiled as 32-bit, but is running in WOW64, it will
117 automatically report as 32-bit regardless of the actual system architecture.
118 It detects whether or not the program is using WOW64 or not, and then
119 uses GetNativeSystemInfo(). If it is, it will properly report the actual
120 system architecture to the user. */
121 if (isWow64)
122 GetNativeSystemInfo(&archInfo);
123 else
124 GetSystemInfo(&archInfo);
125
126 /* Now check to see what the system architecture is */
127 if(archInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN)
128 {
129 switch(archInfo.wProcessorArchitecture)
130 {
131 case PROCESSOR_ARCHITECTURE_INTEL:
132 {
133 wsprintfW(szBuffer, L"32-bit");
134 break;
135 }
136 case PROCESSOR_ARCHITECTURE_AMD64:
137 {
138 wsprintfW(szBuffer, L"64-bit");
139 break;
140 }
141 case PROCESSOR_ARCHITECTURE_IA64:
142 {
143 wsprintfW(szBuffer, L"Itanium");
144 break;
145 }
146 case PROCESSOR_ARCHITECTURE_ARM:
147 {
148 wsprintfW(szBuffer, L"ARM");
149 break;
150 }
151 default:break;
152 }
153 }
154 }
155
156 static
157 SIZE_T
GetBIOSValue(BOOL UseSMBios,PCHAR DmiString,LPWSTR RegValue,PVOID pBuf,DWORD cchBuf,BOOL bTrim)158 GetBIOSValue(
159 BOOL UseSMBios,
160 PCHAR DmiString,
161 LPWSTR RegValue,
162 PVOID pBuf,
163 DWORD cchBuf,
164 BOOL bTrim)
165 {
166 SIZE_T Length = 0;
167 BOOL Result;
168
169 if (UseSMBios)
170 {
171 Length = GetSMBiosStringW(DmiString, pBuf, cchBuf, bTrim);
172 }
173 if (Length == 0)
174 {
175 Result = GetRegValue(HKEY_LOCAL_MACHINE, L"Hardware\\Description\\System\\BIOS", RegValue, REG_SZ, pBuf, cchBuf * sizeof(WCHAR));
176 if (Result)
177 {
178 Length = wcslen(pBuf);
179 }
180 }
181 return Length;
182 }
183
184 static
185 VOID
InitializeSystemPage(HWND hwndDlg)186 InitializeSystemPage(HWND hwndDlg)
187 {
188 WCHAR szTime[200];
189 WCHAR szOSName[50];
190 DWORD Length;
191 DWORDLONG AvailableBytes, UsedBytes;
192 MEMORYSTATUSEX mem;
193 WCHAR szFormat[50];
194 WCHAR szDesc[50];
195 SYSTEM_INFO SysInfo;
196 OSVERSIONINFO VersionInfo;
197 PVOID SMBiosBuf;
198 PCHAR DmiStrings[ID_STRINGS_MAX] = { 0 };
199 BOOL Result;
200
201 /* set date/time */
202 szTime[0] = L'\0';
203 Length = GetDateFormat(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL, NULL, szTime, _countof(szTime));
204 if (Length)
205 {
206 szTime[Length-1] = L',';
207 szTime[Length++] = L' ';
208 }
209 Length = GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT|LOCALE_NOUSEROVERRIDE, NULL, NULL, szTime + Length, _countof(szTime));
210 szTime[_countof(szTime)-1] = L'\0';
211 SendDlgItemMessageW(hwndDlg, IDC_STATIC_TIME, WM_SETTEXT, 0, (LPARAM)szTime);
212
213 /* set computer name */
214 szTime[0] = L'\0';
215 Length = _countof(szTime);
216 if (GetComputerNameW(szTime, &Length))
217 SendDlgItemMessageW(hwndDlg, IDC_STATIC_COMPUTER, WM_SETTEXT, 0, (LPARAM)szTime);
218
219 /* set product name */
220 if (GetRegValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"ProductName", REG_SZ, szOSName, sizeof(szOSName)))
221 {
222 if (LoadStringW(hInst, IDS_OS_VERSION, szFormat, _countof(szFormat)))
223 {
224 WCHAR szCpuName[50];
225
226 ZeroMemory(&VersionInfo, sizeof(OSVERSIONINFO));
227 VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
228
229 GetSystemCPU(szCpuName);
230
231 if (GetVersionEx(&VersionInfo))
232 {
233 szTime[_countof(szTime)-1] = L'\0';
234 wsprintfW(szTime, szFormat, szOSName, szCpuName, VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, VersionInfo.dwBuildNumber);
235 SendDlgItemMessageW(hwndDlg, IDC_STATIC_OS, WM_SETTEXT, 0, (LPARAM)szTime);
236 }
237 else
238 {
239 /* If the version of the OS cannot be retrieved for some reason, then just give the OS Name and Architecture */
240 szTime[_countof(szTime)-1] = L'\0';
241 wsprintfW(szTime, L"%s %s", szOSName, szCpuName);
242 SendDlgItemMessageW(hwndDlg, IDC_STATIC_OS, WM_SETTEXT, 0, (LPARAM)szTime);
243 }
244 }
245 }
246 else
247 {
248 if (LoadStringW(hInst, IDS_VERSION_UNKNOWN, szTime, _countof(szTime)))
249 {
250 szTime[_countof(szTime)-1] = L'\0';
251 SendDlgItemMessage(hwndDlg, IDC_STATIC_VERSION, WM_SETTEXT, 0, (LPARAM)szTime);
252 }
253 }
254
255 /* FIXME set product language/local language */
256 if (GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SLANGUAGE, szTime, _countof(szTime)))
257 SendDlgItemMessageW(hwndDlg, IDC_STATIC_LANG, WM_SETTEXT, 0, (LPARAM)szTime);
258
259 /* prepare SMBIOS data */
260 SMBiosBuf = LoadSMBiosData(DmiStrings);
261
262 /* set system manufacturer */
263 szTime[0] = L'\0';
264 Length = GetBIOSValue(SMBiosBuf != NULL,
265 DmiStrings[SYS_VENDOR],
266 L"SystemManufacturer",
267 szTime, _countof(szTime), FALSE);
268 if (Length > 0)
269 {
270 szTime[_countof(szTime)-1] = L'\0';
271 SendDlgItemMessageW(hwndDlg, IDC_STATIC_MANU, WM_SETTEXT, 0, (LPARAM)szTime);
272 }
273
274 /* set motherboard model */
275 szTime[0] = L'\0';
276 Length = GetBIOSValue(SMBiosBuf != NULL,
277 DmiStrings[SYS_PRODUCT],
278 L"SystemProductName",
279 szTime, _countof(szTime), FALSE);
280 if (Length > 0)
281 {
282 SendDlgItemMessageW(hwndDlg, IDC_STATIC_MODEL, WM_SETTEXT, 0, (LPARAM)szTime);
283 }
284
285 /* set bios model */
286 szTime[0] = L'\0';
287 Length = GetBIOSValue(SMBiosBuf != NULL,
288 DmiStrings[BIOS_VENDOR],
289 L"BIOSVendor",
290 szTime, _countof(szTime), TRUE);
291 if (Length > 0)
292 {
293 DWORD Index;
294 DWORD StrLength = _countof(szTime);
295
296 Index = wcslen(szTime);
297 if (Index + 1 < _countof(szTime))
298 {
299 szTime[Index++] = L' ';
300 szTime[Index] = L'\0';
301 }
302 StrLength -= Index;
303
304 Length = GetBIOSValue(SMBiosBuf != NULL,
305 DmiStrings[BIOS_DATE],
306 L"BIOSReleaseDate",
307 szTime + Index, StrLength, TRUE);
308 if (Length > 0)
309 {
310 if (Index + StrLength > _countof(szTime) - 15)
311 {
312 //FIXME retrieve BiosMajorRelease, BiosMinorRelease
313 //StrLength = wcslen(szTime + Index);
314 //szTime[Index+StrLength] = L' ';
315 //wcscpy(szTime + Index + StrLength, L"Ver: "); //FIXME NON-NLS
316 //szTime[_countof(szTime)-1] = L'\0';
317 }
318 SendDlgItemMessageW(hwndDlg, IDC_STATIC_BIOS, WM_SETTEXT, 0, (LPARAM)szTime);
319 }
320 }
321
322 /* clean SMBIOS data */
323 FreeSMBiosData(SMBiosBuf);
324
325 /* set processor string */
326 Result = GetRegValue(HKEY_LOCAL_MACHINE, L"Hardware\\Description\\System\\CentralProcessor\\0", L"ProcessorNameString", REG_SZ, szDesc, sizeof(szDesc));
327 if (!Result)
328 {
329 /* Processor Brand String not found */
330 /* FIXME: Implement CPU name detection routine */
331
332 /* Finally try to use Identifier string */
333 Result = GetRegValue(HKEY_LOCAL_MACHINE, L"Hardware\\Description\\System\\CentralProcessor\\0", L"Identifier", REG_SZ, szDesc, sizeof(szDesc));
334 }
335 if (Result)
336 {
337 TrimDmiStringW(szDesc);
338 /* FIXME retrieve current speed */
339 szFormat[0] = L'\0';
340 GetSystemInfo(&SysInfo);
341 if (SysInfo.dwNumberOfProcessors > 1)
342 LoadStringW(hInst, IDS_FORMAT_MPPROC, szFormat, _countof(szFormat));
343 else
344 LoadStringW(hInst, IDS_FORMAT_UNIPROC, szFormat, _countof(szFormat));
345
346 szFormat[_countof(szFormat)-1] = L'\0';
347 wsprintfW(szTime, szFormat, szDesc, SysInfo.dwNumberOfProcessors);
348 SendDlgItemMessageW(hwndDlg, IDC_STATIC_PROC, WM_SETTEXT, 0, (LPARAM)szTime);
349 }
350
351 /* retrieve available memory */
352 ZeroMemory(&mem, sizeof(mem));
353 mem.dwLength = sizeof(mem);
354 if (GlobalMemoryStatusEx(&mem))
355 {
356 if (LoadStringW(hInst, IDS_FORMAT_MB, szFormat, _countof(szFormat)))
357 {
358 /* set total mem string */
359 szFormat[_countof(szFormat)-1] = L'\0';
360 wsprintfW(szTime, szFormat, (mem.ullTotalPhys/1048576));
361 SendDlgItemMessageW(hwndDlg, IDC_STATIC_MEM, WM_SETTEXT, 0, (LPARAM)szTime);
362 }
363
364 if (LoadStringW(hInst, IDS_FORMAT_SWAP, szFormat, _countof(szFormat)))
365 {
366 /* set swap string */
367 AvailableBytes = (mem.ullTotalPageFile-mem.ullTotalPhys)/1048576;
368 UsedBytes = (mem.ullTotalPageFile-mem.ullAvailPageFile)/1048576;
369
370 szFormat[_countof(szFormat)-1] = L'\0';
371 wsprintfW(szTime, szFormat, (UsedBytes), (AvailableBytes));
372 SendDlgItemMessageW(hwndDlg, IDC_STATIC_SWAP, WM_SETTEXT, 0, (LPARAM)szTime);
373 }
374 }
375 /* set directx version string */
376 wcscpy(szTime, L"ReactX ");
377 if (GetDirectXVersion(szTime + 7))
378 {
379 SendDlgItemMessage(hwndDlg, IDC_STATIC_VERSION, WM_SETTEXT, 0, (LPARAM)szTime);
380 }
381 else
382 {
383 if (LoadStringW(hInst, IDS_VERSION_UNKNOWN, szTime, _countof(szTime)))
384 {
385 szTime[_countof(szTime)-1] = L'\0';
386 SendDlgItemMessage(hwndDlg, IDC_STATIC_VERSION, WM_SETTEXT, 0, (LPARAM)szTime);
387 }
388 }
389 }
390
391
392 INT_PTR CALLBACK
SystemPageWndProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)393 SystemPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
394 {
395 UNREFERENCED_PARAMETER(lParam);
396 UNREFERENCED_PARAMETER(wParam);
397 switch (message)
398 {
399 case WM_INITDIALOG:
400 {
401 SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
402 InitializeSystemPage(hDlg);
403 return TRUE;
404 }
405 }
406
407 return FALSE;
408 }
409