diff options
| author | Bob Arnson <bob@firegiant.com> | 2022-01-15 21:40:54 -0500 |
|---|---|---|
| committer | Bob Arnson <github@bobs.org> | 2022-01-16 10:28:44 -0500 |
| commit | 47bca2dc51525fcad86f325278b14953ac5b137e (patch) | |
| tree | 80a153833efbe0794be7153c64e712a5799649c4 /src | |
| parent | 6d1c4cc83214b65032251c67239b02da59a3e635 (diff) | |
| download | wix-47bca2dc51525fcad86f325278b14953ac5b137e.tar.gz wix-47bca2dc51525fcad86f325278b14953ac5b137e.tar.bz2 wix-47bca2dc51525fcad86f325278b14953ac5b137e.zip | |
Fix 32/64-bit bitness handling in Burn and BUtil.
- Take advantage of RegOpenEx.
- Always look for related bundles in both 32 and 64 hives.
- BundleEnumRelatedBundle requires caller to specify bitness.
Diffstat (limited to 'src')
| -rw-r--r-- | src/burn/engine/elevation.cpp | 8 | ||||
| -rw-r--r-- | src/burn/engine/relatedbundle.cpp | 24 | ||||
| -rw-r--r-- | src/burn/engine/search.cpp | 16 | ||||
| -rw-r--r-- | src/burn/engine/variable.cpp | 2 | ||||
| -rw-r--r-- | src/burn/test/BurnUnitTest/RegistrationTest.cpp | 2 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/butil.cpp | 232 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/butil.h | 7 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/regutil.h | 9 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/monutil.cpp | 13 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/precomp.h | 2 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/regutil.cpp | 19 | ||||
| -rw-r--r-- | src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1x64/BundleAv1x64.wixproj | 16 | ||||
| -rw-r--r-- | src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1x64/BundleAv1x64.wxs | 10 | ||||
| -rw-r--r-- | src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs | 17 |
14 files changed, 180 insertions, 197 deletions
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 355b4a34..221d8b6d 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
| @@ -3299,7 +3299,6 @@ static HRESULT OnLaunchApprovedExe( | |||
| 3299 | SIZE_T iData = 0; | 3299 | SIZE_T iData = 0; |
| 3300 | BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL; | 3300 | BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL; |
| 3301 | BURN_APPROVED_EXE* pApprovedExe = NULL; | 3301 | BURN_APPROVED_EXE* pApprovedExe = NULL; |
| 3302 | REGSAM samDesired = KEY_QUERY_VALUE; | ||
| 3303 | HKEY hKey = NULL; | 3302 | HKEY hKey = NULL; |
| 3304 | DWORD dwProcessId = 0; | 3303 | DWORD dwProcessId = 0; |
| 3305 | BYTE* pbSendData = NULL; | 3304 | BYTE* pbSendData = NULL; |
| @@ -3323,12 +3322,7 @@ static HRESULT OnLaunchApprovedExe( | |||
| 3323 | 3322 | ||
| 3324 | LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_SEARCH, pApprovedExe->sczKey, pApprovedExe->sczValueName ? pApprovedExe->sczValueName : L"", pApprovedExe->fWin64 ? L"yes" : L"no"); | 3323 | LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_SEARCH, pApprovedExe->sczKey, pApprovedExe->sczValueName ? pApprovedExe->sczValueName : L"", pApprovedExe->fWin64 ? L"yes" : L"no"); |
| 3325 | 3324 | ||
| 3326 | if (pApprovedExe->fWin64) | 3325 | hr = RegOpenEx(HKEY_LOCAL_MACHINE, pApprovedExe->sczKey, KEY_QUERY_VALUE, pApprovedExe->fWin64 ? REG_KEY_64BIT : REG_KEY_32BIT, &hKey); |
| 3327 | { | ||
| 3328 | samDesired |= KEY_WOW64_64KEY; | ||
| 3329 | } | ||
| 3330 | |||
| 3331 | hr = RegOpen(HKEY_LOCAL_MACHINE, pApprovedExe->sczKey, samDesired, &hKey); | ||
| 3332 | ExitOnFailure(hr, "Failed to open the registry key for the approved exe path."); | 3326 | ExitOnFailure(hr, "Failed to open the registry key for the approved exe path."); |
| 3333 | 3327 | ||
| 3334 | hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath); | 3328 | hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath); |
diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index 99ed8553..619fa8dd 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp | |||
| @@ -11,13 +11,13 @@ static __callback int __cdecl CompareRelatedBundles( | |||
| 11 | ); | 11 | ); |
| 12 | static HRESULT InitializeForScopeAndBitness( | 12 | static HRESULT InitializeForScopeAndBitness( |
| 13 | __in BOOL fPerMachine, | 13 | __in BOOL fPerMachine, |
| 14 | __in BOOL fWow6432, | 14 | __in REG_KEY_BITNESS regBitness, |
| 15 | __in BURN_REGISTRATION* pRegistration, | 15 | __in BURN_REGISTRATION* pRegistration, |
| 16 | __in BURN_RELATED_BUNDLES* pRelatedBundles | 16 | __in BURN_RELATED_BUNDLES* pRelatedBundles |
| 17 | ); | 17 | ); |
| 18 | static HRESULT LoadIfRelatedBundle( | 18 | static HRESULT LoadIfRelatedBundle( |
| 19 | __in BOOL fPerMachine, | 19 | __in BOOL fPerMachine, |
| 20 | __in BOOL fWow6432, | 20 | __in REG_KEY_BITNESS regBitness, |
| 21 | __in HKEY hkUninstallKey, | 21 | __in HKEY hkUninstallKey, |
| 22 | __in_z LPCWSTR sczRelatedBundleId, | 22 | __in_z LPCWSTR sczRelatedBundleId, |
| 23 | __in BURN_REGISTRATION* pRegistration, | 23 | __in BURN_REGISTRATION* pRegistration, |
| @@ -47,13 +47,11 @@ extern "C" HRESULT RelatedBundlesInitializeForScope( | |||
| 47 | { | 47 | { |
| 48 | HRESULT hr = S_OK; | 48 | HRESULT hr = S_OK; |
| 49 | 49 | ||
| 50 | hr = InitializeForScopeAndBitness(fPerMachine, /*fWow6432*/FALSE, pRegistration, pRelatedBundles); | 50 | hr = InitializeForScopeAndBitness(fPerMachine, REG_KEY_32BIT, pRegistration, pRelatedBundles); |
| 51 | ExitOnFailure(hr, "Failed to open platform-native uninstall registry key."); | ||
| 52 | |||
| 53 | #if defined(_WIN64) | ||
| 54 | hr = InitializeForScopeAndBitness(fPerMachine, /*fWow6432*/TRUE, pRegistration, pRelatedBundles); | ||
| 55 | ExitOnFailure(hr, "Failed to open 32-bit uninstall registry key."); | 51 | ExitOnFailure(hr, "Failed to open 32-bit uninstall registry key."); |
| 56 | #endif | 52 | |
| 53 | hr = InitializeForScopeAndBitness(fPerMachine, REG_KEY_64BIT, pRegistration, pRelatedBundles); | ||
| 54 | ExitOnFailure(hr, "Failed to open 64-bit uninstall registry key."); | ||
| 57 | 55 | ||
| 58 | LExit: | 56 | LExit: |
| 59 | return hr; | 57 | return hr; |
| @@ -170,7 +168,7 @@ static __callback int __cdecl CompareRelatedBundles( | |||
| 170 | 168 | ||
| 171 | static HRESULT InitializeForScopeAndBitness( | 169 | static HRESULT InitializeForScopeAndBitness( |
| 172 | __in BOOL fPerMachine, | 170 | __in BOOL fPerMachine, |
| 173 | __in BOOL fWow6432, | 171 | __in REG_KEY_BITNESS regBitness, |
| 174 | __in BURN_REGISTRATION * pRegistration, | 172 | __in BURN_REGISTRATION * pRegistration, |
| 175 | __in BURN_RELATED_BUNDLES * pRelatedBundles | 173 | __in BURN_RELATED_BUNDLES * pRelatedBundles |
| 176 | ) | 174 | ) |
| @@ -180,7 +178,7 @@ static HRESULT InitializeForScopeAndBitness( | |||
| 180 | HKEY hkUninstallKey = NULL; | 178 | HKEY hkUninstallKey = NULL; |
| 181 | LPWSTR sczRelatedBundleId = NULL; | 179 | LPWSTR sczRelatedBundleId = NULL; |
| 182 | 180 | ||
| 183 | hr = RegOpen(hkRoot, BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ | (fWow6432 ? KEY_WOW64_32KEY : 0), &hkUninstallKey); | 181 | hr = RegOpenEx(hkRoot, BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ, regBitness, &hkUninstallKey); |
| 184 | if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) | 182 | if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) |
| 185 | { | 183 | { |
| 186 | ExitFunction1(hr = S_OK); | 184 | ExitFunction1(hr = S_OK); |
| @@ -202,7 +200,7 @@ static HRESULT InitializeForScopeAndBitness( | |||
| 202 | { | 200 | { |
| 203 | // Ignore failures here since we'll often find products that aren't actually | 201 | // Ignore failures here since we'll often find products that aren't actually |
| 204 | // related bundles (or even bundles at all). | 202 | // related bundles (or even bundles at all). |
| 205 | HRESULT hrRelatedBundle = LoadIfRelatedBundle(fPerMachine, fWow6432, hkUninstallKey, sczRelatedBundleId, pRegistration, pRelatedBundles); | 203 | HRESULT hrRelatedBundle = LoadIfRelatedBundle(fPerMachine, regBitness, hkUninstallKey, sczRelatedBundleId, pRegistration, pRelatedBundles); |
| 206 | UNREFERENCED_PARAMETER(hrRelatedBundle); | 204 | UNREFERENCED_PARAMETER(hrRelatedBundle); |
| 207 | } | 205 | } |
| 208 | } | 206 | } |
| @@ -216,7 +214,7 @@ LExit: | |||
| 216 | 214 | ||
| 217 | static HRESULT LoadIfRelatedBundle( | 215 | static HRESULT LoadIfRelatedBundle( |
| 218 | __in BOOL fPerMachine, | 216 | __in BOOL fPerMachine, |
| 219 | __in BOOL fWow6432, | 217 | __in REG_KEY_BITNESS regBitness, |
| 220 | __in HKEY hkUninstallKey, | 218 | __in HKEY hkUninstallKey, |
| 221 | __in_z LPCWSTR sczRelatedBundleId, | 219 | __in_z LPCWSTR sczRelatedBundleId, |
| 222 | __in BURN_REGISTRATION* pRegistration, | 220 | __in BURN_REGISTRATION* pRegistration, |
| @@ -227,7 +225,7 @@ static HRESULT LoadIfRelatedBundle( | |||
| 227 | HKEY hkBundleId = NULL; | 225 | HKEY hkBundleId = NULL; |
| 228 | BOOTSTRAPPER_RELATION_TYPE relationType = BOOTSTRAPPER_RELATION_NONE; | 226 | BOOTSTRAPPER_RELATION_TYPE relationType = BOOTSTRAPPER_RELATION_NONE; |
| 229 | 227 | ||
| 230 | hr = RegOpen(hkUninstallKey, sczRelatedBundleId, KEY_READ | (fWow6432 ? KEY_WOW64_32KEY : 0), &hkBundleId); | 228 | hr = RegOpenEx(hkUninstallKey, sczRelatedBundleId, KEY_READ, regBitness, &hkBundleId); |
| 231 | ExitOnFailure(hr, "Failed to open uninstall key for potential related bundle: %ls", sczRelatedBundleId); | 229 | ExitOnFailure(hr, "Failed to open uninstall key for potential related bundle: %ls", sczRelatedBundleId); |
| 232 | 230 | ||
| 233 | hr = DetermineRelationType(hkBundleId, pRegistration, &relationType); | 231 | hr = DetermineRelationType(hkBundleId, pRegistration, &relationType); |
diff --git a/src/burn/engine/search.cpp b/src/burn/engine/search.cpp index 6d5f8d49..4505e1a2 100644 --- a/src/burn/engine/search.cpp +++ b/src/burn/engine/search.cpp | |||
| @@ -836,19 +836,13 @@ static HRESULT RegistrySearchExists( | |||
| 836 | HKEY hKey = NULL; | 836 | HKEY hKey = NULL; |
| 837 | DWORD dwType = 0; | 837 | DWORD dwType = 0; |
| 838 | BOOL fExists = FALSE; | 838 | BOOL fExists = FALSE; |
| 839 | REGSAM samDesired = KEY_QUERY_VALUE; | ||
| 840 | |||
| 841 | if (pSearch->RegistrySearch.fWin64) | ||
| 842 | { | ||
| 843 | samDesired = samDesired | KEY_WOW64_64KEY; | ||
| 844 | } | ||
| 845 | 839 | ||
| 846 | // format key string | 840 | // format key string |
| 847 | hr = VariableFormatString(pVariables, pSearch->RegistrySearch.sczKey, &sczKey, NULL); | 841 | hr = VariableFormatString(pVariables, pSearch->RegistrySearch.sczKey, &sczKey, NULL); |
| 848 | ExitOnFailure(hr, "Failed to format key string."); | 842 | ExitOnFailure(hr, "Failed to format key string."); |
| 849 | 843 | ||
| 850 | // open key | 844 | // open key |
| 851 | hr = RegOpen(pSearch->RegistrySearch.hRoot, sczKey, samDesired, &hKey); | 845 | hr = RegOpenEx(pSearch->RegistrySearch.hRoot, sczKey, KEY_QUERY_VALUE, pSearch->RegistrySearch.fWin64 ? REG_KEY_64BIT : REG_KEY_32BIT, &hKey); |
| 852 | if (SUCCEEDED(hr)) | 846 | if (SUCCEEDED(hr)) |
| 853 | { | 847 | { |
| 854 | fExists = TRUE; | 848 | fExists = TRUE; |
| @@ -922,12 +916,6 @@ static HRESULT RegistrySearchValue( | |||
| 922 | LPBYTE pData = NULL; | 916 | LPBYTE pData = NULL; |
| 923 | DWORD cch = 0; | 917 | DWORD cch = 0; |
| 924 | BURN_VARIANT value = { }; | 918 | BURN_VARIANT value = { }; |
| 925 | REGSAM samDesired = KEY_QUERY_VALUE; | ||
| 926 | |||
| 927 | if (pSearch->RegistrySearch.fWin64) | ||
| 928 | { | ||
| 929 | samDesired = samDesired | KEY_WOW64_64KEY; | ||
| 930 | } | ||
| 931 | 919 | ||
| 932 | // format key string | 920 | // format key string |
| 933 | hr = VariableFormatString(pVariables, pSearch->RegistrySearch.sczKey, &sczKey, NULL); | 921 | hr = VariableFormatString(pVariables, pSearch->RegistrySearch.sczKey, &sczKey, NULL); |
| @@ -941,7 +929,7 @@ static HRESULT RegistrySearchValue( | |||
| 941 | } | 929 | } |
| 942 | 930 | ||
| 943 | // open key | 931 | // open key |
| 944 | hr = RegOpen(pSearch->RegistrySearch.hRoot, sczKey, samDesired, &hKey); | 932 | hr = RegOpenEx(pSearch->RegistrySearch.hRoot, sczKey, KEY_QUERY_VALUE, pSearch->RegistrySearch.fWin64 ? REG_KEY_64BIT : REG_KEY_32BIT, &hKey); |
| 945 | if (E_FILENOTFOUND == hr) | 933 | if (E_FILENOTFOUND == hr) |
| 946 | { | 934 | { |
| 947 | // What if there is a hidden variable in sczKey? | 935 | // What if there is a hidden variable in sczKey? |
diff --git a/src/burn/engine/variable.cpp b/src/burn/engine/variable.cpp index fa6190dd..b3dcdb7d 100644 --- a/src/burn/engine/variable.cpp +++ b/src/burn/engine/variable.cpp | |||
| @@ -2361,7 +2361,7 @@ static HRESULT Get64bitFolderFromRegistry( | |||
| 2361 | AssertSz(CSIDL_PROGRAM_FILES == nFolder || CSIDL_PROGRAM_FILES_COMMON == nFolder, "Unknown folder CSIDL."); | 2361 | AssertSz(CSIDL_PROGRAM_FILES == nFolder || CSIDL_PROGRAM_FILES_COMMON == nFolder, "Unknown folder CSIDL."); |
| 2362 | LPCWSTR wzFolderValue = CSIDL_PROGRAM_FILES_COMMON == nFolder ? L"CommonFilesDir" : L"ProgramFilesDir"; | 2362 | LPCWSTR wzFolderValue = CSIDL_PROGRAM_FILES_COMMON == nFolder ? L"CommonFilesDir" : L"ProgramFilesDir"; |
| 2363 | 2363 | ||
| 2364 | hr = RegOpen(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", KEY_READ | KEY_WOW64_64KEY, &hkFolders); | 2364 | hr = RegOpenEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", KEY_READ, REG_KEY_64BIT, &hkFolders); |
| 2365 | ExitOnFailure(hr, "Failed to open Windows folder key."); | 2365 | ExitOnFailure(hr, "Failed to open Windows folder key."); |
| 2366 | 2366 | ||
| 2367 | hr = RegReadString(hkFolders, wzFolderValue, psczPath); | 2367 | hr = RegReadString(hkFolders, wzFolderValue, psczPath); |
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp index dbcd2613..d2ec0a82 100644 --- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp +++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp | |||
| @@ -645,7 +645,7 @@ namespace Bootstrapper | |||
| 645 | NativeAssert::Succeeded(hr, "Failed to allocate buffer for related bundle id."); | 645 | NativeAssert::Succeeded(hr, "Failed to allocate buffer for related bundle id."); |
| 646 | 646 | ||
| 647 | // Verify we can find ourself via the UpgradeCode | 647 | // Verify we can find ourself via the UpgradeCode |
| 648 | hr = BundleEnumRelatedBundleFixed(TEST_BUNDLE_UPGRADE_CODE, BUNDLE_INSTALL_CONTEXT_USER, &dwRelatedBundleIndex, sczRelatedBundleId); | 648 | hr = BundleEnumRelatedBundleFixed(TEST_BUNDLE_UPGRADE_CODE, BUNDLE_INSTALL_CONTEXT_USER, REG_KEY_DEFAULT, &dwRelatedBundleIndex, sczRelatedBundleId); |
| 649 | TestThrowOnFailure(hr, L"Failed to enumerate related bundle."); | 649 | TestThrowOnFailure(hr, L"Failed to enumerate related bundle."); |
| 650 | 650 | ||
| 651 | NativeAssert::StringEqual(TEST_BUNDLE_ID, sczRelatedBundleId); | 651 | NativeAssert::StringEqual(TEST_BUNDLE_ID, sczRelatedBundleId); |
diff --git a/src/libs/dutil/WixToolset.DUtil/butil.cpp b/src/libs/dutil/WixToolset.DUtil/butil.cpp index 4262d573..2f45da56 100644 --- a/src/libs/dutil/WixToolset.DUtil/butil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/butil.cpp | |||
| @@ -63,13 +63,6 @@ static HRESULT CopyStringToBuffer( | |||
| 63 | __in_z_opt LPWSTR wzBuffer, | 63 | __in_z_opt LPWSTR wzBuffer, |
| 64 | __inout SIZE_T* pcchBuffer | 64 | __inout SIZE_T* pcchBuffer |
| 65 | ); | 65 | ); |
| 66 | static HRESULT DoBundleEnumRelatedBundle( | ||
| 67 | __in HKEY hkRoot, | ||
| 68 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 69 | __in_z LPCWSTR wzUpgradeCode, | ||
| 70 | __inout PDWORD pdwStartIndex, | ||
| 71 | __deref_out_z LPWSTR* psczBundleId | ||
| 72 | ); | ||
| 73 | 66 | ||
| 74 | 67 | ||
| 75 | DAPI_(HRESULT) BundleGetBundleInfo( | 68 | DAPI_(HRESULT) BundleGetBundleInfo( |
| @@ -156,11 +149,21 @@ LExit: | |||
| 156 | DAPI_(HRESULT) BundleEnumRelatedBundle( | 149 | DAPI_(HRESULT) BundleEnumRelatedBundle( |
| 157 | __in_z LPCWSTR wzUpgradeCode, | 150 | __in_z LPCWSTR wzUpgradeCode, |
| 158 | __in BUNDLE_INSTALL_CONTEXT context, | 151 | __in BUNDLE_INSTALL_CONTEXT context, |
| 152 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 159 | __inout PDWORD pdwStartIndex, | 153 | __inout PDWORD pdwStartIndex, |
| 160 | __deref_out_z LPWSTR* psczBundleId | 154 | __deref_out_z LPWSTR* psczBundleId |
| 161 | ) | 155 | ) |
| 162 | { | 156 | { |
| 163 | HRESULT hr = S_OK; | 157 | HRESULT hr = S_OK; |
| 158 | BOOL fUpgradeCodeFound = FALSE; | ||
| 159 | HKEY hkUninstall = NULL; | ||
| 160 | HKEY hkBundle = NULL; | ||
| 161 | LPWSTR sczUninstallSubKey = NULL; | ||
| 162 | LPWSTR sczUninstallSubKeyPath = NULL; | ||
| 163 | LPWSTR sczValue = NULL; | ||
| 164 | DWORD dwType = 0; | ||
| 165 | LPWSTR* rgsczBundleUpgradeCodes = NULL; | ||
| 166 | DWORD cBundleUpgradeCodes = 0; | ||
| 164 | HKEY hkRoot = BUNDLE_INSTALL_CONTEXT_USER == context ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 167 | HKEY hkRoot = BUNDLE_INSTALL_CONTEXT_USER == context ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
| 165 | 168 | ||
| 166 | if (!wzUpgradeCode || !pdwStartIndex) | 169 | if (!wzUpgradeCode || !pdwStartIndex) |
| @@ -168,27 +171,105 @@ DAPI_(HRESULT) BundleEnumRelatedBundle( | |||
| 168 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); | 171 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); |
| 169 | } | 172 | } |
| 170 | 173 | ||
| 171 | hr = DoBundleEnumRelatedBundle(hkRoot, REG_KEY_DEFAULT, wzUpgradeCode, pdwStartIndex, psczBundleId); | 174 | hr = RegOpenEx(hkRoot, BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ, kbKeyBitness, &hkUninstall); |
| 172 | ButilExitOnFailure(hr, "Failed to enumerate default-bitness bundles."); | 175 | ButilExitOnFailure(hr, "Failed to open bundle uninstall key path."); |
| 173 | if (S_FALSE == hr) | 176 | |
| 177 | for (DWORD dwIndex = *pdwStartIndex; !fUpgradeCodeFound; dwIndex++) | ||
| 174 | { | 178 | { |
| 175 | #if defined(_WIN64) | 179 | hr = RegKeyEnum(hkUninstall, dwIndex, &sczUninstallSubKey); |
| 176 | hr = DoBundleEnumRelatedBundle(hkRoot, REG_KEY_32BIT, wzUpgradeCode, pdwStartIndex, psczBundleId); | 180 | ButilExitOnFailure(hr, "Failed to enumerate bundle uninstall key path."); |
| 177 | ButilExitOnFailure(hr, "Failed to enumerate 32-bit bundles."); | 181 | |
| 178 | #else | 182 | hr = StrAllocFormatted(&sczUninstallSubKeyPath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, sczUninstallSubKey); |
| 179 | hr = DoBundleEnumRelatedBundle(hkRoot, REG_KEY_64BIT, wzUpgradeCode, pdwStartIndex, psczBundleId); | 183 | ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); |
| 180 | ButilExitOnFailure(hr, "Failed to enumerate 64-bit bundles."); | 184 | |
| 181 | #endif | 185 | hr = RegOpenEx(hkRoot, sczUninstallSubKeyPath, KEY_READ, kbKeyBitness, &hkBundle); |
| 186 | ButilExitOnFailure(hr, "Failed to open uninstall key path."); | ||
| 187 | |||
| 188 | // If it's a bundle, it should have a BundleUpgradeCode value of type REG_SZ (old) or REG_MULTI_SZ | ||
| 189 | hr = RegGetType(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &dwType); | ||
| 190 | if (FAILED(hr)) | ||
| 191 | { | ||
| 192 | ReleaseRegKey(hkBundle); | ||
| 193 | ReleaseNullStr(sczUninstallSubKey); | ||
| 194 | ReleaseNullStr(sczUninstallSubKeyPath); | ||
| 195 | // Not a bundle | ||
| 196 | continue; | ||
| 197 | } | ||
| 198 | |||
| 199 | switch (dwType) | ||
| 200 | { | ||
| 201 | case REG_SZ: | ||
| 202 | hr = RegReadString(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &sczValue); | ||
| 203 | ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode string property."); | ||
| 204 | |||
| 205 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, sczValue, -1, wzUpgradeCode, -1)) | ||
| 206 | { | ||
| 207 | *pdwStartIndex = dwIndex; | ||
| 208 | fUpgradeCodeFound = TRUE; | ||
| 209 | break; | ||
| 210 | } | ||
| 211 | |||
| 212 | ReleaseNullStr(sczValue); | ||
| 213 | |||
| 214 | break; | ||
| 215 | case REG_MULTI_SZ: | ||
| 216 | hr = RegReadStringArray(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &rgsczBundleUpgradeCodes, &cBundleUpgradeCodes); | ||
| 217 | ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode multi-string property."); | ||
| 218 | |||
| 219 | for (DWORD i = 0; i < cBundleUpgradeCodes; i++) | ||
| 220 | { | ||
| 221 | LPWSTR wzBundleUpgradeCode = rgsczBundleUpgradeCodes[i]; | ||
| 222 | if (wzBundleUpgradeCode && *wzBundleUpgradeCode) | ||
| 223 | { | ||
| 224 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzBundleUpgradeCode, -1, wzUpgradeCode, -1)) | ||
| 225 | { | ||
| 226 | *pdwStartIndex = dwIndex; | ||
| 227 | fUpgradeCodeFound = TRUE; | ||
| 228 | break; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | } | ||
| 232 | ReleaseNullStrArray(rgsczBundleUpgradeCodes, cBundleUpgradeCodes); | ||
| 233 | |||
| 234 | break; | ||
| 235 | |||
| 236 | default: | ||
| 237 | ButilExitWithRootFailure(hr, E_NOTIMPL, "BundleUpgradeCode of type 0x%x not implemented.", dwType); | ||
| 238 | } | ||
| 239 | |||
| 240 | if (fUpgradeCodeFound) | ||
| 241 | { | ||
| 242 | if (psczBundleId) | ||
| 243 | { | ||
| 244 | *psczBundleId = sczUninstallSubKey; | ||
| 245 | sczUninstallSubKey = NULL; | ||
| 246 | } | ||
| 247 | |||
| 248 | break; | ||
| 249 | } | ||
| 250 | |||
| 251 | // Cleanup before next iteration | ||
| 252 | ReleaseRegKey(hkBundle); | ||
| 253 | ReleaseNullStr(sczUninstallSubKey); | ||
| 254 | ReleaseNullStr(sczUninstallSubKeyPath); | ||
| 182 | } | 255 | } |
| 183 | 256 | ||
| 184 | LExit: | 257 | LExit: |
| 185 | return hr; | 258 | ReleaseStr(sczValue); |
| 259 | ReleaseStr(sczUninstallSubKey); | ||
| 260 | ReleaseStr(sczUninstallSubKeyPath); | ||
| 261 | ReleaseRegKey(hkBundle); | ||
| 262 | ReleaseRegKey(hkUninstall); | ||
| 263 | ReleaseStrArray(rgsczBundleUpgradeCodes, cBundleUpgradeCodes); | ||
| 264 | |||
| 265 | return FAILED(hr) ? hr : fUpgradeCodeFound ? S_OK : S_FALSE; | ||
| 186 | } | 266 | } |
| 187 | 267 | ||
| 188 | 268 | ||
| 189 | DAPI_(HRESULT) BundleEnumRelatedBundleFixed( | 269 | DAPI_(HRESULT) BundleEnumRelatedBundleFixed( |
| 190 | __in_z LPCWSTR wzUpgradeCode, | 270 | __in_z LPCWSTR wzUpgradeCode, |
| 191 | __in BUNDLE_INSTALL_CONTEXT context, | 271 | __in BUNDLE_INSTALL_CONTEXT context, |
| 272 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 192 | __inout PDWORD pdwStartIndex, | 273 | __inout PDWORD pdwStartIndex, |
| 193 | __out_ecount(MAX_GUID_CHARS+1) LPWSTR wzBundleId | 274 | __out_ecount(MAX_GUID_CHARS+1) LPWSTR wzBundleId |
| 194 | ) | 275 | ) |
| @@ -197,7 +278,7 @@ DAPI_(HRESULT) BundleEnumRelatedBundleFixed( | |||
| 197 | LPWSTR sczValue = NULL; | 278 | LPWSTR sczValue = NULL; |
| 198 | size_t cchValue = 0; | 279 | size_t cchValue = 0; |
| 199 | 280 | ||
| 200 | hr = BundleEnumRelatedBundle(wzUpgradeCode, context, pdwStartIndex, &sczValue); | 281 | hr = BundleEnumRelatedBundle(wzUpgradeCode, context, kbKeyBitness, pdwStartIndex, &sczValue); |
| 201 | if (S_OK == hr && wzBundleId) | 282 | if (S_OK == hr && wzBundleId) |
| 202 | { | 283 | { |
| 203 | hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchValue); | 284 | hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchValue); |
| @@ -396,116 +477,3 @@ static HRESULT CopyStringToBuffer( | |||
| 396 | 477 | ||
| 397 | return hr; | 478 | return hr; |
| 398 | } | 479 | } |
| 399 | |||
| 400 | static HRESULT DoBundleEnumRelatedBundle( | ||
| 401 | __in HKEY hkRoot, | ||
| 402 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 403 | __in_z LPCWSTR wzUpgradeCode, | ||
| 404 | __inout PDWORD pdwStartIndex, | ||
| 405 | __deref_out_z LPWSTR* psczBundleId | ||
| 406 | ) | ||
| 407 | { | ||
| 408 | HRESULT hr = S_OK; | ||
| 409 | BOOL fUpgradeCodeFound = FALSE; | ||
| 410 | HKEY hkUninstall = NULL; | ||
| 411 | HKEY hkBundle = NULL; | ||
| 412 | LPWSTR sczUninstallSubKey = NULL; | ||
| 413 | LPWSTR sczUninstallSubKeyPath = NULL; | ||
| 414 | LPWSTR sczValue = NULL; | ||
| 415 | DWORD dwType = 0; | ||
| 416 | LPWSTR* rgsczBundleUpgradeCodes = NULL; | ||
| 417 | DWORD cBundleUpgradeCodes = 0; | ||
| 418 | |||
| 419 | hr = RegOpenEx(hkRoot, BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ, kbKeyBitness, &hkUninstall); | ||
| 420 | ButilExitOnFailure(hr, "Failed to open bundle uninstall key path."); | ||
| 421 | |||
| 422 | for (DWORD dwIndex = *pdwStartIndex; !fUpgradeCodeFound; dwIndex++) | ||
| 423 | { | ||
| 424 | hr = RegKeyEnum(hkUninstall, dwIndex, &sczUninstallSubKey); | ||
| 425 | ButilExitOnFailure(hr, "Failed to enumerate bundle uninstall key path."); | ||
| 426 | |||
| 427 | hr = StrAllocFormatted(&sczUninstallSubKeyPath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, sczUninstallSubKey); | ||
| 428 | ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); | ||
| 429 | |||
| 430 | hr = RegOpenEx(hkRoot, sczUninstallSubKeyPath, KEY_READ, kbKeyBitness, &hkBundle); | ||
| 431 | ButilExitOnFailure(hr, "Failed to open uninstall key path."); | ||
| 432 | |||
| 433 | // If it's a bundle, it should have a BundleUpgradeCode value of type REG_SZ (old) or REG_MULTI_SZ | ||
| 434 | hr = RegGetType(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &dwType); | ||
| 435 | if (FAILED(hr)) | ||
| 436 | { | ||
| 437 | ReleaseRegKey(hkBundle); | ||
| 438 | ReleaseNullStr(sczUninstallSubKey); | ||
| 439 | ReleaseNullStr(sczUninstallSubKeyPath); | ||
| 440 | // Not a bundle | ||
| 441 | continue; | ||
| 442 | } | ||
| 443 | |||
| 444 | switch (dwType) | ||
| 445 | { | ||
| 446 | case REG_SZ: | ||
| 447 | hr = RegReadString(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &sczValue); | ||
| 448 | ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode string property."); | ||
| 449 | |||
| 450 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, sczValue, -1, wzUpgradeCode, -1)) | ||
| 451 | { | ||
| 452 | *pdwStartIndex = dwIndex; | ||
| 453 | fUpgradeCodeFound = TRUE; | ||
| 454 | break; | ||
| 455 | } | ||
| 456 | |||
| 457 | ReleaseNullStr(sczValue); | ||
| 458 | |||
| 459 | break; | ||
| 460 | case REG_MULTI_SZ: | ||
| 461 | hr = RegReadStringArray(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &rgsczBundleUpgradeCodes, &cBundleUpgradeCodes); | ||
| 462 | ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode multi-string property."); | ||
| 463 | |||
| 464 | for (DWORD i = 0; i < cBundleUpgradeCodes; i++) | ||
| 465 | { | ||
| 466 | LPWSTR wzBundleUpgradeCode = rgsczBundleUpgradeCodes[i]; | ||
| 467 | if (wzBundleUpgradeCode && *wzBundleUpgradeCode) | ||
| 468 | { | ||
| 469 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzBundleUpgradeCode, -1, wzUpgradeCode, -1)) | ||
| 470 | { | ||
| 471 | *pdwStartIndex = dwIndex; | ||
| 472 | fUpgradeCodeFound = TRUE; | ||
| 473 | break; | ||
| 474 | } | ||
| 475 | } | ||
| 476 | } | ||
| 477 | ReleaseNullStrArray(rgsczBundleUpgradeCodes, cBundleUpgradeCodes); | ||
| 478 | |||
| 479 | break; | ||
| 480 | |||
| 481 | default: | ||
| 482 | ButilExitWithRootFailure(hr, E_NOTIMPL, "BundleUpgradeCode of type 0x%x not implemented.", dwType); | ||
| 483 | } | ||
| 484 | |||
| 485 | if (fUpgradeCodeFound) | ||
| 486 | { | ||
| 487 | if (psczBundleId) | ||
| 488 | { | ||
| 489 | *psczBundleId = sczUninstallSubKey; | ||
| 490 | sczUninstallSubKey = NULL; | ||
| 491 | } | ||
| 492 | |||
| 493 | break; | ||
| 494 | } | ||
| 495 | |||
| 496 | // Cleanup before next iteration | ||
| 497 | ReleaseRegKey(hkBundle); | ||
| 498 | ReleaseNullStr(sczUninstallSubKey); | ||
| 499 | ReleaseNullStr(sczUninstallSubKeyPath); | ||
| 500 | } | ||
| 501 | |||
| 502 | LExit: | ||
| 503 | ReleaseStr(sczValue); | ||
| 504 | ReleaseStr(sczUninstallSubKey); | ||
| 505 | ReleaseStr(sczUninstallSubKeyPath); | ||
| 506 | ReleaseRegKey(hkBundle); | ||
| 507 | ReleaseRegKey(hkUninstall); | ||
| 508 | ReleaseStrArray(rgsczBundleUpgradeCodes, cBundleUpgradeCodes); | ||
| 509 | |||
| 510 | return FAILED(hr) ? hr : fUpgradeCodeFound ? S_OK : S_FALSE; | ||
| 511 | } | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/butil.h b/src/libs/dutil/WixToolset.DUtil/inc/butil.h index 3b316e66..9c2010ee 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/butil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/butil.h | |||
| @@ -60,7 +60,9 @@ HRESULT DAPI BundleGetBundleInfoFixed( | |||
| 60 | ); | 60 | ); |
| 61 | 61 | ||
| 62 | /******************************************************************** | 62 | /******************************************************************** |
| 63 | BundleEnumRelatedBundle - Queries the bundle installation metadata for installs with the given upgrade code | 63 | BundleEnumRelatedBundle - Queries the bundle installation metadata for installs with the given upgrade code. |
| 64 | Enumerate 32-bit and 64-bit in two passes. | ||
| 65 | |||
| 64 | RETURNS: | 66 | RETURNS: |
| 65 | E_INVALIDARG | 67 | E_INVALIDARG |
| 66 | An invalid parameter was passed to the function. | 68 | An invalid parameter was passed to the function. |
| @@ -74,12 +76,14 @@ RETURNS: | |||
| 74 | HRESULT DAPI BundleEnumRelatedBundle( | 76 | HRESULT DAPI BundleEnumRelatedBundle( |
| 75 | __in_z LPCWSTR wzUpgradeCode, | 77 | __in_z LPCWSTR wzUpgradeCode, |
| 76 | __in BUNDLE_INSTALL_CONTEXT context, | 78 | __in BUNDLE_INSTALL_CONTEXT context, |
| 79 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 77 | __inout PDWORD pdwStartIndex, | 80 | __inout PDWORD pdwStartIndex, |
| 78 | __deref_out_z LPWSTR* psczBundleId | 81 | __deref_out_z LPWSTR* psczBundleId |
| 79 | ); | 82 | ); |
| 80 | 83 | ||
| 81 | /******************************************************************** | 84 | /******************************************************************** |
| 82 | BundleEnumRelatedBundleFixed - Queries the bundle installation metadata for installs with the given upgrade code | 85 | BundleEnumRelatedBundleFixed - Queries the bundle installation metadata for installs with the given upgrade code |
| 86 | Enumerate 32-bit and 64-bit in two passes. | ||
| 83 | 87 | ||
| 84 | NOTE: lpBundleIdBuff is a buffer to receive the bundle GUID. This buffer must be 39 characters long. | 88 | NOTE: lpBundleIdBuff is a buffer to receive the bundle GUID. This buffer must be 39 characters long. |
| 85 | The first 38 characters are for the GUID, and the last character is for the terminating null character. | 89 | The first 38 characters are for the GUID, and the last character is for the terminating null character. |
| @@ -96,6 +100,7 @@ RETURNS: | |||
| 96 | HRESULT DAPI BundleEnumRelatedBundleFixed( | 100 | HRESULT DAPI BundleEnumRelatedBundleFixed( |
| 97 | __in_z LPCWSTR wzUpgradeCode, | 101 | __in_z LPCWSTR wzUpgradeCode, |
| 98 | __in BUNDLE_INSTALL_CONTEXT context, | 102 | __in BUNDLE_INSTALL_CONTEXT context, |
| 103 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 99 | __inout PDWORD pdwStartIndex, | 104 | __inout PDWORD pdwStartIndex, |
| 100 | __out_ecount(MAX_GUID_CHARS+1) LPWSTR wzBundleId | 105 | __out_ecount(MAX_GUID_CHARS+1) LPWSTR wzBundleId |
| 101 | ); | 106 | ); |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h index db8e0c5c..3cbb53b0 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h | |||
| @@ -408,6 +408,15 @@ BOOL DAPI RegValueExists( | |||
| 408 | __in REG_KEY_BITNESS kbKeyBitness | 408 | __in REG_KEY_BITNESS kbKeyBitness |
| 409 | ); | 409 | ); |
| 410 | 410 | ||
| 411 | /******************************************************************** | ||
| 412 | RegTranslateKeyBitness - Converts from REG_KEY_BITNESS values to | ||
| 413 | REGSAM-compatible values. | ||
| 414 | |||
| 415 | *********************************************************************/ | ||
| 416 | REGSAM DAPI RegTranslateKeyBitness( | ||
| 417 | __in REG_KEY_BITNESS kbKeyBitness | ||
| 418 | ); | ||
| 419 | |||
| 411 | #ifdef __cplusplus | 420 | #ifdef __cplusplus |
| 412 | } | 421 | } |
| 413 | #endif | 422 | #endif |
diff --git a/src/libs/dutil/WixToolset.DUtil/monutil.cpp b/src/libs/dutil/WixToolset.DUtil/monutil.cpp index 6a7f0596..6ad75b56 100644 --- a/src/libs/dutil/WixToolset.DUtil/monutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/monutil.cpp | |||
| @@ -1677,18 +1677,7 @@ static REGSAM GetRegKeyBitness( | |||
| 1677 | __in MON_REQUEST *pRequest | 1677 | __in MON_REQUEST *pRequest |
| 1678 | ) | 1678 | ) |
| 1679 | { | 1679 | { |
| 1680 | if (REG_KEY_32BIT == pRequest->regkey.kbKeyBitness) | 1680 | return RegTranslateKeyBitness(pRequest->regkey.kbKeyBitness); |
| 1681 | { | ||
| 1682 | return KEY_WOW64_32KEY; | ||
| 1683 | } | ||
| 1684 | else if (REG_KEY_64BIT == pRequest->regkey.kbKeyBitness) | ||
| 1685 | { | ||
| 1686 | return KEY_WOW64_64KEY; | ||
| 1687 | } | ||
| 1688 | else | ||
| 1689 | { | ||
| 1690 | return 0; | ||
| 1691 | } | ||
| 1692 | } | 1681 | } |
| 1693 | 1682 | ||
| 1694 | static HRESULT DuplicateRemoveMessage( | 1683 | static HRESULT DuplicateRemoveMessage( |
diff --git a/src/libs/dutil/WixToolset.DUtil/precomp.h b/src/libs/dutil/WixToolset.DUtil/precomp.h index 093c16a2..902fe3e3 100644 --- a/src/libs/dutil/WixToolset.DUtil/precomp.h +++ b/src/libs/dutil/WixToolset.DUtil/precomp.h | |||
| @@ -48,7 +48,6 @@ | |||
| 48 | #include "apputil.h" | 48 | #include "apputil.h" |
| 49 | #include "atomutil.h" | 49 | #include "atomutil.h" |
| 50 | #include "buffutil.h" | 50 | #include "buffutil.h" |
| 51 | #include "butil.h" | ||
| 52 | #include "cabcutil.h" | 51 | #include "cabcutil.h" |
| 53 | #include "cabutil.h" | 52 | #include "cabutil.h" |
| 54 | #include "conutil.h" | 53 | #include "conutil.h" |
| @@ -76,6 +75,7 @@ | |||
| 76 | #include "polcutil.h" | 75 | #include "polcutil.h" |
| 77 | #include "procutil.h" | 76 | #include "procutil.h" |
| 78 | #include "regutil.h" | 77 | #include "regutil.h" |
| 78 | #include "butil.h" // NOTE: Butil must come after Regutil. | ||
| 79 | #include "resrutil.h" | 79 | #include "resrutil.h" |
| 80 | #include "reswutil.h" | 80 | #include "reswutil.h" |
| 81 | #include "rmutil.h" | 81 | #include "rmutil.h" |
diff --git a/src/libs/dutil/WixToolset.DUtil/regutil.cpp b/src/libs/dutil/WixToolset.DUtil/regutil.cpp index f4719466..219a6c11 100644 --- a/src/libs/dutil/WixToolset.DUtil/regutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/regutil.cpp | |||
| @@ -32,9 +32,6 @@ static PFN_REGDELETEVALUEW vpfnRegDeleteValueW = ::RegDeleteValueW; | |||
| 32 | static HMODULE vhAdvApi32Dll = NULL; | 32 | static HMODULE vhAdvApi32Dll = NULL; |
| 33 | static BOOL vfRegInitialized = FALSE; | 33 | static BOOL vfRegInitialized = FALSE; |
| 34 | 34 | ||
| 35 | static REGSAM TranslateKeyBitness( | ||
| 36 | __in REG_KEY_BITNESS kbKeyBitness | ||
| 37 | ); | ||
| 38 | static HRESULT WriteStringToRegistry( | 35 | static HRESULT WriteStringToRegistry( |
| 39 | __in HKEY hk, | 36 | __in HKEY hk, |
| 40 | __in_z_opt LPCWSTR wzName, | 37 | __in_z_opt LPCWSTR wzName, |
| @@ -135,7 +132,7 @@ DAPI_(HRESULT) RegCreateEx( | |||
| 135 | DWORD er = ERROR_SUCCESS; | 132 | DWORD er = ERROR_SUCCESS; |
| 136 | DWORD dwDisposition; | 133 | DWORD dwDisposition; |
| 137 | 134 | ||
| 138 | REGSAM samDesired = TranslateKeyBitness(kbKeyBitness); | 135 | REGSAM samDesired = RegTranslateKeyBitness(kbKeyBitness); |
| 139 | er = vpfnRegCreateKeyExW(hkRoot, wzSubKey, 0, NULL, fVolatile ? REG_OPTION_VOLATILE : REG_OPTION_NON_VOLATILE, dwAccess | samDesired, pSecurityAttributes, phk, &dwDisposition); | 136 | er = vpfnRegCreateKeyExW(hkRoot, wzSubKey, 0, NULL, fVolatile ? REG_OPTION_VOLATILE : REG_OPTION_NON_VOLATILE, dwAccess | samDesired, pSecurityAttributes, phk, &dwDisposition); |
| 140 | RegExitOnWin32Error(er, hr, "Failed to create registry key."); | 137 | RegExitOnWin32Error(er, hr, "Failed to create registry key."); |
| 141 | 138 | ||
| @@ -171,7 +168,7 @@ DAPI_(HRESULT) RegOpenEx( | |||
| 171 | HRESULT hr = S_OK; | 168 | HRESULT hr = S_OK; |
| 172 | DWORD er = ERROR_SUCCESS; | 169 | DWORD er = ERROR_SUCCESS; |
| 173 | 170 | ||
| 174 | REGSAM samDesired = TranslateKeyBitness(kbKeyBitness); | 171 | REGSAM samDesired = RegTranslateKeyBitness(kbKeyBitness); |
| 175 | er = vpfnRegOpenKeyExW(hkRoot, wzSubKey, 0, dwAccess | samDesired, phk); | 172 | er = vpfnRegOpenKeyExW(hkRoot, wzSubKey, 0, dwAccess | samDesired, phk); |
| 176 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) | 173 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) |
| 177 | { | 174 | { |
| @@ -229,7 +226,7 @@ DAPI_(HRESULT) RegDelete( | |||
| 229 | 226 | ||
| 230 | if (NULL != vpfnRegDeleteKeyExW) | 227 | if (NULL != vpfnRegDeleteKeyExW) |
| 231 | { | 228 | { |
| 232 | REGSAM samDesired = TranslateKeyBitness(kbKeyBitness); | 229 | REGSAM samDesired = RegTranslateKeyBitness(kbKeyBitness); |
| 233 | er = vpfnRegDeleteKeyExW(hkRoot, wzSubKey, samDesired, 0); | 230 | er = vpfnRegDeleteKeyExW(hkRoot, wzSubKey, samDesired, 0); |
| 234 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) | 231 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) |
| 235 | { | 232 | { |
| @@ -912,11 +909,6 @@ LExit: | |||
| 912 | return hr; | 909 | return hr; |
| 913 | } | 910 | } |
| 914 | 911 | ||
| 915 | /******************************************************************** | ||
| 916 | RegValueExists - determines whether a named value exists in a | ||
| 917 | specified subkey. | ||
| 918 | |||
| 919 | *********************************************************************/ | ||
| 920 | DAPI_(BOOL) RegValueExists( | 912 | DAPI_(BOOL) RegValueExists( |
| 921 | __in HKEY hk, | 913 | __in HKEY hk, |
| 922 | __in_z LPCWSTR wzSubKey, | 914 | __in_z LPCWSTR wzSubKey, |
| @@ -940,7 +932,7 @@ LExit: | |||
| 940 | return SUCCEEDED(hr); | 932 | return SUCCEEDED(hr); |
| 941 | } | 933 | } |
| 942 | 934 | ||
| 943 | static REGSAM TranslateKeyBitness( | 935 | DAPI_(REGSAM) RegTranslateKeyBitness( |
| 944 | __in REG_KEY_BITNESS kbKeyBitness | 936 | __in REG_KEY_BITNESS kbKeyBitness |
| 945 | ) | 937 | ) |
| 946 | { | 938 | { |
| @@ -948,14 +940,11 @@ static REGSAM TranslateKeyBitness( | |||
| 948 | { | 940 | { |
| 949 | case REG_KEY_32BIT: | 941 | case REG_KEY_32BIT: |
| 950 | return KEY_WOW64_32KEY; | 942 | return KEY_WOW64_32KEY; |
| 951 | break; | ||
| 952 | case REG_KEY_64BIT: | 943 | case REG_KEY_64BIT: |
| 953 | return KEY_WOW64_64KEY; | 944 | return KEY_WOW64_64KEY; |
| 954 | break; | ||
| 955 | case REG_KEY_DEFAULT: | 945 | case REG_KEY_DEFAULT: |
| 956 | default: | 946 | default: |
| 957 | return 0; | 947 | return 0; |
| 958 | break; | ||
| 959 | } | 948 | } |
| 960 | } | 949 | } |
| 961 | 950 | ||
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1x64/BundleAv1x64.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1x64/BundleAv1x64.wixproj new file mode 100644 index 00000000..44bf9772 --- /dev/null +++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1x64/BundleAv1x64.wixproj | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | <Project Sdk="WixToolset.Sdk"> | ||
| 3 | <Import Project="..\BundleAv1\BundleA.props" /> | ||
| 4 | <PropertyGroup> | ||
| 5 | <BA>TestBA_x64</BA> | ||
| 6 | <InstallerPlatform>X64</InstallerPlatform> | ||
| 7 | </PropertyGroup> | ||
| 8 | <ItemGroup> | ||
| 9 | <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" /> | ||
| 10 | <ProjectReference Include="..\..\TestBA\TestBAWixlib_x64\testbawixlib_x64.wixproj" /> | ||
| 11 | </ItemGroup> | ||
| 12 | <ItemGroup> | ||
| 13 | <PackageReference Include="WixToolset.Bal.wixext" /> | ||
| 14 | <PackageReference Include="WixToolset.NetFx.wixext" /> | ||
| 15 | </ItemGroup> | ||
| 16 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1x64/BundleAv1x64.wxs b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1x64/BundleAv1x64.wxs new file mode 100644 index 00000000..7bf16212 --- /dev/null +++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1x64/BundleAv1x64.wxs | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | |||
| 3 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
| 5 | <Fragment> | ||
| 6 | <PackageGroup Id="BundlePackages"> | ||
| 7 | <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" /> | ||
| 8 | </PackageGroup> | ||
| 9 | </Fragment> | ||
| 10 | </Wix> | ||
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs index a515ed69..6d81252e 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs | |||
| @@ -49,5 +49,22 @@ namespace WixToolsetTest.BurnE2E | |||
| 49 | 49 | ||
| 50 | bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); | 50 | bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); |
| 51 | } | 51 | } |
| 52 | |||
| 53 | [Fact] | ||
| 54 | public void Bundle32UpgradesBundle64() | ||
| 55 | { | ||
| 56 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); | ||
| 57 | var packageAv2 = this.CreatePackageInstaller("PackageAv2"); | ||
| 58 | var bundleAv1x64 = this.CreateBundleInstaller("BundleAv1x64"); | ||
| 59 | var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); | ||
| 60 | |||
| 61 | bundleAv1x64.Install(); | ||
| 62 | bundleAv1x64.VerifyRegisteredAndInPackageCache(); | ||
| 63 | |||
| 64 | bundleAv2.Install(); | ||
| 65 | bundleAv2.VerifyRegisteredAndInPackageCache(); | ||
| 66 | |||
| 67 | bundleAv1x64.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
| 68 | } | ||
| 52 | } | 69 | } |
| 53 | } | 70 | } |
