aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/conutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dutil/conutil.cpp77
1 files changed, 47 insertions, 30 deletions
diff --git a/src/dutil/conutil.cpp b/src/dutil/conutil.cpp
index 4c820a1c..33e1b59a 100644
--- a/src/dutil/conutil.cpp
+++ b/src/dutil/conutil.cpp
@@ -3,6 +3,21 @@
3#include "precomp.h" 3#include "precomp.h"
4 4
5 5
6// Exit macros
7#define ConExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_CONUTIL, x, s, __VA_ARGS__)
8#define ConExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_CONUTIL, x, s, __VA_ARGS__)
9#define ConExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_CONUTIL, x, s, __VA_ARGS__)
10#define ConExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_CONUTIL, x, s, __VA_ARGS__)
11#define ConExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_CONUTIL, x, s, __VA_ARGS__)
12#define ConExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_CONUTIL, x, s, __VA_ARGS__)
13#define ConExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_CONUTIL, p, x, e, s, __VA_ARGS__)
14#define ConExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_CONUTIL, p, x, s, __VA_ARGS__)
15#define ConExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_CONUTIL, p, x, e, s, __VA_ARGS__)
16#define ConExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_CONUTIL, p, x, s, __VA_ARGS__)
17#define ConExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_CONUTIL, e, x, s, __VA_ARGS__)
18#define ConExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_CONUTIL, g, x, s, __VA_ARGS__)
19
20
6static HANDLE vhStdIn = INVALID_HANDLE_VALUE; 21static HANDLE vhStdIn = INVALID_HANDLE_VALUE;
7static HANDLE vhStdOut = INVALID_HANDLE_VALUE; 22static HANDLE vhStdOut = INVALID_HANDLE_VALUE;
8static BOOL vfConsoleIn = FALSE; 23static BOOL vfConsoleIn = FALSE;
@@ -19,13 +34,13 @@ extern "C" HRESULT DAPI ConsoleInitialize()
19 vhStdIn = ::GetStdHandle(STD_INPUT_HANDLE); 34 vhStdIn = ::GetStdHandle(STD_INPUT_HANDLE);
20 if (INVALID_HANDLE_VALUE == vhStdIn) 35 if (INVALID_HANDLE_VALUE == vhStdIn)
21 { 36 {
22 ExitOnLastError(hr, "failed to open stdin"); 37 ConExitOnLastError(hr, "failed to open stdin");
23 } 38 }
24 39
25 vhStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE); 40 vhStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
26 if (INVALID_HANDLE_VALUE == vhStdOut) 41 if (INVALID_HANDLE_VALUE == vhStdOut)
27 { 42 {
28 ExitOnLastError(hr, "failed to open stdout"); 43 ConExitOnLastError(hr, "failed to open stdout");
29 } 44 }
30 45
31 // check if we have a std in on the console 46 // check if we have a std in on the console
@@ -43,7 +58,7 @@ extern "C" HRESULT DAPI ConsoleInitialize()
43 } 58 }
44 else 59 else
45 { 60 {
46 ExitOnWin32Error(er, hr, "failed to get input console screen buffer info"); 61 ConExitOnWin32Error(er, hr, "failed to get input console screen buffer info");
47 } 62 }
48 } 63 }
49 64
@@ -62,7 +77,7 @@ extern "C" HRESULT DAPI ConsoleInitialize()
62 } 77 }
63 else 78 else
64 { 79 {
65 ExitOnWin32Error(er, hr, "failed to get output console screen buffer info"); 80 ConExitOnWin32Error(er, hr, "failed to get output console screen buffer info");
66 } 81 }
67 } 82 }
68 83
@@ -89,6 +104,8 @@ LExit:
89 104
90extern "C" void DAPI ConsoleUninitialize() 105extern "C" void DAPI ConsoleUninitialize()
91{ 106{
107 BOOL fOutEqualsIn = vhStdOut == vhStdIn;
108
92 memset(&vcsbiInfo, 0, sizeof(vcsbiInfo)); 109 memset(&vcsbiInfo, 0, sizeof(vcsbiInfo));
93 110
94 if (INVALID_HANDLE_VALUE != vhStdOut) 111 if (INVALID_HANDLE_VALUE != vhStdOut)
@@ -96,7 +113,7 @@ extern "C" void DAPI ConsoleUninitialize()
96 ::CloseHandle(vhStdOut); 113 ::CloseHandle(vhStdOut);
97 } 114 }
98 115
99 if (INVALID_HANDLE_VALUE != vhStdIn && vhStdOut != vhStdIn) 116 if (INVALID_HANDLE_VALUE != vhStdIn && !fOutEqualsIn)
100 { 117 {
101 ::CloseHandle(vhStdIn); 118 ::CloseHandle(vhStdIn);
102 } 119 }
@@ -178,14 +195,14 @@ extern "C" HRESULT DAPI ConsoleWrite(
178 va_start(args, szFormat); 195 va_start(args, szFormat);
179 hr = StrAnsiAllocFormattedArgs(&pszOutput, szFormat, args); 196 hr = StrAnsiAllocFormattedArgs(&pszOutput, szFormat, args);
180 va_end(args); 197 va_end(args);
181 ExitOnFailure(hr, "failed to format message: \"%s\"", szFormat); 198 ConExitOnFailure(hr, "failed to format message: \"%s\"", szFormat);
182 199
183 cchOutput = lstrlenA(pszOutput); 200 cchOutput = lstrlenA(pszOutput);
184 while (cbTotal < (sizeof(*pszOutput) * cchOutput)) 201 while (cbTotal < (sizeof(*pszOutput) * cchOutput))
185 { 202 {
186 if (!::WriteFile(vhStdOut, reinterpret_cast<BYTE*>(pszOutput) + cbTotal, cchOutput * sizeof(*pszOutput) - cbTotal, &cbWrote, NULL)) 203 if (!::WriteFile(vhStdOut, reinterpret_cast<BYTE*>(pszOutput) + cbTotal, cchOutput * sizeof(*pszOutput) - cbTotal, &cbWrote, NULL))
187 { 204 {
188 ExitOnLastError(hr, "failed to write output to console: %s", pszOutput); 205 ConExitOnLastError(hr, "failed to write output to console: %s", pszOutput);
189 } 206 }
190 207
191 cbTotal += cbWrote; 208 cbTotal += cbWrote;
@@ -236,7 +253,7 @@ extern "C" HRESULT DAPI ConsoleWriteLine(
236 va_start(args, szFormat); 253 va_start(args, szFormat);
237 hr = StrAnsiAllocFormattedArgs(&pszOutput, szFormat, args); 254 hr = StrAnsiAllocFormattedArgs(&pszOutput, szFormat, args);
238 va_end(args); 255 va_end(args);
239 ExitOnFailure(hr, "failed to format message: \"%s\"", szFormat); 256 ConExitOnFailure(hr, "failed to format message: \"%s\"", szFormat);
240 257
241 // 258 //
242 // write the string 259 // write the string
@@ -245,7 +262,7 @@ extern "C" HRESULT DAPI ConsoleWriteLine(
245 while (cbTotal < (sizeof(*pszOutput) * cchOutput)) 262 while (cbTotal < (sizeof(*pszOutput) * cchOutput))
246 { 263 {
247 if (!::WriteFile(vhStdOut, reinterpret_cast<BYTE*>(pszOutput) + cbTotal, cchOutput * sizeof(*pszOutput) - cbTotal, &cbWrote, NULL)) 264 if (!::WriteFile(vhStdOut, reinterpret_cast<BYTE*>(pszOutput) + cbTotal, cchOutput * sizeof(*pszOutput) - cbTotal, &cbWrote, NULL))
248 ExitOnLastError(hr, "failed to write output to console: %s", pszOutput); 265 ConExitOnLastError(hr, "failed to write output to console: %s", pszOutput);
249 266
250 cbTotal += cbWrote; 267 cbTotal += cbWrote;
251 } 268 }
@@ -255,7 +272,7 @@ extern "C" HRESULT DAPI ConsoleWriteLine(
255 // 272 //
256 if (!::WriteFile(vhStdOut, reinterpret_cast<const BYTE*>(szNewLine), 2, &cbWrote, NULL)) 273 if (!::WriteFile(vhStdOut, reinterpret_cast<const BYTE*>(szNewLine), 2, &cbWrote, NULL))
257 { 274 {
258 ExitOnLastError(hr, "failed to write newline to console"); 275 ConExitOnLastError(hr, "failed to write newline to console");
259 } 276 }
260 277
261 // reset the color to normal 278 // reset the color to normal
@@ -289,7 +306,7 @@ HRESULT ConsoleWriteError(
289 va_start(args, szFormat); 306 va_start(args, szFormat);
290 hr = StrAnsiAllocFormattedArgs(&pszMessage, szFormat, args); 307 hr = StrAnsiAllocFormattedArgs(&pszMessage, szFormat, args);
291 va_end(args); 308 va_end(args);
292 ExitOnFailure(hr, "failed to format error message: \"%s\"", szFormat); 309 ConExitOnFailure(hr, "failed to format error message: \"%s\"", szFormat);
293 310
294 if (FAILED(hrError)) 311 if (FAILED(hrError))
295 { 312 {
@@ -326,14 +343,14 @@ extern "C" HRESULT DAPI ConsoleReadW(
326 343
327 cch = 64; 344 cch = 64;
328 hr = StrAnsiAlloc(&psz, cch); 345 hr = StrAnsiAlloc(&psz, cch);
329 ExitOnFailure(hr, "failed to allocate memory to read from console"); 346 ConExitOnFailure(hr, "failed to allocate memory to read from console");
330 347
331 // loop until we read the \r\n from the console 348 // loop until we read the \r\n from the console
332 for (;;) 349 for (;;)
333 { 350 {
334 // read one character at a time, since that seems to be the only way to make this work 351 // read one character at a time, since that seems to be the only way to make this work
335 if (!::ReadFile(vhStdIn, psz + cchTotalRead, 1, &cchRead, NULL)) 352 if (!::ReadFile(vhStdIn, psz + cchTotalRead, 1, &cchRead, NULL))
336 ExitOnLastError(hr, "failed to read string from console"); 353 ConExitOnLastError(hr, "failed to read string from console");
337 354
338 cchTotalRead += cchRead; 355 cchTotalRead += cchRead;
339 if (1 < cchTotalRead && '\r' == psz[cchTotalRead - 2] || '\n' == psz[cchTotalRead - 1]) 356 if (1 < cchTotalRead && '\r' == psz[cchTotalRead - 2] || '\n' == psz[cchTotalRead - 1])
@@ -351,7 +368,7 @@ extern "C" HRESULT DAPI ConsoleReadW(
351 { 368 {
352 cch *= 2; // double everytime we run out of space 369 cch *= 2; // double everytime we run out of space
353 hr = StrAnsiAlloc(&psz, cch); 370 hr = StrAnsiAlloc(&psz, cch);
354 ExitOnFailure(hr, "failed to allocate memory to read from console"); 371 ConExitOnFailure(hr, "failed to allocate memory to read from console");
355 } 372 }
356 } 373 }
357 374
@@ -381,7 +398,7 @@ extern "C" HRESULT DAPI ConsoleReadNonBlockingW(
381 398
382 LPSTR psz = NULL; 399 LPSTR psz = NULL;
383 400
384 ExitOnNull(ppwzBuffer, hr, E_INVALIDARG, "Failed to read from console because buffer was not provided"); 401 ConExitOnNull(ppwzBuffer, hr, E_INVALIDARG, "Failed to read from console because buffer was not provided");
385 402
386 DWORD dwRead; 403 DWORD dwRead;
387 DWORD dwNumInput; 404 DWORD dwNumInput;
@@ -412,7 +429,7 @@ extern "C" HRESULT DAPI ConsoleReadNonBlockingW(
412 429
413 if (!GetNumberOfConsoleInputEvents(vhStdIn, &dwRead)) 430 if (!GetNumberOfConsoleInputEvents(vhStdIn, &dwRead))
414 { 431 {
415 ExitOnLastError(hr, "failed to peek at console input"); 432 ConExitOnLastError(hr, "failed to peek at console input");
416 } 433 }
417 434
418 if (0 == dwRead) 435 if (0 == dwRead)
@@ -424,7 +441,7 @@ extern "C" HRESULT DAPI ConsoleReadNonBlockingW(
424 { 441 {
425 if (!ReadConsoleInputW(vhStdIn, &ir, 1, &dwNumInput)) 442 if (!ReadConsoleInputW(vhStdIn, &ir, 1, &dwNumInput))
426 { 443 {
427 ExitOnLastError(hr, "Failed to read input from console"); 444 ConExitOnLastError(hr, "Failed to read input from console");
428 } 445 }
429 446
430 // If what we have is a KEY_EVENT, and that event signifies keyUp, we're interested 447 // If what we have is a KEY_EVENT, and that event signifies keyUp, we're interested
@@ -463,14 +480,14 @@ extern "C" HRESULT DAPI ConsoleReadNonBlockingW(
463 480
464 cch = 8; 481 cch = 8;
465 hr = StrAnsiAlloc(&psz, cch); 482 hr = StrAnsiAlloc(&psz, cch);
466 ExitOnFailure(hr, "failed to allocate memory to read from console"); 483 ConExitOnFailure(hr, "failed to allocate memory to read from console");
467 484
468 for (/*dwRead from PeekNamedPipe*/; dwRead > 0; dwRead--) 485 for (/*dwRead from PeekNamedPipe*/; dwRead > 0; dwRead--)
469 { 486 {
470 // read one character at a time, since that seems to be the only way to make this work 487 // read one character at a time, since that seems to be the only way to make this work
471 if (!::ReadFile(vhStdIn, psz + cchTotalRead, 1, &cchRead, NULL)) 488 if (!::ReadFile(vhStdIn, psz + cchTotalRead, 1, &cchRead, NULL))
472 { 489 {
473 ExitOnLastError(hr, "failed to read string from console"); 490 ConExitOnLastError(hr, "failed to read string from console");
474 } 491 }
475 492
476 cchTotalRead += cchRead; 493 cchTotalRead += cchRead;
@@ -490,7 +507,7 @@ extern "C" HRESULT DAPI ConsoleReadNonBlockingW(
490 { 507 {
491 cch *= 2; // double everytime we run out of space 508 cch *= 2; // double everytime we run out of space
492 hr = StrAnsiAlloc(&psz, cch); 509 hr = StrAnsiAlloc(&psz, cch);
493 ExitOnFailure(hr, "failed to allocate memory to read from console"); 510 ConExitOnFailure(hr, "failed to allocate memory to read from console");
494 } 511 }
495 } 512 }
496 513
@@ -510,7 +527,7 @@ LExit:
510 527
511*********************************************************************/ 528*********************************************************************/
512extern "C" HRESULT DAPI ConsoleReadStringA( 529extern "C" HRESULT DAPI ConsoleReadStringA(
513 __deref_out_ecount_part(cchCharBuffer,*pcchNumCharReturn) LPSTR* ppszCharBuffer, 530 __deref_inout_ecount_part(cchCharBuffer,*pcchNumCharReturn) LPSTR* ppszCharBuffer,
514 CONST DWORD cchCharBuffer, 531 CONST DWORD cchCharBuffer,
515 __out DWORD* pcchNumCharReturn 532 __out DWORD* pcchNumCharReturn
516 ) 533 )
@@ -526,11 +543,11 @@ extern "C" HRESULT DAPI ConsoleReadStringA(
526 do 543 do
527 { 544 {
528 hr = StrAnsiAlloc(ppszCharBuffer, cchCharBuffer * iRead); 545 hr = StrAnsiAlloc(ppszCharBuffer, cchCharBuffer * iRead);
529 ExitOnFailure(hr, "failed to allocate memory for ConsoleReadStringW"); 546 ConExitOnFailure(hr, "failed to allocate memory for ConsoleReadStringW");
530 // ReadConsoleW will not return until <Return>, the last two chars are 13 and 10. 547 // ReadConsoleW will not return until <Return>, the last two chars are 13 and 10.
531 if (!::ReadConsoleA(vhStdIn, *ppszCharBuffer + iReadCharTotal, cchCharBuffer, pcchNumCharReturn, NULL) || *pcchNumCharReturn == 0) 548 if (!::ReadConsoleA(vhStdIn, *ppszCharBuffer + iReadCharTotal, cchCharBuffer, pcchNumCharReturn, NULL) || *pcchNumCharReturn == 0)
532 { 549 {
533 ExitOnLastError(hr, "failed to read string from console"); 550 ConExitOnLastError(hr, "failed to read string from console");
534 } 551 }
535 iReadCharTotal += *pcchNumCharReturn; 552 iReadCharTotal += *pcchNumCharReturn;
536 iRead += 1; 553 iRead += 1;
@@ -543,7 +560,7 @@ extern "C" HRESULT DAPI ConsoleReadStringA(
543 if (!::ReadConsoleA(vhStdIn, *ppszCharBuffer, cchCharBuffer, pcchNumCharReturn, NULL) || 560 if (!::ReadConsoleA(vhStdIn, *ppszCharBuffer, cchCharBuffer, pcchNumCharReturn, NULL) ||
544 *pcchNumCharReturn > cchCharBuffer || *pcchNumCharReturn == 0) 561 *pcchNumCharReturn > cchCharBuffer || *pcchNumCharReturn == 0)
545 { 562 {
546 ExitOnLastError(hr, "failed to read string from console"); 563 ConExitOnLastError(hr, "failed to read string from console");
547 } 564 }
548 if ((*ppszCharBuffer)[*pcchNumCharReturn - 1] != 10 || 565 if ((*ppszCharBuffer)[*pcchNumCharReturn - 1] != 10 ||
549 (*ppszCharBuffer)[*pcchNumCharReturn - 2] != 13) 566 (*ppszCharBuffer)[*pcchNumCharReturn - 2] != 13)
@@ -567,7 +584,7 @@ LExit:
567 584
568*********************************************************************/ 585*********************************************************************/
569extern "C" HRESULT DAPI ConsoleReadStringW( 586extern "C" HRESULT DAPI ConsoleReadStringW(
570 __deref_out_ecount_part(cchCharBuffer,*pcchNumCharReturn) LPWSTR* ppwzCharBuffer, 587 __deref_inout_ecount_part(cchCharBuffer,*pcchNumCharReturn) LPWSTR* ppwzCharBuffer,
571 const DWORD cchCharBuffer, 588 const DWORD cchCharBuffer,
572 __out DWORD* pcchNumCharReturn 589 __out DWORD* pcchNumCharReturn
573 ) 590 )
@@ -583,11 +600,11 @@ extern "C" HRESULT DAPI ConsoleReadStringW(
583 do 600 do
584 { 601 {
585 hr = StrAlloc(ppwzCharBuffer, cchCharBuffer * iRead); 602 hr = StrAlloc(ppwzCharBuffer, cchCharBuffer * iRead);
586 ExitOnFailure(hr, "failed to allocate memory for ConsoleReadStringW"); 603 ConExitOnFailure(hr, "failed to allocate memory for ConsoleReadStringW");
587 // ReadConsoleW will not return until <Return>, the last two chars are 13 and 10. 604 // ReadConsoleW will not return until <Return>, the last two chars are 13 and 10.
588 if (!::ReadConsoleW(vhStdIn, *ppwzCharBuffer + iReadCharTotal, cchCharBuffer, pcchNumCharReturn, NULL) || *pcchNumCharReturn == 0) 605 if (!::ReadConsoleW(vhStdIn, *ppwzCharBuffer + iReadCharTotal, cchCharBuffer, pcchNumCharReturn, NULL) || *pcchNumCharReturn == 0)
589 { 606 {
590 ExitOnLastError(hr, "failed to read string from console"); 607 ConExitOnLastError(hr, "failed to read string from console");
591 } 608 }
592 iReadCharTotal += *pcchNumCharReturn; 609 iReadCharTotal += *pcchNumCharReturn;
593 iRead += 1; 610 iRead += 1;
@@ -600,7 +617,7 @@ extern "C" HRESULT DAPI ConsoleReadStringW(
600 if (!::ReadConsoleW(vhStdIn, *ppwzCharBuffer, cchCharBuffer, pcchNumCharReturn, NULL) || 617 if (!::ReadConsoleW(vhStdIn, *ppwzCharBuffer, cchCharBuffer, pcchNumCharReturn, NULL) ||
601 *pcchNumCharReturn > cchCharBuffer || *pcchNumCharReturn == 0) 618 *pcchNumCharReturn > cchCharBuffer || *pcchNumCharReturn == 0)
602 { 619 {
603 ExitOnLastError(hr, "failed to read string from console"); 620 ConExitOnLastError(hr, "failed to read string from console");
604 } 621 }
605 if ((*ppwzCharBuffer)[*pcchNumCharReturn - 1] != 10 || 622 if ((*ppwzCharBuffer)[*pcchNumCharReturn - 1] != 10 ||
606 (*ppwzCharBuffer)[*pcchNumCharReturn - 2] != 13) 623 (*ppwzCharBuffer)[*pcchNumCharReturn - 2] != 13)
@@ -630,7 +647,7 @@ extern "C" HRESULT DAPI ConsoleSetReadHidden(void)
630 ::FlushConsoleInputBuffer(vhStdIn); 647 ::FlushConsoleInputBuffer(vhStdIn);
631 if (!::SetConsoleMode(vhStdIn, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT)) 648 if (!::SetConsoleMode(vhStdIn, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT))
632 { 649 {
633 ExitOnLastError(hr, "failed to set console input mode to be hidden"); 650 ConExitOnLastError(hr, "failed to set console input mode to be hidden");
634 } 651 }
635 652
636LExit: 653LExit:
@@ -647,7 +664,7 @@ extern "C" HRESULT DAPI ConsoleSetReadNormal(void)
647 HRESULT hr = S_OK; 664 HRESULT hr = S_OK;
648 if (!::SetConsoleMode(vhStdIn, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT)) 665 if (!::SetConsoleMode(vhStdIn, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT))
649 { 666 {
650 ExitOnLastError(hr, "failed to set console input mode to be normal"); 667 ConExitOnLastError(hr, "failed to set console input mode to be normal");
651 } 668 }
652 669
653LExit: 670LExit: