diff options
| author | Bob Arnson <bob@firegiant.com> | 2022-01-09 23:23:51 -0500 |
|---|---|---|
| committer | Bob Arnson <github@bobs.org> | 2022-01-10 00:47:18 -0500 |
| commit | a96db4a508f1d1774500ab89f2c57e581fb5a13a (patch) | |
| tree | 40de5d2904e564e28c04c5816fd7528f8f090e2c /src | |
| parent | bae756f4354fed4de6097c931590ccafc907fdb2 (diff) | |
| download | wix-a96db4a508f1d1774500ab89f2c57e581fb5a13a.tar.gz wix-a96db4a508f1d1774500ab89f2c57e581fb5a13a.tar.bz2 wix-a96db4a508f1d1774500ab89f2c57e581fb5a13a.zip | |
Add registry bitness to RegUtil and BUtil.
Fixes https://github.com/wixtoolset/issues/issues/6669.
Fixes https://github.com/wixtoolset/issues/issues/6670.
Diffstat (limited to 'src')
| -rw-r--r-- | src/burn/engine/registration.cpp | 16 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/butil.cpp | 239 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/deputil.cpp | 6 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/butil.h | 8 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/regutil.h | 19 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/regutil.cpp | 69 |
6 files changed, 219 insertions, 138 deletions
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index ffeb39d1..a5b061eb 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp | |||
| @@ -1742,38 +1742,38 @@ static BOOL IsRegistryRebootPending() | |||
| 1742 | HKEY hk = NULL; | 1742 | HKEY hk = NULL; |
| 1743 | BOOL fRebootPending = FALSE; | 1743 | BOOL fRebootPending = FALSE; |
| 1744 | 1744 | ||
| 1745 | hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\ServerManager", L"CurrentRebootAttempts", TRUE, &dwValue); | 1745 | hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\ServerManager", L"CurrentRebootAttempts", REG_KEY_DEFAULT, &dwValue); |
| 1746 | fRebootPending = SUCCEEDED(hr) && 0 < dwValue; | 1746 | fRebootPending = SUCCEEDED(hr) && 0 < dwValue; |
| 1747 | 1747 | ||
| 1748 | if (!fRebootPending) | 1748 | if (!fRebootPending) |
| 1749 | { | 1749 | { |
| 1750 | hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Updates", L"UpdateExeVolatile", TRUE, &dwValue); | 1750 | hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Updates", L"UpdateExeVolatile", REG_KEY_DEFAULT, &dwValue); |
| 1751 | fRebootPending = SUCCEEDED(hr) && 0 < dwValue; | 1751 | fRebootPending = SUCCEEDED(hr) && 0 < dwValue; |
| 1752 | 1752 | ||
| 1753 | if (!fRebootPending) | 1753 | if (!fRebootPending) |
| 1754 | { | 1754 | { |
| 1755 | fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending", NULL, TRUE); | 1755 | fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending", NULL, REG_KEY_DEFAULT); |
| 1756 | 1756 | ||
| 1757 | if (!fRebootPending) | 1757 | if (!fRebootPending) |
| 1758 | { | 1758 | { |
| 1759 | fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootInProgress", NULL, TRUE); | 1759 | fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootInProgress", NULL, REG_KEY_DEFAULT); |
| 1760 | 1760 | ||
| 1761 | if (!fRebootPending) | 1761 | if (!fRebootPending) |
| 1762 | { | 1762 | { |
| 1763 | hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update", L"AUState", TRUE, &dwValue); | 1763 | hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update", L"AUState", REG_KEY_DEFAULT, &dwValue); |
| 1764 | fRebootPending = SUCCEEDED(hr) && 8 == dwValue; | 1764 | fRebootPending = SUCCEEDED(hr) && 8 == dwValue; |
| 1765 | 1765 | ||
| 1766 | if (!fRebootPending) | 1766 | if (!fRebootPending) |
| 1767 | { | 1767 | { |
| 1768 | fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager", L"PendingFileRenameOperations", TRUE); | 1768 | fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager", L"PendingFileRenameOperations", REG_KEY_DEFAULT); |
| 1769 | 1769 | ||
| 1770 | if (!fRebootPending) | 1770 | if (!fRebootPending) |
| 1771 | { | 1771 | { |
| 1772 | fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager", L"PendingFileRenameOperations2", TRUE); | 1772 | fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager", L"PendingFileRenameOperations2", REG_KEY_DEFAULT); |
| 1773 | 1773 | ||
| 1774 | if (!fRebootPending) | 1774 | if (!fRebootPending) |
| 1775 | { | 1775 | { |
| 1776 | hr = RegOpen(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\FileRenameOperations", KEY_READ | KEY_WOW64_64KEY, &hk); | 1776 | hr = RegOpenEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\FileRenameOperations", KEY_READ, REG_KEY_DEFAULT, &hk); |
| 1777 | if (SUCCEEDED(hr)) | 1777 | if (SUCCEEDED(hr)) |
| 1778 | { | 1778 | { |
| 1779 | DWORD cSubKeys = 0; | 1779 | DWORD cSubKeys = 0; |
diff --git a/src/libs/dutil/WixToolset.DUtil/butil.cpp b/src/libs/dutil/WixToolset.DUtil/butil.cpp index 4c96dfc1..4262d573 100644 --- a/src/libs/dutil/WixToolset.DUtil/butil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/butil.cpp | |||
| @@ -55,6 +55,7 @@ static HRESULT OpenBundleKey( | |||
| 55 | __in_z LPCWSTR wzBundleId, | 55 | __in_z LPCWSTR wzBundleId, |
| 56 | __in BUNDLE_INSTALL_CONTEXT context, | 56 | __in BUNDLE_INSTALL_CONTEXT context, |
| 57 | __in_opt LPCWSTR wzSubKey, | 57 | __in_opt LPCWSTR wzSubKey, |
| 58 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 58 | __inout HKEY* phKey | 59 | __inout HKEY* phKey |
| 59 | ); | 60 | ); |
| 60 | static HRESULT CopyStringToBuffer( | 61 | static HRESULT CopyStringToBuffer( |
| @@ -62,6 +63,14 @@ static HRESULT CopyStringToBuffer( | |||
| 62 | __in_z_opt LPWSTR wzBuffer, | 63 | __in_z_opt LPWSTR wzBuffer, |
| 63 | __inout SIZE_T* pcchBuffer | 64 | __inout SIZE_T* pcchBuffer |
| 64 | ); | 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 | |||
| 65 | 74 | ||
| 66 | DAPI_(HRESULT) BundleGetBundleInfo( | 75 | DAPI_(HRESULT) BundleGetBundleInfo( |
| 67 | __in_z LPCWSTR wzBundleId, | 76 | __in_z LPCWSTR wzBundleId, |
| @@ -153,113 +162,26 @@ DAPI_(HRESULT) BundleEnumRelatedBundle( | |||
| 153 | { | 162 | { |
| 154 | HRESULT hr = S_OK; | 163 | HRESULT hr = S_OK; |
| 155 | HKEY hkRoot = BUNDLE_INSTALL_CONTEXT_USER == context ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 164 | HKEY hkRoot = BUNDLE_INSTALL_CONTEXT_USER == context ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
| 156 | HKEY hkUninstall = NULL; | ||
| 157 | HKEY hkBundle = NULL; | ||
| 158 | LPWSTR sczUninstallSubKey = NULL; | ||
| 159 | LPWSTR sczUninstallSubKeyPath = NULL; | ||
| 160 | LPWSTR sczValue = NULL; | ||
| 161 | DWORD dwType = 0; | ||
| 162 | |||
| 163 | LPWSTR* rgsczBundleUpgradeCodes = NULL; | ||
| 164 | DWORD cBundleUpgradeCodes = 0; | ||
| 165 | BOOL fUpgradeCodeFound = FALSE; | ||
| 166 | 165 | ||
| 167 | if (!wzUpgradeCode || !pdwStartIndex) | 166 | if (!wzUpgradeCode || !pdwStartIndex) |
| 168 | { | 167 | { |
| 169 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); | 168 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); |
| 170 | } | 169 | } |
| 171 | 170 | ||
| 172 | hr = RegOpen(hkRoot, BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ, &hkUninstall); | 171 | hr = DoBundleEnumRelatedBundle(hkRoot, REG_KEY_DEFAULT, wzUpgradeCode, pdwStartIndex, psczBundleId); |
| 173 | ButilExitOnFailure(hr, "Failed to open bundle uninstall key path."); | 172 | ButilExitOnFailure(hr, "Failed to enumerate default-bitness bundles."); |
| 174 | 173 | if (S_FALSE == hr) | |
| 175 | for (DWORD dwIndex = *pdwStartIndex; !fUpgradeCodeFound; dwIndex++) | ||
| 176 | { | 174 | { |
| 177 | hr = RegKeyEnum(hkUninstall, dwIndex, &sczUninstallSubKey); | 175 | #if defined(_WIN64) |
| 178 | ButilExitOnFailure(hr, "Failed to enumerate bundle uninstall key path."); | 176 | hr = DoBundleEnumRelatedBundle(hkRoot, REG_KEY_32BIT, wzUpgradeCode, pdwStartIndex, psczBundleId); |
| 179 | 177 | ButilExitOnFailure(hr, "Failed to enumerate 32-bit bundles."); | |
| 180 | hr = StrAllocFormatted(&sczUninstallSubKeyPath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, sczUninstallSubKey); | 178 | #else |
| 181 | ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); | 179 | hr = DoBundleEnumRelatedBundle(hkRoot, REG_KEY_64BIT, wzUpgradeCode, pdwStartIndex, psczBundleId); |
| 182 | 180 | ButilExitOnFailure(hr, "Failed to enumerate 64-bit bundles."); | |
| 183 | hr = RegOpen(hkRoot, sczUninstallSubKeyPath, KEY_READ, &hkBundle); | 181 | #endif |
| 184 | ButilExitOnFailure(hr, "Failed to open uninstall key path."); | ||
| 185 | |||
| 186 | // If it's a bundle, it should have a BundleUpgradeCode value of type REG_SZ (old) or REG_MULTI_SZ | ||
| 187 | hr = RegGetType(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &dwType); | ||
| 188 | if (FAILED(hr)) | ||
| 189 | { | ||
| 190 | ReleaseRegKey(hkBundle); | ||
| 191 | ReleaseNullStr(sczUninstallSubKey); | ||
| 192 | ReleaseNullStr(sczUninstallSubKeyPath); | ||
| 193 | // Not a bundle | ||
| 194 | continue; | ||
| 195 | } | ||
| 196 | |||
| 197 | switch (dwType) | ||
| 198 | { | ||
| 199 | case REG_SZ: | ||
| 200 | hr = RegReadString(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &sczValue); | ||
| 201 | ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode string property."); | ||
| 202 | |||
| 203 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, sczValue, -1, wzUpgradeCode, -1)) | ||
| 204 | { | ||
| 205 | *pdwStartIndex = dwIndex; | ||
| 206 | fUpgradeCodeFound = TRUE; | ||
| 207 | break; | ||
| 208 | } | ||
| 209 | |||
| 210 | ReleaseNullStr(sczValue); | ||
| 211 | |||
| 212 | break; | ||
| 213 | case REG_MULTI_SZ: | ||
| 214 | hr = RegReadStringArray(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &rgsczBundleUpgradeCodes, &cBundleUpgradeCodes); | ||
| 215 | ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode multi-string property."); | ||
| 216 | |||
| 217 | for (DWORD i = 0; i < cBundleUpgradeCodes; i++) | ||
| 218 | { | ||
| 219 | LPWSTR wzBundleUpgradeCode = rgsczBundleUpgradeCodes[i]; | ||
| 220 | if (wzBundleUpgradeCode && *wzBundleUpgradeCode) | ||
| 221 | { | ||
| 222 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzBundleUpgradeCode, -1, wzUpgradeCode, -1)) | ||
| 223 | { | ||
| 224 | *pdwStartIndex = dwIndex; | ||
| 225 | fUpgradeCodeFound = TRUE; | ||
| 226 | break; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | } | ||
| 230 | ReleaseNullStrArray(rgsczBundleUpgradeCodes, cBundleUpgradeCodes); | ||
| 231 | |||
| 232 | break; | ||
| 233 | |||
| 234 | default: | ||
| 235 | ButilExitWithRootFailure(hr, E_NOTIMPL, "BundleUpgradeCode of type 0x%x not implemented.", dwType); | ||
| 236 | } | ||
| 237 | |||
| 238 | if (fUpgradeCodeFound) | ||
| 239 | { | ||
| 240 | if (psczBundleId) | ||
| 241 | { | ||
| 242 | *psczBundleId = sczUninstallSubKey; | ||
| 243 | sczUninstallSubKey = NULL; | ||
| 244 | } | ||
| 245 | |||
| 246 | break; | ||
| 247 | } | ||
| 248 | |||
| 249 | // Cleanup before next iteration | ||
| 250 | ReleaseRegKey(hkBundle); | ||
| 251 | ReleaseNullStr(sczUninstallSubKey); | ||
| 252 | ReleaseNullStr(sczUninstallSubKeyPath); | ||
| 253 | } | 182 | } |
| 254 | 183 | ||
| 255 | LExit: | 184 | LExit: |
| 256 | ReleaseStr(sczValue); | ||
| 257 | ReleaseStr(sczUninstallSubKey); | ||
| 258 | ReleaseStr(sczUninstallSubKeyPath); | ||
| 259 | ReleaseRegKey(hkBundle); | ||
| 260 | ReleaseRegKey(hkUninstall); | ||
| 261 | ReleaseStrArray(rgsczBundleUpgradeCodes, cBundleUpgradeCodes); | ||
| 262 | |||
| 263 | return hr; | 185 | return hr; |
| 264 | } | 186 | } |
| 265 | 187 | ||
| @@ -276,7 +198,7 @@ DAPI_(HRESULT) BundleEnumRelatedBundleFixed( | |||
| 276 | size_t cchValue = 0; | 198 | size_t cchValue = 0; |
| 277 | 199 | ||
| 278 | hr = BundleEnumRelatedBundle(wzUpgradeCode, context, pdwStartIndex, &sczValue); | 200 | hr = BundleEnumRelatedBundle(wzUpgradeCode, context, pdwStartIndex, &sczValue); |
| 279 | if (SUCCEEDED(hr) && wzBundleId) | 201 | if (S_OK == hr && wzBundleId) |
| 280 | { | 202 | { |
| 281 | hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchValue); | 203 | hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchValue); |
| 282 | ButilExitOnRootFailure(hr, "Failed to calculate length of string."); | 204 | ButilExitOnRootFailure(hr, "Failed to calculate length of string."); |
| @@ -380,8 +302,9 @@ static HRESULT LocateAndQueryBundleValue( | |||
| 380 | 302 | ||
| 381 | *pStatus = INTERNAL_BUNDLE_STATUS_SUCCESS; | 303 | *pStatus = INTERNAL_BUNDLE_STATUS_SUCCESS; |
| 382 | 304 | ||
| 383 | if (FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_MACHINE, wzSubKey, phKey)) && | 305 | if (FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_MACHINE, wzSubKey, REG_KEY_32BIT, phKey)) && |
| 384 | FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_USER, wzSubKey, phKey))) | 306 | FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_MACHINE, wzSubKey, REG_KEY_64BIT, phKey)) && |
| 307 | FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_USER, wzSubKey, REG_KEY_DEFAULT, phKey))) | ||
| 385 | { | 308 | { |
| 386 | if (E_FILENOTFOUND == hr) | 309 | if (E_FILENOTFOUND == hr) |
| 387 | { | 310 | { |
| @@ -413,6 +336,7 @@ static HRESULT OpenBundleKey( | |||
| 413 | __in_z LPCWSTR wzBundleId, | 336 | __in_z LPCWSTR wzBundleId, |
| 414 | __in BUNDLE_INSTALL_CONTEXT context, | 337 | __in BUNDLE_INSTALL_CONTEXT context, |
| 415 | __in_opt LPCWSTR wzSubKey, | 338 | __in_opt LPCWSTR wzSubKey, |
| 339 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 416 | __inout HKEY* phKey | 340 | __inout HKEY* phKey |
| 417 | ) | 341 | ) |
| 418 | { | 342 | { |
| @@ -433,7 +357,7 @@ static HRESULT OpenBundleKey( | |||
| 433 | } | 357 | } |
| 434 | ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); | 358 | ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); |
| 435 | 359 | ||
| 436 | hr = RegOpen(hkRoot, sczKeypath, KEY_READ, phKey); | 360 | hr = RegOpenEx(hkRoot, sczKeypath, KEY_READ, kbKeyBitness, phKey); |
| 437 | ButilExitOnFailure(hr, "Failed to open bundle uninstall key path."); | 361 | ButilExitOnFailure(hr, "Failed to open bundle uninstall key path."); |
| 438 | 362 | ||
| 439 | LExit: | 363 | LExit: |
| @@ -472,3 +396,116 @@ static HRESULT CopyStringToBuffer( | |||
| 472 | 396 | ||
| 473 | return hr; | 397 | return hr; |
| 474 | } | 398 | } |
| 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/deputil.cpp b/src/libs/dutil/WixToolset.DUtil/deputil.cpp index 2e6d6a6c..754365e9 100644 --- a/src/libs/dutil/WixToolset.DUtil/deputil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/deputil.cpp | |||
| @@ -337,7 +337,7 @@ DAPI_(HRESULT) DepRegisterDependency( | |||
| 337 | DepExitOnFailure(hr, "Failed to allocate the registry key for dependency \"%ls\".", wzProviderKey); | 337 | DepExitOnFailure(hr, "Failed to allocate the registry key for dependency \"%ls\".", wzProviderKey); |
| 338 | 338 | ||
| 339 | // Create the dependency key (or open it if it already exists). | 339 | // Create the dependency key (or open it if it already exists). |
| 340 | hr = RegCreateEx(hkHive, sczKey, KEY_WRITE, FALSE, NULL, &hkKey, &fCreated); | 340 | hr = RegCreateEx(hkHive, sczKey, KEY_WRITE, REG_KEY_DEFAULT, FALSE, NULL, &hkKey, &fCreated); |
| 341 | DepExitOnFailure(hr, "Failed to create the dependency registry key \"%ls\".", sczKey); | 341 | DepExitOnFailure(hr, "Failed to create the dependency registry key \"%ls\".", sczKey); |
| 342 | 342 | ||
| 343 | // Set the id if it was provided. | 343 | // Set the id if it was provided. |
| @@ -417,14 +417,14 @@ DAPI_(HRESULT) DepRegisterDependent( | |||
| 417 | DepExitOnFailure(hr, "Failed to allocate the registry key for dependency \"%ls\".", wzDependencyProviderKey); | 417 | DepExitOnFailure(hr, "Failed to allocate the registry key for dependency \"%ls\".", wzDependencyProviderKey); |
| 418 | 418 | ||
| 419 | // Create the dependency key (or open it if it already exists). | 419 | // Create the dependency key (or open it if it already exists). |
| 420 | hr = RegCreateEx(hkHive, sczDependencyKey, KEY_WRITE, FALSE, NULL, &hkDependencyKey, &fCreated); | 420 | hr = RegCreateEx(hkHive, sczDependencyKey, KEY_WRITE, REG_KEY_DEFAULT, FALSE, NULL, &hkDependencyKey, &fCreated); |
| 421 | DepExitOnFailure(hr, "Failed to create the dependency registry key \"%ls\".", sczDependencyKey); | 421 | DepExitOnFailure(hr, "Failed to create the dependency registry key \"%ls\".", sczDependencyKey); |
| 422 | 422 | ||
| 423 | // Create the subkey to register the dependent. | 423 | // Create the subkey to register the dependent. |
| 424 | hr = StrAllocFormatted(&sczKey, L"%ls\\%ls", vsczRegistryDependents, wzProviderKey); | 424 | hr = StrAllocFormatted(&sczKey, L"%ls\\%ls", vsczRegistryDependents, wzProviderKey); |
| 425 | DepExitOnFailure(hr, "Failed to allocate dependent subkey \"%ls\" under dependency \"%ls\".", wzProviderKey, wzDependencyProviderKey); | 425 | DepExitOnFailure(hr, "Failed to allocate dependent subkey \"%ls\" under dependency \"%ls\".", wzProviderKey, wzDependencyProviderKey); |
| 426 | 426 | ||
| 427 | hr = RegCreateEx(hkDependencyKey, sczKey, KEY_WRITE, FALSE, NULL, &hkKey, &fCreated); | 427 | hr = RegCreateEx(hkDependencyKey, sczKey, KEY_WRITE, REG_KEY_DEFAULT, FALSE, NULL, &hkKey, &fCreated); |
| 428 | DepExitOnFailure(hr, "Failed to create the dependency subkey \"%ls\".", sczKey); | 428 | DepExitOnFailure(hr, "Failed to create the dependency subkey \"%ls\".", sczKey); |
| 429 | 429 | ||
| 430 | // Set the minimum version if not NULL. | 430 | // Set the minimum version if not NULL. |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/butil.h b/src/libs/dutil/WixToolset.DUtil/inc/butil.h index 0405be8b..3b316e66 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/butil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/butil.h | |||
| @@ -64,6 +64,10 @@ BundleEnumRelatedBundle - Queries the bundle installation metadata for installs | |||
| 64 | RETURNS: | 64 | RETURNS: |
| 65 | E_INVALIDARG | 65 | E_INVALIDARG |
| 66 | An invalid parameter was passed to the function. | 66 | An invalid parameter was passed to the function. |
| 67 | S_OK | ||
| 68 | Related bundle was found. | ||
| 69 | S_FALSE | ||
| 70 | Related bundle was not found. | ||
| 67 | 71 | ||
| 68 | All other returns are unexpected returns from other dutil methods. | 72 | All other returns are unexpected returns from other dutil methods. |
| 69 | ********************************************************************/ | 73 | ********************************************************************/ |
| @@ -82,6 +86,10 @@ NOTE: lpBundleIdBuff is a buffer to receive the bundle GUID. This buffer must be | |||
| 82 | RETURNS: | 86 | RETURNS: |
| 83 | E_INVALIDARG | 87 | E_INVALIDARG |
| 84 | An invalid parameter was passed to the function. | 88 | An invalid parameter was passed to the function. |
| 89 | S_OK | ||
| 90 | Related bundle was found. | ||
| 91 | S_FALSE | ||
| 92 | Related bundle was not found. | ||
| 85 | 93 | ||
| 86 | All other returns are unexpected returns from other dutil methods. | 94 | All other returns are unexpected returns from other dutil methods. |
| 87 | ********************************************************************/ | 95 | ********************************************************************/ |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h index ae47f75e..db8e0c5c 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h | |||
| @@ -147,6 +147,7 @@ HRESULT DAPI RegCreateEx( | |||
| 147 | __in HKEY hkRoot, | 147 | __in HKEY hkRoot, |
| 148 | __in_z LPCWSTR wzSubKey, | 148 | __in_z LPCWSTR wzSubKey, |
| 149 | __in DWORD dwAccess, | 149 | __in DWORD dwAccess, |
| 150 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 150 | __in BOOL fVolatile, | 151 | __in BOOL fVolatile, |
| 151 | __in_opt SECURITY_ATTRIBUTES* pSecurityAttributes, | 152 | __in_opt SECURITY_ATTRIBUTES* pSecurityAttributes, |
| 152 | __out HKEY* phk, | 153 | __out HKEY* phk, |
| @@ -162,7 +163,19 @@ HRESULT DAPI RegOpen( | |||
| 162 | __in_z LPCWSTR wzSubKey, | 163 | __in_z LPCWSTR wzSubKey, |
| 163 | __in DWORD dwAccess, | 164 | __in DWORD dwAccess, |
| 164 | __out HKEY* phk | 165 | __out HKEY* phk |
| 165 | ); | 166 | ); |
| 167 | |||
| 168 | /******************************************************************** | ||
| 169 | RegOpenEx - opens a registry key. | ||
| 170 | |||
| 171 | *********************************************************************/ | ||
| 172 | HRESULT DAPI RegOpenEx( | ||
| 173 | __in HKEY hkRoot, | ||
| 174 | __in_z LPCWSTR wzSubKey, | ||
| 175 | __in DWORD dwAccess, | ||
| 176 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 177 | __out HKEY* phk | ||
| 178 | ); | ||
| 166 | 179 | ||
| 167 | /******************************************************************** | 180 | /******************************************************************** |
| 168 | RegDelete - deletes a registry key (and optionally it's whole tree). | 181 | RegDelete - deletes a registry key (and optionally it's whole tree). |
| @@ -379,7 +392,7 @@ HRESULT DAPI RegKeyReadNumber( | |||
| 379 | __in HKEY hk, | 392 | __in HKEY hk, |
| 380 | __in_z LPCWSTR wzSubKey, | 393 | __in_z LPCWSTR wzSubKey, |
| 381 | __in_z_opt LPCWSTR wzName, | 394 | __in_z_opt LPCWSTR wzName, |
| 382 | __in BOOL f64Bit, | 395 | __in REG_KEY_BITNESS kbKeyBitness, |
| 383 | __out DWORD* pdwValue | 396 | __out DWORD* pdwValue |
| 384 | ); | 397 | ); |
| 385 | 398 | ||
| @@ -392,7 +405,7 @@ BOOL DAPI RegValueExists( | |||
| 392 | __in HKEY hk, | 405 | __in HKEY hk, |
| 393 | __in_z LPCWSTR wzSubKey, | 406 | __in_z LPCWSTR wzSubKey, |
| 394 | __in_z_opt LPCWSTR wzName, | 407 | __in_z_opt LPCWSTR wzName, |
| 395 | __in BOOL f64Bit | 408 | __in REG_KEY_BITNESS kbKeyBitness |
| 396 | ); | 409 | ); |
| 397 | 410 | ||
| 398 | #ifdef __cplusplus | 411 | #ifdef __cplusplus |
diff --git a/src/libs/dutil/WixToolset.DUtil/regutil.cpp b/src/libs/dutil/WixToolset.DUtil/regutil.cpp index 57093f97..f4719466 100644 --- a/src/libs/dutil/WixToolset.DUtil/regutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/regutil.cpp | |||
| @@ -32,6 +32,9 @@ 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 | ); | ||
| 35 | static HRESULT WriteStringToRegistry( | 38 | static HRESULT WriteStringToRegistry( |
| 36 | __in HKEY hk, | 39 | __in HKEY hk, |
| 37 | __in_z_opt LPCWSTR wzName, | 40 | __in_z_opt LPCWSTR wzName, |
| @@ -121,6 +124,7 @@ DAPI_(HRESULT) RegCreateEx( | |||
| 121 | __in HKEY hkRoot, | 124 | __in HKEY hkRoot, |
| 122 | __in_z LPCWSTR wzSubKey, | 125 | __in_z LPCWSTR wzSubKey, |
| 123 | __in DWORD dwAccess, | 126 | __in DWORD dwAccess, |
| 127 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 124 | __in BOOL fVolatile, | 128 | __in BOOL fVolatile, |
| 125 | __in_opt SECURITY_ATTRIBUTES* pSecurityAttributes, | 129 | __in_opt SECURITY_ATTRIBUTES* pSecurityAttributes, |
| 126 | __out HKEY* phk, | 130 | __out HKEY* phk, |
| @@ -131,7 +135,8 @@ DAPI_(HRESULT) RegCreateEx( | |||
| 131 | DWORD er = ERROR_SUCCESS; | 135 | DWORD er = ERROR_SUCCESS; |
| 132 | DWORD dwDisposition; | 136 | DWORD dwDisposition; |
| 133 | 137 | ||
| 134 | er = vpfnRegCreateKeyExW(hkRoot, wzSubKey, 0, NULL, fVolatile ? REG_OPTION_VOLATILE : REG_OPTION_NON_VOLATILE, dwAccess, pSecurityAttributes, phk, &dwDisposition); | 138 | REGSAM samDesired = TranslateKeyBitness(kbKeyBitness); |
| 139 | er = vpfnRegCreateKeyExW(hkRoot, wzSubKey, 0, NULL, fVolatile ? REG_OPTION_VOLATILE : REG_OPTION_NON_VOLATILE, dwAccess | samDesired, pSecurityAttributes, phk, &dwDisposition); | ||
| 135 | RegExitOnWin32Error(er, hr, "Failed to create registry key."); | 140 | RegExitOnWin32Error(er, hr, "Failed to create registry key."); |
| 136 | 141 | ||
| 137 | if (pfCreated) | 142 | if (pfCreated) |
| @@ -149,12 +154,25 @@ DAPI_(HRESULT) RegOpen( | |||
| 149 | __in_z LPCWSTR wzSubKey, | 154 | __in_z LPCWSTR wzSubKey, |
| 150 | __in DWORD dwAccess, | 155 | __in DWORD dwAccess, |
| 151 | __out HKEY* phk | 156 | __out HKEY* phk |
| 152 | ) | 157 | ) |
| 158 | { | ||
| 159 | return RegOpenEx(hkRoot, wzSubKey, dwAccess, REG_KEY_DEFAULT, phk); | ||
| 160 | } | ||
| 161 | |||
| 162 | |||
| 163 | DAPI_(HRESULT) RegOpenEx( | ||
| 164 | __in HKEY hkRoot, | ||
| 165 | __in_z LPCWSTR wzSubKey, | ||
| 166 | __in DWORD dwAccess, | ||
| 167 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 168 | __out HKEY* phk | ||
| 169 | ) | ||
| 153 | { | 170 | { |
| 154 | HRESULT hr = S_OK; | 171 | HRESULT hr = S_OK; |
| 155 | DWORD er = ERROR_SUCCESS; | 172 | DWORD er = ERROR_SUCCESS; |
| 156 | 173 | ||
| 157 | er = vpfnRegOpenKeyExW(hkRoot, wzSubKey, 0, dwAccess, phk); | 174 | REGSAM samDesired = TranslateKeyBitness(kbKeyBitness); |
| 175 | er = vpfnRegOpenKeyExW(hkRoot, wzSubKey, 0, dwAccess | samDesired, phk); | ||
| 158 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) | 176 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) |
| 159 | { | 177 | { |
| 160 | ExitFunction1(hr = E_FILENOTFOUND); | 178 | ExitFunction1(hr = E_FILENOTFOUND); |
| @@ -178,7 +196,6 @@ DAPI_(HRESULT) RegDelete( | |||
| 178 | LPWSTR pszEnumeratedSubKey = NULL; | 196 | LPWSTR pszEnumeratedSubKey = NULL; |
| 179 | LPWSTR pszRecursiveSubKey = NULL; | 197 | LPWSTR pszRecursiveSubKey = NULL; |
| 180 | HKEY hkKey = NULL; | 198 | HKEY hkKey = NULL; |
| 181 | REGSAM samDesired = 0; | ||
| 182 | 199 | ||
| 183 | if (!vfRegInitialized && REG_KEY_DEFAULT != kbKeyBitness) | 200 | if (!vfRegInitialized && REG_KEY_DEFAULT != kbKeyBitness) |
| 184 | { | 201 | { |
| @@ -186,22 +203,9 @@ DAPI_(HRESULT) RegDelete( | |||
| 186 | RegExitOnFailure(hr, "RegInitialize must be called first in order to RegDelete() a key with non-default bit attributes!"); | 203 | RegExitOnFailure(hr, "RegInitialize must be called first in order to RegDelete() a key with non-default bit attributes!"); |
| 187 | } | 204 | } |
| 188 | 205 | ||
| 189 | switch (kbKeyBitness) | ||
| 190 | { | ||
| 191 | case REG_KEY_32BIT: | ||
| 192 | samDesired = KEY_WOW64_32KEY; | ||
| 193 | break; | ||
| 194 | case REG_KEY_64BIT: | ||
| 195 | samDesired = KEY_WOW64_64KEY; | ||
| 196 | break; | ||
| 197 | case REG_KEY_DEFAULT: | ||
| 198 | // Nothing to do | ||
| 199 | break; | ||
| 200 | } | ||
| 201 | |||
| 202 | if (fDeleteTree) | 206 | if (fDeleteTree) |
| 203 | { | 207 | { |
| 204 | hr = RegOpen(hkRoot, wzSubKey, KEY_READ | samDesired, &hkKey); | 208 | hr = RegOpenEx(hkRoot, wzSubKey, KEY_READ, kbKeyBitness, &hkKey); |
| 205 | if (E_FILENOTFOUND == hr) | 209 | if (E_FILENOTFOUND == hr) |
| 206 | { | 210 | { |
| 207 | ExitFunction1(hr = S_OK); | 211 | ExitFunction1(hr = S_OK); |
| @@ -225,6 +229,7 @@ DAPI_(HRESULT) RegDelete( | |||
| 225 | 229 | ||
| 226 | if (NULL != vpfnRegDeleteKeyExW) | 230 | if (NULL != vpfnRegDeleteKeyExW) |
| 227 | { | 231 | { |
| 232 | REGSAM samDesired = TranslateKeyBitness(kbKeyBitness); | ||
| 228 | er = vpfnRegDeleteKeyExW(hkRoot, wzSubKey, samDesired, 0); | 233 | er = vpfnRegDeleteKeyExW(hkRoot, wzSubKey, samDesired, 0); |
| 229 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) | 234 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) |
| 230 | { | 235 | { |
| @@ -250,7 +255,6 @@ LExit: | |||
| 250 | return hr; | 255 | return hr; |
| 251 | } | 256 | } |
| 252 | 257 | ||
| 253 | |||
| 254 | DAPI_(HRESULT) RegKeyEnum( | 258 | DAPI_(HRESULT) RegKeyEnum( |
| 255 | __in HKEY hk, | 259 | __in HKEY hk, |
| 256 | __in DWORD dwIndex, | 260 | __in DWORD dwIndex, |
| @@ -889,14 +893,14 @@ DAPI_(HRESULT) RegKeyReadNumber( | |||
| 889 | __in HKEY hk, | 893 | __in HKEY hk, |
| 890 | __in_z LPCWSTR wzSubKey, | 894 | __in_z LPCWSTR wzSubKey, |
| 891 | __in_z_opt LPCWSTR wzName, | 895 | __in_z_opt LPCWSTR wzName, |
| 892 | __in BOOL f64Bit, | 896 | __in REG_KEY_BITNESS kbKeyBitness, |
| 893 | __out DWORD* pdwValue | 897 | __out DWORD* pdwValue |
| 894 | ) | 898 | ) |
| 895 | { | 899 | { |
| 896 | HRESULT hr = S_OK; | 900 | HRESULT hr = S_OK; |
| 897 | HKEY hkKey = NULL; | 901 | HKEY hkKey = NULL; |
| 898 | 902 | ||
| 899 | hr = RegOpen(hk, wzSubKey, KEY_READ | f64Bit ? KEY_WOW64_64KEY : 0, &hkKey); | 903 | hr = RegOpenEx(hk, wzSubKey, KEY_READ, kbKeyBitness, &hkKey); |
| 900 | RegExitOnFailure(hr, "Failed to open key: %ls", wzSubKey); | 904 | RegExitOnFailure(hr, "Failed to open key: %ls", wzSubKey); |
| 901 | 905 | ||
| 902 | hr = RegReadNumber(hkKey, wzName, pdwValue); | 906 | hr = RegReadNumber(hkKey, wzName, pdwValue); |
| @@ -917,14 +921,14 @@ DAPI_(BOOL) RegValueExists( | |||
| 917 | __in HKEY hk, | 921 | __in HKEY hk, |
| 918 | __in_z LPCWSTR wzSubKey, | 922 | __in_z LPCWSTR wzSubKey, |
| 919 | __in_z_opt LPCWSTR wzName, | 923 | __in_z_opt LPCWSTR wzName, |
| 920 | __in BOOL f64Bit | 924 | __in REG_KEY_BITNESS kbKeyBitness |
| 921 | ) | 925 | ) |
| 922 | { | 926 | { |
| 923 | HRESULT hr = S_OK; | 927 | HRESULT hr = S_OK; |
| 924 | HKEY hkKey = NULL; | 928 | HKEY hkKey = NULL; |
| 925 | DWORD dwType = 0; | 929 | DWORD dwType = 0; |
| 926 | 930 | ||
| 927 | hr = RegOpen(hk, wzSubKey, KEY_READ | f64Bit ? KEY_WOW64_64KEY : 0, &hkKey); | 931 | hr = RegOpenEx(hk, wzSubKey, KEY_READ, kbKeyBitness, &hkKey); |
| 928 | RegExitOnFailure(hr, "Failed to open key: %ls", wzSubKey); | 932 | RegExitOnFailure(hr, "Failed to open key: %ls", wzSubKey); |
| 929 | 933 | ||
| 930 | hr = RegGetType(hkKey, wzName, &dwType); | 934 | hr = RegGetType(hkKey, wzName, &dwType); |
| @@ -936,6 +940,25 @@ LExit: | |||
| 936 | return SUCCEEDED(hr); | 940 | return SUCCEEDED(hr); |
| 937 | } | 941 | } |
| 938 | 942 | ||
| 943 | static REGSAM TranslateKeyBitness( | ||
| 944 | __in REG_KEY_BITNESS kbKeyBitness | ||
| 945 | ) | ||
| 946 | { | ||
| 947 | switch (kbKeyBitness) | ||
| 948 | { | ||
| 949 | case REG_KEY_32BIT: | ||
| 950 | return KEY_WOW64_32KEY; | ||
| 951 | break; | ||
| 952 | case REG_KEY_64BIT: | ||
| 953 | return KEY_WOW64_64KEY; | ||
| 954 | break; | ||
| 955 | case REG_KEY_DEFAULT: | ||
| 956 | default: | ||
| 957 | return 0; | ||
| 958 | break; | ||
| 959 | } | ||
| 960 | } | ||
| 961 | |||
| 939 | static HRESULT WriteStringToRegistry( | 962 | static HRESULT WriteStringToRegistry( |
| 940 | __in HKEY hk, | 963 | __in HKEY hk, |
| 941 | __in_z_opt LPCWSTR wzName, | 964 | __in_z_opt LPCWSTR wzName, |
