diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 41694090254..9b4dbea89f1 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); @@ -4764,14 +4763,12 @@ static void test_CreateProcessCUI(void) AllocConsole(); res = check_child_console_bits(guiexec, 0); - todo_wine ok(res == 0, "Unexpected result %x\n", res); res = check_child_console_bits(guiexec, DETACHED_PROCESS); ok(res == 0, "Unexpected result %x\n", res); 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 +4782,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..589a8d4c6cd 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,25 @@ void init_console( void ) init_console_std_handles( FALSE ); } } - else if (params->ConsoleHandle == CONSOLE_HANDLE_ALLOC) + else { HMODULE mod = GetModuleHandleW( NULL ); - params->ConsoleHandle = NULL; + if (RtlImageNtHeader( mod )->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI) - AllocConsole(); + { + if (params->ConsoleHandle == CONSOLE_HANDLE_ALLOC || + params->ConsoleHandle == CONSOLE_HANDLE_ALLOC_NO_WINDOW) + { + BOOL no_window = params->ConsoleHandle == CONSOLE_HANDLE_ALLOC_NO_WINDOW; + params->ConsoleHandle = NULL; + alloc_console( no_window ); + } + else if (params->ConsoleHandle) create_console_connection( params->ConsoleHandle ); + } + else if (params->ConsoleHandle) + { + CloseHandle( params->ConsoleHandle ); + params->ConsoleHandle = NULL; + } } - 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 */