diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-07-19 18:50:27 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-07-19 19:20:56 -0500 |
| commit | ab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b (patch) | |
| tree | 4a782518ae501e645aa635403bfd535576c3917e | |
| parent | 041cbc2ab9ca6b29841f19792c5b66fd1233dd37 (diff) | |
| download | wix-ab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b.tar.gz wix-ab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b.tar.bz2 wix-ab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b.zip | |
Add fixed buffer butil APIs.
| -rw-r--r-- | src/burn/test/BurnUnitTest/RegistrationTest.cpp | 3 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/butil.cpp | 140 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/butil.h | 81 |
3 files changed, 203 insertions, 21 deletions
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp index a8319bb2..b1c911f7 100644 --- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp +++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp | |||
| @@ -593,9 +593,10 @@ namespace Bootstrapper | |||
| 593 | Assert::Empty((System::Collections::IEnumerable ^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"WixBundleForcedRestartPackage"), nullptr)); | 593 | Assert::Empty((System::Collections::IEnumerable ^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"WixBundleForcedRestartPackage"), nullptr)); |
| 594 | 594 | ||
| 595 | hr = StrAlloc(&sczRelatedBundleId, MAX_GUID_CHARS + 1); | 595 | hr = StrAlloc(&sczRelatedBundleId, MAX_GUID_CHARS + 1); |
| 596 | NativeAssert::Succeeded(hr, "Failed to allocate buffer for related bundle id."); | ||
| 596 | 597 | ||
| 597 | // Verify we can find ourself via the UpgradeCode | 598 | // Verify we can find ourself via the UpgradeCode |
| 598 | hr = BundleEnumRelatedBundle(TEST_BUNDLE_UPGRADE_CODE, BUNDLE_INSTALL_CONTEXT_USER, &dwRelatedBundleIndex, sczRelatedBundleId); | 599 | hr = BundleEnumRelatedBundleFixed(TEST_BUNDLE_UPGRADE_CODE, BUNDLE_INSTALL_CONTEXT_USER, &dwRelatedBundleIndex, sczRelatedBundleId); |
| 599 | TestThrowOnFailure(hr, L"Failed to enumerate related bundle."); | 600 | TestThrowOnFailure(hr, L"Failed to enumerate related bundle."); |
| 600 | 601 | ||
| 601 | NativeAssert::StringEqual(TEST_BUNDLE_ID, sczRelatedBundleId); | 602 | 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 5e980699..4c96dfc1 100644 --- a/src/libs/dutil/WixToolset.DUtil/butil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/butil.cpp | |||
| @@ -57,6 +57,11 @@ static HRESULT OpenBundleKey( | |||
| 57 | __in_opt LPCWSTR wzSubKey, | 57 | __in_opt LPCWSTR wzSubKey, |
| 58 | __inout HKEY* phKey | 58 | __inout HKEY* phKey |
| 59 | ); | 59 | ); |
| 60 | static HRESULT CopyStringToBuffer( | ||
| 61 | __in_z LPWSTR wzValue, | ||
| 62 | __in_z_opt LPWSTR wzBuffer, | ||
| 63 | __inout SIZE_T* pcchBuffer | ||
| 64 | ); | ||
| 60 | 65 | ||
| 61 | DAPI_(HRESULT) BundleGetBundleInfo( | 66 | DAPI_(HRESULT) BundleGetBundleInfo( |
| 62 | __in_z LPCWSTR wzBundleId, | 67 | __in_z LPCWSTR wzBundleId, |
| @@ -111,11 +116,39 @@ LExit: | |||
| 111 | } | 116 | } |
| 112 | 117 | ||
| 113 | 118 | ||
| 119 | DAPI_(HRESULT) BundleGetBundleInfoFixed( | ||
| 120 | __in_z LPCWSTR wzBundleId, | ||
| 121 | __in_z LPCWSTR wzAttribute, | ||
| 122 | __out_ecount_opt(*pcchValue) LPWSTR wzValue, | ||
| 123 | __inout SIZE_T* pcchValue | ||
| 124 | ) | ||
| 125 | { | ||
| 126 | HRESULT hr = S_OK; | ||
| 127 | LPWSTR sczValue = NULL; | ||
| 128 | |||
| 129 | if (!pcchValue) | ||
| 130 | { | ||
| 131 | ButilExitWithRootFailure(hr, E_INVALIDARG, "An invalid parameter was passed to the function."); | ||
| 132 | } | ||
| 133 | |||
| 134 | hr = BundleGetBundleInfo(wzBundleId, wzAttribute, &sczValue); | ||
| 135 | if (SUCCEEDED(hr)) | ||
| 136 | { | ||
| 137 | hr = CopyStringToBuffer(sczValue, wzValue, pcchValue); | ||
| 138 | } | ||
| 139 | |||
| 140 | LExit: | ||
| 141 | ReleaseStr(sczValue); | ||
| 142 | |||
| 143 | return hr; | ||
| 144 | } | ||
| 145 | |||
| 146 | |||
| 114 | DAPI_(HRESULT) BundleEnumRelatedBundle( | 147 | DAPI_(HRESULT) BundleEnumRelatedBundle( |
| 115 | __in_z LPCWSTR wzUpgradeCode, | 148 | __in_z LPCWSTR wzUpgradeCode, |
| 116 | __in BUNDLE_INSTALL_CONTEXT context, | 149 | __in BUNDLE_INSTALL_CONTEXT context, |
| 117 | __inout PDWORD pdwStartIndex, | 150 | __inout PDWORD pdwStartIndex, |
| 118 | __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf | 151 | __deref_out_z LPWSTR* psczBundleId |
| 119 | ) | 152 | ) |
| 120 | { | 153 | { |
| 121 | HRESULT hr = S_OK; | 154 | HRESULT hr = S_OK; |
| @@ -123,7 +156,6 @@ DAPI_(HRESULT) BundleEnumRelatedBundle( | |||
| 123 | HKEY hkUninstall = NULL; | 156 | HKEY hkUninstall = NULL; |
| 124 | HKEY hkBundle = NULL; | 157 | HKEY hkBundle = NULL; |
| 125 | LPWSTR sczUninstallSubKey = NULL; | 158 | LPWSTR sczUninstallSubKey = NULL; |
| 126 | size_t cchUninstallSubKey = 0; | ||
| 127 | LPWSTR sczUninstallSubKeyPath = NULL; | 159 | LPWSTR sczUninstallSubKeyPath = NULL; |
| 128 | LPWSTR sczValue = NULL; | 160 | LPWSTR sczValue = NULL; |
| 129 | DWORD dwType = 0; | 161 | DWORD dwType = 0; |
| @@ -132,7 +164,7 @@ DAPI_(HRESULT) BundleEnumRelatedBundle( | |||
| 132 | DWORD cBundleUpgradeCodes = 0; | 164 | DWORD cBundleUpgradeCodes = 0; |
| 133 | BOOL fUpgradeCodeFound = FALSE; | 165 | BOOL fUpgradeCodeFound = FALSE; |
| 134 | 166 | ||
| 135 | if (!wzUpgradeCode || !lpBundleIdBuf || !pdwStartIndex) | 167 | if (!wzUpgradeCode || !pdwStartIndex) |
| 136 | { | 168 | { |
| 137 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); | 169 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); |
| 138 | } | 170 | } |
| @@ -205,13 +237,10 @@ DAPI_(HRESULT) BundleEnumRelatedBundle( | |||
| 205 | 237 | ||
| 206 | if (fUpgradeCodeFound) | 238 | if (fUpgradeCodeFound) |
| 207 | { | 239 | { |
| 208 | if (lpBundleIdBuf) | 240 | if (psczBundleId) |
| 209 | { | 241 | { |
| 210 | hr = ::StringCchLengthW(sczUninstallSubKey, STRSAFE_MAX_CCH, &cchUninstallSubKey); | 242 | *psczBundleId = sczUninstallSubKey; |
| 211 | ButilExitOnRootFailure(hr, "Failed to calculate length of string."); | 243 | sczUninstallSubKey = NULL; |
| 212 | |||
| 213 | hr = ::StringCchCopyNExW(lpBundleIdBuf, MAX_GUID_CHARS + 1, sczUninstallSubKey, cchUninstallSubKey, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); | ||
| 214 | ButilExitOnRootFailure(hr, "Failed to copy the property value to the output buffer."); | ||
| 215 | } | 244 | } |
| 216 | 245 | ||
| 217 | break; | 246 | break; |
| @@ -235,6 +264,34 @@ LExit: | |||
| 235 | } | 264 | } |
| 236 | 265 | ||
| 237 | 266 | ||
| 267 | DAPI_(HRESULT) BundleEnumRelatedBundleFixed( | ||
| 268 | __in_z LPCWSTR wzUpgradeCode, | ||
| 269 | __in BUNDLE_INSTALL_CONTEXT context, | ||
| 270 | __inout PDWORD pdwStartIndex, | ||
| 271 | __out_ecount(MAX_GUID_CHARS+1) LPWSTR wzBundleId | ||
| 272 | ) | ||
| 273 | { | ||
| 274 | HRESULT hr = S_OK; | ||
| 275 | LPWSTR sczValue = NULL; | ||
| 276 | size_t cchValue = 0; | ||
| 277 | |||
| 278 | hr = BundleEnumRelatedBundle(wzUpgradeCode, context, pdwStartIndex, &sczValue); | ||
| 279 | if (SUCCEEDED(hr) && wzBundleId) | ||
| 280 | { | ||
| 281 | hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchValue); | ||
| 282 | ButilExitOnRootFailure(hr, "Failed to calculate length of string."); | ||
| 283 | |||
| 284 | hr = ::StringCchCopyNExW(wzBundleId, MAX_GUID_CHARS + 1, sczValue, cchValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); | ||
| 285 | ButilExitOnRootFailure(hr, "Failed to copy the property value to the output buffer."); | ||
| 286 | } | ||
| 287 | |||
| 288 | LExit: | ||
| 289 | ReleaseStr(sczValue); | ||
| 290 | |||
| 291 | return hr; | ||
| 292 | } | ||
| 293 | |||
| 294 | |||
| 238 | DAPI_(HRESULT) BundleGetBundleVariable( | 295 | DAPI_(HRESULT) BundleGetBundleVariable( |
| 239 | __in_z LPCWSTR wzBundleId, | 296 | __in_z LPCWSTR wzBundleId, |
| 240 | __in_z LPCWSTR wzVariable, | 297 | __in_z LPCWSTR wzVariable, |
| @@ -282,6 +339,34 @@ LExit: | |||
| 282 | return hr; | 339 | return hr; |
| 283 | } | 340 | } |
| 284 | 341 | ||
| 342 | |||
| 343 | DAPI_(HRESULT) BundleGetBundleVariableFixed( | ||
| 344 | __in_z LPCWSTR wzBundleId, | ||
| 345 | __in_z LPCWSTR wzVariable, | ||
| 346 | __out_ecount_opt(*pcchValue) LPWSTR wzValue, | ||
| 347 | __inout SIZE_T* pcchValue | ||
| 348 | ) | ||
| 349 | { | ||
| 350 | HRESULT hr = S_OK; | ||
| 351 | LPWSTR sczValue = NULL; | ||
| 352 | |||
| 353 | if (!pcchValue) | ||
| 354 | { | ||
| 355 | ButilExitWithRootFailure(hr, E_INVALIDARG, "An invalid parameter was passed to the function."); | ||
| 356 | } | ||
| 357 | |||
| 358 | hr = BundleGetBundleVariable(wzBundleId, wzVariable, &sczValue); | ||
| 359 | if (SUCCEEDED(hr)) | ||
| 360 | { | ||
| 361 | hr = CopyStringToBuffer(sczValue, wzValue, pcchValue); | ||
| 362 | } | ||
| 363 | |||
| 364 | LExit: | ||
| 365 | ReleaseStr(sczValue); | ||
| 366 | |||
| 367 | return hr; | ||
| 368 | } | ||
| 369 | |||
| 285 | static HRESULT LocateAndQueryBundleValue( | 370 | static HRESULT LocateAndQueryBundleValue( |
| 286 | __in_z LPCWSTR wzBundleId, | 371 | __in_z LPCWSTR wzBundleId, |
| 287 | __in_opt LPCWSTR wzSubKey, | 372 | __in_opt LPCWSTR wzSubKey, |
| @@ -356,3 +441,34 @@ LExit: | |||
| 356 | 441 | ||
| 357 | return hr; | 442 | return hr; |
| 358 | } | 443 | } |
| 444 | |||
| 445 | static HRESULT CopyStringToBuffer( | ||
| 446 | __in_z LPWSTR wzValue, | ||
| 447 | __in_z_opt LPWSTR wzBuffer, | ||
| 448 | __inout SIZE_T* pcchBuffer | ||
| 449 | ) | ||
| 450 | { | ||
| 451 | HRESULT hr = S_OK; | ||
| 452 | BOOL fTooSmall = !wzBuffer; | ||
| 453 | |||
| 454 | if (!fTooSmall) | ||
| 455 | { | ||
| 456 | hr = ::StringCchCopyExW(wzBuffer, *pcchBuffer, wzValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); | ||
| 457 | if (STRSAFE_E_INSUFFICIENT_BUFFER == hr) | ||
| 458 | { | ||
| 459 | fTooSmall = TRUE; | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 463 | if (fTooSmall) | ||
| 464 | { | ||
| 465 | hr = ::StringCchLengthW(wzValue, STRSAFE_MAX_LENGTH, reinterpret_cast<size_t*>(pcchBuffer)); | ||
| 466 | if (SUCCEEDED(hr)) | ||
| 467 | { | ||
| 468 | hr = E_MOREDATA; | ||
| 469 | *pcchBuffer += 1; // null terminator. | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 473 | return hr; | ||
| 474 | } | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/butil.h b/src/libs/dutil/WixToolset.DUtil/inc/butil.h index 989d4237..0405be8b 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/butil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/butil.h | |||
| @@ -30,15 +30,54 @@ RETURNS: | |||
| 30 | All other returns are unexpected returns from other dutil methods. | 30 | All other returns are unexpected returns from other dutil methods. |
| 31 | ********************************************************************/ | 31 | ********************************************************************/ |
| 32 | HRESULT DAPI BundleGetBundleInfo( | 32 | HRESULT DAPI BundleGetBundleInfo( |
| 33 | __in_z LPCWSTR szBundleId, | 33 | __in_z LPCWSTR wzBundleId, |
| 34 | __in_z LPCWSTR szAttribute, | 34 | __in_z LPCWSTR wzAttribute, |
| 35 | __deref_out_z LPWSTR* psczValue | 35 | __deref_out_z LPWSTR* psczValue |
| 36 | ); | 36 | ); |
| 37 | 37 | ||
| 38 | /******************************************************************** | 38 | /******************************************************************** |
| 39 | BundleGetBundleInfoFixed - Queries the bundle installation metadata for a given property | ||
| 40 | |||
| 41 | RETURNS: | ||
| 42 | E_INVALIDARG | ||
| 43 | An invalid parameter was passed to the function. | ||
| 44 | HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) | ||
| 45 | The bundle is not installed | ||
| 46 | HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) | ||
| 47 | The property is unrecognized | ||
| 48 | HRESULT_FROM_WIN32(ERROR_MORE_DATA) | ||
| 49 | A buffer is too small to hold the requested data. | ||
| 50 | E_NOTIMPL: | ||
| 51 | Tried to read a bundle attribute for a type which has not been implemented | ||
| 52 | |||
| 53 | All other returns are unexpected returns from other dutil methods. | ||
| 54 | ********************************************************************/ | ||
| 55 | HRESULT DAPI BundleGetBundleInfoFixed( | ||
| 56 | __in_z LPCWSTR wzBundleId, | ||
| 57 | __in_z LPCWSTR wzAttribute, | ||
| 58 | __out_ecount_opt(*pcchValue) LPWSTR wzValue, | ||
| 59 | __inout SIZE_T* pcchValue | ||
| 60 | ); | ||
| 61 | |||
| 62 | /******************************************************************** | ||
| 39 | 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 | RETURNS: | ||
| 65 | E_INVALIDARG | ||
| 66 | An invalid parameter was passed to the function. | ||
| 40 | 67 | ||
| 41 | NOTE: lpBundleIdBuff is a buffer to receive the bundle GUID. This buffer must be 39 characters long. | 68 | All other returns are unexpected returns from other dutil methods. |
| 69 | ********************************************************************/ | ||
| 70 | HRESULT DAPI BundleEnumRelatedBundle( | ||
| 71 | __in_z LPCWSTR wzUpgradeCode, | ||
| 72 | __in BUNDLE_INSTALL_CONTEXT context, | ||
| 73 | __inout PDWORD pdwStartIndex, | ||
| 74 | __deref_out_z LPWSTR* psczBundleId | ||
| 75 | ); | ||
| 76 | |||
| 77 | /******************************************************************** | ||
| 78 | BundleEnumRelatedBundleFixed - Queries the bundle installation metadata for installs with the given upgrade code | ||
| 79 | |||
| 80 | NOTE: lpBundleIdBuff is a buffer to receive the bundle GUID. This buffer must be 39 characters long. | ||
| 42 | The first 38 characters are for the GUID, and the last character is for the terminating null character. | 81 | The first 38 characters are for the GUID, and the last character is for the terminating null character. |
| 43 | RETURNS: | 82 | RETURNS: |
| 44 | E_INVALIDARG | 83 | E_INVALIDARG |
| @@ -46,11 +85,11 @@ RETURNS: | |||
| 46 | 85 | ||
| 47 | All other returns are unexpected returns from other dutil methods. | 86 | All other returns are unexpected returns from other dutil methods. |
| 48 | ********************************************************************/ | 87 | ********************************************************************/ |
| 49 | HRESULT DAPI BundleEnumRelatedBundle( | 88 | HRESULT DAPI BundleEnumRelatedBundleFixed( |
| 50 | __in_z LPCWSTR lpUpgradeCode, | 89 | __in_z LPCWSTR wzUpgradeCode, |
| 51 | __in BUNDLE_INSTALL_CONTEXT context, | 90 | __in BUNDLE_INSTALL_CONTEXT context, |
| 52 | __inout PDWORD pdwStartIndex, | 91 | __inout PDWORD pdwStartIndex, |
| 53 | __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf | 92 | __out_ecount(MAX_GUID_CHARS+1) LPWSTR wzBundleId |
| 54 | ); | 93 | ); |
| 55 | 94 | ||
| 56 | /******************************************************************** | 95 | /******************************************************************** |
| @@ -77,6 +116,32 @@ HRESULT DAPI BundleGetBundleVariable( | |||
| 77 | __deref_out_z LPWSTR* psczValue | 116 | __deref_out_z LPWSTR* psczValue |
| 78 | ); | 117 | ); |
| 79 | 118 | ||
| 119 | /******************************************************************** | ||
| 120 | BundleGetBundleVariableFixed - Queries the bundle installation metadata for a given variable | ||
| 121 | |||
| 122 | RETURNS: | ||
| 123 | S_OK | ||
| 124 | Success, if the variable had a value, it's returned in psczValue | ||
| 125 | E_INVALIDARG | ||
| 126 | An invalid parameter was passed to the function. | ||
| 127 | HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) | ||
| 128 | The bundle is not installed | ||
| 129 | HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) | ||
| 130 | The variable is unrecognized | ||
| 131 | HRESULT_FROM_WIN32(ERROR_MORE_DATA) | ||
| 132 | A buffer is too small to hold the requested data. | ||
| 133 | E_NOTIMPL: | ||
| 134 | Tried to read a bundle variable for a type which has not been implemented | ||
| 135 | |||
| 136 | All other returns are unexpected returns from other dutil methods. | ||
| 137 | ********************************************************************/ | ||
| 138 | HRESULT DAPI BundleGetBundleVariableFixed( | ||
| 139 | __in_z LPCWSTR wzBundleId, | ||
| 140 | __in_z LPCWSTR wzVariable, | ||
| 141 | __out_ecount_opt(*pcchValue) LPWSTR wzValue, | ||
| 142 | __inout SIZE_T* pcchValue | ||
| 143 | ); | ||
| 144 | |||
| 80 | 145 | ||
| 81 | #ifdef __cplusplus | 146 | #ifdef __cplusplus |
| 82 | } | 147 | } |
