diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-01-31 16:43:44 -0600 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-02-01 23:36:23 -0600 |
| commit | a2b98c1abd6e6a1469936af5d93e4ace713b3fba (patch) | |
| tree | 86f49a07f09f5052dd26c8310d8df7a0cd7c19cc /src | |
| parent | c95c41151d595f4630c4c2f4aeb4c7f9a97af5c7 (diff) | |
| download | wix-a2b98c1abd6e6a1469936af5d93e4ace713b3fba.tar.gz wix-a2b98c1abd6e6a1469936af5d93e4ace713b3fba.tar.bz2 wix-a2b98c1abd6e6a1469936af5d93e4ace713b3fba.zip | |
Remove some assumptions in dependency planning.
* A package might be installed even if it was already present.
* A package might be uninstalled even if it was already absent.
* The bundle might not actually be uninstalled even if the planned action was uninstall.
Fixes #6510
Diffstat (limited to 'src')
| -rw-r--r-- | src/burn/engine/dependency.cpp | 257 | ||||
| -rw-r--r-- | src/burn/engine/detect.cpp | 4 | ||||
| -rw-r--r-- | src/burn/engine/package.h | 7 | ||||
| -rw-r--r-- | src/burn/engine/plan.cpp | 79 | ||||
| -rw-r--r-- | src/burn/engine/plan.h | 1 | ||||
| -rw-r--r-- | src/burn/test/BurnUnitTest/PlanTest.cpp | 18 | ||||
| -rw-r--r-- | src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs | 2 |
7 files changed, 158 insertions, 210 deletions
diff --git a/src/burn/engine/dependency.cpp b/src/burn/engine/dependency.cpp index 01f27d72..b783d4c4 100644 --- a/src/burn/engine/dependency.cpp +++ b/src/burn/engine/dependency.cpp | |||
| @@ -41,7 +41,6 @@ static BOOL GetProviderExists( | |||
| 41 | 41 | ||
| 42 | static void CalculateDependencyActionStates( | 42 | static void CalculateDependencyActionStates( |
| 43 | __in const BURN_PACKAGE* pPackage, | 43 | __in const BURN_PACKAGE* pPackage, |
| 44 | __in const BOOTSTRAPPER_ACTION action, | ||
| 45 | __out BURN_DEPENDENCY_ACTION* pDependencyExecuteAction, | 44 | __out BURN_DEPENDENCY_ACTION* pDependencyExecuteAction, |
| 46 | __out BURN_DEPENDENCY_ACTION* pDependencyRollbackAction | 45 | __out BURN_DEPENDENCY_ACTION* pDependencyRollbackAction |
| 47 | ); | 46 | ); |
| @@ -497,7 +496,7 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
| 497 | } | 496 | } |
| 498 | 497 | ||
| 499 | // Calculate the dependency actions before the package itself is planned. | 498 | // Calculate the dependency actions before the package itself is planned. |
| 500 | CalculateDependencyActionStates(pPackage, pPlan->action, &dependencyExecuteAction, &dependencyRollbackAction); | 499 | CalculateDependencyActionStates(pPackage, &dependencyExecuteAction, &dependencyRollbackAction); |
| 501 | 500 | ||
| 502 | // If dependents were found, change the action to not uninstall the package. | 501 | // If dependents were found, change the action to not uninstall the package. |
| 503 | if (fDependentBlocksUninstall) | 502 | if (fDependentBlocksUninstall) |
| @@ -510,37 +509,54 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
| 510 | } | 509 | } |
| 511 | else | 510 | else |
| 512 | { | 511 | { |
| 513 | // Use the calculated dependency actions as the provider actions if there | 512 | // Only plan providers when the package is current (not obsolete). |
| 514 | // are any non-imported providers that need to be registered and the package | ||
| 515 | // is current (not obsolete). | ||
| 516 | if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE != pPackage->currentState) | 513 | if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE != pPackage->currentState) |
| 517 | { | 514 | { |
| 518 | BOOL fAllImportedProviders = TRUE; // assume all providers were imported. | ||
| 519 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | 515 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) |
| 520 | { | 516 | { |
| 521 | const BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | 517 | BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; |
| 522 | if (!pProvider->fImported) | 518 | |
| 519 | // Only need to handle providers that were authored directly in the bundle. | ||
| 520 | if (pProvider->fImported) | ||
| 523 | { | 521 | { |
| 524 | fAllImportedProviders = FALSE; | 522 | continue; |
| 525 | break; | ||
| 526 | } | 523 | } |
| 527 | } | ||
| 528 | 524 | ||
| 529 | if (!fAllImportedProviders) | 525 | pProvider->providerExecute = dependencyExecuteAction; |
| 530 | { | 526 | pProvider->providerRollback = dependencyRollbackAction; |
| 531 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | 527 | |
| 528 | // Don't overwrite providers that we don't own. | ||
| 529 | if (pPackage->compatiblePackage.fDetected) | ||
| 530 | { | ||
| 531 | if (BURN_DEPENDENCY_ACTION_REGISTER == pProvider->providerExecute) | ||
| 532 | { | ||
| 533 | pProvider->providerExecute = BURN_DEPENDENCY_ACTION_NONE; | ||
| 534 | pProvider->providerRollback = BURN_DEPENDENCY_ACTION_NONE; | ||
| 535 | } | ||
| 536 | |||
| 537 | if (BURN_DEPENDENCY_ACTION_REGISTER == pProvider->providerRollback) | ||
| 538 | { | ||
| 539 | pProvider->providerRollback = BURN_DEPENDENCY_ACTION_NONE; | ||
| 540 | } | ||
| 541 | } | ||
| 542 | |||
| 543 | if (BURN_DEPENDENCY_ACTION_UNREGISTER == pProvider->providerExecute && !pProvider->fExists) | ||
| 544 | { | ||
| 545 | pProvider->providerExecute = BURN_DEPENDENCY_ACTION_NONE; | ||
| 546 | } | ||
| 547 | |||
| 548 | if (BURN_DEPENDENCY_ACTION_UNREGISTER == pProvider->providerRollback && pProvider->fExists || | ||
| 549 | BURN_DEPENDENCY_ACTION_REGISTER == pProvider->providerRollback && !pProvider->fExists) | ||
| 532 | { | 550 | { |
| 533 | BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | 551 | pProvider->providerRollback = BURN_DEPENDENCY_ACTION_NONE; |
| 534 | pProvider->providerExecute = dependencyExecuteAction; | ||
| 535 | pProvider->providerRollback = dependencyRollbackAction; | ||
| 536 | } | 552 | } |
| 537 | 553 | ||
| 538 | if (BURN_DEPENDENCY_ACTION_NONE != dependencyExecuteAction) | 554 | if (BURN_DEPENDENCY_ACTION_NONE != pProvider->providerExecute) |
| 539 | { | 555 | { |
| 540 | pPackage->fProviderExecute = TRUE; | 556 | pPackage->fProviderExecute = TRUE; |
| 541 | } | 557 | } |
| 542 | 558 | ||
| 543 | if (BURN_DEPENDENCY_ACTION_NONE != dependencyRollbackAction) | 559 | if (BURN_DEPENDENCY_ACTION_NONE != pProvider->providerRollback) |
| 544 | { | 560 | { |
| 545 | pPackage->fProviderRollback = TRUE; | 561 | pPackage->fProviderRollback = TRUE; |
| 546 | } | 562 | } |
| @@ -567,6 +583,23 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
| 567 | pProvider->dependentExecute = dependencyExecuteAction; | 583 | pProvider->dependentExecute = dependencyExecuteAction; |
| 568 | pProvider->dependentRollback = dependencyRollbackAction; | 584 | pProvider->dependentRollback = dependencyRollbackAction; |
| 569 | 585 | ||
| 586 | if (BURN_DEPENDENCY_ACTION_REGISTER == pProvider->dependentRollback && | ||
| 587 | BURN_DEPENDENCY_ACTION_UNREGISTER == pProvider->providerExecute && BURN_DEPENDENCY_ACTION_REGISTER != pProvider->providerRollback) | ||
| 588 | { | ||
| 589 | pProvider->dependentRollback = BURN_DEPENDENCY_ACTION_NONE; | ||
| 590 | } | ||
| 591 | |||
| 592 | if (BURN_DEPENDENCY_ACTION_UNREGISTER == pProvider->dependentExecute && !pProvider->fBundleRegisteredAsDependent) | ||
| 593 | { | ||
| 594 | pProvider->dependentExecute = BURN_DEPENDENCY_ACTION_NONE; | ||
| 595 | } | ||
| 596 | |||
| 597 | if (BURN_DEPENDENCY_ACTION_UNREGISTER == pProvider->dependentRollback && pProvider->fBundleRegisteredAsDependent || | ||
| 598 | BURN_DEPENDENCY_ACTION_REGISTER == pProvider->dependentRollback && !pProvider->fBundleRegisteredAsDependent) | ||
| 599 | { | ||
| 600 | pProvider->dependentRollback = BURN_DEPENDENCY_ACTION_NONE; | ||
| 601 | } | ||
| 602 | |||
| 570 | // The highest aggregate action state found will be returned. | 603 | // The highest aggregate action state found will be returned. |
| 571 | if (pPackage->dependencyExecute < pProvider->dependentExecute) | 604 | if (pPackage->dependencyExecute < pProvider->dependentExecute) |
| 572 | { | 605 | { |
| @@ -655,16 +688,8 @@ extern "C" HRESULT DependencyPlanPackageComplete( | |||
| 655 | // installed and all that good stuff. | 688 | // installed and all that good stuff. |
| 656 | if (BURN_DEPENDENCY_ACTION_REGISTER == pPackage->dependencyExecute) | 689 | if (BURN_DEPENDENCY_ACTION_REGISTER == pPackage->dependencyExecute) |
| 657 | { | 690 | { |
| 658 | // Recalculate the dependency actions in case other operations may have changed | 691 | hr = AddPackageDependencyActions(NULL, pPackage, pPlan, pPackage->dependencyExecute, pPackage->dependencyRollback); |
| 659 | // the package execution state. | 692 | ExitOnFailure(hr, "Failed to plan the dependency actions for package: %ls", pPackage->sczId); |
| 660 | CalculateDependencyActionStates(pPackage, pPlan->action, &pPackage->dependencyExecute, &pPackage->dependencyRollback); | ||
| 661 | |||
| 662 | // If the dependency execution action is *still* to register, add the dependency actions to the plan. | ||
| 663 | if (BURN_DEPENDENCY_ACTION_REGISTER == pPackage->dependencyExecute) | ||
| 664 | { | ||
| 665 | hr = AddPackageDependencyActions(NULL, pPackage, pPlan, pPackage->dependencyExecute, pPackage->dependencyRollback); | ||
| 666 | ExitOnFailure(hr, "Failed to plan the dependency actions for package: %ls", pPackage->sczId); | ||
| 667 | } | ||
| 668 | } | 693 | } |
| 669 | 694 | ||
| 670 | LExit: | 695 | LExit: |
| @@ -863,15 +888,6 @@ extern "C" HRESULT DependencyDetectCompatibleEntry( | |||
| 863 | LPCWSTR wzPackageProviderId = GetPackageProviderId(pPackage); | 888 | LPCWSTR wzPackageProviderId = GetPackageProviderId(pPackage); |
| 864 | HKEY hkHive = pRegistration->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 889 | HKEY hkHive = pRegistration->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| 865 | 890 | ||
| 866 | switch (pPackage->type) | ||
| 867 | { | ||
| 868 | case BURN_PACKAGE_TYPE_MSI: | ||
| 869 | // Only MSI packages can handle compatible entries. | ||
| 870 | break; | ||
| 871 | default: | ||
| 872 | ExitFunction(); | ||
| 873 | } | ||
| 874 | |||
| 875 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | 891 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) |
| 876 | { | 892 | { |
| 877 | BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | 893 | BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; |
| @@ -944,46 +960,30 @@ static HRESULT DetectPackageDependents( | |||
| 944 | BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | 960 | BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; |
| 945 | 961 | ||
| 946 | hr = DepCheckDependents(hkHive, pProvider->sczKey, 0, NULL, &pProvider->rgDependents, &pProvider->cDependents); | 962 | hr = DepCheckDependents(hkHive, pProvider->sczKey, 0, NULL, &pProvider->rgDependents, &pProvider->cDependents); |
| 947 | if (E_FILENOTFOUND != hr) | 963 | if (E_FILENOTFOUND == hr) |
| 948 | { | 964 | { |
| 949 | ExitOnFailure(hr, "Failed dependents check on package provider: %ls", pProvider->sczKey); | 965 | hr = S_OK; |
| 950 | 966 | } | |
| 951 | if (!pPackage->fPackageProviderExists && (0 < pProvider->cDependents || GetProviderExists(hkHive, pProvider->sczKey))) | 967 | ExitOnFailure(hr, "Failed dependents check on package provider: %ls", pProvider->sczKey); |
| 952 | { | ||
| 953 | pPackage->fPackageProviderExists = TRUE; | ||
| 954 | } | ||
| 955 | |||
| 956 | if (fCanIgnorePresence && !fBundleRegisteredAsDependent) | ||
| 957 | { | ||
| 958 | for (DWORD iDependent = 0; iDependent < pProvider->cDependents; ++iDependent) | ||
| 959 | { | ||
| 960 | DEPENDENCY* pDependent = pProvider->rgDependents + iDependent; | ||
| 961 | 968 | ||
| 962 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczId, -1, pDependent->sczKey, -1)) | 969 | if (0 < pProvider->cDependents || GetProviderExists(hkHive, pProvider->sczKey)) |
| 963 | { | 970 | { |
| 964 | fBundleRegisteredAsDependent = TRUE; | 971 | pProvider->fExists = TRUE; |
| 965 | break; | ||
| 966 | } | ||
| 967 | } | ||
| 968 | } | ||
| 969 | } | 972 | } |
| 970 | else | 973 | |
| 974 | for (DWORD iDependent = 0; iDependent < pProvider->cDependents; ++iDependent) | ||
| 971 | { | 975 | { |
| 972 | hr = S_OK; | 976 | DEPENDENCY* pDependent = pProvider->rgDependents + iDependent; |
| 973 | 977 | ||
| 974 | if (!pPackage->fPackageProviderExists && GetProviderExists(hkHive, pProvider->sczKey)) | 978 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczId, -1, pDependent->sczKey, -1)) |
| 975 | { | 979 | { |
| 976 | pPackage->fPackageProviderExists = TRUE; | 980 | pProvider->fBundleRegisteredAsDependent = TRUE; |
| 981 | fBundleRegisteredAsDependent = TRUE; | ||
| 982 | break; | ||
| 977 | } | 983 | } |
| 978 | } | 984 | } |
| 979 | } | 985 | } |
| 980 | 986 | ||
| 981 | // Older bundles may not have written the id so try the default. | ||
| 982 | if (!pPackage->fPackageProviderExists && BURN_PACKAGE_TYPE_MSI == pPackage->type && pPackage->Msi.sczProductCode && GetProviderExists(hkHive, pPackage->Msi.sczProductCode)) | ||
| 983 | { | ||
| 984 | pPackage->fPackageProviderExists = TRUE; | ||
| 985 | } | ||
| 986 | |||
| 987 | if (fCanIgnorePresence && !fBundleRegisteredAsDependent) | 987 | if (fCanIgnorePresence && !fBundleRegisteredAsDependent) |
| 988 | { | 988 | { |
| 989 | if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState) | 989 | if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState) |
| @@ -1190,95 +1190,54 @@ static BOOL GetProviderExists( | |||
| 1190 | *********************************************************************/ | 1190 | *********************************************************************/ |
| 1191 | static void CalculateDependencyActionStates( | 1191 | static void CalculateDependencyActionStates( |
| 1192 | __in const BURN_PACKAGE* pPackage, | 1192 | __in const BURN_PACKAGE* pPackage, |
| 1193 | __in const BOOTSTRAPPER_ACTION action, | ||
| 1194 | __out BURN_DEPENDENCY_ACTION* pDependencyExecuteAction, | 1193 | __out BURN_DEPENDENCY_ACTION* pDependencyExecuteAction, |
| 1195 | __out BURN_DEPENDENCY_ACTION* pDependencyRollbackAction | 1194 | __out BURN_DEPENDENCY_ACTION* pDependencyRollbackAction |
| 1196 | ) | 1195 | ) |
| 1197 | { | 1196 | { |
| 1198 | switch (action) | 1197 | switch (pPackage->execute) |
| 1199 | { | 1198 | { |
| 1200 | case BOOTSTRAPPER_ACTION_UNINSTALL: | 1199 | case BOOTSTRAPPER_ACTION_STATE_NONE: |
| 1201 | // Always remove the dependency when uninstalling a bundle even if the package is absent. | 1200 | switch (pPackage->requested) |
| 1202 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_UNREGISTER; | ||
| 1203 | break; | ||
| 1204 | case BOOTSTRAPPER_ACTION_INSTALL: __fallthrough; | ||
| 1205 | case BOOTSTRAPPER_ACTION_CACHE: | ||
| 1206 | // Always remove the dependency during rollback when installing a bundle. | ||
| 1207 | *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_UNREGISTER; | ||
| 1208 | __fallthrough; | ||
| 1209 | case BOOTSTRAPPER_ACTION_MODIFY: __fallthrough; | ||
| 1210 | case BOOTSTRAPPER_ACTION_REPAIR: | ||
| 1211 | switch (pPackage->execute) | ||
| 1212 | { | 1201 | { |
| 1213 | case BOOTSTRAPPER_ACTION_STATE_NONE: | 1202 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: |
| 1214 | switch (pPackage->requested) | 1203 | // Unregister if the package is not requested but already not installed. |
| 1204 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_UNREGISTER; | ||
| 1205 | break; | ||
| 1206 | case BOOTSTRAPPER_REQUEST_STATE_NONE: | ||
| 1207 | // Register if a newer, compatible package is already installed. | ||
| 1208 | switch (pPackage->currentState) | ||
| 1215 | { | 1209 | { |
| 1216 | case BOOTSTRAPPER_REQUEST_STATE_NONE: | 1210 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; |
| 1217 | // Register if a newer, compatible package is already installed. | 1211 | case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: |
| 1218 | switch (pPackage->currentState) | 1212 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_REGISTER; |
| 1219 | { | ||
| 1220 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: | ||
| 1221 | if (!pPackage->fPackageProviderExists) | ||
| 1222 | { | ||
| 1223 | break; | ||
| 1224 | } | ||
| 1225 | __fallthrough; | ||
| 1226 | case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: | ||
| 1227 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_REGISTER; | ||
| 1228 | break; | ||
| 1229 | } | ||
| 1230 | break; | ||
| 1231 | case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; | ||
| 1232 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
| 1233 | // Register if the package is requested but already installed. | ||
| 1234 | switch (pPackage->currentState) | ||
| 1235 | { | ||
| 1236 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: | ||
| 1237 | if (!pPackage->fPackageProviderExists) | ||
| 1238 | { | ||
| 1239 | break; | ||
| 1240 | } | ||
| 1241 | __fallthrough; | ||
| 1242 | case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: __fallthrough; | ||
| 1243 | case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: | ||
| 1244 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_REGISTER; | ||
| 1245 | break; | ||
| 1246 | } | ||
| 1247 | break; | 1213 | break; |
| 1248 | } | 1214 | } |
| 1249 | break; | 1215 | break; |
| 1250 | case BOOTSTRAPPER_ACTION_STATE_UNINSTALL: | 1216 | case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; |
| 1251 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_UNREGISTER; | 1217 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: |
| 1252 | break; | 1218 | // Register if the package is requested but already installed. |
| 1253 | case BOOTSTRAPPER_ACTION_STATE_INSTALL: __fallthrough; | ||
| 1254 | case BOOTSTRAPPER_ACTION_STATE_MODIFY: __fallthrough; | ||
| 1255 | case BOOTSTRAPPER_ACTION_STATE_REPAIR: __fallthrough; | ||
| 1256 | case BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE: | ||
| 1257 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_REGISTER; | 1219 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_REGISTER; |
| 1258 | break; | 1220 | break; |
| 1259 | } | 1221 | } |
| 1260 | break; | 1222 | break; |
| 1223 | case BOOTSTRAPPER_ACTION_STATE_UNINSTALL: | ||
| 1224 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_UNREGISTER; | ||
| 1225 | break; | ||
| 1226 | case BOOTSTRAPPER_ACTION_STATE_INSTALL: __fallthrough; | ||
| 1227 | case BOOTSTRAPPER_ACTION_STATE_MODIFY: __fallthrough; | ||
| 1228 | case BOOTSTRAPPER_ACTION_STATE_REPAIR: __fallthrough; | ||
| 1229 | case BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE: | ||
| 1230 | *pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_REGISTER; | ||
| 1231 | break; | ||
| 1261 | } | 1232 | } |
| 1262 | 1233 | ||
| 1263 | switch (*pDependencyExecuteAction) | 1234 | switch (*pDependencyExecuteAction) |
| 1264 | { | 1235 | { |
| 1265 | case BURN_DEPENDENCY_ACTION_REGISTER: | 1236 | case BURN_DEPENDENCY_ACTION_REGISTER: |
| 1266 | switch (pPackage->currentState) | 1237 | *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_UNREGISTER; |
| 1267 | { | ||
| 1268 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; | ||
| 1269 | case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: | ||
| 1270 | *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_UNREGISTER; | ||
| 1271 | break; | ||
| 1272 | } | ||
| 1273 | break; | 1238 | break; |
| 1274 | case BURN_DEPENDENCY_ACTION_UNREGISTER: | 1239 | case BURN_DEPENDENCY_ACTION_UNREGISTER: |
| 1275 | switch (pPackage->currentState) | 1240 | *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_REGISTER; |
| 1276 | { | ||
| 1277 | case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: __fallthrough; | ||
| 1278 | case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: | ||
| 1279 | *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_REGISTER; | ||
| 1280 | break; | ||
| 1281 | } | ||
| 1282 | break; | 1241 | break; |
| 1283 | } | 1242 | } |
| 1284 | } | 1243 | } |
| @@ -1376,13 +1335,10 @@ static HRESULT RegisterPackageProvider( | |||
| 1376 | { | 1335 | { |
| 1377 | HRESULT hr = S_OK; | 1336 | HRESULT hr = S_OK; |
| 1378 | 1337 | ||
| 1379 | if (!pProvider->fImported) | 1338 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_PACKAGE_REGISTER, pProvider->sczKey, pProvider->sczVersion, wzPackageId); |
| 1380 | { | ||
| 1381 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_PACKAGE_REGISTER, pProvider->sczKey, pProvider->sczVersion, wzPackageId); | ||
| 1382 | 1339 | ||
| 1383 | hr = DepRegisterDependency(hkRoot, pProvider->sczKey, pProvider->sczVersion, pProvider->sczDisplayName, wzPackageProviderId, 0); | 1340 | hr = DepRegisterDependency(hkRoot, pProvider->sczKey, pProvider->sczVersion, pProvider->sczDisplayName, wzPackageProviderId, 0); |
| 1384 | ExitOnFailure(hr, "Failed to register the package dependency provider: %ls", pProvider->sczKey); | 1341 | ExitOnFailure(hr, "Failed to register the package dependency provider: %ls", pProvider->sczKey); |
| 1385 | } | ||
| 1386 | 1342 | ||
| 1387 | LExit: | 1343 | LExit: |
| 1388 | if (!fVital) | 1344 | if (!fVital) |
| @@ -1406,17 +1362,14 @@ static void UnregisterPackageProvider( | |||
| 1406 | { | 1362 | { |
| 1407 | HRESULT hr = S_OK; | 1363 | HRESULT hr = S_OK; |
| 1408 | 1364 | ||
| 1409 | if (!pProvider->fImported) | 1365 | hr = DepUnregisterDependency(hkRoot, pProvider->sczKey); |
| 1366 | if (SUCCEEDED(hr)) | ||
| 1410 | { | 1367 | { |
| 1411 | hr = DepUnregisterDependency(hkRoot, pProvider->sczKey); | 1368 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_PACKAGE_UNREGISTERED, pProvider->sczKey, wzPackageId); |
| 1412 | if (SUCCEEDED(hr)) | 1369 | } |
| 1413 | { | 1370 | else if (FAILED(hr) && E_FILENOTFOUND != hr) |
| 1414 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_PACKAGE_UNREGISTERED, pProvider->sczKey, wzPackageId); | 1371 | { |
| 1415 | } | 1372 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_PACKAGE_UNREGISTERED_FAILED, pProvider->sczKey, wzPackageId, hr); |
| 1416 | else if (FAILED(hr) && E_FILENOTFOUND != hr) | ||
| 1417 | { | ||
| 1418 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_PACKAGE_UNREGISTERED_FAILED, pProvider->sczKey, wzPackageId, hr); | ||
| 1419 | } | ||
| 1420 | } | 1373 | } |
| 1421 | } | 1374 | } |
| 1422 | 1375 | ||
diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp index 617b418b..e251871c 100644 --- a/src/burn/engine/detect.cpp +++ b/src/burn/engine/detect.cpp | |||
| @@ -57,7 +57,6 @@ extern "C" void DetectReset( | |||
| 57 | BURN_PACKAGE* pPackage = pPackages->rgPackages + iPackage; | 57 | BURN_PACKAGE* pPackage = pPackages->rgPackages + iPackage; |
| 58 | 58 | ||
| 59 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN; | 59 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN; |
| 60 | pPackage->fPackageProviderExists = FALSE; | ||
| 61 | pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; | 60 | pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; |
| 62 | pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; | 61 | pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; |
| 63 | 62 | ||
| @@ -92,6 +91,9 @@ extern "C" void DetectReset( | |||
| 92 | { | 91 | { |
| 93 | BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders + iProvider; | 92 | BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders + iProvider; |
| 94 | 93 | ||
| 94 | pProvider->fExists = FALSE; | ||
| 95 | pProvider->fBundleRegisteredAsDependent = FALSE; | ||
| 96 | |||
| 95 | if (pProvider->rgDependents) | 97 | if (pProvider->rgDependents) |
| 96 | { | 98 | { |
| 97 | ReleaseDependencyArray(pProvider->rgDependents, pProvider->cDependents); | 99 | ReleaseDependencyArray(pProvider->rgDependents, pProvider->cDependents); |
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 38be2098..6d1b5dd9 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
| @@ -193,8 +193,10 @@ typedef struct _BURN_DEPENDENCY_PROVIDER | |||
| 193 | LPWSTR sczDisplayName; | 193 | LPWSTR sczDisplayName; |
| 194 | BOOL fImported; | 194 | BOOL fImported; |
| 195 | 195 | ||
| 196 | DEPENDENCY* rgDependents; // only valid after Detect. | 196 | BOOL fExists; // only valid after Detect. |
| 197 | UINT cDependents; // only valid after Detect. | 197 | BOOL fBundleRegisteredAsDependent; // only valid after Detect. |
| 198 | DEPENDENCY* rgDependents; // only valid after Detect. | ||
| 199 | UINT cDependents; // only valid after Detect. | ||
| 198 | 200 | ||
| 199 | BURN_DEPENDENCY_ACTION dependentExecute; // only valid during Plan. | 201 | BURN_DEPENDENCY_ACTION dependentExecute; // only valid during Plan. |
| 200 | BURN_DEPENDENCY_ACTION dependentRollback; // only valid during Plan. | 202 | BURN_DEPENDENCY_ACTION dependentRollback; // only valid during Plan. |
| @@ -264,7 +266,6 @@ typedef struct _BURN_PACKAGE | |||
| 264 | 266 | ||
| 265 | BOOTSTRAPPER_PACKAGE_STATE currentState; // only valid after Detect. | 267 | BOOTSTRAPPER_PACKAGE_STATE currentState; // only valid after Detect. |
| 266 | BOOL fCached; // only valid after Detect. | 268 | BOOL fCached; // only valid after Detect. |
| 267 | BOOL fPackageProviderExists; // only valid after Detect. | ||
| 268 | BOOTSTRAPPER_CACHE_TYPE cacheType; // only valid during Plan. | 269 | BOOTSTRAPPER_CACHE_TYPE cacheType; // only valid during Plan. |
| 269 | BOOTSTRAPPER_REQUEST_STATE defaultRequested;// only valid during Plan. | 270 | BOOTSTRAPPER_REQUEST_STATE defaultRequested;// only valid during Plan. |
| 270 | BOOTSTRAPPER_REQUEST_STATE requested; // only valid during Plan. | 271 | BOOTSTRAPPER_REQUEST_STATE requested; // only valid during Plan. |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 812dcd15..f850d49c 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
| @@ -67,7 +67,6 @@ static HRESULT ProcessPackageRollbackBoundary( | |||
| 67 | ); | 67 | ); |
| 68 | static HRESULT GetActionDefaultRequestState( | 68 | static HRESULT GetActionDefaultRequestState( |
| 69 | __in BOOTSTRAPPER_ACTION action, | 69 | __in BOOTSTRAPPER_ACTION action, |
| 70 | __in BOOL fPermanent, | ||
| 71 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, | 70 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, |
| 72 | __out BOOTSTRAPPER_REQUEST_STATE* pRequestState | 71 | __out BOOTSTRAPPER_REQUEST_STATE* pRequestState |
| 73 | ); | 72 | ); |
| @@ -318,7 +317,6 @@ LExit: | |||
| 318 | extern "C" HRESULT PlanDefaultPackageRequestState( | 317 | extern "C" HRESULT PlanDefaultPackageRequestState( |
| 319 | __in BURN_PACKAGE_TYPE packageType, | 318 | __in BURN_PACKAGE_TYPE packageType, |
| 320 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, | 319 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, |
| 321 | __in BOOL fPermanent, | ||
| 322 | __in BOOTSTRAPPER_ACTION action, | 320 | __in BOOTSTRAPPER_ACTION action, |
| 323 | __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, | 321 | __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, |
| 324 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 322 | __in BOOTSTRAPPER_RELATION_TYPE relationType, |
| @@ -333,6 +331,20 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
| 333 | { | 331 | { |
| 334 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; | 332 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; |
| 335 | } | 333 | } |
| 334 | else if (BOOTSTRAPPER_ACTION_CACHE == action) | ||
| 335 | { | ||
| 336 | switch (currentState) | ||
| 337 | { | ||
| 338 | case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: __fallthrough; | ||
| 339 | case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: | ||
| 340 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | ||
| 341 | break; | ||
| 342 | |||
| 343 | default: | ||
| 344 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; | ||
| 345 | break; | ||
| 346 | } | ||
| 347 | } | ||
| 336 | else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) | 348 | else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) |
| 337 | { | 349 | { |
| 338 | // For patch related bundles, only install a patch if currently absent during install, modify, or repair. | 350 | // For patch related bundles, only install a patch if currently absent during install, modify, or repair. |
| @@ -345,33 +357,30 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
| 345 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | 357 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; |
| 346 | } | 358 | } |
| 347 | } | 359 | } |
| 348 | else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action) | ||
| 349 | { | ||
| 350 | // Superseded means the package is on the machine but not active, so only uninstall operations are allowed. | ||
| 351 | // All other operations do nothing. | ||
| 352 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 353 | } | ||
| 354 | else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType)) | ||
| 355 | { | ||
| 356 | // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete | ||
| 357 | // and present so allow them to be removed during uninstall. Everyone else, gets nothing. | ||
| 358 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 359 | } | ||
| 360 | else // pick the best option for the action state and install condition. | 360 | else // pick the best option for the action state and install condition. |
| 361 | { | 361 | { |
| 362 | hr = GetActionDefaultRequestState(action, fPermanent, currentState, &defaultRequestState); | 362 | hr = GetActionDefaultRequestState(action, currentState, &defaultRequestState); |
| 363 | ExitOnFailure(hr, "Failed to get default request state for action."); | 363 | ExitOnFailure(hr, "Failed to get default request state for action."); |
| 364 | 364 | ||
| 365 | // If we're doing an install, use the install condition | 365 | if (BOOTSTRAPPER_ACTION_UNINSTALL != action) |
| 366 | // to determine whether to use the default request state or make the package absent. | ||
| 367 | if (BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == installCondition) | ||
| 368 | { | ||
| 369 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; | ||
| 370 | } | ||
| 371 | else // just set the package to the default request state. | ||
| 372 | { | 366 | { |
| 373 | *pRequestState = defaultRequestState; | 367 | // If we're not doing an uninstall, use the install condition |
| 368 | // to determine whether to use the default request state or make the package absent. | ||
| 369 | if (BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == installCondition) | ||
| 370 | { | ||
| 371 | defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; | ||
| 372 | } | ||
| 373 | // Obsolete means the package is not on the machine and should not be installed, | ||
| 374 | // *except* patches can be obsolete and present. | ||
| 375 | // Superseded means the package is on the machine but not active, so only uninstall operations are allowed. | ||
| 376 | // All other operations do nothing. | ||
| 377 | else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState || BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState) | ||
| 378 | { | ||
| 379 | defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT <= defaultRequestState ? BOOTSTRAPPER_REQUEST_STATE_NONE : defaultRequestState; | ||
| 380 | } | ||
| 374 | } | 381 | } |
| 382 | |||
| 383 | *pRequestState = defaultRequestState; | ||
| 375 | } | 384 | } |
| 376 | 385 | ||
| 377 | LExit: | 386 | LExit: |
| @@ -873,7 +882,7 @@ static HRESULT InitializePackage( | |||
| 873 | } | 882 | } |
| 874 | 883 | ||
| 875 | // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. | 884 | // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. |
| 876 | hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, pPackage->fPermanent, pPlan->action, installCondition, relationType, &pPackage->defaultRequested); | 885 | hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, pPlan->action, installCondition, relationType, &pPackage->defaultRequested); |
| 877 | ExitOnFailure(hr, "Failed to set default package state."); | 886 | ExitOnFailure(hr, "Failed to set default package state."); |
| 878 | 887 | ||
| 879 | pPackage->requested = pPackage->defaultRequested; | 888 | pPackage->requested = pPackage->defaultRequested; |
| @@ -1993,7 +2002,6 @@ static void ResetPlannedRollbackBoundaryState( | |||
| 1993 | 2002 | ||
| 1994 | static HRESULT GetActionDefaultRequestState( | 2003 | static HRESULT GetActionDefaultRequestState( |
| 1995 | __in BOOTSTRAPPER_ACTION action, | 2004 | __in BOOTSTRAPPER_ACTION action, |
| 1996 | __in BOOL fPermanent, | ||
| 1997 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, | 2005 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, |
| 1998 | __out BOOTSTRAPPER_REQUEST_STATE* pRequestState | 2006 | __out BOOTSTRAPPER_REQUEST_STATE* pRequestState |
| 1999 | ) | 2007 | ) |
| @@ -2002,22 +2010,7 @@ static HRESULT GetActionDefaultRequestState( | |||
| 2002 | 2010 | ||
| 2003 | switch (action) | 2011 | switch (action) |
| 2004 | { | 2012 | { |
| 2005 | case BOOTSTRAPPER_ACTION_CACHE: | 2013 | case BOOTSTRAPPER_ACTION_INSTALL: |
| 2006 | switch (currentState) | ||
| 2007 | { | ||
| 2008 | case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: | ||
| 2009 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | ||
| 2010 | break; | ||
| 2011 | |||
| 2012 | default: | ||
| 2013 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; | ||
| 2014 | break; | ||
| 2015 | } | ||
| 2016 | break; | ||
| 2017 | |||
| 2018 | case BOOTSTRAPPER_ACTION_INSTALL: __fallthrough; | ||
| 2019 | case BOOTSTRAPPER_ACTION_UPDATE_REPLACE: __fallthrough; | ||
| 2020 | case BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED: | ||
| 2021 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | 2014 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; |
| 2022 | break; | 2015 | break; |
| 2023 | 2016 | ||
| @@ -2026,7 +2019,7 @@ static HRESULT GetActionDefaultRequestState( | |||
| 2026 | break; | 2019 | break; |
| 2027 | 2020 | ||
| 2028 | case BOOTSTRAPPER_ACTION_UNINSTALL: | 2021 | case BOOTSTRAPPER_ACTION_UNINSTALL: |
| 2029 | *pRequestState = fPermanent ? BOOTSTRAPPER_REQUEST_STATE_NONE : BOOTSTRAPPER_REQUEST_STATE_ABSENT; | 2022 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; |
| 2030 | break; | 2023 | break; |
| 2031 | 2024 | ||
| 2032 | case BOOTSTRAPPER_ACTION_MODIFY: | 2025 | case BOOTSTRAPPER_ACTION_MODIFY: |
| @@ -2052,7 +2045,7 @@ static HRESULT GetActionDefaultRequestState( | |||
| 2052 | } | 2045 | } |
| 2053 | 2046 | ||
| 2054 | LExit: | 2047 | LExit: |
| 2055 | return hr; | 2048 | return hr; |
| 2056 | } | 2049 | } |
| 2057 | 2050 | ||
| 2058 | static HRESULT AddRegistrationAction( | 2051 | static HRESULT AddRegistrationAction( |
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index 3e5ab159..0734e39f 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h | |||
| @@ -317,7 +317,6 @@ HRESULT PlanSetVariables( | |||
| 317 | HRESULT PlanDefaultPackageRequestState( | 317 | HRESULT PlanDefaultPackageRequestState( |
| 318 | __in BURN_PACKAGE_TYPE packageType, | 318 | __in BURN_PACKAGE_TYPE packageType, |
| 319 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, | 319 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, |
| 320 | __in BOOL fPermanent, | ||
| 321 | __in BOOTSTRAPPER_ACTION action, | 320 | __in BOOTSTRAPPER_ACTION action, |
| 322 | __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, | 321 | __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, |
| 323 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 322 | __in BOOTSTRAPPER_RELATION_TYPE relationType, |
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 1c390782..99644115 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp | |||
| @@ -305,7 +305,7 @@ namespace Bootstrapper | |||
| 305 | 305 | ||
| 306 | InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState); | 306 | InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState); |
| 307 | DetectPackagesAsAbsent(pEngineState); | 307 | DetectPackagesAsAbsent(pEngineState); |
| 308 | DetectCompatibleMsiPackage(pEngineState->packages.rgPackages, L"{C24F3903-38E7-4D44-8037-D9856B3C5046}", L"2.0.0.0"); | 308 | DetectCompatibleMsiPackage(pEngineState, pEngineState->packages.rgPackages, L"{C24F3903-38E7-4D44-8037-D9856B3C5046}", L"2.0.0.0"); |
| 309 | 309 | ||
| 310 | hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL); | 310 | hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL); |
| 311 | NativeAssert::Succeeded(hr, "CorePlan failed"); | 311 | NativeAssert::Succeeded(hr, "CorePlan failed"); |
| @@ -491,7 +491,6 @@ namespace Bootstrapper | |||
| 491 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 491 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 492 | ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); | 492 | ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); |
| 493 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 493 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 494 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 495 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | 494 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); |
| 496 | Assert::Equal(dwIndex, pPlan->cExecuteActions); | 495 | Assert::Equal(dwIndex, pPlan->cExecuteActions); |
| 497 | 496 | ||
| @@ -501,8 +500,6 @@ namespace Bootstrapper | |||
| 501 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); | 500 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); |
| 502 | ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); | 501 | ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); |
| 503 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 502 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 504 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1); | ||
| 505 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 506 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 503 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 507 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | 504 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); |
| 508 | Assert::Equal(dwIndex, pPlan->cRollbackActions); | 505 | Assert::Equal(dwIndex, pPlan->cRollbackActions); |
| @@ -561,8 +558,6 @@ namespace Bootstrapper | |||
| 561 | dwIndex = 0; | 558 | dwIndex = 0; |
| 562 | DWORD dwExecuteCheckpointId = 1; | 559 | DWORD dwExecuteCheckpointId = 1; |
| 563 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); | 560 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); |
| 564 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", unregisterActions1, 1); | ||
| 565 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1); | ||
| 566 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER, 0); | 561 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER, 0); |
| 567 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 562 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 568 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 563 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| @@ -613,10 +608,10 @@ namespace Bootstrapper | |||
| 613 | vfUseRelatedBundleRequestState = TRUE; | 608 | vfUseRelatedBundleRequestState = TRUE; |
| 614 | vRelatedBundleRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; | 609 | vRelatedBundleRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; |
| 615 | 610 | ||
| 616 | hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_MODIFY); | 611 | hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_INSTALL); |
| 617 | NativeAssert::Succeeded(hr, "CorePlan failed"); | 612 | NativeAssert::Succeeded(hr, "CorePlan failed"); |
| 618 | 613 | ||
| 619 | Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_MODIFY, pPlan->action); | 614 | Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action); |
| 620 | Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine); | 615 | Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine); |
| 621 | Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback); | 616 | Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback); |
| 622 | 617 | ||
| @@ -1258,7 +1253,7 @@ namespace Bootstrapper | |||
| 1258 | } | 1253 | } |
| 1259 | } | 1254 | } |
| 1260 | 1255 | ||
| 1261 | void DetectCompatibleMsiPackage(BURN_PACKAGE* pPackage, LPCWSTR wzProductCode, LPCWSTR wzVersion) | 1256 | void DetectCompatibleMsiPackage(BURN_ENGINE_STATE* pEngineState, BURN_PACKAGE* pPackage, LPCWSTR wzProductCode, LPCWSTR wzVersion) |
| 1262 | { | 1257 | { |
| 1263 | HRESULT hr = S_OK; | 1258 | HRESULT hr = S_OK; |
| 1264 | Assert(BOOTSTRAPPER_PACKAGE_STATE_PRESENT > pPackage->currentState); | 1259 | Assert(BOOTSTRAPPER_PACKAGE_STATE_PRESENT > pPackage->currentState); |
| @@ -1286,6 +1281,8 @@ namespace Bootstrapper | |||
| 1286 | 1281 | ||
| 1287 | hr = StrAllocString(&pCompatiblePackage->compatibleEntry.sczProviderKey, pProvider->sczKey, 0); | 1282 | hr = StrAllocString(&pCompatiblePackage->compatibleEntry.sczProviderKey, pProvider->sczKey, 0); |
| 1288 | NativeAssert::Succeeded(hr, "Failed to copy provider key"); | 1283 | NativeAssert::Succeeded(hr, "Failed to copy provider key"); |
| 1284 | |||
| 1285 | DetectPackageDependent(pPackage, pEngineState->registration.sczId); | ||
| 1289 | } | 1286 | } |
| 1290 | 1287 | ||
| 1291 | void DetectPackageAsAbsent(BURN_PACKAGE* pPackage) | 1288 | void DetectPackageAsAbsent(BURN_PACKAGE* pPackage) |
| @@ -1319,6 +1316,9 @@ namespace Bootstrapper | |||
| 1319 | 1316 | ||
| 1320 | hr = DepDependencyArrayAlloc(&pProvider->rgDependents, &pProvider->cDependents, wzId, NULL); | 1317 | hr = DepDependencyArrayAlloc(&pProvider->rgDependents, &pProvider->cDependents, wzId, NULL); |
| 1321 | NativeAssert::Succeeded(hr, "Failed to add package dependent"); | 1318 | NativeAssert::Succeeded(hr, "Failed to add package dependent"); |
| 1319 | |||
| 1320 | pProvider->fExists = TRUE; | ||
| 1321 | pProvider->fBundleRegisteredAsDependent = TRUE; | ||
| 1322 | } | 1322 | } |
| 1323 | } | 1323 | } |
| 1324 | 1324 | ||
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs index ecd12fb3..7c74f348 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs | |||
| @@ -611,7 +611,7 @@ namespace WixToolsetTest.BurnE2E | |||
| 611 | packageGv2.VerifyInstalled(false); | 611 | packageGv2.VerifyInstalled(false); |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6510")] | 614 | [Fact] |
| 615 | public void DoesntLoseDependenciesOnFailedMajorUpgradeBundleFromMinorUpdateMsi() | 615 | public void DoesntLoseDependenciesOnFailedMajorUpgradeBundleFromMinorUpdateMsi() |
| 616 | { | 616 | { |
| 617 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); | 617 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); |
