conhost: Implement IOCTL_CONDRV_READ_INPUT.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2020-08-25 14:52:58 +02:00 committed by Alexandre Julliard
parent b75ae8c31e
commit e703e2da39
2 changed files with 54 additions and 0 deletions

View File

@ -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 )

View File

@ -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) );