1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2007-2011 Free Software Foundation Europe e.V.
5 Copyright (C) 2016-2020 Bareos GmbH & Co. KG
6
7 This program is Free Software; you can redistribute it and/or
8 modify it under the terms of version three of the GNU Affero General Public
9 License as published by the Free Software Foundation and included
10 in the file LICENSE.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.
21 */
22 /*
23 * Kern Sibbald, August 2007
24 *
25 * Note, some of the original Bareos Windows startup and service handling code
26 * was derived from VNC code that was used in apcupsd then ported to
27 * Bareos. However, since then the code has been significantly enhanced
28 * and largely rewritten.
29 *
30 * Evidently due to the nature of Windows startup code and service
31 * handling code, certain similarities remain. Thanks to the original
32 * VNC authors.
33 *
34 * This is a generic main routine, which is used by all three
35 * of the daemons. Each one compiles it with slightly different
36 * #defines.
37 */
38
39 #include <mutex>
40 #include <windows.h>
41 #include <tchar.h>
42 #include <stdio.h>
43
44 #include "osinfo.h"
45
46 static char win_os[300];
47 static bool win_os_initialized = false;
48 static std::mutex init_mutex;
49
50 static bool GetWindowsVersionString(LPTSTR osbuf, int maxsiz);
51
GetOsInfoString()52 const char* GetOsInfoString()
53 {
54 if (!win_os_initialized) {
55 const std::lock_guard<std::mutex> lock(init_mutex);
56 if (!win_os_initialized) {
57 GetWindowsVersionString(win_os, sizeof(win_os) - 1);
58 win_os_initialized = true;
59 }
60 }
61 return win_os;
62 }
63
64
65 #ifndef PRODUCT_UNLICENSED
66 # define PRODUCT_UNLICENSED 0xABCDABCD
67 # define PRODUCT_BUSINESS 0x00000006
68 # define PRODUCT_BUSINESS_N 0x00000010
69 # define PRODUCT_CLUSTER_SERVER 0x00000012
70 # define PRODUCT_DATACENTER_SERVER 0x00000008
71 # define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
72 # define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
73 # define PRODUCT_DATACENTER_SERVER_V 0x00000025
74 # define PRODUCT_ENTERPRISE 0x00000004
75 # define PRODUCT_ENTERPRISE_E 0x00000046
76 # define PRODUCT_ENTERPRISE_N 0x0000001B
77 # define PRODUCT_ENTERPRISE_SERVER 0x0000000A
78 # define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
79 # define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
80 # define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
81 # define PRODUCT_ENTERPRISE_SERVER_V 0x00000026
82 # define PRODUCT_HOME_BASIC 0x00000002
83 # define PRODUCT_HOME_BASIC_E 0x00000043
84 # define PRODUCT_HOME_BASIC_N 0x00000005
85 # define PRODUCT_HOME_PREMIUM 0x00000003
86 # define PRODUCT_HOME_PREMIUM_E 0x00000044
87 # define PRODUCT_HOME_PREMIUM_N 0x0000001A
88 # define PRODUCT_HYPERV 0x0000002A
89 # define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
90 # define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
91 # define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
92 # define PRODUCT_PROFESSIONAL 0x00000030
93 # define PRODUCT_PROFESSIONAL_E 0x00000045
94 # define PRODUCT_PROFESSIONAL_N 0x00000031
95 # define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
96 # define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023
97 # define PRODUCT_SERVER_FOUNDATION 0x00000021
98 # define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
99 # define PRODUCT_SOLUTION_EMBEDDEDSERVER 0x00000038
100 # define PRODUCT_STANDARD_SERVER 0x00000007
101 # define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
102 # define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
103 # define PRODUCT_STANDARD_SERVER_V 0x00000024
104 # define PRODUCT_STARTER 0x0000000B
105 # define PRODUCT_STARTER_E 0x00000042
106 # define PRODUCT_STARTER_N 0x0000002F
107 # define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
108 # define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
109 # define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
110 # define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
111 # define PRODUCT_UNDEFINED 0x00000000
112 # define PRODUCT_ULTIMATE 0x00000001
113 # define PRODUCT_ULTIMATE_E 0x00000047
114 # define PRODUCT_ULTIMATE_N 0x0000001C
115 # define PRODUCT_WEB_SERVER 0x00000011
116 # define PRODUCT_WEB_SERVER_CORE 0x0000001D
117
118 # define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x19
119 # define SM_SERVERR2 89
120 # define VER_SERVER_NT 0x80000000
121
122 #endif
123
124 #ifndef PRODUCT_PROFESSIONAL
125 # define PRODUCT_PROFESSIONAL 0x00000030
126 #endif
127 #ifndef VER_SUITE_STORAGE_SERVER
128 # define VER_SUITE_STORAGE_SERVER 0x00002000
129 #endif
130 #ifndef VER_SUITE_COMPUTE_SERVER
131 # define VER_SUITE_COMPUTE_SERVER 0x00004000
132 #endif
133
134 /* Unknown value */
135 #undef VER_SUITE_WH_SERVER
136 #define VER_SUITE_WH_SERVER -1
137
138
139 typedef void(WINAPI* PGNSI)(LPSYSTEM_INFO);
140 typedef BOOL(WINAPI* PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
141
142 /*
143 * Get Windows version display string
144 */
GetWindowsVersionString(LPTSTR osbuf,int maxsiz)145 static bool GetWindowsVersionString(LPTSTR osbuf, int maxsiz)
146 {
147 OSVERSIONINFOEX osvi;
148 SYSTEM_INFO si;
149 PGNSI pGNSI;
150 PGPI pGPI;
151 BOOL bOsVersionInfoEx;
152 DWORD dwType;
153
154 memset(&si, 0, sizeof(SYSTEM_INFO));
155 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
156
157 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
158
159 if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi))) return 1;
160
161 // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
162
163 pGNSI = (PGNSI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
164 "GetNativeSystemInfo");
165 if (pGNSI) {
166 pGNSI(&si);
167 } else {
168 GetSystemInfo(&si);
169 }
170
171 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion > 4) {
172 strncpy(osbuf, TEXT("Microsoft "), maxsiz);
173
174 /*
175 * Test for the specific product.
176 */
177 switch (osvi.dwMajorVersion) {
178 case 6:
179 switch (osvi.dwMinorVersion) {
180 case 0:
181 if (osvi.wProductType == VER_NT_WORKSTATION) {
182 strncat(osbuf, TEXT("Windows Vista "), maxsiz);
183 } else {
184 strncat(osbuf, TEXT("Windows Server 2008 "), maxsiz);
185 }
186 break;
187 case 1:
188 if (osvi.wProductType == VER_NT_WORKSTATION) {
189 strncat(osbuf, TEXT("Windows 7 "), maxsiz);
190 } else {
191 strncat(osbuf, TEXT("Windows Server 2008 R2 "), maxsiz);
192 }
193 break;
194 case 2:
195 if (osvi.wProductType == VER_NT_WORKSTATION) {
196 strncat(osbuf, TEXT("Windows 8 "), maxsiz);
197 } else {
198 strncat(osbuf, TEXT("Windows Server 2012 "), maxsiz);
199 }
200 break;
201 default:
202 strncat(osbuf, TEXT("Windows Unknown Release "), maxsiz);
203 break;
204 }
205
206 pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
207 "GetProductInfo");
208 if (pGPI) {
209 pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
210 } else {
211 dwType = PRODUCT_HOME_BASIC;
212 }
213
214 switch (dwType) {
215 case PRODUCT_ULTIMATE:
216 strncat(osbuf, TEXT("Ultimate Edition"), maxsiz);
217 break;
218 case PRODUCT_PROFESSIONAL:
219 strncat(osbuf, TEXT("Professional"), maxsiz);
220 break;
221 case PRODUCT_HOME_PREMIUM:
222 strncat(osbuf, TEXT("Home Premium Edition"), maxsiz);
223 break;
224 case PRODUCT_HOME_BASIC:
225 strncat(osbuf, TEXT("Home Basic Edition"), maxsiz);
226 break;
227 case PRODUCT_ENTERPRISE:
228 strncat(osbuf, TEXT("Enterprise Edition"), maxsiz);
229 break;
230 case PRODUCT_BUSINESS:
231 strncat(osbuf, TEXT("Business Edition"), maxsiz);
232 break;
233 case PRODUCT_STARTER:
234 strncat(osbuf, TEXT("Starter Edition"), maxsiz);
235 break;
236 case PRODUCT_CLUSTER_SERVER:
237 strncat(osbuf, TEXT("Cluster Server Edition"), maxsiz);
238 break;
239 case PRODUCT_DATACENTER_SERVER:
240 strncat(osbuf, TEXT("Datacenter Edition"), maxsiz);
241 break;
242 case PRODUCT_DATACENTER_SERVER_CORE:
243 strncat(osbuf, TEXT("Datacenter Edition (core installation)"),
244 maxsiz);
245 break;
246 case PRODUCT_ENTERPRISE_SERVER:
247 strncat(osbuf, TEXT("Enterprise Edition"), maxsiz);
248 break;
249 case PRODUCT_ENTERPRISE_SERVER_CORE:
250 strncat(osbuf, TEXT("Enterprise Edition (core installation)"),
251 maxsiz);
252 break;
253 case PRODUCT_ENTERPRISE_SERVER_IA64:
254 strncat(osbuf, TEXT("Enterprise Edition for Itanium-based Systems"),
255 maxsiz);
256 break;
257 case PRODUCT_SMALLBUSINESS_SERVER:
258 strncat(osbuf, TEXT("Small Business Server"), maxsiz);
259 break;
260 case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
261 strncat(osbuf, TEXT("Small Business Server Premium Edition"),
262 maxsiz);
263 break;
264 case PRODUCT_STANDARD_SERVER:
265 strncat(osbuf, TEXT("Standard Edition"), maxsiz);
266 break;
267 case PRODUCT_STANDARD_SERVER_CORE:
268 strncat(osbuf, TEXT("Standard Edition (core installation)"),
269 maxsiz);
270 break;
271 case PRODUCT_WEB_SERVER:
272 strncat(osbuf, TEXT("Web Server Edition"), maxsiz);
273 break;
274 }
275 break;
276 case 5:
277 switch (osvi.dwMinorVersion) {
278 case 2:
279 if (GetSystemMetrics(SM_SERVERR2)) {
280 strncat(osbuf, TEXT("Windows Server 2003 R2 "), maxsiz);
281 } else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER) {
282 strncat(osbuf, TEXT("Windows Storage Server 2003"), maxsiz);
283 } else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER) {
284 strncat(osbuf, TEXT("Windows Home Server"), maxsiz);
285 } else if (osvi.wProductType == VER_NT_WORKSTATION
286 && si.wProcessorArchitecture
287 == PROCESSOR_ARCHITECTURE_AMD64) {
288 strncat(osbuf, TEXT("Windows XP Professional x64 Edition"),
289 maxsiz);
290 } else {
291 strncat(osbuf, TEXT("Windows Server 2003 "), maxsiz);
292 }
293
294 /*
295 * Test for the server type.
296 */
297 if (osvi.wProductType != VER_NT_WORKSTATION) {
298 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
299 if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
300 strncat(osbuf,
301 TEXT("Datacenter Edition for Itanium-based Systems"),
302 maxsiz);
303 } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
304 strncat(osbuf,
305 TEXT("Enterprise Edition for Itanium-based Systems"),
306 maxsiz);
307 }
308 } else if (si.wProcessorArchitecture
309 == PROCESSOR_ARCHITECTURE_AMD64) {
310 if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
311 strncat(osbuf, TEXT("Datacenter x64 Edition"), maxsiz);
312 } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
313 strncat(osbuf, TEXT("Enterprise x64 Edition"), maxsiz);
314 } else {
315 strncat(osbuf, TEXT("Standard x64 Edition"), maxsiz);
316 }
317 } else {
318 if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER) {
319 strncat(osbuf, TEXT("Compute Cluster Edition"), maxsiz);
320 } else if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
321 strncat(osbuf, TEXT("Datacenter Edition"), maxsiz);
322 } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
323 strncat(osbuf, TEXT("Enterprise Edition"), maxsiz);
324 } else if (osvi.wSuiteMask & VER_SUITE_BLADE) {
325 strncat(osbuf, TEXT("Web Edition"), maxsiz);
326 } else {
327 strncat(osbuf, TEXT("Standard Edition"), maxsiz);
328 }
329 }
330 }
331 break;
332 case 1:
333 strncat(osbuf, TEXT("Windows XP "), maxsiz);
334 if (osvi.wSuiteMask & VER_SUITE_PERSONAL) {
335 strncat(osbuf, TEXT("Home Edition"), maxsiz);
336 } else {
337 strncat(osbuf, TEXT("Professional"), maxsiz);
338 }
339 break;
340 case 0:
341 strncat(osbuf, TEXT("Windows 2000 "), maxsiz);
342 if (osvi.wProductType == VER_NT_WORKSTATION) {
343 strncat(osbuf, TEXT("Professional"), maxsiz);
344 } else {
345 if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
346 strncat(osbuf, TEXT("Datacenter Server"), maxsiz);
347 } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
348 strncat(osbuf, TEXT("Advanced Server"), maxsiz);
349 } else {
350 strncat(osbuf, TEXT("Server"), maxsiz);
351 }
352 }
353 break;
354 }
355 break;
356 default:
357 break;
358 }
359
360 /*
361 * Include service pack (if any) and build number.
362 */
363 if (_tcslen(osvi.szCSDVersion) > 0) {
364 strncat(osbuf, TEXT(" "), maxsiz);
365 strncat(osbuf, osvi.szCSDVersion, maxsiz);
366 }
367
368 char buf[80];
369
370 snprintf(buf, 80, " (build %d)", (int)osvi.dwBuildNumber);
371 strncat(osbuf, buf, maxsiz);
372
373 if (osvi.dwMajorVersion >= 6) {
374 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
375 strncat(osbuf, TEXT(", 64-bit"), maxsiz);
376 else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
377 strncat(osbuf, TEXT(", 32-bit"), maxsiz);
378 }
379
380 return true;
381 } else {
382 strncpy(osbuf, "Unknown Windows version.", maxsiz);
383 return true;
384 }
385 }
386