server: Pass the NT process flags to the new_process request.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-04-16 11:43:14 +02:00
parent a1bba82861
commit 828077e3b3
8 changed files with 42 additions and 44 deletions

View File

@ -246,7 +246,7 @@ struct _PROC_THREAD_ATTRIBUTE_LIST
* create_nt_process
*/
static NTSTATUS create_nt_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUTES *psa,
SECURITY_ATTRIBUTES *tsa, BOOL inherit, DWORD flags,
SECURITY_ATTRIBUTES *tsa, DWORD process_flags,
RTL_USER_PROCESS_PARAMETERS *params,
RTL_USER_PROCESS_INFORMATION *info, HANDLE parent,
const struct proc_thread_attr *handle_list )
@ -263,8 +263,6 @@ static NTSTATUS create_nt_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUT
status = RtlDosPathNameToNtPathName_U_WithStatus( params->ImagePathName.Buffer, &nameW, NULL, NULL );
if (!status)
{
params->DebugFlags = flags; /* hack, cf. RtlCreateUserProcess implementation */
RtlNormalizeProcessParams( params );
attr->Attributes[pos].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
@ -290,7 +288,7 @@ static NTSTATUS create_nt_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUT
attr->Attributes[pos].ReturnLength = NULL;
pos++;
}
if (inherit && handle_list)
if ((process_flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES) && handle_list)
{
attr->Attributes[pos].Attribute = PS_ATTRIBUTE_HANDLE_LIST;
attr->Attributes[pos].Size = handle_list->size;
@ -320,8 +318,7 @@ static NTSTATUS create_nt_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUT
InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, tsa ? tsa->lpSecurityDescriptor : NULL );
status = NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
&process_attr, &thread_attr,
inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0,
&process_attr, &thread_attr, process_flags,
THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params,
&create_info, attr );
@ -335,7 +332,7 @@ static NTSTATUS create_nt_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUT
* create_vdm_process
*/
static NTSTATUS create_vdm_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUTES *psa,
SECURITY_ATTRIBUTES *tsa, BOOL inherit, DWORD flags,
SECURITY_ATTRIBUTES *tsa, DWORD flags,
RTL_USER_PROCESS_PARAMETERS *params,
RTL_USER_PROCESS_INFORMATION *info )
{
@ -356,7 +353,7 @@ static NTSTATUS create_vdm_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBU
winevdm, params->ImagePathName.Buffer, params->CommandLine.Buffer );
RtlInitUnicodeString( &params->ImagePathName, winevdm );
RtlInitUnicodeString( &params->CommandLine, newcmdline );
status = create_nt_process( token, debug, psa, tsa, inherit, flags, params, info, NULL, NULL );
status = create_nt_process( token, debug, psa, tsa, flags, params, info, NULL, NULL );
HeapFree( GetProcessHeap(), 0, newcmdline );
return status;
}
@ -366,7 +363,7 @@ static NTSTATUS create_vdm_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBU
* create_cmd_process
*/
static NTSTATUS create_cmd_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUTES *psa,
SECURITY_ATTRIBUTES *tsa, BOOL inherit, DWORD flags,
SECURITY_ATTRIBUTES *tsa, DWORD flags,
RTL_USER_PROCESS_PARAMETERS *params,
RTL_USER_PROCESS_INFORMATION *info )
{
@ -385,7 +382,7 @@ static NTSTATUS create_cmd_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBU
swprintf( newcmdline, len, L"%s /s/c \"%s\"", comspec, params->CommandLine.Buffer );
RtlInitUnicodeString( &params->ImagePathName, comspec );
RtlInitUnicodeString( &params->CommandLine, newcmdline );
status = create_nt_process( token, debug, psa, tsa, inherit, flags, params, info, NULL, NULL );
status = create_nt_process( token, debug, psa, tsa, flags, params, info, NULL, NULL );
RtlFreeHeap( GetProcessHeap(), 0, newcmdline );
return status;
}
@ -494,6 +491,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
RTL_USER_PROCESS_PARAMETERS *params = NULL;
RTL_USER_PROCESS_INFORMATION rtl_info;
HANDLE parent = 0, debug = 0;
ULONG nt_flags = 0;
NTSTATUS status;
/* Process the AppName and/or CmdLine to get module name and path */
@ -590,8 +588,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
}
}
status = create_nt_process( token, debug, process_attr, thread_attr, inherit,
flags, params, &rtl_info, parent, handle_list );
if (inherit) nt_flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
if (flags & DEBUG_ONLY_THIS_PROCESS) nt_flags |= PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT;
if (flags & CREATE_BREAKAWAY_FROM_JOB) nt_flags |= PROCESS_CREATE_FLAGS_BREAKAWAY;
if (flags & CREATE_SUSPENDED) nt_flags |= PROCESS_CREATE_FLAGS_SUSPENDED;
status = create_nt_process( token, debug, process_attr, thread_attr,
nt_flags, params, &rtl_info, parent, handle_list );
switch (status)
{
case STATUS_SUCCESS:
@ -601,7 +604,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
case STATUS_INVALID_IMAGE_PROTECT:
TRACE( "starting %s as Win16/DOS binary\n", debugstr_w(app_name) );
status = create_vdm_process( token, debug, process_attr, thread_attr,
inherit, flags, params, &rtl_info );
nt_flags, params, &rtl_info );
break;
case STATUS_INVALID_IMAGE_NOT_MZ:
/* check for .com or .bat extension */
@ -610,13 +613,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
{
TRACE( "starting %s as DOS binary\n", debugstr_w(app_name) );
status = create_vdm_process( token, debug, process_attr, thread_attr,
inherit, flags, params, &rtl_info );
nt_flags, params, &rtl_info );
}
else if (!wcsicmp( p, L".bat" ) || !wcsicmp( p, L".cmd" ))
{
TRACE( "starting %s as batch binary\n", debugstr_w(app_name) );
status = create_cmd_process( token, debug, process_attr, thread_attr,
inherit, flags, params, &rtl_info );
nt_flags, params, &rtl_info );
}
break;
}

View File

@ -711,8 +711,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
req->token = wine_server_obj_handle( token );
req->debug = wine_server_obj_handle( debug );
req->parent_process = wine_server_obj_handle( parent );
req->inherit_all = !!(process_flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES);
req->create_flags = params->DebugFlags; /* hack: creation flags stored in DebugFlags for now */
req->flags = process_flags;
req->socket_fd = socketfd[1];
req->access = process_access;
req->cpu = get_machine_cpu( &pe_info );

View File

@ -833,8 +833,7 @@ struct new_process_request
obj_handle_t token;
obj_handle_t debug;
obj_handle_t parent_process;
int inherit_all;
unsigned int create_flags;
unsigned int flags;
int socket_fd;
unsigned int access;
client_cpu_t cpu;
@ -844,7 +843,6 @@ struct new_process_request
/* VARARG(handles,uints,handles_size); */
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */
char __pad_52[4];
};
struct new_process_reply
{
@ -6224,7 +6222,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 690
#define SERVER_PROTOCOL_VERSION 691
/* ### protocol_version end ### */

View File

@ -511,7 +511,7 @@ static void start_sigkill_timer( struct process *process )
/* create a new process */
/* if the function fails the fd is closed */
struct process *create_process( int fd, struct process *parent, int inherit_all, const startup_info_t *info,
struct process *create_process( int fd, struct process *parent, unsigned int flags, const startup_info_t *info,
const struct security_descriptor *sd, const obj_handle_t *handles,
unsigned int handle_count, struct token *token )
{
@ -591,8 +591,10 @@ struct process *create_process( int fd, struct process *parent, int inherit_all,
std_handles[2] = info->hstderr;
process->parent_id = parent->id;
process->handles = inherit_all ? copy_handle_table( process, parent, handles, handle_count, std_handles )
: alloc_handle_table( process, 0 );
if (flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES)
process->handles = copy_handle_table( process, parent, handles, handle_count, std_handles );
else
process->handles = alloc_handle_table( process, 0 );
/* Note: for security reasons, starting a new process does not attempt
* to use the current impersonation token for the new process */
process->token = token_duplicate( token ? token : parent->token, TRUE, 0, NULL, NULL, 0, NULL, 0 );
@ -1060,7 +1062,7 @@ DECL_HANDLER(new_process)
}
else parent = (struct process *)grab_object( current->process );
if (parent->job && (req->create_flags & CREATE_BREAKAWAY_FROM_JOB) &&
if (parent->job && (req->flags & PROCESS_CREATE_FLAGS_BREAKAWAY) &&
!(parent->job->limit_flags & (JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)))
{
set_error( STATUS_ACCESS_DENIED );
@ -1144,14 +1146,14 @@ DECL_HANDLER(new_process)
goto done;
}
if (!(process = create_process( socket_fd, parent, req->inherit_all, info->data, sd,
if (!(process = create_process( socket_fd, parent, req->flags, info->data, sd,
handles, req->handles_size / sizeof(*handles), token )))
goto done;
process->startup_info = (struct startup_info *)grab_object( info );
if (parent->job
&& !(req->create_flags & CREATE_BREAKAWAY_FROM_JOB)
&& !(req->flags & PROCESS_CREATE_FLAGS_BREAKAWAY)
&& !(parent->job->limit_flags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK))
{
add_job_process( parent->job, process );
@ -1165,7 +1167,7 @@ DECL_HANDLER(new_process)
info->data->console = duplicate_handle( parent, info->data->console, process,
0, 0, DUPLICATE_SAME_ACCESS );
if (!req->inherit_all && !(req->create_flags & CREATE_NEW_CONSOLE))
if (!(req->flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES) && info->data->console != 1)
{
info->data->hstdin = duplicate_handle( parent, info->data->hstdin, process,
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
@ -1182,7 +1184,7 @@ DECL_HANDLER(new_process)
if (debug_obj)
{
process->debug_obj = debug_obj;
process->debug_children = !(req->create_flags & DEBUG_ONLY_THIS_PROCESS);
process->debug_children = !(req->flags & PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT);
}
else if (parent->debug_children)
{
@ -1190,8 +1192,7 @@ DECL_HANDLER(new_process)
/* debug_children is set to 1 by default */
}
if (!(req->create_flags & CREATE_NEW_PROCESS_GROUP))
process->group_id = parent->group_id;
if (!info->data->console_flags) process->group_id = parent->group_id;
info->process = (struct process *)grab_object( process );
reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );

View File

@ -97,7 +97,7 @@ struct process
extern unsigned int alloc_ptid( void *ptr );
extern void free_ptid( unsigned int id );
extern void *get_ptid_entry( unsigned int id );
extern struct process *create_process( int fd, struct process *parent, int inherit_all, const startup_info_t *info,
extern struct process *create_process( int fd, struct process *parent, unsigned int flags, const startup_info_t *info,
const struct security_descriptor *sd, const obj_handle_t *handles,
unsigned int handle_count, struct token *token );
extern data_size_t get_process_startup_info_size( struct process *process );

View File

@ -847,8 +847,7 @@ typedef struct
obj_handle_t token; /* process token */
obj_handle_t debug; /* process debug object */
obj_handle_t parent_process; /* parent process */
int inherit_all; /* inherit all handles from parent */
unsigned int create_flags; /* creation flags */
unsigned int flags; /* process creation flags */
int socket_fd; /* file descriptor for process socket */
unsigned int access; /* access rights for process object */
client_cpu_t cpu; /* CPU that the new process will use */

View File

@ -707,14 +707,13 @@ C_ASSERT( sizeof(user_handle_t) == 4 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, token) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, debug) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, parent_process) == 20 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 24 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 28 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 32 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 36 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 40 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 44 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, handles_size) == 48 );
C_ASSERT( sizeof(struct new_process_request) == 56 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, flags) == 24 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 28 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 32 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 36 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 40 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, handles_size) == 44 );
C_ASSERT( sizeof(struct new_process_request) == 48 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, pid) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 );

View File

@ -1368,8 +1368,7 @@ static void dump_new_process_request( const struct new_process_request *req )
fprintf( stderr, " token=%04x", req->token );
fprintf( stderr, ", debug=%04x", req->debug );
fprintf( stderr, ", parent_process=%04x", req->parent_process );
fprintf( stderr, ", inherit_all=%d", req->inherit_all );
fprintf( stderr, ", create_flags=%08x", req->create_flags );
fprintf( stderr, ", flags=%08x", req->flags );
fprintf( stderr, ", socket_fd=%d", req->socket_fd );
fprintf( stderr, ", access=%08x", req->access );
dump_client_cpu( ", cpu=", &req->cpu );