Module: wine Branch: master Commit: 8231dbf04961356a74bf026cfd3e359605ddc81e URL: https://source.winehq.org/git/wine.git/?a=commit;h=8231dbf04961356a74bf026cf...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Aug 20 23:51:05 2020 +0200
condrv: Implement initial ioctl processing.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
programs/conhost/conhost.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 27283e415b..2014ca2260 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -25,6 +25,7 @@ #include <winuser.h> #include <winternl.h>
+#include "wine/server.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(conhost); @@ -34,6 +35,68 @@ struct console HANDLE server; /* console server handle */ };
+static void *ioctl_buffer; +static size_t ioctl_buffer_size; + +static void *alloc_ioctl_buffer( size_t size ) +{ + if (size > ioctl_buffer_size) + { + void *new_buffer; + if (!(new_buffer = realloc( ioctl_buffer, size ))) return NULL; + ioctl_buffer = new_buffer; + ioctl_buffer_size = size; + } + return ioctl_buffer; +} + +static NTSTATUS console_input_ioctl( struct console *console, unsigned int code, const void *in_data, + size_t in_size, size_t *out_size ) +{ + FIXME( "unsupported ioctl %x\n", code ); + return STATUS_NOT_SUPPORTED; +} + +static NTSTATUS process_console_ioctls( struct console *console ) +{ + size_t out_size = 0, in_size; + unsigned int code; + NTSTATUS status = STATUS_SUCCESS; + + for (;;) + { + if (status) out_size = 0; + + SERVER_START_REQ( get_next_console_request ) + { + req->handle = wine_server_obj_handle( console->server ); + req->status = status; + wine_server_add_data( req, ioctl_buffer, out_size ); + wine_server_set_reply( req, ioctl_buffer, ioctl_buffer_size ); + status = wine_server_call( req ); + code = reply->code; + out_size = reply->out_size; + in_size = wine_server_reply_size( reply ); + } + SERVER_END_REQ; + + if (status == STATUS_PENDING) return STATUS_SUCCESS; + if (status == STATUS_BUFFER_OVERFLOW) + { + if (!alloc_ioctl_buffer( out_size )) return STATUS_NO_MEMORY; + status = STATUS_SUCCESS; + continue; + } + if (status) + { + TRACE( "failed to get next request: %#x\n", status ); + return status; + } + + status = console_input_ioctl( console, code, ioctl_buffer, in_size, &out_size ); + } +} + static int main_loop( struct console *console, HANDLE signal ) { HANDLE signal_event = NULL; @@ -52,6 +115,8 @@ static int main_loop( struct console *console, HANDLE signal ) if (status && status != STATUS_PENDING) return 1; }
+ if (!alloc_ioctl_buffer( 4096 )) return 1; + wait_handles[wait_cnt++] = console->server; if (signal) wait_handles[wait_cnt++] = signal_event;
@@ -62,8 +127,8 @@ static int main_loop( struct console *console, HANDLE signal ) switch (res) { case WAIT_OBJECT_0: - FIXME( "console ioctls not yet implemented\n" ); - return 1; + if (process_console_ioctls( console )) return 0; + break;
case WAIT_OBJECT_0 + 1: if (signal_io.Status || signal_io.Information != sizeof(signal_id))