Jacek Caban : kernelbase: Fix handling processes using STARTF_USESTDHANDLES when setting standard handles in AllocConsole.
Alexandre Julliard
julliard at winehq.org
Thu Jul 30 15:31:26 CDT 2020
Module: wine
Branch: master
Commit: bd54f39766e53f92909bc208e5746497c0dc5d69
URL: https://source.winehq.org/git/wine.git/?a=commit;h=bd54f39766e53f92909bc208e5746497c0dc5d69
Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;
More information about the wine-cvs
mailing list