aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Util/ca/OsInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/Util/ca/OsInfo.cpp')
-rw-r--r--src/ext/Util/ca/OsInfo.cpp487
1 files changed, 487 insertions, 0 deletions
diff --git a/src/ext/Util/ca/OsInfo.cpp b/src/ext/Util/ca/OsInfo.cpp
new file mode 100644
index 00000000..4783673e
--- /dev/null
+++ b/src/ext/Util/ca/OsInfo.cpp
@@ -0,0 +1,487 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5// constants we'll pick up from later SDKs
6#define SM_TABLETPC 86
7#define SM_MEDIACENTER 87
8#define SM_STARTER 88
9#define SM_SERVERR2 89
10#define VER_SUITE_WH_SERVER 0x00008000
11
12/********************************************************************
13WixQueryOsInfo - entry point for WixQueryOsInfo custom action
14
15 Called as Type 1 custom action (DLL from the Binary table) from
16 Windows Installer to set properties that identify OS information
17 and predefined directories
18********************************************************************/
19extern "C" UINT __stdcall WixQueryOsInfo(
20 __in MSIHANDLE hInstall
21 )
22{
23 HRESULT hr = S_OK;
24 DWORD er = ERROR_SUCCESS;
25 OSVERSIONINFOEXW ovix = {0};
26
27 hr = WcaInitialize(hInstall, "WixQueryOsInfo");
28 ExitOnFailure(hr, "WixQueryOsInfo failed to initialize");
29
30 // identify product suites
31 ovix.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
32 #pragma warning(suppress: 4996) //TODO: use osutil
33 ::GetVersionExW(reinterpret_cast<LPOSVERSIONINFOW>(&ovix));
34
35 if (VER_SUITE_SMALLBUSINESS == (ovix.wSuiteMask & VER_SUITE_SMALLBUSINESS))
36 {
37 WcaSetIntProperty(L"WIX_SUITE_SMALLBUSINESS", 1);
38 }
39
40 if (VER_SUITE_ENTERPRISE == (ovix.wSuiteMask & VER_SUITE_ENTERPRISE))
41 {
42 WcaSetIntProperty(L"WIX_SUITE_ENTERPRISE", 1);
43 }
44
45 if (VER_SUITE_BACKOFFICE == (ovix.wSuiteMask & VER_SUITE_BACKOFFICE))
46 {
47 WcaSetIntProperty(L"WIX_SUITE_BACKOFFICE", 1);
48 }
49
50 if (VER_SUITE_COMMUNICATIONS == (ovix.wSuiteMask & VER_SUITE_COMMUNICATIONS))
51 {
52 WcaSetIntProperty(L"WIX_SUITE_COMMUNICATIONS", 1);
53 }
54
55 if (VER_SUITE_TERMINAL == (ovix.wSuiteMask & VER_SUITE_TERMINAL))
56 {
57 WcaSetIntProperty(L"WIX_SUITE_TERMINAL", 1);
58 }
59
60 if (VER_SUITE_SMALLBUSINESS_RESTRICTED == (ovix.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))
61 {
62 WcaSetIntProperty(L"WIX_SUITE_SMALLBUSINESS_RESTRICTED", 1);
63 }
64
65 if (VER_SUITE_EMBEDDEDNT == (ovix.wSuiteMask & VER_SUITE_EMBEDDEDNT))
66 {
67 WcaSetIntProperty(L"WIX_SUITE_EMBEDDEDNT", 1);
68 }
69
70 if (VER_SUITE_DATACENTER == (ovix.wSuiteMask & VER_SUITE_DATACENTER))
71 {
72 WcaSetIntProperty(L"WIX_SUITE_DATACENTER", 1);
73 }
74
75 if (VER_SUITE_SINGLEUSERTS == (ovix.wSuiteMask & VER_SUITE_SINGLEUSERTS))
76 {
77 WcaSetIntProperty(L"WIX_SUITE_SINGLEUSERTS", 1);
78 }
79
80 if (VER_SUITE_PERSONAL == (ovix.wSuiteMask & VER_SUITE_PERSONAL))
81 {
82 WcaSetIntProperty(L"WIX_SUITE_PERSONAL", 1);
83 }
84
85 if (VER_SUITE_BLADE == (ovix.wSuiteMask & VER_SUITE_BLADE))
86 {
87 WcaSetIntProperty(L"WIX_SUITE_BLADE", 1);
88 }
89
90 if (VER_SUITE_EMBEDDED_RESTRICTED == (ovix.wSuiteMask & VER_SUITE_EMBEDDED_RESTRICTED))
91 {
92 WcaSetIntProperty(L"WIX_SUITE_EMBEDDED_RESTRICTED", 1);
93 }
94
95 if (VER_SUITE_SECURITY_APPLIANCE == (ovix.wSuiteMask & VER_SUITE_SECURITY_APPLIANCE))
96 {
97 WcaSetIntProperty(L"WIX_SUITE_SECURITY_APPLIANCE", 1);
98 }
99
100 if (VER_SUITE_STORAGE_SERVER == (ovix.wSuiteMask & VER_SUITE_STORAGE_SERVER))
101 {
102 WcaSetIntProperty(L"WIX_SUITE_STORAGE_SERVER", 1);
103 }
104
105 if (VER_SUITE_COMPUTE_SERVER == (ovix.wSuiteMask & VER_SUITE_COMPUTE_SERVER))
106 {
107 WcaSetIntProperty(L"WIX_SUITE_COMPUTE_SERVER", 1);
108 }
109
110 if (VER_SUITE_WH_SERVER == (ovix.wSuiteMask & VER_SUITE_WH_SERVER))
111 {
112 WcaSetIntProperty(L"WIX_SUITE_WH_SERVER", 1);
113 }
114
115 // only for XP and later
116 if (5 < ovix.dwMajorVersion || (5 == ovix.dwMajorVersion && 0 < ovix.dwMinorVersion))
117 {
118 if (::GetSystemMetrics(SM_SERVERR2))
119 {
120 WcaSetIntProperty(L"WIX_SUITE_SERVERR2", 1);
121 }
122
123 if (::GetSystemMetrics(SM_MEDIACENTER))
124 {
125 WcaSetIntProperty(L"WIX_SUITE_MEDIACENTER", 1);
126 }
127
128 if (::GetSystemMetrics(SM_STARTER))
129 {
130 WcaSetIntProperty(L"WIX_SUITE_STARTER", 1);
131 }
132
133 if (::GetSystemMetrics(SM_TABLETPC))
134 {
135 WcaSetIntProperty(L"WIX_SUITE_TABLETPC", 1);
136 }
137 }
138
139LExit:
140 if (FAILED(hr))
141 er = ERROR_INSTALL_FAILURE;
142 return WcaFinalize(er);
143}
144
145/********************************************************************
146WixQueryOsDirs - entry point for WixQueryOsDirs custom action
147
148 Called as Type 1 custom action (DLL from the Binary table) from
149 Windows Installer to set properties that identify predefined directories
150********************************************************************/
151extern "C" UINT __stdcall WixQueryOsDirs(
152 __in MSIHANDLE hInstall
153 )
154{
155 HRESULT hr = S_OK;
156 DWORD er = ERROR_SUCCESS;
157
158 hr = WcaInitialize(hInstall, "WixQueryOsDirs");
159 ExitOnFailure(hr, "WixQueryOsDirs failed to initialize");
160
161 // get the paths of the CSIDLs that represent real paths and for which MSI
162 // doesn't yet have standard folder properties
163 WCHAR path[MAX_PATH];
164 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_ADMINTOOLS, NULL, SHGFP_TYPE_CURRENT, path))
165 {
166 WcaSetProperty(L"WIX_DIR_ADMINTOOLS", path);
167 }
168
169 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_ALTSTARTUP, NULL, SHGFP_TYPE_CURRENT, path))
170 {
171 WcaSetProperty(L"WIX_DIR_ALTSTARTUP", path);
172 }
173
174 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_CDBURN_AREA, NULL, SHGFP_TYPE_CURRENT, path))
175 {
176 WcaSetProperty(L"WIX_DIR_CDBURN_AREA", path);
177 }
178
179 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_ADMINTOOLS, NULL, SHGFP_TYPE_CURRENT, path))
180 {
181 WcaSetProperty(L"WIX_DIR_COMMON_ADMINTOOLS", path);
182 }
183
184 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_ALTSTARTUP, NULL, SHGFP_TYPE_CURRENT, path))
185 {
186 WcaSetProperty(L"WIX_DIR_COMMON_ALTSTARTUP", path);
187 }
188
189 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))
190 {
191 WcaSetProperty(L"WIX_DIR_COMMON_DOCUMENTS", path);
192 }
193
194 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path))
195 {
196 WcaSetProperty(L"WIX_DIR_COMMON_FAVORITES", path);
197 }
198
199 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_MUSIC, NULL, SHGFP_TYPE_CURRENT, path))
200 {
201 WcaSetProperty(L"WIX_DIR_COMMON_MUSIC", path);
202 }
203
204 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_PICTURES, NULL, SHGFP_TYPE_CURRENT, path))
205 {
206 WcaSetProperty(L"WIX_DIR_COMMON_PICTURES", path);
207 }
208
209 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_VIDEO, NULL, SHGFP_TYPE_CURRENT, path))
210 {
211 WcaSetProperty(L"WIX_DIR_COMMON_VIDEO", path);
212 }
213
214 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COOKIES, NULL, SHGFP_TYPE_CURRENT, path))
215 {
216 WcaSetProperty(L"WIX_DIR_COOKIES", path);
217 }
218
219 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, path))
220 {
221 WcaSetProperty(L"WIX_DIR_DESKTOP", path);
222 }
223
224 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_HISTORY, NULL, SHGFP_TYPE_CURRENT, path))
225 {
226 WcaSetProperty(L"WIX_DIR_HISTORY", path);
227 }
228
229 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_INTERNET_CACHE, NULL, SHGFP_TYPE_CURRENT, path))
230 {
231 WcaSetProperty(L"WIX_DIR_INTERNET_CACHE", path);
232 }
233
234 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_MYMUSIC, NULL, SHGFP_TYPE_CURRENT, path))
235 {
236 WcaSetProperty(L"WIX_DIR_MYMUSIC", path);
237 }
238
239 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, SHGFP_TYPE_CURRENT, path))
240 {
241 WcaSetProperty(L"WIX_DIR_MYPICTURES", path);
242 }
243
244 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_MYVIDEO, NULL, SHGFP_TYPE_CURRENT, path))
245 {
246 WcaSetProperty(L"WIX_DIR_MYVIDEO", path);
247 }
248
249 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_NETHOOD, NULL, SHGFP_TYPE_CURRENT, path))
250 {
251 WcaSetProperty(L"WIX_DIR_NETHOOD", path);
252 }
253
254 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))
255 {
256 WcaSetProperty(L"WIX_DIR_PERSONAL", path);
257 }
258
259 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_PRINTHOOD, NULL, SHGFP_TYPE_CURRENT, path))
260 {
261 WcaSetProperty(L"WIX_DIR_PRINTHOOD", path);
262 }
263
264 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, path))
265 {
266 WcaSetProperty(L"WIX_DIR_PROFILE", path);
267 }
268
269 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_RECENT, NULL, SHGFP_TYPE_CURRENT, path))
270 {
271 WcaSetProperty(L"WIX_DIR_RECENT", path);
272 }
273
274 if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_RESOURCES, NULL, SHGFP_TYPE_CURRENT, path))
275 {
276 WcaSetProperty(L"WIX_DIR_RESOURCES", path);
277 }
278
279LExit:
280 if (FAILED(hr))
281 er = ERROR_INSTALL_FAILURE;
282 return WcaFinalize(er);
283}
284
285
286/********************************************************************
287SetPropertyWellKnownSID
288
289 Set a property with the localized name of a well known windows SID
290********************************************************************/
291static HRESULT SetPropertyWellKnownSID(
292 __in WELL_KNOWN_SID_TYPE sidType,
293 __in LPCWSTR wzPropertyName,
294 __in BOOL fIncludeDomainName
295 )
296{
297 HRESULT hr = S_OK;
298 PSID psid = NULL;
299 WCHAR wzRefDomain[MAX_PATH] = {0};
300 SID_NAME_USE nameUse;
301 DWORD refSize = MAX_PATH;
302 WCHAR wzName[MAX_PATH] = {0};
303 LPWSTR pwzPropertyValue = NULL;
304 DWORD size = MAX_PATH;
305
306 hr = AclGetWellKnownSid(sidType, &psid);
307 ExitOnFailure(hr, "Failed to get SID; skipping account %ls", wzPropertyName);
308
309 if (!::LookupAccountSidW(NULL, psid, wzName, &size, wzRefDomain, &refSize, &nameUse))
310 {
311 ExitWithLastError(hr, "Failed to look up account for SID; skipping account %ls.", wzPropertyName);
312 }
313
314 if (fIncludeDomainName)
315 {
316 hr = StrAllocFormatted(&pwzPropertyValue, L"%s\\%s", wzRefDomain, wzName);
317 ExitOnFailure(hr, "Failed to format property value");
318
319 hr = WcaSetProperty(wzPropertyName, pwzPropertyValue);
320 ExitOnFailure(hr, "Failed write domain\\name property");
321 }
322 else
323 {
324 hr = WcaSetProperty(wzPropertyName, wzName);
325 ExitOnFailure(hr, "Failed write to name-only property");
326 }
327
328LExit:
329 if (NULL != psid)
330 {
331 ::LocalFree(psid);
332 }
333 ReleaseStr(pwzPropertyValue);
334 return hr;
335}
336
337/********************************************************************
338WixQueryOsWellKnownSID - entry point for WixQueryOsWellKnownSID custom action
339
340 Called as Type 1 custom action (DLL from the Binary table) from
341 Windows Installer to set properties with the localized names of built-in
342 Windows Security IDs
343********************************************************************/
344extern "C" UINT __stdcall WixQueryOsWellKnownSID(
345 __in MSIHANDLE hInstall
346 )
347{
348 HRESULT hr = S_OK;
349 DWORD er = ERROR_SUCCESS;
350
351 hr = WcaInitialize(hInstall, "WixQueryOsWellKnownSID");
352 ExitOnFailure(hr, "WixQueryOsWellKnownSID failed to initialize");
353
354 SetPropertyWellKnownSID(WinLocalSystemSid, L"WIX_ACCOUNT_LOCALSYSTEM", TRUE);
355 SetPropertyWellKnownSID(WinLocalServiceSid, L"WIX_ACCOUNT_LOCALSERVICE", TRUE);
356 SetPropertyWellKnownSID(WinNetworkServiceSid, L"WIX_ACCOUNT_NETWORKSERVICE", TRUE);
357 SetPropertyWellKnownSID(WinBuiltinAdministratorsSid, L"WIX_ACCOUNT_ADMINISTRATORS", TRUE);
358 SetPropertyWellKnownSID(WinBuiltinUsersSid, L"WIX_ACCOUNT_USERS", TRUE);
359 SetPropertyWellKnownSID(WinBuiltinGuestsSid, L"WIX_ACCOUNT_GUESTS", TRUE);
360 SetPropertyWellKnownSID(WinBuiltinPerfLoggingUsersSid, L"WIX_ACCOUNT_PERFLOGUSERS", TRUE);
361 SetPropertyWellKnownSID(WinBuiltinPerfLoggingUsersSid, L"WIX_ACCOUNT_PERFLOGUSERS_NODOMAIN", FALSE);
362
363LExit:
364 if (FAILED(hr))
365 {
366 er = ERROR_INSTALL_FAILURE;
367 }
368 return WcaFinalize(er);
369}
370
371
372/********************************************************************
373DetectWDDMDriver
374
375 Set a property if the driver on the machine is a WDDM driver. One
376 reliable way to detect the presence of a WDDM driver is to try and
377 use the Direct3DCreate9Ex() function. This method attempts that
378 then sets the property appropriately.
379********************************************************************/
380static HRESULT DetectWDDMDriver()
381{
382 HRESULT hr = S_OK;
383 HMODULE hModule = NULL;
384
385 // Manually load the d3d9.dll library. If the library couldn't be loaded then we obviously won't be able
386 // to try calling the function so just return.
387 hr = LoadSystemLibrary(L"d3d9.dll", &hModule);
388 if (E_MODNOTFOUND == hr)
389 {
390 TraceError(hr, "Unable to load DirectX APIs, skipping WDDM driver check.");
391 ExitFunction1(hr = S_OK);
392 }
393 ExitOnFailure(hr, "Failed to the load the existing DirectX APIs.");
394
395 // Obtain the address of the Direct3DCreate9Ex function. If this fails we know it isn't a WDDM
396 // driver so just exit.
397 const void* Direct3DCreate9ExPtr = ::GetProcAddress(hModule, "Direct3DCreate9Ex");
398 ExitOnNull(Direct3DCreate9ExPtr, hr, S_OK, "Unable to load Direct3DCreateEx function, so the driver is not a WDDM driver.");
399
400 // At this point we know it's a WDDM driver so set the property.
401 hr = WcaSetIntProperty(L"WIX_WDDM_DRIVER_PRESENT", 1);
402 ExitOnFailure(hr, "Failed write property");
403
404LExit:
405 if (NULL != hModule)
406 {
407 FreeLibrary(hModule);
408 }
409
410 return hr;
411}
412
413/********************************************************************
414DetectIsCompositionEnabled
415
416 Set a property based on the return value of DwmIsCompositionEnabled().
417********************************************************************/
418static HRESULT DetectIsCompositionEnabled()
419{
420 HRESULT hr = S_OK;
421 HMODULE hModule = NULL;
422 BOOL compositionState = false;
423
424 // Manually load the d3d9.dll library. If the library can't load it's likely because we are not on a Vista
425 // OS. Just return ok, and the property won't get set.
426 hr = LoadSystemLibrary(L"dwmapi.dll", &hModule);
427 if (E_MODNOTFOUND == hr)
428 {
429 TraceError(hr, "Unable to load Vista desktop window manager APIs, skipping Composition Enabled check.");
430 ExitFunction1(hr = S_OK);
431 }
432 ExitOnFailure(hr, "Failed to load the existing window manager APIs.");
433
434 // If for some reason we can't get the function pointer that's ok, just return.
435 typedef HRESULT (WINAPI *DWMISCOMPOSITIONENABLEDPTR)(BOOL*);
436 DWMISCOMPOSITIONENABLEDPTR DwmIsCompositionEnabledPtr = (DWMISCOMPOSITIONENABLEDPTR)::GetProcAddress(hModule, "DwmIsCompositionEnabled");
437 ExitOnNull(hModule, hr, S_OK, "Unable to obtain function information, skipping Composition Enabled check.");
438
439 hr = DwmIsCompositionEnabledPtr(&compositionState);
440 ExitOnFailure(hr, "Failed to retrieve Composition state");
441
442 if (compositionState)
443 {
444 hr = WcaSetIntProperty(L"WIX_DWM_COMPOSITION_ENABLED", 1);
445 ExitOnFailure(hr, "Failed write property");
446 }
447
448LExit:
449 if (NULL != hModule)
450 {
451 FreeLibrary(hModule);
452 }
453 return hr;
454}
455
456/********************************************************************
457WixQueryOsDriverInfo - entry point for WixQueryOsDriverInfo custom action
458
459 Called as Type 1 custom action (DLL from the Binary table) from
460 Windows Installer to set properties about drivers installed on
461 the target machine
462********************************************************************/
463extern "C" UINT __stdcall WixQueryOsDriverInfo(
464 __in MSIHANDLE hInstall
465 )
466{
467 HRESULT hr = S_OK;
468 DWORD er = ERROR_SUCCESS;
469
470 hr = WcaInitialize(hInstall, "WixQueryOsDriverInfo");
471 ExitOnFailure(hr, "WixQueryOsDriverInfo failed to initialize");
472
473 // Detect the WDDM driver status
474 hr = DetectWDDMDriver();
475 ExitOnFailure(hr, "Failed to detect WIX_WDDM_DRIVER_PRESENT");
476
477 // Detect whether composition is enabled
478 hr = DetectIsCompositionEnabled();
479 ExitOnFailure(hr, "Failed to detect WIX_DWM_COMPOSITION_ENABLED");
480
481LExit:
482 if (FAILED(hr))
483 {
484 er = ERROR_INSTALL_FAILURE;
485 }
486 return WcaFinalize(er);
487}