/*============================================================================
  KWSys - Kitware System Library
  Copyright 2000-2016 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "kwsysPrivate.h"

// Ignore Windows version levels defined by command-line flags.  This
// source needs access to all APIs available on the host in order for
// the test to run properly.  The test binary is not installed anyway.
#undef _WIN32_WINNT
#undef NTDDI_VERSION

#include KWSYS_HEADER(Encoding.hxx)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "Encoding.hxx.in"
#endif

#if defined(_WIN32)

#include <windows.h>
#include <string.h>
#include <wchar.h>
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include "testConsoleBuf.hxx"

#if defined(_MSC_VER) && _MSC_VER >= 1800
# define KWSYS_WINDOWS_DEPRECATED_GetVersion
#endif
// يونيكود
static const WCHAR UnicodeInputTestString[] = L"\u064A\u0648\u0646\u064A\u0643\u0648\u062F!";
static UINT TestCodepage = KWSYS_ENCODING_DEFAULT_CODEPAGE;

static const DWORD waitTimeout = 10 * 1000;
static STARTUPINFO startupInfo;
static PROCESS_INFORMATION processInfo;
static HANDLE beforeInputEvent;
static HANDLE afterOutputEvent;
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);
}

std::basic_streambuf<char> *errstream(const char *unused) {
  static_cast<void>(unused);
  return std::cerr.rdbuf();
}

std::basic_streambuf<wchar_t> *errstream(const wchar_t *unused) {
  static_cast<void>(unused);
  return std::wcerr.rdbuf();
}

//----------------------------------------------------------------------------
template<typename T>
static void dumpBuffers(const T *expected, const T *received, size_t size) {
  std::basic_ostream<T> err(errstream(expected));
  err << "Expected output: '" << std::basic_string<T>(expected, size) << "'" << std::endl;
  if (err.fail()) {
    err.clear();
    err << "--- Error while outputting ---" << std::endl;
  }
  err << "Received output: '" << std::basic_string<T>(received, size) << "'" << std::endl;
  if (err.fail()) {
    err.clear();
    err << "--- Error while outputting ---" << std::endl;
  }
  std::cerr << "Expected output | Received output" << std::endl;
  for (size_t i = 0; i < size; i++) {
    std::cerr << std::setbase(16) << std::setfill('0') << "     " <<
    "0x" << std::setw(8) << static_cast<unsigned int>(expected[i]) << " | " <<
    "0x" << std::setw(8) << static_cast<unsigned int>(received[i]);
    if (static_cast<unsigned int>(expected[i]) != static_cast<unsigned int>(received[i])) {
      std::cerr << "   MISMATCH!";
    }
    std::cerr << std::endl;
  }
  std::cerr << std::endl;
}

//----------------------------------------------------------------------------
static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr)
{
  BOOL bInheritHandles = FALSE;
  DWORD dwCreationFlags = 0;
  memset(&processInfo, 0, sizeof(processInfo));
  memset(&startupInfo, 0, sizeof(startupInfo));
  startupInfo.cb = sizeof(startupInfo);
  startupInfo.dwFlags = STARTF_USESHOWWINDOW;
  startupInfo.wShowWindow = SW_HIDE;
  if (hIn || hOut || hErr) {
    startupInfo.dwFlags |= STARTF_USESTDHANDLES;
    startupInfo.hStdInput = hIn;
    startupInfo.hStdOutput = hOut;
    startupInfo.hStdError = hErr;
    bInheritHandles = TRUE;
  }

  WCHAR cmd[MAX_PATH];
  if (GetModuleFileNameW(NULL, cmd, MAX_PATH) == 0) {
    std::cerr << "GetModuleFileName failed!" << std::endl;
    return false;
  }
  WCHAR *p = cmd + wcslen(cmd);
  while (p > cmd && *p != L'\\') p--;
  *(p+1) = 0;
  wcscat(cmd, cmdConsoleBufChild);
  wcscat(cmd, L".exe");

  bool success = CreateProcessW(NULL,             // No module name (use command line)
                                cmd,              // Command line
                                NULL,             // Process handle not inheritable
                                NULL,             // Thread handle not inheritable
                                bInheritHandles,  // Set handle inheritance
                                dwCreationFlags,
                                NULL,             // Use parent's environment block
                                NULL,             // Use parent's starting directory
                                &startupInfo,     // Pointer to STARTUPINFO structure
                                &processInfo) != 0; // Pointer to PROCESS_INFORMATION structure
  if (!success) {
    DWORD lastError = GetLastError();
    std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")" << std::endl;
    displayError(lastError);
  }
  return success;
}

//----------------------------------------------------------------------------
static void finishProcess(bool success)
{
  if (success) {
    success = WaitForSingleObject(processInfo.hProcess, waitTimeout)
              == WAIT_OBJECT_0;
  };
  if (!success) {
    TerminateProcess(processInfo.hProcess, 1);
  }
  CloseHandle(processInfo.hProcess);
  CloseHandle(processInfo.hThread);
}

//----------------------------------------------------------------------------
static bool createPipe(PHANDLE readPipe, PHANDLE writePipe)
{
  SECURITY_ATTRIBUTES securityAttributes;
  securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  securityAttributes.bInheritHandle = TRUE;
  securityAttributes.lpSecurityDescriptor = NULL;
  return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0
         ? false : true;
}

//----------------------------------------------------------------------------
static void finishPipe(HANDLE readPipe, HANDLE writePipe)
{
  if (readPipe != INVALID_HANDLE_VALUE) {
    CloseHandle(readPipe);
  }
  if (writePipe != INVALID_HANDLE_VALUE) {
    CloseHandle(writePipe);
  }
}

//----------------------------------------------------------------------------
static HANDLE createFile(LPCWSTR fileName)
{
  SECURITY_ATTRIBUTES securityAttributes;
  securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  securityAttributes.bInheritHandle = TRUE;
  securityAttributes.lpSecurityDescriptor = NULL;

  HANDLE file = CreateFileW(fileName,
                            GENERIC_READ | GENERIC_WRITE,
                            0,                    // do not share
                            &securityAttributes,
                            CREATE_ALWAYS,        // overwrite existing
                            FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
                            NULL);                // no template
  if (file == INVALID_HANDLE_VALUE) {
    DWORD lastError = GetLastError();
    std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" << std::endl;
    displayError(lastError);
  }
  return file;
}

//----------------------------------------------------------------------------
static void finishFile(HANDLE file)
{
  if (file != INVALID_HANDLE_VALUE) {
    CloseHandle(file);
  }
}

//----------------------------------------------------------------------------

#ifndef MAPVK_VK_TO_VSC
#  define MAPVK_VK_TO_VSC  (0)
#endif

static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr)
{
  inputBuffer[0].EventType = KEY_EVENT;
  inputBuffer[0].Event.KeyEvent.bKeyDown = TRUE;
  inputBuffer[0].Event.KeyEvent.wRepeatCount = 1;
  SHORT keyCode = VkKeyScanW(chr);
  if (keyCode == -1) {
    // Character can't be entered with current keyboard layout
    // Just set any, it doesn't really matter
    keyCode = 'K';
  }
  inputBuffer[0].Event.KeyEvent.wVirtualKeyCode = LOBYTE(keyCode);
  inputBuffer[0].Event.KeyEvent.wVirtualScanCode =
      MapVirtualKey(inputBuffer[0].Event.KeyEvent.wVirtualKeyCode,
                    MAPVK_VK_TO_VSC);
  inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar = chr;
  inputBuffer[0].Event.KeyEvent.dwControlKeyState = 0;
  if ((HIBYTE(keyCode) & 1) == 1) {
    inputBuffer[0].Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
  }
  if ((HIBYTE(keyCode) & 2) == 2) {
    inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_CTRL_PRESSED;
  }
  if ((HIBYTE(keyCode) & 4) == 4) {
    inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED;
  }
  inputBuffer[1].EventType = inputBuffer[0].EventType;
  inputBuffer[1].Event.KeyEvent.bKeyDown = FALSE;
  inputBuffer[1].Event.KeyEvent.wRepeatCount = 1;
  inputBuffer[1].Event.KeyEvent.wVirtualKeyCode   = inputBuffer[0].Event.
                                                      KeyEvent.wVirtualKeyCode;
  inputBuffer[1].Event.KeyEvent.wVirtualScanCode  = inputBuffer[0].Event.
                                                      KeyEvent.wVirtualScanCode;
  inputBuffer[1].Event.KeyEvent.uChar.UnicodeChar = inputBuffer[0].Event.
                                                      KeyEvent.uChar.UnicodeChar;
  inputBuffer[1].Event.KeyEvent.dwControlKeyState = 0;
}

//----------------------------------------------------------------------------
static int testPipe()
{
  int didFail = 1;
  HANDLE inPipeRead = INVALID_HANDLE_VALUE;
  HANDLE inPipeWrite = INVALID_HANDLE_VALUE;
  HANDLE outPipeRead = INVALID_HANDLE_VALUE;
  HANDLE outPipeWrite = INVALID_HANDLE_VALUE;
  HANDLE errPipeRead = INVALID_HANDLE_VALUE;
  HANDLE errPipeWrite = INVALID_HANDLE_VALUE;
  UINT currentCodepage = GetConsoleCP();
  char buffer[200];
  char buffer2[200];
  try {
    if (!createPipe(&inPipeRead, &inPipeWrite) ||
        !createPipe(&outPipeRead, &outPipeWrite) ||
        !createPipe(&errPipeRead, &errPipeWrite)) {
      throw std::runtime_error("createFile failed!");
    }
    if (TestCodepage == CP_ACP) {
      TestCodepage = GetACP();
    }
    if (!SetConsoleCP(TestCodepage)) {
      throw std::runtime_error("SetConsoleCP failed!");
    }

    DWORD bytesWritten = 0;
    if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(),
                   (DWORD)encodedInputTestString.size(), &bytesWritten, NULL)
        || bytesWritten == 0) {
      throw std::runtime_error("WriteFile failed!");
    }

    if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) {
      try {
        DWORD status;
        if ((status = WaitForSingleObject(afterOutputEvent, 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#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#2 failed!");
        }
        if (memcmp(buffer, encodedTestString.c_str(),
                   encodedTestString.size()) == 0 &&
            memcmp(buffer + encodedTestString.size() + 1,
                   encodedInputTestString.c_str(),
                   encodedInputTestString.size()) == 0) {
          bytesRead = 0;
          if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead, NULL)
              || bytesRead == 0) {
            throw std::runtime_error("ReadFile#3 failed!");
          }
          buffer2[bytesRead - 1] = 0;
          didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
        }
        if (didFail != 0) {
          std::cerr << "Pipe's output didn't match expected output!" << std::endl;
          dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size());
          dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size());
          dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size());
        }
      } catch (const std::runtime_error &ex) {
        DWORD lastError = GetLastError();
        std::cerr << "In function testPipe, line " <<  __LINE__ << ": "
                  << ex.what() << std::endl;
        displayError(lastError);
      }
      finishProcess(didFail == 0);
    }
  } catch (const std::runtime_error &ex) {
    DWORD lastError = GetLastError();
    std::cerr << "In function testPipe, line " <<  __LINE__ << ": "
              << ex.what() << std::endl;
    displayError(lastError);
  }
  finishPipe(inPipeRead, inPipeWrite);
  finishPipe(outPipeRead, outPipeWrite);
  finishPipe(errPipeRead, errPipeWrite);
  SetConsoleCP(currentCodepage);
  return didFail;
}

//----------------------------------------------------------------------------
static int testFile()
{
  int didFail = 1;
  HANDLE inFile = INVALID_HANDLE_VALUE;
  HANDLE outFile = INVALID_HANDLE_VALUE;
  HANDLE errFile = INVALID_HANDLE_VALUE;
  try {
    if ((inFile = createFile(L"stdinFile.txt")) == INVALID_HANDLE_VALUE ||
        (outFile = createFile(L"stdoutFile.txt")) == INVALID_HANDLE_VALUE ||
        (errFile = createFile(L"stderrFile.txt")) == INVALID_HANDLE_VALUE) {
      throw std::runtime_error("createFile failed!");
    }
    DWORD bytesWritten = 0;
    char buffer[200];
    char buffer2[200];

    int length;
    if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1,
                                      buffer, sizeof(buffer),
                                      NULL, NULL)) == 0) {
      throw std::runtime_error("WideCharToMultiByte failed!");
    }
    buffer[length - 1] = '\n';
    if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL)
        || bytesWritten == 0) {
      throw std::runtime_error("WriteFile failed!");
    }
    if (SetFilePointer(inFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
      throw std::runtime_error("SetFilePointer failed!");
    }

    if (createProcess(inFile, outFile, errFile)) {
      DWORD bytesRead = 0;
      try {
        DWORD status;
        if ((status = WaitForSingleObject(afterOutputEvent, 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#1 failed!");
        }
        if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL)
            || bytesRead == 0) {
          throw std::runtime_error("ReadFile#1 failed!");
        }
        buffer[bytesRead - 1] = 0;
        if (memcmp(buffer, encodedTestString.c_str(),
                   encodedTestString.size()) == 0 &&
            memcmp(buffer + encodedTestString.size() + 1,
                   encodedInputTestString.c_str(),
                   encodedInputTestString.size() - 1) == 0) {
          bytesRead = 0;
          if (SetFilePointer(errFile, 0, 0, FILE_BEGIN)
              == INVALID_SET_FILE_POINTER) {
            throw std::runtime_error("SetFilePointer#2 failed!");
          }
          if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, NULL)
              || bytesRead == 0) {
            throw std::runtime_error("ReadFile#2 failed!");
          }
          buffer2[bytesRead - 1] = 0;
          didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
        }
        if (didFail != 0) {
          std::cerr << "File's output didn't match expected output!" << std::endl;
          dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size());
          dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size() - 1);
          dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size());
        }
      } catch (const std::runtime_error &ex) {
        DWORD lastError = GetLastError();
        std::cerr << "In function testFile, line " <<  __LINE__ << ": "
                  << ex.what() << std::endl;
        displayError(lastError);
      }
      finishProcess(didFail == 0);
    }
  } catch (const std::runtime_error &ex) {
    DWORD lastError = GetLastError();
    std::cerr << "In function testFile, line " <<  __LINE__ << ": "
              << ex.what() << std::endl;
    displayError(lastError);
  }
  finishFile(inFile);
  finishFile(outFile);
  finishFile(errFile);
  return didFail;
}

#ifndef _WIN32_WINNT_VISTA
# define _WIN32_WINNT_VISTA 0x0600
#endif

//----------------------------------------------------------------------------
static int testConsole()
{
  int didFail = 1;
  HANDLE parentIn = GetStdHandle(STD_INPUT_HANDLE);
  HANDLE parentOut = GetStdHandle(STD_OUTPUT_HANDLE);
  HANDLE parentErr = GetStdHandle(STD_ERROR_HANDLE);
  HANDLE hIn = parentIn;
  HANDLE hOut = parentOut;
  DWORD consoleMode;
  bool newConsole = false;
  bool forceNewConsole = false;
  bool restoreConsole = false;
  LPCWSTR TestFaceName = L"Lucida Console";
  const DWORD TestFontFamily = 0x00000036;
  const DWORD TestFontSize = 0x000c0000;
  HKEY hConsoleKey;
  WCHAR FaceName[200];
  FaceName[0] = 0;
  DWORD FaceNameSize = sizeof(FaceName);
  DWORD FontFamily = TestFontFamily;
  DWORD FontSize = TestFontSize;
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
# pragma warning (push)
# ifdef __INTEL_COMPILER
#  pragma warning (disable:1478)
# else
#  pragma warning (disable:4996)
# endif
#endif
  const bool isVistaOrGreater = LOBYTE(LOWORD(GetVersion())) >= HIBYTE(_WIN32_WINNT_VISTA);
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
# pragma warning (pop)
#endif
  if (!isVistaOrGreater) {
    if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE,
                      &hConsoleKey) == ERROR_SUCCESS) {
      DWORD dwordSize = sizeof(DWORD);
      if (RegQueryValueExW(hConsoleKey, L"FontFamily", NULL, NULL,
                           (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) {
        if (FontFamily != TestFontFamily) {
          RegQueryValueExW(hConsoleKey, L"FaceName", NULL, NULL,
                           (LPBYTE)FaceName, &FaceNameSize);
          RegQueryValueExW(hConsoleKey, L"FontSize", NULL, NULL,
                           (LPBYTE)&FontSize, &dwordSize);

          RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
                         (BYTE *)&TestFontFamily, sizeof(TestFontFamily));
          RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
                         (BYTE *)TestFaceName, (DWORD)((wcslen(TestFaceName) + 1) * sizeof(WCHAR)));
          RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
                         (BYTE *)&TestFontSize, sizeof(TestFontSize));

          restoreConsole = true;
          forceNewConsole = true;
        }
      } else {
        std::cerr << "RegGetValueW(FontFamily) failed!" << std::endl;
      }
      RegCloseKey(hConsoleKey);
    } else {
      std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!" << std::endl;
    }
  }
  if (forceNewConsole || GetConsoleMode(parentOut, &consoleMode) == 0) {
    // Not a real console, let's create new one.
    FreeConsole();
    if (!AllocConsole()) {
      std::cerr << "AllocConsole failed!" << std::endl;
      return didFail;
    }
    SECURITY_ATTRIBUTES securityAttributes;
    securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
    securityAttributes.bInheritHandle = TRUE;
    securityAttributes.lpSecurityDescriptor = NULL;
    hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
                       &securityAttributes, OPEN_EXISTING, 0, NULL);
    if (hIn == INVALID_HANDLE_VALUE) {
      DWORD lastError = GetLastError();
      std::cerr << "CreateFile(CONIN$)" << std::endl;
      displayError(lastError);
    }
    hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
                       &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);
    newConsole = true;
  }

#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
  if (isVistaOrGreater) {
    CONSOLE_FONT_INFOEX consoleFont;
    memset(&consoleFont, 0, sizeof(consoleFont));
    consoleFont.cbSize = sizeof(consoleFont);
    HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
    typedef BOOL (WINAPI *GetCurrentConsoleFontExFunc)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
    typedef BOOL (WINAPI *SetCurrentConsoleFontExFunc)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
    GetCurrentConsoleFontExFunc getConsoleFont = (GetCurrentConsoleFontExFunc)GetProcAddress(kernel32, "GetCurrentConsoleFontEx");
    SetCurrentConsoleFontExFunc setConsoleFont = (SetCurrentConsoleFontExFunc)GetProcAddress(kernel32, "SetCurrentConsoleFontEx");
    if (getConsoleFont(hOut, FALSE, &consoleFont)) {
      if (consoleFont.FontFamily != TestFontFamily) {
        consoleFont.FontFamily = TestFontFamily;
        wcscpy(consoleFont.FaceName, TestFaceName);
        if (!setConsoleFont(hOut, FALSE, &consoleFont)) {
          std::cerr << "SetCurrentConsoleFontEx failed!" << std::endl;
        }
      }
    } else {
      std::cerr << "GetCurrentConsoleFontEx failed!" << std::endl;
    }
  } else {
#endif
    if (restoreConsole && RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0,
                                        KEY_WRITE, &hConsoleKey) == ERROR_SUCCESS) {
      RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
                     (BYTE *)&FontFamily, sizeof(FontFamily));
      if (FaceName[0] != 0) {
        RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
                       (BYTE *)FaceName, FaceNameSize);
      } else {
        RegDeleteValueW(hConsoleKey, L"FaceName");
      }
      RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
                     (BYTE *)&FontSize, sizeof(FontSize));
      RegCloseKey(hConsoleKey);
    }
#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
  }
#endif

  if (createProcess(NULL, NULL, NULL)) {
    try {
      DWORD status;
      if ((status = WaitForSingleObject(beforeInputEvent, 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];
      memset(&inputBuffer, 0, sizeof(inputBuffer));
      unsigned int i;
      for (i = 0; i < (sizeof(UnicodeInputTestString) /
                       sizeof(UnicodeInputTestString[0]) - 1); i++) {
        writeInputKeyEvent(&inputBuffer[i*2], UnicodeInputTestString[i]);
      }
      writeInputKeyEvent(&inputBuffer[i*2], VK_RETURN);
      DWORD eventsWritten = 0;
      // We need to wait a bit before writing to console so child process have started waiting for input on stdin.
      Sleep(300);
      if (!WriteConsoleInputW(hIn, inputBuffer, sizeof(inputBuffer) /
                                                sizeof(inputBuffer[0]),
                              &eventsWritten) || eventsWritten == 0) {
        throw std::runtime_error("WriteConsoleInput failed!");
      }
      if ((status = WaitForSingleObject(afterOutputEvent, 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)) {
        throw std::runtime_error("GetConsoleScreenBufferInfo failed!");
      }

      COORD coord;
      DWORD charsRead = 0;
      coord.X = 0;
      coord.Y = screenBufferInfo.dwCursorPosition.Y - 4;
      WCHAR *outputBuffer = new WCHAR[screenBufferInfo.dwSize.X * 4];
      if (!ReadConsoleOutputCharacterW(hOut, outputBuffer,
          screenBufferInfo.dwSize.X * 4, coord, &charsRead)
          || charsRead == 0) {
        delete[] outputBuffer;
        throw std::runtime_error("ReadConsoleOutputCharacter failed!");
      }
      std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString);
      std::wstring wideInputTestString = kwsys::Encoding::ToWide(encodedInputTestString);
      if (memcmp(outputBuffer, wideTestString.c_str(),
                 wideTestString.size() * sizeof(wchar_t)) == 0 &&
          memcmp(outputBuffer + screenBufferInfo.dwSize.X * 1,
                 wideTestString.c_str(), wideTestString.size() * sizeof(wchar_t)) == 0 &&
          memcmp(outputBuffer + screenBufferInfo.dwSize.X * 2,
                 UnicodeInputTestString, sizeof(UnicodeInputTestString) -
                                         sizeof(WCHAR)) == 0 &&
          memcmp(outputBuffer + screenBufferInfo.dwSize.X * 3,
                 wideInputTestString.c_str(),
                 (wideInputTestString.size() - 1) * sizeof(wchar_t)) == 0
      ) {
        didFail = 0;
      } else {
        std::cerr << "Console's output didn't match expected output!" << std::endl;
        dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer, wideTestString.size());
        dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 1, wideTestString.size());
        dumpBuffers<wchar_t>(UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2, (sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR));
        dumpBuffers<wchar_t>(wideInputTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 3, wideInputTestString.size() - 1);
      }
      delete[] outputBuffer;
    } catch (const std::runtime_error &ex) {
      DWORD lastError = GetLastError();
      std::cerr << "In function testConsole, line " <<  __LINE__ << ": "
                << ex.what() << std::endl;
      displayError(lastError);
    }
    finishProcess(didFail == 0);
  }
  if (newConsole) {
    SetStdHandle(STD_INPUT_HANDLE, parentIn);
    SetStdHandle(STD_OUTPUT_HANDLE, parentOut);
    SetStdHandle(STD_ERROR_HANDLE, parentErr);
    CloseHandle(hIn);
    CloseHandle(hOut);
    FreeConsole();
  }
  return didFail;
}

#endif

//----------------------------------------------------------------------------
int testConsoleBuf(int, char*[])
{
  int ret = 0;

#if defined(_WIN32)
  beforeInputEvent = CreateEventW(NULL,
                       FALSE,  // auto-reset event
                       FALSE,  // initial state is nonsignaled
                       BeforeInputEventName);  // object name
  if (!beforeInputEvent) {
    std::cerr << "CreateEvent#1 failed " << GetLastError() << std::endl;
    return 1;
  }

  afterOutputEvent = CreateEventW(NULL, FALSE, FALSE, AfterOutputEventName);
  if (!afterOutputEvent) {
    std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl;
    return 1;
  }

  encodedTestString = kwsys::Encoding::ToNarrow(UnicodeTestString);
  encodedInputTestString = kwsys::Encoding::ToNarrow(UnicodeInputTestString);
  encodedInputTestString += "\n";

  ret |= testPipe();
  ret |= testFile();
  ret |= testConsole();

  CloseHandle(beforeInputEvent);
  CloseHandle(afterOutputEvent);
#endif

  return ret;
}
