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"); |