Signed-off-by: Torge Matthies openglfreak@googlemail.com --- dlls/kernel32/tests/console.c | 46 +++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 98692760acf..9195ac204f7 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 BOOL check_subprocess(const char* exec, const char* verb, DWORD flags) { STARTUPINFOA si = { sizeof(si) }; PROCESS_INFORMATION info; @@ -4698,7 +4698,7 @@ static BOOL check_whether_child_attached(const char* exec, DWORD flags) BOOL res; DWORD ret;
- sprintf(buf, ""%s" console check_console", exec); + sprintf(buf, ""%s" console %s", exec, verb); res = CreateProcessA(NULL, buf, NULL, NULL, FALSE, flags, NULL, NULL, &si, &info); ok(res, "CreateProcess failed: %lu %s\n", GetLastError(), buf); CloseHandle(info.hThread); @@ -4711,6 +4711,18 @@ static BOOL check_whether_child_attached(const char* exec, DWORD flags) return exit_code != 0; }
+static BOOL check_whether_child_attached(const char* exec, DWORD flags) +{ + return check_subprocess(exec, "check_console", flags); +} + +static BOOL check_same_console(const char* exec, DWORD flags) +{ + char buf[MAX_PATH]; + sprintf(buf, "check_same_console %lx", GetCurrentProcessId()); + return check_subprocess(exec, buf, flags); +} + static void test_CreateProcessCUI(void) { char guiexec[MAX_PATH]; @@ -4726,14 +4738,33 @@ static void test_CreateProcessCUI(void) strcat(cuiexec, "console_cui.exe"); copy_change_subsystem(argv[0], cuiexec, IMAGE_SUBSYSTEM_WINDOWS_CUI);
+ AllocConsole(); + + res = check_same_console(cuiexec, 0); + ok(res, "Expected child to be attached to the same console\n"); + res = check_same_console(cuiexec, DETACHED_PROCESS); + ok(!res, "Expected child to be attached to a different console\n"); + res = check_same_console(cuiexec, CREATE_NO_WINDOW); + todo_wine ok(!res, "Expected child to be attached to a different console\n"); + res = check_same_console(cuiexec, CREATE_NO_WINDOW|DETACHED_PROCESS); + ok(!res, "Expected child to be attached to a different console\n"); + res = check_same_console(cuiexec, CREATE_NO_WINDOW|CREATE_NEW_CONSOLE); + ok(!res, "Expected child to be attached to a different console\n"); + 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, CREATE_NO_WINDOW); + 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, CREATE_NO_WINDOW); + ok(res, "Expecting child to be attached to a console\n"); + res = check_whether_child_attached(cuiexec, CREATE_NO_WINDOW|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");
@@ -4774,6 +4805,17 @@ START_TEST(console) ExitProcess(GetConsoleCP() != 0); }
+ if (argc > 3 && !strcmp(argv[2], "check_same_console")) + { + DWORD parent_pid, count, pids[2]; + sscanf(argv[3], "%lx", &parent_pid); + count = GetConsoleProcessList(pids, ARRAY_SIZE(pids)); + while (count--) + if (pids[count] == parent_pid) + ExitProcess(1); + ExitProcess(0); + } + test_current = argc >= 3 && !strcmp(argv[2], "--current"); using_pseudo_console = argc >= 3 && !strcmp(argv[2], "--pseudo-console");
Signed-off-by: Torge Matthies openglfreak@googlemail.com --- dlls/kernel32/tests/console.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 9195ac204f7..8a995ca36db 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4723,6 +4723,11 @@ static BOOL check_same_console(const char* exec, DWORD flags) return check_subprocess(exec, buf, flags); }
+static BOOL check_has_window(const char* exec, DWORD flags) +{ + return check_subprocess(exec, "check_console_has_window", flags); +} + static void test_CreateProcessCUI(void) { char guiexec[MAX_PATH]; @@ -4751,6 +4756,17 @@ static void test_CreateProcessCUI(void) res = check_same_console(cuiexec, CREATE_NO_WINDOW|CREATE_NEW_CONSOLE); ok(!res, "Expected child to be attached to a different console\n");
+ res = check_has_window(cuiexec, 0); + ok(res, "Expected child to have a console window\n"); + res = check_has_window(cuiexec, DETACHED_PROCESS); + ok(!res, "Expected child to not have a console window\n"); + res = check_has_window(cuiexec, CREATE_NO_WINDOW); + todo_wine ok(!res, "Expected child to not have a console window\n"); + res = check_has_window(cuiexec, CREATE_NO_WINDOW|DETACHED_PROCESS); + ok(!res, "Expected child to not have a console window\n"); + res = check_has_window(cuiexec, CREATE_NO_WINDOW|CREATE_NEW_CONSOLE); + ok(res, "Expected child to have a console window\n"); + FreeConsole();
res = check_whether_child_attached(guiexec, DETACHED_PROCESS); @@ -4816,6 +4832,11 @@ START_TEST(console) ExitProcess(0); }
+ if (argc == 3 && !strcmp(argv[2], "check_console_has_window")) + { + ExitProcess(IsWindow(GetConsoleWindow())); + } + test_current = argc >= 3 && !strcmp(argv[2], "--current"); using_pseudo_console = argc >= 3 && !strcmp(argv[2], "--pseudo-console");
Instead of if ConsoleFlags != 0.
Signed-off-by: Torge Matthies openglfreak@googlemail.com --- dlls/ntdll/unix/process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 99c8e37053c..e8a7ada8f2f 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -443,7 +443,7 @@ static NTSTATUS spawn_process( const RTL_USER_PROCESS_PARAMETERS *params, int so { if (!(pid = fork())) /* grandchild */ { - if (params->ConsoleFlags || + if ((params->ConsoleFlags & 1) || params->ConsoleHandle == CONSOLE_HANDLE_ALLOC || (params->hStdInput == INVALID_HANDLE_VALUE && params->hStdOutput == INVALID_HANDLE_VALUE)) { @@ -583,7 +583,7 @@ static NTSTATUS fork_and_exec( OBJECT_ATTRIBUTES *attr, int unixdir, { close( fd[0] );
- if (params->ConsoleFlags || + if ((params->ConsoleFlags & 1) || params->ConsoleHandle == CONSOLE_HANDLE_ALLOC || (params->hStdInput == INVALID_HANDLE_VALUE && params->hStdOutput == INVALID_HANDLE_VALUE)) {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111920
Your paranoid android.
=== debian11 (32 bit WoW report) ===
ntdll: change.c:241: Test failed: should be ready change.c:247: Test failed: action wrong change.c:277: Test failed: should be ready change.c:280: Test failed: info not set change.c:293: Test failed: status set too soon change.c:294: Test failed: info set too soon
Instead of if console_flags != 0.
Signed-off-by: Torge Matthies openglfreak@googlemail.com --- server/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/process.c b/server/process.c index 65e2aa70de2..283cd5db209 100644 --- a/server/process.c +++ b/server/process.c @@ -1363,7 +1363,7 @@ DECL_HANDLER(new_process) /* debug_children is set to 1 by default */ }
- if (!info->data->console_flags) process->group_id = parent->group_id; + if (!(info->data->console_flags & 1)) process->group_id = parent->group_id;
info->process = (struct process *)grab_object( process ); reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
Signed-off-by: Torge Matthies openglfreak@googlemail.com --- programs/conhost/conhost.c | 9 +++++++-- programs/conhost/conhost.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index d494e3f53a5..9b47f87cb4c 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; } @@ -2897,6 +2897,11 @@ int __cdecl wmain(int argc, WCHAR *argv[]) if ((!height && !console.is_unix) || height > 0xffff || *end) return 1; continue; } + if (!wcscmp( argv[i], L"--no-window")) + { + console.no_window = 1; + continue; + } if (!wcscmp( argv[i], L"--signal" )) { if (++i == argc) return 1; @@ -2932,7 +2937,7 @@ int __cdecl wmain(int argc, WCHAR *argv[]) init_tty_output( &console ); if (!console.is_unix && !ensure_tty_input_thread( &console )) return 1; } - else + else if (!console.no_window) { STARTUPINFOW si; if (!init_window( &console )) return 1; diff --git a/programs/conhost/conhost.h b/programs/conhost/conhost.h index 8ca09bb80d0..252c01de501 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; /* do now allocate a window */ INPUT_RECORD *records; /* input records */ unsigned int record_count; /* number of input records */ unsigned int record_size; /* size of input records buffer */
Use the second bit of ConsoleFlags to pass this flag to the child.
Signed-off-by: Torge Matthies openglfreak@googlemail.com --- dlls/kernel32/tests/console.c | 4 ++-- dlls/kernelbase/console.c | 3 +++ dlls/kernelbase/process.c | 11 +++++++---- 3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 8a995ca36db..0de96f416bf 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4750,7 +4750,7 @@ static void test_CreateProcessCUI(void) res = check_same_console(cuiexec, DETACHED_PROCESS); ok(!res, "Expected child to be attached to a different console\n"); res = check_same_console(cuiexec, CREATE_NO_WINDOW); - todo_wine ok(!res, "Expected child to be attached to a different console\n"); + ok(!res, "Expected child to be attached to a different console\n"); res = check_same_console(cuiexec, CREATE_NO_WINDOW|DETACHED_PROCESS); ok(!res, "Expected child to be attached to a different console\n"); res = check_same_console(cuiexec, CREATE_NO_WINDOW|CREATE_NEW_CONSOLE); @@ -4761,7 +4761,7 @@ static void test_CreateProcessCUI(void) res = check_has_window(cuiexec, DETACHED_PROCESS); ok(!res, "Expected child to not have a console window\n"); res = check_has_window(cuiexec, CREATE_NO_WINDOW); - todo_wine ok(!res, "Expected child to not have a console window\n"); + ok(!res, "Expected child to not have a console window\n"); res = check_has_window(cuiexec, CREATE_NO_WINDOW|DETACHED_PROCESS); ok(!res, "Expected child to not have a console window\n"); res = check_has_window(cuiexec, CREATE_NO_WINDOW|CREATE_NEW_CONSOLE); diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index b2bb6c53fd9..aa6a7681800 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -419,6 +419,8 @@ 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 (NtCurrentTeb()->Peb->ProcessParameters->ConsoleFlags & 2) + wcsncat( cmd, L" --no-window", ARRAY_SIZE(cmd) ); Wow64DisableWow64FsRedirection( &redir ); ret = CreateProcessW( conhost_path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &console_si, &pi ); Wow64RevertWow64FsRedirection( redir ); @@ -2293,6 +2295,7 @@ void init_console( void ) params->ConsoleHandle = NULL; if (RtlImageNtHeader( mod )->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI) AllocConsole(); + params->ConsoleFlags &= ~2; } else if (params->ConsoleHandle) create_console_connection( params->ConsoleHandle ); } diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index 1cecbce9321..c219f3d149c 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -148,6 +148,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename UNICODE_STRING imageW, curdirW, cmdlineW, titleW, desktopW, runtimeW, newdirW; WCHAR imagepath[MAX_PATH]; WCHAR *envW = env; + BOOL no_window = (flags & CREATE_NO_WINDOW) && !(flags & (DETACHED_PROCESS|CREATE_NEW_CONSOLE));
if (!GetLongPathNameW( filename, imagepath, MAX_PATH )) lstrcpynW( imagepath, filename, MAX_PATH ); if (!GetFullPathNameW( imagepath, MAX_PATH, imagepath, NULL )) lstrcpynW( imagepath, filename, MAX_PATH ); @@ -189,8 +190,10 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename } RtlFreeUnicodeString( &newdirW );
- if (flags & CREATE_NEW_PROCESS_GROUP) params->ConsoleFlags = 1; - if (flags & CREATE_NEW_CONSOLE) params->ConsoleHandle = CONSOLE_HANDLE_ALLOC; + params->ConsoleFlags = 0; + if (flags & CREATE_NEW_PROCESS_GROUP) params->ConsoleFlags |= 1; + if (no_window) params->ConsoleFlags |= 2; + if ((flags & CREATE_NEW_CONSOLE) || no_window) params->ConsoleHandle = CONSOLE_HANDLE_ALLOC; else if (!(flags & DETACHED_PROCESS)) { params->ConsoleHandle = NtCurrentTeb()->Peb->ProcessParameters->ConsoleHandle; @@ -532,8 +535,8 @@ 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)
Hi Torge,
On 4/5/22 04:06, Torge Matthies wrote:
Signed-off-by: Torge Matthiesopenglfreak@googlemail.com
dlls/kernel32/tests/console.c | 46 +++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-)
It looks like both you and Eric tackled the problem. While duplication is suboptimal, it's definitely better than no one looking at this :) Eric's tests seemed more complete, so I signed off his version. Please take a look at them and eventually extend them if you see the need.
For the implementation itself, I think that using ConsoleHandle would be a bit nicer. See my other mail.
Thanks,
Jacek