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