Commit 82b0bb3c authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

server: Separate console and new group flag (CreateProcess).

We were using bit 1 of RTL_USER_PROCESS_PARAMETERS for two different cases: - rightfully, as a sign to block ctrl-c events from being processed by handlers (and by default, terminating the process) - But this was also used to request for the creation of a new process group. This patch properly separates the two use cases, by using the ProcessGroupId field in RTL_USER_PROCESS_PARAMETERS (checked that Win10 behaves as this patch in RtlCreateUserProcess wrt. RTL_USER_PROCESS_PARAMETERS ProcessGroupId usage input/output). Introduce process_group_id in startup_info_t and use it to pass it to server. ProcessGroupId field in RTL_USER_PROCESS_PARAMETERS is now properly set. Note: this will change some external behavior. - before this patch, a child process created with Ctrl-C disabled (ConsoleFlags set), couldn't turn it on as the process was detached from unix console. - now, SIGINT handling is moved to kernelbase (and can be turned on/off at application will), - when creating a new windows group id, the child will be detached from unix console, so will no longer receives the SIGINT from ctrl-c in unix console (if parent was attached to this unix console). Signed-off-by: 's avatarEric Pouech <epouech@codeweavers.com>
parent ad148dfe
......@@ -5063,13 +5063,13 @@ static void test_CreateProcessCUI(void)
group_flags_tests[] =
{
/* 0 */ {TRUE, 0, CONSOLE_STD, TRUE, CP_INH_CONSOLE | CP_WITH_WINDOW},
{TRUE, CREATE_NEW_PROCESS_GROUP, CONSOLE_STD, TRUE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_GROUP_LEADER, .is_todo = TRUE},
{TRUE, CREATE_NEW_PROCESS_GROUP, CONSOLE_STD, TRUE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_GROUP_LEADER},
{TRUE, 0, CONSOLE_STD, FALSE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_ENABLED_CTRLC},
{TRUE, CREATE_NEW_PROCESS_GROUP, CONSOLE_STD, FALSE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_GROUP_LEADER, .is_todo = TRUE},
{TRUE, CREATE_NEW_PROCESS_GROUP, CONSOLE_STD, FALSE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_GROUP_LEADER},
{TRUE, 0, STARTUPINFO_STD, TRUE, CP_INH_CONSOLE | CP_WITH_WINDOW},
/* 5 */ {TRUE, CREATE_NEW_PROCESS_GROUP, STARTUPINFO_STD, TRUE, CP_INH_CONSOLE | CP_WITH_WINDOW | CP_GROUP_LEADER, .is_todo = TRUE},
/* 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, .is_todo = TRUE},
{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},
......
......@@ -187,7 +187,11 @@ 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_PROCESS_GROUP)
params->ConsoleFlags = 1;
else
params->ProcessGroupId = NtCurrentTeb()->Peb->ProcessParameters->ProcessGroupId;
if (flags & CREATE_NEW_CONSOLE) params->ConsoleHandle = CONSOLE_HANDLE_ALLOC;
else if (!(flags & DETACHED_PROCESS))
{
......
......@@ -684,6 +684,7 @@ void init_user_process_params(void)
new_params->dwFillAttribute = params->dwFillAttribute;
new_params->dwFlags = params->dwFlags;
new_params->wShowWindow = params->wShowWindow;
new_params->ProcessGroupId = params->ProcessGroupId;
NtCurrentTeb()->Peb->ProcessParameters = new_params;
NtFreeVirtualMemory( GetCurrentProcess(), (void **)&params, &size, MEM_RELEASE );
......
......@@ -1823,6 +1823,7 @@ static void *build_wow64_parameters( const RTL_USER_PROCESS_PARAMETERS *params )
wow64_params->dwFillAttribute = params->dwFillAttribute;
wow64_params->dwFlags = params->dwFlags;
wow64_params->wShowWindow = params->wShowWindow;
wow64_params->ProcessGroupId = params->ProcessGroupId;
dst = (WCHAR *)(wow64_params + 1);
dup_unicode_string( &params->CurrentDirectory.DosPath, &dst, &wow64_params->CurrentDirectory.DosPath );
......@@ -1981,6 +1982,7 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module )
params->Size = size;
params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED;
params->wShowWindow = 1; /* SW_SHOWNORMAL */
params->ProcessGroupId = GetCurrentProcessId();
params->CurrentDirectory.DosPath.Buffer = (WCHAR *)(params + 1);
wcscpy( params->CurrentDirectory.DosPath.Buffer, get_dos_path( curdir ));
......@@ -2079,6 +2081,7 @@ void init_startup_info(void)
params->dwFillAttribute = info->attribute;
params->dwFlags = info->flags;
params->wShowWindow = info->show;
params->ProcessGroupId = info->process_group_id;
src = (WCHAR *)(info + 1);
dst = (WCHAR *)(params + 1);
......@@ -2169,6 +2172,7 @@ void *create_startup_info( const UNICODE_STRING *nt_image, const RTL_USER_PROCES
info->attribute = params->dwFillAttribute;
info->flags = params->dwFlags;
info->show = params->wShowWindow;
info->process_group_id = params->ProcessGroupId;
ptr = info + 1;
info->curdir_len = append_string( &ptr, params, &params->CurrentDirectory.DosPath );
......
......@@ -441,7 +441,7 @@ static NTSTATUS spawn_process( const RTL_USER_PROCESS_PARAMETERS *params, int so
{
if (!(pid = fork())) /* grandchild */
{
if (params->ConsoleFlags ||
if ((peb->ProcessParameters && params->ProcessGroupId != peb->ProcessParameters->ProcessGroupId) ||
params->ConsoleHandle == CONSOLE_HANDLE_ALLOC ||
params->ConsoleHandle == CONSOLE_HANDLE_ALLOC_NO_WINDOW ||
(params->hStdInput == INVALID_HANDLE_VALUE && params->hStdOutput == INVALID_HANDLE_VALUE))
......@@ -620,7 +620,7 @@ static NTSTATUS fork_and_exec( OBJECT_ATTRIBUTES *attr, int unixdir,
{
close( fd[0] );
if (params->ConsoleFlags ||
if ((peb->ProcessParameters && params->ProcessGroupId != peb->ProcessParameters->ProcessGroupId) ||
params->ConsoleHandle == CONSOLE_HANDLE_ALLOC ||
params->ConsoleHandle == CONSOLE_HANDLE_ALLOC_NO_WINDOW ||
(params->hStdInput == INVALID_HANDLE_VALUE && params->hStdOutput == INVALID_HANDLE_VALUE))
......
......@@ -208,6 +208,7 @@ typedef struct
unsigned int attribute;
unsigned int flags;
unsigned int show;
process_id_t process_group_id;
data_size_t curdir_len;
data_size_t dllpath_len;
data_size_t imagepath_len;
......@@ -6456,7 +6457,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 780
#define SERVER_PROTOCOL_VERSION 781
/* ### protocol_version end ### */
......
......@@ -1358,7 +1358,10 @@ 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->process_group_id == parent->group_id)
process->group_id = parent->group_id;
else
info->data->process_group_id = process->group_id;
info->process = (struct process *)grab_object( process );
reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
......
......@@ -224,6 +224,7 @@ typedef struct
unsigned int attribute;
unsigned int flags;
unsigned int show;
process_id_t process_group_id;
data_size_t curdir_len;
data_size_t dllpath_len;
data_size_t imagepath_len;
......
......@@ -721,7 +721,7 @@ C_ASSERT( sizeof(property_data_t) == 16 );
C_ASSERT( sizeof(rectangle_t) == 16 );
C_ASSERT( sizeof(select_op_t) == 264 );
C_ASSERT( sizeof(short int) == 2 );
C_ASSERT( sizeof(startup_info_t) == 92 );
C_ASSERT( sizeof(startup_info_t) == 96 );
C_ASSERT( sizeof(struct filesystem_event) == 12 );
C_ASSERT( sizeof(struct handle_info) == 20 );
C_ASSERT( sizeof(struct luid) == 8 );
......
......@@ -960,10 +960,11 @@ static void dump_varargs_startup_info( const char *prefix, data_size_t size )
fprintf( stderr,
"%s{debug_flags=%x,console_flags=%x,console=%04x,hstdin=%04x,hstdout=%04x,hstderr=%04x,"
"x=%u,y=%u,xsize=%u,ysize=%u,xchars=%u,ychars=%u,attribute=%02x,flags=%x,show=%u",
"x=%u,y=%u,xsize=%u,ysize=%u,xchars=%u,ychars=%u,attribute=%02x,flags=%x,show=%u,"
"process_group_id=%u",
prefix, info.debug_flags, info.console_flags, info.console,
info.hstdin, info.hstdout, info.hstderr, info.x, info.y, info.xsize, info.ysize,
info.xchars, info.ychars, info.attribute, info.flags, info.show );
info.xchars, info.ychars, info.attribute, info.flags, info.show, info.process_group_id );
pos = dump_inline_unicode_string( ",curdir=L\"", pos, info.curdir_len, size );
pos = dump_inline_unicode_string( "\",dllpath=L\"", pos, info.dllpath_len, size );
pos = dump_inline_unicode_string( "\",imagepath=L\"", pos, info.imagepath_len, size );
......
......@@ -61,7 +61,7 @@ my %formats =
"pe_image_info_t" => [ 80, 8 ],
"property_data_t" => [ 16, 8 ],
"select_op_t" => [ 264, 8 ],
"startup_info_t" => [ 92, 4 ],
"startup_info_t" => [ 96, 4 ],
"user_apc_t" => [ 40, 8 ],
"struct filesystem_event" => [ 12, 4 ],
"struct handle_info" => [ 20, 4 ],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment