diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-01-31 15:44:20 -0600 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-02-01 23:36:23 -0600 |
| commit | b152761dfddc0a131dcd13f70ae0e9b9e41b37fe (patch) | |
| tree | 40086227e4808bdd99be972f123c57bb1ed23731 | |
| parent | 56c980318e7167be591f7807c2fc34cea7d5cb42 (diff) | |
| download | wix-b152761dfddc0a131dcd13f70ae0e9b9e41b37fe.tar.gz wix-b152761dfddc0a131dcd13f70ae0e9b9e41b37fe.tar.bz2 wix-b152761dfddc0a131dcd13f70ae0e9b9e41b37fe.zip | |
Remove orphan package providers when unregistering the bundle.
Fixes #3850
| -rw-r--r-- | src/burn/engine/dependency.cpp | 61 | ||||
| -rw-r--r-- | src/burn/engine/registration.cpp | 8 | ||||
| -rw-r--r-- | src/ext/Dependency/ca/wixdepca.cpp | 4 | ||||
| -rw-r--r-- | src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs | 2 |
4 files changed, 60 insertions, 15 deletions
diff --git a/src/burn/engine/dependency.cpp b/src/burn/engine/dependency.cpp index ce183a8a..e94b0e93 100644 --- a/src/burn/engine/dependency.cpp +++ b/src/burn/engine/dependency.cpp | |||
| @@ -77,6 +77,9 @@ static void UnregisterPackageDependency( | |||
| 77 | __in const BURN_PACKAGE* pPackage, | 77 | __in const BURN_PACKAGE* pPackage, |
| 78 | __in_z LPCWSTR wzDependentProviderKey | 78 | __in_z LPCWSTR wzDependentProviderKey |
| 79 | ); | 79 | ); |
| 80 | static void UnregisterOrphanPackageProviders( | ||
| 81 | __in const BURN_PACKAGE* pPackage | ||
| 82 | ); | ||
| 80 | 83 | ||
| 81 | 84 | ||
| 82 | // functions | 85 | // functions |
| @@ -734,15 +737,19 @@ extern "C" void DependencyUnregisterBundle( | |||
| 734 | HRESULT hr = S_OK; | 737 | HRESULT hr = S_OK; |
| 735 | LPCWSTR wzDependentProviderKey = pRegistration->sczId; | 738 | LPCWSTR wzDependentProviderKey = pRegistration->sczId; |
| 736 | 739 | ||
| 737 | // Remove the bundle provider key. | 740 | // If we own the bundle dependency then remove it. |
| 738 | hr = DepUnregisterDependency(pRegistration->hkRoot, pRegistration->sczProviderKey); | 741 | if (!pRegistration->fDetectedForeignProviderKeyBundleId) |
| 739 | if (SUCCEEDED(hr)) | ||
| 740 | { | ||
| 741 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_UNREGISTERED, pRegistration->sczProviderKey); | ||
| 742 | } | ||
| 743 | else if (FAILED(hr) && E_FILENOTFOUND != hr) | ||
| 744 | { | 742 | { |
| 745 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_UNREGISTERED_FAILED, pRegistration->sczProviderKey, hr); | 743 | // Remove the bundle provider key. |
| 744 | hr = DepUnregisterDependency(pRegistration->hkRoot, pRegistration->sczProviderKey); | ||
| 745 | if (SUCCEEDED(hr)) | ||
| 746 | { | ||
| 747 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_UNREGISTERED, pRegistration->sczProviderKey); | ||
| 748 | } | ||
| 749 | else if (FAILED(hr) && E_FILENOTFOUND != hr) | ||
| 750 | { | ||
| 751 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_UNREGISTERED_FAILED, pRegistration->sczProviderKey, hr); | ||
| 752 | } | ||
| 746 | } | 753 | } |
| 747 | 754 | ||
| 748 | // Best effort to make sure this bundle is not registered as a dependent for anything. | 755 | // Best effort to make sure this bundle is not registered as a dependent for anything. |
| @@ -757,6 +764,13 @@ extern "C" void DependencyUnregisterBundle( | |||
| 757 | const BURN_PACKAGE* pPackage = &pRegistration->relatedBundles.rgRelatedBundles[i].package; | 764 | const BURN_PACKAGE* pPackage = &pRegistration->relatedBundles.rgRelatedBundles[i].package; |
| 758 | UnregisterPackageDependency(pPackage->fPerMachine, pPackage, wzDependentProviderKey); | 765 | UnregisterPackageDependency(pPackage->fPerMachine, pPackage, wzDependentProviderKey); |
| 759 | } | 766 | } |
| 767 | |||
| 768 | // Best effort to make sure package providers are removed if unused. | ||
| 769 | for (DWORD i = 0; i < pPackages->cPackages; ++i) | ||
| 770 | { | ||
| 771 | const BURN_PACKAGE* pPackage = pPackages->rgPackages + i; | ||
| 772 | UnregisterOrphanPackageProviders(pPackage); | ||
| 773 | } | ||
| 760 | } | 774 | } |
| 761 | 775 | ||
| 762 | extern "C" HRESULT DependencyDetectCompatibleEntry( | 776 | extern "C" HRESULT DependencyDetectCompatibleEntry( |
| @@ -1431,3 +1445,34 @@ static void UnregisterPackageDependency( | |||
| 1431 | } | 1445 | } |
| 1432 | } | 1446 | } |
| 1433 | } | 1447 | } |
| 1448 | |||
| 1449 | static void UnregisterOrphanPackageProviders( | ||
| 1450 | __in const BURN_PACKAGE* pPackage | ||
| 1451 | ) | ||
| 1452 | { | ||
| 1453 | HRESULT hr = S_OK; | ||
| 1454 | DEPENDENCY* rgDependents = NULL; | ||
| 1455 | UINT cDependents = 0; | ||
| 1456 | HKEY hkRoot = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | ||
| 1457 | |||
| 1458 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | ||
| 1459 | { | ||
| 1460 | const BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | ||
| 1461 | |||
| 1462 | // Skip providers not owned by the bundle. | ||
| 1463 | if (pProvider->fImported) | ||
| 1464 | { | ||
| 1465 | continue; | ||
| 1466 | } | ||
| 1467 | |||
| 1468 | hr = DepCheckDependents(hkRoot, pProvider->sczKey, 0, NULL, &rgDependents, &cDependents); | ||
| 1469 | if (SUCCEEDED(hr) && !cDependents) | ||
| 1470 | { | ||
| 1471 | UnregisterPackageProvider(pProvider, pPackage->sczId, hkRoot); | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | ReleaseDependencyArray(rgDependents, cDependents); | ||
| 1475 | rgDependents = NULL; | ||
| 1476 | cDependents = 0; | ||
| 1477 | } | ||
| 1478 | } | ||
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index 59947867..a1b1b607 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp | |||
| @@ -900,12 +900,8 @@ extern "C" HRESULT RegistrationSessionEnd( | |||
| 900 | { | 900 | { |
| 901 | AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE == registrationType, "Registration type must be NONE if resume mode is NONE"); | 901 | AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE == registrationType, "Registration type must be NONE if resume mode is NONE"); |
| 902 | 902 | ||
| 903 | // If we own the bundle dependency then remove it. | 903 | // Remove the bundle dependencies. |
| 904 | if (!pRegistration->fDetectedForeignProviderKeyBundleId) | 904 | DependencyUnregisterBundle(pRegistration, pPackages); |
| 905 | { | ||
| 906 | // Remove the bundle dependency key. | ||
| 907 | DependencyUnregisterBundle(pRegistration, pPackages); | ||
| 908 | } | ||
| 909 | 905 | ||
| 910 | // Delete update registration key. | 906 | // Delete update registration key. |
| 911 | if (pRegistration->update.fRegisterUpdate) | 907 | if (pRegistration->update.fRegisterUpdate) |
diff --git a/src/ext/Dependency/ca/wixdepca.cpp b/src/ext/Dependency/ca/wixdepca.cpp index 88342217..e9278e04 100644 --- a/src/ext/Dependency/ca/wixdepca.cpp +++ b/src/ext/Dependency/ca/wixdepca.cpp | |||
| @@ -338,6 +338,10 @@ static HRESULT EnsureAbsentDependents( | |||
| 338 | 338 | ||
| 339 | // Check the registry to see if the provider has any dependents registered. | 339 | // Check the registry to see if the provider has any dependents registered. |
| 340 | hr = DepCheckDependents(hkHive, sczProviderKey, iAttributes, sdIgnoredDependents, &rgDependents, &cDependents); | 340 | hr = DepCheckDependents(hkHive, sczProviderKey, iAttributes, sdIgnoredDependents, &rgDependents, &cDependents); |
| 341 | if (E_FILENOTFOUND == hr) | ||
| 342 | { | ||
| 343 | hr = S_OK; | ||
| 344 | } | ||
| 341 | ExitOnFailure(hr, "Failed dependents check for %ls.", sczId); | 345 | ExitOnFailure(hr, "Failed dependents check for %ls.", sczId); |
| 342 | } | 346 | } |
| 343 | 347 | ||
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs index e0b402ff..ecd12fb3 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs | |||
| @@ -857,7 +857,7 @@ namespace WixToolsetTest.BurnE2E | |||
| 857 | bundleA.VerifyExeTestRegistryRootDeleted(testRegistryValueExe); | 857 | bundleA.VerifyExeTestRegistryRootDeleted(testRegistryValueExe); |
| 858 | } | 858 | } |
| 859 | 859 | ||
| 860 | [Fact(Skip = "https://github.com/wixtoolset/issues/issues/3850")] | 860 | [Fact] |
| 861 | public void RemovesDependencyProviderFromUpgradedPackageDuringUninstall() | 861 | public void RemovesDependencyProviderFromUpgradedPackageDuringUninstall() |
| 862 | { | 862 | { |
| 863 | var packageC = this.CreatePackageInstaller("PackageC"); | 863 | var packageC = this.CreatePackageInstaller("PackageC"); |
