diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-03-30 19:38:33 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-03-30 21:59:51 -0500 |
commit | e9a4f673511dd06a8209f3e4037ad20f153d6caa (patch) | |
tree | df3ea53150c1927f43bd7375d1a33bf0e0491932 | |
parent | 5cbe372f0a512babc5db7f519fc407eb40606346 (diff) | |
download | wix-e9a4f673511dd06a8209f3e4037ad20f153d6caa.tar.gz wix-e9a4f673511dd06a8209f3e4037ad20f153d6caa.tar.bz2 wix-e9a4f673511dd06a8209f3e4037ad20f153d6caa.zip |
Skip bundle dependent checking when ignoring dependencies includes ALL.
Fixes #6391.
-rw-r--r-- | src/engine/dependency.cpp | 14 | ||||
-rw-r--r-- | src/engine/plan.cpp | 95 | ||||
-rw-r--r-- | src/engine/plan.h | 1 | ||||
-rw-r--r-- | src/engine/registration.h | 1 |
4 files changed, 62 insertions, 49 deletions
diff --git a/src/engine/dependency.cpp b/src/engine/dependency.cpp index 51aca239..1bd0c7d4 100644 --- a/src/engine/dependency.cpp +++ b/src/engine/dependency.cpp | |||
@@ -19,7 +19,8 @@ static HRESULT DetectPackageDependents( | |||
19 | static HRESULT SplitIgnoreDependencies( | 19 | static HRESULT SplitIgnoreDependencies( |
20 | __in_z LPCWSTR wzIgnoreDependencies, | 20 | __in_z LPCWSTR wzIgnoreDependencies, |
21 | __deref_inout_ecount_opt(*pcDependencies) DEPENDENCY** prgDependencies, | 21 | __deref_inout_ecount_opt(*pcDependencies) DEPENDENCY** prgDependencies, |
22 | __inout LPUINT pcDependencies | 22 | __inout LPUINT pcDependencies, |
23 | __out BOOL* pfIgnoreAll | ||
23 | ); | 24 | ); |
24 | 25 | ||
25 | static HRESULT JoinIgnoreDependencies( | 26 | static HRESULT JoinIgnoreDependencies( |
@@ -194,7 +195,7 @@ extern "C" HRESULT DependencyInitialize( | |||
194 | // Add the list of dependencies to ignore. | 195 | // Add the list of dependencies to ignore. |
195 | if (wzIgnoreDependencies) | 196 | if (wzIgnoreDependencies) |
196 | { | 197 | { |
197 | hr = SplitIgnoreDependencies(wzIgnoreDependencies, &pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies); | 198 | hr = SplitIgnoreDependencies(wzIgnoreDependencies, &pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies, &pRegistration->fIgnoreAllDependents); |
198 | ExitOnFailure(hr, "Failed to split the list of dependencies to ignore."); | 199 | ExitOnFailure(hr, "Failed to split the list of dependencies to ignore."); |
199 | } | 200 | } |
200 | 201 | ||
@@ -816,12 +817,14 @@ LExit: | |||
816 | static HRESULT SplitIgnoreDependencies( | 817 | static HRESULT SplitIgnoreDependencies( |
817 | __in_z LPCWSTR wzIgnoreDependencies, | 818 | __in_z LPCWSTR wzIgnoreDependencies, |
818 | __deref_inout_ecount_opt(*pcDependencies) DEPENDENCY** prgDependencies, | 819 | __deref_inout_ecount_opt(*pcDependencies) DEPENDENCY** prgDependencies, |
819 | __inout LPUINT pcDependencies | 820 | __inout LPUINT pcDependencies, |
821 | __out BOOL* pfIgnoreAll | ||
820 | ) | 822 | ) |
821 | { | 823 | { |
822 | HRESULT hr = S_OK; | 824 | HRESULT hr = S_OK; |
823 | LPWSTR wzContext = NULL; | 825 | LPWSTR wzContext = NULL; |
824 | STRINGDICT_HANDLE sdIgnoreDependencies = NULL; | 826 | STRINGDICT_HANDLE sdIgnoreDependencies = NULL; |
827 | *pfIgnoreAll = FALSE; | ||
825 | 828 | ||
826 | // Create a dictionary to hold unique dependencies. | 829 | // Create a dictionary to hold unique dependencies. |
827 | hr = DictCreateStringList(&sdIgnoreDependencies, INITIAL_STRINGDICT_SIZE, DICT_FLAG_CASEINSENSITIVE); | 830 | hr = DictCreateStringList(&sdIgnoreDependencies, INITIAL_STRINGDICT_SIZE, DICT_FLAG_CASEINSENSITIVE); |
@@ -842,6 +845,11 @@ static HRESULT SplitIgnoreDependencies( | |||
842 | 845 | ||
843 | hr = DictAddKey(sdIgnoreDependencies, wzToken); | 846 | hr = DictAddKey(sdIgnoreDependencies, wzToken); |
844 | ExitOnFailure(hr, "Failed to add \"%ls\" to the string dictionary.", wzToken); | 847 | ExitOnFailure(hr, "Failed to add \"%ls\" to the string dictionary.", wzToken); |
848 | |||
849 | if (!*pfIgnoreAll && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, L"ALL", -1, wzToken, -1)) | ||
850 | { | ||
851 | *pfIgnoreAll = TRUE; | ||
852 | } | ||
845 | } | 853 | } |
846 | } | 854 | } |
847 | 855 | ||
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 | } |
diff --git a/src/engine/plan.h b/src/engine/plan.h index e72186c7..77f82e1f 100644 --- a/src/engine/plan.h +++ b/src/engine/plan.h | |||
@@ -314,6 +314,7 @@ typedef struct _BURN_PLAN | |||
314 | BOOL fDisallowRemoval; | 314 | BOOL fDisallowRemoval; |
315 | BOOL fDisableRollback; | 315 | BOOL fDisableRollback; |
316 | BOOL fAffectedMachineState; | 316 | BOOL fAffectedMachineState; |
317 | BOOL fIgnoreAllDependents; | ||
317 | 318 | ||
318 | DWORD64 qwCacheSizeTotal; | 319 | DWORD64 qwCacheSizeTotal; |
319 | 320 | ||
diff --git a/src/engine/registration.h b/src/engine/registration.h index e0418fa3..39fee65f 100644 --- a/src/engine/registration.h +++ b/src/engine/registration.h | |||
@@ -146,6 +146,7 @@ typedef struct _BURN_REGISTRATION | |||
146 | UINT cIgnoredDependencies; // Only valid after detect. | 146 | UINT cIgnoredDependencies; // Only valid after detect. |
147 | DEPENDENCY* rgDependents; // Only valid after detect. | 147 | DEPENDENCY* rgDependents; // Only valid after detect. |
148 | UINT cDependents; // Only valid after detect. | 148 | UINT cDependents; // Only valid after detect. |
149 | BOOL fIgnoreAllDependents; // Only valid after detect. | ||
149 | LPCWSTR wzSelfDependent; // Only valid after detect. | 150 | LPCWSTR wzSelfDependent; // Only valid after detect. |
150 | BOOL fSelfRegisteredAsDependent; // Only valid after detect. | 151 | BOOL fSelfRegisteredAsDependent; // Only valid after detect. |
151 | BOOL fParentRegisteredAsDependent; // Only valid after detect. | 152 | BOOL fParentRegisteredAsDependent; // Only valid after detect. |