The following series is the result of work from - Torge Matties, Jacek Caban and myself - and went through various convergence, merges, rewrite and improvements (especially patch #2 for various authors)
it provides: - support for CREATE_NO_WINDOW flag in CreateProcess - a solution for regression introduced in f034084d49b354811096524d472ae5172ac1cebf (when a Wine initial process isn't attached to a unix console, it can generates lots new console window creation, with unwanted side effects, like not using parents std streams for output) - with the correspondings non regression tests
v3 -> v4: - using negative handle values for console pseudo handles - don't report FIXME to users - removed Wine only tests
Signed-off-by: Eric Pouech eric.pouech@gmail.com ---
Supersedes: 231894-231897
Eric Pouech (4): dlls/kernel32/tests: Add more CreateProcess console management tests. dlls/{ntdll, kernel*}: Add support for CREATE_NO_WINDOW flag in CreateProcess. include/condrv.h, server: using negative values for console pseudo handles dlls/{ntdll,kernel*}: provide a pseudo console environment for initial CUI processes not tied to an Unix tty
dlls/kernel32/tests/console.c | 86 +++++++++++++++++++++++++++++------ dlls/kernelbase/console.c | 39 ++++++++++++---- dlls/kernelbase/process.c | 11 +++-- dlls/ntdll/unix/env.c | 2 + dlls/ntdll/unix/process.c | 2 + include/wine/condrv.h | 6 ++- programs/conhost/conhost.c | 11 +++-- programs/conhost/conhost.h | 1 + server/process.c | 4 +- 9 files changed, 128 insertions(+), 34 deletions(-)
- check for console bits after create process - add tests for CREATE_NO_WINDOW flag in CreateProcess
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/kernel32/tests/console.c | 89 +++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 13 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 98692760acf..da19e3c6a3f 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4689,7 +4689,7 @@ static void copy_change_subsystem(const char* in, const char* out, DWORD subsyst CloseHandle(hFile); }
-static BOOL check_whether_child_attached(const char* exec, DWORD flags) +static DWORD check_child_console_bits(const char* exec, DWORD flags) { STARTUPINFOA si = { sizeof(si) }; PROCESS_INFORMATION info; @@ -4705,12 +4705,18 @@ static BOOL check_whether_child_attached(const char* exec, DWORD flags) ret = WaitForSingleObject(info.hProcess, 30000); ok(ret == WAIT_OBJECT_0, "Could not wait for the child process: %ld le=%lu\n", ret, GetLastError()); - ret = GetExitCodeProcess(info.hProcess, &exit_code); - ok(ret && exit_code <= 255, "Couldn't get exit_code\n"); + res = GetExitCodeProcess(info.hProcess, &exit_code); + ok(res && exit_code <= 255, "Couldn't get exit_code\n"); CloseHandle(info.hProcess); - return exit_code != 0; + return exit_code; }
+#define CP_WITH_CONSOLE 0x01 /* attached to a console */ +#define CP_WITH_HANDLE 0x02 /* child has a console handle */ +#define CP_WITH_WINDOW 0x04 /* child has a console window */ +#define CP_ALONE 0x08 /* whether child is the single process attached to console */ +#define CP_GROUP_LEADER 0x10 /* whether the child is the process group leader */ + static void test_CreateProcessCUI(void) { char guiexec[MAX_PATH]; @@ -4728,14 +4734,63 @@ static void test_CreateProcessCUI(void)
FreeConsole();
- res = check_whether_child_attached(guiexec, DETACHED_PROCESS); - ok(!res, "Don't expecting child to be attached to a console\n"); - res = check_whether_child_attached(guiexec, 0); - ok(!res, "Don't expecting child to be attached to a console\n"); - res = check_whether_child_attached(cuiexec, DETACHED_PROCESS); - ok(!res, "Don't expecting child to be attached to a console\n"); - res = check_whether_child_attached(cuiexec, 0); - ok(res, "Expecting child to be attached to a console\n"); + res = check_child_console_bits(guiexec, 0); + 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); + 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); + res = check_child_console_bits(guiexec, CREATE_NEW_CONSOLE | CREATE_NO_WINDOW); + ok(res == 0, "Unexpected result %x\n", res); + + res = check_child_console_bits(cuiexec, 0); + ok(res == (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_WITH_WINDOW | CP_ALONE), "Unexpected result %x\n", res); + res = check_child_console_bits(cuiexec, DETACHED_PROCESS); + ok(res == 0, "Unexpected result %x\n", res); + 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); + res = check_child_console_bits(cuiexec, CREATE_NEW_CONSOLE | CREATE_NO_WINDOW); + ok(res == (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_WITH_WINDOW | CP_ALONE), "Unexpected result %x\n", res); + + 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); + res = check_child_console_bits(guiexec, CREATE_NEW_CONSOLE | CREATE_NO_WINDOW); + ok(res == 0, "Unexpected result %x\n", res); + + res = check_child_console_bits(cuiexec, 0); + ok(res == (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_WITH_WINDOW), "Unexpected result %x\n", res); + res = check_child_console_bits(cuiexec, DETACHED_PROCESS); + ok(res == 0, "Unexpected result %x\n", res); + 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); + res = check_child_console_bits(cuiexec, CREATE_NEW_CONSOLE | CREATE_NO_WINDOW); + ok(res == (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_WITH_WINDOW | CP_ALONE), "Unexpected result %x\n", res);
DeleteFileA(guiexec); DeleteFileA(cuiexec); @@ -4771,7 +4826,15 @@ START_TEST(console)
if (argc == 3 && !strcmp(argv[2], "check_console")) { - ExitProcess(GetConsoleCP() != 0); + DWORD exit_code = 0, pcslist; + if (GetConsoleCP() != 0) exit_code |= CP_WITH_CONSOLE; + if (RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle) exit_code |= CP_WITH_HANDLE; + if (IsWindow(GetConsoleWindow())) exit_code |= CP_WITH_WINDOW; + if (pGetConsoleProcessList && GetConsoleProcessList(&pcslist, 1) == 1) + exit_code |= CP_ALONE; + if (RtlGetCurrentPeb()->ProcessParameters->ProcessGroupId == GetCurrentProcessId()) + exit_code |= CP_GROUP_LEADER; + ExitProcess(exit_code); }
test_current = argc >= 3 && !strcmp(argv[2], "--current");
Signed-off-by: Jacek Caban jacek@codeweavers.com
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 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 */
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/condrv.h | 6 +++--- server/process.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/wine/condrv.h b/include/wine/condrv.h index 452ce552da1..2d763d0b821 100644 --- a/include/wine/condrv.h +++ b/include/wine/condrv.h @@ -188,8 +188,8 @@ struct condrv_ctrl_event };
/* Wine specific values for console inheritance (params->ConsoleHandle) */ -#define CONSOLE_HANDLE_ALLOC UlongToHandle(1) -#define CONSOLE_HANDLE_ALLOC_NO_WINDOW UlongToHandle(2) -#define CONSOLE_HANDLE_SHELL UlongToHandle(3) +#define CONSOLE_HANDLE_ALLOC LongToHandle(-1) +#define CONSOLE_HANDLE_ALLOC_NO_WINDOW LongToHandle(-2) +#define CONSOLE_HANDLE_SHELL LongToHandle(-3)
#endif /* _INC_CONDRV */ diff --git a/server/process.c b/server/process.c index 65e2aa70de2..d1407204718 100644 --- a/server/process.c +++ b/server/process.c @@ -1333,8 +1333,8 @@ DECL_HANDLER(new_process) /* connect to the window station */ connect_process_winstation( process, parent_thread, parent );
- /* set the process console */ - if (info->data->console > 3) + /* inherit the process console, but keep pseudo handles (< 0), and 0 (= not attached to a console) as is */ + if ((int)info->data->console > 0) info->data->console = duplicate_handle( parent, info->data->console, process, 0, 0, DUPLICATE_SAME_ACCESS );
Signed-off-by: Jacek Caban jacek@codeweavers.com
should improve situation for various bug reports
https://bugs.winehq.org/show_bug.cgi?id=52771 https://bugs.winehq.org/show_bug.cgi?id=52761 https://bugs.winehq.org/show_bug.cgi?id=52743 Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/kernelbase/console.c | 18 ++++++++++++++---- dlls/ntdll/unix/env.c | 2 ++ include/wine/condrv.h | 1 + 3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 046eee6147c..e298e940148 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -86,6 +86,12 @@ static BOOL console_ioctl( HANDLE handle, DWORD code, void *in_buff, DWORD in_co IO_STATUS_BLOCK io; NTSTATUS status;
+ if (handle == CONSOLE_HANDLE_SHELL_NO_WINDOW) + { + WARN("Incorrect access to Shell-no-window console (ioctl=%x)\n", code); + SetLastError( ERROR_INVALID_ACCESS ); + return FALSE; + } status = NtDeviceIoControlFile( handle, NULL, NULL, NULL, &io, code, in_buff, in_count, out_buff, out_count ); switch( status ) @@ -621,10 +627,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH FreeConsole(void) { RtlEnterCriticalSection( &console_section );
- NtClose( console_connection ); - console_connection = NULL; + if (RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle != CONSOLE_HANDLE_SHELL_NO_WINDOW) + { + NtClose( console_connection ); + console_connection = NULL;
- NtClose( RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle ); + NtClose( RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle ); + } RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
if (console_flags & CONSOLE_INPUT_HANDLE) NtClose( GetStdHandle( STD_INPUT_HANDLE )); @@ -2303,5 +2312,6 @@ void init_console( void ) if (RtlImageNtHeader( mod )->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI) alloc_console( no_window ); } - else if (params->ConsoleHandle) create_console_connection( params->ConsoleHandle ); + else if (params->ConsoleHandle && params->ConsoleHandle != CONSOLE_HANDLE_SHELL_NO_WINDOW) + create_console_connection( params->ConsoleHandle ); } diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 64117e70abe..2ead6c1fcc3 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -1684,6 +1684,8 @@ static void get_initial_console( RTL_USER_PROCESS_PARAMETERS *params ) params->hStdOutput = (HANDLE)((UINT_PTR)params->hStdOutput | 1); output_fd = 1; } + if (!params->ConsoleHandle && main_image_info.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI) + params->ConsoleHandle = CONSOLE_HANDLE_SHELL_NO_WINDOW;
if (output_fd != -1) { diff --git a/include/wine/condrv.h b/include/wine/condrv.h index 2d763d0b821..3355d7177b0 100644 --- a/include/wine/condrv.h +++ b/include/wine/condrv.h @@ -191,5 +191,6 @@ struct condrv_ctrl_event #define CONSOLE_HANDLE_ALLOC LongToHandle(-1) #define CONSOLE_HANDLE_ALLOC_NO_WINDOW LongToHandle(-2) #define CONSOLE_HANDLE_SHELL LongToHandle(-3) +#define CONSOLE_HANDLE_SHELL_NO_WINDOW LongToHandle(-4)
#endif /* _INC_CONDRV */
Signed-off-by: Jacek Caban jacek@codeweavers.com