xref: /reactos/base/applications/dxdiag/system.c (revision cc439606)
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 }
399