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 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 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