Jacek Caban : server: Introduce IOCTL_CONDRV_SETUP_INPUT ioctl.

Alexandre Julliard julliard at winehq.org
Mon Sep 21 15:12:16 CDT 2020


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Sep 21 17:06:26 2020 +0200

server: Introduce IOCTL_CONDRV_SETUP_INPUT ioctl.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 include/wine/condrv.h |  5 ++++-
 server/console.c      | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++
 server/trace.c        |  1 +
 3 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/include/wine/condrv.h b/include/wine/condrv.h
index e5ba9c7444..b82531280b 100644
--- a/include/wine/condrv.h
+++ b/include/wine/condrv.h
@@ -50,7 +50,10 @@
 #define IOCTL_CONDRV_SCROLL                CTL_CODE(FILE_DEVICE_CONSOLE, 37, METHOD_BUFFERED, FILE_WRITE_ACCESS)
 
 /* console connection ioctls */
-#define IOCTL_CONDRV_BIND_PID              CTL_CODE(FILE_DEVICE_CONSOLE, 51, METHOD_BUFFERED, FILE_READ_PROPERTIES)
+#define IOCTL_CONDRV_BIND_PID              CTL_CODE(FILE_DEVICE_CONSOLE, 51, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/* console server ioctls */
+#define IOCTL_CONDRV_SETUP_INPUT           CTL_CODE(FILE_DEVICE_CONSOLE, 60, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
 /* console renderer ioctls */
 #define IOCTL_CONDRV_GET_RENDERER_EVENTS   CTL_CODE(FILE_DEVICE_CONSOLE, 70, METHOD_BUFFERED, FILE_READ_ACCESS)
diff --git a/server/console.c b/server/console.c
index a946abacbb..2a5d7733fe 100644
--- a/server/console.c
+++ b/server/console.c
@@ -28,6 +28,8 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <signal.h>
+#include <sys/ioctl.h>
+#include <termios.h>
 
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
@@ -198,6 +200,8 @@ struct console_server
     struct list           queue;       /* ioctl queue */
     struct list           read_queue;  /* blocking read queue */
     int                   busy;        /* flag if server processing an ioctl */
+    int                   term_fd;     /* UNIX terminal fd */
+    struct termios        termios;     /* original termios */
 };
 
 static void console_server_dump( struct object *obj, int verbose );
@@ -665,6 +669,13 @@ static void disconnect_console_server( struct console_server *server )
         console_host_ioctl_terminate( call, STATUS_CANCELLED );
     }
 
+    if (server->term_fd != -1)
+    {
+        tcsetattr( server->term_fd, TCSANOW, &server->termios );
+        close( server->term_fd );
+        server->term_fd = -1;
+    }
+
     if (server->console)
     {
         assert( server->console->server == server );
@@ -1772,6 +1783,7 @@ static struct object *create_console_server( void )
     if (!(server = alloc_object( &console_server_ops ))) return NULL;
     server->console = NULL;
     server->busy    = 0;
+    server->term_fd = -1;
     list_init( &server->queue );
     list_init( &server->read_queue );
     server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT );
@@ -2337,6 +2349,53 @@ static int console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async
             return !get_error();
         }
 
+    case IOCTL_CONDRV_SETUP_INPUT:
+        {
+            struct termios term;
+            obj_handle_t handle;
+            struct file *file;
+            int unix_fd;
+
+            if (get_req_data_size() != sizeof(unsigned int) || get_reply_max_size())
+            {
+                set_error( STATUS_INVALID_PARAMETER );
+                return 0;
+            }
+            if (server->term_fd != -1)
+            {
+                tcsetattr( server->term_fd, TCSANOW, &server->termios );
+                close( server->term_fd );
+                server->term_fd = -1;
+            }
+            handle = *(unsigned int *)get_req_data();
+            if (!handle) return 1;
+            if (!(file = get_file_obj( current->process, handle, FILE_READ_DATA  )))
+            {
+                return 0;
+            }
+            unix_fd = get_file_unix_fd( file );
+            release_object( file );
+
+            if (tcgetattr( unix_fd, &server->termios ))
+            {
+                file_set_error();
+                return 0;
+            }
+            term = server->termios;
+            term.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
+            term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+            term.c_cflag &= ~(CSIZE | PARENB);
+            term.c_cflag |= CS8;
+            term.c_cc[VMIN] = 1;
+            term.c_cc[VTIME] = 0;
+            if (tcsetattr( unix_fd, TCSANOW, &term ) || (server->term_fd = dup( unix_fd )) == -1)
+            {
+                file_set_error();
+                return 0;
+            }
+            return 1;
+        }
+
     default:
         set_error( STATUS_INVALID_HANDLE );
         return 0;
diff --git a/server/trace.c b/server/trace.c
index 91e3208c49..707a952357 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -129,6 +129,7 @@ static void dump_ioctl_code( const char *prefix, const ioctl_code_t *code )
         CASE(IOCTL_CONDRV_READ_OUTPUT);
         CASE(IOCTL_CONDRV_SET_MODE);
         CASE(IOCTL_CONDRV_SET_OUTPUT_INFO);
+        CASE(IOCTL_CONDRV_SETUP_INPUT);
         CASE(IOCTL_CONDRV_WRITE_CONSOLE);
         CASE(IOCTL_CONDRV_WRITE_INPUT);
         CASE(IOCTL_CONDRV_WRITE_OUTPUT);




More information about the wine-cvs mailing list