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 | } | ||
