Add fixed buffer butil APIs.
Sean Hall committed
Jul 19, 2021 at 18:50 UTC
ab47449ca6ccd2ae2b6f0bf477bcea7e49aa8f6b
3 files changed
+203
-21
src/burn/test/BurnUnitTest/RegistrationTest.cpp
+2
-1
@@ -593,9 +593,10 @@ namespace Bootstrapper
593
Assert::Empty((System::Collections::IEnumerable ^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"WixBundleForcedRestartPackage"), nullptr));
594
595
hr = StrAlloc(&sczRelatedBundleId, MAX_GUID_CHARS + 1);
596
+ NativeAssert::Succeeded(hr, "Failed to allocate buffer for related bundle id.");
597
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);
600
TestThrowOnFailure(hr, L"Failed to enumerate related bundle.");
601
602
NativeAssert::StringEqual(TEST_BUNDLE_ID, sczRelatedBundleId);
src/libs/dutil/WixToolset.DUtil/butil.cpp
+128
-12
@@ -57,6 +57,11 @@ static HRESULT OpenBundleKey(
57
__in_opt LPCWSTR wzSubKey,
58
__inout HKEY* phKey
59
);
60
+static HRESULT CopyStringToBuffer(
61
+ __in_z LPWSTR wzValue,
62
+ __in_z_opt LPWSTR wzBuffer,
63
+ __inout SIZE_T* pcchBuffer
64
+ );
65
66
DAPI_(HRESULT) BundleGetBundleInfo(
67
__in_z LPCWSTR wzBundleId,
@@ -111,11 +116,39 @@ LExit:
116
}
117
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
+
147
DAPI_(HRESULT) BundleEnumRelatedBundle(
115
- __in_z LPCWSTR wzUpgradeCode,
116
- __in BUNDLE_INSTALL_CONTEXT context,
117
- __inout PDWORD pdwStartIndex,
118
- __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf
148
+ __in_z LPCWSTR wzUpgradeCode,
149
+ __in BUNDLE_INSTALL_CONTEXT context,
150
+ __inout PDWORD pdwStartIndex,
151
+ __deref_out_z LPWSTR* psczBundleId
152
)
153
{
154
HRESULT hr = S_OK;
@@ -123,7 +156,6 @@ DAPI_(HRESULT) BundleEnumRelatedBundle(
156
HKEY hkUninstall = NULL;
157
HKEY hkBundle = NULL;
158
LPWSTR sczUninstallSubKey = NULL;
126
- size_t cchUninstallSubKey = 0;
159
LPWSTR sczUninstallSubKeyPath = NULL;
160
LPWSTR sczValue = NULL;
161
DWORD dwType = 0;
@@ -132,7 +164,7 @@ DAPI_(HRESULT) BundleEnumRelatedBundle(
164
DWORD cBundleUpgradeCodes = 0;
165
BOOL fUpgradeCodeFound = FALSE;
166
135
- if (!wzUpgradeCode || !lpBundleIdBuf || !pdwStartIndex)
167
+ if (!wzUpgradeCode || !pdwStartIndex)
168
{
169
ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function.");
170
}
@@ -205,13 +237,10 @@ DAPI_(HRESULT) BundleEnumRelatedBundle(
237
238
if (fUpgradeCodeFound)
239
{
208
- if (lpBundleIdBuf)
240
+ if (psczBundleId)
241
{
210
- hr = ::StringCchLengthW(sczUninstallSubKey, STRSAFE_MAX_CCH, &cchUninstallSubKey);
211
- ButilExitOnRootFailure(hr, "Failed to calculate length of string.");
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.");
242
+ *psczBundleId = sczUninstallSubKey;
243
+ sczUninstallSubKey = NULL;
244
}
245
246
break;
@@ -235,6 +264,34 @@ LExit:
264
}
265
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
+
295
DAPI_(HRESULT) BundleGetBundleVariable(
296
__in_z LPCWSTR wzBundleId,
297
__in_z LPCWSTR wzVariable,
@@ -282,6 +339,34 @@ LExit:
339
return hr;
340
}
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
+
370
static HRESULT LocateAndQueryBundleValue(
371
__in_z LPCWSTR wzBundleId,
372
__in_opt LPCWSTR wzSubKey,
@@ -356,3 +441,34 @@ LExit:
441
442
return hr;
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
+}
src/libs/dutil/WixToolset.DUtil/inc/butil.h
+73
-8
@@ -30,15 +30,54 @@ RETURNS:
30
All other returns are unexpected returns from other dutil methods.
31
********************************************************************/
32
HRESULT DAPI BundleGetBundleInfo(
33
- __in_z LPCWSTR szBundleId,
34
- __in_z LPCWSTR szAttribute,
33
+ __in_z LPCWSTR wzBundleId,
34
+ __in_z LPCWSTR wzAttribute,
35
__deref_out_z LPWSTR* psczValue
36
);
37
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
/********************************************************************
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.
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.
81
The first 38 characters are for the GUID, and the last character is for the terminating null character.
82
RETURNS:
83
E_INVALIDARG
@@ -46,11 +85,11 @@ RETURNS:
85
86
All other returns are unexpected returns from other dutil methods.
87
********************************************************************/
49
-HRESULT DAPI BundleEnumRelatedBundle(
50
- __in_z LPCWSTR lpUpgradeCode,
51
- __in BUNDLE_INSTALL_CONTEXT context,
52
- __inout PDWORD pdwStartIndex,
53
- __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf
88
+HRESULT DAPI BundleEnumRelatedBundleFixed(
89
+ __in_z LPCWSTR wzUpgradeCode,
90
+ __in BUNDLE_INSTALL_CONTEXT context,
91
+ __inout PDWORD pdwStartIndex,
92
+ __out_ecount(MAX_GUID_CHARS+1) LPWSTR wzBundleId
93
);
94
95
/********************************************************************
@@ -77,6 +116,32 @@ HRESULT DAPI BundleGetBundleVariable(
116
__deref_out_z LPWSTR* psczValue
117
);
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
+
145
146
#ifdef __cplusplus
147
}