This implements the method only with empty flags, nowait (0x2) and all flags on noremove(0x1) | nowait(0x2)
-- v3: kernel32: Implement ReadConsoleInputEx
From: Jayson Reis santosdosreis@gmail.com
This implements the method only with empty flags, nowait (0x2) and all flags on noremove(0x1) | nowait(0x2) --- dlls/kernel32/kernel32.spec | 4 +-- dlls/kernel32/tests/console.c | 40 +++++++++++++++++++++++++ dlls/kernelbase/console.c | 53 +++++++++++++++++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 4 +-- 4 files changed, 97 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index caa6c92b653..7d008cbaccd 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -1218,8 +1218,8 @@ @ stdcall -import RaiseFailFastException(ptr ptr long) @ stdcall -import ReadConsoleA(long ptr long ptr ptr) @ stdcall -import ReadConsoleInputA(long ptr long ptr) -@ stub ReadConsoleInputExA -@ stub ReadConsoleInputExW +@ stdcall -import ReadConsoleInputExA(long ptr long ptr long) +@ stdcall -import ReadConsoleInputExW(long ptr long ptr long) @ stdcall -import ReadConsoleInputW(long ptr long ptr) @ stdcall -import ReadConsoleOutputA(long ptr long long ptr) @ stdcall -import ReadConsoleOutputAttribute(long ptr long long ptr) diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 398b818776a..8c094a6495f 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -35,6 +35,8 @@ static DWORD (WINAPI *pGetConsoleProcessList)(LPDWORD, DWORD); static HANDLE (WINAPI *pOpenConsoleW)(LPCWSTR,DWORD,BOOL,DWORD); static BOOL (WINAPI *pSetConsoleInputExeNameA)(LPCSTR); static BOOL (WINAPI *pVerifyConsoleIoHandle)(HANDLE handle); +static BOOL (WINAPI *pReadConsoleInputExA)(HANDLE handle, INPUT_RECORD *buffer, + DWORD length, DWORD *count, USHORT flags);
static BOOL skip_nt;
@@ -81,6 +83,7 @@ static void init_function_pointers(void) KERNEL32_GET_PROC(OpenConsoleW); KERNEL32_GET_PROC(SetConsoleInputExeNameA); KERNEL32_GET_PROC(VerifyConsoleIoHandle); + KERNEL32_GET_PROC(ReadConsoleInputExA);
#undef KERNEL32_GET_PROC } @@ -3426,6 +3429,41 @@ static void test_ReadConsole(HANDLE input) CloseHandle(output); }
+static void test_ReadConsoleInputEx(HANDLE input) +{ + DWORD ret, count; + INPUT_RECORD buf; + + ret = pReadConsoleInputExA(input, &buf, 1, &count, 0x0001); + if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { + skip("ReadConsoleInputExA not implemented\n"); + } + + // When empty, just return as is without blocking + ret = pReadConsoleInputExA(input, &buf, 1, &count, 0x0002); + ok(ret, "ReadConsoleInputExA nowait failed %ld %ld \n", count, GetLastError()); + + memset(&buf, 0, sizeof(buf)); + buf.EventType = MOUSE_EVENT; + buf.Event.MouseEvent.dwEventFlags = DOUBLE_CLICK; + ret = WriteConsoleInputA(input, &buf, 1, &count); + ok(ret, "got error %lu\n", GetLastError()); + + memset(&buf, 0, sizeof(buf)); + ret = pReadConsoleInputExA(input, &buf, 1, &count, 0x0000); + ok(ret && buf.EventType == MOUSE_EVENT, "ReadConsoleInputExA failed %#lx \n", GetLastError()); + + memset(&buf, 0, sizeof(buf)); + buf.EventType = MOUSE_EVENT; + buf.Event.MouseEvent.dwEventFlags = DOUBLE_CLICK; + ret = WriteConsoleInputA(input, &buf, 1, &count); + ok(ret, "got error %lu\n", GetLastError()); + + memset(&buf, 0, sizeof(buf)); + ret = pReadConsoleInputExA(input, &buf, 1, &count, 0x0002); + ok(ret && buf.EventType == MOUSE_EVENT, "ReadConsoleInputExA failed %#lx \n", GetLastError()); +} + static void test_GetCurrentConsoleFont(HANDLE std_output) { BOOL ret; @@ -5826,6 +5864,8 @@ START_TEST(console) if (!ret) return;
test_ReadConsole(hConIn); + test_ReadConsoleInputEx(hConIn); + /* Non interactive tests */ testCursor(hConOut, sbi.dwSize); /* test parameters (FIXME: test functionality) */ diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 8c90eb321df..eadecd6130f 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -1821,6 +1821,59 @@ BOOL WINAPI ReadConsoleInputW( HANDLE handle, INPUT_RECORD *buffer, DWORD length }
+ +/*********************************************************************** + * ReadConsoleInputExW (kernelbase.@) + */ +BOOL WINAPI ReadConsoleInputExW( HANDLE handle, INPUT_RECORD *buffer, DWORD length, DWORD *count, USHORT flags ) +{ + USHORT no_remove = 1; + USHORT no_wait = 2; + USHORT all = 3; + + TRACE( "(%p,%p,%ld,%p,%#x).\n", handle, buffer, length, count, flags ); + /* if all flags are set, it is the same as calling PeekConsoleInputW */ + if ((flags & all) == all) + return PeekConsoleInputW( handle, buffer, length, count) ; + + if (flags == no_wait) { + /* TODO: Does it need to be the exact count that the user supplied? */ + if (PeekConsoleInputW( handle, buffer, 1, count) && *count > 0) { + return ReadConsoleInputExW( handle, buffer, length, count, 0 ); + } + return TRUE; + } + + if (flags == no_remove) { + FIXME("ReadConsoleInputExW not implemented for NOREMOVE"); + SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; + } + + if (!console_ioctl( handle, IOCTL_CONDRV_READ_INPUT, NULL, 0, + buffer, length * sizeof(*buffer), count )) + return FALSE; + *count /= sizeof(*buffer); + return TRUE; +} + + + +/*********************************************************************** + * ReadConsoleInputExA (kernelbase.@) + */ +BOOL WINAPI ReadConsoleInputExA( HANDLE handle, INPUT_RECORD *buffer, DWORD length, DWORD *count, USHORT flags ) +{ + DWORD read; + + if (!ReadConsoleInputExW( handle, buffer, length, &read, flags )) return FALSE; + input_records_WtoA( buffer, read ); + if (count) *count = read; + return TRUE; +} + + + /****************************************************************************** * WriteConsoleInputA (kernelbase.@) */ diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index fd9868fb69e..45ee0e340f3 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1280,8 +1280,8 @@ @ stdcall ReOpenFile(ptr long long long) @ stdcall ReadConsoleA(long ptr long ptr ptr) @ stdcall ReadConsoleInputA(long ptr long ptr) -@ stub ReadConsoleInputExA -@ stub ReadConsoleInputExW +@ stdcall ReadConsoleInputExA(long ptr long ptr long) +@ stdcall ReadConsoleInputExW(long ptr long ptr long) @ stdcall ReadConsoleInputW(long ptr long ptr) @ stdcall ReadConsoleOutputA(long ptr long long ptr) @ stdcall ReadConsoleOutputAttribute(long ptr long long ptr)