server: Create the initial thread as a separate request.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-09-20 13:26:35 +02:00
parent 0fd450af5b
commit 39afcaac4a
7 changed files with 110 additions and 52 deletions

View File

@ -3096,7 +3096,6 @@ static void test_process_security_child(void)
CloseHandle( handle ); CloseHandle( handle );
handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() ); handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() );
todo_wine
ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n"); ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n");
} }

View File

@ -1949,6 +1949,68 @@ static pid_t exec_loader( LPCWSTR cmd_line, unsigned int flags, int socketfd,
return pid; return pid;
} }
/* creates a struct security_descriptor and contained information in one contiguous piece of memory */
static NTSTATUS alloc_object_attributes( const SECURITY_ATTRIBUTES *attr, struct object_attributes **ret,
data_size_t *ret_len )
{
unsigned int len = sizeof(**ret);
PSID owner = NULL, group = NULL;
ACL *dacl, *sacl;
BOOLEAN dacl_present, sacl_present, defaulted;
PSECURITY_DESCRIPTOR sd = NULL;
NTSTATUS status;
*ret = NULL;
*ret_len = 0;
if (attr) sd = attr->lpSecurityDescriptor;
if (sd)
{
len += sizeof(struct security_descriptor);
if ((status = RtlGetOwnerSecurityDescriptor( sd, &owner, &defaulted ))) return status;
if ((status = RtlGetGroupSecurityDescriptor( sd, &group, &defaulted ))) return status;
if ((status = RtlGetSaclSecurityDescriptor( sd, &sacl_present, &sacl, &defaulted ))) return status;
if ((status = RtlGetDaclSecurityDescriptor( sd, &dacl_present, &dacl, &defaulted ))) return status;
if (owner) len += RtlLengthSid( owner );
if (group) len += RtlLengthSid( group );
if (sacl_present && sacl) len += sacl->AclSize;
if (dacl_present && dacl) len += dacl->AclSize;
}
len = (len + 3) & ~3; /* DWORD-align the entire structure */
*ret = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
if (!*ret) return STATUS_NO_MEMORY;
(*ret)->attributes = (attr && attr->bInheritHandle) ? OBJ_INHERIT : 0;
if (sd)
{
struct security_descriptor *descr = (struct security_descriptor *)(*ret + 1);
unsigned char *ptr = (unsigned char *)(descr + 1);
descr->control = ((SECURITY_DESCRIPTOR *)sd)->Control & ~SE_SELF_RELATIVE;
if (owner) descr->owner_len = RtlLengthSid( owner );
if (group) descr->group_len = RtlLengthSid( group );
if (sacl_present && sacl) descr->sacl_len = sacl->AclSize;
if (dacl_present && dacl) descr->dacl_len = dacl->AclSize;
memcpy( ptr, owner, descr->owner_len );
ptr += descr->owner_len;
memcpy( ptr, group, descr->group_len );
ptr += descr->group_len;
memcpy( ptr, sacl, descr->sacl_len );
ptr += descr->sacl_len;
memcpy( ptr, dacl, descr->dacl_len );
(*ret)->sd_len = (sizeof(*descr) + descr->owner_len + descr->group_len + descr->sacl_len +
descr->dacl_len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1);
}
*ret_len = len;
return STATUS_SUCCESS;
}
/*********************************************************************** /***********************************************************************
* create_process * create_process
* *
@ -1964,7 +2026,9 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
static const char *cpu_names[] = { "x86", "x86_64", "PowerPC", "ARM", "ARM64" }; static const char *cpu_names[] = { "x86", "x86_64", "PowerPC", "ARM", "ARM64" };
NTSTATUS status; NTSTATUS status;
BOOL success = FALSE; BOOL success = FALSE;
HANDLE process_info; HANDLE process_info, process_handle = 0;
struct object_attributes *objattr;
data_size_t attr_len;
WCHAR *env_end; WCHAR *env_end;
char *winedebug = NULL; char *winedebug = NULL;
startup_info_t *startup_info; startup_info_t *startup_info;
@ -2062,10 +2126,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
req->create_flags = flags; req->create_flags = flags;
req->socket_fd = socketfd[1]; req->socket_fd = socketfd[1];
req->exe_file = wine_server_obj_handle( hFile ); req->exe_file = wine_server_obj_handle( hFile );
req->process_access = PROCESS_ALL_ACCESS; req->access = PROCESS_ALL_ACCESS;
req->process_attr = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle) ? OBJ_INHERIT : 0; req->attributes = (psa && psa->nLength >= sizeof(*psa) && psa->bInheritHandle) ? OBJ_INHERIT : 0;
req->thread_access = THREAD_ALL_ACCESS;
req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0;
req->cpu = cpu; req->cpu = cpu;
req->info_size = startup_info_size; req->info_size = startup_info_size;
@ -2074,14 +2136,33 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
if (!(status = wine_server_call( req ))) if (!(status = wine_server_call( req )))
{ {
info->dwProcessId = (DWORD)reply->pid; info->dwProcessId = (DWORD)reply->pid;
info->dwThreadId = (DWORD)reply->tid; process_handle = wine_server_ptr_handle( reply->handle );
info->hProcess = wine_server_ptr_handle( reply->phandle );
info->hThread = wine_server_ptr_handle( reply->thandle );
} }
process_info = wine_server_ptr_handle( reply->info ); process_info = wine_server_ptr_handle( reply->info );
} }
SERVER_END_REQ; SERVER_END_REQ;
if (!status)
{
alloc_object_attributes( tsa, &objattr, &attr_len );
SERVER_START_REQ( new_thread )
{
req->process = wine_server_obj_handle( process_handle );
req->access = THREAD_ALL_ACCESS;
req->suspend = !!(flags & CREATE_SUSPENDED);
req->request_fd = -1;
wine_server_add_data( req, objattr, attr_len );
if (!(status = wine_server_call( req )))
{
info->hProcess = process_handle;
info->hThread = wine_server_ptr_handle( reply->handle );
info->dwThreadId = reply->tid;
}
}
SERVER_END_REQ;
HeapFree( GetProcessHeap(), 0, objattr );
}
RtlReleasePebLock(); RtlReleasePebLock();
if (status) if (status)
{ {
@ -2096,6 +2177,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
break; break;
} }
close( socketfd[0] ); close( socketfd[0] );
CloseHandle( process_handle );
HeapFree( GetProcessHeap(), 0, startup_info ); HeapFree( GetProcessHeap(), 0, startup_info );
HeapFree( GetProcessHeap(), 0, winedebug ); HeapFree( GetProcessHeap(), 0, winedebug );
SetLastError( RtlNtStatusToDosError( status )); SetLastError( RtlNtStatusToDosError( status ));

View File

@ -726,25 +726,21 @@ struct new_process_request
unsigned int create_flags; unsigned int create_flags;
int socket_fd; int socket_fd;
obj_handle_t exe_file; obj_handle_t exe_file;
unsigned int process_access; unsigned int access;
unsigned int process_attr; unsigned int attributes;
unsigned int thread_access;
unsigned int thread_attr;
cpu_type_t cpu; cpu_type_t cpu;
data_size_t info_size; data_size_t info_size;
/* VARARG(info,startup_info,info_size); */ /* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */ /* VARARG(env,unicode_str); */
char __pad_52[4]; char __pad_44[4];
}; };
struct new_process_reply struct new_process_reply
{ {
struct reply_header __header; struct reply_header __header;
obj_handle_t info; obj_handle_t info;
process_id_t pid; process_id_t pid;
obj_handle_t phandle; obj_handle_t handle;
thread_id_t tid; char __pad_20[4];
obj_handle_t thandle;
char __pad_28[4];
}; };
@ -6536,6 +6532,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply; struct terminate_job_reply terminate_job_reply;
}; };
#define SERVER_PROTOCOL_VERSION 562 #define SERVER_PROTOCOL_VERSION 563
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -1061,7 +1061,6 @@ struct process_snapshot *process_snap( int *count )
DECL_HANDLER(new_process) DECL_HANDLER(new_process)
{ {
struct startup_info *info; struct startup_info *info;
struct thread *thread;
struct process *process = NULL; struct process *process = NULL;
struct process *parent = current->process; struct process *parent = current->process;
int socket_fd = thread_get_inflight_fd( current, req->socket_fd ); int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
@ -1166,7 +1165,6 @@ DECL_HANDLER(new_process)
} }
if (!(process = create_process( socket_fd, current, req->inherit_all ))) goto done; if (!(process = create_process( socket_fd, current, req->inherit_all ))) goto done;
if (!(thread = create_thread( -1, process, NULL ))) goto done;
process->startup_info = (struct startup_info *)grab_object( info ); process->startup_info = (struct startup_info *)grab_object( info );
@ -1180,9 +1178,6 @@ DECL_HANDLER(new_process)
/* connect to the window station */ /* connect to the window station */
connect_process_winstation( process, current ); connect_process_winstation( process, current );
/* thread will be actually suspended in init_done */
if (req->create_flags & CREATE_SUSPENDED) thread->suspend++;
/* set the process console */ /* set the process console */
if (!(req->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE))) if (!(req->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)))
{ {
@ -1224,9 +1219,7 @@ DECL_HANDLER(new_process)
info->process = (struct process *)grab_object( process ); info->process = (struct process *)grab_object( process );
reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 ); reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
reply->pid = get_process_id( process ); reply->pid = get_process_id( process );
reply->tid = get_thread_id( thread ); reply->handle = alloc_handle( parent, process, req->access, req->attributes );
reply->phandle = alloc_handle( parent, process, req->process_access, req->process_attr );
reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr );
done: done:
if (process) release_object( process ); if (process) release_object( process );

View File

@ -740,10 +740,8 @@ struct rawinput_device
unsigned int create_flags; /* creation flags */ unsigned int create_flags; /* creation flags */
int socket_fd; /* file descriptor for process socket */ int socket_fd; /* file descriptor for process socket */
obj_handle_t exe_file; /* file handle for main exe */ obj_handle_t exe_file; /* file handle for main exe */
unsigned int process_access; /* access rights for process object */ unsigned int access; /* access rights for process object */
unsigned int process_attr; /* attributes for process object */ unsigned int attributes; /* attributes for process object */
unsigned int thread_access; /* access rights for thread object */
unsigned int thread_attr; /* attributes for thread object */
cpu_type_t cpu; /* CPU that the new process will use */ cpu_type_t cpu; /* CPU that the new process will use */
data_size_t info_size; /* size of startup info */ data_size_t info_size; /* size of startup info */
VARARG(info,startup_info,info_size); /* startup information */ VARARG(info,startup_info,info_size); /* startup information */
@ -751,9 +749,7 @@ struct rawinput_device
@REPLY @REPLY
obj_handle_t info; /* new process info handle */ obj_handle_t info; /* new process info handle */
process_id_t pid; /* process id */ process_id_t pid; /* process id */
obj_handle_t phandle; /* process handle (in the current process) */ obj_handle_t handle; /* process handle (in the current process) */
thread_id_t tid; /* thread id */
obj_handle_t thandle; /* thread handle (in the current process) */
@END @END

View File

@ -734,19 +734,15 @@ C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 16 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 20 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 20 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 24 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 24 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, process_access) == 28 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 28 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, process_attr) == 32 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, attributes) == 32 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_access) == 36 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 36 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_attr) == 40 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 40 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 44 ); C_ASSERT( sizeof(struct new_process_request) == 48 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 48 );
C_ASSERT( sizeof(struct new_process_request) == 56 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 ); 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, pid) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, phandle) == 16 ); C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, tid) == 20 ); C_ASSERT( sizeof(struct new_process_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, thandle) == 24 );
C_ASSERT( sizeof(struct new_process_reply) == 32 );
C_ASSERT( FIELD_OFFSET(struct get_new_process_info_request, info) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_new_process_info_request, info) == 12 );
C_ASSERT( sizeof(struct get_new_process_info_request) == 16 ); C_ASSERT( sizeof(struct get_new_process_info_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, success) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, success) == 8 );

View File

@ -1229,10 +1229,8 @@ static void dump_new_process_request( const struct new_process_request *req )
fprintf( stderr, ", create_flags=%08x", req->create_flags ); fprintf( stderr, ", create_flags=%08x", req->create_flags );
fprintf( stderr, ", socket_fd=%d", req->socket_fd ); fprintf( stderr, ", socket_fd=%d", req->socket_fd );
fprintf( stderr, ", exe_file=%04x", req->exe_file ); fprintf( stderr, ", exe_file=%04x", req->exe_file );
fprintf( stderr, ", process_access=%08x", req->process_access ); fprintf( stderr, ", access=%08x", req->access );
fprintf( stderr, ", process_attr=%08x", req->process_attr ); fprintf( stderr, ", attributes=%08x", req->attributes );
fprintf( stderr, ", thread_access=%08x", req->thread_access );
fprintf( stderr, ", thread_attr=%08x", req->thread_attr );
dump_cpu_type( ", cpu=", &req->cpu ); dump_cpu_type( ", cpu=", &req->cpu );
fprintf( stderr, ", info_size=%u", req->info_size ); fprintf( stderr, ", info_size=%u", req->info_size );
dump_varargs_startup_info( ", info=", min(cur_size,req->info_size) ); dump_varargs_startup_info( ", info=", min(cur_size,req->info_size) );
@ -1243,9 +1241,7 @@ static void dump_new_process_reply( const struct new_process_reply *req )
{ {
fprintf( stderr, " info=%04x", req->info ); fprintf( stderr, " info=%04x", req->info );
fprintf( stderr, ", pid=%04x", req->pid ); fprintf( stderr, ", pid=%04x", req->pid );
fprintf( stderr, ", phandle=%04x", req->phandle ); fprintf( stderr, ", handle=%04x", req->handle );
fprintf( stderr, ", tid=%04x", req->tid );
fprintf( stderr, ", thandle=%04x", req->thandle );
} }
static void dump_get_new_process_info_request( const struct get_new_process_info_request *req ) static void dump_get_new_process_info_request( const struct get_new_process_info_request *req )