1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3 #include <sstream>
4 #include <string>
5
6 #ifndef _WIN32_WINNT
7 #define _WIN32_WINNT 0x500
8 #endif
9
10 #include <windows.h>
11
12 #ifndef PRODUCT_BUSINESS
13
14 #define PRODUCT_BUSINESS 0x00000006
15 #define PRODUCT_BUSINESS_N 0x00000010
16 #define PRODUCT_CLUSTER_SERVER 0x00000012
17 #define PRODUCT_DATACENTER_SERVER 0x00000008
18 #define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
19 #define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
20 #define PRODUCT_DATACENTER_SERVER_V 0x00000025
21 #define PRODUCT_ENTERPRISE 0x00000004
22 #define PRODUCT_ENTERPRISE_N 0x0000001B
23 #define PRODUCT_ENTERPRISE_SERVER 0x0000000A
24 #define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
25 #define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
26 #define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
27 #define PRODUCT_ENTERPRISE_SERVER_V 0x00000026
28 #define PRODUCT_HOME_BASIC 0x00000002
29 #define PRODUCT_HOME_BASIC_N 0x00000005
30 #define PRODUCT_HOME_PREMIUM 0x00000003
31 #define PRODUCT_HOME_PREMIUM_N 0x0000001A
32 #define PRODUCT_HOME_SERVER 0x00000013
33 #define PRODUCT_HYPERV 0x0000002A
34 #define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
35 #define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
36 #define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
37 #define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
38 #define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023
39 #define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
40 #define PRODUCT_STANDARD_SERVER 0x00000007
41 #define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
42 #define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
43 #define PRODUCT_STANDARD_SERVER_V 0x00000024
44 #define PRODUCT_STARTER 0x0000000B
45 #define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
46 #define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
47 #define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
48 #define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
49 #define PRODUCT_UNDEFINED 0x00000000
50 #define PRODUCT_ULTIMATE 0x00000001
51 #define PRODUCT_ULTIMATE_N 0x0000001C
52 #define PRODUCT_WEB_SERVER 0x00000011
53 #define PRODUCT_WEB_SERVER_CORE 0x0000001D
54
55 #endif
56
57 typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
58 typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
59
60 #ifndef SM_SERVERR2
61 #define SM_SERVERR2 89
62 #endif
63
64 // this is a modified version of http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx
65 // always provide a long enough buffer
GetOSDisplayString()66 std::string GetOSDisplayString()
67 {
68 OSVERSIONINFOEX osvi;
69 SYSTEM_INFO si;
70 PGNSI pGNSI;
71 BOOL bOsVersionInfoEx;
72 DWORD dwType;
73
74 ZeroMemory(&si, sizeof(SYSTEM_INFO));
75 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
76
77 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
78
79 if ( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
80 return std::string("error getting Windows version");
81
82 // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
83
84 pGNSI = (PGNSI) GetProcAddress(
85 GetModuleHandle(TEXT("kernel32.dll")),
86 "GetNativeSystemInfo");
87 if (NULL != pGNSI)
88 pGNSI(&si);
89 else GetSystemInfo(&si);
90
91 if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId &&
92 osvi.dwMajorVersion > 4 )
93 {
94 std::ostringstream oss;
95 oss << "Microsoft ";
96
97 // Test for the specific product.
98
99 if ( osvi.dwMajorVersion == 6)
100 {
101 if (osvi.dwMinorVersion == 0) {
102 if ( osvi.wProductType == VER_NT_WORKSTATION )
103 oss << "Windows Vista ";
104 else oss << "Windows Server 2008 ";
105 } else if (osvi.dwMinorVersion == 1) {
106 if( osvi.wProductType == VER_NT_WORKSTATION )
107 oss << "Windows 7 ";
108 else oss << "Windows Server 2008 R2 ";
109 }
110
111 PGPI pGPI = (PGPI) GetProcAddress(
112 GetModuleHandle(TEXT("kernel32.dll")),
113 "GetProductInfo");
114
115 pGPI( 6, 0, 0, 0, &dwType);
116
117 switch ( dwType )
118 {
119 case PRODUCT_ULTIMATE:
120 oss << "Ultimate Edition";
121 break;
122 case PRODUCT_HOME_PREMIUM:
123 oss << "Home Premium Edition";
124 break;
125 case PRODUCT_HOME_BASIC:
126 oss << "Home Basic Edition";
127 break;
128 case PRODUCT_ENTERPRISE:
129 oss << "Enterprise Edition";
130 break;
131 case PRODUCT_BUSINESS:
132 oss << "Business Edition";
133 break;
134 case PRODUCT_STARTER:
135 oss << "Starter Edition";
136 break;
137 case PRODUCT_CLUSTER_SERVER:
138 oss << "Cluster Server Edition";
139 break;
140 case PRODUCT_DATACENTER_SERVER:
141 oss << "Datacenter Edition";
142 break;
143 case PRODUCT_DATACENTER_SERVER_CORE:
144 oss << "Datacenter Edition (core installation)";
145 break;
146 case PRODUCT_ENTERPRISE_SERVER:
147 oss << "Enterprise Edition";
148 break;
149 case PRODUCT_ENTERPRISE_SERVER_CORE:
150 oss << "Enterprise Edition (core installation)";
151 break;
152 case PRODUCT_ENTERPRISE_SERVER_IA64:
153 oss << "Enterprise Edition for Itanium-based Systems";
154 break;
155 case PRODUCT_SMALLBUSINESS_SERVER:
156 oss << "Small Business Server";
157 break;
158 /* undocumented?
159 case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
160 oss << "Small Business Server Premium Edition";
161 break; */
162 case PRODUCT_STANDARD_SERVER:
163 oss << "Standard Edition";
164 break;
165 case PRODUCT_STANDARD_SERVER_CORE:
166 oss << "Standard Edition (core installation)";
167 break;
168 case PRODUCT_WEB_SERVER:
169 oss << "Web Server Edition";
170 break;
171 }
172 if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
173 oss << ", 64-bit";
174 else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
175 oss << ", 32-bit";
176 }
177
178 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
179 {
180 if ( GetSystemMetrics(SM_SERVERR2) )
181 oss << "Windows Server 2003 R2, ";
182 else if ( osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER )
183 oss << "Windows Storage Server 2003";
184 else if ( osvi.wProductType == VER_NT_WORKSTATION &&
185 si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
186 {
187 oss << "Windows XP Professional x64 Edition";
188 }
189 else oss << "Windows Server 2003, ";
190
191 // Test for the server type.
192 if ( osvi.wProductType != VER_NT_WORKSTATION )
193 {
194 if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 )
195 {
196 if ( osvi.wSuiteMask & VER_SUITE_DATACENTER )
197 oss << "Datacenter Edition for Itanium-based Systems";
198 else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
199 oss << "Enterprise Edition for Itanium-based Systems";
200 }
201
202 else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
203 {
204 if ( osvi.wSuiteMask & VER_SUITE_DATACENTER )
205 oss << "Datacenter x64 Edition";
206 else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
207 oss << "Enterprise x64 Edition";
208 else oss << "Standard x64 Edition";
209 }
210
211 else
212 {
213 if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
214 oss << "Compute Cluster Edition";
215 else if ( osvi.wSuiteMask & VER_SUITE_DATACENTER )
216 oss << "Datacenter Edition";
217 else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
218 oss << "Enterprise Edition" ;
219 else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
220 oss << "Web Edition";
221 else oss << "Standard Edition";
222 }
223 }
224 }
225
226 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
227 {
228 oss << "Windows XP ";
229 if ( osvi.wSuiteMask & VER_SUITE_PERSONAL )
230 oss << "Home Edition";
231 else oss << "Professional";
232 }
233
234 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
235 {
236 oss << "Windows 2000 ";
237
238 if ( osvi.wProductType == VER_NT_WORKSTATION )
239 {
240 oss << "Professional";
241 }
242 else
243 {
244 if ( osvi.wSuiteMask & VER_SUITE_DATACENTER )
245 oss << "Datacenter Server";
246 else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
247 oss << "Advanced Server";
248 else oss << "Server";
249 }
250 }
251
252 // Include service pack (if any) and build number.
253
254 if (strlen(osvi.szCSDVersion) > 0 )
255 {
256 oss << " " << osvi.szCSDVersion;
257 }
258
259 oss << " (build " << osvi.dwBuildNumber << ")";
260
261 return oss.str();
262 }
263
264 else
265 {
266 return std::string("unsupported version of Windows");
267 }
268 }
269
270
271 // this tries to read info about the CPU and available memory
GetHardwareInfoString()272 std::string GetHardwareInfoString()
273 {
274 std::ostringstream oss;
275
276 unsigned char regbuf[200];
277 DWORD regLength=sizeof(regbuf);
278 DWORD regType=REG_SZ;
279 HKEY regkey;
280 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
281 "Hardware\\Description\\System\\CentralProcessor\\0",
282 0, KEY_READ, ®key)==ERROR_SUCCESS)
283 {
284 if (RegQueryValueEx(regkey,"ProcessorNameString",0,®Type,regbuf,®Length)==ERROR_SUCCESS)
285 {
286 oss << regbuf << "; ";
287 }
288 else
289 {
290 oss << "cannot read processor data; ";
291 }
292 RegCloseKey(regkey);
293 }
294 else
295 {
296 oss << "cannot open key with processor data; ";
297 }
298
299 MEMORYSTATUSEX statex;
300 const int div = 1024*1024;
301 statex.dwLength = sizeof (statex);
302
303 GlobalMemoryStatusEx (&statex);
304
305 oss << (statex.ullTotalPhys/div) << "MB RAM, "
306 << (statex.ullTotalPageFile/div) << "MB pagefile";
307 return oss.str();
308 }
309