diff options
| author | Bob Arnson <bob@firegiant.com> | 2026-02-04 20:47:04 -0500 |
|---|---|---|
| committer | Bob Arnson <bob@firegiant.com> | 2026-02-04 20:47:04 -0500 |
| commit | edccb203c421d2bd820062024088c6698424d9ee (patch) | |
| tree | 6b47c3eb5ca53bd9f79f3d032dc1a596d411bf38 /src/burn/engine/dependency.cpp | |
| parent | a3d3963f806117ce123d95e8b77e73e1c1545b25 (diff) | |
| download | wix-bob/ConfigurableScopeBundles.tar.gz wix-bob/ConfigurableScopeBundles.tar.bz2 wix-bob/ConfigurableScopeBundles.zip | |
Support dual-purpose packages in Burn.bob/ConfigurableScopeBundles
Fixes https://github.com/wixtoolset/issues/issues/8958
Diffstat (limited to '')
| -rw-r--r-- | src/burn/engine/dependency.cpp | 72 |
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 | ||
| 13 | static HRESULT DetectPackageDependents( | 13 | static 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 | ||
| 325 | LExit: | 368 | LExit: |
| 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 | ||
| 628 | extern "C" HRESULT DependencyPlanPackage( | 671 | extern "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 | ||
| 947 | static HRESULT DetectPackageDependents( | 990 | static 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) |
