diff options
Diffstat (limited to 'src/engine/plan.cpp')
-rw-r--r-- | src/engine/plan.cpp | 95 |
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 | } |