From Jacek Caban jacek@codeweavers.com
Based on patches by Eric Pouech and Torge Matthies.
v2: Added spawn_process part, spotted and implemented by Eric. v3: Added fork_and_exec, spotted and implemented by Eric.
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- 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 91136683f73..72e4f123377 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 */