From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/kernel32/tests/console.c | 12 ++++++------ dlls/kernel32/tests/process.c | 6 +++--- dlls/ntdll/unix/env.c | 24 +++++++++++++++++++++++- include/wine/server_protocol.h | 5 +++-- server/process.c | 4 +++- server/process.h | 1 + server/protocol.def | 1 + server/request.h | 5 +++-- server/trace.c | 1 + 9 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 54d1a80709b..74f8f467a9f 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -5014,10 +5014,10 @@ static void test_CreateProcessCUI(void) {FALSE, DETACHED_PROCESS | CREATE_NO_WINDOW, NULL_STD, 0}, /* 5*/ {FALSE, CREATE_NEW_CONSOLE | CREATE_NO_WINDOW, NULL_STD, 0},
- {FALSE, 0, CONSOLE_STD, 0, TRUE}, + {FALSE, 0, CONSOLE_STD, 0}, {FALSE, DETACHED_PROCESS, CONSOLE_STD, 0}, {FALSE, CREATE_NEW_CONSOLE, CONSOLE_STD, 0}, - {FALSE, CREATE_NO_WINDOW, CONSOLE_STD, 0, TRUE}, + {FALSE, CREATE_NO_WINDOW, CONSOLE_STD, 0}, /*10*/ {FALSE, DETACHED_PROCESS | CREATE_NO_WINDOW, CONSOLE_STD, 0}, {FALSE, CREATE_NEW_CONSOLE | CREATE_NO_WINDOW, CONSOLE_STD, 0},
@@ -5070,10 +5070,10 @@ static void test_CreateProcessCUI(void) /* 5 */ {TRUE, CREATE_NEW_PROCESS_GROUP, STARTUPINFO_STD, TRUE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_GROUP_LEADER}, {TRUE, 0, STARTUPINFO_STD, FALSE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_ENABLED_CTRLC}, {TRUE, CREATE_NEW_PROCESS_GROUP, STARTUPINFO_STD, FALSE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_GROUP_LEADER}, - {FALSE, 0, CONSOLE_STD, TRUE, 0, .is_todo = TRUE}, - {FALSE, CREATE_NEW_PROCESS_GROUP, CONSOLE_STD, TRUE, CP_GROUP_LEADER, .is_todo = TRUE}, -/* 10 */ {FALSE, 0, CONSOLE_STD, FALSE, CP_ENABLED_CTRLC, .is_todo = TRUE}, - {FALSE, CREATE_NEW_PROCESS_GROUP, CONSOLE_STD, FALSE, CP_GROUP_LEADER, .is_todo = TRUE}, + {FALSE, 0, CONSOLE_STD, TRUE, 0}, + {FALSE, CREATE_NEW_PROCESS_GROUP, CONSOLE_STD, TRUE, CP_GROUP_LEADER}, +/* 10 */ {FALSE, 0, CONSOLE_STD, FALSE, CP_ENABLED_CTRLC}, + {FALSE, CREATE_NEW_PROCESS_GROUP, CONSOLE_STD, FALSE, CP_GROUP_LEADER}, {FALSE, 0, STARTUPINFO_STD, TRUE, 0, .is_todo = TRUE}, {FALSE, CREATE_NEW_PROCESS_GROUP, STARTUPINFO_STD, TRUE, CP_GROUP_LEADER, .is_todo = TRUE}, {FALSE, 0, STARTUPINFO_STD, FALSE, CP_ENABLED_CTRLC, .is_todo = TRUE}, diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 56465520569..11cf72c08fa 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -3259,7 +3259,7 @@ static void test_StdHandleInheritance(void) {ARG_STD | ARG_CP_INHERIT | ARG_HANDLE_INHERIT | H_DISK, HATTR_TYPE | HATTR_INHERIT | FILE_TYPE_DISK},
/* all others handles type behave as H_DISK */ - {ARG_STARTUPINFO | ARG_HANDLE_INHERIT | H_DISK, HATTR_NULL, .is_todo = 7, .is_broken = HATTR_TYPE | FILE_TYPE_UNKNOWN}, + {ARG_STARTUPINFO | ARG_HANDLE_INHERIT | H_DISK, HATTR_NULL, .is_broken = HATTR_TYPE | FILE_TYPE_UNKNOWN}, {ARG_STD | ARG_HANDLE_INHERIT | H_DISK, HATTR_TYPE | HATTR_INHERIT | FILE_TYPE_DISK}, }, nothing_gui[] = @@ -3275,8 +3275,8 @@ static void test_StdHandleInheritance(void) {ARG_STD | ARG_CP_INHERIT | ARG_HANDLE_INHERIT | H_CONSOLE, HATTR_NULL, .is_todo = 1, .is_broken = HATTR_TYPE | FILE_TYPE_UNKNOWN},
/* all others handles type behave as H_DISK */ - {ARG_STARTUPINFO | ARG_HANDLE_INHERIT | H_DISK, HATTR_NULL, .is_todo = 7, .is_broken = HATTR_TYPE | FILE_TYPE_UNKNOWN}, - {ARG_STD | ARG_HANDLE_INHERIT | H_DISK, HATTR_NULL, .is_todo = 1}, + {ARG_STARTUPINFO | ARG_HANDLE_INHERIT | H_DISK, HATTR_NULL, .is_broken = HATTR_TYPE | FILE_TYPE_UNKNOWN}, + {ARG_STD | ARG_HANDLE_INHERIT | H_DISK, HATTR_NULL}, }, detached_cui[] = { diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 4fd3254b2d2..33b4f20130f 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -2023,6 +2023,26 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module ) }
+static void inherit_std_handles( unsigned int creation_flags, RTL_USER_PROCESS_PARAMETERS *params ) +{ + if (creation_flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES) return; + + /* when the inherit flag isn't in CreateProcess by parent, + * only inherit the default std handles for CUI subsystem + */ + if (main_image_info.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI || + (params->dwFlags & STARTF_USESTDHANDLES)) + { + NtClose( params->hStdInput ); + params->hStdInput = NULL; + NtClose( params->hStdOutput ); + params->hStdOutput = NULL; + NtClose( params->hStdError ); + params->hStdError = NULL; + } +} + + /************************************************************************* * init_startup_info */ @@ -2030,7 +2050,7 @@ void init_startup_info(void) { WCHAR *src, *dst, *env, *image; void *module = NULL; - unsigned int status; + unsigned int status, creation_flags; SIZE_T size, info_size, env_size, env_pos; RTL_USER_PROCESS_PARAMETERS *params = NULL; startup_info_t *info; @@ -2050,6 +2070,7 @@ void init_startup_info(void) wine_server_set_reply( req, info, startup_info_size ); status = wine_server_call( req ); machine = reply->machine; + creation_flags = reply->creation_flags; info_size = reply->info_size; env_size = (wine_server_reply_size( reply ) - info_size) / sizeof(WCHAR); } @@ -2139,6 +2160,7 @@ void init_startup_info(void) rebuild_argv(); main_wargv = build_wargv( get_dos_path( image )); free( image ); + inherit_std_handles( creation_flags, params ); init_peb( params, module ); }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index a392b532f4e..aef56c5dc03 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -954,10 +954,11 @@ struct get_startup_info_reply { struct reply_header __header; data_size_t info_size; + unsigned int creation_flags; unsigned short machine; /* VARARG(info,startup_info,info_size); */ /* VARARG(env,unicode_str); */ - char __pad_14[2]; + char __pad_18[6]; };
@@ -6504,7 +6505,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 784 +#define SERVER_PROTOCOL_VERSION 785
/* ### protocol_version end ### */
diff --git a/server/process.c b/server/process.c index a0d5ea64d97..7039fe27109 100644 --- a/server/process.c +++ b/server/process.c @@ -668,6 +668,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla process->image = NULL; process->job = NULL; process->console = NULL; + process->creation_flags = flags; process->startup_state = STARTUP_IN_PROGRESS; process->startup_info = NULL; process->idle_event = NULL; @@ -1333,7 +1334,7 @@ DECL_HANDLER(new_process) info->data->console = duplicate_handle( parent, info->data->console, process, 0, 0, DUPLICATE_SAME_ACCESS );
- if (!(req->flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES) && info->data->console != 1) + if (!(req->flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES)) { info->data->hstdin = duplicate_handle( parent, info->data->hstdin, process, 0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS ); @@ -1401,6 +1402,7 @@ DECL_HANDLER(get_startup_info)
/* we return the data directly without making a copy so this can only be called once */ reply->machine = process->machine; + reply->creation_flags = process->creation_flags; reply->info_size = info->info_size; size = info->data_size; if (size > get_reply_max_size()) size = get_reply_max_size(); diff --git a/server/process.h b/server/process.h index 97e0d455ece..d564c49933a 100644 --- a/server/process.h +++ b/server/process.h @@ -68,6 +68,7 @@ struct process struct list locks; /* list of file locks owned by the process */ struct list classes; /* window classes owned by the process */ struct console *console; /* console input */ + unsigned int creation_flags; /* flags used by parent to create self */ enum startup_state startup_state; /* startup state */ struct startup_info *startup_info; /* startup info while init is in progress */ struct event *idle_event; /* event for input idle */ diff --git a/server/protocol.def b/server/protocol.def index e9195df6b65..a0606f143fa 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -945,6 +945,7 @@ typedef struct @REQ(get_startup_info) @REPLY data_size_t info_size; /* size of startup info */ + unsigned int creation_flags; /* flags used by parent to create the new process */ unsigned short machine; /* architecture for the new process */ VARARG(info,startup_info,info_size); /* startup information */ VARARG(env,unicode_str); /* environment */ diff --git a/server/request.h b/server/request.h index d6043c5fdc3..9dc38f2a71b 100644 --- a/server/request.h +++ b/server/request.h @@ -772,8 +772,9 @@ C_ASSERT( FIELD_OFFSET(struct new_thread_reply, handle) == 12 ); C_ASSERT( sizeof(struct new_thread_reply) == 16 ); C_ASSERT( sizeof(struct get_startup_info_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, info_size) == 8 ); -C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, machine) == 12 ); -C_ASSERT( sizeof(struct get_startup_info_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, creation_flags) == 12 ); +C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, machine) == 16 ); +C_ASSERT( sizeof(struct get_startup_info_reply) == 24 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, teb) == 16 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, peb) == 24 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, ldt_copy) == 32 ); diff --git a/server/trace.c b/server/trace.c index 55ccefa1746..13520183de3 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1447,6 +1447,7 @@ static void dump_get_startup_info_request( const struct get_startup_info_request static void dump_get_startup_info_reply( const struct get_startup_info_reply *req ) { fprintf( stderr, " info_size=%u", req->info_size ); + fprintf( stderr, ", creation_flags=%08x", req->creation_flags ); fprintf( stderr, ", machine=%04x", req->machine ); dump_varargs_startup_info( ", info=", min(cur_size,req->info_size) ); dump_varargs_unicode_str( ", env=", cur_size );