aboutsummaryrefslogtreecommitdiff
path: root/src/engine/plan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/plan.cpp')
-rw-r--r--src/engine/plan.cpp95
1 files changed, 49 insertions, 46 deletions
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp
index 65da4ab3..c75c1753 100644
--- a/src/engine/plan.cpp
+++ b/src/engine/plan.cpp
@@ -588,8 +588,8 @@ extern "C" HRESULT PlanRegistration(
588 STRINGDICT_HANDLE sdIgnoreDependents = NULL; 588 STRINGDICT_HANDLE sdIgnoreDependents = NULL;
589 589
590 pPlan->fCanAffectMachineState = TRUE; // register the bundle since we're modifying machine state. 590 pPlan->fCanAffectMachineState = TRUE; // register the bundle since we're modifying machine state.
591
592 pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed 591 pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed
592 pPlan->fIgnoreAllDependents = pRegistration->fIgnoreAllDependents;
593 593
594 // Ensure the bundle is cached if not running from the cache. 594 // Ensure the bundle is cached if not running from the cache.
595 if (!CacheBundleRunningFromCache()) 595 if (!CacheBundleRunningFromCache())
@@ -633,68 +633,71 @@ extern "C" HRESULT PlanRegistration(
633 ExitOnFailure(hr, "Failed to add self-dependent to ignore dependents."); 633 ExitOnFailure(hr, "Failed to add self-dependent to ignore dependents.");
634 } 634 }
635 635
636 // If we are not doing an upgrade, we check to see if there are still dependents on us and if so we skip planning. 636 if (!pPlan->fIgnoreAllDependents)
637 // However, when being upgraded, we always execute our uninstall because a newer version of us is probably
638 // already on the machine and we need to clean up the stuff specific to this bundle.
639 if (BOOTSTRAPPER_RELATION_UPGRADE != relationType)
640 { 637 {
641 // If there were other dependencies to ignore, add them. 638 // If we are not doing an upgrade, we check to see if there are still dependents on us and if so we skip planning.
642 for (DWORD iDependency = 0; iDependency < pRegistration->cIgnoredDependencies; ++iDependency) 639 // However, when being upgraded, we always execute our uninstall because a newer version of us is probably
640 // already on the machine and we need to clean up the stuff specific to this bundle.
641 if (BOOTSTRAPPER_RELATION_UPGRADE != relationType)
643 { 642 {
644 DEPENDENCY* pDependency = pRegistration->rgIgnoredDependencies + iDependency; 643 // If there were other dependencies to ignore, add them.
645 644 for (DWORD iDependency = 0; iDependency < pRegistration->cIgnoredDependencies; ++iDependency)
646 hr = DictKeyExists(sdIgnoreDependents, pDependency->sczKey);
647 if (E_NOTFOUND != hr)
648 {
649 ExitOnFailure(hr, "Failed to check the dictionary of ignored dependents.");
650 }
651 else
652 { 645 {
653 hr = DictAddKey(sdIgnoreDependents, pDependency->sczKey); 646 DEPENDENCY* pDependency = pRegistration->rgIgnoredDependencies + iDependency;
654 ExitOnFailure(hr, "Failed to add dependent key to ignored dependents.");
655 }
656 }
657 647
658 // For addon or patch bundles, dependent related bundles should be ignored. This allows 648 hr = DictKeyExists(sdIgnoreDependents, pDependency->sczKey);
659 // that addon or patch to be removed even though bundles it targets still are registered. 649 if (E_NOTFOUND != hr)
660 for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) 650 {
661 { 651 ExitOnFailure(hr, "Failed to check the dictionary of ignored dependents.");
662 const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i; 652 }
653 else
654 {
655 hr = DictAddKey(sdIgnoreDependents, pDependency->sczKey);
656 ExitOnFailure(hr, "Failed to add dependent key to ignored dependents.");
657 }
658 }
663 659
664 if (BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType) 660 // For addon or patch bundles, dependent related bundles should be ignored. This allows
661 // that addon or patch to be removed even though bundles it targets still are registered.
662 for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i)
665 { 663 {
666 for (DWORD j = 0; j < pRelatedBundle->package.cDependencyProviders; ++j) 664 const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i;
665
666 if (BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType)
667 { 667 {
668 const BURN_DEPENDENCY_PROVIDER* pProvider = pRelatedBundle->package.rgDependencyProviders + j; 668 for (DWORD j = 0; j < pRelatedBundle->package.cDependencyProviders; ++j)
669 {
670 const BURN_DEPENDENCY_PROVIDER* pProvider = pRelatedBundle->package.rgDependencyProviders + j;
669 671
670 hr = DependencyAddIgnoreDependencies(sdIgnoreDependents, pProvider->sczKey); 672 hr = DependencyAddIgnoreDependencies(sdIgnoreDependents, pProvider->sczKey);
671 ExitOnFailure(hr, "Failed to add dependent bundle provider key to ignore dependents."); 673 ExitOnFailure(hr, "Failed to add dependent bundle provider key to ignore dependents.");
674 }
672 } 675 }
673 } 676 }
674 }
675
676 // If there are any (non-ignored and not-planned-to-be-removed) dependents left, skip planning.
677 for (DWORD iDependent = 0; iDependent < pRegistration->cDependents; ++iDependent)
678 {
679 DEPENDENCY* pDependent = pRegistration->rgDependents + iDependent;
680 677
681 hr = DictKeyExists(sdIgnoreDependents, pDependent->sczKey); 678 // If there are any (non-ignored and not-planned-to-be-removed) dependents left, skip planning.
682 if (E_NOTFOUND == hr) 679 for (DWORD iDependent = 0; iDependent < pRegistration->cDependents; ++iDependent)
683 { 680 {
684 hr = S_OK; 681 DEPENDENCY* pDependent = pRegistration->rgDependents + iDependent;
685 682
686 // TODO: callback to the BA and let it have the option to ignore this dependent? 683 hr = DictKeyExists(sdIgnoreDependents, pDependent->sczKey);
687 if (!pPlan->fDisallowRemoval) 684 if (E_NOTFOUND == hr)
688 { 685 {
689 pPlan->fDisallowRemoval = TRUE; // ensure the registration stays 686 hr = S_OK;
690 *pfContinuePlanning = FALSE; // skip the rest of planning.
691 687
692 LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DUE_TO_DEPENDENTS); 688 // TODO: callback to the BA and let it have the option to ignore this dependent?
693 } 689 if (!pPlan->fDisallowRemoval)
690 {
691 pPlan->fDisallowRemoval = TRUE; // ensure the registration stays
692 *pfContinuePlanning = FALSE; // skip the rest of planning.
694 693
695 LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_DEPENDENT, pDependent->sczKey, LoggingStringOrUnknownIfNull(pDependent->sczName)); 694 LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DUE_TO_DEPENDENTS);
695 }
696
697 LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_DEPENDENT, pDependent->sczKey, LoggingStringOrUnknownIfNull(pDependent->sczName));
698 }
699 ExitOnFailure(hr, "Failed to check for remaining dependents during planning.");
696 } 700 }
697 ExitOnFailure(hr, "Failed to check for remaining dependents during planning.");
698 } 701 }
699 } 702 }
700 } 703 }