diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-12-10 11:42:44 -0600 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-12-11 20:03:13 -0600 |
| commit | fc30db9fa3aa1d25a6ef078452864673caa67ec5 (patch) | |
| tree | e3415a5a1329a867b2934a038243e95098214ec3 /src/burn/engine | |
| parent | 1d58b3333d1d694d08b68f6c87223aa504bfe773 (diff) | |
| download | wix-fc30db9fa3aa1d25a6ef078452864673caa67ec5.tar.gz wix-fc30db9fa3aa1d25a6ef078452864673caa67ec5.tar.bz2 wix-fc30db9fa3aa1d25a6ef078452864673caa67ec5.zip | |
Add BA events for setting the update bundle.
Fixes #6410
Diffstat (limited to 'src/burn/engine')
| -rw-r--r-- | src/burn/engine/core.cpp | 2 | ||||
| -rw-r--r-- | src/burn/engine/externalengine.cpp | 86 | ||||
| -rw-r--r-- | src/burn/engine/pseudobundle.cpp | 77 | ||||
| -rw-r--r-- | src/burn/engine/pseudobundle.h | 12 | ||||
| -rw-r--r-- | src/burn/engine/userexperience.cpp | 44 | ||||
| -rw-r--r-- | src/burn/engine/userexperience.h | 9 |
6 files changed, 195 insertions, 35 deletions
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index bbd0ff96..812c7261 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
| @@ -1193,7 +1193,7 @@ extern "C" HRESULT CoreCreateUpdateBundleCommandLine( | |||
| 1193 | { | 1193 | { |
| 1194 | HRESULT hr = S_OK; | 1194 | HRESULT hr = S_OK; |
| 1195 | 1195 | ||
| 1196 | hr = CoreRecreateCommandLine(psczCommandLine, BOOTSTRAPPER_ACTION_INSTALL, pInternalCommand, pCommand, BOOTSTRAPPER_RELATION_NONE, FALSE); | 1196 | hr = CoreRecreateCommandLine(psczCommandLine, BOOTSTRAPPER_ACTION_INSTALL, pInternalCommand, pCommand, BOOTSTRAPPER_RELATION_UPDATE, FALSE); |
| 1197 | ExitOnFailure(hr, "Failed to recreate update bundle command-line."); | 1197 | ExitOnFailure(hr, "Failed to recreate update bundle command-line."); |
| 1198 | 1198 | ||
| 1199 | LExit: | 1199 | LExit: |
diff --git a/src/burn/engine/externalengine.cpp b/src/burn/engine/externalengine.cpp index da84c83d..abe9b8bc 100644 --- a/src/burn/engine/externalengine.cpp +++ b/src/burn/engine/externalengine.cpp | |||
| @@ -269,64 +269,82 @@ HRESULT ExternalEngineSetUpdate( | |||
| 269 | ) | 269 | ) |
| 270 | { | 270 | { |
| 271 | HRESULT hr = S_OK; | 271 | HRESULT hr = S_OK; |
| 272 | BOOL fLeaveCriticalSection = FALSE; | ||
| 272 | LPWSTR sczFilePath = NULL; | 273 | LPWSTR sczFilePath = NULL; |
| 273 | LPWSTR sczCommandline = NULL; | 274 | LPWSTR sczCommandline = NULL; |
| 275 | LPWSTR sczPreviousId = NULL; | ||
| 276 | LPCWSTR wzNewId = NULL; | ||
| 274 | UUID guid = { }; | 277 | UUID guid = { }; |
| 275 | WCHAR wzGuid[39]; | 278 | WCHAR wzGuid[39]; |
| 276 | RPC_STATUS rs = RPC_S_OK; | 279 | RPC_STATUS rs = RPC_S_OK; |
| 280 | BOOL fRemove = (!wzLocalSource || !*wzLocalSource) && (!wzDownloadSource || !*wzDownloadSource); | ||
| 281 | |||
| 282 | UserExperienceOnSetUpdateBegin(&pEngineState->userExperience); | ||
| 277 | 283 | ||
| 278 | ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive); | 284 | ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive); |
| 285 | fLeaveCriticalSection = TRUE; | ||
| 279 | hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience); | 286 | hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience); |
| 280 | ExitOnFailure(hr, "Engine is active, cannot change engine state."); | 287 | ExitOnFailure(hr, "Engine is active, cannot change engine state."); |
| 281 | 288 | ||
| 282 | if ((!wzLocalSource || !*wzLocalSource) && (!wzDownloadSource || !*wzDownloadSource)) | 289 | if (!fRemove) |
| 283 | { | ||
| 284 | UpdateUninitialize(&pEngineState->update); | ||
| 285 | } | ||
| 286 | else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_NONE == hashType && (0 != cbHash || rgbHash)) | ||
| 287 | { | 290 | { |
| 288 | hr = E_INVALIDARG; | 291 | if (BOOTSTRAPPER_UPDATE_HASH_TYPE_NONE == hashType && (0 != cbHash || rgbHash)) |
| 292 | { | ||
| 293 | ExitFunction1(hr = E_INVALIDARG); | ||
| 294 | } | ||
| 295 | else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_SHA512 == hashType && (SHA512_HASH_LEN != cbHash || !rgbHash)) | ||
| 296 | { | ||
| 297 | ExitFunction1(hr = E_INVALIDARG); | ||
| 298 | } | ||
| 289 | } | 299 | } |
| 290 | else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_SHA512 == hashType && (SHA512_HASH_LEN != cbHash || !rgbHash)) | 300 | |
| 301 | sczPreviousId = pEngineState->update.package.sczId; | ||
| 302 | pEngineState->update.package.sczId = NULL; | ||
| 303 | UpdateUninitialize(&pEngineState->update); | ||
| 304 | |||
| 305 | if (fRemove) | ||
| 291 | { | 306 | { |
| 292 | hr = E_INVALIDARG; | 307 | ExitFunction(); |
| 293 | } | 308 | } |
| 294 | else | ||
| 295 | { | ||
| 296 | UpdateUninitialize(&pEngineState->update); | ||
| 297 | 309 | ||
| 298 | hr = CoreCreateUpdateBundleCommandLine(&sczCommandline, &pEngineState->internalCommand, &pEngineState->command); | 310 | hr = CoreCreateUpdateBundleCommandLine(&sczCommandline, &pEngineState->internalCommand, &pEngineState->command); |
| 299 | ExitOnFailure(hr, "Failed to create command-line for update bundle."); | 311 | ExitOnFailure(hr, "Failed to create command-line for update bundle."); |
| 300 | 312 | ||
| 301 | // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths. | 313 | // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths. |
| 302 | // Here I am generating a random guid, but in the future it would be nice if the feed would provide the ID of the update. | 314 | // Here I am generating a random guid, but in the future it would be nice if the feed would provide the ID of the update. |
| 303 | rs = ::UuidCreate(&guid); | 315 | rs = ::UuidCreate(&guid); |
| 304 | hr = HRESULT_FROM_RPC(rs); | 316 | hr = HRESULT_FROM_RPC(rs); |
| 305 | ExitOnFailure(hr, "Failed to create bundle update guid."); | 317 | ExitOnFailure(hr, "Failed to create bundle update guid."); |
| 306 | 318 | ||
| 307 | if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) | 319 | if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) |
| 308 | { | 320 | { |
| 309 | hr = E_OUTOFMEMORY; | 321 | hr = E_OUTOFMEMORY; |
| 310 | ExitOnRootFailure(hr, "Failed to convert bundle update guid into string."); | 322 | ExitOnRootFailure(hr, "Failed to convert bundle update guid into string."); |
| 311 | } | 323 | } |
| 312 | 324 | ||
| 313 | hr = StrAllocFormatted(&sczFilePath, L"%ls\\%ls", wzGuid, pEngineState->registration.sczExecutableName); | 325 | hr = StrAllocFormatted(&sczFilePath, L"%ls\\%ls", wzGuid, pEngineState->registration.sczExecutableName); |
| 314 | ExitOnFailure(hr, "Failed to build bundle update file path."); | 326 | ExitOnFailure(hr, "Failed to build bundle update file path."); |
| 315 | 327 | ||
| 316 | if (!wzLocalSource || !*wzLocalSource) | 328 | if (!wzLocalSource || !*wzLocalSource) |
| 317 | { | 329 | { |
| 318 | wzLocalSource = sczFilePath; | 330 | wzLocalSource = sczFilePath; |
| 319 | } | 331 | } |
| 320 | 332 | ||
| 321 | hr = PseudoBundleInitialize(FILEMAKEVERSION(rmj, rmm, rup, rpr), &pEngineState->update.package, FALSE, pEngineState->registration.sczId, BOOTSTRAPPER_RELATION_UPDATE, BOOTSTRAPPER_PACKAGE_STATE_ABSENT, FALSE, sczFilePath, wzLocalSource, wzDownloadSource, qwSize, TRUE, sczCommandline, NULL, NULL, NULL, rgbHash, cbHash); | 333 | hr = PseudoBundleInitializeUpdateBundle(&pEngineState->update.package, wzGuid, pEngineState->registration.sczId, sczFilePath, wzLocalSource, wzDownloadSource, qwSize, sczCommandline, rgbHash, cbHash); |
| 322 | ExitOnFailure(hr, "Failed to set update bundle."); | 334 | ExitOnFailure(hr, "Failed to set update bundle."); |
| 323 | 335 | ||
| 324 | pEngineState->update.fUpdateAvailable = TRUE; | 336 | pEngineState->update.fUpdateAvailable = TRUE; |
| 325 | } | 337 | wzNewId = wzGuid; |
| 326 | 338 | ||
| 327 | LExit: | 339 | LExit: |
| 328 | ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive); | 340 | if (fLeaveCriticalSection) |
| 341 | { | ||
| 342 | ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive); | ||
| 343 | } | ||
| 344 | |||
| 345 | UserExperienceOnSetUpdateComplete(&pEngineState->userExperience, hr, sczPreviousId, wzNewId); | ||
| 329 | 346 | ||
| 347 | ReleaseStr(sczPreviousId); | ||
| 330 | ReleaseStr(sczCommandline); | 348 | ReleaseStr(sczCommandline); |
| 331 | ReleaseStr(sczFilePath); | 349 | ReleaseStr(sczFilePath); |
| 332 | 350 | ||
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index 52b7bd8a..91c6c14f 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp | |||
| @@ -240,3 +240,80 @@ LExit: | |||
| 240 | ReleaseStr(sczArguments); | 240 | ReleaseStr(sczArguments); |
| 241 | return hr; | 241 | return hr; |
| 242 | } | 242 | } |
| 243 | |||
| 244 | extern "C" HRESULT PseudoBundleInitializeUpdateBundle( | ||
| 245 | __in BURN_PACKAGE* pPackage, | ||
| 246 | __in_z LPCWSTR wzId, | ||
| 247 | __in_z LPCWSTR wzCacheId, | ||
| 248 | __in_z LPCWSTR wzFilePath, | ||
| 249 | __in_z LPCWSTR wzLocalSource, | ||
| 250 | __in_z_opt LPCWSTR wzDownloadSource, | ||
| 251 | __in DWORD64 qwSize, | ||
| 252 | __in_z LPCWSTR wzInstallArguments, | ||
| 253 | __in_opt const BYTE* pbHash, | ||
| 254 | __in const DWORD cbHash | ||
| 255 | ) | ||
| 256 | { | ||
| 257 | HRESULT hr = S_OK; | ||
| 258 | BURN_PAYLOAD* pPayload = NULL; | ||
| 259 | |||
| 260 | // Initialize the single payload, and fill out all the necessary fields | ||
| 261 | pPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM), TRUE); | ||
| 262 | ExitOnNull(pPackage->payloads.rgItems, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload group inside of update bundle struct"); | ||
| 263 | pPackage->payloads.cItems = 1; | ||
| 264 | |||
| 265 | pPayload = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD), TRUE); | ||
| 266 | ExitOnNull(pPayload, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of update bundle struct"); | ||
| 267 | pPackage->payloads.rgItems[0].pPayload = pPayload; | ||
| 268 | pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL; | ||
| 269 | pPayload->qwFileSize = qwSize; | ||
| 270 | pPayload->verification = BURN_PAYLOAD_VERIFICATION_UPDATE_BUNDLE; | ||
| 271 | |||
| 272 | hr = StrAllocString(&pPayload->sczKey, wzId, 0); | ||
| 273 | ExitOnFailure(hr, "Failed to copy key for pseudo bundle payload."); | ||
| 274 | |||
| 275 | hr = StrAllocString(&pPayload->sczFilePath, wzFilePath, 0); | ||
| 276 | ExitOnFailure(hr, "Failed to copy filename for pseudo bundle."); | ||
| 277 | |||
| 278 | hr = StrAllocString(&pPayload->sczSourcePath, wzLocalSource, 0); | ||
| 279 | ExitOnFailure(hr, "Failed to copy local source path for pseudo bundle."); | ||
| 280 | |||
| 281 | if (wzDownloadSource && *wzDownloadSource) | ||
| 282 | { | ||
| 283 | hr = StrAllocString(&pPayload->downloadSource.sczUrl, wzDownloadSource, 0); | ||
| 284 | ExitOnFailure(hr, "Failed to copy download source for pseudo bundle."); | ||
| 285 | } | ||
| 286 | |||
| 287 | if (pbHash) | ||
| 288 | { | ||
| 289 | pPayload->pbHash = static_cast<BYTE*>(MemAlloc(cbHash, FALSE)); | ||
| 290 | ExitOnNull(pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for update bundle payload hash."); | ||
| 291 | |||
| 292 | pPayload->cbHash = cbHash; | ||
| 293 | memcpy_s(pPayload->pbHash, pPayload->cbHash, pbHash, cbHash); | ||
| 294 | } | ||
| 295 | |||
| 296 | pPackage->Exe.fPseudoBundle = TRUE; | ||
| 297 | |||
| 298 | pPackage->type = BURN_PACKAGE_TYPE_EXE; | ||
| 299 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; | ||
| 300 | pPackage->qwInstallSize = qwSize; | ||
| 301 | pPackage->qwSize = qwSize; | ||
| 302 | pPackage->fVital = TRUE; | ||
| 303 | |||
| 304 | hr = StrAllocString(&pPackage->sczId, wzId, 0); | ||
| 305 | ExitOnFailure(hr, "Failed to copy id for update bundle."); | ||
| 306 | |||
| 307 | hr = StrAllocString(&pPackage->sczCacheId, wzCacheId, 0); | ||
| 308 | ExitOnFailure(hr, "Failed to copy cache id for update bundle."); | ||
| 309 | |||
| 310 | hr = StrAllocString(&pPackage->Exe.sczInstallArguments, wzInstallArguments, 0); | ||
| 311 | ExitOnFailure(hr, "Failed to copy install arguments for update bundle package"); | ||
| 312 | |||
| 313 | // Assume the update bundle has the same engine version as this one. | ||
| 314 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN; | ||
| 315 | pPackage->Exe.fSupportsAncestors = TRUE; | ||
| 316 | |||
| 317 | LExit: | ||
| 318 | return hr; | ||
| 319 | } \ No newline at end of file | ||
diff --git a/src/burn/engine/pseudobundle.h b/src/burn/engine/pseudobundle.h index aa26d29d..0fd4cbdb 100644 --- a/src/burn/engine/pseudobundle.h +++ b/src/burn/engine/pseudobundle.h | |||
| @@ -32,6 +32,18 @@ HRESULT PseudoBundleInitializePassthrough( | |||
| 32 | __in BOOTSTRAPPER_COMMAND* pCommand, | 32 | __in BOOTSTRAPPER_COMMAND* pCommand, |
| 33 | __in BURN_PACKAGE* pPackage | 33 | __in BURN_PACKAGE* pPackage |
| 34 | ); | 34 | ); |
| 35 | HRESULT PseudoBundleInitializeUpdateBundle( | ||
| 36 | __in BURN_PACKAGE* pPackage, | ||
| 37 | __in_z LPCWSTR wzId, | ||
| 38 | __in_z LPCWSTR wzCacheId, | ||
| 39 | __in_z LPCWSTR wzFilePath, | ||
| 40 | __in_z LPCWSTR wzLocalSource, | ||
| 41 | __in_z_opt LPCWSTR wzDownloadSource, | ||
| 42 | __in DWORD64 qwSize, | ||
| 43 | __in_z LPCWSTR wzInstallArguments, | ||
| 44 | __in_opt const BYTE* pbHash, | ||
| 45 | __in const DWORD cbHash | ||
| 46 | ); | ||
| 35 | 47 | ||
| 36 | #if defined(__cplusplus) | 48 | #if defined(__cplusplus) |
| 37 | } | 49 | } |
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp index 2bd6ecaf..a6d670ea 100644 --- a/src/burn/engine/userexperience.cpp +++ b/src/burn/engine/userexperience.cpp | |||
| @@ -2241,6 +2241,50 @@ LExit: | |||
| 2241 | return hr; | 2241 | return hr; |
| 2242 | } | 2242 | } |
| 2243 | 2243 | ||
| 2244 | EXTERN_C BAAPI UserExperienceOnSetUpdateBegin( | ||
| 2245 | __in BURN_USER_EXPERIENCE* pUserExperience | ||
| 2246 | ) | ||
| 2247 | { | ||
| 2248 | HRESULT hr = S_OK; | ||
| 2249 | BA_ONSETUPDATEBEGIN_ARGS args = { }; | ||
| 2250 | BA_ONSETUPDATEBEGIN_RESULTS results = { }; | ||
| 2251 | |||
| 2252 | args.cbSize = sizeof(args); | ||
| 2253 | |||
| 2254 | results.cbSize = sizeof(results); | ||
| 2255 | |||
| 2256 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN, &args, &results); | ||
| 2257 | ExitOnFailure(hr, "BA OnSetUpdateBegin failed."); | ||
| 2258 | |||
| 2259 | LExit: | ||
| 2260 | return hr; | ||
| 2261 | } | ||
| 2262 | |||
| 2263 | EXTERN_C BAAPI UserExperienceOnSetUpdateComplete( | ||
| 2264 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 2265 | __in HRESULT hrStatus, | ||
| 2266 | __in_z_opt LPCWSTR wzPreviousPackageId, | ||
| 2267 | __in_z_opt LPCWSTR wzNewPackageId | ||
| 2268 | ) | ||
| 2269 | { | ||
| 2270 | HRESULT hr = S_OK; | ||
| 2271 | BA_ONSETUPDATECOMPLETE_ARGS args = { }; | ||
| 2272 | BA_ONSETUPDATECOMPLETE_RESULTS results = { }; | ||
| 2273 | |||
| 2274 | args.cbSize = sizeof(args); | ||
| 2275 | args.hrStatus = hrStatus; | ||
| 2276 | args.wzPreviousPackageId = wzPreviousPackageId; | ||
| 2277 | args.wzNewPackageId = wzNewPackageId; | ||
| 2278 | |||
| 2279 | results.cbSize = sizeof(results); | ||
| 2280 | |||
| 2281 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE, &args, &results); | ||
| 2282 | ExitOnFailure(hr, "BA OnSetUpdateComplete failed."); | ||
| 2283 | |||
| 2284 | LExit: | ||
| 2285 | return hr; | ||
| 2286 | } | ||
| 2287 | |||
| 2244 | EXTERN_C BAAPI UserExperienceOnShutdown( | 2288 | EXTERN_C BAAPI UserExperienceOnShutdown( |
| 2245 | __in BURN_USER_EXPERIENCE* pUserExperience, | 2289 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 2246 | __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction | 2290 | __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction |
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h index 2493569b..f7ac962c 100644 --- a/src/burn/engine/userexperience.h +++ b/src/burn/engine/userexperience.h | |||
| @@ -505,6 +505,15 @@ BAAPI UserExperienceOnRollbackMsiTransactionComplete( | |||
| 505 | __in LPCWSTR wzTransactionId, | 505 | __in LPCWSTR wzTransactionId, |
| 506 | __in HRESULT hrStatus | 506 | __in HRESULT hrStatus |
| 507 | ); | 507 | ); |
| 508 | BAAPI UserExperienceOnSetUpdateBegin( | ||
| 509 | __in BURN_USER_EXPERIENCE* pUserExperience | ||
| 510 | ); | ||
| 511 | BAAPI UserExperienceOnSetUpdateComplete( | ||
| 512 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 513 | __in HRESULT hrStatus, | ||
| 514 | __in_z_opt LPCWSTR wzPreviousPackageId, | ||
| 515 | __in_z_opt LPCWSTR wzNewPackageId | ||
| 516 | ); | ||
| 508 | BAAPI UserExperienceOnShutdown( | 517 | BAAPI UserExperienceOnShutdown( |
| 509 | __in BURN_USER_EXPERIENCE* pUserExperience, | 518 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 510 | __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction | 519 | __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction |
