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