aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-07-19 18:50:27 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-07-19 19:20:56 -0500
commitab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b (patch)
tree4a782518ae501e645aa635403bfd535576c3917e
parent041cbc2ab9ca6b29841f19792c5b66fd1233dd37 (diff)
downloadwix-ab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b.tar.gz
wix-ab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b.tar.bz2
wix-ab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b.zip
Add fixed buffer butil APIs.
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp3
-rw-r--r--src/libs/dutil/WixToolset.DUtil/butil.cpp140
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/butil.h81
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 );
60static HRESULT CopyStringToBuffer(
61 __in_z LPWSTR wzValue,
62 __in_z_opt LPWSTR wzBuffer,
63 __inout SIZE_T* pcchBuffer
64 );
60 65
61DAPI_(HRESULT) BundleGetBundleInfo( 66DAPI_(HRESULT) BundleGetBundleInfo(
62 __in_z LPCWSTR wzBundleId, 67 __in_z LPCWSTR wzBundleId,
@@ -111,11 +116,39 @@ LExit:
111} 116}
112 117
113 118
119DAPI_(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
140LExit:
141 ReleaseStr(sczValue);
142
143 return hr;
144}
145
146
114DAPI_(HRESULT) BundleEnumRelatedBundle( 147DAPI_(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
267DAPI_(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
288LExit:
289 ReleaseStr(sczValue);
290
291 return hr;
292}
293
294
238DAPI_(HRESULT) BundleGetBundleVariable( 295DAPI_(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
343DAPI_(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
364LExit:
365 ReleaseStr(sczValue);
366
367 return hr;
368}
369
285static HRESULT LocateAndQueryBundleValue( 370static 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
445static 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********************************************************************/
32HRESULT DAPI BundleGetBundleInfo( 32HRESULT 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/********************************************************************
39BundleGetBundleInfoFixed - Queries the bundle installation metadata for a given property
40
41RETURNS:
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********************************************************************/
55HRESULT 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/********************************************************************
39BundleEnumRelatedBundle - Queries the bundle installation metadata for installs with the given upgrade code 63BundleEnumRelatedBundle - Queries the bundle installation metadata for installs with the given upgrade code
64RETURNS:
65 E_INVALIDARG
66 An invalid parameter was passed to the function.
40 67
41NOTE: 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********************************************************************/
70HRESULT 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/********************************************************************
78BundleEnumRelatedBundleFixed - Queries the bundle installation metadata for installs with the given upgrade code
79
80NOTE: 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.
43RETURNS: 82RETURNS:
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********************************************************************/
49HRESULT DAPI BundleEnumRelatedBundle( 88HRESULT 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/********************************************************************
120BundleGetBundleVariableFixed - Queries the bundle installation metadata for a given variable
121
122RETURNS:
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********************************************************************/
138HRESULT 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}