Jacek Caban : conhost: Implement IOCTL_CONDRV_READ_INPUT.
Alexandre Julliard
julliard at winehq.org
Wed Aug 26 15:24:44 CDT 2020
Module: wine
Branch: master
Commit: e703e2da39a411e1f0aaf6d5ff7a1fa36edb87cd
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e703e2da39a411e1f0aaf6d5ff7a1fa36edb87cd
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Aug 25 14:52:58 2020 +0200
conhost: Implement IOCTL_CONDRV_READ_INPUT.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/kernel32/tests/console.c | 1 +
programs/conhost/conhost.c | 53 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c
index afc91ecfce..09c48ee705 100644
--- a/dlls/kernel32/tests/console.c
+++ b/dlls/kernel32/tests/console.c
@@ -3968,6 +3968,7 @@ static void test_pseudo_console_child(HANDLE input)
ok(ret, "SetConsoleMode failed: %u\n", GetLastError());
test_console_title();
+ test_WriteConsoleInputW(input);
}
static DWORD WINAPI read_pipe_proc( void *handle )
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c
index 525ca9058e..d65a605f04 100644
--- a/programs/conhost/conhost.c
+++ b/programs/conhost/conhost.c
@@ -48,6 +48,7 @@ struct console
INPUT_RECORD *records; /* input records */
unsigned int record_count; /* number of input records */
unsigned int record_size; /* size of input records buffer */
+ size_t pending_read; /* size of pending read buffer */
WCHAR *title; /* console title */
size_t title_len; /* length of console title */
struct history_line **history; /* lines history */
@@ -75,6 +76,36 @@ static void *alloc_ioctl_buffer( size_t size )
return ioctl_buffer;
}
+static NTSTATUS read_console_input( struct console *console, size_t out_size )
+{
+ size_t count = min( out_size / sizeof(INPUT_RECORD), console->record_count );
+ NTSTATUS status;
+
+ TRACE("count %u\n", count);
+
+ SERVER_START_REQ( get_next_console_request )
+ {
+ req->handle = wine_server_obj_handle( console->server );
+ req->signal = count < console->record_count;
+ req->read = 1;
+ req->status = STATUS_SUCCESS;
+ wine_server_add_data( req, console->records, count * sizeof(*console->records) );
+ status = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ if (status)
+ {
+ ERR( "failed: %#x\n", status );
+ return status;
+ }
+
+ if (count < console->record_count)
+ memmove( console->records, console->records + count,
+ (console->record_count - count) * sizeof(*console->records) );
+ console->record_count -= count;
+ return STATUS_SUCCESS;
+}
+
/* add input events to a console input queue */
static NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *records,
unsigned int count )
@@ -115,6 +146,11 @@ static NTSTATUS write_console_input( struct console *console, const INPUT_RECORD
}
}
console->record_count += count;
+ if (count && console->pending_read)
+ {
+ read_console_input( console, console->pending_read );
+ console->pending_read = 0;
+ }
return STATUS_SUCCESS;
}
@@ -156,6 +192,23 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code,
TRACE( "set %x mode\n", console->mode );
return STATUS_SUCCESS;
+ case IOCTL_CONDRV_READ_INPUT:
+ {
+ unsigned int blocking;
+ NTSTATUS status;
+ if (in_size && in_size != sizeof(blocking)) return STATUS_INVALID_PARAMETER;
+ blocking = in_size && *(unsigned int *)in_data;
+ if (blocking && !console->record_count && *out_size)
+ {
+ TRACE( "pending read" );
+ console->pending_read = *out_size;
+ return STATUS_PENDING;
+ }
+ status = read_console_input( console, *out_size );
+ *out_size = 0;
+ return status;
+ }
+
case IOCTL_CONDRV_WRITE_INPUT:
if (in_size % sizeof(INPUT_RECORD) || *out_size) return STATUS_INVALID_PARAMETER;
return write_console_input( console, in_data, in_size / sizeof(INPUT_RECORD) );
More information about the wine-cvs
mailing list