From bae756f4354fed4de6097c931590ccafc907fdb2 Mon Sep 17 00:00:00 2001 From: Bob Arnson Date: Mon, 3 Jan 2022 22:36:16 -0500 Subject: Handle 32-bit related-bundle registration... ...from 64-bit bundles. --- src/burn/engine/relatedbundle.cpp | 93 ++++++++++++++-------- .../BundleAv2x64/BundleAv2x64.wixproj | 17 ++++ .../BundleAv2x64/BundleAv2x64.wxs | 10 +++ .../UpgradeRelatedBundleTests.cs | 17 ++++ 4 files changed, 105 insertions(+), 32 deletions(-) create mode 100644 src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2x64/BundleAv2x64.wixproj create mode 100644 src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2x64/BundleAv2x64.wxs diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index 1eafef07..99ed8553 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp @@ -8,9 +8,16 @@ static __callback int __cdecl CompareRelatedBundles( __in void* pvContext, __in const void* pvLeft, __in const void* pvRight +); +static HRESULT InitializeForScopeAndBitness( + __in BOOL fPerMachine, + __in BOOL fWow6432, + __in BURN_REGISTRATION* pRegistration, + __in BURN_RELATED_BUNDLES* pRelatedBundles ); static HRESULT LoadIfRelatedBundle( __in BOOL fPerMachine, + __in BOOL fWow6432, __in HKEY hkUninstallKey, __in_z LPCWSTR sczRelatedBundleId, __in BURN_REGISTRATION* pRegistration, @@ -39,41 +46,16 @@ extern "C" HRESULT RelatedBundlesInitializeForScope( ) { HRESULT hr = S_OK; - HKEY hkRoot = fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - HKEY hkUninstallKey = NULL; - LPWSTR sczRelatedBundleId = NULL; - - hr = RegOpen(hkRoot, BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ, &hkUninstallKey); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) - { - ExitFunction1(hr = S_OK); - } - ExitOnFailure(hr, "Failed to open uninstall registry key."); - for (DWORD dwIndex = 0; /* exit via break below */; ++dwIndex) - { - hr = RegKeyEnum(hkUninstallKey, dwIndex, &sczRelatedBundleId); - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - break; - } - ExitOnFailure(hr, "Failed to enumerate uninstall key for related bundles."); + hr = InitializeForScopeAndBitness(fPerMachine, /*fWow6432*/FALSE, pRegistration, pRelatedBundles); + ExitOnFailure(hr, "Failed to open platform-native uninstall registry key."); - // If we did not find our bundle id, try to load the subkey as a related bundle. - if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, sczRelatedBundleId, -1, pRegistration->sczId, -1)) - { - // Ignore failures here since we'll often find products that aren't actually - // related bundles (or even bundles at all). - HRESULT hrRelatedBundle = LoadIfRelatedBundle(fPerMachine, hkUninstallKey, sczRelatedBundleId, pRegistration, pRelatedBundles); - UNREFERENCED_PARAMETER(hrRelatedBundle); - } - } +#if defined(_WIN64) + hr = InitializeForScopeAndBitness(fPerMachine, /*fWow6432*/TRUE, pRegistration, pRelatedBundles); + ExitOnFailure(hr, "Failed to open 32-bit uninstall registry key."); +#endif LExit: - ReleaseStr(sczRelatedBundleId); - ReleaseRegKey(hkUninstallKey); - return hr; } @@ -186,8 +168,55 @@ static __callback int __cdecl CompareRelatedBundles( return ret; } +static HRESULT InitializeForScopeAndBitness( + __in BOOL fPerMachine, + __in BOOL fWow6432, + __in BURN_REGISTRATION * pRegistration, + __in BURN_RELATED_BUNDLES * pRelatedBundles +) +{ + HRESULT hr = S_OK; + HKEY hkRoot = fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + HKEY hkUninstallKey = NULL; + LPWSTR sczRelatedBundleId = NULL; + + hr = RegOpen(hkRoot, BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ | (fWow6432 ? KEY_WOW64_32KEY : 0), &hkUninstallKey); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) + { + ExitFunction1(hr = S_OK); + } + ExitOnFailure(hr, "Failed to open uninstall registry key."); + + for (DWORD dwIndex = 0; /* exit via break below */; ++dwIndex) + { + hr = RegKeyEnum(hkUninstallKey, dwIndex, &sczRelatedBundleId); + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + break; + } + ExitOnFailure(hr, "Failed to enumerate uninstall key for related bundles."); + + // If we did not find our bundle id, try to load the subkey as a related bundle. + if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, sczRelatedBundleId, -1, pRegistration->sczId, -1)) + { + // Ignore failures here since we'll often find products that aren't actually + // related bundles (or even bundles at all). + HRESULT hrRelatedBundle = LoadIfRelatedBundle(fPerMachine, fWow6432, hkUninstallKey, sczRelatedBundleId, pRegistration, pRelatedBundles); + UNREFERENCED_PARAMETER(hrRelatedBundle); + } + } + +LExit: + ReleaseStr(sczRelatedBundleId); + ReleaseRegKey(hkUninstallKey); + + return hr; +} + static HRESULT LoadIfRelatedBundle( __in BOOL fPerMachine, + __in BOOL fWow6432, __in HKEY hkUninstallKey, __in_z LPCWSTR sczRelatedBundleId, __in BURN_REGISTRATION* pRegistration, @@ -198,7 +227,7 @@ static HRESULT LoadIfRelatedBundle( HKEY hkBundleId = NULL; BOOTSTRAPPER_RELATION_TYPE relationType = BOOTSTRAPPER_RELATION_NONE; - hr = RegOpen(hkUninstallKey, sczRelatedBundleId, KEY_READ, &hkBundleId); + hr = RegOpen(hkUninstallKey, sczRelatedBundleId, KEY_READ | (fWow6432 ? KEY_WOW64_32KEY : 0), &hkBundleId); ExitOnFailure(hr, "Failed to open uninstall key for potential related bundle: %ls", sczRelatedBundleId); hr = DetermineRelationType(hkBundleId, pRegistration, &relationType); diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2x64/BundleAv2x64.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2x64/BundleAv2x64.wixproj new file mode 100644 index 00000000..fb7d592b --- /dev/null +++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2x64/BundleAv2x64.wixproj @@ -0,0 +1,17 @@ + + + + + TestBA_x64 + X64 + 2.0.0.0 + + + + + + + + + + \ No newline at end of file diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2x64/BundleAv2x64.wxs b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2x64/BundleAv2x64.wxs new file mode 100644 index 00000000..5cbee5a8 --- /dev/null +++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2x64/BundleAv2x64.wxs @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs index 35cc64f0..a515ed69 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs @@ -32,5 +32,22 @@ namespace WixToolsetTest.BurnE2E Assert.True(LogVerifier.MessageInLogFileRegex(bundleAv2InstallLogFilePath, @"OnDetectRelatedBundle\(\) - id: \{[0-9A-Za-z\-]{36}\}, missing from cache: True")); Assert.True(LogVerifier.MessageInLogFileRegex(bundleAv2InstallLogFilePath, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Upgrade, scope: PerMachine, version: 1\.0\.0\.0, cached: No")); } + + [Fact] + public void Bundle64UpgradesBundle32() + { + var packageAv1 = this.CreatePackageInstaller("PackageAv1"); + var packageAv2 = this.CreatePackageInstaller("PackageAv2"); + var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); + var bundleAv2x64 = this.CreateBundleInstaller("BundleAv2x64"); + + bundleAv1.Install(); + bundleAv1.VerifyRegisteredAndInPackageCache(); + + bundleAv2x64.Install(); + bundleAv2x64.VerifyRegisteredAndInPackageCache(); + + bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); + } } } -- cgit v1.2.3-55-g6feb