diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-02-10 18:09:34 -0600 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-02-10 19:51:19 -0600 |
| commit | 27a0db4070a2b5756282bf15b957dd7f0021417f (patch) | |
| tree | 2d0cdfe80d5ccd6d207bdf664a4f8e512281c1cf /src/burn/engine | |
| parent | 091573d459d6ab4947bd39bd3bc8faee3d18b4fc (diff) | |
| download | wix-27a0db4070a2b5756282bf15b957dd7f0021417f.tar.gz wix-27a0db4070a2b5756282bf15b957dd7f0021417f.tar.bz2 wix-27a0db4070a2b5756282bf15b957dd7f0021417f.zip | |
When rolling back a bundle failure, reinstall all upgrade related bundles.
Fixes #3421
Diffstat (limited to 'src/burn/engine')
| -rw-r--r-- | src/burn/engine/apply.cpp | 50 | ||||
| -rw-r--r-- | src/burn/engine/bundlepackageengine.cpp | 2 | ||||
| -rw-r--r-- | src/burn/engine/core.cpp | 4 | ||||
| -rw-r--r-- | src/burn/engine/engine.mc | 9 | ||||
| -rw-r--r-- | src/burn/engine/package.h | 1 | ||||
| -rw-r--r-- | src/burn/engine/plan.cpp | 143 | ||||
| -rw-r--r-- | src/burn/engine/plan.h | 4 | ||||
| -rw-r--r-- | src/burn/engine/pseudobundle.cpp | 1 | ||||
| -rw-r--r-- | src/burn/engine/registration.h | 4 | ||||
| -rw-r--r-- | src/burn/engine/userexperience.cpp | 30 | ||||
| -rw-r--r-- | src/burn/engine/userexperience.h | 5 |
11 files changed, 227 insertions, 26 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index 5cc63d02..73f8fc72 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp | |||
| @@ -210,6 +210,11 @@ static HRESULT ExecuteRelatedBundle( | |||
| 210 | __out BOOL* pfSuspend, | 210 | __out BOOL* pfSuspend, |
| 211 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 211 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
| 212 | ); | 212 | ); |
| 213 | static HRESULT DoRestoreRelatedBundleActions( | ||
| 214 | __in BURN_ENGINE_STATE* pEngineState, | ||
| 215 | __in BURN_EXECUTE_CONTEXT* pContext, | ||
| 216 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
| 217 | ); | ||
| 213 | static HRESULT ExecuteExePackage( | 218 | static HRESULT ExecuteExePackage( |
| 214 | __in BURN_ENGINE_STATE* pEngineState, | 219 | __in BURN_ENGINE_STATE* pEngineState, |
| 215 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 220 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
| @@ -788,6 +793,9 @@ extern "C" HRESULT ApplyExecute( | |||
| 788 | { | 793 | { |
| 789 | if (pCheckpoint->pActiveRollbackBoundary->fVital) | 794 | if (pCheckpoint->pActiveRollbackBoundary->fVital) |
| 790 | { | 795 | { |
| 796 | hrRollback = DoRestoreRelatedBundleActions(pEngineState, &context, pRestart); | ||
| 797 | IgnoreRollbackError(hrRollback, "Failed rollback actions"); | ||
| 798 | |||
| 791 | // If the rollback boundary is vital, end execution here. | 799 | // If the rollback boundary is vital, end execution here. |
| 792 | break; | 800 | break; |
| 793 | } | 801 | } |
| @@ -2590,6 +2598,48 @@ LExit: | |||
| 2590 | return hr; | 2598 | return hr; |
| 2591 | } | 2599 | } |
| 2592 | 2600 | ||
| 2601 | static HRESULT DoRestoreRelatedBundleActions( | ||
| 2602 | __in BURN_ENGINE_STATE* pEngineState, | ||
| 2603 | __in BURN_EXECUTE_CONTEXT* pContext, | ||
| 2604 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
| 2605 | ) | ||
| 2606 | { | ||
| 2607 | HRESULT hr = S_OK; | ||
| 2608 | BOOL fRetryIgnored = FALSE; | ||
| 2609 | BOOL fSuspendIgnored = FALSE; | ||
| 2610 | |||
| 2611 | // execute restore related bundle actions | ||
| 2612 | for (DWORD i = 0; i < pEngineState->plan.cRestoreRelatedBundleActions; ++i) | ||
| 2613 | { | ||
| 2614 | BURN_EXECUTE_ACTION* pRestoreRelatedBundleAction = &pEngineState->plan.rgRestoreRelatedBundleActions[i]; | ||
| 2615 | if (pRestoreRelatedBundleAction->fDeleted) | ||
| 2616 | { | ||
| 2617 | continue; | ||
| 2618 | } | ||
| 2619 | |||
| 2620 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
| 2621 | switch (pRestoreRelatedBundleAction->type) | ||
| 2622 | { | ||
| 2623 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
| 2624 | hr = ExecuteRelatedBundle(pEngineState, pRestoreRelatedBundleAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); | ||
| 2625 | IgnoreRollbackError(hr, "Failed to restore related bundle package."); | ||
| 2626 | break; | ||
| 2627 | |||
| 2628 | default: | ||
| 2629 | hr = E_UNEXPECTED; | ||
| 2630 | ExitOnFailure(hr, "Invalid restore related bundle action: %d.", pRestoreRelatedBundleAction->type); | ||
| 2631 | } | ||
| 2632 | |||
| 2633 | if (*pRestart < restart) | ||
| 2634 | { | ||
| 2635 | *pRestart = restart; | ||
| 2636 | } | ||
| 2637 | } | ||
| 2638 | |||
| 2639 | LExit: | ||
| 2640 | return hr; | ||
| 2641 | } | ||
| 2642 | |||
| 2593 | static HRESULT ExecuteExePackage( | 2643 | static HRESULT ExecuteExePackage( |
| 2594 | __in BURN_ENGINE_STATE* pEngineState, | 2644 | __in BURN_ENGINE_STATE* pEngineState, |
| 2595 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 2645 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp index cd84601f..b5fc51e5 100644 --- a/src/burn/engine/bundlepackageengine.cpp +++ b/src/burn/engine/bundlepackageengine.cpp | |||
| @@ -51,7 +51,7 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage( | |||
| 51 | execute = BOOTSTRAPPER_ACTION_STATE_NONE; | 51 | execute = BOOTSTRAPPER_ACTION_STATE_NONE; |
| 52 | break; | 52 | break; |
| 53 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | 53 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: |
| 54 | execute = pPackage->Bundle.fRepairable ? BOOTSTRAPPER_ACTION_STATE_REPAIR : BOOTSTRAPPER_ACTION_STATE_NONE; | 54 | execute = BOOTSTRAPPER_ACTION_STATE_REPAIR; |
| 55 | break; | 55 | break; |
| 56 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; | 56 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; |
| 57 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: | 57 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: |
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 7f7a915e..8fac7bd0 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
| @@ -558,7 +558,7 @@ extern "C" HRESULT CorePlan( | |||
| 558 | ExitOnFailure(hr, "Failed to plan packages."); | 558 | ExitOnFailure(hr, "Failed to plan packages."); |
| 559 | 559 | ||
| 560 | // Schedule the update of related bundles last. | 560 | // Schedule the update of related bundles last. |
| 561 | hr = PlanRelatedBundlesComplete(&pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, dwExecuteActionEarlyIndex); | 561 | hr = PlanRelatedBundlesComplete(&pEngineState->userExperience, &pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, dwExecuteActionEarlyIndex); |
| 562 | ExitOnFailure(hr, "Failed to schedule related bundles."); | 562 | ExitOnFailure(hr, "Failed to schedule related bundles."); |
| 563 | } | 563 | } |
| 564 | } | 564 | } |
| @@ -2309,7 +2309,7 @@ static void LogRelatedBundles( | |||
| 2309 | 2309 | ||
| 2310 | if (pRelatedBundle->fPlannable) | 2310 | if (pRelatedBundle->fPlannable) |
| 2311 | { | 2311 | { |
| 2312 | LogId(REPORT_STANDARD, MSG_PLANNED_RELATED_BUNDLE, pPackage->sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingDependencyActionToString(pPackage->dependencyExecute)); | 2312 | LogId(REPORT_STANDARD, MSG_PLANNED_RELATED_BUNDLE, pPackage->sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingRequestStateToString(pRelatedBundle->defaultRequestedRestore), LoggingRequestStateToString(pRelatedBundle->requestedRestore), LoggingActionStateToString(pRelatedBundle->restore), LoggingDependencyActionToString(pPackage->dependencyExecute)); |
| 2313 | } | 2313 | } |
| 2314 | } | 2314 | } |
| 2315 | } | 2315 | } |
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index b8c9a2d3..675a5644 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc | |||
| @@ -352,13 +352,6 @@ Language=English | |||
| 352 | Planned package: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, default cache strategy: %7!hs!, ba requested strategy: %8!hs!, cache: %9!hs!, uncache: %10!hs!, dependency: %11!hs!, expected install registration state: %12!hs!, expected cache registration state: %13!hs! | 352 | Planned package: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, default cache strategy: %7!hs!, ba requested strategy: %8!hs!, cache: %9!hs!, uncache: %10!hs!, dependency: %11!hs!, expected install registration state: %12!hs!, expected cache registration state: %13!hs! |
| 353 | . | 353 | . |
| 354 | 354 | ||
| 355 | MessageId=202 | ||
| 356 | Severity=Success | ||
| 357 | SymbolicName=MSG_PLANNED_BUNDLE_UX_CHANGED_REQUEST | ||
| 358 | Language=English | ||
| 359 | Planned bundle: %1!ls!, ba requested state: %2!hs! over default: %3!hs! | ||
| 360 | . | ||
| 361 | |||
| 362 | MessageId=203 | 355 | MessageId=203 |
| 363 | Severity=Success | 356 | Severity=Success |
| 364 | SymbolicName=MSG_PLANNED_MSI_FEATURE | 357 | SymbolicName=MSG_PLANNED_MSI_FEATURE |
| @@ -391,7 +384,7 @@ MessageId=207 | |||
| 391 | Severity=Success | 384 | Severity=Success |
| 392 | SymbolicName=MSG_PLANNED_RELATED_BUNDLE | 385 | SymbolicName=MSG_PLANNED_RELATED_BUNDLE |
| 393 | Language=English | 386 | Language=English |
| 394 | Planned related bundle: %1!ls!, type: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, dependency: %7!hs! | 387 | Planned related bundle: %1!ls!, type: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, default requested restore: %7!hs!, ba requested restore: %8!hs!, restore: %9!hs!, dependency: %10!hs! |
| 395 | . | 388 | . |
| 396 | 389 | ||
| 397 | MessageId=208 | 390 | MessageId=208 |
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 6d1b5dd9..1e61d92b 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
| @@ -309,7 +309,6 @@ typedef struct _BURN_PACKAGE | |||
| 309 | LPCWSTR wzAncestors; // points directly into engine state. | 309 | LPCWSTR wzAncestors; // points directly into engine state. |
| 310 | LPCWSTR wzEngineWorkingDirectory; // points directly into engine state. | 310 | LPCWSTR wzEngineWorkingDirectory; // points directly into engine state. |
| 311 | 311 | ||
| 312 | BOOL fRepairable; | ||
| 313 | BOOL fSupportsBurnProtocol; | 312 | BOOL fSupportsBurnProtocol; |
| 314 | 313 | ||
| 315 | BURN_EXE_EXIT_CODE* rgExitCodes; | 314 | BURN_EXE_EXIT_CODE* rgExitCodes; |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index f850d49c..f1fb87b8 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
| @@ -103,6 +103,10 @@ static HRESULT AppendCleanAction( | |||
| 103 | __in BURN_PLAN* pPlan, | 103 | __in BURN_PLAN* pPlan, |
| 104 | __out BURN_CLEAN_ACTION** ppCleanAction | 104 | __out BURN_CLEAN_ACTION** ppCleanAction |
| 105 | ); | 105 | ); |
| 106 | static HRESULT AppendRestoreRelatedBundleAction( | ||
| 107 | __in BURN_PLAN* pPlan, | ||
| 108 | __out BURN_EXECUTE_ACTION** ppExecuteAction | ||
| 109 | ); | ||
| 106 | static HRESULT ProcessPayloadGroup( | 110 | static HRESULT ProcessPayloadGroup( |
| 107 | __in BURN_PLAN* pPlan, | 111 | __in BURN_PLAN* pPlan, |
| 108 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | 112 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
| @@ -196,6 +200,15 @@ extern "C" void PlanReset( | |||
| 196 | MemFree(pPlan->rgRollbackActions); | 200 | MemFree(pPlan->rgRollbackActions); |
| 197 | } | 201 | } |
| 198 | 202 | ||
| 203 | if (pPlan->rgRestoreRelatedBundleActions) | ||
| 204 | { | ||
| 205 | for (DWORD i = 0; i < pPlan->cRestoreRelatedBundleActions; ++i) | ||
| 206 | { | ||
| 207 | PlanUninitializeExecuteAction(&pPlan->rgRestoreRelatedBundleActions[i]); | ||
| 208 | } | ||
| 209 | MemFree(pPlan->rgRestoreRelatedBundleActions); | ||
| 210 | } | ||
| 211 | |||
| 199 | if (pPlan->rgCleanActions) | 212 | if (pPlan->rgCleanActions) |
| 200 | { | 213 | { |
| 201 | // Nothing needs to be freed inside clean actions today. | 214 | // Nothing needs to be freed inside clean actions today. |
| @@ -1276,6 +1289,9 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
| 1276 | continue; | 1289 | continue; |
| 1277 | } | 1290 | } |
| 1278 | 1291 | ||
| 1292 | pRelatedBundle->defaultRequestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 1293 | pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 1294 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1279 | pRelatedBundle->package.defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1295 | pRelatedBundle->package.defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; |
| 1280 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1296 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; |
| 1281 | 1297 | ||
| @@ -1312,12 +1328,6 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
| 1312 | hr = UserExperienceOnPlanRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->package.requested); | 1328 | hr = UserExperienceOnPlanRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->package.requested); |
| 1313 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); | 1329 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); |
| 1314 | 1330 | ||
| 1315 | // Log when the BA changed the bundle state so the engine doesn't get blamed for planning the wrong thing. | ||
| 1316 | if (pRelatedBundle->package.requested != pRelatedBundle->package.defaultRequested) | ||
| 1317 | { | ||
| 1318 | LogId(REPORT_STANDARD, MSG_PLANNED_BUNDLE_UX_CHANGED_REQUEST, pRelatedBundle->package.sczId, LoggingRequestStateToString(pRelatedBundle->package.requested), LoggingRequestStateToString(pRelatedBundle->package.defaultRequested)); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. | 1331 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. |
| 1322 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) | 1332 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) |
| 1323 | { | 1333 | { |
| @@ -1340,6 +1350,7 @@ LExit: | |||
| 1340 | } | 1350 | } |
| 1341 | 1351 | ||
| 1342 | extern "C" HRESULT PlanRelatedBundlesComplete( | 1352 | extern "C" HRESULT PlanRelatedBundlesComplete( |
| 1353 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 1343 | __in BURN_REGISTRATION* pRegistration, | 1354 | __in BURN_REGISTRATION* pRegistration, |
| 1344 | __in BURN_PLAN* pPlan, | 1355 | __in BURN_PLAN* pPlan, |
| 1345 | __in BURN_LOGGING* pLog, | 1356 | __in BURN_LOGGING* pLog, |
| @@ -1359,16 +1370,19 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1359 | ExitOnFailure(hr, "Failed to create dictionary for planned packages."); | 1370 | ExitOnFailure(hr, "Failed to create dictionary for planned packages."); |
| 1360 | 1371 | ||
| 1361 | BOOL fExecutingAnyPackage = FALSE; | 1372 | BOOL fExecutingAnyPackage = FALSE; |
| 1373 | BOOL fInstallingAnyPackage = FALSE; | ||
| 1362 | 1374 | ||
| 1363 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) | 1375 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) |
| 1364 | { | 1376 | { |
| 1377 | BOOTSTRAPPER_ACTION_STATE packageAction = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1378 | |||
| 1365 | switch (pPlan->rgExecuteActions[i].type) | 1379 | switch (pPlan->rgExecuteActions[i].type) |
| 1366 | { | 1380 | { |
| 1367 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | 1381 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: |
| 1368 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].relatedBundle.action) | 1382 | packageAction = pPlan->rgExecuteActions[i].relatedBundle.action; |
| 1369 | { | ||
| 1370 | fExecutingAnyPackage = TRUE; | ||
| 1371 | 1383 | ||
| 1384 | if (BOOTSTRAPPER_ACTION_STATE_NONE != packageAction) | ||
| 1385 | { | ||
| 1372 | BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package; | 1386 | BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package; |
| 1373 | if (pPackage->cDependencyProviders) | 1387 | if (pPackage->cDependencyProviders) |
| 1374 | { | 1388 | { |
| @@ -1380,21 +1394,24 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1380 | break; | 1394 | break; |
| 1381 | 1395 | ||
| 1382 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 1396 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
| 1383 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].exePackage.action); | 1397 | packageAction = pPlan->rgExecuteActions[i].exePackage.action; |
| 1384 | break; | 1398 | break; |
| 1385 | 1399 | ||
| 1386 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: | 1400 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: |
| 1387 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msiPackage.action); | 1401 | packageAction = pPlan->rgExecuteActions[i].msiPackage.action; |
| 1388 | break; | 1402 | break; |
| 1389 | 1403 | ||
| 1390 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: | 1404 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: |
| 1391 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].mspTarget.action); | 1405 | packageAction = pPlan->rgExecuteActions[i].mspTarget.action; |
| 1392 | break; | 1406 | break; |
| 1393 | 1407 | ||
| 1394 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: | 1408 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: |
| 1395 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msuPackage.action); | 1409 | packageAction = pPlan->rgExecuteActions[i].msuPackage.action; |
| 1396 | break; | 1410 | break; |
| 1397 | } | 1411 | } |
| 1412 | |||
| 1413 | fExecutingAnyPackage |= BOOTSTRAPPER_ACTION_STATE_NONE != packageAction; | ||
| 1414 | fInstallingAnyPackage |= BOOTSTRAPPER_ACTION_STATE_INSTALL == packageAction || BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE == packageAction; | ||
| 1398 | } | 1415 | } |
| 1399 | 1416 | ||
| 1400 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | 1417 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) |
| @@ -1492,6 +1509,62 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1492 | hr = DependencyPlanPackageComplete(&pRelatedBundle->package, pPlan); | 1509 | hr = DependencyPlanPackageComplete(&pRelatedBundle->package, pPlan); |
| 1493 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); | 1510 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); |
| 1494 | } | 1511 | } |
| 1512 | |||
| 1513 | if (fInstallingAnyPackage && BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->relationType) | ||
| 1514 | { | ||
| 1515 | BURN_EXECUTE_ACTION* pAction = NULL; | ||
| 1516 | |||
| 1517 | pRelatedBundle->defaultRequestedRestore = pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; | ||
| 1518 | |||
| 1519 | hr = UserExperienceOnPlanRestoreRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->requestedRestore); | ||
| 1520 | ExitOnRootFailure(hr, "BA aborted plan restore related bundle."); | ||
| 1521 | |||
| 1522 | switch (pRelatedBundle->requestedRestore) | ||
| 1523 | { | ||
| 1524 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
| 1525 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_REPAIR; | ||
| 1526 | break; | ||
| 1527 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; | ||
| 1528 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: __fallthrough; | ||
| 1529 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: | ||
| 1530 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; | ||
| 1531 | break; | ||
| 1532 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: | ||
| 1533 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_INSTALL; | ||
| 1534 | break; | ||
| 1535 | default: | ||
| 1536 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1537 | break; | ||
| 1538 | } | ||
| 1539 | |||
| 1540 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pRelatedBundle->restore) | ||
| 1541 | { | ||
| 1542 | hr = AppendRestoreRelatedBundleAction(pPlan, &pAction); | ||
| 1543 | ExitOnFailure(hr, "Failed to append restore related bundle action to plan."); | ||
| 1544 | |||
| 1545 | pAction->type = BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE; | ||
| 1546 | pAction->relatedBundle.pRelatedBundle = pRelatedBundle; | ||
| 1547 | pAction->relatedBundle.action = pRelatedBundle->restore; | ||
| 1548 | |||
| 1549 | if (pRelatedBundle->package.Bundle.sczIgnoreDependencies) | ||
| 1550 | { | ||
| 1551 | hr = StrAllocString(&pAction->relatedBundle.sczIgnoreDependencies, pRelatedBundle->package.Bundle.sczIgnoreDependencies, 0); | ||
| 1552 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | if (pRelatedBundle->package.Bundle.wzAncestors) | ||
| 1556 | { | ||
| 1557 | hr = StrAllocString(&pAction->relatedBundle.sczAncestors, pRelatedBundle->package.Bundle.wzAncestors, 0); | ||
| 1558 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | if (pRelatedBundle->package.Bundle.wzEngineWorkingDirectory) | ||
| 1562 | { | ||
| 1563 | hr = StrAllocString(&pAction->relatedBundle.sczEngineWorkingDirectory, pRelatedBundle->package.Bundle.wzEngineWorkingDirectory, 0); | ||
| 1564 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); | ||
| 1565 | } | ||
| 1566 | } | ||
| 1567 | } | ||
| 1495 | } | 1568 | } |
| 1496 | 1569 | ||
| 1497 | LExit: | 1570 | LExit: |
| @@ -2269,6 +2342,23 @@ LExit: | |||
| 2269 | return hr; | 2342 | return hr; |
| 2270 | } | 2343 | } |
| 2271 | 2344 | ||
| 2345 | static HRESULT AppendRestoreRelatedBundleAction( | ||
| 2346 | __in BURN_PLAN* pPlan, | ||
| 2347 | __out BURN_EXECUTE_ACTION** ppExecuteAction | ||
| 2348 | ) | ||
| 2349 | { | ||
| 2350 | HRESULT hr = S_OK; | ||
| 2351 | |||
| 2352 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pPlan->rgRestoreRelatedBundleActions), pPlan->cRestoreRelatedBundleActions, 1, sizeof(BURN_EXECUTE_ACTION), 5); | ||
| 2353 | ExitOnFailure(hr, "Failed to grow plan's array of restore related bundle actions."); | ||
| 2354 | |||
| 2355 | *ppExecuteAction = pPlan->rgRestoreRelatedBundleActions + pPlan->cRestoreRelatedBundleActions; | ||
| 2356 | ++pPlan->cRestoreRelatedBundleActions; | ||
| 2357 | |||
| 2358 | LExit: | ||
| 2359 | return hr; | ||
| 2360 | } | ||
| 2361 | |||
| 2272 | static HRESULT ProcessPayloadGroup( | 2362 | static HRESULT ProcessPayloadGroup( |
| 2273 | __in BURN_PLAN* pPlan, | 2363 | __in BURN_PLAN* pPlan, |
| 2274 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | 2364 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
| @@ -2725,6 +2815,28 @@ static void ExecuteActionLog( | |||
| 2725 | } | 2815 | } |
| 2726 | } | 2816 | } |
| 2727 | 2817 | ||
| 2818 | static void RestoreRelatedBundleActionLog( | ||
| 2819 | __in DWORD iAction, | ||
| 2820 | __in BURN_EXECUTE_ACTION* pAction | ||
| 2821 | ) | ||
| 2822 | { | ||
| 2823 | switch (pAction->type) | ||
| 2824 | { | ||
| 2825 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
| 2826 | LogStringLine(PlanDumpLevel, "Restore action[%u]: RELATED_BUNDLE package id: %ls, action: %hs, ignore dependencies: %ls", iAction, pAction->relatedBundle.pRelatedBundle->package.sczId, LoggingActionStateToString(pAction->relatedBundle.action), pAction->relatedBundle.sczIgnoreDependencies); | ||
| 2827 | break; | ||
| 2828 | |||
| 2829 | default: | ||
| 2830 | AssertSz(FALSE, "Unknown execute action type."); | ||
| 2831 | break; | ||
| 2832 | } | ||
| 2833 | |||
| 2834 | if (pAction->fDeleted) | ||
| 2835 | { | ||
| 2836 | LogStringLine(PlanDumpLevel, " (deleted action)"); | ||
| 2837 | } | ||
| 2838 | } | ||
| 2839 | |||
| 2728 | static void CleanActionLog( | 2840 | static void CleanActionLog( |
| 2729 | __in DWORD iAction, | 2841 | __in DWORD iAction, |
| 2730 | __in BURN_CLEAN_ACTION* pAction | 2842 | __in BURN_CLEAN_ACTION* pAction |
| @@ -2784,6 +2896,11 @@ extern "C" void PlanDump( | |||
| 2784 | ExecuteActionLog(i, pPlan->rgRollbackActions + i, TRUE); | 2896 | ExecuteActionLog(i, pPlan->rgRollbackActions + i, TRUE); |
| 2785 | } | 2897 | } |
| 2786 | 2898 | ||
| 2899 | for (DWORD i = 0; i < pPlan->cRestoreRelatedBundleActions; ++i) | ||
| 2900 | { | ||
| 2901 | RestoreRelatedBundleActionLog(i, pPlan->rgRestoreRelatedBundleActions + i); | ||
| 2902 | } | ||
| 2903 | |||
| 2787 | for (DWORD i = 0; i < pPlan->cCleanActions; ++i) | 2904 | for (DWORD i = 0; i < pPlan->cCleanActions; ++i) |
| 2788 | { | 2905 | { |
| 2789 | CleanActionLog(i, pPlan->rgCleanActions + i); | 2906 | CleanActionLog(i, pPlan->rgCleanActions + i); |
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index 0734e39f..3dce8e5d 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h | |||
| @@ -280,6 +280,9 @@ typedef struct _BURN_PLAN | |||
| 280 | BURN_EXECUTE_ACTION* rgRollbackActions; | 280 | BURN_EXECUTE_ACTION* rgRollbackActions; |
| 281 | DWORD cRollbackActions; | 281 | DWORD cRollbackActions; |
| 282 | 282 | ||
| 283 | BURN_EXECUTE_ACTION* rgRestoreRelatedBundleActions; | ||
| 284 | DWORD cRestoreRelatedBundleActions; | ||
| 285 | |||
| 283 | BURN_CLEAN_ACTION* rgCleanActions; | 286 | BURN_CLEAN_ACTION* rgCleanActions; |
| 284 | DWORD cCleanActions; | 287 | DWORD cCleanActions; |
| 285 | 288 | ||
| @@ -394,6 +397,7 @@ HRESULT PlanRelatedBundlesBegin( | |||
| 394 | __in BURN_PLAN* pPlan | 397 | __in BURN_PLAN* pPlan |
| 395 | ); | 398 | ); |
| 396 | HRESULT PlanRelatedBundlesComplete( | 399 | HRESULT PlanRelatedBundlesComplete( |
| 400 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 397 | __in BURN_REGISTRATION* pRegistration, | 401 | __in BURN_REGISTRATION* pRegistration, |
| 398 | __in BURN_PLAN* pPlan, | 402 | __in BURN_PLAN* pPlan, |
| 399 | __in BURN_LOGGING* pLog, | 403 | __in BURN_LOGGING* pLog, |
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index 94b095c5..082c4487 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp | |||
| @@ -51,7 +51,6 @@ extern "C" HRESULT PseudoBundleInitializeRelated( | |||
| 51 | pPackage->fVital = FALSE; | 51 | pPackage->fVital = FALSE; |
| 52 | 52 | ||
| 53 | pPackage->fPermanent = FALSE; | 53 | pPackage->fPermanent = FALSE; |
| 54 | pPackage->Bundle.fRepairable = TRUE; | ||
| 55 | pPackage->Bundle.fSupportsBurnProtocol = fSupportsBurnProtocol; | 54 | pPackage->Bundle.fSupportsBurnProtocol = fSupportsBurnProtocol; |
| 56 | 55 | ||
| 57 | hr = StrAllocString(&pPackage->sczId, wzId, 0); | 56 | hr = StrAllocString(&pPackage->sczId, wzId, 0); |
diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h index 0ae61974..64191828 100644 --- a/src/burn/engine/registration.h +++ b/src/burn/engine/registration.h | |||
| @@ -61,6 +61,10 @@ typedef struct _BURN_RELATED_BUNDLE | |||
| 61 | BOOL fPlannable; | 61 | BOOL fPlannable; |
| 62 | 62 | ||
| 63 | BURN_PACKAGE package; | 63 | BURN_PACKAGE package; |
| 64 | |||
| 65 | BOOTSTRAPPER_REQUEST_STATE defaultRequestedRestore; | ||
| 66 | BOOTSTRAPPER_REQUEST_STATE requestedRestore; | ||
| 67 | BOOTSTRAPPER_ACTION_STATE restore; | ||
| 64 | } BURN_RELATED_BUNDLE; | 68 | } BURN_RELATED_BUNDLE; |
| 65 | 69 | ||
| 66 | typedef struct _BURN_RELATED_BUNDLES | 70 | typedef struct _BURN_RELATED_BUNDLES |
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp index 1439f5f2..59988bef 100644 --- a/src/burn/engine/userexperience.cpp +++ b/src/burn/engine/userexperience.cpp | |||
| @@ -2176,6 +2176,36 @@ LExit: | |||
| 2176 | return hr; | 2176 | return hr; |
| 2177 | } | 2177 | } |
| 2178 | 2178 | ||
| 2179 | EXTERN_C BAAPI UserExperienceOnPlanRestoreRelatedBundle( | ||
| 2180 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 2181 | __in_z LPCWSTR wzBundleId, | ||
| 2182 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState | ||
| 2183 | ) | ||
| 2184 | { | ||
| 2185 | HRESULT hr = S_OK; | ||
| 2186 | BA_ONPLANRESTORERELATEDBUNDLE_ARGS args = { }; | ||
| 2187 | BA_ONPLANRESTORERELATEDBUNDLE_RESULTS results = { }; | ||
| 2188 | |||
| 2189 | args.cbSize = sizeof(args); | ||
| 2190 | args.wzBundleId = wzBundleId; | ||
| 2191 | args.recommendedState = *pRequestedState; | ||
| 2192 | |||
| 2193 | results.cbSize = sizeof(results); | ||
| 2194 | results.requestedState = *pRequestedState; | ||
| 2195 | |||
| 2196 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE, &args, &results); | ||
| 2197 | ExitOnFailure(hr, "BA OnPlanRestoreRelatedBundle failed."); | ||
| 2198 | |||
| 2199 | if (results.fCancel) | ||
| 2200 | { | ||
| 2201 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
| 2202 | } | ||
| 2203 | *pRequestedState = results.requestedState; | ||
| 2204 | |||
| 2205 | LExit: | ||
| 2206 | return hr; | ||
| 2207 | } | ||
| 2208 | |||
| 2179 | EXTERN_C BAAPI UserExperienceOnPlanRollbackBoundary( | 2209 | EXTERN_C BAAPI UserExperienceOnPlanRollbackBoundary( |
| 2180 | __in BURN_USER_EXPERIENCE* pUserExperience, | 2210 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 2181 | __in_z LPCWSTR wzRollbackBoundaryId, | 2211 | __in_z LPCWSTR wzRollbackBoundaryId, |
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h index e8341120..8106d7f7 100644 --- a/src/burn/engine/userexperience.h +++ b/src/burn/engine/userexperience.h | |||
| @@ -497,6 +497,11 @@ BAAPI UserExperienceOnPlanRelatedBundle( | |||
| 497 | __in_z LPCWSTR wzBundleId, | 497 | __in_z LPCWSTR wzBundleId, |
| 498 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState | 498 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState |
| 499 | ); | 499 | ); |
| 500 | BAAPI UserExperienceOnPlanRestoreRelatedBundle( | ||
| 501 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 502 | __in_z LPCWSTR wzBundleId, | ||
| 503 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState | ||
| 504 | ); | ||
| 500 | BAAPI UserExperienceOnPlanRollbackBoundary( | 505 | BAAPI UserExperienceOnPlanRollbackBoundary( |
| 501 | __in BURN_USER_EXPERIENCE* pUserExperience, | 506 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 502 | __in_z LPCWSTR wzRollbackBoundaryId, | 507 | __in_z LPCWSTR wzRollbackBoundaryId, |
