aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-01-31 15:44:20 -0600
committerSean Hall <r.sean.hall@gmail.com>2022-02-01 23:36:23 -0600
commitb152761dfddc0a131dcd13f70ae0e9b9e41b37fe (patch)
tree40086227e4808bdd99be972f123c57bb1ed23731
parent56c980318e7167be591f7807c2fc34cea7d5cb42 (diff)
downloadwix-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.cpp61
-rw-r--r--src/burn/engine/registration.cpp8
-rw-r--r--src/ext/Dependency/ca/wixdepca.cpp4
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs2
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 );
80static 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
762extern "C" HRESULT DependencyDetectCompatibleEntry( 776extern "C" HRESULT DependencyDetectCompatibleEntry(
@@ -1431,3 +1445,34 @@ static void UnregisterPackageDependency(
1431 } 1445 }
1432 } 1446 }
1433} 1447}
1448
1449static 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");