Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/kernelbase/console.c | 12 ++++++++---- programs/conhost/conhost.c | 9 +++++++-- programs/conhost/conhost.h | 1 + 3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 52949ab7541..25e2447e61e 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -1608,7 +1608,7 @@ BOOL WINAPI ReadConsoleW( HANDLE handle, void *buffer, DWORD length, DWORD *coun SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } - if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(DWORD) + crc->nInitialChars * sizeof(WCHAR) ))) + if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(DWORD) + length * sizeof(WCHAR) ))) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return FALSE; @@ -1618,9 +1618,13 @@ BOOL WINAPI ReadConsoleW( HANDLE handle, void *buffer, DWORD length, DWORD *coun memcpy( tmp + sizeof(DWORD), buffer, crc->nInitialChars * sizeof(WCHAR) ); ret = console_ioctl( handle, IOCTL_CONDRV_READ_COMPLETION, tmp, sizeof(DWORD) + crc->nInitialChars * sizeof(WCHAR), - buffer, length * sizeof(WCHAR), - count ); - crc->dwConsoleKeyState = 0; + tmp, sizeof(DWORD) + length * sizeof(WCHAR), count ); + if (ret) + { + memcpy( &crc->dwConsoleKeyState, tmp, sizeof(DWORD) ); + *count -= sizeof(DWORD); + memcpy( buffer, tmp + sizeof(DWORD), *count ); + } HeapFree( GetProcessHeap(), 0, tmp ); } else diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index b7f59a25e0d..70ff054372e 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -457,6 +457,8 @@ static NTSTATUS read_complete( struct console *console, NTSTATUS status, const v req->signal = signal; req->read = 1; req->status = status; + if (console->read_ioctl == IOCTL_CONDRV_READ_COMPLETION) + wine_server_add_data( req, &console->key_state, sizeof(console->key_state) ); wine_server_add_data( req, buf, size ); status = wine_server_call( req ); } @@ -1250,6 +1252,7 @@ static NTSTATUS process_console_input( struct console *console ) struct edit_line *ctx = &console->edit_line; unsigned int i; WCHAR ctrl_value = FIRST_NON_CONTROL_CHAR; + unsigned int ctrl_keyvalue = 0;
switch (console->read_ioctl) { @@ -1295,6 +1298,7 @@ static NTSTATUS process_console_input( struct console *console ) (ctx->ctrl_mask & (1u << ir.Event.KeyEvent.uChar.UnicodeChar))) { ctrl_value = ir.Event.KeyEvent.uChar.UnicodeChar; + ctrl_keyvalue = ir.Event.KeyEvent.dwControlKeyState; ctx->status = STATUS_SUCCESS; continue; } @@ -1358,6 +1362,7 @@ static NTSTATUS process_console_input( struct console *console ) if (ctrl_value < FIRST_NON_CONTROL_CHAR) { edit_line_insert( console, &ctrl_value, 1 ); + console->key_state = ctrl_keyvalue; } else { @@ -2526,10 +2531,10 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code,
case IOCTL_CONDRV_READ_COMPLETION: if ((in_size < sizeof(DWORD)) || ((in_size - sizeof(DWORD)) % sizeof(WCHAR)) || - (*out_size % sizeof(WCHAR))) + (*out_size < sizeof(DWORD)) || ((*out_size - sizeof(DWORD)) % sizeof(WCHAR))) return STATUS_INVALID_PARAMETER; ensure_tty_input_thread( console ); - status = read_console( console, code, *out_size, + status = read_console( console, code, *out_size - sizeof(DWORD), (const WCHAR*)((const char*)in_data + sizeof(DWORD)), (in_size - sizeof(DWORD)) / sizeof(WCHAR), *(DWORD*)in_data ); diff --git a/programs/conhost/conhost.h b/programs/conhost/conhost.h index d150fd0acad..479a1aa065e 100644 --- a/programs/conhost/conhost.h +++ b/programs/conhost/conhost.h @@ -88,6 +88,7 @@ struct console unsigned int read_ioctl; /* current read ioctl */ size_t pending_read; /* size of pending read buffer */ struct edit_line edit_line; /* edit line context */ + unsigned int key_state; struct console_window *window; WCHAR *title; /* console title */ struct history_line **history; /* lines history */