aboutsummaryrefslogtreecommitdiff
path: root/src/libs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2024-01-11 18:26:20 -0800
committerRob Mensching <rob@firegiant.com>2024-03-06 18:03:38 -0800
commit0d3d54992104288e9ee0c834d0b96e8502fd2d42 (patch)
tree9efa49c4983cd2ba1becab64bd1f2faccac88acf /src/libs
parent2824298d9dd817a47527c920363556b54ead5d5d (diff)
downloadwix-0d3d54992104288e9ee0c834d0b96e8502fd2d42.tar.gz
wix-0d3d54992104288e9ee0c834d0b96e8502fd2d42.tar.bz2
wix-0d3d54992104288e9ee0c834d0b96e8502fd2d42.zip
Move the BootstrapperApplication out of proc
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/buffutil.cpp271
-rw-r--r--src/libs/dutil/WixToolset.DUtil/dutil.cpp39
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/buffutil.h115
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/dlutil.h1
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/dutil.h7
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/pipeutil.h115
-rw-r--r--src/libs/dutil/WixToolset.DUtil/monutil.cpp12
-rw-r--r--src/libs/dutil/WixToolset.DUtil/pipeutil.cpp351
-rw-r--r--src/libs/dutil/WixToolset.DUtil/strutil.cpp32
-rw-r--r--src/libs/dutil/WixToolset.DUtil/thmutil.cpp4
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/PipeUtilTest.cpp21
11 files changed, 831 insertions, 137 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
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.cpp b/src/libs/dutil/WixToolset.DUtil/dutil.cpp
index 83b53f64..3f0d1658 100644
--- a/src/libs/dutil/WixToolset.DUtil/dutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/dutil.cpp
@@ -50,6 +50,19 @@ DAPI_(void) DutilUninitialize()
50 vpfnTraceErrorCallback = NULL; 50 vpfnTraceErrorCallback = NULL;
51} 51}
52 52
53
54DAPI_(HRESULT) DutilSizetToDword(SIZE_T sizet, DWORD* pdw)
55{
56 if (DWORD_MAX < sizet)
57 {
58 return E_INVALIDARG;
59 }
60
61 *pdw = static_cast<DWORD>(sizet);
62 return S_OK;
63}
64
65
53DAPI_(BOOL) DutilSuppressTraceErrorSource() 66DAPI_(BOOL) DutilSuppressTraceErrorSource()
54{ 67{
55 if (DWORD_MAX == vtdwSuppressTraceErrorSource) 68 if (DWORD_MAX == vtdwSuppressTraceErrorSource)
@@ -169,7 +182,7 @@ extern "C" void DAPI Dutil_AssertMsg(
169 DExitOnFailure(hr, "failed to concat string while building assert message"); 182 DExitOnFailure(hr, "failed to concat string while building assert message");
170 183
171 id = ::MessageBoxA(0, szMsg, "Debug Assert Message", 184 id = ::MessageBoxA(0, szMsg, "Debug Assert Message",
172 MB_SERVICE_NOTIFICATION | MB_TOPMOST | 185 MB_SERVICE_NOTIFICATION | MB_TOPMOST |
173 MB_DEFBUTTON2 | MB_ABORTRETRYIGNORE); 186 MB_DEFBUTTON2 | MB_ABORTRETRYIGNORE);
174 } 187 }
175 } 188 }
@@ -206,7 +219,7 @@ Dutil_Assert
206 219
207*******************************************************************/ 220*******************************************************************/
208extern "C" void DAPI Dutil_Assert( 221extern "C" void DAPI Dutil_Assert(
209 __in_z LPCSTR szFile, 222 __in_z LPCSTR szFile,
210 __in int iLine 223 __in int iLine
211 ) 224 )
212{ 225{
@@ -229,8 +242,8 @@ Dutil_AssertSz
229 242
230*******************************************************************/ 243*******************************************************************/
231extern "C" void DAPI Dutil_AssertSz( 244extern "C" void DAPI Dutil_AssertSz(
232 __in_z LPCSTR szFile, 245 __in_z LPCSTR szFile,
233 __in int iLine, 246 __in int iLine,
234 __in_z __format_string LPCSTR szMsg 247 __in_z __format_string LPCSTR szMsg
235 ) 248 )
236{ 249{
@@ -278,10 +291,10 @@ Dutil_Trace
278 291
279*******************************************************************/ 292*******************************************************************/
280extern "C" void DAPIV Dutil_Trace( 293extern "C" void DAPIV Dutil_Trace(
281 __in_z LPCSTR szFile, 294 __in_z LPCSTR szFile,
282 __in int iLine, 295 __in int iLine,
283 __in REPORT_LEVEL rl, 296 __in REPORT_LEVEL rl,
284 __in_z __format_string LPCSTR szFormat, 297 __in_z __format_string LPCSTR szFormat,
285 ... 298 ...
286 ) 299 )
287{ 300{
@@ -355,11 +368,11 @@ Dutil_TraceError
355 368
356*******************************************************************/ 369*******************************************************************/
357extern "C" void DAPIV Dutil_TraceError( 370extern "C" void DAPIV Dutil_TraceError(
358 __in_z LPCSTR szFile, 371 __in_z LPCSTR szFile,
359 __in int iLine, 372 __in int iLine,
360 __in REPORT_LEVEL rl, 373 __in REPORT_LEVEL rl,
361 __in HRESULT hrError, 374 __in HRESULT hrError,
362 __in_z __format_string LPCSTR szFormat, 375 __in_z __format_string LPCSTR szFormat,
363 ... 376 ...
364 ) 377 )
365{ 378{
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/buffutil.h b/src/libs/dutil/WixToolset.DUtil/inc/buffutil.h
index 322209e6..116b67bd 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/buffutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/buffutil.h
@@ -9,9 +9,35 @@ extern "C" {
9 9
10// macro definitions 10// macro definitions
11 11
12#define ReleaseBuffer ReleaseMem 12#define ReleaseBuffer(b) BuffFree(b)
13#define ReleaseNullBuffer ReleaseNullMem 13#define ReleaseNullBuffer(b) BuffFree(b)
14#define BuffFree MemFree 14#define BuffFree(b) if (b.pbData) { MemFree(b.pbData); b.pbData = NULL; } b.cbData = 0
15
16
17// structs
18
19// A buffer that owns its data and must be freed with BuffFree().
20typedef struct _BUFF_BUFFER
21{
22 LPBYTE pbData;
23 SIZE_T cbData;
24} BUFF_BUFFER;
25
26// A read-only buffer with internal pointer that can be advanced for multiple reads.
27typedef struct _BUFF_READER
28{
29 LPCBYTE pbData;
30 SIZE_T cbData;
31
32 SIZE_T iBuffer;
33} BUFF_READER;
34
35// A write buffer that does not own its data.
36typedef struct _BUFF_WRITER
37{
38 LPBYTE *ppbData;
39 SIZE_T *pcbData;
40} BUFF_WRITER;
15 41
16 42
17// function declarations 43// function declarations
@@ -53,6 +79,37 @@ HRESULT BuffReadStream(
53 __deref_inout_bcount(*pcbStream) BYTE** ppbStream, 79 __deref_inout_bcount(*pcbStream) BYTE** ppbStream,
54 __out SIZE_T* pcbStream 80 __out SIZE_T* pcbStream
55 ); 81 );
82HRESULT BuffSkipExtraData(
83 __in SIZE_T cbExpectedSize,
84 __in SIZE_T cbActualSize,
85 __inout SIZE_T* piBuffer
86 );
87
88HRESULT BuffReaderReadNumber(
89 __in BUFF_READER* pReader,
90 __out DWORD* pdw
91 );
92HRESULT BuffReaderReadNumber64(
93 __in BUFF_READER* pReader,
94 __out DWORD64* pdw64
95 );
96HRESULT BuffReaderReadPointer(
97 __in BUFF_READER* pReader,
98 __out DWORD_PTR* pdw
99);
100HRESULT BuffReaderReadString(
101 __in BUFF_READER* pReader,
102 __deref_out_z LPWSTR* pscz
103 );
104HRESULT BuffReaderReadStringAnsi(
105 __in BUFF_READER* pReader,
106 __deref_out_z LPSTR* pscz
107 );
108HRESULT BuffReaderReadStream(
109 __in BUFF_READER* pReader,
110 __deref_inout_bcount(*pcbStream) BYTE** ppbStream,
111 __out SIZE_T* pcbStream
112 );
56 113
57HRESULT BuffWriteNumber( 114HRESULT BuffWriteNumber(
58 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer, 115 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer,
@@ -86,6 +143,58 @@ HRESULT BuffWriteStream(
86 __in SIZE_T cbStream 143 __in SIZE_T cbStream
87 ); 144 );
88 145
146HRESULT BuffWriteNumberToBuffer(
147 __in BUFF_BUFFER* pBuffer,
148 __in DWORD dw
149 );
150HRESULT BuffWriteNumber64ToBuffer(
151 __in BUFF_BUFFER* pBuffer,
152 __in DWORD64 dw64
153 );
154HRESULT BuffWritePointerToBuffer(
155 __in BUFF_BUFFER* pBuffer,
156 __in DWORD_PTR dw
157 );
158HRESULT BuffWriteStringToBuffer(
159 __in BUFF_BUFFER* pBuffer,
160 __in_z_opt LPCWSTR scz
161 );
162HRESULT BuffWriteStringAnsiToBuffer(
163 __in BUFF_BUFFER* pBuffer,
164 __in_z_opt LPCSTR scz
165 );
166HRESULT BuffWriteStreamToBuffer(
167 __in BUFF_BUFFER* pBuffer,
168 __in_bcount(cbStream) const BYTE* pbStream,
169 __in SIZE_T cbStream
170 );
171
172HRESULT BuffWriterWriteNumber(
173 __in BUFF_WRITER* pWriter,
174 __in DWORD dw
175 );
176HRESULT BuffWriterWriteNumber64(
177 __in BUFF_WRITER* pWriter,
178 __in DWORD64 dw64
179 );
180HRESULT BuffWriterWritePointer(
181 __in BUFF_WRITER* pWriter,
182 __in DWORD_PTR dw
183 );
184HRESULT BuffWriterWriteString(
185 __in BUFF_WRITER* pWriter,
186 __in_z_opt LPCWSTR scz
187 );
188HRESULT BuffWriterWriteStringAnsi(
189 __in BUFF_WRITER* pWriter,
190 __in_z_opt LPCSTR scz
191 );
192HRESULT BuffWriterWriteStream(
193 __in BUFF_WRITER* pWriter,
194 __in_bcount(cbStream) const BYTE* pbStream,
195 __in SIZE_T cbStream
196 );
197
89#ifdef __cplusplus 198#ifdef __cplusplus
90} 199}
91#endif 200#endif
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/dlutil.h b/src/libs/dutil/WixToolset.DUtil/inc/dlutil.h
index 3e95103a..912c2732 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/dlutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/dlutil.h
@@ -27,6 +27,7 @@ typedef struct _DOWNLOAD_SOURCE
27 LPWSTR sczUrl; 27 LPWSTR sczUrl;
28 LPWSTR sczUser; 28 LPWSTR sczUser;
29 LPWSTR sczPassword; 29 LPWSTR sczPassword;
30 LPWSTR sczAuthorizationHeader;
30} DOWNLOAD_SOURCE; 31} DOWNLOAD_SOURCE;
31 32
32typedef struct _DOWNLOAD_CACHE_CALLBACK 33typedef struct _DOWNLOAD_CACHE_CALLBACK
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/dutil.h b/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
index 4a172f46..7d8c7d81 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
@@ -41,6 +41,13 @@ HRESULT DAPI DutilInitialize(
41*******************************************************************/ 41*******************************************************************/
42void DAPI DutilUninitialize(); 42void DAPI DutilUninitialize();
43 43
44/*******************************************************************
45 DutilSizetToDword - safely convert SIZE_T to DWORD.
46
47 Returns
48 E_INVALIDARG - If SIZE_T value is greater than DWORD_MAX.
49********************************************************************/
50HRESULT DAPI DutilSizetToDword(SIZE_T sizet, DWORD* pdw);
44 51
45/******************************************************************** 52/********************************************************************
46 DutilSuppressTraceErrorSource - tells dutil to skip calling 53 DutilSuppressTraceErrorSource - tells dutil to skip calling
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/pipeutil.h b/src/libs/dutil/WixToolset.DUtil/inc/pipeutil.h
index d16d768c..e92462d2 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/pipeutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/pipeutil.h
@@ -6,7 +6,9 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9#define ReleasePipeHandle(h) if (h != INVALID_HANDLE_VALUE) { ::CloseHandle(h); } 9// macro definitions
10
11#define ReleasePipeHandle(h) if (h != INVALID_HANDLE_VALUE) { ::CloseHandle(h); h = INVALID_HANDLE_VALUE; }
10#define ReleasePipeMessage(pMsg) if (pMsg) { PipeFreeMessage(pMsg); } 12#define ReleasePipeMessage(pMsg) if (pMsg) { PipeFreeMessage(pMsg); }
11 13
12 14
@@ -27,6 +29,23 @@ typedef struct _PIPE_MESSAGE
27 LPVOID pvData; 29 LPVOID pvData;
28} PIPE_MESSAGE; 30} PIPE_MESSAGE;
29 31
32typedef struct _PIPE_RPC_HANDLE
33{
34 HANDLE hPipe;
35 CRITICAL_SECTION cs;
36
37 BOOL fInitialized;
38 BOOL fOwnHandle;
39} PIPE_RPC_HANDLE;
40
41typedef struct _PIPE_RPC_RESULT
42{
43 HRESULT hr;
44
45 DWORD cbData;
46 LPBYTE pbData;
47} PIPE_RPC_RESULT;
48
30 49
31// functions 50// functions
32 51
@@ -72,17 +91,87 @@ DAPI_(HRESULT) PipeReadMessage(
72); 91);
73 92
74/******************************************************************* 93/*******************************************************************
75 PipeWriteMessage - writes a message to the pipe. 94 PipeRpcInitiailize - initializes a RPC pipe handle from a pipe handle.
76 95
77*******************************************************************/ 96*******************************************************************/
78DAPI_(HRESULT) PipeWriteMessage( 97DAPI_(void) PipeRpcInitialize(
98 __in PIPE_RPC_HANDLE* phRpcPipe,
79 __in HANDLE hPipe, 99 __in HANDLE hPipe,
100 __in BOOL fTakeHandleOwnership
101);
102
103/*******************************************************************
104 PipeRpcInitialized - checks if a RPC pipe handle is initialized.
105
106*******************************************************************/
107DAPI_(BOOL) PipeRpcInitialized(
108 __in PIPE_RPC_HANDLE* phRpcPipe
109);
110
111/*******************************************************************
112 PipeRpcUninitiailize - uninitializes a RPC pipe handle.
113
114*******************************************************************/
115DAPI_(void) PipeRpcUninitiailize(
116 __in PIPE_RPC_HANDLE* phRpcPipe
117);
118
119/*******************************************************************
120 PipeRpcReadMessage - reads a message from the pipe. Free with
121 PipeFreeMessage().
122
123*******************************************************************/
124DAPI_(HRESULT) PipeRpcReadMessage(
125 __in PIPE_RPC_HANDLE* phRpcPipe,
126 __in PIPE_MESSAGE* pMsg
127);
128
129/*******************************************************************
130 PipeRpcRequest - sends message and reads a response over the pipe.
131 Free with PipeFreeRpcResult().
132
133*******************************************************************/
134DAPI_(HRESULT) PipeRpcRequest(
135 __in PIPE_RPC_HANDLE* phRpcPipe,
136 __in DWORD dwMessageType,
137 __in_bcount(cbArgs) LPVOID pbArgs,
138 __in SIZE_T cbArgs,
139 __in PIPE_RPC_RESULT* pResult
140);
141
142/*******************************************************************
143 PipeRpcResponse - sends response over the pipe.
144
145*******************************************************************/
146DAPI_(HRESULT) PipeRpcResponse(
147 __in PIPE_RPC_HANDLE* phPipe,
148 __in DWORD dwMessageType,
149 __in HRESULT hrResult,
150 __in_bcount(cbResult) LPVOID pvResult,
151 __in SIZE_T cbResult
152 );
153
154/*******************************************************************
155 PipeRpcWriteMessage - writes a message to the pipe.
156
157*******************************************************************/
158DAPI_(HRESULT) PipeRpcWriteMessage(
159 __in PIPE_RPC_HANDLE* phPipe,
80 __in DWORD dwMessageType, 160 __in DWORD dwMessageType,
81 __in_bcount_opt(cbData) LPVOID pvData, 161 __in_bcount_opt(cbData) LPVOID pvData,
82 __in SIZE_T cbData 162 __in SIZE_T cbData
83); 163);
84 164
85/******************************************************************* 165/*******************************************************************
166 PipeWriteDisconnect - writes a message to the pipe indicating the
167 client should disconnect.
168
169*******************************************************************/
170DAPI_(HRESULT) PipeWriteDisconnect(
171 __in HANDLE hPipe
172 );
173
174/*******************************************************************
86 PipeFreeMessage - frees any memory allocated in PipeReadMessage. 175 PipeFreeMessage - frees any memory allocated in PipeReadMessage.
87 176
88*******************************************************************/ 177*******************************************************************/
@@ -91,14 +180,34 @@ DAPI_(void) PipeFreeMessage(
91); 180);
92 181
93/******************************************************************* 182/*******************************************************************
183 PipeFreeRpcResult - frees any memory allocated in PipeRpcRequest.
184
185*******************************************************************/
186DAPI_(void) PipeFreeRpcResult(
187 __in PIPE_RPC_RESULT* pResult
188);
189
190/*******************************************************************
94 PipeServerWaitForClientConnect - Called from the server process to 191 PipeServerWaitForClientConnect - Called from the server process to
95 wait for a client to connect back to the provided pipe. 192 wait for a client to connect back to the provided pipe.
96 193
97*******************************************************************/ 194*******************************************************************/
98DAPI_(HRESULT) PipeServerWaitForClientConnect( 195DAPI_(HRESULT) PipeServerWaitForClientConnect(
196 __in HANDLE hClientProcess,
99 __in HANDLE hPipe 197 __in HANDLE hPipe
100); 198);
101 199
200/*******************************************************************
201 PipeWriteMessage - writes a message to the pipe.
202
203*******************************************************************/
204DAPI_(HRESULT) PipeWriteMessage(
205 __in HANDLE hPipe,
206 __in DWORD dwMessageType,
207 __in_bcount_opt(cbData) LPVOID pvData,
208 __in SIZE_T cbData
209);
210
102#ifdef __cplusplus 211#ifdef __cplusplus
103} 212}
104#endif 213#endif
diff --git a/src/libs/dutil/WixToolset.DUtil/monutil.cpp b/src/libs/dutil/WixToolset.DUtil/monutil.cpp
index d7bcfa52..b42332ef 100644
--- a/src/libs/dutil/WixToolset.DUtil/monutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/monutil.cpp
@@ -1209,7 +1209,7 @@ static DWORD WINAPI WaiterThread(
1209 1209
1210 ZeroMemory(rgfProcessedIndex, sizeof(rgfProcessedIndex)); 1210 ZeroMemory(rgfProcessedIndex, sizeof(rgfProcessedIndex));
1211 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i) 1211 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i)
1212 { 1212 {
1213 if (rgfProcessedIndex[i]) 1213 if (rgfProcessedIndex[i])
1214 { 1214 {
1215 // if we already processed this item due to UpdateWaitStatus swapping array indices, then skip it 1215 // if we already processed this item due to UpdateWaitStatus swapping array indices, then skip it
@@ -1244,7 +1244,7 @@ static DWORD WINAPI WaiterThread(
1244 1244
1245 ZeroMemory(rgfProcessedIndex, sizeof(rgfProcessedIndex)); 1245 ZeroMemory(rgfProcessedIndex, sizeof(rgfProcessedIndex));
1246 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i) 1246 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i)
1247 { 1247 {
1248 if (rgfProcessedIndex[i]) 1248 if (rgfProcessedIndex[i])
1249 { 1249 {
1250 // if we already processed this item due to UpdateWaitStatus swapping array indices, then skip it 1250 // if we already processed this item due to UpdateWaitStatus swapping array indices, then skip it
@@ -1279,7 +1279,7 @@ static DWORD WINAPI WaiterThread(
1279 1279
1280 ZeroMemory(rgfProcessedIndex, sizeof(rgfProcessedIndex)); 1280 ZeroMemory(rgfProcessedIndex, sizeof(rgfProcessedIndex));
1281 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i) 1281 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i)
1282 { 1282 {
1283 if (rgfProcessedIndex[i]) 1283 if (rgfProcessedIndex[i])
1284 { 1284 {
1285 // if we already processed this item due to UpdateWaitStatus swapping array indices, then skip it 1285 // if we already processed this item due to UpdateWaitStatus swapping array indices, then skip it
@@ -1308,7 +1308,7 @@ static DWORD WINAPI WaiterThread(
1308 case MON_MESSAGE_DRIVE_STATUS_UPDATE: 1308 case MON_MESSAGE_DRIVE_STATUS_UPDATE:
1309 ZeroMemory(rgfProcessedIndex, sizeof(rgfProcessedIndex)); 1309 ZeroMemory(rgfProcessedIndex, sizeof(rgfProcessedIndex));
1310 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i) 1310 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i)
1311 { 1311 {
1312 if (rgfProcessedIndex[i]) 1312 if (rgfProcessedIndex[i])
1313 { 1313 {
1314 // if we already processed this item due to UpdateWaitStatus swapping array indices, then skip it 1314 // if we already processed this item due to UpdateWaitStatus swapping array indices, then skip it
@@ -1349,7 +1349,7 @@ static DWORD WINAPI WaiterThread(
1349 if (pInternalWait->dwSendIteration == static_cast<DWORD>(msg.lParam)) 1349 if (pInternalWait->dwSendIteration == static_cast<DWORD>(msg.lParam))
1350 { 1350 {
1351 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i) 1351 for (DWORD i = 0; i < pWaiterContext->cRequests; ++i)
1352 { 1352 {
1353 if (MON_DIRECTORY == pWaiterContext->rgRequests[i].type && pWaiterContext->rgHandles[i + 1] == reinterpret_cast<HANDLE>(pInternalWait->pvContext)) 1353 if (MON_DIRECTORY == pWaiterContext->rgRequests[i].type && pWaiterContext->rgHandles[i + 1] == reinterpret_cast<HANDLE>(pInternalWait->pvContext))
1354 { 1354 {
1355 // Release handles ASAP so the remove request will succeed 1355 // Release handles ASAP so the remove request will succeed
@@ -1878,7 +1878,7 @@ static HRESULT CreateMonWindow(
1878 } 1878 }
1879 1879
1880 *pHwnd = ::CreateWindowExW(0, wc.lpszClassName, L"", 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, HWND_DESKTOP, NULL, wc.hInstance, pm); 1880 *pHwnd = ::CreateWindowExW(0, wc.lpszClassName, L"", 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, HWND_DESKTOP, NULL, wc.hInstance, pm);
1881 MonExitOnNullWithLastError(*pHwnd, hr, "Failed to create window."); 1881 MonExitOnNullWithLastError(*pHwnd, hr, "Failed to create monitor window.");
1882 1882
1883 // Rumor has it that drive arrival / removal events can be lost in the rare event that some other application higher up in z-order is hanging if we don't make our window topmost 1883 // Rumor has it that drive arrival / removal events can be lost in the rare event that some other application higher up in z-order is hanging if we don't make our window topmost
1884 // SWP_NOACTIVATE is important so the currently active window doesn't lose focus 1884 // SWP_NOACTIVATE is important so the currently active window doesn't lose focus
diff --git a/src/libs/dutil/WixToolset.DUtil/pipeutil.cpp b/src/libs/dutil/WixToolset.DUtil/pipeutil.cpp
index 4aa69d56..8d0a5ed0 100644
--- a/src/libs/dutil/WixToolset.DUtil/pipeutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/pipeutil.cpp
@@ -5,7 +5,7 @@
5 5
6static const DWORD PIPE_64KB = 64 * 1024; 6static const DWORD PIPE_64KB = 64 * 1024;
7static const LPCWSTR PIPE_NAME_FORMAT_STRING = L"\\\\.\\pipe\\%ls"; 7static const LPCWSTR PIPE_NAME_FORMAT_STRING = L"\\\\.\\pipe\\%ls";
8 8static const DWORD PIPE_MESSAGE_DISCONNECT = 0xFFFFFFFF;
9 9
10// Exit macros 10// Exit macros
11#define PipeExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_PIPEUTIL, x, s, __VA_ARGS__) 11#define PipeExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_PIPEUTIL, x, s, __VA_ARGS__)
@@ -113,8 +113,19 @@ DAPI_(void) PipeFreeMessage(
113 ReleaseNullMem(pMsg->pvData); 113 ReleaseNullMem(pMsg->pvData);
114 pMsg->fAllocatedData = FALSE; 114 pMsg->fAllocatedData = FALSE;
115 } 115 }
116
117 ZeroMemory(pMsg, sizeof(PIPE_MESSAGE));
116} 118}
117 119
120DAPI_(void) PipeFreeRpcResult(
121 __in PIPE_RPC_RESULT* pResult
122)
123{
124 if (pResult->pbData)
125 {
126 ReleaseNullMem(pResult->pbData);
127 }
128}
118 129
119DAPI_(HRESULT) PipeOpen( 130DAPI_(HRESULT) PipeOpen(
120 __in_z LPCWSTR wzName, 131 __in_z LPCWSTR wzName,
@@ -166,39 +177,281 @@ DAPI_(HRESULT) PipeReadMessage(
166) 177)
167{ 178{
168 HRESULT hr = S_OK; 179 HRESULT hr = S_OK;
169 BYTE pbMessageIdAndByteCount[sizeof(DWORD) + sizeof(DWORD)] = { }; 180 DWORD rgdwMessageIdAndByteCount[2] = { };
181 LPBYTE pbData = NULL;
182 DWORD cbData = 0;
170 183
171 hr = FileReadHandle(hPipe, pbMessageIdAndByteCount, sizeof(pbMessageIdAndByteCount)); 184 hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(rgdwMessageIdAndByteCount), sizeof(rgdwMessageIdAndByteCount));
172 if (HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE) == hr) 185 if (HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE) == hr)
173 { 186 {
174 memset(pbMessageIdAndByteCount, 0, sizeof(pbMessageIdAndByteCount)); 187 memset(rgdwMessageIdAndByteCount, 0, sizeof(rgdwMessageIdAndByteCount));
175 hr = S_FALSE; 188 hr = S_FALSE;
176 } 189 }
177 PipeExitOnFailure(hr, "Failed to read message from pipe."); 190 PipeExitOnFailure(hr, "Failed to read message from pipe.");
178 191
179 pMsg->dwMessageType = *(DWORD*)(pbMessageIdAndByteCount); 192 Trace(REPORT_STANDARD, "RPC pipe %p read message: %u recv cbData: %u", hPipe, rgdwMessageIdAndByteCount[0], rgdwMessageIdAndByteCount[1]);
180 pMsg->cbData = *(DWORD*)(pbMessageIdAndByteCount + sizeof(DWORD)); 193
181 if (pMsg->cbData) 194 cbData = rgdwMessageIdAndByteCount[1];
195 if (cbData)
182 { 196 {
183 pMsg->pvData = MemAlloc(pMsg->cbData, FALSE); 197 pbData = reinterpret_cast<LPBYTE>(MemAlloc(cbData, FALSE));
184 PipeExitOnNull(pMsg->pvData, hr, E_OUTOFMEMORY, "Failed to allocate data for message."); 198 PipeExitOnNull(pbData, hr, E_OUTOFMEMORY, "Failed to allocate data for message.");
185 199
186 hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(pMsg->pvData), pMsg->cbData); 200 hr = FileReadHandle(hPipe, pbData, cbData);
187 PipeExitOnFailure(hr, "Failed to read data for message."); 201 PipeExitOnFailure(hr, "Failed to read data for message.");
202 }
203
204 pMsg->dwMessageType = rgdwMessageIdAndByteCount[0];
205 pMsg->cbData = cbData;
206 pMsg->pvData = pbData;
207 pbData = NULL;
208
209 if (PIPE_MESSAGE_DISCONNECT == pMsg->dwMessageType)
210 {
211 hr = S_FALSE;
212 }
213
214LExit:
215 ReleaseMem(pbData);
216
217 return hr;
218}
219
220DAPI_(void) PipeRpcInitialize(
221 __in PIPE_RPC_HANDLE* phRpcPipe,
222 __in HANDLE hPipe,
223 __in BOOL fTakeHandleOwnership
224)
225{
226 phRpcPipe->hPipe = hPipe;
227 if (phRpcPipe->hPipe != INVALID_HANDLE_VALUE)
228 {
229 ::InitializeCriticalSection(&phRpcPipe->cs);
230 phRpcPipe->fOwnHandle = fTakeHandleOwnership;
231 phRpcPipe->fInitialized = TRUE;
232 }
233}
234
235DAPI_(BOOL) PipeRpcInitialized(
236 __in PIPE_RPC_HANDLE* phRpcPipe
237)
238{
239 return phRpcPipe->fInitialized && phRpcPipe->hPipe != INVALID_HANDLE_VALUE;
240}
241
242DAPI_(void) PipeRpcUninitiailize(
243 __in PIPE_RPC_HANDLE* phRpcPipe
244)
245{
246 if (phRpcPipe->fInitialized)
247 {
248 ::DeleteCriticalSection(&phRpcPipe->cs);
249
250 if (phRpcPipe->fOwnHandle)
251 {
252 ::CloseHandle(phRpcPipe->hPipe);
253 }
254
255 phRpcPipe->hPipe = INVALID_HANDLE_VALUE;
256 phRpcPipe->fOwnHandle = FALSE;
257 phRpcPipe->fInitialized = FALSE;
258 }
259}
260
261DAPI_(HRESULT) PipeRpcReadMessage(
262 __in PIPE_RPC_HANDLE* phRpcPipe,
263 __in PIPE_MESSAGE* pMsg
264)
265{
266 HRESULT hr = S_OK;
267
268 ::EnterCriticalSection(&phRpcPipe->cs);
269
270 hr = PipeReadMessage(phRpcPipe->hPipe, pMsg);
271 PipeExitOnFailure(hr, "Failed to read message from RPC pipe.");
272
273LExit:
274 ::LeaveCriticalSection(&phRpcPipe->cs);
275
276 return hr;
277}
278
279DAPI_(HRESULT) PipeRpcRequest(
280 __in PIPE_RPC_HANDLE* phRpcPipe,
281 __in DWORD dwMessageType,
282 __in_bcount(cbArgs) LPVOID pvArgs,
283 __in SIZE_T cbArgs,
284 __in PIPE_RPC_RESULT* pResult
285)
286{
287 HRESULT hr = S_OK;
288 HANDLE hPipe = phRpcPipe->hPipe;
289 BOOL fLocked = FALSE;
290 DWORD rgResultAndDataSize[2] = { };
291 DWORD cbData = 0;
292 LPBYTE pbData = NULL;
293
294 if (hPipe == INVALID_HANDLE_VALUE)
295 {
296 ExitFunction();
297 }
298
299 Trace(REPORT_STANDARD, "RPC pipe %p request message: %d send cbArgs: %u", hPipe, dwMessageType, cbArgs);
300
301 ::EnterCriticalSection(&phRpcPipe->cs);
302 fLocked = TRUE;
303
304 // Send the message.
305 hr = PipeRpcWriteMessage(phRpcPipe, dwMessageType, pvArgs, cbArgs);
306 PipeExitOnFailure(hr, "Failed to send RPC pipe request.");
307
308 // Read the result and size of response data.
309 hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(rgResultAndDataSize), sizeof(rgResultAndDataSize));
310 PipeExitOnFailure(hr, "Failed to read result and size of message.");
311
312 pResult->hr = rgResultAndDataSize[0];
313 cbData = rgResultAndDataSize[1];
314
315 Trace(REPORT_STANDARD, "RPC pipe %p request message: %d returned hr: 0x%x, cbData: %u", hPipe, dwMessageType, pResult->hr, cbData);
316 AssertSz(FAILED(pResult->hr) || pResult->hr == S_OK || pResult->hr == S_FALSE, "Unexpected HRESULT from RPC pipe request.");
317
318 if (cbData)
319 {
320 pbData = reinterpret_cast<LPBYTE>(MemAlloc(cbData, TRUE));
321 PipeExitOnNull(pbData, hr, E_OUTOFMEMORY, "Failed to allocate memory for RPC pipe results.");
322
323 hr = FileReadHandle(hPipe, pbData, cbData);
324 PipeExitOnFailure(hr, "Failed to read result data.");
325 }
326
327 pResult->cbData = cbData;
328 pResult->pbData = pbData;
329 pbData = NULL;
330
331 hr = pResult->hr;
332 PipeExitOnFailure(hr, "RPC pipe client reported failure.");
333
334LExit:
335 ReleaseMem(pbData);
336
337 if (fLocked)
338 {
339 ::LeaveCriticalSection(&phRpcPipe->cs);
340 }
341
342 return hr;
343}
344
345DAPI_(HRESULT) PipeRpcResponse(
346 __in PIPE_RPC_HANDLE* phRpcPipe,
347 __in DWORD
348#if DEBUG
349 dwMessageType
350#endif
351 ,
352 __in HRESULT hrResult,
353 __in_bcount(cbResult) LPVOID pvResult,
354 __in SIZE_T cbResult
355 )
356{
357 HRESULT hr = S_OK;
358 HANDLE hPipe = phRpcPipe->hPipe;
359 DWORD dwcbResult = 0;
360
361 hr = DutilSizetToDword(pvResult ? cbResult : 0, &dwcbResult);
362 PipeExitOnFailure(hr, "Pipe message is too large.");
363
364 Trace(REPORT_STANDARD, "RPC pipe %p response message: %d returned hr: 0x%x, cbResult: %u", hPipe, dwMessageType, hrResult, dwcbResult);
188 365
189 pMsg->fAllocatedData = TRUE; 366 ::EnterCriticalSection(&phRpcPipe->cs);
367
368 hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(&hrResult), sizeof(hrResult));
369 PipeExitOnFailure(hr, "Failed to write RPC result code to pipe.");
370
371 hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(&dwcbResult), sizeof(dwcbResult));
372 PipeExitOnFailure(hr, "Failed to write RPC result size to pipe.");
373
374 if (dwcbResult)
375 {
376 hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(pvResult), dwcbResult);
377 PipeExitOnFailure(hr, "Failed to write RPC result data to pipe.");
190 } 378 }
191 379
192LExit: 380LExit:
193 if (!pMsg->fAllocatedData && pMsg->pvData) 381 ::LeaveCriticalSection(&phRpcPipe->cs);
382
383 return hr;
384}
385
386DAPI_(HRESULT) PipeRpcWriteMessage(
387 __in PIPE_RPC_HANDLE* phRpcPipe,
388 __in DWORD dwMessageType,
389 __in_bcount_opt(cbData) LPVOID pvData,
390 __in SIZE_T cbData
391)
392{
393 HRESULT hr = S_OK;
394
395 ::EnterCriticalSection(&phRpcPipe->cs);
396
397 hr = PipeWriteMessage(phRpcPipe->hPipe, dwMessageType, pvData, cbData);
398 PipeExitOnFailure(hr, "Failed to write message type to RPC pipe.");
399
400LExit:
401 ::LeaveCriticalSection(&phRpcPipe->cs);
402
403 return hr;
404}
405
406DAPI_(HRESULT) PipeRpcWriteMessageReadResponse(
407 __in PIPE_RPC_HANDLE* phRpcPipe,
408 __in DWORD dwMessageType,
409 __in_bcount_opt(cbData) LPBYTE pbArgData,
410 __in SIZE_T cbArgData,
411 __in PIPE_RPC_RESULT* pResult
412)
413{
414 HRESULT hr = S_OK;
415 DWORD rgResultAndSize[2] = { };
416 LPBYTE pbResultData = NULL;
417 DWORD cbResultData = 0;
418
419 hr = PipeWriteMessage(phRpcPipe->hPipe, dwMessageType, pbArgData, cbArgData);
420 PipeExitOnFailure(hr, "Failed to write message type to RPC pipe.");
421
422 // Read the result and size of response.
423 hr = FileReadHandle(phRpcPipe->hPipe, reinterpret_cast<LPBYTE>(rgResultAndSize), sizeof(rgResultAndSize));
424 ExitOnFailure(hr, "Failed to read result and size of message.");
425
426 pResult->hr = rgResultAndSize[0];
427 cbResultData = rgResultAndSize[1];
428
429 if (cbResultData)
194 { 430 {
195 MemFree(pMsg->pvData); 431 pbResultData = reinterpret_cast<LPBYTE>(MemAlloc(cbResultData, TRUE));
432 ExitOnNull(pbResultData, hr, E_OUTOFMEMORY, "Failed to allocate memory for BA results.");
433
434 hr = FileReadHandle(phRpcPipe->hPipe, pbResultData, cbResultData);
435 ExitOnFailure(hr, "Failed to read result and size of message.");
196 } 436 }
197 437
438 pResult->cbData = cbResultData;
439 pResult->pbData = pbResultData;
440 pbResultData = NULL;
441
442 hr = pResult->hr;
443 ExitOnFailure(hr, "BA reported failure.");
444
445LExit:
446 ReleaseMem(pbResultData);
447
448 ::LeaveCriticalSection(&phRpcPipe->cs);
449
198 return hr; 450 return hr;
199} 451}
200 452
201DAPI_(HRESULT) PipeServerWaitForClientConnect( 453DAPI_(HRESULT) PipeServerWaitForClientConnect(
454 __in HANDLE hClientProcess,
202 __in HANDLE hPipe 455 __in HANDLE hPipe
203) 456)
204{ 457{
@@ -206,13 +459,13 @@ DAPI_(HRESULT) PipeServerWaitForClientConnect(
206 DWORD dwPipeState = PIPE_READMODE_BYTE | PIPE_NOWAIT; 459 DWORD dwPipeState = PIPE_READMODE_BYTE | PIPE_NOWAIT;
207 460
208 // Temporarily make the pipe non-blocking so we will not get stuck in ::ConnectNamedPipe() forever 461 // Temporarily make the pipe non-blocking so we will not get stuck in ::ConnectNamedPipe() forever
209 // if the child decides not to show up. 462 // if the client decides not to show up.
210 if (!::SetNamedPipeHandleState(hPipe, &dwPipeState, NULL, NULL)) 463 if (!::SetNamedPipeHandleState(hPipe, &dwPipeState, NULL, NULL))
211 { 464 {
212 PipeExitWithLastError(hr, "Failed to set pipe to non-blocking."); 465 PipeExitWithLastError(hr, "Failed to set pipe to non-blocking.");
213 } 466 }
214 467
215 // Loop for a while waiting for a connection from child process. 468 // Loop for a while waiting for a connection from client process.
216 DWORD cRetry = 0; 469 DWORD cRetry = 0;
217 do 470 do
218 { 471 {
@@ -237,7 +490,19 @@ DAPI_(HRESULT) PipeServerWaitForClientConnect(
237 } 490 }
238 491
239 ++cRetry; 492 ++cRetry;
240 ::Sleep(PIPE_WAIT_FOR_CONNECTION); 493
494 // Ensure the client is still around.
495 hr = ::AppWaitForSingleObject(hClientProcess, PIPE_WAIT_FOR_CONNECTION);
496 if (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr)
497 {
498 // Timeout out means the process is still there, that's good.
499 hr = HRESULT_FROM_WIN32(ERROR_PIPE_LISTENING);
500 }
501 else if (SUCCEEDED(hr))
502 {
503 // Success means the process is gone, that's bad.
504 hr = HRESULT_FROM_WIN32(WAIT_ABANDONED);
505 }
241 } 506 }
242 else 507 else
243 { 508 {
@@ -259,6 +524,26 @@ LExit:
259 return hr; 524 return hr;
260} 525}
261 526
527DAPI_(HRESULT) PipeWriteDisconnect(
528 __in HANDLE hPipe
529 )
530{
531 HRESULT hr = S_OK;
532 LPVOID pv = NULL;
533 SIZE_T cb = 0;
534
535 hr = AllocatePipeMessage(PIPE_MESSAGE_DISCONNECT, NULL, 0, &pv, &cb);
536 ExitOnFailure(hr, "Failed to allocate message to write.");
537
538 // Write the message.
539 hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(pv), cb);
540 ExitOnFailure(hr, "Failed to write message type to pipe.");
541
542LExit:
543 ReleaseMem(pv);
544 return hr;
545}
546
262DAPI_(HRESULT) PipeWriteMessage( 547DAPI_(HRESULT) PipeWriteMessage(
263 __in HANDLE hPipe, 548 __in HANDLE hPipe,
264 __in DWORD dwMessageType, 549 __in DWORD dwMessageType,
@@ -266,22 +551,6 @@ DAPI_(HRESULT) PipeWriteMessage(
266 __in SIZE_T cbData 551 __in SIZE_T cbData
267) 552)
268{ 553{
269// HRESULT hr = S_OK;
270//
271// hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(&dwMessageType), sizeof(dwMessageType));
272// PipeExitOnFailure(hr, "Failed to write message id to pipe.");
273//
274// hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(&cbData), sizeof(cbData));
275// PipeExitOnFailure(hr, "Failed to write message data size to pipe.");
276//
277// if (pvData && cbData)
278// {
279// hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(pvData), cbData);
280// PipeExitOnFailure(hr, "Failed to write message data to pipe.");
281// }
282//
283//LExit:
284// return hr;
285 HRESULT hr = S_OK; 554 HRESULT hr = S_OK;
286 LPVOID pv = NULL; 555 LPVOID pv = NULL;
287 SIZE_T cb = 0; 556 SIZE_T cb = 0;
@@ -295,6 +564,7 @@ DAPI_(HRESULT) PipeWriteMessage(
295 564
296LExit: 565LExit:
297 ReleaseMem(pv); 566 ReleaseMem(pv);
567
298 return hr; 568 return hr;
299} 569}
300 570
@@ -302,7 +572,7 @@ static HRESULT AllocatePipeMessage(
302 __in DWORD dwMessageType, 572 __in DWORD dwMessageType,
303 __in_bcount_opt(cbData) LPVOID pvData, 573 __in_bcount_opt(cbData) LPVOID pvData,
304 __in SIZE_T cbData, 574 __in SIZE_T cbData,
305 __out_bcount(cb) LPVOID* ppvMessage, 575 __out_bcount(*pcbMessage) LPVOID* ppvMessage,
306 __out SIZE_T* pcbMessage 576 __out SIZE_T* pcbMessage
307) 577)
308{ 578{
@@ -311,21 +581,12 @@ static HRESULT AllocatePipeMessage(
311 size_t cb = 0; 581 size_t cb = 0;
312 DWORD dwcbData = 0; 582 DWORD dwcbData = 0;
313 583
314 // If no data was provided, ensure the count of bytes is zero. 584 hr = DutilSizetToDword(pvData ? cbData : 0, &dwcbData);
315 if (!pvData) 585 PipeExitOnFailure(hr, "Pipe message is too large.");
316 {
317 cbData = 0;
318 }
319 else if (MAXDWORD < cbData)
320 {
321 ExitWithRootFailure(hr, E_INVALIDDATA, "Pipe message is too large.");
322 }
323 586
324 hr = ::SizeTAdd(sizeof(dwMessageType) + sizeof(dwcbData), cbData, &cb); 587 hr = ::SizeTAdd(sizeof(dwMessageType) + sizeof(dwcbData), dwcbData, &cb);
325 ExitOnRootFailure(hr, "Failed to calculate total pipe message size"); 588 ExitOnRootFailure(hr, "Failed to calculate total pipe message size");
326 589
327 dwcbData = (DWORD)cbData;
328
329 // Allocate the message. 590 // Allocate the message.
330 pv = MemAlloc(cb, FALSE); 591 pv = MemAlloc(cb, FALSE);
331 ExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to allocate memory for message."); 592 ExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to allocate memory for message.");
diff --git a/src/libs/dutil/WixToolset.DUtil/strutil.cpp b/src/libs/dutil/WixToolset.DUtil/strutil.cpp
index a483cf54..0a00c690 100644
--- a/src/libs/dutil/WixToolset.DUtil/strutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/strutil.cpp
@@ -80,7 +80,7 @@ extern "C" HRESULT DAPI StrAllocSecure(
80 80
81/******************************************************************** 81/********************************************************************
82AllocHelper - allocates or reuses dynamic string memory 82AllocHelper - allocates or reuses dynamic string memory
83If fZeroOnRealloc is true and the memory needs to reallocated, 83If fZeroOnRealloc is true and the memory needs to reallocated,
84calls SecureZeroMemory on original block of memory after it is moved. 84calls SecureZeroMemory on original block of memory after it is moved.
85 85
86NOTE: caller is responsible for freeing ppwz even if function fails 86NOTE: caller is responsible for freeing ppwz even if function fails
@@ -350,8 +350,8 @@ extern "C" HRESULT DAPI StrAllocString(
350} 350}
351 351
352/******************************************************************** 352/********************************************************************
353StrAllocStringSecure - allocates or reuses dynamic string memory and 353StrAllocStringSecure - allocates or reuses dynamic string memory and
354copies in an existing string. If the memory needs to reallocated, 354copies in an existing string. If the memory needs to reallocated,
355calls SecureZeroMemory on original block of memory after it is moved. 355calls SecureZeroMemory on original block of memory after it is moved.
356 356
357NOTE: caller is responsible for freeing ppwz even if function fails 357NOTE: caller is responsible for freeing ppwz even if function fails
@@ -369,7 +369,7 @@ extern "C" HRESULT DAPI StrAllocStringSecure(
369 369
370/******************************************************************** 370/********************************************************************
371AllocStringHelper - allocates or reuses dynamic string memory and copies in an existing string 371AllocStringHelper - allocates or reuses dynamic string memory and copies in an existing string
372If fZeroOnRealloc is true and the memory needs to reallocated, 372If fZeroOnRealloc is true and the memory needs to reallocated,
373calls SecureZeroMemory on original block of memory after it is moved. 373calls SecureZeroMemory on original block of memory after it is moved.
374 374
375NOTE: caller is responsible for freeing ppwz even if function fails 375NOTE: caller is responsible for freeing ppwz even if function fails
@@ -623,7 +623,7 @@ LExit:
623 623
624 624
625/******************************************************************** 625/********************************************************************
626StrAllocPrefix - allocates or reuses dynamic string memory and 626StrAllocPrefix - allocates or reuses dynamic string memory and
627 prefixes a string 627 prefixes a string
628 628
629NOTE: caller is responsible for freeing ppwz even if function fails 629NOTE: caller is responsible for freeing ppwz even if function fails
@@ -703,8 +703,8 @@ extern "C" HRESULT DAPI StrAllocConcat(
703 703
704 704
705/******************************************************************** 705/********************************************************************
706StrAllocConcatSecure - allocates or reuses dynamic string memory and 706StrAllocConcatSecure - allocates or reuses dynamic string memory and
707adds an existing string. If the memory needs to reallocated, calls 707adds an existing string. If the memory needs to reallocated, calls
708SecureZeroMemory on the original block of memory after it is moved. 708SecureZeroMemory on the original block of memory after it is moved.
709 709
710NOTE: caller is responsible for freeing ppwz even if function fails 710NOTE: caller is responsible for freeing ppwz even if function fails
@@ -723,7 +723,7 @@ extern "C" HRESULT DAPI StrAllocConcatSecure(
723 723
724/******************************************************************** 724/********************************************************************
725AllocConcatHelper - allocates or reuses dynamic string memory and adds an existing string 725AllocConcatHelper - allocates or reuses dynamic string memory and adds an existing string
726If fZeroOnRealloc is true and the memory needs to reallocated, 726If fZeroOnRealloc is true and the memory needs to reallocated,
727calls SecureZeroMemory on original block of memory after it is moved. 727calls SecureZeroMemory on original block of memory after it is moved.
728 728
729NOTE: caller is responsible for freeing ppwz even if function fails 729NOTE: caller is responsible for freeing ppwz even if function fails
@@ -940,7 +940,7 @@ LExit:
940 940
941 941
942/******************************************************************** 942/********************************************************************
943StrAllocFormattedSecure - allocates or reuses dynamic string memory 943StrAllocFormattedSecure - allocates or reuses dynamic string memory
944and formats it. If the memory needs to be reallocated, 944and formats it. If the memory needs to be reallocated,
945calls SecureZeroMemory on original block of memory after it is moved. 945calls SecureZeroMemory on original block of memory after it is moved.
946 946
@@ -990,7 +990,7 @@ extern "C" HRESULT DAPI StrAnsiAllocFormatted(
990 990
991 991
992/******************************************************************** 992/********************************************************************
993StrAllocFormattedArgs - allocates or reuses dynamic string memory 993StrAllocFormattedArgs - allocates or reuses dynamic string memory
994and formats it with the passed in args 994and formats it with the passed in args
995 995
996NOTE: caller is responsible for freeing ppwz even if function fails 996NOTE: caller is responsible for freeing ppwz even if function fails
@@ -1009,7 +1009,7 @@ extern "C" HRESULT DAPI StrAllocFormattedArgs(
1009StrAllocFormattedArgsSecure - allocates or reuses dynamic string memory 1009StrAllocFormattedArgsSecure - allocates or reuses dynamic string memory
1010and formats it with the passed in args. 1010and formats it with the passed in args.
1011 1011
1012If the memory needs to reallocated, calls SecureZeroMemory on the 1012If the memory needs to reallocated, calls SecureZeroMemory on the
1013original block of memory after it is moved. 1013original block of memory after it is moved.
1014 1014
1015NOTE: caller is responsible for freeing ppwz even if function fails 1015NOTE: caller is responsible for freeing ppwz even if function fails
@@ -1028,7 +1028,7 @@ extern "C" HRESULT DAPI StrAllocFormattedArgsSecure(
1028AllocFormattedArgsHelper - allocates or reuses dynamic string memory 1028AllocFormattedArgsHelper - allocates or reuses dynamic string memory
1029and formats it with the passed in args. 1029and formats it with the passed in args.
1030 1030
1031If fZeroOnRealloc is true and the memory needs to reallocated, 1031If fZeroOnRealloc is true and the memory needs to reallocated,
1032calls SecureZeroMemory on original block of memory after it is moved. 1032calls SecureZeroMemory on original block of memory after it is moved.
1033 1033
1034NOTE: caller is responsible for freeing ppwz even if function fails 1034NOTE: caller is responsible for freeing ppwz even if function fails
@@ -1108,7 +1108,7 @@ LExit:
1108 1108
1109 1109
1110/******************************************************************** 1110/********************************************************************
1111StrAnsiAllocFormattedArgs - allocates or reuses dynamic ANSI string memory 1111StrAnsiAllocFormattedArgs - allocates or reuses dynamic ANSI string memory
1112and formats it with the passed in args 1112and formats it with the passed in args
1113 1113
1114NOTE: caller is responsible for freeing ppsz even if function fails 1114NOTE: caller is responsible for freeing ppsz even if function fails
@@ -1946,7 +1946,7 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1946 // Allocate the result buffer 1946 // Allocate the result buffer
1947 hr = StrAlloc(&pwzResult, cchResult + 1); 1947 hr = StrAlloc(&pwzResult, cchResult + 1);
1948 StrExitOnFailure(hr, "failed to allocate result string"); 1948 StrExitOnFailure(hr, "failed to allocate result string");
1949 1949
1950 // Prepend 1950 // Prepend
1951 hr = ::StringCchCopyW(pwzResult, cchResult, pwzInsert); 1951 hr = ::StringCchCopyW(pwzResult, cchResult, pwzInsert);
1952 StrExitOnRootFailure(hr, "failed to copy prepend string: %ls", pwzInsert); 1952 StrExitOnRootFailure(hr, "failed to copy prepend string: %ls", pwzInsert);
@@ -2395,7 +2395,7 @@ extern "C" HRESULT DAPI StrStringToUInt16(
2395 ULONGLONG ull = 0; 2395 ULONGLONG ull = 0;
2396 2396
2397 hr = StrStringToUInt64(wzIn, cchIn, &ull); 2397 hr = StrStringToUInt64(wzIn, cchIn, &ull);
2398 StrExitOnFailure(hr, "Failed to parse uint64."); 2398 StrExitOnFailure(hr, "Failed to parse uint64 to convert to uint16.");
2399 2399
2400 if (USHORT_MAX < ull) 2400 if (USHORT_MAX < ull)
2401 { 2401 {
@@ -2447,7 +2447,7 @@ extern "C" HRESULT DAPI StrStringToUInt32(
2447 ULONGLONG ull = 0; 2447 ULONGLONG ull = 0;
2448 2448
2449 hr = StrStringToUInt64(wzIn, cchIn, &ull); 2449 hr = StrStringToUInt64(wzIn, cchIn, &ull);
2450 StrExitOnFailure(hr, "Failed to parse uint64."); 2450 StrExitOnFailure(hr, "Failed to parse uint64 to convert to uint32.");
2451 2451
2452 if (UINT_MAX < ull) 2452 if (UINT_MAX < ull)
2453 { 2453 {
diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
index 7938cd0b..910b05c2 100644
--- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
@@ -954,7 +954,7 @@ DAPI_(HRESULT) ThemeLocalize(
954 954
955LExit: 955LExit:
956 ReleaseStr(sczCaption); 956 ReleaseStr(sczCaption);
957 957
958 return hr; 958 return hr;
959} 959}
960 960
@@ -6312,7 +6312,7 @@ static HRESULT LoadControls(
6312 } 6312 }
6313 6313
6314 pControl->hWnd = ::CreateWindowExW(dwWindowExBits, wzWindowClass, pControl->sczText, pControl->dwStyle | dwWindowBits, x, y, w, h, hwndParent, reinterpret_cast<HMENU>(wControlId), NULL, pControl); 6314 pControl->hWnd = ::CreateWindowExW(dwWindowExBits, wzWindowClass, pControl->sczText, pControl->dwStyle | dwWindowBits, x, y, w, h, hwndParent, reinterpret_cast<HMENU>(wControlId), NULL, pControl);
6315 ThmExitOnNullWithLastError(pControl->hWnd, hr, "Failed to create window."); 6315 ThmExitOnNullWithLastError(pControl->hWnd, hr, "Failed to create control %ls window.", wzWindowClass);
6316 6316
6317 if (pControl->sczTooltip) 6317 if (pControl->sczTooltip)
6318 { 6318 {
diff --git a/src/libs/dutil/test/DUtilUnitTest/PipeUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/PipeUtilTest.cpp
index 87a5e8f2..aa6874e4 100644
--- a/src/libs/dutil/test/DUtilUnitTest/PipeUtilTest.cpp
+++ b/src/libs/dutil/test/DUtilUnitTest/PipeUtilTest.cpp
@@ -23,6 +23,7 @@ namespace DutilTests
23 HRESULT hr = S_OK; 23 HRESULT hr = S_OK;
24 HANDLE hServerPipe = INVALID_HANDLE_VALUE; 24 HANDLE hServerPipe = INVALID_HANDLE_VALUE;
25 HANDLE hClientThread = NULL; 25 HANDLE hClientThread = NULL;
26 PIPE_RPC_HANDLE hRpc = { INVALID_HANDLE_VALUE };
26 PIPE_MESSAGE msg = { }; 27 PIPE_MESSAGE msg = { };
27 DWORD dwThread = 42; 28 DWORD dwThread = 42;
28 DWORD dwTestMessageId = 987654; 29 DWORD dwTestMessageId = 987654;
@@ -32,6 +33,12 @@ namespace DutilTests
32 hr = PipeCreate(L"DutilTest", NULL, &hServerPipe); 33 hr = PipeCreate(L"DutilTest", NULL, &hServerPipe);
33 NativeAssert::Succeeded(hr, "Failed to create server pipe."); 34 NativeAssert::Succeeded(hr, "Failed to create server pipe.");
34 35
36 PipeRpcInitialize(&hRpc, hServerPipe, FALSE);
37 NativeAssert::Equal((DWORD_PTR)hServerPipe, (DWORD_PTR)hRpc.hPipe);
38
39 BOOL fInitialized = PipeRpcInitialized(&hRpc);
40 NativeAssert::True(fInitialized);
41
35 hClientThread = ::CreateThread(NULL, 0, _TestPipeClientThreadProc, &dwTestMessageId, 0, NULL); 42 hClientThread = ::CreateThread(NULL, 0, _TestPipeClientThreadProc, &dwTestMessageId, 0, NULL);
36 if (hClientThread == 0) 43 if (hClientThread == 0)
37 { 44 {
@@ -39,10 +46,10 @@ namespace DutilTests
39 return; 46 return;
40 } 47 }
41 48
42 hr = PipeServerWaitForClientConnect(hServerPipe); 49 hr = PipeServerWaitForClientConnect(hClientThread, hServerPipe);
43 NativeAssert::Succeeded(hr, "Failed to wait for client to connect to pipe."); 50 NativeAssert::Succeeded(hr, "Failed to wait for client to connect to pipe.");
44 51
45 hr = PipeReadMessage(hServerPipe, &msg); 52 hr = PipeRpcReadMessage(&hRpc, &msg);
46 NativeAssert::Succeeded(hr, "Failed to read message from client."); 53 NativeAssert::Succeeded(hr, "Failed to read message from client.");
47 54
48 NativeAssert::Equal(dwTestMessageId, msg.dwMessageType); 55 NativeAssert::Equal(dwTestMessageId, msg.dwMessageType);
@@ -57,6 +64,8 @@ namespace DutilTests
57 ReleasePipeMessage(&msg); 64 ReleasePipeMessage(&msg);
58 ReleaseHandle(hClientThread); 65 ReleaseHandle(hClientThread);
59 ReleasePipeHandle(hServerPipe); 66 ReleasePipeHandle(hServerPipe);
67
68 PipeRpcUninitiailize(&hRpc);
60 } 69 }
61 } 70 }
62 }; 71 };
@@ -69,6 +78,7 @@ static DWORD STDAPICALLTYPE _TestPipeClientThreadProc(
69{ 78{
70 HRESULT hr = S_OK; 79 HRESULT hr = S_OK;
71 HANDLE hClientPipe = INVALID_HANDLE_VALUE; 80 HANDLE hClientPipe = INVALID_HANDLE_VALUE;
81 PIPE_RPC_HANDLE hRpc = { INVALID_HANDLE_VALUE };
72 82
73 hr = PipeClientConnect(L"DutilTest", &hClientPipe); 83 hr = PipeClientConnect(L"DutilTest", &hClientPipe);
74 if (FAILED(hr)) 84 if (FAILED(hr))
@@ -76,14 +86,17 @@ static DWORD STDAPICALLTYPE _TestPipeClientThreadProc(
76 return hr; 86 return hr;
77 } 87 }
78 88
89 PipeRpcInitialize(&hRpc, hClientPipe, TRUE);
90
79 ::Sleep(200); 91 ::Sleep(200);
80 92
81 hr = PipeWriteMessage(hClientPipe, *(LPDWORD)lpThreadParameter, NULL, 0); 93 hr = PipeRpcWriteMessage(&hRpc, *(LPDWORD)lpThreadParameter, NULL, 0);
82 if (FAILED(hr)) 94 if (FAILED(hr))
83 { 95 {
84 return hr; 96 return hr;
85 } 97 }
86 98
87 ReleasePipeHandle(hClientPipe); 99 PipeRpcUninitiailize(&hRpc);
100
88 return 12; 101 return 12;
89} 102}