Jacek Caban : server: Introduce IOCTL_CONDRV_BIND_PID ioctl.

Alexandre Julliard julliard at winehq.org
Wed Sep 16 15:37:34 CDT 2020


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 16 20:39:26 2020 +0200

server: Introduce IOCTL_CONDRV_BIND_PID ioctl.

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

---

 include/wine/condrv.h |  3 ++
 server/console.c      | 81 +++++++++++++++++++++++++++++++++++++++++++++++++--
 server/trace.c        |  1 +
 3 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/include/wine/condrv.h b/include/wine/condrv.h
index 1b3b918504..e5ba9c7444 100644
--- a/include/wine/condrv.h
+++ b/include/wine/condrv.h
@@ -49,6 +49,9 @@
 #define IOCTL_CONDRV_FILL_OUTPUT           CTL_CODE(FILE_DEVICE_CONSOLE, 36, METHOD_BUFFERED, FILE_WRITE_ACCESS)
 #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)
+
 /* console renderer ioctls */
 #define IOCTL_CONDRV_GET_RENDERER_EVENTS   CTL_CODE(FILE_DEVICE_CONSOLE, 70, METHOD_BUFFERED, FILE_READ_ACCESS)
 #define IOCTL_CONDRV_ATTACH_RENDERER       CTL_CODE(FILE_DEVICE_CONSOLE, 71, METHOD_BUFFERED, FILE_READ_ACCESS)
diff --git a/server/console.c b/server/console.c
index 95c087ae15..b9fb0fb448 100644
--- a/server/console.c
+++ b/server/console.c
@@ -362,12 +362,15 @@ static const struct object_ops console_device_ops =
 struct console_connection
 {
     struct object         obj;         /* object header */
+    struct fd            *fd;          /* pseudo-fd for ioctls */
 };
 
 static void console_connection_dump( struct object *obj, int verbose );
+static struct fd *console_connection_get_fd( struct object *obj );
 static struct object *console_connection_open_file( struct object *obj, unsigned int access,
                                                     unsigned int sharing, unsigned int options );
 static int console_connection_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
+static void console_connection_destroy( struct object *obj );
 
 static const struct object_ops console_connection_ops =
 {
@@ -379,7 +382,7 @@ static const struct object_ops console_connection_ops =
     NULL,                             /* signaled */
     no_satisfied,                     /* satisfied */
     no_signal,                        /* signal */
-    no_get_fd,                        /* get_fd */
+    console_connection_get_fd,        /* get_fd */
     no_map_access,                    /* map_access */
     default_get_sd,                   /* get_sd */
     default_set_sd,                   /* set_sd */
@@ -389,7 +392,24 @@ static const struct object_ops console_connection_ops =
     console_connection_open_file,     /* open_file */
     no_kernel_obj_list,               /* get_kernel_obj_list */
     console_connection_close_handle,  /* close_handle */
-    no_destroy                        /* destroy */
+    console_connection_destroy        /* destroy */
+};
+
+static int console_connection_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
+
+static const struct fd_ops console_connection_fd_ops =
+{
+    default_fd_get_poll_events,   /* get_poll_events */
+    default_poll_event,           /* poll_event */
+    console_get_fd_type,          /* get_fd_type */
+    no_fd_read,                   /* read */
+    no_fd_write,                  /* write */
+    no_fd_flush,                  /* flush */
+    no_fd_get_file_info,          /* get_file_info */
+    no_fd_get_volume_info,        /* get_volume_info */
+    console_connection_ioctl,     /* ioctl */
+    default_fd_queue_async,       /* queue_async */
+    default_fd_reselect_async     /* reselect_async */
 };
 
 static struct list screen_buffer_list = LIST_INIT(screen_buffer_list);
@@ -1329,6 +1349,11 @@ static struct object *create_console_connection( struct console_input *console )
     }
 
     if (!(connection = alloc_object( &console_connection_ops ))) return NULL;
+    if (!(connection->fd = alloc_pseudo_fd( &console_connection_fd_ops, &connection->obj, 0 )))
+    {
+        release_object( connection );
+        return NULL;
+    }
 
     if (console)
     {
@@ -2248,6 +2273,46 @@ static int console_input_events_ioctl( struct fd *fd, ioctl_code_t code, struct
     }
 }
 
+static int console_connection_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
+{
+    struct console_connection *console_connection = get_fd_user( fd );
+
+    switch (code)
+    {
+    case IOCTL_CONDRV_BIND_PID:
+        {
+            struct process *process;
+            unsigned int pid;
+            if (get_req_data_size() != sizeof(unsigned int))
+            {
+                set_error( STATUS_INVALID_PARAMETER );
+                return 0;
+            }
+            if (current->process->console)
+            {
+                set_error( STATUS_INVALID_HANDLE );
+                return 0;
+            }
+
+            pid = *(unsigned int *)get_req_data();
+            if (pid == ATTACH_PARENT_PROCESS) pid = current->process->parent_id;
+            if (!(process = get_process_from_id( pid ))) return 0;
+
+            if (process->console)
+            {
+                current->process->console = (struct console_input *)grab_object( process->console );
+                process->console->num_proc++;
+            }
+            else set_error( STATUS_ACCESS_DENIED );
+            release_object( process );
+            return !get_error();
+        }
+
+    default:
+        return default_fd_ioctl( console_connection->fd, code, async );
+    }
+}
+
 static int console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
 {
     struct console_server *server = get_fd_user( fd );
@@ -2282,6 +2347,12 @@ static void console_connection_dump( struct object *obj, int verbose )
     fputs( "console connection\n", stderr );
 }
 
+static struct fd *console_connection_get_fd( struct object *obj )
+{
+    struct console_connection *connection = (struct console_connection *)obj;
+    return (struct fd *)grab_object( connection->fd );
+}
+
 static struct object *console_connection_open_file( struct object *obj, unsigned int access,
                                                     unsigned int sharing, unsigned int options )
 {
@@ -2294,6 +2365,12 @@ static int console_connection_close_handle( struct object *obj, struct process *
     return 1;
 }
 
+static void console_connection_destroy( struct object *obj )
+{
+    struct console_connection *connection = (struct console_connection *)obj;
+    if (connection->fd) release_object( connection->fd );
+}
+
 static struct object_type *console_device_get_type( struct object *obj )
 {
     static const WCHAR name[] = {'D','e','v','i','c','e'};
diff --git a/server/trace.c b/server/trace.c
index c93e4fe3b4..990515d635 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -116,6 +116,7 @@ static void dump_ioctl_code( const char *prefix, const ioctl_code_t *code )
 #define CASE(c) case c: fprintf( stderr, "%s%s", prefix, #c ); break
         CASE(IOCTL_CONDRV_ACTIVATE);
         CASE(IOCTL_CONDRV_ATTACH_RENDERER);
+        CASE(IOCTL_CONDRV_BIND_PID);
         CASE(IOCTL_CONDRV_CTRL_EVENT);
         CASE(IOCTL_CONDRV_FILL_OUTPUT);
         CASE(IOCTL_CONDRV_GET_INPUT_INFO);




More information about the wine-cvs mailing list