From 6898bdca94cde73bd8d8b88d99153a731f6a7a6b Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 25 Jun 2020 22:26:35 +0200 Subject: [PATCH] server: Introduce ConDrv device. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- server/console.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ server/directory.c | 6 +++- server/file.h | 1 + 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/server/console.c b/server/console.c index 302be6a1c1a..2e7845adbe2 100644 --- a/server/console.c +++ b/server/console.c @@ -212,6 +212,35 @@ static const struct fd_ops console_fd_ops = default_fd_reselect_async /* reselect_async */ }; +static struct object_type *console_device_get_type( struct object *obj ); +static void console_device_dump( struct object *obj, int verbose ); +static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); +static struct object *console_device_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ); + +static const struct object_ops console_device_ops = +{ + sizeof(struct object), /* size */ + console_device_dump, /* dump */ + console_device_get_type, /* get_type */ + no_add_queue, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + no_satisfied, /* satisfied */ + no_signal, /* signal */ + no_get_fd, /* get_fd */ + default_fd_map_access, /* map_access */ + default_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ + console_device_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ + console_device_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ +}; + static struct list screen_buffer_list = LIST_INIT(screen_buffer_list); static const char_info_t empty_char_info = { ' ', 0x000f }; /* white on black space */ @@ -1440,6 +1469,55 @@ static void scroll_console_output( struct screen_buffer *screen_buffer, int xsrc console_input_events_append( screen_buffer->input, &evt ); } +static struct object_type *console_device_get_type( struct object *obj ) +{ + static const WCHAR name[] = {'D','e','v','i','c','e'}; + static const struct unicode_str str = { name, sizeof(name) }; + return get_object_type( &str ); +} + +static void console_device_dump( struct object *obj, int verbose ) +{ + fputs( "Console device\n", stderr ); +} + +static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) +{ + static const WCHAR consoleW[] = {'C','o','n','s','o','l','e'}; + + if (name->len == sizeof(consoleW) && !memcmp( name->str, consoleW, name->len )) + { + name->len = 0; + return grab_object( obj ); + } + + return NULL; +} + +static struct object *console_device_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ) +{ + int is_output; + access = default_fd_map_access( obj, access ); + is_output = access & FILE_WRITE_DATA; + if (!current->process->console || (is_output && !current->process->console)) + { + set_error( STATUS_INVALID_HANDLE ); + return NULL; + } + if (is_output && (access & FILE_READ_DATA)) + { + set_error( STATUS_INVALID_PARAMETER ); + return NULL; + } + return is_output ? grab_object( current->process->console->active ) : grab_object( current->process->console ); +} + +struct object *create_console_device( struct object *root, const struct unicode_str *name ) +{ + return create_named_object( root, &console_device_ops, name, 0, NULL ); +} + /* allocate a console for the renderer */ DECL_HANDLER(alloc_console) { diff --git a/server/directory.c b/server/directory.c index 74cbb3ca974..9932a633533 100644 --- a/server/directory.c +++ b/server/directory.c @@ -356,9 +356,11 @@ void init_directories(void) /* devices */ static const WCHAR named_pipeW[] = {'N','a','m','e','d','P','i','p','e'}; static const WCHAR mailslotW[] = {'M','a','i','l','S','l','o','t'}; + static const WCHAR condrvW[] = {'C','o','n','D','r','v'}; static const WCHAR nullW[] = {'N','u','l','l'}; static const struct unicode_str named_pipe_str = {named_pipeW, sizeof(named_pipeW)}; static const struct unicode_str mailslot_str = {mailslotW, sizeof(mailslotW)}; + static const struct unicode_str condrv_str = {condrvW, sizeof(condrvW)}; static const struct unicode_str null_str = {nullW, sizeof(nullW)}; /* events */ @@ -386,7 +388,7 @@ void init_directories(void) struct directory *dir_driver, *dir_device, *dir_global, *dir_kernel; struct object *link_dosdev, *link_global, *link_nul, *link_pipe, *link_mailslot; - struct object *named_pipe_device, *mailslot_device, *null_device, *user_data_mapping; + struct object *named_pipe_device, *mailslot_device, *null_device, *user_data_mapping, *console_device; struct keyed_event *keyed_event; unsigned int i; @@ -403,10 +405,12 @@ void init_directories(void) /* devices */ named_pipe_device = create_named_pipe_device( &dir_device->obj, &named_pipe_str ); mailslot_device = create_mailslot_device( &dir_device->obj, &mailslot_str ); + console_device = create_console_device( &dir_device->obj, &condrv_str ); null_device = create_unix_device( &dir_device->obj, &null_str, "/dev/null" ); make_object_static( named_pipe_device ); make_object_static( mailslot_device ); make_object_static( null_device ); + make_object_static( console_device ); /* sessions */ create_session( 0 ); diff --git a/server/file.h b/server/file.h index 8bdc5a9010a..e8ace7f49e4 100644 --- a/server/file.h +++ b/server/file.h @@ -179,6 +179,7 @@ extern struct object *create_user_data_mapping( struct object *root, const struc extern struct object *create_named_pipe_device( struct object *root, const struct unicode_str *name ); extern struct object *create_mailslot_device( struct object *root, const struct unicode_str *name ); +extern struct object *create_console_device( struct object *root, const struct unicode_str *name ); extern struct object *create_unix_device( struct object *root, const struct unicode_str *name, const char *unix_path );