[IPCONFIG] Implement the /flushdns option and most of the /displaydns option
[reactos.git] / base / applications / dxdiag / system.c
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
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
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
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
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
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
200 /* set date/time */
201 szTime[0] = L'\0';
202 Length = GetDateFormat(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL, NULL, szTime, _countof(szTime));
203 if (Length)
204 {
205 szTime[Length-1] = L',';
206 szTime[Length++] = L' ';
207 }
208 Length = GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT|LOCALE_NOUSEROVERRIDE, NULL, NULL, szTime + Length, _countof(szTime));
209 szTime[_countof(szTime)-1] = L'\0';
210 SendDlgItemMessageW(hwndDlg, IDC_STATIC_TIME, WM_SETTEXT, 0, (LPARAM)szTime);
211
212 /* set computer name */
213 szTime[0] = L'\0';
214 Length = _countof(szTime);
215 if (GetComputerNameW(szTime, &Length))
216 SendDlgItemMessageW(hwndDlg, IDC_STATIC_COMPUTER, WM_SETTEXT, 0, (LPARAM)szTime);
217
218 /* set product name */
219 if (GetRegValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"ProductName", REG_SZ, szOSName, sizeof(szOSName)))
220 {
221 if (LoadStringW(hInst, IDS_OS_VERSION, szFormat, _countof(szFormat)))
222 {
223 WCHAR szCpuName[50];
224
225 ZeroMemory(&VersionInfo, sizeof(OSVERSIONINFO));
226 VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
227
228 GetSystemCPU(szCpuName);
229
230 if (GetVersionEx(&VersionInfo))
231 {
232 szTime[_countof(szTime)-1] = L'\0';
233 wsprintfW(szTime, szFormat, szOSName, szCpuName, VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, VersionInfo.dwBuildNumber);
234 SendDlgItemMessageW(hwndDlg, IDC_STATIC_OS, WM_SETTEXT, 0, (LPARAM)szTime);
235 }
236 else
237 {
238 /* If the version of the OS cannot be retrieved for some reason, then just give the OS Name and Architecture */
239 szTime[_countof(szTime)-1] = L'\0';
240 wsprintfW(szTime, L"%s %s", szOSName, szCpuName);
241 SendDlgItemMessageW(hwndDlg, IDC_STATIC_OS, WM_SETTEXT, 0, (LPARAM)szTime);
242 }
243 }
244 }
245 else
246 {
247 if (LoadStringW(hInst, IDS_VERSION_UNKNOWN, szTime, _countof(szTime)))
248 {
249 szTime[_countof(szTime)-1] = L'\0';
250 SendDlgItemMessage(hwndDlg, IDC_STATIC_VERSION, WM_SETTEXT, 0, (LPARAM)szTime);
251 }
252 }
253
254 /* FIXME set product language/local language */
255 if (GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SLANGUAGE, szTime, _countof(szTime)))
256 SendDlgItemMessageW(hwndDlg, IDC_STATIC_LANG, WM_SETTEXT, 0, (LPARAM)szTime);
257
258 /* prepare SMBIOS data */
259 SMBiosBuf = LoadSMBiosData(DmiStrings);
260
261 /* set system manufacturer */
262 szTime[0] = L'\0';
263 Length = GetBIOSValue(SMBiosBuf != NULL,
264 DmiStrings[SYS_VENDOR],
265 L"SystemManufacturer",
266 szTime, _countof(szTime), FALSE);
267 if (Length > 0)
268 {
269 szTime[_countof(szTime)-1] = L'\0';
270 SendDlgItemMessageW(hwndDlg, IDC_STATIC_MANU, WM_SETTEXT, 0, (LPARAM)szTime);
271 }
272
273 /* set motherboard model */
274 szTime[0] = L'\0';
275 Length = GetBIOSValue(SMBiosBuf != NULL,
276 DmiStrings[SYS_PRODUCT],
277 L"SystemProductName",
278 szTime, _countof(szTime), FALSE);
279 if (Length > 0)
280 {
281 SendDlgItemMessageW(hwndDlg, IDC_STATIC_MODEL, WM_SETTEXT, 0, (LPARAM)szTime);
282 }
283
284 /* set bios model */
285 szTime[0] = L'\0';
286 Length = GetBIOSValue(SMBiosBuf != NULL,
287 DmiStrings[BIOS_VENDOR],
288 L"BIOSVendor",
289 szTime, _countof(szTime), TRUE);
290 if (Length > 0)
291 {
292 DWORD Index;
293 DWORD StrLength = _countof(szTime);
294
295 Index = wcslen(szTime);
296 if (Index + 1 < _countof(szTime))
297 {
298 szTime[Index++] = L' ';
299 szTime[Index] = L'\0';
300 }
301 StrLength -= Index;
302
303 Length = GetBIOSValue(SMBiosBuf != NULL,
304 DmiStrings[BIOS_DATE],
305 L"BIOSReleaseDate",
306 szTime + Index, StrLength, TRUE);
307 if (Length > 0)
308 {
309 if (Index + StrLength > _countof(szTime) - 15)
310 {
311 //FIXME retrieve BiosMajorRelease, BiosMinorRelease
312 //StrLength = wcslen(szTime + Index);
313 //szTime[Index+StrLength] = L' ';
314 //wcscpy(szTime + Index + StrLength, L"Ver: "); //FIXME NON-NLS
315 //szTime[_countof(szTime)-1] = L'\0';
316 }
317 SendDlgItemMessageW(hwndDlg, IDC_STATIC_BIOS, WM_SETTEXT, 0, (LPARAM)szTime);
318 }
319 }
320
321 /* clean SMBIOS data */
322 FreeSMBiosData(SMBiosBuf);
323
324 /* set processor string */
325 if (GetRegValue(HKEY_LOCAL_MACHINE, L"Hardware\\Description\\System\\CentralProcessor\\0", L"ProcessorNameString", REG_SZ, szDesc, sizeof(szDesc)))
326 {
327 TrimDmiStringW(szDesc);
328 /* FIXME retrieve current speed */
329 szFormat[0] = L'\0';
330 GetSystemInfo(&SysInfo);
331 if (SysInfo.dwNumberOfProcessors > 1)
332 LoadStringW(hInst, IDS_FORMAT_MPPROC, szFormat, _countof(szFormat));
333 else
334 LoadStringW(hInst, IDS_FORMAT_UNIPROC, szFormat, _countof(szFormat));
335
336 szFormat[_countof(szFormat)-1] = L'\0';
337 wsprintfW(szTime, szFormat, szDesc, SysInfo.dwNumberOfProcessors);
338 SendDlgItemMessageW(hwndDlg, IDC_STATIC_PROC, WM_SETTEXT, 0, (LPARAM)szTime);
339 }
340
341 /* retrieve available memory */
342 ZeroMemory(&mem, sizeof(mem));
343 mem.dwLength = sizeof(mem);
344 if (GlobalMemoryStatusEx(&mem))
345 {
346 if (LoadStringW(hInst, IDS_FORMAT_MB, szFormat, _countof(szFormat)))
347 {
348 /* set total mem string */
349 szFormat[_countof(szFormat)-1] = L'\0';
350 wsprintfW(szTime, szFormat, (mem.ullTotalPhys/1048576));
351 SendDlgItemMessageW(hwndDlg, IDC_STATIC_MEM, WM_SETTEXT, 0, (LPARAM)szTime);
352 }
353
354 if (LoadStringW(hInst, IDS_FORMAT_SWAP, szFormat, _countof(szFormat)))
355 {
356 /* set swap string */
357 AvailableBytes = (mem.ullTotalPageFile-mem.ullTotalPhys)/1048576;
358 UsedBytes = (mem.ullTotalPageFile-mem.ullAvailPageFile)/1048576;
359
360 szFormat[_countof(szFormat)-1] = L'\0';
361 wsprintfW(szTime, szFormat, (UsedBytes), (AvailableBytes));
362 SendDlgItemMessageW(hwndDlg, IDC_STATIC_SWAP, WM_SETTEXT, 0, (LPARAM)szTime);
363 }
364 }
365 /* set directx version string */
366 wcscpy(szTime, L"ReactX ");
367 if (GetDirectXVersion(szTime + 7))
368 {
369 SendDlgItemMessage(hwndDlg, IDC_STATIC_VERSION, WM_SETTEXT, 0, (LPARAM)szTime);
370 }
371 else
372 {
373 if (LoadStringW(hInst, IDS_VERSION_UNKNOWN, szTime, _countof(szTime)))
374 {
375 szTime[_countof(szTime)-1] = L'\0';
376 SendDlgItemMessage(hwndDlg, IDC_STATIC_VERSION, WM_SETTEXT, 0, (LPARAM)szTime);
377 }
378 }
379 }
380
381
382 INT_PTR CALLBACK
383 SystemPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
384 {
385 UNREFERENCED_PARAMETER(lParam);
386 UNREFERENCED_PARAMETER(wParam);
387 switch (message)
388 {
389 case WM_INITDIALOG:
390 {
391 SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
392 InitializeSystemPage(hDlg);
393 return TRUE;
394 }
395 }
396
397 return FALSE;
398 }