aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/buffutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/buffutil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/buffutil.cpp271
1 files changed, 226 insertions, 45 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/buffutil.cpp b/src/libs/dutil/WixToolset.DUtil/buffutil.cpp
index acde4dc9..270bfc85 100644
--- a/src/libs/dutil/WixToolset.DUtil/buffutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/buffutil.cpp
@@ -33,6 +33,8 @@ static HRESULT EnsureBufferSize(
33 33
34// functions 34// functions
35 35
36// Buffer read functions
37
36extern "C" HRESULT BuffReadNumber( 38extern "C" HRESULT BuffReadNumber(
37 __in_bcount(cbBuffer) const BYTE* pbBuffer, 39 __in_bcount(cbBuffer) const BYTE* pbBuffer,
38 __in SIZE_T cbBuffer, 40 __in SIZE_T cbBuffer,
@@ -55,7 +57,7 @@ extern "C" HRESULT BuffReadNumber(
55 if (sizeof(DWORD) > cbAvailable) 57 if (sizeof(DWORD) > cbAvailable)
56 { 58 {
57 hr = E_INVALIDARG; 59 hr = E_INVALIDARG;
58 BuffExitOnRootFailure(hr, "Buffer too small."); 60 BuffExitOnRootFailure(hr, "Buffer too small to read number. cbAvailable: %u", cbAvailable);
59 } 61 }
60 62
61 *pdw = *(const DWORD*)(pbBuffer + *piBuffer); 63 *pdw = *(const DWORD*)(pbBuffer + *piBuffer);
@@ -87,7 +89,7 @@ extern "C" HRESULT BuffReadNumber64(
87 if (sizeof(DWORD64) > cbAvailable) 89 if (sizeof(DWORD64) > cbAvailable)
88 { 90 {
89 hr = E_INVALIDARG; 91 hr = E_INVALIDARG;
90 BuffExitOnRootFailure(hr, "Buffer too small."); 92 BuffExitOnRootFailure(hr, "Buffer too small to read 64-bit number. cbAvailable: %u", cbAvailable);
91 } 93 }
92 94
93 *pdw64 = *(const DWORD64*)(pbBuffer + *piBuffer); 95 *pdw64 = *(const DWORD64*)(pbBuffer + *piBuffer);
@@ -119,7 +121,7 @@ extern "C" HRESULT BuffReadPointer(
119 if (sizeof(DWORD_PTR) > cbAvailable) 121 if (sizeof(DWORD_PTR) > cbAvailable)
120 { 122 {
121 hr = E_INVALIDARG; 123 hr = E_INVALIDARG;
122 BuffExitOnRootFailure(hr, "Buffer too small."); 124 BuffExitOnRootFailure(hr, "Buffer too small to read pointer. cbAvailable: %u", cbAvailable);
123 } 125 }
124 126
125 *pdw64 = *(const DWORD_PTR*)(pbBuffer + *piBuffer); 127 *pdw64 = *(const DWORD_PTR*)(pbBuffer + *piBuffer);
@@ -141,7 +143,7 @@ extern "C" HRESULT BuffReadString(
141 Assert(pscz); 143 Assert(pscz);
142 144
143 HRESULT hr = S_OK; 145 HRESULT hr = S_OK;
144 SIZE_T cch = 0; 146 DWORD cch = 0;
145 SIZE_T cb = 0; 147 SIZE_T cb = 0;
146 SIZE_T cbAvailable = 0; 148 SIZE_T cbAvailable = 0;
147 149
@@ -150,19 +152,19 @@ extern "C" HRESULT BuffReadString(
150 BuffExitOnRootFailure(hr, "Failed to calculate available data size for character count."); 152 BuffExitOnRootFailure(hr, "Failed to calculate available data size for character count.");
151 153
152 // verify buffer size 154 // verify buffer size
153 if (sizeof(SIZE_T) > cbAvailable) 155 if (sizeof(DWORD) > cbAvailable)
154 { 156 {
155 hr = E_INVALIDARG; 157 hr = E_INVALIDARG;
156 BuffExitOnRootFailure(hr, "Buffer too small."); 158 BuffExitOnRootFailure(hr, "Buffer too small to read size of string. cbAvailable: %u", cbAvailable);
157 } 159 }
158 160
159 // read character count 161 // read character count
160 cch = *(const SIZE_T*)(pbBuffer + *piBuffer); 162 cch = *(const DWORD*)(pbBuffer + *piBuffer);
161 163
162 hr = ::SIZETMult(cch, sizeof(WCHAR), &cb); 164 hr = ::SIZETMult(cch, sizeof(WCHAR), &cb);
163 BuffExitOnRootFailure(hr, "Overflow while multiplying to calculate buffer size"); 165 BuffExitOnRootFailure(hr, "Overflow while multiplying to calculate buffer size");
164 166
165 hr = ::SIZETAdd(*piBuffer, sizeof(SIZE_T), piBuffer); 167 hr = ::SIZETAdd(*piBuffer, sizeof(cch), piBuffer);
166 BuffExitOnRootFailure(hr, "Overflow while adding to calculate buffer size"); 168 BuffExitOnRootFailure(hr, "Overflow while adding to calculate buffer size");
167 169
168 // get availiable data size 170 // get availiable data size
@@ -173,7 +175,7 @@ extern "C" HRESULT BuffReadString(
173 if (cb > cbAvailable) 175 if (cb > cbAvailable)
174 { 176 {
175 hr = E_INVALIDARG; 177 hr = E_INVALIDARG;
176 BuffExitOnRootFailure(hr, "Buffer too small to hold character data."); 178 BuffExitOnRootFailure(hr, "Buffer too small to read string data. cbAvailable: %u, cb: %u", cbAvailable, cb);
177 } 179 }
178 180
179 // copy character data 181 // copy character data
@@ -198,7 +200,7 @@ extern "C" HRESULT BuffReadStringAnsi(
198 Assert(pscz); 200 Assert(pscz);
199 201
200 HRESULT hr = S_OK; 202 HRESULT hr = S_OK;
201 SIZE_T cch = 0; 203 DWORD cch = 0;
202 SIZE_T cb = 0; 204 SIZE_T cb = 0;
203 SIZE_T cbAvailable = 0; 205 SIZE_T cbAvailable = 0;
204 206
@@ -207,19 +209,19 @@ extern "C" HRESULT BuffReadStringAnsi(
207 BuffExitOnRootFailure(hr, "Failed to calculate available data size for character count."); 209 BuffExitOnRootFailure(hr, "Failed to calculate available data size for character count.");
208 210
209 // verify buffer size 211 // verify buffer size
210 if (sizeof(SIZE_T) > cbAvailable) 212 if (sizeof(DWORD) > cbAvailable)
211 { 213 {
212 hr = E_INVALIDARG; 214 hr = E_INVALIDARG;
213 BuffExitOnRootFailure(hr, "Buffer too small."); 215 BuffExitOnRootFailure(hr, "Buffer too small to read size of ANSI string. cbAvailable: %u", cbAvailable);
214 } 216 }
215 217
216 // read character count 218 // read character count
217 cch = *(const SIZE_T*)(pbBuffer + *piBuffer); 219 cch = *(const DWORD*)(pbBuffer + *piBuffer);
218 220
219 hr = ::SIZETMult(cch, sizeof(CHAR), &cb); 221 hr = ::SIZETMult(cch, sizeof(CHAR), &cb);
220 BuffExitOnRootFailure(hr, "Overflow while multiplying to calculate buffer size"); 222 BuffExitOnRootFailure(hr, "Overflow while multiplying to calculate buffer size");
221 223
222 hr = ::SIZETAdd(*piBuffer, sizeof(SIZE_T), piBuffer); 224 hr = ::SIZETAdd(*piBuffer, sizeof(cch), piBuffer);
223 BuffExitOnRootFailure(hr, "Overflow while adding to calculate buffer size"); 225 BuffExitOnRootFailure(hr, "Overflow while adding to calculate buffer size");
224 226
225 // get availiable data size 227 // get availiable data size
@@ -230,7 +232,7 @@ extern "C" HRESULT BuffReadStringAnsi(
230 if (cb > cbAvailable) 232 if (cb > cbAvailable)
231 { 233 {
232 hr = E_INVALIDARG; 234 hr = E_INVALIDARG;
233 BuffExitOnRootFailure(hr, "Buffer too small to hold character count."); 235 BuffExitOnRootFailure(hr, "Buffer too small to read ANSI string data. cbAvailable: %u, cb: %u", cbAvailable, cb);
234 } 236 }
235 237
236 // copy character data 238 // copy character data
@@ -266,15 +268,15 @@ extern "C" HRESULT BuffReadStream(
266 BuffExitOnRootFailure(hr, "Failed to calculate available data size for stream size."); 268 BuffExitOnRootFailure(hr, "Failed to calculate available data size for stream size.");
267 269
268 // verify buffer size 270 // verify buffer size
269 if (sizeof(SIZE_T) > cbAvailable) 271 if (sizeof(DWORD) > cbAvailable)
270 { 272 {
271 hr = E_INVALIDARG; 273 hr = E_INVALIDARG;
272 BuffExitOnRootFailure(hr, "Buffer too small."); 274 BuffExitOnRootFailure(hr, "Buffer too small to read size of stream. cbAvailable: %u, cb: %u", cbAvailable, cb);
273 } 275 }
274 276
275 // read stream size 277 // read stream size
276 cb = *(const SIZE_T*)(pbBuffer + *piBuffer); 278 cb = *(const DWORD*)(pbBuffer + *piBuffer);
277 *piBuffer += sizeof(SIZE_T); 279 *piBuffer += sizeof(DWORD);
278 280
279 // get availiable data size 281 // get availiable data size
280 hr = ::SIZETSub(cbBuffer, *piBuffer, &cbAvailable); 282 hr = ::SIZETSub(cbBuffer, *piBuffer, &cbAvailable);
@@ -284,7 +286,7 @@ extern "C" HRESULT BuffReadStream(
284 if (cb > cbAvailable) 286 if (cb > cbAvailable)
285 { 287 {
286 hr = E_INVALIDARG; 288 hr = E_INVALIDARG;
287 BuffExitOnRootFailure(hr, "Buffer too small to hold byte count."); 289 BuffExitOnRootFailure(hr, "Buffer too small to read stream data. cbAvailable: %u, cb: %u", cbAvailable, cb);
288 } 290 }
289 291
290 // allocate buffer 292 // allocate buffer
@@ -307,6 +309,52 @@ LExit:
307 return hr; 309 return hr;
308} 310}
309 311
312
313// Buffer Reader read functions
314
315extern "C" HRESULT BuffReaderReadNumber(
316 __in BUFF_READER* pReader,
317 __out DWORD* pdw
318 )
319{
320 return BuffReadNumber(pReader->pbData, pReader->cbData, &pReader->iBuffer, pdw);
321}
322
323extern "C" HRESULT BuffReaderReadNumber64(
324 __in BUFF_READER* pReader,
325 __out DWORD64* pdw64
326 )
327{
328 return BuffReadNumber64(pReader->pbData, pReader->cbData, &pReader->iBuffer, pdw64);
329}
330
331extern "C" HRESULT BuffReaderReadPointer(
332 __in BUFF_READER* pReader,
333 __out DWORD_PTR* pdw
334 )
335{
336 return BuffReadPointer(pReader->pbData, pReader->cbData, &pReader->iBuffer, pdw);
337}
338
339extern "C" HRESULT BuffReaderReadString(
340 __in BUFF_READER* pReader,
341 __deref_out_z LPWSTR* pscz
342 )
343{
344 return BuffReadString(pReader->pbData, pReader->cbData, &pReader->iBuffer, pscz);
345}
346
347extern "C" HRESULT BuffReaderReadStringAnsi(
348 __in BUFF_READER* pReader,
349 __deref_out_z LPSTR* pscz
350 )
351{
352 return BuffReadStringAnsi(pReader->pbData, pReader->cbData, &pReader->iBuffer, pscz);
353}
354
355
356// Buffer write functions
357
310extern "C" HRESULT BuffWriteNumber( 358extern "C" HRESULT BuffWriteNumber(
311 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer, 359 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer,
312 __inout SIZE_T* piBuffer, 360 __inout SIZE_T* piBuffer,
@@ -323,7 +371,7 @@ extern "C" HRESULT BuffWriteNumber(
323 BuffExitOnFailure(hr, "Failed to ensure buffer size."); 371 BuffExitOnFailure(hr, "Failed to ensure buffer size.");
324 372
325 // copy data to buffer 373 // copy data to buffer
326 *(DWORD*)(*ppbBuffer + *piBuffer) = dw; 374 *reinterpret_cast<DWORD*>(*ppbBuffer + *piBuffer) = dw;
327 *piBuffer += sizeof(DWORD); 375 *piBuffer += sizeof(DWORD);
328 376
329LExit: 377LExit:
@@ -386,25 +434,35 @@ extern "C" HRESULT BuffWriteString(
386 Assert(piBuffer); 434 Assert(piBuffer);
387 435
388 HRESULT hr = S_OK; 436 HRESULT hr = S_OK;
389 SIZE_T cch = 0; 437 DWORD cch = 0; // This value *MUST* be treated as a DWORD to be marshalled over the pipe between 32-bit and 64-bit process the same.
390 SIZE_T cb = 0; 438 SIZE_T cb = 0;
391 errno_t err = 0; 439 errno_t err = 0;
392 440
393 if (scz) 441 if (scz)
394 { 442 {
395 hr = ::StringCchLengthW(scz, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cch)); 443 size_t size = 0;
396 BuffExitOnRootFailure(hr, "Failed to get string size.") 444
445 hr = ::StringCchLengthW(scz, STRSAFE_MAX_CCH, &size);
446 BuffExitOnRootFailure(hr, "Failed to get string size.");
447
448 if (size > DWORD_MAX)
449 {
450 hr = E_INVALIDARG;
451 BuffExitOnRootFailure(hr, "String too long to write to buffer.");
452 }
453
454 cch = static_cast<DWORD>(size);
397 } 455 }
398 456
399 cb = cch * sizeof(WCHAR); 457 cb = cch * sizeof(WCHAR);
400 458
401 // make sure we have a buffer with sufficient space 459 // make sure we have a buffer with sufficient space for the length plus the string without terminator.
402 hr = EnsureBufferSize(ppbBuffer, *piBuffer + (sizeof(SIZE_T) + cb)); 460 hr = EnsureBufferSize(ppbBuffer, *piBuffer + sizeof(DWORD) + cb);
403 BuffExitOnFailure(hr, "Failed to ensure buffer size."); 461 BuffExitOnFailure(hr, "Failed to ensure buffer size.");
404 462
405 // copy character count to buffer 463 // copy the character count to buffer as a DWORD
406 *(SIZE_T*)(*ppbBuffer + *piBuffer) = cch; 464 *reinterpret_cast<DWORD*>(*ppbBuffer + *piBuffer) = cch;
407 *piBuffer += sizeof(SIZE_T); 465 *piBuffer += sizeof(DWORD);
408 466
409 // copy data to buffer 467 // copy data to buffer
410 err = memcpy_s(*ppbBuffer + *piBuffer, cb, scz, cb); 468 err = memcpy_s(*ppbBuffer + *piBuffer, cb, scz, cb);
@@ -429,25 +487,35 @@ extern "C" HRESULT BuffWriteStringAnsi(
429 Assert(piBuffer); 487 Assert(piBuffer);
430 488
431 HRESULT hr = S_OK; 489 HRESULT hr = S_OK;
432 SIZE_T cch = 0; 490 DWORD cch = 0; // This value *MUST* be treated as a DWORD to be marshalled over the pipe between 32-bit and 64-bit process the same.
433 SIZE_T cb = 0; 491 SIZE_T cb = 0;
434 errno_t err = 0; 492 errno_t err = 0;
435 493
436 if (scz) 494 if (scz)
437 { 495 {
438 hr = ::StringCchLengthA(scz, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cch)); 496 size_t size = 0;
439 BuffExitOnRootFailure(hr, "Failed to get string size.") 497
498 hr = ::StringCchLengthA(scz, STRSAFE_MAX_CCH, &size);
499 BuffExitOnRootFailure(hr, "Failed to get ANSI string size.")
500
501 if (size > DWORD_MAX)
502 {
503 hr = E_INVALIDARG;
504 BuffExitOnRootFailure(hr, "ANSI string too long to write to buffer.");
505 }
506
507 cch = static_cast<DWORD>(size);
440 } 508 }
441 509
442 cb = cch * sizeof(CHAR); 510 cb = cch * sizeof(CHAR);
443 511
444 // make sure we have a buffer with sufficient space 512 // make sure we have a buffer with sufficient space
445 hr = EnsureBufferSize(ppbBuffer, *piBuffer + (sizeof(SIZE_T) + cb)); 513 hr = EnsureBufferSize(ppbBuffer, *piBuffer + (sizeof(DWORD) + cb));
446 BuffExitOnFailure(hr, "Failed to ensure buffer size."); 514 BuffExitOnFailure(hr, "Failed to ensure buffer size.");
447 515
448 // copy character count to buffer 516 // copy character count to buffer
449 *(SIZE_T*)(*ppbBuffer + *piBuffer) = cch; 517 *reinterpret_cast<DWORD*>(*ppbBuffer + *piBuffer) = cch;
450 *piBuffer += sizeof(SIZE_T); 518 *piBuffer += sizeof(DWORD);
451 519
452 // copy data to buffer 520 // copy data to buffer
453 err = memcpy_s(*ppbBuffer + *piBuffer, cb, scz, cb); 521 err = memcpy_s(*ppbBuffer + *piBuffer, cb, scz, cb);
@@ -474,30 +542,143 @@ extern "C" HRESULT BuffWriteStream(
474 Assert(pbStream); 542 Assert(pbStream);
475 543
476 HRESULT hr = S_OK; 544 HRESULT hr = S_OK;
477 SIZE_T cb = cbStream; 545 DWORD cb = 0;
478 errno_t err = 0; 546 errno_t err = 0;
479 547
548 if (cbStream > DWORD_MAX)
549 {
550 hr = E_INVALIDARG;
551 BuffExitOnRootFailure(hr, "Stream too large to write to buffer.");
552 }
553
554 cb = static_cast<DWORD>(cbStream);
555
480 // make sure we have a buffer with sufficient space 556 // make sure we have a buffer with sufficient space
481 hr = EnsureBufferSize(ppbBuffer, *piBuffer + cbStream + sizeof(SIZE_T)); 557 hr = EnsureBufferSize(ppbBuffer, *piBuffer + cbStream + sizeof(DWORD));
482 BuffExitOnFailure(hr, "Failed to ensure buffer size."); 558 BuffExitOnFailure(hr, "Failed to ensure buffer size.");
483 559
484 // copy byte count to buffer 560 // copy byte count to buffer
485 *(SIZE_T*)(*ppbBuffer + *piBuffer) = cb; 561 *reinterpret_cast<DWORD*>(*ppbBuffer + *piBuffer) = cb;
486 *piBuffer += sizeof(SIZE_T); 562 *piBuffer += sizeof(DWORD);
487 563
488 // copy data to buffer 564 if (cbStream)
489 err = memcpy_s(*ppbBuffer + *piBuffer, cbStream, pbStream, cbStream);
490 if (err)
491 { 565 {
492 BuffExitOnRootFailure(hr = E_INVALIDARG, "Failed to write stream to buffer, error: %d", err); 566 // copy data to buffer
493 } 567 err = memcpy_s(*ppbBuffer + *piBuffer, cbStream, pbStream, cbStream);
568 if (err)
569 {
570 BuffExitOnRootFailure(hr = E_INVALIDARG, "Failed to write stream to buffer, error: %d", err);
571 }
494 572
495 *piBuffer += cbStream; 573 *piBuffer += cbStream;
574 }
496 575
497LExit: 576LExit:
498 return hr; 577 return hr;
499} 578}
500 579
580// Buffer-based write functions
581
582extern "C" HRESULT BuffWriteNumberToBuffer(
583 __in BUFF_BUFFER* pBuffer,
584 __out DWORD dw
585 )
586{
587 return BuffWriteNumber(&pBuffer->pbData, &pBuffer->cbData, dw);
588}
589
590extern "C" HRESULT BuffWriteNumber64ToBuffer(
591 __in BUFF_BUFFER* pBuffer,
592 __out DWORD64 dw64
593 )
594{
595 return BuffWriteNumber64(&pBuffer->pbData, &pBuffer->cbData, dw64);
596}
597
598extern "C" HRESULT BuffWritePointerToBuffer(
599 __in BUFF_BUFFER* pBuffer,
600 __out DWORD_PTR dw
601 )
602{
603 return BuffWritePointer(&pBuffer->pbData, &pBuffer->cbData, dw);
604}
605
606extern "C" HRESULT BuffWriteStringToBuffer(
607 __in BUFF_BUFFER* pBuffer,
608 __in_z_opt LPCWSTR scz
609 )
610{
611 return BuffWriteString(&pBuffer->pbData, &pBuffer->cbData, scz);
612}
613
614extern "C" HRESULT BuffWriteStringAnsiToBuffer(
615 __in BUFF_BUFFER* pBuffer,
616 __in_z_opt LPCSTR scz
617 )
618{
619 return BuffWriteStringAnsi(&pBuffer->pbData, &pBuffer->cbData, scz);
620}
621
622extern "C" HRESULT BuffWriteStreamToBuffer(
623 __in BUFF_BUFFER* pBuffer,
624 __in_bcount(cbStream) const BYTE* pbStream,
625 __in SIZE_T cbStream
626 )
627{
628 return BuffWriteStream(&pBuffer->pbData, &pBuffer->cbData, pbStream, cbStream);
629}
630
631// Buffer Writer write functions
632
633extern "C" HRESULT BuffWriterWriteNumber(
634 __in BUFF_WRITER* pWriter,
635 __out DWORD dw
636 )
637{
638 return BuffWriteNumber(pWriter->ppbData, pWriter->pcbData, dw);
639}
640
641extern "C" HRESULT BuffWriterWriteNumber64(
642 __in BUFF_WRITER* pWriter,
643 __out DWORD64 dw64
644 )
645{
646 return BuffWriteNumber64(pWriter->ppbData, pWriter->pcbData, dw64);
647}
648
649extern "C" HRESULT BuffWriterWritePointer(
650 __in BUFF_WRITER* pWriter,
651 __out DWORD_PTR dw
652 )
653{
654 return BuffWritePointer(pWriter->ppbData, pWriter->pcbData, dw);
655}
656
657extern "C" HRESULT BuffWriterWriteString(
658 __in BUFF_WRITER* pWriter,
659 __in_z_opt LPCWSTR scz
660 )
661{
662 return BuffWriteString(pWriter->ppbData, pWriter->pcbData, scz);
663}
664
665extern "C" HRESULT BuffWriterWriteStringAnsi(
666 __in BUFF_WRITER* pWriter,
667 __in_z_opt LPCSTR scz
668 )
669{
670 return BuffWriteStringAnsi(pWriter->ppbData, pWriter->pcbData, scz);
671}
672
673extern "C" HRESULT BuffWriterWriteStream(
674 __in BUFF_WRITER* pWriter,
675 __in_bcount(cbStream) const BYTE* pbStream,
676 __in SIZE_T cbStream
677 )
678{
679 return BuffWriteStream(pWriter->ppbData, pWriter->pcbData, pbStream, cbStream);
680}
681
501 682
502// helper functions 683// helper functions
503 684