Module: wine Branch: master Commit: 3e115d244ed2e2018bfe4a7fa5a9ea7a37b2c8ea URL: https://source.winehq.org/git/wine.git/?a=commit;h=3e115d244ed2e2018bfe4a7fa...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Sep 16 20:39:26 2020 +0200
server: Introduce IOCTL_CONDRV_BIND_PID ioctl.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);