aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/dependency.cpp
diff options
context:
space:
mode:
authorBob Arnson <bob@firegiant.com>2026-02-04 20:47:04 -0500
committerBob Arnson <bob@firegiant.com>2026-02-04 20:47:04 -0500
commitedccb203c421d2bd820062024088c6698424d9ee (patch)
tree6b47c3eb5ca53bd9f79f3d032dc1a596d411bf38 /src/burn/engine/dependency.cpp
parenta3d3963f806117ce123d95e8b77e73e1c1545b25 (diff)
downloadwix-edccb203c421d2bd820062024088c6698424d9ee.tar.gz
wix-edccb203c421d2bd820062024088c6698424d9ee.tar.bz2
wix-edccb203c421d2bd820062024088c6698424d9ee.zip
Support dual-purpose packages in Burn.bob/ConfigurableScopeBundles
Fixes https://github.com/wixtoolset/issues/issues/8958
Diffstat (limited to 'src/burn/engine/dependency.cpp')
-rw-r--r--src/burn/engine/dependency.cpp72
1 files changed, 59 insertions, 13 deletions
diff --git a/src/burn/engine/dependency.cpp b/src/burn/engine/dependency.cpp
index 94a8a1e4..7cd0db9f 100644
--- a/src/burn/engine/dependency.cpp
+++ b/src/burn/engine/dependency.cpp
@@ -12,6 +12,7 @@ const LPCWSTR vcszIgnoreDependenciesDelim = L";";
12 12
13static HRESULT DetectPackageDependents( 13static HRESULT DetectPackageDependents(
14 __in BURN_PACKAGE* pPackage, 14 __in BURN_PACKAGE* pPackage,
15 __in BOOL fPackagePerMachine,
15 __in const BURN_REGISTRATION* pRegistration 16 __in const BURN_REGISTRATION* pRegistration
16 ); 17 );
17 18
@@ -249,7 +250,22 @@ extern "C" HRESULT DependencyDetectProviderKeyBundleCode(
249{ 250{
250 HRESULT hr = S_OK; 251 HRESULT hr = S_OK;
251 252
252 hr = DepGetProviderInformation(pRegistration->hkRoot, pRegistration->sczProviderKey, &pRegistration->sczDetectedProviderKeyBundleCode, NULL, NULL); 253 // For configurable packages, check both scopes because until planning,
254 // we can't know their planned scope.
255 if (pRegistration->hkRoot)
256 {
257 hr = DepGetProviderInformation(pRegistration->hkRoot, pRegistration->sczProviderKey, &pRegistration->sczDetectedProviderKeyBundleCode, NULL, NULL);
258 }
259 else
260 {
261 hr = DepGetProviderInformation(HKEY_LOCAL_MACHINE, pRegistration->sczProviderKey, &pRegistration->sczDetectedProviderKeyBundleCode, NULL, NULL);
262
263 if (E_NOTFOUND == hr)
264 {
265 hr = DepGetProviderInformation(HKEY_CURRENT_USER, pRegistration->sczProviderKey, &pRegistration->sczDetectedProviderKeyBundleCode, NULL, NULL);
266 }
267 }
268
253 if (E_NOTFOUND == hr) 269 if (E_NOTFOUND == hr)
254 { 270 {
255 ReleaseNullStr(pRegistration->sczDetectedProviderKeyBundleCode); 271 ReleaseNullStr(pRegistration->sczDetectedProviderKeyBundleCode);
@@ -284,7 +300,21 @@ extern "C" HRESULT DependencyDetectBundle(
284 hr = DependencyDetectProviderKeyBundleCode(pRegistration); 300 hr = DependencyDetectProviderKeyBundleCode(pRegistration);
285 ExitOnFailure(hr, "Failed to detect provider key bundle code."); 301 ExitOnFailure(hr, "Failed to detect provider key bundle code.");
286 302
287 hr = DepCheckDependents(pRegistration->hkRoot, pRegistration->sczProviderKey, 0, NULL, &pRegistration->rgDependents, &pRegistration->cDependents); 303 // For configurable packages, check both scopes because until planning,
304 // we can't know their planned scope.
305 if (pRegistration->hkRoot)
306 {
307 hr = DepCheckDependents(pRegistration->hkRoot, pRegistration->sczProviderKey, 0, NULL, &pRegistration->rgDependents, &pRegistration->cDependents);
308 }
309 else
310 {
311 hr = DepCheckDependents(HKEY_LOCAL_MACHINE, pRegistration->sczProviderKey, 0, NULL, &pRegistration->rgDependents, &pRegistration->cDependents);
312
313 if (E_NOTFOUND == hr)
314 {
315 hr = DepCheckDependents(HKEY_CURRENT_USER, pRegistration->sczProviderKey, 0, NULL, &pRegistration->rgDependents, &pRegistration->cDependents);
316 }
317 }
288 ExitOnPathFailure(hr, fExists, "Failed dependents check on bundle."); 318 ExitOnPathFailure(hr, fExists, "Failed dependents check on bundle.");
289 319
290 if (pDependencies->fSelfDependent || pDependencies->fActiveParent) 320 if (pDependencies->fSelfDependent || pDependencies->fActiveParent)
@@ -292,13 +322,13 @@ extern "C" HRESULT DependencyDetectBundle(
292 for (DWORD i = 0; i < pRegistration->cDependents; ++i) 322 for (DWORD i = 0; i < pRegistration->cDependents; ++i)
293 { 323 {
294 DEPENDENCY* pDependent = pRegistration->rgDependents + i; 324 DEPENDENCY* pDependent = pRegistration->rgDependents + i;
295 325
296 if (pDependencies->fActiveParent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzActiveParent, -1, pDependent->sczKey, -1, TRUE)) 326 if (pDependent && pDependencies->fActiveParent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzActiveParent, -1, pDependent->sczKey, -1, TRUE))
297 { 327 {
298 pRegistration->fParentRegisteredAsDependent = TRUE; 328 pRegistration->fParentRegisteredAsDependent = TRUE;
299 } 329 }
300 330
301 if (pDependencies->fSelfDependent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzSelfDependent, -1, pDependent->sczKey, -1, TRUE)) 331 if (pDependent && pDependencies->fSelfDependent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzSelfDependent, -1, pDependent->sczKey, -1, TRUE))
302 { 332 {
303 pRegistration->fSelfRegisteredAsDependent = TRUE; 333 pRegistration->fSelfRegisteredAsDependent = TRUE;
304 } 334 }
@@ -316,11 +346,24 @@ extern "C" HRESULT DependencyDetectChainPackage(
316{ 346{
317 HRESULT hr = S_OK; 347 HRESULT hr = S_OK;
318 348
319 hr = DetectPackageDependents(pPackage, pRegistration); 349 if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == pPackage->scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == pPackage->scope)
320 ExitOnFailure(hr, "Failed to detect dependents for package '%ls'", pPackage->sczId); 350 {
351 // For configurable packages, check both scopes because until planning,
352 // we can't know their planned scope.
353 hr = DetectPackageDependents(pPackage, /*fPerMachine*/TRUE, pRegistration);
354 ExitOnFailure(hr, "Failed to detect per-machine dependents for configurable package '%ls'", pPackage->sczId);
355
356 hr = DetectPackageDependents(pPackage, /*fPerMachine*/FALSE, pRegistration);
357 ExitOnFailure(hr, "Failed to detect per-user dependents for configurable package '%ls'", pPackage->sczId);
358 }
359 else
360 {
361 hr = DetectPackageDependents(pPackage, pPackage->fPerMachine, pRegistration);
362 ExitOnFailure(hr, "Failed to detect dependents for %hs package '%ls'", LoggingInstallScopeToString(pPackage->fPerMachine), pPackage->sczId);
363 }
321 364
322 hr = DependencyDetectCompatibleEntry(pPackage, pRegistration); 365 hr = DependencyDetectCompatibleEntry(pPackage, pRegistration);
323 ExitOnFailure(hr, "Failed to detect compatible package for package '%ls'", pPackage->sczId); 366 ExitOnFailure(hr, "Failed to detect compatible package for %hs package '%ls'", LoggingInstallScopeToString(pPackage->fPerMachine), pPackage->sczId);
324 367
325LExit: 368LExit:
326 return hr; 369 return hr;
@@ -336,7 +379,7 @@ extern "C" HRESULT DependencyDetectRelatedBundle(
336 379
337 if (pRelatedBundle->fPlannable) 380 if (pRelatedBundle->fPlannable)
338 { 381 {
339 hr = DetectPackageDependents(pPackage, pRegistration); 382 hr = DetectPackageDependents(pPackage, pPackage->fPerMachine, pRegistration);
340 ExitOnFailure(hr, "Failed to detect dependents for related bundle '%ls'", pPackage->sczId); 383 ExitOnFailure(hr, "Failed to detect dependents for related bundle '%ls'", pPackage->sczId);
341 } 384 }
342 385
@@ -626,7 +669,7 @@ LExit:
626} 669}
627 670
628extern "C" HRESULT DependencyPlanPackage( 671extern "C" HRESULT DependencyPlanPackage(
629 __in_opt DWORD *pdwInsertSequence, 672 __in_opt DWORD* pdwInsertSequence,
630 __in const BURN_PACKAGE* pPackage, 673 __in const BURN_PACKAGE* pPackage,
631 __in BURN_PLAN* pPlan 674 __in BURN_PLAN* pPlan
632 ) 675 )
@@ -946,18 +989,19 @@ LExit:
946 989
947static HRESULT DetectPackageDependents( 990static HRESULT DetectPackageDependents(
948 __in BURN_PACKAGE* pPackage, 991 __in BURN_PACKAGE* pPackage,
992 __in BOOL fPackagePerMachine,
949 __in const BURN_REGISTRATION* pRegistration 993 __in const BURN_REGISTRATION* pRegistration
950 ) 994 )
951{ 995{
952 HRESULT hr = S_OK; 996 HRESULT hr = S_OK;
953 HKEY hkHive = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 997 HKEY hkHive = fPackagePerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
954 BOOL fCanIgnorePresence = pPackage->fCanAffectRegistration && 0 < pPackage->cDependencyProviders && 998 BOOL fCanIgnorePresence = pPackage->fCanAffectRegistration && 0 < pPackage->cDependencyProviders &&
955 (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState || BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState); 999 (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState || BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState);
956 BOOL fBundleRegisteredAsDependent = FALSE; 1000 BOOL fBundleRegisteredAsDependent = FALSE;
957 1001
958 // There's currently no point in getting the dependents if the scope doesn't match, 1002 // There's currently no point in getting the dependents if the scope doesn't match,
959 // because they will just get ignored. 1003 // because they will just get ignored.
960 if (pRegistration->fPerMachine != pPackage->fPerMachine) 1004 if (pRegistration->fPerMachine != fPackagePerMachine)
961 { 1005 {
962 ExitFunction(); 1006 ExitFunction();
963 } 1007 }
@@ -979,7 +1023,7 @@ static HRESULT DetectPackageDependents(
979 { 1023 {
980 DEPENDENCY* pDependent = pProvider->rgDependents + iDependent; 1024 DEPENDENCY* pDependent = pProvider->rgDependents + iDependent;
981 1025
982 if (CSTR_EQUAL == ::CompareStringOrdinal(pRegistration->sczCode, -1, pDependent->sczKey, -1, TRUE)) 1026 if (pDependent && CSTR_EQUAL == ::CompareStringOrdinal(pRegistration->sczCode, -1, pDependent->sczKey, -1, TRUE))
983 { 1027 {
984 pProvider->fBundleRegisteredAsDependent = TRUE; 1028 pProvider->fBundleRegisteredAsDependent = TRUE;
985 fBundleRegisteredAsDependent = TRUE; 1029 fBundleRegisteredAsDependent = TRUE;
@@ -994,10 +1038,12 @@ static HRESULT DetectPackageDependents(
994 { 1038 {
995 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; 1039 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
996 } 1040 }
1041
997 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState) 1042 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState)
998 { 1043 {
999 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; 1044 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
1000 } 1045 }
1046
1001 if (BURN_PACKAGE_TYPE_MSP == pPackage->type) 1047 if (BURN_PACKAGE_TYPE_MSP == pPackage->type)
1002 { 1048 {
1003 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i) 1049 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)