diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-02-22 20:23:43 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-02-22 23:37:57 -0600 |
commit | 8e8f724d90c6835febb8b5865009746aea73a334 (patch) | |
tree | b255c0a7232af8d24bcf44fd476b95bdfdcfe777 /src/burn/engine/plan.cpp | |
parent | 0740d93ca8be06ec0e5da5b51ceff52f67ab5bf5 (diff) | |
download | wix-8e8f724d90c6835febb8b5865009746aea73a334.tar.gz wix-8e8f724d90c6835febb8b5865009746aea73a334.tar.bz2 wix-8e8f724d90c6835febb8b5865009746aea73a334.zip |
Add UnsafeUninstall action.
Fixes #6721
Diffstat (limited to 'src/burn/engine/plan.cpp')
-rw-r--r-- | src/burn/engine/plan.cpp | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index f1fb87b8..49dd83f4 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
@@ -361,13 +361,15 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
361 | else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) | 361 | else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) |
362 | { | 362 | { |
363 | // For patch related bundles, only install a patch if currently absent during install, modify, or repair. | 363 | // For patch related bundles, only install a patch if currently absent during install, modify, or repair. |
364 | if (BOOTSTRAPPER_PACKAGE_STATE_ABSENT == currentState && BOOTSTRAPPER_ACTION_INSTALL <= action) | 364 | if (BOOTSTRAPPER_PACKAGE_STATE_ABSENT != currentState) |
365 | { | 365 | { |
366 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | 366 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; |
367 | } | 367 | } |
368 | else | 368 | else if (BOOTSTRAPPER_ACTION_INSTALL == action || |
369 | BOOTSTRAPPER_ACTION_MODIFY == action || | ||
370 | BOOTSTRAPPER_ACTION_REPAIR == action) | ||
369 | { | 371 | { |
370 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | 372 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; |
371 | } | 373 | } |
372 | } | 374 | } |
373 | else // pick the best option for the action state and install condition. | 375 | else // pick the best option for the action state and install condition. |
@@ -375,7 +377,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
375 | hr = GetActionDefaultRequestState(action, currentState, &defaultRequestState); | 377 | hr = GetActionDefaultRequestState(action, currentState, &defaultRequestState); |
376 | ExitOnFailure(hr, "Failed to get default request state for action."); | 378 | ExitOnFailure(hr, "Failed to get default request state for action."); |
377 | 379 | ||
378 | if (BOOTSTRAPPER_ACTION_UNINSTALL != action) | 380 | if (BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL != action) |
379 | { | 381 | { |
380 | // If we're not doing an uninstall, use the install condition | 382 | // If we're not doing an uninstall, use the install condition |
381 | // to determine whether to use the default request state or make the package absent. | 383 | // to determine whether to use the default request state or make the package absent. |
@@ -485,7 +487,8 @@ extern "C" HRESULT PlanForwardCompatibleBundles( | |||
485 | { | 487 | { |
486 | fRecommendIgnore = FALSE; | 488 | fRecommendIgnore = FALSE; |
487 | } | 489 | } |
488 | else if (BOOTSTRAPPER_ACTION_UNINSTALL == action || | 490 | else if (BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == action || |
491 | BOOTSTRAPPER_ACTION_UNINSTALL == action || | ||
489 | BOOTSTRAPPER_ACTION_MODIFY == action || | 492 | BOOTSTRAPPER_ACTION_MODIFY == action || |
490 | BOOTSTRAPPER_ACTION_REPAIR == action) | 493 | BOOTSTRAPPER_ACTION_REPAIR == action) |
491 | { | 494 | { |
@@ -552,10 +555,10 @@ extern "C" HRESULT PlanRegistration( | |||
552 | HRESULT hr = S_OK; | 555 | HRESULT hr = S_OK; |
553 | STRINGDICT_HANDLE sdBundleDependents = NULL; | 556 | STRINGDICT_HANDLE sdBundleDependents = NULL; |
554 | STRINGDICT_HANDLE sdIgnoreDependents = NULL; | 557 | STRINGDICT_HANDLE sdIgnoreDependents = NULL; |
558 | BOOL fDependentBlocksUninstall = FALSE; | ||
555 | 559 | ||
556 | pPlan->fCanAffectMachineState = TRUE; // register the bundle since we're modifying machine state. | 560 | pPlan->fCanAffectMachineState = TRUE; // register the bundle since we're modifying machine state. |
557 | pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed | 561 | pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed |
558 | pPlan->fIgnoreAllDependents = pDependencies->fIgnoreAllDependents; | ||
559 | 562 | ||
560 | // Ensure the bundle is cached if not running from the cache. | 563 | // Ensure the bundle is cached if not running from the cache. |
561 | if (!CacheBundleRunningFromCache(pPlan->pCache)) | 564 | if (!CacheBundleRunningFromCache(pPlan->pCache)) |
@@ -563,7 +566,7 @@ extern "C" HRESULT PlanRegistration( | |||
563 | pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE; | 566 | pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE; |
564 | } | 567 | } |
565 | 568 | ||
566 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) | 569 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pPlan->action) |
567 | { | 570 | { |
568 | // If our provider key was not owned by a different bundle, | 571 | // If our provider key was not owned by a different bundle, |
569 | // then plan to write our provider key registration to "fix it" if broken | 572 | // then plan to write our provider key registration to "fix it" if broken |
@@ -588,7 +591,7 @@ extern "C" HRESULT PlanRegistration( | |||
588 | ExitOnFailure(hr, "Failed to add self-dependent to ignore dependents."); | 591 | ExitOnFailure(hr, "Failed to add self-dependent to ignore dependents."); |
589 | } | 592 | } |
590 | 593 | ||
591 | if (!pPlan->fIgnoreAllDependents) | 594 | if (!pDependencies->fIgnoreAllDependents) |
592 | { | 595 | { |
593 | // If we are not doing an upgrade, we check to see if there are still dependents on us and if so we skip planning. | 596 | // If we are not doing an upgrade, we check to see if there are still dependents on us and if so we skip planning. |
594 | // However, when being upgraded, we always execute our uninstall because a newer version of us is probably | 597 | // However, when being upgraded, we always execute our uninstall because a newer version of us is probably |
@@ -641,10 +644,9 @@ extern "C" HRESULT PlanRegistration( | |||
641 | hr = S_OK; | 644 | hr = S_OK; |
642 | 645 | ||
643 | // TODO: callback to the BA and let it have the option to ignore this dependent? | 646 | // TODO: callback to the BA and let it have the option to ignore this dependent? |
644 | if (!pPlan->fDisallowRemoval) | 647 | if (!fDependentBlocksUninstall) |
645 | { | 648 | { |
646 | pPlan->fDisallowRemoval = TRUE; // ensure the registration stays | 649 | fDependentBlocksUninstall = TRUE; |
647 | *pfContinuePlanning = FALSE; // skip the rest of planning. | ||
648 | 650 | ||
649 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DUE_TO_DEPENDENTS); | 651 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DUE_TO_DEPENDENTS); |
650 | } | 652 | } |
@@ -653,6 +655,20 @@ extern "C" HRESULT PlanRegistration( | |||
653 | } | 655 | } |
654 | ExitOnFailure(hr, "Failed to check for remaining dependents during planning."); | 656 | ExitOnFailure(hr, "Failed to check for remaining dependents during planning."); |
655 | } | 657 | } |
658 | |||
659 | if (fDependentBlocksUninstall) | ||
660 | { | ||
661 | if (BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pPlan->action) | ||
662 | { | ||
663 | fDependentBlocksUninstall = FALSE; | ||
664 | LogId(REPORT_STANDARD, MSG_PLAN_NOT_SKIPPED_DUE_TO_DEPENDENTS); | ||
665 | } | ||
666 | else | ||
667 | { | ||
668 | pPlan->fDisallowRemoval = TRUE; // ensure the registration stays | ||
669 | *pfContinuePlanning = FALSE; // skip the rest of planning. | ||
670 | } | ||
671 | } | ||
656 | } | 672 | } |
657 | } | 673 | } |
658 | } | 674 | } |
@@ -776,11 +792,12 @@ static HRESULT PlanPackagesHelper( | |||
776 | HRESULT hr = S_OK; | 792 | HRESULT hr = S_OK; |
777 | BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine. | 793 | BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine. |
778 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; | 794 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; |
795 | BOOL fReverseOrder = BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pPlan->action; | ||
779 | 796 | ||
780 | // Initialize the packages. | 797 | // Initialize the packages. |
781 | for (DWORD i = 0; i < cPackages; ++i) | 798 | for (DWORD i = 0; i < cPackages; ++i) |
782 | { | 799 | { |
783 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; | 800 | DWORD iPackage = fReverseOrder ? cPackages - 1 - i : i; |
784 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 801 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
785 | 802 | ||
786 | hr = InitializePackage(pPlan, pUX, pVariables, pPackage); | 803 | hr = InitializePackage(pPlan, pUX, pVariables, pPackage); |
@@ -790,7 +807,7 @@ static HRESULT PlanPackagesHelper( | |||
790 | // Initialize the patch targets after all packages, since they could rely on the requested state of packages that are after the patch's package in the chain. | 807 | // Initialize the patch targets after all packages, since they could rely on the requested state of packages that are after the patch's package in the chain. |
791 | for (DWORD i = 0; i < cPackages; ++i) | 808 | for (DWORD i = 0; i < cPackages; ++i) |
792 | { | 809 | { |
793 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; | 810 | DWORD iPackage = fReverseOrder ? cPackages - 1 - i : i; |
794 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 811 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
795 | 812 | ||
796 | if (BURN_PACKAGE_TYPE_MSP == pPackage->type) | 813 | if (BURN_PACKAGE_TYPE_MSP == pPackage->type) |
@@ -803,7 +820,7 @@ static HRESULT PlanPackagesHelper( | |||
803 | // Plan the packages. | 820 | // Plan the packages. |
804 | for (DWORD i = 0; i < cPackages; ++i) | 821 | for (DWORD i = 0; i < cPackages; ++i) |
805 | { | 822 | { |
806 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; | 823 | DWORD iPackage = fReverseOrder ? cPackages - 1 - i : i; |
807 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 824 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
808 | 825 | ||
809 | hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, &pRollbackBoundary); | 826 | hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, &pRollbackBoundary); |
@@ -825,7 +842,7 @@ static HRESULT PlanPackagesHelper( | |||
825 | // Plan clean up of packages. | 842 | // Plan clean up of packages. |
826 | for (DWORD i = 0; i < cPackages; ++i) | 843 | for (DWORD i = 0; i < cPackages; ++i) |
827 | { | 844 | { |
828 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; | 845 | DWORD iPackage = fReverseOrder ? cPackages - 1 - i : i; |
829 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 846 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
830 | 847 | ||
831 | hr = PlanCleanPackage(pPlan, pPackage); | 848 | hr = PlanCleanPackage(pPlan, pPackage); |
@@ -842,7 +859,7 @@ static HRESULT PlanPackagesHelper( | |||
842 | // Let the BA know the actions that were planned. | 859 | // Let the BA know the actions that were planned. |
843 | for (DWORD i = 0; i < cPackages; ++i) | 860 | for (DWORD i = 0; i < cPackages; ++i) |
844 | { | 861 | { |
845 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; | 862 | DWORD iPackage = fReverseOrder ? cPackages - 1 - i : i; |
846 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 863 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
847 | 864 | ||
848 | UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache); | 865 | UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache); |
@@ -931,8 +948,9 @@ static HRESULT ProcessPackage( | |||
931 | { | 948 | { |
932 | HRESULT hr = S_OK; | 949 | HRESULT hr = S_OK; |
933 | BURN_ROLLBACK_BOUNDARY* pEffectiveRollbackBoundary = NULL; | 950 | BURN_ROLLBACK_BOUNDARY* pEffectiveRollbackBoundary = NULL; |
951 | BOOL fBackward = BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pPlan->action; | ||
934 | 952 | ||
935 | pEffectiveRollbackBoundary = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? pPackage->pRollbackBoundaryBackward : pPackage->pRollbackBoundaryForward; | 953 | pEffectiveRollbackBoundary = fBackward ? pPackage->pRollbackBoundaryBackward : pPackage->pRollbackBoundaryForward; |
936 | hr = ProcessPackageRollbackBoundary(pPlan, pUX, pLog, pVariables, pEffectiveRollbackBoundary, ppRollbackBoundary); | 954 | hr = ProcessPackageRollbackBoundary(pPlan, pUX, pLog, pVariables, pEffectiveRollbackBoundary, ppRollbackBoundary); |
937 | ExitOnFailure(hr, "Failed to process package rollback boundary."); | 955 | ExitOnFailure(hr, "Failed to process package rollback boundary."); |
938 | 956 | ||
@@ -1205,6 +1223,7 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | |||
1205 | { | 1223 | { |
1206 | HRESULT hr = S_OK; | 1224 | HRESULT hr = S_OK; |
1207 | int nCompareResult = 0; | 1225 | int nCompareResult = 0; |
1226 | BOOL fUninstalling = BOOTSTRAPPER_ACTION_UNINSTALL == action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == action; | ||
1208 | 1227 | ||
1209 | // Never touch related bundles during Cache. | 1228 | // Never touch related bundles during Cache. |
1210 | if (BOOTSTRAPPER_ACTION_CACHE == action) | 1229 | if (BOOTSTRAPPER_ACTION_CACHE == action) |
@@ -1215,7 +1234,7 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | |||
1215 | switch (relatedBundleRelationType) | 1234 | switch (relatedBundleRelationType) |
1216 | { | 1235 | { |
1217 | case BOOTSTRAPPER_RELATION_UPGRADE: | 1236 | case BOOTSTRAPPER_RELATION_UPGRADE: |
1218 | if (BOOTSTRAPPER_RELATION_UPGRADE != commandRelationType && BOOTSTRAPPER_ACTION_UNINSTALL < action) | 1237 | if (BOOTSTRAPPER_RELATION_UPGRADE != commandRelationType && !fUninstalling) |
1219 | { | 1238 | { |
1220 | hr = VerCompareParsedVersions(pRegistrationVersion, pRelatedBundleVersion, &nCompareResult); | 1239 | hr = VerCompareParsedVersions(pRegistrationVersion, pRelatedBundleVersion, &nCompareResult); |
1221 | ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistrationVersion ? pRegistrationVersion->sczVersion : NULL, pRelatedBundleVersion ? pRelatedBundleVersion->sczVersion : NULL); | 1240 | ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistrationVersion ? pRegistrationVersion->sczVersion : NULL, pRelatedBundleVersion ? pRelatedBundleVersion->sczVersion : NULL); |
@@ -1225,7 +1244,7 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | |||
1225 | break; | 1244 | break; |
1226 | case BOOTSTRAPPER_RELATION_PATCH: __fallthrough; | 1245 | case BOOTSTRAPPER_RELATION_PATCH: __fallthrough; |
1227 | case BOOTSTRAPPER_RELATION_ADDON: | 1246 | case BOOTSTRAPPER_RELATION_ADDON: |
1228 | if (BOOTSTRAPPER_ACTION_UNINSTALL == action) | 1247 | if (fUninstalling) |
1229 | { | 1248 | { |
1230 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; | 1249 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; |
1231 | } | 1250 | } |
@@ -1242,7 +1261,7 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | |||
1242 | // Automatically repair dependent bundles to restore missing | 1261 | // Automatically repair dependent bundles to restore missing |
1243 | // packages after uninstall unless we're being upgraded with the | 1262 | // packages after uninstall unless we're being upgraded with the |
1244 | // assumption that upgrades are cumulative (as intended). | 1263 | // assumption that upgrades are cumulative (as intended). |
1245 | if (BOOTSTRAPPER_RELATION_UPGRADE != commandRelationType && BOOTSTRAPPER_ACTION_UNINSTALL == action) | 1264 | if (BOOTSTRAPPER_RELATION_UPGRADE != commandRelationType && fUninstalling) |
1246 | { | 1265 | { |
1247 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_REPAIR; | 1266 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_REPAIR; |
1248 | } | 1267 | } |
@@ -1270,6 +1289,7 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
1270 | LPWSTR* rgsczAncestors = NULL; | 1289 | LPWSTR* rgsczAncestors = NULL; |
1271 | UINT cAncestors = 0; | 1290 | UINT cAncestors = 0; |
1272 | STRINGDICT_HANDLE sdAncestors = NULL; | 1291 | STRINGDICT_HANDLE sdAncestors = NULL; |
1292 | BOOL fUninstalling = BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pPlan->action; | ||
1273 | 1293 | ||
1274 | if (pPlan->pInternalCommand->sczAncestors) | 1294 | if (pPlan->pInternalCommand->sczAncestors) |
1275 | { | 1295 | { |
@@ -1329,7 +1349,7 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
1329 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); | 1349 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); |
1330 | 1350 | ||
1331 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. | 1351 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. |
1332 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) | 1352 | if (fUninstalling && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) |
1333 | { | 1353 | { |
1334 | if (0 < pRelatedBundle->package.cDependencyProviders) | 1354 | if (0 < pRelatedBundle->package.cDependencyProviders) |
1335 | { | 1355 | { |
@@ -1361,6 +1381,9 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1361 | HRESULT hr = S_OK; | 1381 | HRESULT hr = S_OK; |
1362 | LPWSTR sczIgnoreDependencies = NULL; | 1382 | LPWSTR sczIgnoreDependencies = NULL; |
1363 | STRINGDICT_HANDLE sdProviderKeys = NULL; | 1383 | STRINGDICT_HANDLE sdProviderKeys = NULL; |
1384 | BOOL fExecutingAnyPackage = FALSE; | ||
1385 | BOOL fInstallingAnyPackage = FALSE; | ||
1386 | BOOL fUninstalling = BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pPlan->action; | ||
1364 | 1387 | ||
1365 | // Get the list of dependencies to ignore to pass to related bundles. | 1388 | // Get the list of dependencies to ignore to pass to related bundles. |
1366 | hr = DependencyAllocIgnoreDependencies(pPlan, &sczIgnoreDependencies); | 1389 | hr = DependencyAllocIgnoreDependencies(pPlan, &sczIgnoreDependencies); |
@@ -1369,9 +1392,6 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1369 | hr = DictCreateStringList(&sdProviderKeys, pPlan->cExecuteActions, DICT_FLAG_CASEINSENSITIVE); | 1392 | hr = DictCreateStringList(&sdProviderKeys, pPlan->cExecuteActions, DICT_FLAG_CASEINSENSITIVE); |
1370 | ExitOnFailure(hr, "Failed to create dictionary for planned packages."); | 1393 | ExitOnFailure(hr, "Failed to create dictionary for planned packages."); |
1371 | 1394 | ||
1372 | BOOL fExecutingAnyPackage = FALSE; | ||
1373 | BOOL fInstallingAnyPackage = FALSE; | ||
1374 | |||
1375 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) | 1395 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) |
1376 | { | 1396 | { |
1377 | BOOTSTRAPPER_ACTION_STATE packageAction = BOOTSTRAPPER_ACTION_STATE_NONE; | 1397 | BOOTSTRAPPER_ACTION_STATE packageAction = BOOTSTRAPPER_ACTION_STATE_NONE; |
@@ -1444,7 +1464,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1444 | } | 1464 | } |
1445 | 1465 | ||
1446 | // For an uninstall, there is no need to repair dependent bundles if no packages are executing. | 1466 | // For an uninstall, there is no need to repair dependent bundles if no packages are executing. |
1447 | if (!fExecutingAnyPackage && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_REPAIR == pRelatedBundle->package.requested && BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) | 1467 | if (!fExecutingAnyPackage && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_REPAIR == pRelatedBundle->package.requested && fUninstalling) |
1448 | { | 1468 | { |
1449 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1469 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; |
1450 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DEPENDENT_BUNDLE_REPAIR, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType)); | 1470 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DEPENDENT_BUNDLE_REPAIR, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType)); |
@@ -1457,7 +1477,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1457 | ExitOnFailure(hr, "Failed to copy the list of dependencies to ignore."); | 1477 | ExitOnFailure(hr, "Failed to copy the list of dependencies to ignore."); |
1458 | 1478 | ||
1459 | // Uninstall addons and patches early in the chain, before other packages are uninstalled. | 1479 | // Uninstall addons and patches early in the chain, before other packages are uninstalled. |
1460 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) | 1480 | if (fUninstalling) |
1461 | { | 1481 | { |
1462 | pdwInsertIndex = &dwExecuteActionEarlyIndex; | 1482 | pdwInsertIndex = &dwExecuteActionEarlyIndex; |
1463 | } | 1483 | } |
@@ -1475,7 +1495,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1475 | ExitOnFailure(hr, "Failed to begin plan dependency actions to package: %ls", pRelatedBundle->package.sczId); | 1495 | ExitOnFailure(hr, "Failed to begin plan dependency actions to package: %ls", pRelatedBundle->package.sczId); |
1476 | 1496 | ||
1477 | // If uninstalling a related bundle, make sure the bundle is uninstalled after removing registration. | 1497 | // If uninstalling a related bundle, make sure the bundle is uninstalled after removing registration. |
1478 | if (pdwInsertIndex && BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) | 1498 | if (pdwInsertIndex && fUninstalling) |
1479 | { | 1499 | { |
1480 | ++(*pdwInsertIndex); | 1500 | ++(*pdwInsertIndex); |
1481 | } | 1501 | } |
@@ -1599,9 +1619,10 @@ extern "C" HRESULT PlanCleanPackage( | |||
1599 | HRESULT hr = S_OK; | 1619 | HRESULT hr = S_OK; |
1600 | BOOL fPlanCleanPackage = FALSE; | 1620 | BOOL fPlanCleanPackage = FALSE; |
1601 | BURN_CLEAN_ACTION* pCleanAction = NULL; | 1621 | BURN_CLEAN_ACTION* pCleanAction = NULL; |
1622 | BOOL fUninstalling = BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pPlan->action; | ||
1602 | 1623 | ||
1603 | // The following is a complex set of logic that determines when a package should be cleaned from the cache. | 1624 | // The following is a complex set of logic that determines when a package should be cleaned from the cache. |
1604 | if (BOOTSTRAPPER_CACHE_TYPE_FORCE > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action) | 1625 | if (BOOTSTRAPPER_CACHE_TYPE_FORCE > pPackage->cacheType || fUninstalling) |
1605 | { | 1626 | { |
1606 | // The following are all different reasons why the package should be cleaned from the cache. | 1627 | // The following are all different reasons why the package should be cleaned from the cache. |
1607 | // The else-ifs are used to make the conditions easier to see (rather than have them combined | 1628 | // The else-ifs are used to make the conditions easier to see (rather than have them combined |
@@ -1624,7 +1645,7 @@ extern "C" HRESULT PlanCleanPackage( | |||
1624 | { | 1645 | { |
1625 | fPlanCleanPackage = TRUE; | 1646 | fPlanCleanPackage = TRUE; |
1626 | } | 1647 | } |
1627 | else if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action && // uninstalling and | 1648 | else if (fUninstalling && // uninstalling and |
1628 | BOOTSTRAPPER_REQUEST_STATE_NONE == pPackage->requested && // requested do nothing (aka: default) and | 1649 | BOOTSTRAPPER_REQUEST_STATE_NONE == pPackage->requested && // requested do nothing (aka: default) and |
1629 | BOOTSTRAPPER_ACTION_STATE_NONE == pPackage->execute && // execute is still do nothing and | 1650 | BOOTSTRAPPER_ACTION_STATE_NONE == pPackage->execute && // execute is still do nothing and |
1630 | !pPackage->fDependencyManagerWasHere && // dependency manager didn't change execute and | 1651 | !pPackage->fDependencyManagerWasHere && // dependency manager didn't change execute and |
@@ -2091,6 +2112,7 @@ static HRESULT GetActionDefaultRequestState( | |||
2091 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_REPAIR; | 2112 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_REPAIR; |
2092 | break; | 2113 | break; |
2093 | 2114 | ||
2115 | case BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL: __fallthrough; | ||
2094 | case BOOTSTRAPPER_ACTION_UNINSTALL: | 2116 | case BOOTSTRAPPER_ACTION_UNINSTALL: |
2095 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; | 2117 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; |
2096 | break; | 2118 | break; |
@@ -2671,7 +2693,7 @@ static BOOL ForceCache( | |||
2671 | BOOTSTRAPPER_REQUEST_STATE_CACHE < pPackage->requested; | 2693 | BOOTSTRAPPER_REQUEST_STATE_CACHE < pPackage->requested; |
2672 | case BOOTSTRAPPER_CACHE_TYPE_FORCE: | 2694 | case BOOTSTRAPPER_CACHE_TYPE_FORCE: |
2673 | // All packages that have cacheType set to force should be cached if the bundle is going to be present. | 2695 | // All packages that have cacheType set to force should be cached if the bundle is going to be present. |
2674 | return BOOTSTRAPPER_ACTION_UNINSTALL < pPlan->action; | 2696 | return BOOTSTRAPPER_ACTION_UNINSTALL != pPlan->action && BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL != pPlan->action; |
2675 | default: | 2697 | default: |
2676 | return FALSE; | 2698 | return FALSE; |
2677 | } | 2699 | } |