in BusTools/MinComm/main.cpp [395:529]
void ReadSerialWriteConsole (HANDLE serialHandle)
{
HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (!SetConsoleMode(
stdOut,
ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT)) {
throw wexception(
L"Failed to set console mode for stdout. GetLastError() = 0x%x",
GetLastError());
}
Event overlappedEvent(CreateEventW(NULL, TRUE, FALSE, NULL));
if (!overlappedEvent.IsValid()) {
throw wexception(
L"Failed to create event for overlapped IO. "
L"(GetLastError() = 0x%x)",
GetLastError());
}
for (;;) {
auto overlapped = OVERLAPPED();
overlapped.hEvent = overlappedEvent.Get();
CHAR buf[512];
DWORD bytesRead = 0;
if (!ReadFile(
serialHandle,
reinterpret_cast<BYTE*>(buf),
sizeof(buf),
&bytesRead,
&overlapped) && (GetLastError() != ERROR_IO_PENDING)) {
DWORD error = GetLastError();
if (error == ERROR_OPERATION_ABORTED) {
return; // error is due to application exit
}
throw wexception(
L"Failed to read from serial device. (GetLastError = 0x%x)",
error);
}
if (!GetOverlappedResult(
serialHandle,
&overlapped,
&bytesRead,
TRUE)) {
DWORD error = GetLastError();
if (error == ERROR_OPERATION_ABORTED) {
return; // error is due to application exit
}
throw wexception(
L"GetOverlappedResult() for ReadFile() failed. "
L"(GetLastError() = 0x%x)",
error);
}
WCHAR wbuf[ARRAYSIZE(buf)];
int charsConverted = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
buf,
bytesRead,
wbuf,
ARRAYSIZE(wbuf));
if (!charsConverted) {
throw wexception(
L"Failed to convert string to unicode. (GetLastError() = 0x%x)",
GetLastError());
}
const WCHAR* chunkBegin = wbuf;
const WCHAR* const bufEnd = wbuf + charsConverted;
do {
// scan for cairrage returns and backspaces
bool specialCharFound;
const WCHAR* chunkEnd = FindSpecialChar(
chunkBegin,
static_cast<ULONG>(bufEnd - chunkBegin),
&specialCharFound);
DWORD charsWritten;
if (!WriteConsole(
stdOut,
chunkBegin,
static_cast<ULONG>(chunkEnd - chunkBegin),
&charsWritten,
NULL)) {
throw wexception(
L"WriteConsole failed. (GetLastError() = 0x%x)",
GetLastError());
}
// Handle special character if one was found. The special
// character is the last character of the chunk.
if (specialCharFound)
{
switch (chunkEnd[-1]) {
case '\r':
{
const WCHAR lf = L'\n';
if (!WriteConsole(stdOut, &lf, 1, &charsWritten, NULL)) {
throw wexception(
L"WriteConsole failed. (GetLastError() = 0x%x)",
GetLastError());
}
break;
}
case '\b':
{
const WCHAR backspace[] = {L' ', L'\b'};
if (!WriteConsole(
stdOut,
&backspace,
ARRAYSIZE(backspace),
&charsWritten,
NULL)) {
throw wexception(
L"WriteConsole failed. (GetLastError() = 0x%x)",
GetLastError());
}
break;
}
} // switch
}
chunkBegin = chunkEnd;
} while (chunkBegin != bufEnd);
}
}