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, &regkey)==ERROR_SUCCESS)
283     {
284         if (RegQueryValueEx(regkey,"ProcessorNameString",0,&regType,regbuf,&regLength)==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