Module: wine Branch: master Commit: bd54f39766e53f92909bc208e5746497c0dc5d69 URL: https://source.winehq.org/git/wine.git/?a=commit;h=bd54f39766e53f92909bc208e...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Jul 30 17:16:01 2020 +0200
kernelbase: Fix handling processes using STARTF_USESTDHANDLES when setting standard handles in AllocConsole.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernelbase/console.c | 89 ++++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 32 deletions(-)
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index c3634c792f..d326901eac 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -169,6 +169,61 @@ static COORD get_largest_console_window_size( HANDLE handle ) return c; }
+static BOOL init_console_std_handles(void) +{ + HANDLE std_out = NULL, std_err = NULL, handle; + OBJECT_ATTRIBUTES attr = {sizeof(attr)}; + IO_STATUS_BLOCK iosb; + UNICODE_STRING name; + STARTUPINFOW si; + NTSTATUS status; + + GetStartupInfoW( &si ); + attr.ObjectName = &name; + attr.Attributes = OBJ_INHERIT; + + if (!(si.dwFlags & STARTF_USESTDHANDLES) || !GetStdHandle( STD_INPUT_HANDLE )) + { + /* FIXME: Use unbound console handle */ + RtlInitUnicodeString( &name, L"\Device\ConDrv\CurrentIn" ); + 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, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); + if (!set_ntstatus( status )) return FALSE; + SetStdHandle( STD_INPUT_HANDLE, console_handle_map( handle )); + } + + if (si.dwFlags & STARTF_USESTDHANDLES) + { + std_out = GetStdHandle( STD_OUTPUT_HANDLE ); + std_err = GetStdHandle( STD_ERROR_HANDLE ); + if (std_out && std_err) return TRUE; + } + + /* FIXME: Use unbound console handle */ + RtlInitUnicodeString( &name, L"\Device\ConDrv\CurrentOut" ); + 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, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); + if (!set_ntstatus( status )) return FALSE; + if (!std_out) + { + SetStdHandle( STD_OUTPUT_HANDLE, console_handle_map( handle )); + } + + if (!std_err) + { + if (!std_out && !DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), + &handle, 0, TRUE, DUPLICATE_SAME_ACCESS )) + return FALSE; + SetStdHandle( STD_ERROR_HANDLE, console_handle_map( handle )); + } + + return TRUE; +} + /****************************************************************** * AttachConsole (kernelbase.@) */ @@ -203,13 +258,10 @@ BOOL WINAPI DECLSPEC_HOTPATCH AttachConsole( DWORD pid ) BOOL WINAPI AllocConsole(void) { SECURITY_ATTRIBUTES inheritable_attr = { sizeof(inheritable_attr), NULL, TRUE }; - HANDLE std_in = INVALID_HANDLE_VALUE; - HANDLE std_out = INVALID_HANDLE_VALUE; - HANDLE std_err = INVALID_HANDLE_VALUE; STARTUPINFOW app_si, console_si; WCHAR buffer[1024], cmd[256]; PROCESS_INFORMATION pi; - HANDLE event; + HANDLE event, std_in; DWORD mode; BOOL ret;
@@ -266,42 +318,15 @@ BOOL WINAPI AllocConsole(void) CloseHandle( pi.hProcess ); } CloseHandle( event ); - if (!ret) goto error; + if (!ret || !init_console_std_handles()) goto error; TRACE( "Started wineconsole pid=%08x tid=%08x\n", pi.dwProcessId, pi.dwThreadId );
- if (!(app_si.dwFlags & STARTF_USESTDHANDLES)) - { - - std_in = CreateFileW( L"CONIN$", GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 0, &inheritable_attr, - OPEN_EXISTING, 0, 0); - if (std_in == INVALID_HANDLE_VALUE) goto error; - - std_out = CreateFileW( L"CONOUT$", GENERIC_READ | GENERIC_WRITE, 0, &inheritable_attr, OPEN_EXISTING, 0, 0); - if (std_out == INVALID_HANDLE_VALUE) goto error; - - if (!DuplicateHandle( GetCurrentProcess(), std_out, GetCurrentProcess(), - &std_err, 0, TRUE, DUPLICATE_SAME_ACCESS) ) - goto error; - } - else - { - std_in = app_si.hStdInput; - std_out = app_si.hStdOutput; - std_err = app_si.hStdError; - } - - SetStdHandle( STD_INPUT_HANDLE, std_in ); - SetStdHandle( STD_OUTPUT_HANDLE, std_out ); - SetStdHandle( STD_ERROR_HANDLE, std_err ); RtlLeaveCriticalSection( &console_section ); SetLastError( ERROR_SUCCESS ); return TRUE;
error: ERR("Can't allocate console\n"); - if (std_in != INVALID_HANDLE_VALUE) CloseHandle(std_in); - if (std_out != INVALID_HANDLE_VALUE) CloseHandle(std_out); - if (std_err != INVALID_HANDLE_VALUE) CloseHandle(std_err); FreeConsole(); RtlLeaveCriticalSection( &console_section ); return FALSE;