00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdmisc.h"
00027
00028 #ifdef NL_OS_WINDOWS
00029 #include <windows.h>
00030 #include <tchar.h>
00031 #else
00032 #include <sys/types.h>
00033 #include <sys/stat.h>
00034 #include <fcntl.h>
00035 #include <unistd.h>
00036 #endif
00037
00038 #include "nel/misc/system_info.h"
00039 #include "nel/misc/command.h"
00040 #include "nel/misc/heap_allocator.h"
00041
00042 using namespace std;
00043
00044 namespace NLMISC {
00045
00046 string CSystemInfo::getOS ()
00047 {
00048 string OSString = "Unknown";
00049 #ifdef NL_OS_WINDOWS
00050 char ver[1024];
00051
00052 OSVERSIONINFOEX osvi;
00053 BOOL bOsVersionInfoEx;
00054
00055
00056
00057
00058
00059
00060 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
00061 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
00062
00063 if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
00064 {
00065
00066 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
00067 if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
00068 return "Windows Unknown";
00069 }
00070
00071 switch (osvi.dwPlatformId)
00072 {
00073 case VER_PLATFORM_WIN32_NT:
00074
00075
00076 if ( osvi.dwMajorVersion <= 4 )
00077 OSString = "Microsoft Windows NT ";
00078
00079 if ( osvi.dwMajorVersion == 5 )
00080 OSString = "Microsoft Windows 2000 ";
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 {
00094 HKEY hKey;
00095 char szProductType[80];
00096 DWORD dwBufLen;
00097
00098 RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey );
00099 RegQueryValueEx( hKey, "ProductType", NULL, NULL, (LPBYTE) szProductType, &dwBufLen);
00100 RegCloseKey( hKey );
00101 if ( lstrcmpi( "WINNT", szProductType) == 0 )
00102 OSString += "Workstation ";
00103 if ( lstrcmpi( "SERVERNT", szProductType) == 0 )
00104 OSString += "Server ";
00105 }
00106
00107
00108 smprintf(ver, 1024, "version %d.%d '%s' (Build %d)", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
00109 OSString += ver;
00110 break;
00111
00112 case VER_PLATFORM_WIN32_WINDOWS:
00113
00114 if(osvi.dwMinorVersion == 0)
00115 OSString = "Microsoft Windows 95 ";
00116 else if (osvi.dwMinorVersion == 10)
00117 OSString = "Microsoft Windows 98 ";
00118 else if (osvi.dwMinorVersion == 90)
00119 OSString = "Microsoft Windows Millenium ";
00120
00121
00122
00123
00124
00125
00126
00127 smprintf(ver, 1024, "version %d.%d %s (Build %d)", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
00128 OSString += ver;
00129 break;
00130
00131 case VER_PLATFORM_WIN32s:
00132 OSString = "Microsoft Win32s";
00133 break;
00134 }
00135
00136 #elif defined NL_OS_UNIX
00137
00138 OSString = "Unix";
00139
00140 #endif // NL_OS_UNIX
00141
00142 return OSString;
00143 }
00144
00145 string CSystemInfo::getProc ()
00146 {
00147 string ProcString = "Unknown";
00148
00149 #ifdef NL_OS_WINDOWS
00150
00151 LONG result;
00152 char value[1024];
00153 DWORD valueSize;
00154 HKEY hKey;
00155
00156 result = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Hardware\\Description\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey);
00157 if (result == ERROR_SUCCESS)
00158 {
00159
00160 valueSize = 1024;
00161 result = ::RegQueryValueEx (hKey, _T("ProcessorNameString"), NULL, NULL, (LPBYTE)&value, &valueSize);
00162 if (result == ERROR_SUCCESS)
00163 ProcString = value;
00164 else
00165 ProcString = "UnknownProc";
00166
00167 ProcString += " / ";
00168
00169
00170 valueSize = 1024;
00171 result = ::RegQueryValueEx (hKey, _T("Identifier"), NULL, NULL, (LPBYTE)&value, &valueSize);
00172 if (result == ERROR_SUCCESS)
00173 ProcString += value;
00174 else
00175 ProcString += "UnknownIdentifier";
00176
00177 ProcString += " / ";
00178
00179
00180 valueSize = 1024;
00181 result = ::RegQueryValueEx (hKey, _T("VendorIdentifier"), NULL, NULL, (LPBYTE)&value, &valueSize);
00182 if (result == ERROR_SUCCESS)
00183 ProcString += value;
00184 else
00185 ProcString += "UnknownVendor";
00186
00187 ProcString += " / ";
00188
00189
00190 result = ::RegQueryValueEx (hKey, _T("~MHz"), NULL, NULL, (LPBYTE)&value, &valueSize);
00191 if (result == ERROR_SUCCESS)
00192 {
00193 ProcString += itoa (*(int *)value, value, 10);
00194 ProcString += "MHz";
00195 }
00196 else
00197 ProcString += "UnknownFreq";
00198 }
00199
00200
00201
00202 RegCloseKey (hKey);
00203
00204 #elif defined NL_OS_UNIX
00205
00206
00207 #endif
00208
00209 return ProcString;
00210 }
00211
00212 string CSystemInfo::getMem ()
00213 {
00214 string MemString = "Unknown";
00215
00216 #ifdef NL_OS_WINDOWS
00217
00218 MEMORYSTATUS ms;
00219
00220 GlobalMemoryStatus (&ms);
00221
00222 sint extt = 0, extf = 0;
00223 char *ext2str[] = { "b", "Kb", "Mb", "Gb", "Tb" };
00224
00225 while (ms.dwTotalPhys > 1024)
00226 {
00227 ms.dwTotalPhys /= 1024;
00228 extt++;
00229 }
00230
00231 while (ms.dwAvailPhys > 1024)
00232 {
00233 ms.dwAvailPhys /= 1024;
00234 extf++;
00235 }
00236
00237 char mem[1024];
00238 smprintf (mem, 1024, "physical memory: total: %d %s free: %d %s", ms.dwTotalPhys+1, ext2str[extt], ms.dwAvailPhys+1, ext2str[extf]);
00239 MemString = mem;
00240
00241 #elif defined NL_OS_UNIX
00242
00243
00244 #endif
00245
00246 return MemString;
00247 }
00248
00249
00250 static bool DetectMMX()
00251 {
00252 #ifdef NL_OS_WINDOWS
00253 if (!CSystemInfo::hasCPUID()) return false;
00254
00255 uint32 result = 0;
00256 __asm
00257 {
00258 mov eax,1
00259 cpuid
00260 test edx,0x800000
00261 je noMMX
00262 mov result, 1
00263 noMMX:
00264 }
00265
00266 return result == 1;
00267
00268
00269
00270 #else
00271 return false;
00272 #endif
00273 }
00274
00275
00276 static bool DetectSSE()
00277 {
00278 #ifdef NL_OS_WINDOWS
00279 if (!CSystemInfo::hasCPUID()) return false;
00280
00281 uint32 result = 0;
00282 __asm
00283 {
00284 mov eax, 1
00285 cpuid
00286 test EDX, 002000000h
00287 je noSSE
00288 mov result, 1
00289 noSSE:
00290 }
00291
00292
00293 if (result)
00294 {
00295
00296 try
00297 {
00298 __asm
00299 {
00300 xorps xmm0, xmm0
00301 }
00302 }
00303 catch(...)
00304 {
00305 return false;
00306 }
00307
00308
00309
00310 return true;
00311 }
00312 else
00313 {
00314 return false;
00315 }
00316 #else
00317 return false;
00318 #endif
00319 }
00320
00321 static bool HaveMMX = DetectMMX ();
00322 static bool HaveSSE = DetectSSE ();
00323
00324 bool CSystemInfo::hasCPUID ()
00325 {
00326 #ifdef NL_OS_WINDOWS
00327 uint32 result;
00328 __asm
00329 {
00330 pushad
00331 pushfd
00332
00333 pushfd
00334 pop eax
00335 mov ecx,eax
00336 xor eax,0x200000
00337 push eax
00338 popfd
00339 pushfd
00340 pop eax
00341 xor eax,ecx
00342 je noCpuid
00343
00344 popfd
00345 popad
00346 mov result, 1
00347 jmp CPUIDPresent
00348
00349 noCpuid:
00350 popfd
00351 popad
00352 mov result, 0
00353 CPUIDPresent:
00354 }
00355 return result == 1;
00356 #else
00357 return false;
00358 #endif
00359 }
00360 bool CSystemInfo::hasMMX () { return HaveMMX; }
00361 bool CSystemInfo::hasSSE () { return HaveSSE; }
00362
00363
00364 bool CSystemInfo::isNT()
00365 {
00366 #ifdef NL_OS_WINDOWS
00367 OSVERSIONINFO ver;
00368 ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00369 GetVersionEx(&ver);
00370 return ver.dwPlatformId == VER_PLATFORM_WIN32_NT;
00371 #else
00372 return false;
00373 #endif
00374 }
00375
00376
00377 #ifdef NL_OS_UNIX
00378
00379 static inline char *skipWS(const char *p)
00380 {
00381 while (isspace(*p)) p++;
00382 return (char *)p;
00383 }
00384
00385 static inline char *skipToken(const char *p)
00386 {
00387 while (isspace(*p)) p++;
00388 while (*p && !isspace(*p)) p++;
00389 return (char *)p;
00390 }
00391
00392
00393 uint32 getSystemMemory (uint col)
00394 {
00395 if (col > 5)
00396 return 0;
00397
00398 char buffer[4096+1];
00399 int fd, len;
00400 char *p;
00401
00402
00403 {
00404 char *p;
00405
00406 fd = open("/proc/meminfo", O_RDONLY);
00407 len = read(fd, buffer, sizeof(buffer)-1);
00408 close(fd);
00409 buffer[len] = '\0';
00410
00411
00412
00413 p = strchr(buffer, '\n');
00414 p = skipToken(p);
00415 for (uint i = 0; i < col; i++)
00416 {
00417 p = skipToken(p);
00418 }
00419 return strtoul(p, &p, 10);
00420 }
00421 }
00422
00423 #endif // NL_OS_UNIX
00424
00425
00426
00427
00428 uint32 CSystemInfo::availablePhysicalMemory ()
00429 {
00430 #ifdef NL_OS_WINDOWS
00431
00432 MEMORYSTATUS ms;
00433 GlobalMemoryStatus (&ms);
00434 return ms.dwAvailPhys;
00435
00436 #elif defined NL_OS_UNIX
00437
00438 return getSystemMemory (2);
00439
00440 #endif
00441
00442 return 0;
00443 }
00444
00445 uint32 CSystemInfo::totalPhysicalMemory ()
00446 {
00447 #ifdef NL_OS_WINDOWS
00448
00449 MEMORYSTATUS ms;
00450 GlobalMemoryStatus (&ms);
00451 return ms.dwTotalPhys;
00452
00453 #elif defined NL_OS_UNIX
00454
00455 return getSystemMemory (0);
00456
00457 #endif
00458
00459 return 0;
00460 }
00461
00462
00463 NLMISC_DYNVARIABLE(uint32, AvailablePhysicalMemory, "Physical memory available on this computer in bytes")
00464 {
00465 if (get) *pointer = CSystemInfo::availablePhysicalMemory ();
00466 }
00467
00468 NLMISC_DYNVARIABLE(uint32, TotalPhysicalMemory, "Total physical memory on this computer in bytes")
00469 {
00470 if (get) *pointer = CSystemInfo::totalPhysicalMemory ();
00471 }
00472
00473 NLMISC_DYNVARIABLE(uint32, ProcessUsedMemory, "Memory used by this process in bytes")
00474 {
00475 if (get) *pointer = CHeapAllocator::getAllocatedSystemMemory ();
00476 }
00477
00478
00479 }