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 | } |