diff --git a/testConsoleBuf.cxx b/testConsoleBuf.cxx index 3dec097332ef9ce5e8b02580a426bbd8b2ea1638..6c79d891d998085e48261aff3412d23d1524451d 100644 --- a/testConsoleBuf.cxx +++ b/testConsoleBuf.cxx @@ -48,6 +48,25 @@ static HANDLE syncEvent; static std::string encodedInputTestString; static std::string encodedTestString; +static void displayError(DWORD errorCode) { + std::cerr.setf(std::ios::hex, std::ios::basefield); + std::cerr << "Failed with error: 0x" << errorCode << "!" << std::endl; + LPWSTR message; + if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + errorCode, + 0, + (LPWSTR)&message, 0, + NULL) + ) { + std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message) << std::endl; + HeapFree(GetProcessHeap(), 0, message); + } else { + std::cerr << "FormatMessage() failed with error: 0x" << GetLastError() << "!" << std::endl; + } + std::cerr.unsetf(std::ios::hex); +} + //---------------------------------------------------------------------------- static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) { @@ -89,23 +108,8 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) &processInfo) != 0; // Pointer to PROCESS_INFORMATION structure if (!success) { DWORD lastError = GetLastError(); - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) - << ") failed with error: 0x" << lastError << "!" << std::endl; - LPWSTR message; - if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - lastError, - 0, - (LPWSTR)&message, 0, - NULL) - ) { - std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message) << std::endl; - HeapFree(GetProcessHeap(), 0, message); - } else { - std::cerr << "FormatMessage() failed with error: 0x" << GetLastError() << "!" << std::endl; - } - std::cerr.unsetf(std::ios::hex); + std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")" << std::endl; + displayError(lastError); } return success; } @@ -162,8 +166,9 @@ static HANDLE createFile(LPCWSTR fileName) FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); // no template if (file == INVALID_HANDLE_VALUE) { - std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) - << ") failed!" << std::endl; + DWORD lastError = GetLastError(); + std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" << std::endl; + displayError(lastError); } return file; } @@ -255,19 +260,23 @@ static int testPipe() if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) { try { Sleep(100); - if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) { + DWORD status; + if ((status = WaitForSingleObject(syncEvent, waitTimeout)) != WAIT_OBJECT_0) { + std::cerr.setf(std::ios::hex, std::ios::basefield); + std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl; + std::cerr.unsetf(std::ios::hex); throw std::runtime_error("WaitForSingleObject failed!"); } DWORD bytesRead = 0; if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, NULL) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#1 failed!"); } if ((bytesRead < encodedTestString.size() + 1 + encodedInputTestString.size() && !ReadFile(outPipeRead, buffer + bytesRead, sizeof(buffer) - bytesRead, &bytesRead, NULL)) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#2 failed!"); } if (memcmp(buffer, encodedTestString.c_str(), encodedTestString.size()) == 0 && @@ -277,7 +286,7 @@ static int testPipe() bytesRead = 0; if (!ReadFile(errPipeRead, buffer, sizeof(buffer), &bytesRead, NULL) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#3 failed!"); } buffer[bytesRead - 1] = 0; didFail = encodedTestString.compare(buffer) == 0 ? 0 : 1; @@ -286,12 +295,16 @@ static int testPipe() std::cerr << "Pipe's output didn't match expected output!" << std::endl << std::flush; } } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishProcess(didFail == 0); } } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishPipe(inPipeRead, inPipeWrite); finishPipe(outPipeRead, outPipeWrite); @@ -335,16 +348,20 @@ static int testFile() DWORD bytesRead = 0; try { Sleep(100); - if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) { + DWORD status; + if ((status = WaitForSingleObject(syncEvent, waitTimeout)) != WAIT_OBJECT_0) { + std::cerr.setf(std::ios::hex, std::ios::basefield); + std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl; + std::cerr.unsetf(std::ios::hex); throw std::runtime_error("WaitForSingleObject failed!"); } if (SetFilePointer(outFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { - throw std::runtime_error("SetFilePointer failed!"); + throw std::runtime_error("SetFilePointer#1 failed!"); } if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#1 failed!"); } buffer[bytesRead - 1] = 0; if (memcmp(buffer, encodedTestString.c_str(), @@ -355,11 +372,11 @@ static int testFile() bytesRead = 0; if (SetFilePointer(errFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { - throw std::runtime_error("SetFilePointer failed!"); + throw std::runtime_error("SetFilePointer#2 failed!"); } if (!ReadFile(errFile, buffer, sizeof(buffer), &bytesRead, NULL) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#2 failed!"); } buffer[bytesRead - 1] = 0; didFail = encodedTestString.compare(buffer) == 0 ? 0 : 1; @@ -368,12 +385,16 @@ static int testFile() std::cerr << "File's output didn't match expected output!" << std::endl << std::flush; } } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishProcess(didFail == 0); } } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishFile(inFile); finishFile(outFile); @@ -462,7 +483,17 @@ static int testConsole() hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, 0, &securityAttributes, OPEN_EXISTING, 0, NULL); hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, 0, + if (hIn == INVALID_HANDLE_VALUE) { + DWORD lastError = GetLastError(); + std::cerr << "CreateFile(CONIN$)" << std::endl; + displayError(lastError); + } &securityAttributes, OPEN_EXISTING, 0, NULL); + if (hOut == INVALID_HANDLE_VALUE) { + DWORD lastError = GetLastError(); + std::cerr << "CreateFile(CONOUT$)" << std::endl; + displayError(lastError); + } SetStdHandle(STD_INPUT_HANDLE, hIn); SetStdHandle(STD_OUTPUT_HANDLE, hOut); SetStdHandle(STD_ERROR_HANDLE, hOut); @@ -508,8 +539,12 @@ static int testConsole() if (createProcess(NULL, NULL, NULL)) { try { - if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) { - throw std::runtime_error("WaitForSingleObject failed!"); + DWORD status; + if ((status = WaitForSingleObject(syncEvent, waitTimeout)) != WAIT_OBJECT_0) { + std::cerr.setf(std::ios::hex, std::ios::basefield); + std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl; + std::cerr.unsetf(std::ios::hex); + throw std::runtime_error("WaitForSingleObject#1 failed!"); } INPUT_RECORD inputBuffer[(sizeof(UnicodeInputTestString) / sizeof(UnicodeInputTestString[0])) * 2]; @@ -526,8 +561,11 @@ static int testConsole() &eventsWritten) || eventsWritten == 0) { throw std::runtime_error("WriteConsoleInput failed!"); } - if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) { - throw std::runtime_error("WaitForSingleObject failed!"); + if ((status = WaitForSingleObject(syncEvent, waitTimeout)) != WAIT_OBJECT_0) { + std::cerr.setf(std::ios::hex, std::ios::basefield); + std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl; + std::cerr.unsetf(std::ios::hex); + throw std::runtime_error("WaitForSingleObject#2 failed!"); } CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo; if (!GetConsoleScreenBufferInfo(hOut, &screenBufferInfo)) { @@ -562,7 +600,9 @@ static int testConsole() } delete[] outputBuffer; } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishProcess(didFail == 0); }