aboutsummaryrefslogtreecommitdiff
path: root/src/libs
diff options
context:
space:
mode:
authorBob Arnson <bob@firegiant.com>2022-01-09 23:23:51 -0500
committerBob Arnson <github@bobs.org>2022-01-10 00:47:18 -0500
commita96db4a508f1d1774500ab89f2c57e581fb5a13a (patch)
tree40de5d2904e564e28c04c5816fd7528f8f090e2c /src/libs
parentbae756f4354fed4de6097c931590ccafc907fdb2 (diff)
downloadwix-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/libs')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/butil.cpp239
-rw-r--r--src/libs/dutil/WixToolset.DUtil/deputil.cpp6
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/butil.h8
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/regutil.h19
-rw-r--r--src/libs/dutil/WixToolset.DUtil/regutil.cpp69
5 files changed, 211 insertions, 130 deletions
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 );
60static HRESULT CopyStringToBuffer( 61static 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 );
66static 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
66DAPI_(HRESULT) BundleGetBundleInfo( 75DAPI_(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
255LExit: 184LExit:
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
439LExit: 363LExit:
@@ -472,3 +396,116 @@ static HRESULT CopyStringToBuffer(
472 396
473 return hr; 397 return hr;
474} 398}
399
400static 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
502LExit:
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
64RETURNS: 64RETURNS:
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
82RETURNS: 86RETURNS:
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*********************************************************************/
172HRESULT 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;
32static HMODULE vhAdvApi32Dll = NULL; 32static HMODULE vhAdvApi32Dll = NULL;
33static BOOL vfRegInitialized = FALSE; 33static BOOL vfRegInitialized = FALSE;
34 34
35static REGSAM TranslateKeyBitness(
36 __in REG_KEY_BITNESS kbKeyBitness
37);
35static HRESULT WriteStringToRegistry( 38static 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
163DAPI_(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
254DAPI_(HRESULT) RegKeyEnum( 258DAPI_(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
943static 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
939static HRESULT WriteStringToRegistry( 962static HRESULT WriteStringToRegistry(
940 __in HKEY hk, 963 __in HKEY hk,
941 __in_z_opt LPCWSTR wzName, 964 __in_z_opt LPCWSTR wzName,