main
cpp 261 lines 6.43 KB
Raw
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 #define OUTPUT_BUFFER 1024
6
7 // WixCA name quiet commandline argument properties
8 const LPCWSTR WIX_QUIET_ARGUMENTS_PROPERTY = L"WixQuietExecCmdLine";
9 const LPCWSTR WIX_QUIET64_ARGUMENTS_PROPERTY = L"WixQuietExec64CmdLine";
10
11 // WixCA quiet timeout properties
12 const LPCWSTR WIX_QUIET_TIMEOUT_PROPERTY = L"WixQuietExecCmdTimeout";
13 const LPCWSTR WIX_QUIET64_TIMEOUT_PROPERTY = L"WixQuietExec64CmdTimeout";
14
15 // WixCA silent commandline argument properties
16 const LPCWSTR WIX_SILENT_ARGUMENTS_PROPERTY = L"WixSilentExecCmdLine";
17 const LPCWSTR WIX_SILENT64_ARGUMENTS_PROPERTY = L"WixSilentExec64CmdLine";
18
19 // WixCA silent timeout properties
20 const LPCWSTR WIX_SILENT_TIMEOUT_PROPERTY = L"WixSilentExecCmdTimeout";
21 const LPCWSTR WIX_SILENT64_TIMEOUT_PROPERTY = L"WixSilentExec64CmdTimeout";
22
23 HRESULT BuildCommandLine(
24 __in LPCWSTR wzProperty,
25 __out LPWSTR *ppwzCommand
26 )
27 {
28 Assert(ppwzCommand);
29
30 HRESULT hr = S_OK;
31 BOOL fScheduled = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED);
32 BOOL fRollback = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK);
33 BOOL fCommit = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_COMMIT);
34
35 if (fScheduled || fRollback || fCommit)
36 {
37 if (WcaIsPropertySet("CustomActionData"))
38 {
39 hr = WcaGetProperty( L"CustomActionData", ppwzCommand);
40 ExitOnFailure(hr, "Failed to get CustomActionData");
41 }
42 }
43 else if (WcaIsUnicodePropertySet(wzProperty))
44 {
45 hr = WcaGetFormattedProperty(wzProperty, ppwzCommand);
46 ExitOnFailure(hr, "Failed to get %ls", wzProperty);
47 hr = WcaSetProperty(wzProperty, L""); // clear out the property now that we've read it
48 ExitOnFailure(hr, "Failed to set %ls", wzProperty);
49 }
50
51 if (!*ppwzCommand)
52 {
53 ExitOnFailure(hr = E_INVALIDARG, "Failed to get command line data");
54 }
55
56 if (L'"' != **ppwzCommand)
57 {
58 WcaLog(LOGMSG_STANDARD, "Command string must begin with quoted application name.");
59 ExitOnFailure(hr = E_INVALIDARG, "invalid command line property value");
60 }
61
62 LExit:
63 return hr;
64 }
65
66 #define ONEMINUTE 60000
67
68 DWORD GetTimeout(LPCWSTR wzPropertyName)
69 {
70 DWORD dwTimeout = ONEMINUTE;
71 HRESULT hr = S_OK;
72
73 LPWSTR pwzData = NULL;
74
75 if (WcaIsUnicodePropertySet(wzPropertyName))
76 {
77 hr = WcaGetProperty(wzPropertyName, &pwzData);
78 ExitOnFailure(hr, "Failed to get %ls", wzPropertyName);
79
80 if ((dwTimeout = (DWORD)_wtoi(pwzData)) == 0)
81 {
82 dwTimeout = ONEMINUTE;
83 }
84 }
85
86 LExit:
87 ReleaseStr(pwzData);
88
89 return dwTimeout;
90
91 }
92
93 HRESULT ExecCommon(
94 __in LPCWSTR wzArgumentsProperty,
95 __in LPCWSTR wzTimeoutProperty,
96 __in BOOL fLogCommand,
97 __in BOOL fLogOutput
98 )
99 {
100 HRESULT hr = S_OK;
101 LPWSTR pwzCommand = NULL;
102 DWORD dwTimeout = 0;
103
104 hr = BuildCommandLine(wzArgumentsProperty, &pwzCommand);
105 ExitOnFailure(hr, "Failed to get Command Line");
106
107 dwTimeout = GetTimeout(wzTimeoutProperty);
108
109 hr = QuietExec(pwzCommand, dwTimeout, fLogCommand, fLogOutput);
110 ExitOnFailure(hr, "QuietExec Failed");
111
112 LExit:
113 ReleaseStr(pwzCommand);
114
115 return hr;
116 }
117
118 HRESULT ExecCommon64(
119 __in LPCWSTR wzArgumentsProperty,
120 __in LPCWSTR wzTimeoutProperty,
121 __in BOOL fLogCommand,
122 __in BOOL fLogOutput
123 )
124 {
125 HRESULT hr = S_OK;
126 LPWSTR pwzCommand = NULL;
127 DWORD dwTimeout = 0;
128 #ifndef _WIN64
129 BOOL fIsWow64Initialized = FALSE;
130 BOOL fRedirected = FALSE;
131
132 hr = WcaInitializeWow64();
133 if (S_FALSE == hr)
134 {
135 hr = TYPE_E_DLLFUNCTIONNOTFOUND;
136 }
137 ExitOnFailure(hr, "Failed to intialize WOW64.");
138 fIsWow64Initialized = TRUE;
139
140 hr = WcaDisableWow64FSRedirection();
141 ExitOnFailure(hr, "Failed to enable filesystem redirection.");
142 fRedirected = TRUE;
143 #endif
144
145 hr = BuildCommandLine(wzArgumentsProperty, &pwzCommand);
146 ExitOnFailure(hr, "Failed to get Command Line");
147
148 dwTimeout = GetTimeout(wzTimeoutProperty);
149
150 hr = QuietExec(pwzCommand, dwTimeout, fLogCommand, fLogOutput);
151 ExitOnFailure(hr, "QuietExec64 Failed");
152
153 LExit:
154 ReleaseStr(pwzCommand);
155
156 #ifndef _WIN64
157 if (fRedirected)
158 {
159 WcaRevertWow64FSRedirection();
160 }
161
162 if (fIsWow64Initialized)
163 {
164 WcaFinalizeWow64();
165 }
166 #endif
167
168 return hr;
169 }
170
171 extern "C" UINT __stdcall WixQuietExec(
172 __in MSIHANDLE hInstall
173 )
174 {
175 Assert(hInstall);
176 HRESULT hr = S_OK;
177 UINT er = ERROR_SUCCESS;
178
179 hr = WcaInitialize(hInstall, "WixQuietExec");
180 ExitOnFailure(hr, "Failed to initialize");
181
182 hr = ExecCommon(WIX_QUIET_ARGUMENTS_PROPERTY, WIX_QUIET_TIMEOUT_PROPERTY, TRUE, TRUE);
183 ExitOnFailure(hr, "Failed in ExecCommon method");
184
185 LExit:
186 if (FAILED(hr))
187 {
188 er = ERROR_INSTALL_FAILURE;
189 }
190
191 return WcaFinalize(er);
192 }
193
194 extern "C" UINT __stdcall WixQuietExec64(
195 __in MSIHANDLE hInstall
196 )
197 {
198 Assert(hInstall);
199 HRESULT hr = S_OK;
200 UINT er = ERROR_SUCCESS;
201
202 hr = WcaInitialize(hInstall, "WixQuietExec64");
203 ExitOnFailure(hr, "Failed to initialize");
204
205 hr = ExecCommon64(WIX_QUIET64_ARGUMENTS_PROPERTY, WIX_QUIET64_TIMEOUT_PROPERTY, TRUE, TRUE);
206 ExitOnFailure(hr, "Failed in ExecCommon method");
207
208 LExit:
209 if (FAILED(hr))
210 {
211 er = ERROR_INSTALL_FAILURE;
212 }
213
214 return WcaFinalize(er);
215 }
216
217 extern "C" UINT __stdcall WixSilentExec(
218 __in MSIHANDLE hInstall
219 )
220 {
221 Assert(hInstall);
222 HRESULT hr = S_OK;
223 UINT er = ERROR_SUCCESS;
224
225 hr = WcaInitialize(hInstall, "WixSilentExec");
226 ExitOnFailure(hr, "Failed to initialize");
227
228 hr = ExecCommon(WIX_SILENT_ARGUMENTS_PROPERTY, WIX_SILENT_TIMEOUT_PROPERTY, FALSE, FALSE);
229 ExitOnFailure(hr, "Failed in ExecCommon method");
230
231 LExit:
232 if (FAILED(hr))
233 {
234 er = ERROR_INSTALL_FAILURE;
235 }
236
237 return WcaFinalize(er);
238 }
239
240 extern "C" UINT __stdcall WixSilentExec64(
241 __in MSIHANDLE hInstall
242 )
243 {
244 Assert(hInstall);
245 HRESULT hr = S_OK;
246 UINT er = ERROR_SUCCESS;
247
248 hr = WcaInitialize(hInstall, "WixSilentExec64");
249 ExitOnFailure(hr, "Failed to initialize");
250
251 hr = ExecCommon64(WIX_SILENT64_ARGUMENTS_PROPERTY, WIX_SILENT64_TIMEOUT_PROPERTY, FALSE, FALSE);
252 ExitOnFailure(hr, "Failed in ExecCommon method");
253
254 LExit:
255 if (FAILED(hr))
256 {
257 er = ERROR_INSTALL_FAILURE;
258 }
259
260 return WcaFinalize(er);
261 }