diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2018-12-15 21:46:30 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-15 21:46:30 -0600 |
commit | f7020c0d16baf2b960e7123e233e20c519f6a340 (patch) | |
tree | d2cd464ee15b2b3f304ff780c531b39bb292d331 /src/ca/qtexecca.cpp | |
parent | 6ed8d107e6edf16956c778bda3573f8d7a7690fc (diff) | |
download | wix-f7020c0d16baf2b960e7123e233e20c519f6a340.tar.gz wix-f7020c0d16baf2b960e7123e233e20c519f6a340.tar.bz2 wix-f7020c0d16baf2b960e7123e233e20c519f6a340.zip |
Import implementation of UtilCA from old repo's WixCA/scasched/scaexec. (#3)
Diffstat (limited to 'src/ca/qtexecca.cpp')
-rw-r--r-- | src/ca/qtexecca.cpp | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/src/ca/qtexecca.cpp b/src/ca/qtexecca.cpp new file mode 100644 index 00000000..6acad0bb --- /dev/null +++ b/src/ca/qtexecca.cpp | |||
@@ -0,0 +1,312 @@ | |||
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 | BOOL fIsWow64Initialized = FALSE; | ||
135 | BOOL fRedirected = FALSE; | ||
136 | |||
137 | hr = WcaInitializeWow64(); | ||
138 | if (S_FALSE == hr) | ||
139 | { | ||
140 | hr = TYPE_E_DLLFUNCTIONNOTFOUND; | ||
141 | } | ||
142 | ExitOnFailure(hr, "Failed to intialize WOW64."); | ||
143 | fIsWow64Initialized = TRUE; | ||
144 | |||
145 | hr = WcaDisableWow64FSRedirection(); | ||
146 | ExitOnFailure(hr, "Failed to enable filesystem redirection."); | ||
147 | fRedirected = TRUE; | ||
148 | |||
149 | hr = BuildCommandLine(wzArgumentsProperty, &pwzCommand); | ||
150 | ExitOnFailure(hr, "Failed to get Command Line"); | ||
151 | |||
152 | dwTimeout = GetTimeout(wzTimeoutProperty); | ||
153 | |||
154 | hr = QuietExec(pwzCommand, dwTimeout, fLogCommand, fLogOutput); | ||
155 | ExitOnFailure(hr, "QuietExec64 Failed"); | ||
156 | |||
157 | LExit: | ||
158 | ReleaseStr(pwzCommand); | ||
159 | |||
160 | if (fRedirected) | ||
161 | { | ||
162 | WcaRevertWow64FSRedirection(); | ||
163 | } | ||
164 | |||
165 | if (fIsWow64Initialized) | ||
166 | { | ||
167 | WcaFinalizeWow64(); | ||
168 | } | ||
169 | |||
170 | return hr; | ||
171 | } | ||
172 | |||
173 | // These two custom actions are deprecated, and should go away in wix v4.0. WixQuietExec replaces this one, | ||
174 | // and is not intended to have any difference in behavior apart from CA name and property names. | ||
175 | extern "C" UINT __stdcall CAQuietExec( | ||
176 | __in MSIHANDLE hInstall | ||
177 | ) | ||
178 | { | ||
179 | Assert(hInstall); | ||
180 | HRESULT hr = S_OK; | ||
181 | UINT er = ERROR_SUCCESS; | ||
182 | |||
183 | hr = WcaInitialize(hInstall, "CAQuietExec"); | ||
184 | ExitOnFailure(hr, "Failed to initialize"); | ||
185 | |||
186 | hr = ExecCommon(CAQUIET_ARGUMENTS_PROPERTY, CAQUIET_TIMEOUT_PROPERTY, TRUE, TRUE); | ||
187 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
188 | |||
189 | LExit: | ||
190 | if (FAILED(hr)) | ||
191 | { | ||
192 | er = ERROR_INSTALL_FAILURE; | ||
193 | } | ||
194 | |||
195 | return WcaFinalize(er); | ||
196 | } | ||
197 | |||
198 | // 2nd deprecated custom action name, superseded by WixQuietExec64 | ||
199 | extern "C" UINT __stdcall CAQuietExec64( | ||
200 | __in MSIHANDLE hInstall | ||
201 | ) | ||
202 | { | ||
203 | Assert(hInstall); | ||
204 | HRESULT hr = S_OK; | ||
205 | UINT er = ERROR_SUCCESS; | ||
206 | |||
207 | hr = WcaInitialize(hInstall, "CAQuietExec64"); | ||
208 | ExitOnFailure(hr, "Failed to initialize"); | ||
209 | |||
210 | hr = ExecCommon64(CAQUIET64_ARGUMENTS_PROPERTY, CAQUIET_TIMEOUT_PROPERTY, TRUE, TRUE); | ||
211 | ExitOnFailure(hr, "Failed in ExecCommon64 method"); | ||
212 | |||
213 | LExit: | ||
214 | if (FAILED(hr)) | ||
215 | { | ||
216 | er = ERROR_INSTALL_FAILURE; | ||
217 | } | ||
218 | |||
219 | return WcaFinalize(er); | ||
220 | } | ||
221 | |||
222 | extern "C" UINT __stdcall WixQuietExec( | ||
223 | __in MSIHANDLE hInstall | ||
224 | ) | ||
225 | { | ||
226 | Assert(hInstall); | ||
227 | HRESULT hr = S_OK; | ||
228 | UINT er = ERROR_SUCCESS; | ||
229 | |||
230 | hr = WcaInitialize(hInstall, "WixQuietExec"); | ||
231 | ExitOnFailure(hr, "Failed to initialize"); | ||
232 | |||
233 | hr = ExecCommon(WIX_QUIET_ARGUMENTS_PROPERTY, WIX_QUIET_TIMEOUT_PROPERTY, TRUE, TRUE); | ||
234 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
235 | |||
236 | LExit: | ||
237 | if (FAILED(hr)) | ||
238 | { | ||
239 | er = ERROR_INSTALL_FAILURE; | ||
240 | } | ||
241 | |||
242 | return WcaFinalize(er); | ||
243 | } | ||
244 | |||
245 | extern "C" UINT __stdcall WixQuietExec64( | ||
246 | __in MSIHANDLE hInstall | ||
247 | ) | ||
248 | { | ||
249 | Assert(hInstall); | ||
250 | HRESULT hr = S_OK; | ||
251 | UINT er = ERROR_SUCCESS; | ||
252 | |||
253 | hr = WcaInitialize(hInstall, "WixQuietExec64"); | ||
254 | ExitOnFailure(hr, "Failed to initialize"); | ||
255 | |||
256 | hr = ExecCommon64(WIX_QUIET64_ARGUMENTS_PROPERTY, WIX_QUIET64_TIMEOUT_PROPERTY, TRUE, TRUE); | ||
257 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
258 | |||
259 | LExit: | ||
260 | if (FAILED(hr)) | ||
261 | { | ||
262 | er = ERROR_INSTALL_FAILURE; | ||
263 | } | ||
264 | |||
265 | return WcaFinalize(er); | ||
266 | } | ||
267 | |||
268 | extern "C" UINT __stdcall WixSilentExec( | ||
269 | __in MSIHANDLE hInstall | ||
270 | ) | ||
271 | { | ||
272 | Assert(hInstall); | ||
273 | HRESULT hr = S_OK; | ||
274 | UINT er = ERROR_SUCCESS; | ||
275 | |||
276 | hr = WcaInitialize(hInstall, "WixSilentExec"); | ||
277 | ExitOnFailure(hr, "Failed to initialize"); | ||
278 | |||
279 | hr = ExecCommon(WIX_SILENT_ARGUMENTS_PROPERTY, WIX_SILENT_TIMEOUT_PROPERTY, FALSE, FALSE); | ||
280 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
281 | |||
282 | LExit: | ||
283 | if (FAILED(hr)) | ||
284 | { | ||
285 | er = ERROR_INSTALL_FAILURE; | ||
286 | } | ||
287 | |||
288 | return WcaFinalize(er); | ||
289 | } | ||
290 | |||
291 | extern "C" UINT __stdcall WixSilentExec64( | ||
292 | __in MSIHANDLE hInstall | ||
293 | ) | ||
294 | { | ||
295 | Assert(hInstall); | ||
296 | HRESULT hr = S_OK; | ||
297 | UINT er = ERROR_SUCCESS; | ||
298 | |||
299 | hr = WcaInitialize(hInstall, "WixSilentExec64"); | ||
300 | ExitOnFailure(hr, "Failed to initialize"); | ||
301 | |||
302 | hr = ExecCommon64(WIX_SILENT64_ARGUMENTS_PROPERTY, WIX_SILENT64_TIMEOUT_PROPERTY, FALSE, FALSE); | ||
303 | ExitOnFailure(hr, "Failed in ExecCommon method"); | ||
304 | |||
305 | LExit: | ||
306 | if (FAILED(hr)) | ||
307 | { | ||
308 | er = ERROR_INSTALL_FAILURE; | ||
309 | } | ||
310 | |||
311 | return WcaFinalize(er); | ||
312 | } | ||