diff --git a/src/win/tty.c b/src/win/tty.c index e6077a9901..b18992b045 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -827,6 +827,41 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, } +static uint16_t uv_get_os_version() +{ + OSVERSIONINFOEX osvi; + + memset(&osvi, 0, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + if (GetVersionEx((OSVERSIONINFO*) &osvi) == FALSE) { + uv_fatal_error(GetLastError(), "GetVersionEx"); + return 0; + } else { + return ((osvi.dwMajorVersion & 0xF) << 8) | (osvi.dwMinorVersion & 0xF); + } +} + + +static void uv_tty_simulate_enter_key_press(uv_tty_t* handle) { + DWORD events_written; + INPUT_RECORD input; + + assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); + + events_written = 0; + input.EventType = KEY_EVENT; + input.Event.KeyEvent.bKeyDown = TRUE; + input.Event.KeyEvent.dwControlKeyState = 0; + input.Event.KeyEvent.uChar.UnicodeChar = L'\r'; + input.Event.KeyEvent.wRepeatCount = 1; + input.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + input.Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC); + WriteConsoleInputW(handle->handle, &input, 1, &events_written); + input.Event.KeyEvent.bKeyDown = FALSE; + WriteConsoleInputW(handle->handle, &input, 1, &events_written); +} + + int uv_tty_read_stop(uv_tty_t* handle) { uv_loop_t* loop = handle->loop; @@ -847,12 +882,15 @@ int uv_tty_read_stop(uv_tty_t* handle) { /* Cancel line-buffered read */ if (handle->read_line_handle != NULL) { + if(uv_get_os_version() >= _WIN32_WINNT_WIN8) { + /* Forces any pending ReadConsole to exit before we close the handle */ + uv_tty_simulate_enter_key_press(handle); + } /* Closing this handle will cancel the ReadConsole operation */ CloseHandle(handle->read_line_handle); handle->read_line_handle = NULL; } - return 0; } diff --git a/src/win/winapi.h b/src/win/winapi.h index 003c14bad4..88577788a6 100644 --- a/src/win/winapi.h +++ b/src/win/winapi.h @@ -4385,6 +4385,25 @@ typedef NTSTATUS (NTAPI *sNtQuerySystemInformation) } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY; #endif +/* from Windows8 SDK sdkddkver.h */ +#if !defined(_INC_SDKDDKVER) +# define _WIN32_WINNT_NT4 0x0400 +# define _WIN32_WINNT_WIN2K 0x0500 +# define _WIN32_WINNT_WINXP 0x0501 +# define _WIN32_WINNT_WS03 0x0502 +# define _WIN32_WINNT_WIN6 0x0600 +# define _WIN32_WINNT_VISTA 0x0600 +# define _WIN32_WINNT_WS08 0x0600 +# define _WIN32_WINNT_LONGHORN 0x0600 +# define _WIN32_WINNT_WIN7 0x0601 +# define _WIN32_WINNT_WIN8 0x0602 +#endif + +/* for Windows7 SDK users */ +#if !defined(_WIN32_WINNT_WIN8) +# define _WIN32_WINNT_WIN8 0x0602 +#endif + /* from wincon.h */ #ifndef ENABLE_INSERT_MODE # define ENABLE_INSERT_MODE 0x20 diff --git a/uv.gyp b/uv.gyp index da254a1ab4..16a2a8af40 100644 --- a/uv.gyp +++ b/uv.gyp @@ -116,6 +116,7 @@ '-liphlpapi.lib', '-lpsapi.lib', '-lshell32.lib', + '-luser32.lib', '-lws2_32.lib' ], },