Skip bundle dependent checking when ignoring dependencies includes ALL.
Fixes #6391.
Sean Hall committed
Mar 30, 2021 at 19:38 UTC
e9a4f673511dd06a8209f3e4037ad20f153d6caa
4 files changed
+62
-49
src/engine/dependency.cpp
+11
-3
@@ -19,7 +19,8 @@ static HRESULT DetectPackageDependents(
19
static HRESULT SplitIgnoreDependencies(
20
__in_z LPCWSTR wzIgnoreDependencies,
21
__deref_inout_ecount_opt(*pcDependencies) DEPENDENCY** prgDependencies,
22
- __inout LPUINT pcDependencies
22
+ __inout LPUINT pcDependencies,
23
+ __out BOOL* pfIgnoreAll
24
);
25
26
static HRESULT JoinIgnoreDependencies(
@@ -194,7 +195,7 @@ extern "C" HRESULT DependencyInitialize(
195
// Add the list of dependencies to ignore.
196
if (wzIgnoreDependencies)
197
{
197
- hr = SplitIgnoreDependencies(wzIgnoreDependencies, &pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies);
198
+ hr = SplitIgnoreDependencies(wzIgnoreDependencies, &pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies, &pRegistration->fIgnoreAllDependents);
199
ExitOnFailure(hr, "Failed to split the list of dependencies to ignore.");
200
}
201
@@ -816,12 +817,14 @@ LExit:
817
static HRESULT SplitIgnoreDependencies(
818
__in_z LPCWSTR wzIgnoreDependencies,
819
__deref_inout_ecount_opt(*pcDependencies) DEPENDENCY** prgDependencies,
819
- __inout LPUINT pcDependencies
820
+ __inout LPUINT pcDependencies,
821
+ __out BOOL* pfIgnoreAll
822
)
823
{
824
HRESULT hr = S_OK;
825
LPWSTR wzContext = NULL;
826
STRINGDICT_HANDLE sdIgnoreDependencies = NULL;
827
+ *pfIgnoreAll = FALSE;
828
829
// Create a dictionary to hold unique dependencies.
830
hr = DictCreateStringList(&sdIgnoreDependencies, INITIAL_STRINGDICT_SIZE, DICT_FLAG_CASEINSENSITIVE);
@@ -842,6 +845,11 @@ static HRESULT SplitIgnoreDependencies(
845
846
hr = DictAddKey(sdIgnoreDependencies, 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
+ }
853
}
854
}
855
src/engine/plan.cpp
+49
-46
@@ -588,8 +588,8 @@ extern "C" HRESULT PlanRegistration(
588
STRINGDICT_HANDLE sdIgnoreDependents = NULL;
589
590
pPlan->fCanAffectMachineState = TRUE; // register the bundle since we're modifying machine state.
591
-
591
pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed
592
+ pPlan->fIgnoreAllDependents = pRegistration->fIgnoreAllDependents;
593
594
// Ensure the bundle is cached if not running from the cache.
595
if (!CacheBundleRunningFromCache())
@@ -633,68 +633,71 @@ extern "C" HRESULT PlanRegistration(
633
ExitOnFailure(hr, "Failed to add self-dependent to ignore dependents.");
634
}
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.
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)
636
+ if (!pPlan->fIgnoreAllDependents)
637
{
641
- // If there were other dependencies to ignore, add them.
642
- for (DWORD iDependency = 0; iDependency < pRegistration->cIgnoredDependencies; ++iDependency)
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.
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)
642
{
644
- DEPENDENCY* pDependency = pRegistration->rgIgnoredDependencies + iDependency;
645
-
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
643
+ // If there were other dependencies to ignore, add them.
644
+ for (DWORD iDependency = 0; iDependency < pRegistration->cIgnoredDependencies; ++iDependency)
645
{
653
- hr = DictAddKey(sdIgnoreDependents, pDependency->sczKey);
654
- ExitOnFailure(hr, "Failed to add dependent key to ignored dependents.");
655
- }
656
- }
646
+ DEPENDENCY* pDependency = pRegistration->rgIgnoredDependencies + iDependency;
647
658
- // For addon or patch bundles, dependent related bundles should be ignored. This allows
659
- // that addon or patch to be removed even though bundles it targets still are registered.
660
- for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i)
661
- {
662
- const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i;
648
+ hr = DictKeyExists(sdIgnoreDependents, pDependency->sczKey);
649
+ if (E_NOTFOUND != hr)
650
+ {
651
+ ExitOnFailure(hr, "Failed to check the dictionary of ignored dependents.");
652
+ }
653
+ else
654
+ {
655
+ hr = DictAddKey(sdIgnoreDependents, pDependency->sczKey);
656
+ ExitOnFailure(hr, "Failed to add dependent key to ignored dependents.");
657
+ }
658
+ }
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)
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
{
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;
671
670
- hr = DependencyAddIgnoreDependencies(sdIgnoreDependents, pProvider->sczKey);
671
- ExitOnFailure(hr, "Failed to add dependent bundle provider key to ignore dependents.");
672
+ hr = DependencyAddIgnoreDependencies(sdIgnoreDependents, pProvider->sczKey);
673
+ ExitOnFailure(hr, "Failed to add dependent bundle provider key to ignore dependents.");
674
+ }
675
}
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;
677
681
- hr = DictKeyExists(sdIgnoreDependents, pDependent->sczKey);
682
- if (E_NOTFOUND == hr)
678
+ // If there are any (non-ignored and not-planned-to-be-removed) dependents left, skip planning.
679
+ for (DWORD iDependent = 0; iDependent < pRegistration->cDependents; ++iDependent)
680
{
684
- hr = S_OK;
681
+ DEPENDENCY* pDependent = pRegistration->rgDependents + iDependent;
682
686
- // TODO: callback to the BA and let it have the option to ignore this dependent?
687
- if (!pPlan->fDisallowRemoval)
683
+ hr = DictKeyExists(sdIgnoreDependents, pDependent->sczKey);
684
+ if (E_NOTFOUND == hr)
685
{
689
- pPlan->fDisallowRemoval = TRUE; // ensure the registration stays
690
- *pfContinuePlanning = FALSE; // skip the rest of planning.
686
+ hr = S_OK;
687
692
- LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DUE_TO_DEPENDENTS);
693
- }
688
+ // TODO: callback to the BA and let it have the option to ignore this dependent?
689
+ if (!pPlan->fDisallowRemoval)
690
+ {
691
+ pPlan->fDisallowRemoval = TRUE; // ensure the registration stays
692
+ *pfContinuePlanning = FALSE; // skip the rest of planning.
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.");
700
}
697
- ExitOnFailure(hr, "Failed to check for remaining dependents during planning.");
701
}
702
}
703
}
src/engine/plan.h
+1
@@ -314,6 +314,7 @@ typedef struct _BURN_PLAN
314
BOOL fDisallowRemoval;
315
BOOL fDisableRollback;
316
BOOL fAffectedMachineState;
317
+ BOOL fIgnoreAllDependents;
318
319
DWORD64 qwCacheSizeTotal;
320
src/engine/registration.h
+1
@@ -146,6 +146,7 @@ typedef struct _BURN_REGISTRATION
146
UINT cIgnoredDependencies; // Only valid after detect.
147
DEPENDENCY* rgDependents; // Only valid after detect.
148
UINT cDependents; // Only valid after detect.
149
+ BOOL fIgnoreAllDependents; // Only valid after detect.
150
LPCWSTR wzSelfDependent; // Only valid after detect.
151
BOOL fSelfRegisteredAsDependent; // Only valid after detect.
152
BOOL fParentRegisteredAsDependent; // Only valid after detect.