Jacek Caban : condrv: Implement initial ioctl processing.

Alexandre Julliard julliard at winehq.org
Fri Aug 21 16:43:26 CDT 2020


Module: wine
Branch: master
Commit: 8231dbf04961356a74bf026cfd3e359605ddc81e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=8231dbf04961356a74bf026cfd3e359605ddc81e

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Aug 20 23:51:05 2020 +0200

condrv: Implement initial ioctl processing.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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))




More information about the wine-cvs mailing list