diff options
Diffstat (limited to 'src/ext/Util/ca/qtexecca.cpp')
-rw-r--r-- | src/ext/Util/ca/qtexecca.cpp | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/src/ext/Util/ca/qtexecca.cpp b/src/ext/Util/ca/qtexecca.cpp new file mode 100644 index 00000000..ddcc812f --- /dev/null +++ b/src/ext/Util/ca/qtexecca.cpp | |||
@@ -0,0 +1,316 @@ | |||
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 | // These old "CA" prefix names are deprecated, and intended to go away in wix 4.0, only staying now for compatibility reasons | ||
8 | const LPCWSTR CAQUIET_TIMEOUT_PROPERTY = L"QtExecCmdTimeout"; | ||
9 | const LPCWSTR CAQUIET_ARGUMENTS_PROPERTY = L"QtExecCmdLine"; | ||
10 | const LPCWSTR CAQUIET64_ARGUMENTS_PROPERTY = L"QtExec64CmdLine"; | ||
11 | // end deprecated section | ||
12 | |||
13 | // WixCA name quiet commandline argument properties | ||
14 | const LPCWSTR WIX_QUIET_ARGUMENTS_PROPERTY = L"WixQuietExecCmdLine"; | ||
15 | const LPCWSTR WIX_QUIET64_ARGUMENTS_PROPERTY = L"WixQuietExec64CmdLine"; | ||
16 | |||
17 | // WixCA quiet timeout properties | ||
18 | const LPCWSTR WIX_QUIET_TIMEOUT_PROPERTY = L"WixQuietExecCmdTimeout"; | ||
19 | const LPCWSTR WIX_QUIET64_TIMEOUT_PROPERTY = L"WixQuietExec64CmdTimeout"; | ||
20 | |||
21 | // WixCA silent commandline argument properties | ||
22 | const LPCWSTR WIX_SILENT_ARGUMENTS_PROPERTY = L"WixSilentExecCmdLine"; | ||
23 | const LPCWSTR WIX_SILENT64_ARGUMENTS_PROPERTY = L"WixSilentExec64CmdLine"; | ||
24 | |||
25 | // WixCA silent timeout properties | ||
26 | const LPCWSTR WIX_SILENT_TIMEOUT_PROPERTY = L"WixSilentExecCmdTimeout"; | ||
27 | const LPCWSTR WIX_SILENT64_TIMEOUT_PROPERTY = L"WixSilentExec64CmdTimeout"; | ||
28 | |||
29 | HRESULT BuildCommandLine( | ||
30 | __in LPCWSTR wzProperty, | ||
31 | __out LPWSTR *ppwzCommand | ||
32 | ) | ||
33 | { | ||
34 | Assert(ppwzCommand); | ||
35 | |||
36 | HRESULT hr = S_OK; | ||
37 | BOOL fScheduled = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED); | ||
38 | BOOL fRollback = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK); | ||
39 | BOOL fCommit = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_COMMIT); | ||
40 | |||
41 | if (fScheduled || fRollback || fCommit) | ||
42 | { | ||
43 | if (WcaIsPropertySet("CustomActionData")) | ||
44 | { | ||
45 | hr = WcaGetProperty( L"CustomActionData", ppwzCommand); | ||
46 | ExitOnFailure(hr, "Failed to get CustomActionData"); | ||
47 | } | ||
48 | } | ||
49 | else if (WcaIsUnicodePropertySet(wzProperty)) | ||
50 | { | ||
51 | hr = WcaGetFormattedProperty(wzProperty, ppwzCommand); | ||
52 | ExitOnFailure(hr, "Failed to get %ls", wzProperty); | ||
53 | hr = WcaSetProperty(wzProperty, L""); // clear out the property now that we've read it | ||
54 | ExitOnFailure(hr, "Failed to set %ls", wzProperty); | ||
55 | } | ||
56 | |||
57 | if (!*ppwzCommand) | ||
58 | { | ||
59 | ExitOnFailure(hr = E_INVALIDARG, "Failed to get command line data"); | ||
60 | } | ||
61 | |||
62 | if (L'"' != **ppwzCommand) | ||
63 | { | ||
64 | WcaLog(LOGMSG_STANDARD, "Command string must begin with quoted application name."); | ||
65 | ExitOnFailure(hr = E_INVALIDARG, "invalid command line property value"); | ||
66 | } | ||
67 | |||
68 | LExit: | ||
69 | return hr; | ||
70 | } | ||
71 | |||
72 | #define ONEMINUTE 60000 | ||
73 | |||
74 | DWORD GetTimeout(LPCWSTR wzPropertyName) | ||
75 | { | ||
76 | DWORD dwTimeout = ONEMINUTE; | ||
77 | HRESULT hr = S_OK; | ||
78 | |||
79 | LPWSTR pwzData = NULL; | ||
80 | |||
81 | if (WcaIsUnicodePropertySet(wzPropertyName)) | ||
82 | { | ||
83 | hr = WcaGetProperty(wzPropertyName, &pwzData); | ||
84 | ExitOnFailure(hr, "Failed to get %ls", wzPropertyName); | ||
85 | |||
86 | if ((dwTimeout = (DWORD)_wtoi(pwzData)) == 0) | ||
87 | { | ||
88 | dwTimeout = ONEMINUTE; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | LExit: | ||
93 | ReleaseStr(pwzData); | ||
94 | |||
95 | return dwTimeout; | ||
96 | |||
97 | } | ||
98 | |||
99 | HRESULT ExecCommon( | ||
100 | __in LPCWSTR wzArgumentsProperty, | ||
101 | __in LPCWSTR wzTimeoutProperty, | ||
102 | __in BOOL fLogCommand, | ||
103 | __in BOOL fLogOutput | ||
104 | ) | ||
105 | { | ||
106 | HRESULT hr = S_OK; | ||
107 | LPWSTR pwzCommand = NULL; | ||
108 | DWORD dwTimeout = 0; | ||
109 | |||
110 | hr = BuildCommandLine(wzArgumentsProperty, &pwzCommand); | ||
111 | ExitOnFailure(hr, "Failed to get Command Line"); | ||
112 | |||
113 | dwTimeout = GetTimeout(wzTimeoutProperty); | ||
114 | |||
115 | hr = QuietExec(pwzCommand, dwTimeout, fLogCommand, fLogOutput); | ||
116 | ExitOnFailure(hr, "QuietExec Failed"); | ||
117 | |||
118 | LExit: | ||
119 | ReleaseStr(pwzCommand); | ||
120 | |||
121 | return hr; | ||
122 | } | ||
123 | |||
124 | HRESULT ExecCommon64( | ||
125 | __in LPCWSTR wzArgumentsProperty, | ||
126 | __in LPCWSTR wzTimeoutProperty, | ||
127 | __in BOOL fLogCommand, | ||
128 | __in BOOL fLogOutput | ||
129 | ) | ||
130 | { | ||
131 | HRESULT hr = S_OK; | ||
132 | LPWSTR pwzCommand = NULL; | ||
133 | DWORD dwTimeout = 0; | ||
134 | #ifndef _WIN64 | ||
135 | BOOL fIsWow64Initialized = FALSE; | ||
136 | BOOL fRedirected = FALSE; | ||
137 | |||
138 | hr = WcaInitializeWow64(); | ||
139 | if (S_FALSE == hr) | ||
140 | { | ||
141 | hr = TYPE_E_DLLFUNCTIONNOTFOUND; | ||
142 | } | ||
143 | ExitOnFailure(hr, "Failed to intialize WOW64."); | ||
144 | fIsWow64Initialized = TRUE; | ||
145 | |||
146 | hr = WcaDisableWow64FSRedirection(); | ||
147 | ExitOnFailure(hr, "Failed to enable filesystem redirection."); | ||
148 | fRedirected = TRUE; | ||
149 | #endif | ||
150 | |||
151 | hr = BuildCommandLine(wzArgumentsProperty, &pwzCommand); | ||
152 | ExitOnFailure(hr, "Failed to get Command Line"); | ||
153 | |||
154 | dwTimeout = GetTimeout(wzTimeoutProperty); | ||
155 | |||
156 | hr = QuietExec(pwzCommand, dwTimeout, fLogCommand, fLogOutput); | ||
157 | ExitOnFailure(hr, "QuietExec64 Failed"); | ||
158 | |||
159 | LExit: | ||
160 | ReleaseStr(pwzCommand); | ||
161 | |||
162 | #ifndef _WIN64 | ||
163 | if (fRedirected) | ||
164 | { | ||
165 | WcaRevertWow64FSRedirection(); | ||
166 | } | ||
167 | |||
168 | if (fIsWow64Initialized) | ||
169 | { | ||
170 | WcaFinalizeWow64(); | ||
171 | } | ||
172 | #endif | ||
173 | |||
174 | return hr; | ||
175 | } | ||
176 | |||
177 | // These two custom actions are deprecated, and should go away in wix v4.0. WixQuietExec replaces this one, | ||
178 | // and is not intended to have any difference in behavior apart from CA name and property names. | ||
179 | extern "C" UINT __stdcall CAQuietExec( | ||
180 | __in MSIHANDLE hInstall | ||
181 | ) | ||
182 | { | ||
183 | Assert(hInstall); | ||
184 | HRESULT hr = S_OK; | ||
185 | UINT er = ERROR_SUCCESS; | ||
186 | |||
187 | hr = WcaInitialize(hInstall, "CAQuietExec"); | ||
188 | ExitOnFailure(hr, "Failed to initialize"); | ||
189 | |||
190 | hr = ExecCommon(CAQUIET_ARGUMENTS_PROPERTY, CAQUIET_TIMEOUT_PROPERTY, TRUE, TRUE); | ||
191 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
192 | |||
193 | LExit: | ||
194 | if (FAILED(hr)) | ||
195 | { | ||
196 | er = ERROR_INSTALL_FAILURE; | ||
197 | } | ||
198 | |||
199 | return WcaFinalize(er); | ||
200 | } | ||
201 | |||
202 | // 2nd deprecated custom action name, superseded by WixQuietExec64 | ||
203 | extern "C" UINT __stdcall CAQuietExec64( | ||
204 | __in MSIHANDLE hInstall | ||
205 | ) | ||
206 | { | ||
207 | Assert(hInstall); | ||
208 | HRESULT hr = S_OK; | ||
209 | UINT er = ERROR_SUCCESS; | ||
210 | |||
211 | hr = WcaInitialize(hInstall, "CAQuietExec64"); | ||
212 | ExitOnFailure(hr, "Failed to initialize"); | ||
213 | |||
214 | hr = ExecCommon64(CAQUIET64_ARGUMENTS_PROPERTY, CAQUIET_TIMEOUT_PROPERTY, TRUE, TRUE); | ||
215 | ExitOnFailure(hr, "Failed in ExecCommon64 method"); | ||
216 | |||
217 | LExit: | ||
218 | if (FAILED(hr)) | ||
219 | { | ||
220 | er = ERROR_INSTALL_FAILURE; | ||
221 | } | ||
222 | |||
223 | return WcaFinalize(er); | ||
224 | } | ||
225 | |||
226 | extern "C" UINT __stdcall WixQuietExec( | ||
227 | __in MSIHANDLE hInstall | ||
228 | ) | ||
229 | { | ||
230 | Assert(hInstall); | ||
231 | HRESULT hr = S_OK; | ||
232 | UINT er = ERROR_SUCCESS; | ||
233 | |||
234 | hr = WcaInitialize(hInstall, "WixQuietExec"); | ||
235 | ExitOnFailure(hr, "Failed to initialize"); | ||
236 | |||
237 | hr = ExecCommon(WIX_QUIET_ARGUMENTS_PROPERTY, WIX_QUIET_TIMEOUT_PROPERTY, TRUE, TRUE); | ||
238 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
239 | |||
240 | LExit: | ||
241 | if (FAILED(hr)) | ||
242 | { | ||
243 | er = ERROR_INSTALL_FAILURE; | ||
244 | } | ||
245 | |||
246 | return WcaFinalize(er); | ||
247 | } | ||
248 | |||
249 | extern "C" UINT __stdcall WixQuietExec64( | ||
250 | __in MSIHANDLE hInstall | ||
251 | ) | ||
252 | { | ||
253 | Assert(hInstall); | ||
254 | HRESULT hr = S_OK; | ||
255 | UINT er = ERROR_SUCCESS; | ||
256 | |||
257 | hr = WcaInitialize(hInstall, "WixQuietExec64"); | ||
258 | ExitOnFailure(hr, "Failed to initialize"); | ||
259 | |||
260 | hr = ExecCommon64(WIX_QUIET64_ARGUMENTS_PROPERTY, WIX_QUIET64_TIMEOUT_PROPERTY, TRUE, TRUE); | ||
261 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
262 | |||
263 | LExit: | ||
264 | if (FAILED(hr)) | ||
265 | { | ||
266 | er = ERROR_INSTALL_FAILURE; | ||
267 | } | ||
268 | |||
269 | return WcaFinalize(er); | ||
270 | } | ||
271 | |||
272 | extern "C" UINT __stdcall WixSilentExec( | ||
273 | __in MSIHANDLE hInstall | ||
274 | ) | ||
275 | { | ||
276 | Assert(hInstall); | ||
277 | HRESULT hr = S_OK; | ||
278 | UINT er = ERROR_SUCCESS; | ||
279 | |||
280 | hr = WcaInitialize(hInstall, "WixSilentExec"); | ||
281 | ExitOnFailure(hr, "Failed to initialize"); | ||
282 | |||
283 | hr = ExecCommon(WIX_SILENT_ARGUMENTS_PROPERTY, WIX_SILENT_TIMEOUT_PROPERTY, FALSE, FALSE); | ||
284 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
285 | |||
286 | LExit: | ||
287 | if (FAILED(hr)) | ||
288 | { | ||
289 | er = ERROR_INSTALL_FAILURE; | ||
290 | } | ||
291 | |||
292 | return WcaFinalize(er); | ||
293 | } | ||
294 | |||
295 | extern "C" UINT __stdcall WixSilentExec64( | ||
296 | __in MSIHANDLE hInstall | ||
297 | ) | ||
298 | { | ||
299 | Assert(hInstall); | ||
300 | HRESULT hr = S_OK; | ||
301 | UINT er = ERROR_SUCCESS; | ||
302 | |||
303 | hr = WcaInitialize(hInstall, "WixSilentExec64"); | ||
304 | ExitOnFailure(hr, "Failed to initialize"); | ||
305 | |||
306 | hr = ExecCommon64(WIX_SILENT64_ARGUMENTS_PROPERTY, WIX_SILENT64_TIMEOUT_PROPERTY, FALSE, FALSE); | ||
307 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
308 | |||
309 | LExit: | ||
310 | if (FAILED(hr)) | ||
311 | { | ||
312 | er = ERROR_INSTALL_FAILURE; | ||
313 | } | ||
314 | |||
315 | return WcaFinalize(er); | ||
316 | } | ||