Jacek Caban : kernelbase: Add support for CREATE_NO_WINDOW flag in CreateProcess.

Alexandre Julliard julliard at winehq.org
Tue Apr 12 15:35:17 CDT 2022


Module: wine
Branch: master
Commit: b4d91adb16565c9d12a70cb29c2d25cdb3665488
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b4d91adb16565c9d12a70cb29c2d25cdb3665488

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Apr 11 15:04:56 2022 +0200

kernelbase: Add support for CREATE_NO_WINDOW flag in CreateProcess.

Based on patches by Eric Pouech and Torge Matthies.

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/console.c |  3 ---
 dlls/kernelbase/console.c     | 21 +++++++++++++++------
 dlls/kernelbase/process.c     | 11 +++++++----
 dlls/ntdll/unix/process.c     |  2 ++
 include/wine/condrv.h         |  5 +++--
 programs/conhost/conhost.c    | 11 ++++++++---
 programs/conhost/conhost.h    |  1 +
 7 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c
index da19e3c6a3f..5d65b0b75e7 100644
--- a/dlls/kernel32/tests/console.c
+++ b/dlls/kernel32/tests/console.c
@@ -4754,7 +4754,6 @@ static void test_CreateProcessCUI(void)
     res = check_child_console_bits(cuiexec, CREATE_NEW_CONSOLE);
     ok(res == (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_WITH_WINDOW | CP_ALONE), "Unexpected result %x\n", res);
     res = check_child_console_bits(cuiexec, CREATE_NO_WINDOW);
-    todo_wine
     ok(res == (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_ALONE), "Unexpected result %x\n", res);
     res = check_child_console_bits(cuiexec, DETACHED_PROCESS | CREATE_NO_WINDOW);
     ok(res == 0, "Unexpected result %x\n", res);
@@ -4771,7 +4770,6 @@ static void test_CreateProcessCUI(void)
     res = check_child_console_bits(guiexec, CREATE_NEW_CONSOLE);
     ok(res == 0, "Unexpected result %x\n", res);
     res = check_child_console_bits(guiexec, CREATE_NO_WINDOW);
-    todo_wine
     ok(res == 0, "Unexpected result %x\n", res);
     res = check_child_console_bits(guiexec, DETACHED_PROCESS | CREATE_NO_WINDOW);
     ok(res == 0, "Unexpected result %x\n", res);
@@ -4785,7 +4783,6 @@ static void test_CreateProcessCUI(void)
     res = check_child_console_bits(cuiexec, CREATE_NEW_CONSOLE);
     ok(res == (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_WITH_WINDOW | CP_ALONE), "Unexpected result %x\n", res);
     res = check_child_console_bits(cuiexec, CREATE_NO_WINDOW);
-    todo_wine
     ok(res == (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_ALONE), "Unexpected result %x\n", res);
     res = check_child_console_bits(cuiexec, DETACHED_PROCESS | CREATE_NO_WINDOW);
     ok(res == 0, "Unexpected result %x\n", res);
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c
index b2bb6c53fd9..046eee6147c 100644
--- a/dlls/kernelbase/console.c
+++ b/dlls/kernelbase/console.c
@@ -361,10 +361,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH AttachConsole( DWORD pid )
 }
 
 
-/******************************************************************
- *      AllocConsole   (kernelbase.@)
- */
-BOOL WINAPI AllocConsole(void)
+static BOOL alloc_console( BOOL headless )
 {
     SECURITY_ATTRIBUTES inheritable_attr = { sizeof(inheritable_attr), NULL, TRUE };
     STARTUPINFOW app_si, console_si;
@@ -419,6 +416,7 @@ BOOL WINAPI AllocConsole(void)
 
     swprintf( conhost_path, ARRAY_SIZE(conhost_path), L"%s\\conhost.exe", system_dir );
     swprintf( cmd, ARRAY_SIZE(cmd),  L"\"%s\" --server 0x%x", conhost_path, condrv_handle( server ));
+    if (headless) wcscat( cmd, L" --headless" );
     Wow64DisableWow64FsRedirection( &redir );
     ret = CreateProcessW( conhost_path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &console_si, &pi );
     Wow64RevertWow64FsRedirection( redir );
@@ -444,6 +442,15 @@ error:
 }
 
 
+/******************************************************************
+ *      AllocConsole   (kernelbase.@)
+ */
+BOOL WINAPI AllocConsole(void)
+{
+    return alloc_console( FALSE );
+}
+
+
 /******************************************************************************
  *	CreateConsoleScreenBuffer   (kernelbase.@)
  */
@@ -2287,12 +2294,14 @@ void init_console( void )
             init_console_std_handles( FALSE );
         }
     }
-    else if (params->ConsoleHandle == CONSOLE_HANDLE_ALLOC)
+    else if (params->ConsoleHandle == CONSOLE_HANDLE_ALLOC ||
+             params->ConsoleHandle == CONSOLE_HANDLE_ALLOC_NO_WINDOW)
     {
+        BOOL no_window = params->ConsoleHandle == CONSOLE_HANDLE_ALLOC_NO_WINDOW;
         HMODULE mod = GetModuleHandleW( NULL );
         params->ConsoleHandle = NULL;
         if (RtlImageNtHeader( mod )->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
-            AllocConsole();
+            alloc_console( no_window );
     }
     else if (params->ConsoleHandle) create_console_connection( params->ConsoleHandle );
 }
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
index 1cecbce9321..32f622bdf3e 100644
--- a/dlls/kernelbase/process.c
+++ b/dlls/kernelbase/process.c
@@ -193,8 +193,12 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename
     if (flags & CREATE_NEW_CONSOLE) params->ConsoleHandle = CONSOLE_HANDLE_ALLOC;
     else if (!(flags & DETACHED_PROCESS))
     {
-        params->ConsoleHandle = NtCurrentTeb()->Peb->ProcessParameters->ConsoleHandle;
-        if (!params->ConsoleHandle) params->ConsoleHandle = CONSOLE_HANDLE_ALLOC;
+        if (flags & CREATE_NO_WINDOW) params->ConsoleHandle = CONSOLE_HANDLE_ALLOC_NO_WINDOW;
+        else
+        {
+            params->ConsoleHandle = NtCurrentTeb()->Peb->ProcessParameters->ConsoleHandle;
+            if (!params->ConsoleHandle) params->ConsoleHandle = CONSOLE_HANDLE_ALLOC;
+        }
     }
 
     if (startup->dwFlags & STARTF_USESTDHANDLES)
@@ -532,8 +536,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
     /* Warn if unsupported features are used */
 
     if (flags & (IDLE_PRIORITY_CLASS | HIGH_PRIORITY_CLASS | REALTIME_PRIORITY_CLASS |
-                 CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW |
-                 PROFILE_USER | PROFILE_KERNEL | PROFILE_SERVER))
+                 CREATE_DEFAULT_ERROR_MODE | PROFILE_USER | PROFILE_KERNEL | PROFILE_SERVER))
         WARN( "(%s,...): ignoring some flags in %lx\n", debugstr_w(app_name), flags );
 
     if (cur_dir)
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c
index 99c8e37053c..078ad75099d 100644
--- a/dlls/ntdll/unix/process.c
+++ b/dlls/ntdll/unix/process.c
@@ -445,6 +445,7 @@ static NTSTATUS spawn_process( const RTL_USER_PROCESS_PARAMETERS *params, int so
         {
             if (params->ConsoleFlags ||
                 params->ConsoleHandle == CONSOLE_HANDLE_ALLOC ||
+                params->ConsoleHandle == CONSOLE_HANDLE_ALLOC_NO_WINDOW ||
                 (params->hStdInput == INVALID_HANDLE_VALUE && params->hStdOutput == INVALID_HANDLE_VALUE))
             {
                 setsid();
@@ -585,6 +586,7 @@ static NTSTATUS fork_and_exec( OBJECT_ATTRIBUTES *attr, int unixdir,
 
             if (params->ConsoleFlags ||
                 params->ConsoleHandle == CONSOLE_HANDLE_ALLOC ||
+                params->ConsoleHandle == CONSOLE_HANDLE_ALLOC_NO_WINDOW ||
                 (params->hStdInput == INVALID_HANDLE_VALUE && params->hStdOutput == INVALID_HANDLE_VALUE))
             {
                 setsid();
diff --git a/include/wine/condrv.h b/include/wine/condrv.h
index 1000e62e765..452ce552da1 100644
--- a/include/wine/condrv.h
+++ b/include/wine/condrv.h
@@ -188,7 +188,8 @@ struct condrv_ctrl_event
 };
 
 /* Wine specific values for console inheritance (params->ConsoleHandle) */
-#define CONSOLE_HANDLE_ALLOC  ((HANDLE)1)
-#define CONSOLE_HANDLE_SHELL  ((HANDLE)2)
+#define CONSOLE_HANDLE_ALLOC            UlongToHandle(1)
+#define CONSOLE_HANDLE_ALLOC_NO_WINDOW  UlongToHandle(2)
+#define CONSOLE_HANDLE_SHELL            UlongToHandle(3)
 
 #endif /* _INC_CONDRV */
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c
index d494e3f53a5..6ea64395e1a 100644
--- a/programs/conhost/conhost.c
+++ b/programs/conhost/conhost.c
@@ -2650,7 +2650,7 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code,
             TRACE( "get window\n" );
             if (in_size || *out_size != sizeof(*result)) return STATUS_INVALID_PARAMETER;
             if (!(result = alloc_ioctl_buffer( sizeof(*result )))) return STATUS_NO_MEMORY;
-            if (!console->win) init_message_window( console );
+            if (!console->win && !console->no_window) init_message_window( console );
             *result = condrv_handle( console->win );
             return STATUS_SUCCESS;
         }
@@ -2929,8 +2929,13 @@ int __cdecl wmain(int argc, WCHAR *argv[])
     {
         console.tty_input  = GetStdHandle( STD_INPUT_HANDLE );
         console.tty_output = GetStdHandle( STD_OUTPUT_HANDLE );
-        init_tty_output( &console );
-        if (!console.is_unix && !ensure_tty_input_thread( &console )) return 1;
+
+        if (console.tty_input || console.tty_output)
+        {
+            init_tty_output( &console );
+            if (!console.is_unix && !ensure_tty_input_thread( &console )) return 1;
+        }
+        else console.no_window = TRUE;
     }
     else
     {
diff --git a/programs/conhost/conhost.h b/programs/conhost/conhost.h
index 8ca09bb80d0..65cf5d39ebd 100644
--- a/programs/conhost/conhost.h
+++ b/programs/conhost/conhost.h
@@ -79,6 +79,7 @@ struct console
     struct screen_buffer  *active;              /* active screen buffer */
     int                    is_unix;             /* UNIX terminal mode */
     int                    use_relative_cursor; /* use relative cursor positionning */
+    int                    no_window;           /* don't create console window */
     INPUT_RECORD          *records;             /* input records */
     unsigned int           record_count;        /* number of input records */
     unsigned int           record_size;         /* size of input records buffer */




More information about the wine-cvs mailing list