1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2014-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "nel/misc/system_info.h"
28 # define nlcpuid(regs, idx) __cpuid(regs, idx)
30 // define them here to not rely on Windows 10 SDKs
31 # define NL_PRODUCT_UNDEFINED 0x00000000
32 # define NL_PRODUCT_ULTIMATE 0x00000001
33 # define NL_PRODUCT_HOME_BASIC 0x00000002
34 # define NL_PRODUCT_HOME_PREMIUM 0x00000003
35 # define NL_PRODUCT_ENTERPRISE 0x00000004
36 # define NL_PRODUCT_HOME_BASIC_N 0x00000005
37 # define NL_PRODUCT_BUSINESS 0x00000006
38 # define NL_PRODUCT_STANDARD_SERVER 0x00000007
39 # define NL_PRODUCT_DATACENTER_SERVER 0x00000008
40 # define NL_PRODUCT_SMALLBUSINESS_SERVER 0x00000009
41 # define NL_PRODUCT_ENTERPRISE_SERVER 0x0000000A
42 # define NL_PRODUCT_STARTER 0x0000000B
43 # define NL_PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
44 # define NL_PRODUCT_STANDARD_SERVER_CORE 0x0000000D
45 # define NL_PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
46 # define NL_PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
47 # define NL_PRODUCT_BUSINESS_N 0x00000010
48 # define NL_PRODUCT_WEB_SERVER 0x00000011
49 # define NL_PRODUCT_CLUSTER_SERVER 0x00000012
50 # define NL_PRODUCT_HOME_SERVER 0x00000013
51 # define NL_PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
52 # define NL_PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
53 # define NL_PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
54 # define NL_PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
55 # define NL_PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
56 # define NL_PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019
57 # define NL_PRODUCT_HOME_PREMIUM_N 0x0000001A
58 # define NL_PRODUCT_ENTERPRISE_N 0x0000001B
59 # define NL_PRODUCT_ULTIMATE_N 0x0000001C
60 # define NL_PRODUCT_WEB_SERVER_CORE 0x0000001D
61 # define NL_PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
62 # define NL_PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
63 # define NL_PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
64 # define NL_PRODUCT_SERVER_FOUNDATION 0x00000021
65 # define NL_PRODUCT_HOME_PREMIUM_SERVER 0x00000022
66 # define NL_PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023
67 # define NL_PRODUCT_STANDARD_SERVER_V 0x00000024
68 # define NL_PRODUCT_DATACENTER_SERVER_V 0x00000025
69 # define NL_PRODUCT_ENTERPRISE_SERVER_V 0x00000026
70 # define NL_PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
71 # define NL_PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
72 # define NL_PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
73 # define NL_PRODUCT_HYPERV 0x0000002A
74 # define NL_PRODUCT_STORAGE_EXPRESS_SERVER_CORE 0x0000002B
75 # define NL_PRODUCT_STORAGE_STANDARD_SERVER_CORE 0x0000002C
76 # define NL_PRODUCT_STORAGE_WORKGROUP_SERVER_CORE 0x0000002D
77 # define NL_PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE 0x0000002E
78 # define NL_PRODUCT_STARTER_N 0x0000002F
79 # define NL_PRODUCT_PROFESSIONAL 0x00000030
80 # define NL_PRODUCT_PROFESSIONAL_N 0x00000031
81 # define NL_PRODUCT_SB_SOLUTION_SERVER 0x00000032
82 # define NL_PRODUCT_SERVER_FOR_SB_SOLUTIONS 0x00000033
83 # define NL_PRODUCT_STANDARD_SERVER_SOLUTIONS 0x00000034
84 # define NL_PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE 0x00000035
85 # define NL_PRODUCT_SB_SOLUTION_SERVER_EM 0x00000036
86 # define NL_PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM 0x00000037
87 # define NL_PRODUCT_SOLUTION_EMBEDDEDSERVER 0x00000038
88 # define NL_PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE 0x00000039
89 # define NL_PRODUCT_PROFESSIONAL_EMBEDDED 0x0000003A
90 # define NL_PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT 0x0000003B
91 # define NL_PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL 0x0000003C
92 # define NL_PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC 0x0000003D
93 # define NL_PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC 0x0000003E
94 # define NL_PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE 0x0000003F
95 # define NL_PRODUCT_CLUSTER_SERVER_V 0x00000040
96 # define NL_PRODUCT_EMBEDDED 0x00000041
97 # define NL_PRODUCT_STARTER_E 0x00000042
98 # define NL_PRODUCT_HOME_BASIC_E 0x00000043
99 # define NL_PRODUCT_HOME_PREMIUM_E 0x00000044
100 # define NL_PRODUCT_PROFESSIONAL_E 0x00000045
101 # define NL_PRODUCT_ENTERPRISE_E 0x00000046
102 # define NL_PRODUCT_ULTIMATE_E 0x00000047
103 # define NL_PRODUCT_ENTERPRISE_EVALUATION 0x00000048
104 # define NL_PRODUCT_MULTIPOINT_STANDARD_SERVER 0x0000004C
105 # define NL_PRODUCT_MULTIPOINT_PREMIUM_SERVER 0x0000004D
106 # define NL_PRODUCT_STANDARD_EVALUATION_SERVER 0x0000004F
107 # define NL_PRODUCT_DATACENTER_EVALUATION_SERVER 0x00000050
108 # define NL_PRODUCT_ENTERPRISE_N_EVALUATION 0x00000054
109 # define NL_PRODUCT_EMBEDDED_AUTOMOTIVE 0x00000055
110 # define NL_PRODUCT_EMBEDDED_INDUSTRY_A 0x00000056
111 # define NL_PRODUCT_THINPC 0x00000057
112 # define NL_PRODUCT_EMBEDDED_A 0x00000058
113 # define NL_PRODUCT_EMBEDDED_INDUSTRY 0x00000059
114 # define NL_PRODUCT_EMBEDDED_E 0x0000005A
115 # define NL_PRODUCT_EMBEDDED_INDUSTRY_E 0x0000005B
116 # define NL_PRODUCT_EMBEDDED_INDUSTRY_A_E 0x0000005C
117 # define NL_PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER 0x0000005F
118 # define NL_PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER 0x00000060
119 # define NL_PRODUCT_CORE_ARM 0x00000061
120 # define NL_PRODUCT_CORE_N 0x00000062
121 # define NL_PRODUCT_CORE_COUNTRYSPECIFIC 0x00000063
122 # define NL_PRODUCT_CORE_SINGLELANGUAGE 0x00000064
123 # define NL_PRODUCT_CORE 0x00000065
124 # define NL_PRODUCT_PROFESSIONAL_WMC 0x00000067
125 # define NL_PRODUCT_MOBILE_CORE 0x00000068
126 # define NL_PRODUCT_EMBEDDED_INDUSTRY_EVAL 0x00000069
127 # define NL_PRODUCT_EMBEDDED_INDUSTRY_E_EVAL 0x0000006A
128 # define NL_PRODUCT_EMBEDDED_EVAL 0x0000006B
129 # define NL_PRODUCT_EMBEDDED_E_EVAL 0x0000006C
130 # define NL_PRODUCT_CORE_SERVER 0x0000006D
131 # define NL_PRODUCT_CLOUD_STORAGE_SERVER 0x0000006E
132 # define NL_PRODUCT_CORE_CONNECTED 0x0000006F
133 # define NL_PRODUCT_PROFESSIONAL_STUDENT 0x00000070
134 # define NL_PRODUCT_CORE_CONNECTED_N 0x00000071
135 # define NL_PRODUCT_PROFESSIONAL_STUDENT_N 0x00000072
136 # define NL_PRODUCT_CORE_CONNECTED_SINGLELANGUAGE 0x00000073
137 # define NL_PRODUCT_CORE_CONNECTED_COUNTRYSPECIFIC 0x00000074
138 # define NL_PRODUCT_CONNECTED_CAR 0x00000075
139 # define NL_PRODUCT_INDUSTRY_HANDHELD 0x00000076
140 # define NL_PRODUCT_PPI_PRO 0x00000077
141 # define NL_PRODUCT_ARM64_SERVER 0x00000078
142 # define NL_PRODUCT_EDUCATION 0x00000079
143 # define NL_PRODUCT_EDUCATION_N 0x0000007A
144 # define NL_PRODUCT_IOTUAP 0x0000007B
145 # define NL_PRODUCT_CLOUD_HOST_INFRASTRUCTURE_SERVER 0x0000007C
146 # define NL_PRODUCT_ENTERPRISE_S 0x0000007D
147 # define NL_PRODUCT_ENTERPRISE_S_N 0x0000007E
148 # define NL_PRODUCT_PROFESSIONAL_S 0x0000007F
149 # define NL_PRODUCT_PROFESSIONAL_S_N 0x00000080
150 # define NL_PRODUCT_ENTERPRISE_S_EVALUATION 0x00000081
151 # define NL_PRODUCT_ENTERPRISE_S_N_EVALUATION 0x00000082
152 # define NL_PRODUCT_HOLOGRAPHIC 0x00000087
153 # define NL_PRODUCT_PRO_SINGLE_LANGUAGE 0x0000008A
154 # define NL_PRODUCT_PRO_CHINA 0x0000008B
155 # define NL_PRODUCT_ENTERPRISE_SUBSCRIPTION 0x0000008C
156 # define NL_PRODUCT_ENTERPRISE_SUBSCRIPTION_N 0x0000008D
157 # define NL_PRODUCT_DATACENTER_NANO_SERVER 0x0000008F
158 # define NL_PRODUCT_STANDARD_NANO_SERVER 0x00000090
159 # define NL_PRODUCT_DATACENTER_A_SERVER_CORE 0x00000091
160 # define NL_PRODUCT_STANDARD_A_SERVER_CORE 0x00000092
161 # define NL_PRODUCT_DATACENTER_WS_SERVER_CORE 0x00000093
162 # define NL_PRODUCT_STANDARD_WS_SERVER_CORE 0x00000094
163 # define NL_PRODUCT_UTILITY_VM 0x00000095
164 # define NL_PRODUCT_DATACENTER_EVALUATION_SERVER_CORE 0x0000009F
165 # define NL_PRODUCT_STANDARD_EVALUATION_SERVER_CORE 0x000000A0
166 # define NL_PRODUCT_PRO_WORKSTATION 0x000000A1
167 # define NL_PRODUCT_PRO_WORKSTATION_N 0x000000A2
168 # define NL_PRODUCT_PRO_FOR_EDUCATION 0x000000A4
169 # define NL_PRODUCT_PRO_FOR_EDUCATION_N 0x000000A5
170 # define NL_PRODUCT_AZURE_SERVER_CORE 0x000000A8
171 # define NL_PRODUCT_AZURE_NANO_SERVER 0x000000A9
172 # define NL_PRODUCT_ENTERPRISEG 0x000000AB
173 # define NL_PRODUCT_ENTERPRISEGN 0x000000AC
174 # define NL_PRODUCT_SERVERRDSH 0x000000AF
175 # define NL_PRODUCT_CLOUD 0x000000B2
176 # define NL_PRODUCT_CLOUDN 0x000000B3
177 # define NL_PRODUCT_UNLICENSED 0xABCDABCD
180 # include <sys/types.h>
181 # include <sys/stat.h>
187 # define nlcpuid(regs, idx) __cpuid(idx, regs[0], regs[1], regs[2], regs[3])
188 # endif // NL_CPU_INTEL
190 # include <sys/mount.h>
191 # include <sys/sysctl.h>
193 # include <sys/vfs.h>
195 #endif // NL_OS_WINDOWS
197 #include "nel/misc/system_info.h"
198 #include "nel/misc/command.h"
199 #include "nel/misc/variable.h"
204 #define new DEBUG_NEW
210 static string
getCpuInfo(const string
&colname
)
215 int fd
= open("/proc/cpuinfo", O_RDONLY
);
218 nlwarning ("SI: Can't open /proc/cpuinfo: %s", strerror (errno
));
224 uint32 len
= read(fd
, buffer
, sizeof(buffer
)-1);
228 vector
<string
> splitted
;
229 explode(string(buffer
), string("\n"), splitted
, true);
233 for(uint32 i
= 0; i
< splitted
.size(); i
++)
235 vector
<string
> sline
;
236 explode(splitted
[i
], string(":"), sline
, true);
237 if(sline
.size() == 2 && trim(sline
[0]) == colname
)
246 nlwarning ("SI: Can't find the colname '%s' in /proc/cpuinfo", colname
.c_str());
250 // return the value of the colname in bytes from /proc/meminfo
251 static uint64
getSystemMemory (const string
&colname
)
256 int fd
= open("/proc/meminfo", O_RDONLY
);
259 nlwarning ("SI: Can't open /proc/meminfo: %s", strerror (errno
));
265 uint32 len
= read(fd
, buffer
, sizeof(buffer
)-1);
269 vector
<string
> splitted
;
270 explode(string(buffer
), string("\n"), splitted
, true);
272 for(uint32 i
= 0; i
< splitted
.size(); i
++)
274 vector
<string
> sline
;
275 explode(splitted
[i
], string(" "), sline
, true);
276 if(sline
.size() == 3 && sline
[0] == colname
)
278 uint64 val
= atoiInt64(sline
[1].c_str());
279 if(sline
[2] == "kB") val
*= 1024;
284 nlwarning ("SI: Can't find the colname '%s' in /proc/meminfo", colname
.c_str());
290 static sint32
getsysctlnum(const string
&name
)
293 size_t len
= sizeof(value
);
294 if(sysctlbyname(name
.c_str(), &value
, &len
, NULL
, 0) != 0)
296 nlwarning("SI: Can't get '%s' from sysctl: %s", name
.c_str(), strerror (errno
));
301 static sint64
getsysctlnum64(const string
&name
)
304 size_t len
= sizeof(value
);
305 if(sysctlbyname(name
.c_str(), &value
, &len
, NULL
, 0) != 0)
307 nlwarning("SI: Can't get '%s' from sysctl: %s", name
.c_str(), strerror (errno
));
312 static string
getsysctlstr(const string
&name
)
314 string
value("Unknown");
317 if(sysctlbyname(name
.c_str(), NULL
, &len
, NULL
, 0) == 0)
319 p
= (char*)malloc(len
);
320 if(sysctlbyname(name
.c_str(), p
, &len
, NULL
, 0) == 0)
326 nlwarning("SI: Can't get '%s' from sysctl: %s", name
.c_str(), strerror (errno
));
332 nlwarning("SI: Can't get '%s' from sysctl: %s", name
.c_str(), strerror (errno
));
338 string
CSystemInfo::getOS()
340 string OSString
= "Unknown";
344 typedef void (WINAPI
*PGNSI
)(LPSYSTEM_INFO
);
345 typedef BOOL (WINAPI
*PGetProductInfo
)(DWORD
, DWORD
, DWORD
, DWORD
, PDWORD
);
346 typedef LONG (WINAPI
* PRtlGetVersion
)(OSVERSIONINFOEXA
*);
348 const int BUFSIZE
= 80;
350 // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
351 // If that fails, try using the OSVERSIONINFO structure.
354 ZeroMemory(&si
, sizeof(SYSTEM_INFO
));
356 // RtlGetVersion always returns the right version
357 HMODULE hNtDll
= GetModuleHandleA("ntdll.dll");
358 PRtlGetVersion pRtlGetVersion
= (PRtlGetVersion
)GetProcAddress(hNtDll
, "RtlGetVersion");
360 BOOL bOsVersionInfoEx
= 0;
362 // init OSVERSIONINFOEXA
363 OSVERSIONINFOEXA osvi
;
364 ZeroMemory(&osvi
, sizeof(osvi
));
365 osvi
.dwOSVersionInfoSize
= sizeof(osvi
);
370 bOsVersionInfoEx
= pRtlGetVersion(&osvi
) == 0;
373 if (!bOsVersionInfoEx
)
375 // fall back to GetVersionExA
376 bOsVersionInfoEx
= GetVersionExA ((OSVERSIONINFOA
*) &osvi
);
379 if (!bOsVersionInfoEx
)
381 // fall back to GetVersionA struct
382 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
383 if (! GetVersionExA ( (OSVERSIONINFOA
*) &osvi
) )
384 return OSString
+" Can't GetVersionEx()";
387 // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
389 PGNSI pGNSI
= (PGNSI
) GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetNativeSystemInfo");
396 // Test for the Windows NT product family
397 if (VER_PLATFORM_WIN32_NT
== osvi
.dwPlatformId
&& osvi
.dwMajorVersion
> 4)
399 OSString
= "Microsoft";
401 if (osvi
.dwMajorVersion
> 10)
403 OSString
+= " Windows (not released)";
405 else if (osvi
.dwMajorVersion
== 10)
407 OSString
+= " Windows 10";
409 else if (osvi
.dwMajorVersion
== 6)
411 if (osvi
.dwMinorVersion
== 3)
413 if (osvi
.wProductType
== VER_NT_WORKSTATION
)
414 OSString
+= " Windows 8.1";
416 OSString
+= " Windows Server 2012 R2";
418 else if (osvi
.dwMinorVersion
== 2)
420 if (osvi
.wProductType
== VER_NT_WORKSTATION
)
421 OSString
+= " Windows 8";
423 OSString
+= " Windows Server 2012";
425 else if (osvi
.dwMinorVersion
== 1)
427 if (osvi
.wProductType
== VER_NT_WORKSTATION
)
428 OSString
+= " Windows 7";
430 OSString
+= " Windows Server 2008 R2";
432 else if (osvi
.dwMinorVersion
== 0)
434 if (osvi
.wProductType
== VER_NT_WORKSTATION
)
435 OSString
+= " Windows Vista";
437 OSString
+= " Windows Server 2008";
441 OSString
+= " Windows (unknown)";
444 else if (osvi
.dwMajorVersion
== 5)
446 if (osvi
.dwMinorVersion
== 2)
448 if (GetSystemMetrics(89 /* SM_SERVERR2 */))
449 OSString
+= " Windows Server 2003 R2";
450 #ifdef VER_SUITE_STORAGE_SERVER
451 else if (osvi
.wSuiteMask
== VER_SUITE_STORAGE_SERVER
)
452 OSString
+= " Windows Storage Server 2003";
454 #ifdef VER_SUITE_WH_SERVER
455 else if (osvi
.wSuiteMask
== VER_SUITE_WH_SERVER
)
456 OSString
+= " Windows Home Server";
458 else if (osvi
.wProductType
== VER_NT_WORKSTATION
&&
459 si
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
)
460 OSString
+= " Windows XP Professional x64 Edition";
462 OSString
+= " Windows Server 2003";
464 // Test for the server type.
465 if (osvi
.wProductType
!= VER_NT_WORKSTATION
)
467 if (si
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_IA64
)
469 if (osvi
.wSuiteMask
& VER_SUITE_DATACENTER
)
470 OSString
+= " Datacenter Edition for Itanium-based Systems";
471 else if (osvi
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
472 OSString
+= " Enterprise Edition for Itanium-based Systems";
475 else if (si
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
)
477 if (osvi
.wSuiteMask
& VER_SUITE_DATACENTER
)
478 OSString
+= " Datacenter x64 Edition";
479 else if (osvi
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
480 OSString
+= " Enterprise x64 Edition";
482 OSString
+= " Standard x64 Edition";
487 if (osvi
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
488 OSString
+= " Enterprise Edition";
489 #ifdef VER_SUITE_DATACENTER
490 else if (osvi
.wSuiteMask
& VER_SUITE_DATACENTER
)
491 OSString
+= " Datacenter Edition";
493 #ifdef VER_SUITE_BLADE
494 else if (osvi
.wSuiteMask
& VER_SUITE_BLADE
)
495 OSString
+= " Web Edition";
497 #ifdef VER_SUITE_COMPUTE_SERVER
498 else if (osvi
.wSuiteMask
& VER_SUITE_COMPUTE_SERVER
)
499 OSString
+= " Compute Cluster Edition";
502 OSString
+= " Standard Edition";
506 else if (osvi
.dwMinorVersion
== 1)
508 OSString
+= " Windows XP";
509 if (osvi
.wSuiteMask
& VER_SUITE_PERSONAL
)
510 OSString
+= " Home Edition";
512 OSString
+= " Professional";
514 else if (osvi
.dwMinorVersion
== 0)
516 OSString
+= " Windows 2000";
518 if (osvi
.wProductType
== VER_NT_WORKSTATION
)
520 OSString
+= " Professional";
524 if (osvi
.wSuiteMask
& VER_SUITE_DATACENTER
)
525 OSString
+= " Datacenter Server";
526 else if (osvi
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
527 OSString
+= " Advanced Server";
529 OSString
+= " Server";
534 OSString
+= " Unknown Windows";
537 else if (osvi
.dwMajorVersion
<= 4)
539 OSString
+= " Windows NT";
541 // Test for specific product on Windows NT 4.0 SP6 and later.
542 if (bOsVersionInfoEx
)
544 // Test for the workstation type.
545 if (osvi
.wProductType
== VER_NT_WORKSTATION
)
547 if (osvi
.dwMajorVersion
== 4 )
548 OSString
+= " Workstation 4.0";
549 else if (osvi
.wSuiteMask
& VER_SUITE_PERSONAL
)
550 OSString
+= " Home Edition";
552 OSString
+= " Professional";
555 // Test for the server type.
556 else if (osvi
.wProductType
== VER_NT_SERVER
)
558 if (osvi
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
559 OSString
+= " Server 4.0 Enterprise Edition";
561 OSString
+= " Server 4.0";
564 else // Test for specific product on Windows NT 4.0 SP5 and earlier
567 char szProductType
[BUFSIZE
];
568 DWORD dwBufLen
=BUFSIZE
;
571 lRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE
, &hKey
);
572 if (lRet
!= ERROR_SUCCESS
)
573 return OSString
+ " Can't RegOpenKeyEx";
575 lRet
= RegQueryValueExA(hKey
, "ProductType", NULL
, NULL
, (LPBYTE
) szProductType
, &dwBufLen
);
576 if ((lRet
!= ERROR_SUCCESS
) || (dwBufLen
> BUFSIZE
))
577 return OSString
+ " Can't ReQueryValueEx";
581 if (lstrcmpiA("WINNT", szProductType
) == 0)
582 OSString
+= " Workstation";
584 if (lstrcmpiA("LANMANNT", szProductType
) == 0)
585 OSString
+= " Server";
587 if (lstrcmpiA("SERVERNT", szProductType
) == 0)
588 OSString
+= " Advanced Server";
592 PGetProductInfo pGetProductInfo
= (PGetProductInfo
)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetProductInfo");
596 if (pGetProductInfo
&& pGetProductInfo(osvi
.dwMajorVersion
, osvi
.dwMinorVersion
, osvi
.wServicePackMajor
, osvi
.wServicePackMinor
, &dwType
))
598 // Test for the specific product family.
599 // see https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms724358(v=vs.85).aspx
602 case NL_PRODUCT_UNLICENSED
:
603 OSString
+= " Unlicensed";
605 case NL_PRODUCT_ULTIMATE
:
606 OSString
+= " Ultimate";
608 case NL_PRODUCT_HOME_BASIC
:
609 OSString
+= " Home Basic";
611 case NL_PRODUCT_HOME_PREMIUM
:
612 OSString
+= " Home Premium";
614 case NL_PRODUCT_ENTERPRISE
:
615 OSString
+= " Enterprise";
617 case NL_PRODUCT_HOME_BASIC_N
:
618 OSString
+= " Home Basic N";
620 case NL_PRODUCT_BUSINESS
:
621 OSString
+= " Business";
623 case NL_PRODUCT_STANDARD_SERVER
:
624 OSString
+= " Server Standard";
626 case NL_PRODUCT_DATACENTER_SERVER
:
627 OSString
+= " Server Datacenter (full installation)";
629 case NL_PRODUCT_SMALLBUSINESS_SERVER
:
630 OSString
+= " Small Business Server";
632 case NL_PRODUCT_ENTERPRISE_SERVER
:
633 OSString
+= " Server Enterprise (full installation)";
635 case NL_PRODUCT_STARTER
:
636 OSString
+= " Starter";
638 case NL_PRODUCT_DATACENTER_SERVER_CORE
:
639 OSString
+= " Server Datacenter (core installation)";
641 case NL_PRODUCT_STANDARD_SERVER_CORE
:
642 OSString
+= " Server Standard (core installation)";
644 case NL_PRODUCT_ENTERPRISE_SERVER_CORE
:
645 OSString
+= " Server Enterprise (core installation)";
647 case NL_PRODUCT_ENTERPRISE_SERVER_IA64
:
648 OSString
+= " Server Enterprise for Itanium-based Systems";
650 case NL_PRODUCT_BUSINESS_N
:
651 OSString
+= " Business N";
653 case NL_PRODUCT_WEB_SERVER
:
654 OSString
+= " Web Server (full installation)";
656 case NL_PRODUCT_CLUSTER_SERVER
:
657 OSString
+= " Server Hyper Core";
659 case NL_PRODUCT_HOME_SERVER
:
660 OSString
+= " Home Server";
662 case NL_PRODUCT_STORAGE_EXPRESS_SERVER
:
663 OSString
+= " Storage Server Express";
665 case NL_PRODUCT_STORAGE_STANDARD_SERVER
:
666 OSString
+= " Storage Server Standard";
668 case NL_PRODUCT_STORAGE_WORKGROUP_SERVER
:
669 OSString
+= " Storage Server Workgroup";
671 case NL_PRODUCT_STORAGE_ENTERPRISE_SERVER
:
672 OSString
+= " Storage Server Enterprise";
674 case NL_PRODUCT_SERVER_FOR_SMALLBUSINESS
:
675 OSString
+= " Essential Server Solutions";
677 case NL_PRODUCT_SMALLBUSINESS_SERVER_PREMIUM
:
678 OSString
+= " Small Business Server Premium";
680 case NL_PRODUCT_HOME_PREMIUM_N
:
681 OSString
+= " Home Premium N";
683 case NL_PRODUCT_ENTERPRISE_N
:
684 OSString
+= " Enterprise N";
686 case NL_PRODUCT_ULTIMATE_N
:
687 OSString
+= " Ultimate N";
689 case NL_PRODUCT_WEB_SERVER_CORE
:
690 OSString
+= " Web Server (core installation)";
692 case NL_PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT
:
693 OSString
+= " Essential Business Server Management Server";
695 case NL_PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY
:
696 OSString
+= " Essential Business Server Security Server";
698 case NL_PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING
:
699 OSString
+= " Essential Business Server Messaging Server";
701 case NL_PRODUCT_SERVER_FOUNDATION
:
702 OSString
+= " Server Foundation";
704 case NL_PRODUCT_HOME_PREMIUM_SERVER
:
705 OSString
+= " Home Server";
707 case NL_PRODUCT_SERVER_FOR_SMALLBUSINESS_V
:
708 OSString
+= " Server without Hyper-V for Windows Essential Server Solutions";
710 case NL_PRODUCT_STANDARD_SERVER_V
:
711 OSString
+= " Server Standard without Hyper-V";
713 case NL_PRODUCT_DATACENTER_SERVER_V
:
714 OSString
+= " Server Datacenter without Hyper-V (full installation)";
716 case NL_PRODUCT_ENTERPRISE_SERVER_V
:
717 OSString
+= " Enterprise without Hyper-V (full installation)";
719 case NL_PRODUCT_DATACENTER_SERVER_CORE_V
:
720 OSString
+= " Datacenter without Hyper-V (core installation)";
722 case NL_PRODUCT_STANDARD_SERVER_CORE_V
:
723 OSString
+= " Standard without Hyper-V (core installation)";
725 case NL_PRODUCT_ENTERPRISE_SERVER_CORE_V
:
726 OSString
+= " Enterprise without Hyper-V (core installation)";
728 case NL_PRODUCT_HYPERV
:
729 OSString
+= " Hyper-V Server";
731 case NL_PRODUCT_STORAGE_EXPRESS_SERVER_CORE
:
732 OSString
+= " Storage Server Express (core installation)";
734 case NL_PRODUCT_STORAGE_STANDARD_SERVER_CORE
:
735 OSString
+= " Storage Server Standard (core installation)";
737 case NL_PRODUCT_STORAGE_WORKGROUP_SERVER_CORE
:
738 OSString
+= " Storage Server Workgroup (core installation)";
740 case NL_PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE
:
741 OSString
+= " Storage Server Enterprise (core installation)";
743 case NL_PRODUCT_STARTER_N
:
744 OSString
+= " Starter N Edition";
746 case NL_PRODUCT_PROFESSIONAL
:
747 OSString
+= " Professional";
749 case NL_PRODUCT_PROFESSIONAL_N
:
750 OSString
+= " Professional N";
752 case NL_PRODUCT_SB_SOLUTION_SERVER
:
753 OSString
+= " Small Business Server";
755 case NL_PRODUCT_SERVER_FOR_SB_SOLUTIONS
:
756 OSString
+= " Server For Small Business Solutions";
758 case NL_PRODUCT_STANDARD_SERVER_SOLUTIONS
:
759 OSString
+= " Server Solutions Premium";
761 case NL_PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE
:
762 OSString
+= " Server Solutions Premium (core installation)";
764 case NL_PRODUCT_SB_SOLUTION_SERVER_EM
:
765 OSString
+= " Server For Small Business Solutions EM";
767 case NL_PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM
:
768 OSString
+= " Server For Small Business Solutions EM";
770 case NL_PRODUCT_SOLUTION_EMBEDDEDSERVER
:
771 OSString
+= " Solution Embedded Server (full installation)";
773 case NL_PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE
:
774 OSString
+= " Solution Embedded Server (core installation)";
776 case NL_PRODUCT_PROFESSIONAL_EMBEDDED
:
777 OSString
+= " Professional Embedded";
779 case NL_PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT
:
780 OSString
+= " Essential Server Solution Management";
782 case NL_PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL
:
783 OSString
+= " Essential Server Solution Additional";
785 case NL_PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC
:
786 OSString
+= " Essential Server Solution Management SVC";
788 case NL_PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC
:
789 OSString
+= " Essential Server Solution Additional SVC";
791 case NL_PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE
:
792 OSString
+= " Small Business Server Premium (core installation)";
794 case NL_PRODUCT_CLUSTER_SERVER_V
:
795 OSString
+= " Server Hyper Core V";
797 case NL_PRODUCT_EMBEDDED
:
798 OSString
+= " Embedded";
800 case NL_PRODUCT_STARTER_E
:
801 OSString
+= " Starter E";
803 case NL_PRODUCT_HOME_BASIC_E
:
804 OSString
+= " Home Basic E";
806 case NL_PRODUCT_HOME_PREMIUM_E
:
807 OSString
+= " Home Premium E";
809 case NL_PRODUCT_PROFESSIONAL_E
:
810 OSString
+= " Professional E";
812 case NL_PRODUCT_ENTERPRISE_E
:
813 OSString
+= " Enterprise E";
815 case NL_PRODUCT_ULTIMATE_E
:
816 OSString
+= " Ultimate E";
818 case NL_PRODUCT_ENTERPRISE_EVALUATION
:
819 OSString
+= " Enterprise Evaluation";
821 // nothing from 0x49 to 0x4b
822 case NL_PRODUCT_MULTIPOINT_STANDARD_SERVER
:
823 OSString
+= " MultiPoint Server Standard (full installation)";
825 case NL_PRODUCT_MULTIPOINT_PREMIUM_SERVER
:
826 OSString
+= " MultiPoint Server Premium (full installation)";
828 case NL_PRODUCT_STANDARD_EVALUATION_SERVER
:
829 OSString
+= " Server Standard (evaluation installation)";
831 case NL_PRODUCT_DATACENTER_EVALUATION_SERVER
:
832 OSString
+= " Server Datacenter (evaluation installation)";
834 // nothing from 0x51 to 0x53
835 case NL_PRODUCT_ENTERPRISE_N_EVALUATION
:
836 OSString
+= " Enterprise N (evaluation installation)";
838 case NL_PRODUCT_EMBEDDED_AUTOMOTIVE
:
839 OSString
+= " Embedded Automotive";
841 case NL_PRODUCT_EMBEDDED_INDUSTRY_A
:
842 OSString
+= " Embedded Industry A";
844 case NL_PRODUCT_THINPC
:
845 OSString
+= " Thin PC";
847 case NL_PRODUCT_EMBEDDED_A
:
848 OSString
+= " Embedded A";
850 case NL_PRODUCT_EMBEDDED_INDUSTRY
:
851 OSString
+= " Embedded Industry";
853 case NL_PRODUCT_EMBEDDED_E
:
854 OSString
+= " Embedded E";
856 case NL_PRODUCT_EMBEDDED_INDUSTRY_E
:
857 OSString
+= " Embedded Industry E";
859 case NL_PRODUCT_EMBEDDED_INDUSTRY_A_E
:
860 OSString
+= " Embedded Industry A E";
862 // nothing from 0x5d to 0x5e
863 case NL_PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER
:
864 OSString
+= " Storage Server Workgroup (evaluation installation)";
866 case NL_PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER
:
867 OSString
+= " Storage Server Standard (evaluation installation)";
869 case NL_PRODUCT_CORE_ARM
:
872 case NL_PRODUCT_CORE_N
:
873 OSString
+= " Home N";
875 case NL_PRODUCT_CORE_COUNTRYSPECIFIC
:
876 OSString
+= " Home China";
878 case NL_PRODUCT_CORE_SINGLELANGUAGE
:
879 OSString
+= " Home Single Language";
881 case NL_PRODUCT_CORE
:
885 case NL_PRODUCT_PROFESSIONAL_WMC
:
886 OSString
+= " Professional with Media Center";
888 case NL_PRODUCT_MOBILE_CORE
:
889 OSString
+= " Mobile";
891 case NL_PRODUCT_EMBEDDED_INDUSTRY_EVAL
:
892 OSString
+= " Embedded Industry (evaluation installation)";
894 case NL_PRODUCT_EMBEDDED_INDUSTRY_E_EVAL
:
895 OSString
+= " Embedded Industry E (evaluation installation)";
897 case NL_PRODUCT_EMBEDDED_EVAL
:
898 OSString
+= " Embedded (evaluation installation)";
900 case NL_PRODUCT_EMBEDDED_E_EVAL
:
901 OSString
+= " Embedded E (evaluation installation)";
903 case NL_PRODUCT_CORE_SERVER
:
904 OSString
+= " Server";
906 case NL_PRODUCT_CLOUD_STORAGE_SERVER
:
907 OSString
+= " Server Could Storage";
909 case NL_PRODUCT_CORE_CONNECTED
:
910 OSString
+= " Home Connected";
912 case NL_PRODUCT_PROFESSIONAL_STUDENT
:
913 OSString
+= " Professional Student";
915 case NL_PRODUCT_CORE_CONNECTED_N
:
916 OSString
+= " Home N Connected";
918 case NL_PRODUCT_PROFESSIONAL_STUDENT_N
:
919 OSString
+= " Professional Student N";
921 case NL_PRODUCT_CORE_CONNECTED_SINGLELANGUAGE
:
922 OSString
+= " Home Single Language Connected";
924 case NL_PRODUCT_CORE_CONNECTED_COUNTRYSPECIFIC
:
925 OSString
+= " Home China Connected";
927 case NL_PRODUCT_CONNECTED_CAR
:
928 OSString
+= " Connected Car";
930 case NL_PRODUCT_INDUSTRY_HANDHELD
:
931 OSString
+= " Industry Handheld";
933 case NL_PRODUCT_PPI_PRO
:
934 OSString
+= " PPI Pro";
936 case NL_PRODUCT_ARM64_SERVER
:
937 OSString
+= " ARM64 Server";
939 case NL_PRODUCT_EDUCATION
:
940 OSString
+= " Education";
942 case NL_PRODUCT_EDUCATION_N
:
943 OSString
+= " Education N";
945 case NL_PRODUCT_IOTUAP
:
946 OSString
+= " IoT Core";
948 case NL_PRODUCT_CLOUD_HOST_INFRASTRUCTURE_SERVER
:
949 OSString
+= " Cloud Host Infrastructure Server";
951 case NL_PRODUCT_ENTERPRISE_S
:
952 OSString
+= " Product Enterprise S";
954 case NL_PRODUCT_ENTERPRISE_S_N
:
955 OSString
+= " Enterprise S N";
957 case NL_PRODUCT_PROFESSIONAL_S
:
958 OSString
+= " Professional S";
960 case NL_PRODUCT_PROFESSIONAL_S_N
:
961 OSString
+= " Professional S N";
963 case NL_PRODUCT_ENTERPRISE_S_EVALUATION
:
964 OSString
+= " Enterprise S Evaluation";
966 case NL_PRODUCT_ENTERPRISE_S_N_EVALUATION
:
967 OSString
+= " Enterprise S N Evaluation";
969 // nothing from x83 to 0x86
970 case NL_PRODUCT_HOLOGRAPHIC
:
971 OSString
+= " Holographic";
973 // nothing from x88 to 0x89
974 case NL_PRODUCT_PRO_SINGLE_LANGUAGE
:
975 OSString
+= " Pro Single Language";
977 case NL_PRODUCT_PRO_CHINA
:
978 OSString
+= " Pro China";
980 case NL_PRODUCT_ENTERPRISE_SUBSCRIPTION
:
981 OSString
+= " Enterprise Subscription";
983 case NL_PRODUCT_ENTERPRISE_SUBSCRIPTION_N
:
984 OSString
+= " Enterprise Subscription N";
987 case NL_PRODUCT_DATACENTER_NANO_SERVER
:
988 OSString
+= " Datacenter Nano Server";
990 case NL_PRODUCT_STANDARD_NANO_SERVER
:
991 OSString
+= " Standard Nano Server";
993 case NL_PRODUCT_DATACENTER_A_SERVER_CORE
:
994 OSString
+= " Datacenter A Server Core";
996 case NL_PRODUCT_STANDARD_A_SERVER_CORE
:
997 OSString
+= " Standard A Server Core";
999 case NL_PRODUCT_DATACENTER_WS_SERVER_CORE
:
1000 OSString
+= " Datacenter WS Server Core";
1002 case NL_PRODUCT_STANDARD_WS_SERVER_CORE
:
1003 OSString
+= " Standard WS Server Core";
1005 case NL_PRODUCT_UTILITY_VM
:
1006 OSString
+= " Utility VM";
1008 // nothing from 0x96 to 0x9e
1009 case NL_PRODUCT_DATACENTER_EVALUATION_SERVER_CORE
:
1010 OSString
+= " Datacenter_evaluation_server_core";
1012 case NL_PRODUCT_STANDARD_EVALUATION_SERVER_CORE
:
1013 OSString
+= " Standard Evaluation Server Core";
1015 case NL_PRODUCT_PRO_WORKSTATION
:
1016 OSString
+= " Pro Workstation";
1018 case NL_PRODUCT_PRO_WORKSTATION_N
:
1019 OSString
+= " Pro Workstation N";
1022 case NL_PRODUCT_PRO_FOR_EDUCATION
:
1023 OSString
+= " Pro for Education";
1025 case NL_PRODUCT_PRO_FOR_EDUCATION_N
:
1026 OSString
+= " Pro for Education N";
1028 // nothing from 0xa6 to 0xa7
1029 case NL_PRODUCT_AZURE_SERVER_CORE
:
1030 OSString
+= " Azure Server Core";
1032 case NL_PRODUCT_AZURE_NANO_SERVER
:
1033 OSString
+= " Azure Nano Server";
1036 case NL_PRODUCT_ENTERPRISEG
:
1037 OSString
+= " Enterprise G";
1039 case NL_PRODUCT_ENTERPRISEGN
:
1040 OSString
+= " Enterprise GN";
1042 // nothing from 0xad to 0xae
1043 case NL_PRODUCT_SERVERRDSH
:
1044 OSString
+= " Server RDSH";
1046 // nothing from 0xb0 to 0xb1
1047 case NL_PRODUCT_CLOUD
:
1048 OSString
+= " Cloud";
1050 case NL_PRODUCT_CLOUDN
:
1051 OSString
+= " Cloud N";
1055 OSString
+= toString(" Unknown Edition (0x%04x)", dwType
);
1059 if (si
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
)
1060 OSString
+= " 64-bit";
1061 else if (si
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_INTEL
)
1062 OSString
+= " 32-bit";
1064 std::string servicePack
;
1066 // special case for Windows NT 4.0
1067 if (osvi
.dwMajorVersion
== 4 && lstrcmpiA(osvi
.szCSDVersion
, "Service Pack 6") == 0 )
1072 // Test for SP6 versus SP6a.
1073 lRet
= RegOpenKeyExA( HKEY_LOCAL_MACHINE
, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009", 0, KEY_QUERY_VALUE
, &hKey
);
1074 if( lRet
== ERROR_SUCCESS
)
1075 servicePack
= "Service Pack 6a";
1076 else // Windows NT 4.0 prior to SP6a
1078 servicePack
= osvi
.szCSDVersion
;
1081 RegCloseKey( hKey
);
1083 else // Windows NT 3.51 and earlier or Windows 2000 and later
1085 servicePack
= osvi
.szCSDVersion
;
1088 // Include service pack (if any)
1089 if (!servicePack
.empty()) OSString
+= " " + servicePack
;
1091 // Include build number
1092 OSString
+= toString(" (Build %d)", osvi
.dwBuildNumber
& 0xFFFF);
1095 else if ( VER_PLATFORM_WIN32_WINDOWS
== osvi
.dwPlatformId
)
1097 OSString
= "Microsoft";
1099 if (osvi
.dwMajorVersion
== 4 && osvi
.dwMinorVersion
== 0)
1101 OSString
+= " Windows 95";
1102 if ( osvi
.szCSDVersion
[1] == 'C' || osvi
.szCSDVersion
[1] == 'B' )
1103 OSString
+= " OSR2";
1105 else if (osvi
.dwMajorVersion
== 4 && osvi
.dwMinorVersion
== 10)
1107 OSString
+= " Windows 98";
1108 if ( osvi
.szCSDVersion
[1] == 'A' )
1111 else if (osvi
.dwMajorVersion
== 4 && osvi
.dwMinorVersion
== 90)
1113 OSString
+= " Windows Millennium Edition";
1116 OSString
+= " Windows 9x";
1118 // Windows 3.1 with Win32s
1119 else if ( VER_PLATFORM_WIN32s
== osvi
.dwPlatformId
)
1121 OSString
= toString("Microsoft Windows %d.%d + Win32s", osvi
.dwMajorVersion
, osvi
.dwMinorVersion
);
1123 // Unknown Windows version
1126 OSString
= toString("Microsoft Windows %d.%d", osvi
.dwMajorVersion
, osvi
.dwMinorVersion
);
1129 OSString
+= toString( " (%d.%d %d)", osvi
.dwMajorVersion
, osvi
.dwMinorVersion
, osvi
.dwBuildNumber
& 0xFFFF);
1131 #elif defined NL_OS_MAC
1133 OSString
= getsysctlstr("kern.version");
1135 #elif defined NL_OS_UNIX
1137 int fd
= open("/proc/version", O_RDONLY
);
1140 nlwarning ("SI: Can't get OS from /proc/version: %s", strerror (errno
));
1144 char buffer
[4096+1];
1145 int len
= read(fd
, buffer
, sizeof(buffer
)-1);
1148 // remove the \n and set \0
1149 buffer
[len
-1] = '\0';
1154 #endif // NL_OS_UNIX
1159 string
CSystemInfo::getProc ()
1161 string ProcString
= "Unknown";
1163 #ifdef NL_OS_WINDOWS
1170 result
= ::RegOpenKeyExA (HKEY_LOCAL_MACHINE
, "Hardware\\Description\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE
, &hKey
);
1171 if (result
== ERROR_SUCCESS
)
1173 // get processor name
1175 result
= ::RegQueryValueExA (hKey
, "ProcessorNameString", NULL
, NULL
, (LPBYTE
)value
, &valueSize
);
1176 if (result
== ERROR_SUCCESS
)
1179 ProcString
= "UnknownProc";
1181 ProcString
+= " / ";
1183 // get processor identifier
1185 result
= ::RegQueryValueExA (hKey
, "Identifier", NULL
, NULL
, (LPBYTE
)value
, &valueSize
);
1186 if (result
== ERROR_SUCCESS
)
1187 ProcString
+= value
;
1189 ProcString
+= "UnknownIdentifier";
1191 ProcString
+= " / ";
1193 // get processor vendor
1195 result
= ::RegQueryValueExA (hKey
, "VendorIdentifier", NULL
, NULL
, (LPBYTE
)value
, &valueSize
);
1196 if (result
== ERROR_SUCCESS
)
1197 ProcString
+= value
;
1199 ProcString
+= "UnknownVendor";
1201 ProcString
+= " / ";
1203 // get processor frequency
1204 result
= ::RegQueryValueExA (hKey
, "~MHz", NULL
, NULL
, (LPBYTE
)value
, &valueSize
);
1205 if (result
== ERROR_SUCCESS
)
1207 uint32 freq
= *(int *)value
;
1208 // discard the low value (not enough significant)
1211 ProcString
+= toString("%uMHz", freq
);
1214 ProcString
+= "UnknownFreq";
1217 // Make sure to close the reg key
1220 // count the number of processor (max 8, in case this code don't work well)
1222 for(uint i
=1;i
<8;i
++)
1224 string tmp
= string("Hardware\\Description\\System\\CentralProcessor\\") + toString(i
);
1226 // try to open the key
1227 result
= ::RegOpenKeyExA (HKEY_LOCAL_MACHINE
, tmp
.c_str(), 0, KEY_QUERY_VALUE
, &hKey
);
1228 // Make sure to close the reg key
1231 if(result
== ERROR_SUCCESS
)
1236 ProcString
+= " / ";
1237 ProcString
+= toString(numProc
) + " Processors found";
1239 #elif defined NL_OS_MAC
1241 ProcString
= getsysctlstr("machdep.cpu.brand_string");
1242 ProcString
+= " / ";
1243 ProcString
+= getsysctlstr("hw.machine");
1244 ProcString
+= " Family " + toString(getsysctlnum("machdep.cpu.family"));
1245 ProcString
+= " Model " + toString(getsysctlnum("machdep.cpu.model"));
1246 ProcString
+= " Stepping " + toString(getsysctlnum("machdep.cpu.stepping"));
1247 ProcString
+= " / ";
1248 ProcString
+= getsysctlstr("machdep.cpu.vendor");
1249 ProcString
+= " / ";
1250 ProcString
+= toString(getsysctlnum64("hw.cpufrequency")/1000000)+"MHz";
1251 ProcString
+= " / ";
1252 ProcString
+= toString(getsysctlnum("hw.ncpu")) + " Processors found";
1254 #elif defined NL_OS_UNIX
1256 uint processors
= 0;
1257 if (fromString(getCpuInfo("processor"), processors
)) ++processors
;
1259 ProcString
= getCpuInfo("model name");
1260 ProcString
+= " / ?";
1261 ProcString
+= " Family " + getCpuInfo("cpu family");
1262 ProcString
+= " Model " + getCpuInfo("model");
1263 ProcString
+= " Stepping " + getCpuInfo("stepping");
1264 ProcString
+= " / ";
1265 ProcString
+= getCpuInfo("vendor_id");
1266 ProcString
+= " / ";
1267 ProcString
+= getCpuInfo("cpu MHz")+"MHz";
1268 ProcString
+= " / ";
1269 ProcString
+= toString("%u Processors found", processors
);
1273 // Remove beginning spaces
1274 ProcString
= ProcString
.substr (ProcString
.find_first_not_of (" "));
1279 uint64
CSystemInfo::getProcessorFrequency(bool quick
)
1281 static uint64 freq
= 0;
1283 static bool freqComputed
= false;
1284 if (freqComputed
) return freq
;
1288 TTicks bestNumTicks
= 0;
1289 uint64 bestNumCycles
= 0;
1291 const uint numSamples
= 5;
1292 const uint numLoops
= 50000000;
1294 volatile uint k
; // prevent optimization for the loop
1295 for(uint l
= 0; l
< numSamples
; ++l
)
1297 TTicks startTick
= NLMISC::CTime::getPerformanceTime();
1298 uint64 startCycle
= rdtsc();
1299 volatile uint dummy
= 0;
1300 for(k
= 0; k
< numLoops
; ++k
)
1304 numCycles
= rdtsc() - startCycle
;
1305 TTicks numTicks
= NLMISC::CTime::getPerformanceTime() - startTick
;
1306 if (numTicks
> bestNumTicks
)
1308 bestNumTicks
= numTicks
;
1309 bestNumCycles
= numCycles
;
1312 freq
= (uint64
) ((double) bestNumCycles
* 1 / CTime::ticksToSecond(bestNumTicks
));
1316 TTicks timeBefore
= NLMISC::CTime::getPerformanceTime();
1317 uint64 tickBefore
= rdtsc();
1319 TTicks timeAfter
= NLMISC::CTime::getPerformanceTime();
1320 TTicks tickAfter
= rdtsc();
1322 double timeDelta
= CTime::ticksToSecond(timeAfter
- timeBefore
);
1323 TTicks tickDelta
= tickAfter
- tickBefore
;
1325 freq
= (uint64
) ((double)tickDelta
/ timeDelta
);
1328 nlinfo ("SI: CSystemInfo: Processor frequency is %.0f MHz", (float)freq
/1000000.0);
1329 freqComputed
= true;
1330 #endif // NL_CPU_INTEL
1334 static bool DetectMMX()
1337 if (!CSystemInfo::hasCPUID()) return false; // cpuid not supported ...
1340 nlcpuid(CPUInfo
, 1);
1341 // check for bit 23 = MMX instruction set
1342 if (CPUInfo
[3] & 0x800000) return true;
1343 #endif // NL_CPU_INTEL
1349 static bool DetectSSE()
1352 if (!CSystemInfo::hasCPUID()) return false; // cpuid not supported ...
1355 nlcpuid(CPUInfo
, 1);
1357 if (CPUInfo
[3] & 0x2000000)
1359 // check OS support for SSE
1362 unsigned int tmp
= _mm_getcsr();
1363 nlunreferenced(tmp
);
1370 // printf("sse detected\n");
1374 #endif // NL_CPU_INTEL
1379 bool CSystemInfo::_HaveMMX
= DetectMMX ();
1380 bool CSystemInfo::_HaveSSE
= DetectSSE ();
1382 bool CSystemInfo::hasCPUID ()
1386 sint32 CPUInfo
[4] = {-1};
1387 nlcpuid(CPUInfo
, 0);
1388 if (CPUInfo
[3] != -1) result
= 1;
1396 uint32
CSystemInfo::getCPUID()
1403 nlcpuid(CPUInfo
, 1);
1406 #endif // NL_CPU_INTEL
1412 * Note: Not used in NeL probably in Ryzom closed source. Not translated in AT&T asm, I don't understand the aim of this method
1413 * Returns true if the CPU has HT, even if it is disabled. Maybe shoud count how many (virtual) core there is.
1415 bool CSystemInfo::hasHyperThreading()
1417 #ifdef NL_OS_WINDOWS
1422 // get vendor string from cpuid
1424 vendor_id
[31] = '\0';
1425 memset(vendor_id
, 0, sizeof(vendor_id
));
1426 nlcpuid(CPUInfo
, 0);
1427 memcpy(vendor_id
, &CPUInfo
[1], sizeof(sint32
));
1428 memcpy(vendor_id
+4, &CPUInfo
[3], sizeof(sint32
));
1429 memcpy(vendor_id
+8, &CPUInfo
[2], sizeof(sint32
));
1432 nlcpuid(CPUInfo
, 1);
1434 // pentium 4 or later processor?
1435 if ((((CPUInfo
[0] & 0xf00) == 0xf00) || (CPUInfo
[0] & 0xf00000)) &&
1436 strcmp(vendor_id
, "GenuineIntel") == 0)
1437 return (CPUInfo
[3] & 0x10000000)!=0; // Intel Processor Hyper-Threading
1444 bool CSystemInfo::isNT()
1446 #ifdef NL_OS_WINDOWS
1448 ver
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1450 return ver
.dwPlatformId
== VER_PLATFORM_WIN32_NT
;
1456 uint64
CSystemInfo::availableHDSpace (const string
&filename
)
1458 std::string path
= CFile::getPath(filename
);
1462 if (::statfs(path
.c_str(), &stfs
) != 0) return 0;
1464 return (uint64
)stfs
.f_bavail
* (uint64
)stfs
.f_bsize
;
1466 ULARGE_INTEGER freeSpace
= {0};
1467 BOOL bRes
= ::GetDiskFreeSpaceExW(nlUtf8ToWide(path
), &freeSpace
, NULL
, NULL
);
1468 if (!bRes
) return 0;
1470 return (uint64
)freeSpace
.QuadPart
;
1474 uint64
CSystemInfo::availablePhysicalMemory ()
1476 #ifdef NL_OS_WINDOWS
1478 GlobalMemoryStatusEx(&ms
);
1479 return ms
.ullAvailPhys
;
1480 #elif defined NL_OS_MAC
1481 return uint64(getsysctlnum64("hw.usermem"));
1482 #elif defined NL_OS_UNIX
1483 return getSystemMemory("MemFree:")+getSystemMemory("Buffers:")+getSystemMemory("Cached:");
1489 uint64
CSystemInfo::totalPhysicalMemory ()
1491 #ifdef NL_OS_WINDOWS
1493 GlobalMemoryStatusEx(&ms
);
1494 return ms
.ullTotalPhys
;
1495 #elif defined NL_OS_MAC
1496 return uint64(getsysctlnum64("hw.physmem"));
1497 #elif defined NL_OS_UNIX
1498 return getSystemMemory("MemTotal:");
1504 #ifndef NL_OS_WINDOWS
1505 static inline char *skipWS(const char *p
)
1507 while (isspace(*p
)) p
++;
1511 static inline char *skipToken(const char *p
)
1513 while (isspace(*p
)) p
++;
1514 while (*p
&& !isspace(*p
)) p
++;
1519 uint64
CSystemInfo::getAllocatedSystemMemory ()
1521 uint64 systemMemory
= 0;
1522 #ifdef NL_OS_WINDOWS
1523 // Get system memory information
1525 DWORD heapCount
= GetProcessHeaps (100, hHeap
);
1528 for (heap
= 0; heap
< heapCount
; heap
++)
1530 PROCESS_HEAP_ENTRY entry
;
1531 entry
.lpData
= NULL
;
1532 while (HeapWalk (hHeap
[heap
], &entry
))
1534 if (entry
.wFlags
& PROCESS_HEAP_ENTRY_BUSY
)
1536 systemMemory
+= entry
.cbData
+ entry
.cbOverhead
;
1541 #elif defined NL_OS_UNIX
1543 int fd
= open("/proc/self/stat", O_RDONLY
);
1546 nlwarning ("HA: Can't get OS from /proc/self/stat: %s", strerror (errno
));
1550 char buffer
[4096], *p
;
1551 int len
= read(fd
, buffer
, sizeof(buffer
)-1);
1557 p
= strchr(p
, ')')+1; /* skip pid */
1561 p
= skipToken(p
); /* skip ppid */
1562 p
= skipToken(p
); /* skip pgrp */
1563 p
= skipToken(p
); /* skip session */
1564 p
= skipToken(p
); /* skip tty */
1565 p
= skipToken(p
); /* skip tty pgrp */
1566 p
= skipToken(p
); /* skip flags */
1567 p
= skipToken(p
); /* skip min flt */
1568 p
= skipToken(p
); /* skip cmin flt */
1569 p
= skipToken(p
); /* skip maj flt */
1570 p
= skipToken(p
); /* skip cmaj flt */
1571 p
= skipToken(p
); /* utime */
1572 p
= skipToken(p
); /* stime */
1573 p
= skipToken(p
); /* skip cutime */
1574 p
= skipToken(p
); /* skip cstime */
1575 p
= skipToken(p
); /* priority */
1576 p
= skipToken(p
); /* nice */
1577 p
= skipToken(p
); /* skip timeout */
1578 p
= skipToken(p
); /* skip it_real_val */
1579 p
= skipToken(p
); /* skip start_time */
1581 systemMemory
= strtoul(p
, &p
, 10); /* vsize in bytes */
1584 #endif // NL_OS_WINDOWS
1585 return systemMemory
;
1589 NLMISC_CATEGORISED_DYNVARIABLE(nel
, string
, AvailableHDSpace
, "Hard drive space left in bytes")
1591 // ace: it's a little bit tricky, if you don't understand how it works, don't touch!
1592 static string location
;
1595 *pointer
= (CSystemInfo::availableHDSpace(location
));
1600 location
= *pointer
;
1604 NLMISC_CATEGORISED_DYNVARIABLE(nel
, string
, AvailablePhysicalMemory
, "Physical memory available on this computer in bytes")
1606 if (get
) *pointer
= bytesToHumanReadable(CSystemInfo::availablePhysicalMemory ());
1609 NLMISC_CATEGORISED_DYNVARIABLE(nel
, string
, TotalPhysicalMemory
, "Total physical memory on this computer in bytes")
1611 if (get
) *pointer
= bytesToHumanReadable(CSystemInfo::totalPhysicalMemory ());
1614 NLMISC_CATEGORISED_DYNVARIABLE(nel
, string
, ProcessUsedMemory
, "Memory used by this process in bytes")
1616 if (get
) *pointer
= bytesToHumanReadable(CSystemInfo::getAllocatedSystemMemory ());
1619 NLMISC_CATEGORISED_DYNVARIABLE(nel
, string
, OS
, "OS used")
1621 if (get
) *pointer
= CSystemInfo::getOS();
1624 #ifdef NL_OS_WINDOWS
1625 struct DISPLAY_DEVICE_EX
1628 CHAR DeviceName
[32];
1629 CHAR DeviceString
[128];
1632 CHAR DeviceKey
[128];
1634 #endif // NL_OS_WINDOWS
1636 bool CSystemInfo::getVideoInfo (std::string
&deviceName
, uint64
&driverVersion
)
1638 #ifdef NL_OS_WINDOWS
1639 /* Get the device name with EnumDisplayDevices (doesn't work under win95).
1640 * Look for driver information for this device in the registry
1642 * Follow the recommendations in the news group comp.os.ms-windows.programmer.nt.kernel-mode : "Get Video Driver ... Need Version"
1645 HMODULE hm
= GetModuleHandle(TEXT("USER32"));
1648 BOOL (WINAPI
* EnumDisplayDevices
)(LPCTSTR lpDevice
, DWORD iDevNum
, PDISPLAY_DEVICE lpDisplayDevice
, DWORD dwFlags
) = NULL
;
1649 *(FARPROC
*)&EnumDisplayDevices
= GetProcAddress(hm
, "EnumDisplayDevicesA");
1650 if (EnumDisplayDevices
)
1652 DISPLAY_DEVICE_EX DisplayDevice
;
1654 DisplayDevice
.cb
= sizeof (DISPLAY_DEVICE_EX
);
1656 while (EnumDisplayDevices(NULL
, device
, (DISPLAY_DEVICE
*)&DisplayDevice
, 0))
1659 if ((DisplayDevice
.StateFlags
& DISPLAY_DEVICE_PRIMARY_DEVICE
) &&
1660 (DisplayDevice
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
) &&
1661 ((DisplayDevice
.StateFlags
& DISPLAY_DEVICE_MIRRORING_DRIVER
) == 0) &&
1662 (DisplayDevice
.DeviceKey
[0] != 0))
1667 deviceName
= DisplayDevice
.DeviceString
;
1669 string keyPath
= DisplayDevice
.DeviceKey
;
1672 // Get the window version
1674 ver
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1676 bool atleastNT4
= (ver
.dwMajorVersion
> 3) && (ver
.dwPlatformId
== VER_PLATFORM_WIN32_NT
);
1677 bool winXP
= ((ver
.dwMajorVersion
== 5) && (ver
.dwMinorVersion
== 1)) || (ver
.dwMajorVersion
> 5);
1679 // * Get the registry entry for driver
1681 // OSversion >= osWin2k
1686 string::size_type pos
= keyPath
.rfind ('\\');
1687 if (pos
!= string::npos
)
1688 keyPath
= keyPath
.substr (0, pos
+1);
1690 keyName
= "Service";
1694 string::size_type pos
= toLowerAscii(keyPath
).find ("\\device");
1695 if (pos
!= string::npos
)
1696 keyPath
= keyPath
.substr (0, pos
+1);
1697 keyName
= "ImagePath";
1702 keyPath
+= "\\default";
1706 // Format the key path
1707 if (toLowerAscii(keyPath
).find ("\\registry\\machine") == 0)
1709 keyPath
= "HKEY_LOCAL_MACHINE" + keyPath
.substr (strlen ("\\registry\\machine"));
1713 static const char *rootKeys
[]=
1715 "HKEY_CLASSES_ROOT\\",
1716 "HKEY_CURRENT_CONFIG\\",
1717 "HKEY_CURRENT_USER\\",
1718 "HKEY_LOCAL_MACHINE\\",
1720 "HKEY_PERFORMANCE_DATA\\",
1723 static const HKEY rootKeysH
[]=
1726 HKEY_CURRENT_CONFIG
,
1730 HKEY_PERFORMANCE_DATA
,
1734 HKEY keyRoot
= HKEY_LOCAL_MACHINE
;
1735 for (i
=0; i
<sizeof(rootKeysH
)/sizeof(HKEY
); i
++)
1737 if (toUpperAscii(keyPath
).find (rootKeys
[i
]) == 0)
1739 keyPath
= keyPath
.substr (strlen (rootKeys
[i
]));
1740 keyRoot
= rootKeysH
[i
];
1745 // * Read the registry
1747 if (RegOpenKeyExA(keyRoot
, keyPath
.c_str(), 0, KEY_READ
, &baseKey
) == ERROR_SUCCESS
)
1753 if (RegQueryValueExA(baseKey
, keyName
.c_str(), NULL
, &valueType
, (unsigned char *)value
, &size
) == ERROR_SUCCESS
)
1761 // In Windows'XP we got service name -> not real driver name, so
1762 string xpKey
= string ("System\\CurrentControlSet\\Services\\")+value
;
1763 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE
, xpKey
.c_str(), 0, KEY_READ
, &baseKey
) == ERROR_SUCCESS
)
1766 if (RegQueryValueExA(baseKey
, "ImagePath", NULL
, &valueType
, (unsigned char *)value
, &size
) == ERROR_SUCCESS
)
1770 static const std::string s_systemRoot
= "\\SystemRoot\\";
1774 if (driverName
.substr(0, s_systemRoot
.length()) == s_systemRoot
)
1776 driverName
= driverName
.substr(s_systemRoot
.length());
1782 nlwarning ("CSystemInfo::getVideoInfo : empty value ImagePath in key %s", xpKey
.c_str());
1785 nlwarning ("CSystemInfo::getVideoInfo : can't query ImagePath in key %s", xpKey
.c_str());
1788 nlwarning ("CSystemInfo::getVideoInfo : can't open key %s", xpKey
.c_str());
1792 HMODULE hmVersion
= LoadLibraryA ("version.dll");
1795 BOOL (WINAPI
* _GetFileVersionInfo
)(LPSTR
, DWORD
, DWORD
, LPVOID
) = NULL
;
1796 DWORD (WINAPI
* _GetFileVersionInfoSize
)(LPSTR
, LPDWORD
) = NULL
;
1797 BOOL (WINAPI
* _VerQueryValue
)(const LPVOID
, LPSTR
, LPVOID
*, PUINT
) = NULL
;
1798 *(FARPROC
*)&_GetFileVersionInfo
= GetProcAddress(hmVersion
, "GetFileVersionInfoA");
1799 *(FARPROC
*)&_GetFileVersionInfoSize
= GetProcAddress(hmVersion
, "GetFileVersionInfoSizeA");
1800 *(FARPROC
*)&_VerQueryValue
= GetProcAddress(hmVersion
, "VerQueryValueA");
1801 if (_VerQueryValue
&& _GetFileVersionInfoSize
&& _GetFileVersionInfo
)
1803 // value got the path to the driver
1806 nlverify (GetWindowsDirectoryA(value
, 512) != 0);
1810 nlverify (GetSystemDirectoryA(value
, 512) != 0);
1812 driverName
= string (value
) + "\\" + driverName
;
1815 DWORD size
= _GetFileVersionInfoSize ((char*)driverName
.c_str(), &dwHandle
);
1818 vector
<uint8
> buffer
;
1819 buffer
.resize (size
);
1820 if (_GetFileVersionInfo((char*)driverName
.c_str(), dwHandle
, size
, &buffer
[0]))
1822 VS_FIXEDFILEINFO
*info
;
1824 char bslash
[] = { '\\', 0x00 };
1825 if (_VerQueryValue(&buffer
[0], bslash
, (VOID
**)&info
, &len
))
1827 driverVersion
= (((uint64
)info
->dwFileVersionMS
)<<32)|info
->dwFileVersionLS
;
1831 nlwarning ("CSystemInfo::getVideoInfo : VerQueryValue fails (%s)", driverName
.c_str());
1834 nlwarning ("CSystemInfo::getVideoInfo : GetFileVersionInfo fails (%s)", driverName
.c_str());
1837 nlwarning ("CSystemInfo::getVideoInfo : GetFileVersionInfoSize == 0 (%s)", driverName
.c_str());
1840 nlwarning ("CSystemInfo::getVideoInfo : No VerQuery, GetFileVersionInfoSize, GetFileVersionInfo functions");
1843 nlwarning ("CSystemInfo::getVideoInfo : No version dll");
1846 nlwarning ("CSystemInfo::getVideoInfo : empty value %s in key %s", keyName
.c_str(), keyPath
.c_str());
1849 nlwarning ("CSystemInfo::getVideoInfo : can't query value %s in key %s", keyName
.c_str(), keyPath
.c_str());
1852 nlwarning ("CSystemInfo::getVideoInfo : can't open key %s", keyPath
.c_str());
1857 nlwarning ("CSystemInfo::getVideoInfo : No primary display device found");
1860 nlwarning ("CSystemInfo::getVideoInfo : No EnumDisplayDevices function");
1863 nlwarning ("CSystemInfo::getVideoInfo : No user32 dll");
1865 #endif // NL_OS_WINDOWS
1871 uint64
CSystemInfo::virtualMemory ()
1873 #ifdef NL_OS_WINDOWS
1875 GlobalMemoryStatusEx(&ms
);
1876 return ms
.ullTotalVirtual
- ms
.ullAvailVirtual
;