Module: wine Branch: master Commit: d8d2b8a38d6a04f19f3774e860e32c7859bc0fc4 URL: https://source.winehq.org/git/wine.git/?a=commit;h=d8d2b8a38d6a04f19f3774e86...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Nov 12 19:56:23 2020 +0100
server: Support unbound console output device.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/tests/console.c | 1 - dlls/kernelbase/console.c | 3 +- server/console.c | 69 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 13e17e14e4c..f621c5f6a8d 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4035,7 +4035,6 @@ static void test_AllocConsole_child(void) ok(GetStdHandle(STD_OUTPUT_HANDLE) == prev_output, "GetStdHandle(STD_OUTPUT_HANDLE) = %p\n", GetStdHandle(STD_OUTPUT_HANDLE)); ok(GetStdHandle(STD_ERROR_HANDLE) == prev_error, "GetStdHandle(STD_ERROR_HANDLE) = %p\n", GetStdHandle(STD_ERROR_HANDLE)); res = GetConsoleMode(unbound_output, &mode); - todo_wine ok(!res && GetLastError() == ERROR_INVALID_HANDLE, "GetConsoleMode failed: %u\n", GetLastError());
res = AllocConsole(); diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index ed5550bb0b6..9fc34e3c9bc 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -254,8 +254,7 @@ static BOOL init_console_std_handles( BOOL override_all ) if (std_out && std_err) return TRUE; }
- /* FIXME: Use unbound console handle */ - RtlInitUnicodeString( &name, L"\Device\ConDrv\CurrentOut" ); + RtlInitUnicodeString( &name, L"\Device\ConDrv\Output" ); status = NtCreateFile( &handle, FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, &attr, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_CREATE, diff --git a/server/console.c b/server/console.c index bc93809ab97..a290e0647e4 100644 --- a/server/console.c +++ b/server/console.c @@ -313,6 +313,36 @@ static const struct object_ops input_device_ops = no_destroy /* destroy */ };
+static void output_device_dump( struct object *obj, int verbose ); +static int output_device_add_queue( struct object *obj, struct wait_queue_entry *entry ); +static struct fd *output_device_get_fd( struct object *obj ); +static struct object *output_device_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ); + +static const struct object_ops output_device_ops = +{ + sizeof(struct object), /* size */ + output_device_dump, /* dump */ + console_device_get_type, /* get_type */ + output_device_add_queue, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + no_satisfied, /* satisfied */ + no_signal, /* signal */ + output_device_get_fd, /* get_fd */ + no_map_access, /* map_access */ + default_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ + no_get_full_name, /* get_full_name */ + no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ + output_device_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ +}; + struct console_connection { struct object obj; /* object header */ @@ -1096,6 +1126,7 @@ static struct object *console_device_lookup_name( struct object *obj, struct uni static const WCHAR current_inW[] = {'C','u','r','r','e','n','t','I','n'}; static const WCHAR current_outW[] = {'C','u','r','r','e','n','t','O','u','t'}; static const WCHAR inputW[] = {'I','n','p','u','t'}; + static const WCHAR outputW[] = {'O','u','t','p','u','t'}; static const WCHAR screen_bufferW[] = {'S','c','r','e','e','n','B','u','f','f','e','r'}; static const WCHAR serverW[] = {'S','e','r','v','e','r'};
@@ -1133,6 +1164,12 @@ static struct object *console_device_lookup_name( struct object *obj, struct uni return alloc_object( &input_device_ops ); }
+ if (name->len == sizeof(outputW) && !memcmp( name->str, outputW, name->len )) + { + name->len = 0; + return alloc_object( &output_device_ops ); + } + if (name->len == sizeof(screen_bufferW) && !memcmp( name->str, screen_bufferW, name->len )) { if (!current->process->console) @@ -1209,6 +1246,38 @@ static struct object *input_device_open_file( struct object *obj, unsigned int a return grab_object( obj ); }
+static void output_device_dump( struct object *obj, int verbose ) +{ + fputs( "console Output device\n", stderr ); +} + +static int output_device_add_queue( struct object *obj, struct wait_queue_entry *entry ) +{ + if (!current->process->console || !current->process->console->active) + { + set_error( STATUS_ACCESS_DENIED ); + return 0; + } + return add_queue( ¤t->process->console->obj, entry ); +} + +static struct fd *output_device_get_fd( struct object *obj ) +{ + if (!current->process->console || !current->process->console->active) + { + set_error( STATUS_ACCESS_DENIED ); + return NULL; + } + + return get_obj_fd( ¤t->process->console->active->obj ); +} + +static struct object *output_device_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ) +{ + return grab_object( obj ); +} + struct object *create_console_device( struct object *root, const struct unicode_str *name, unsigned int attr, const struct security_descriptor *sd ) {