forked from Mirrors/wine-wine
ntdll: Move NtCreateThreadEx() to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>feature/deterministic
parent
33c750f50f
commit
245efd04e1
|
@ -1028,6 +1028,7 @@
|
||||||
@ stdcall RtlUpperChar(long)
|
@ stdcall RtlUpperChar(long)
|
||||||
@ stdcall RtlUpperString(ptr ptr)
|
@ stdcall RtlUpperString(ptr ptr)
|
||||||
@ stub RtlUsageHeap
|
@ stub RtlUsageHeap
|
||||||
|
@ stdcall -norelay RtlUserThreadStart(ptr ptr)
|
||||||
@ cdecl -i386 -norelay RtlUshortByteSwap() NTDLL_RtlUshortByteSwap
|
@ cdecl -i386 -norelay RtlUshortByteSwap() NTDLL_RtlUshortByteSwap
|
||||||
@ stdcall RtlValidAcl(ptr)
|
@ stdcall RtlValidAcl(ptr)
|
||||||
@ stdcall RtlValidRelativeSecurityDescriptor(ptr long long)
|
@ stdcall RtlValidRelativeSecurityDescriptor(ptr long long)
|
||||||
|
|
|
@ -256,12 +256,10 @@ void WINAPI RtlExitUserThread( ULONG status )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* call_thread_entry_point
|
* RtlUserThreadStart (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
|
__ASM_STDCALL_FUNC( RtlUserThreadStart, 8,
|
||||||
extern void call_thread_entry_point(void) DECLSPEC_HIDDEN;
|
|
||||||
__ASM_GLOBAL_FUNC( call_thread_entry_point,
|
|
||||||
"pushl %ebp\n\t"
|
"pushl %ebp\n\t"
|
||||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||||
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
||||||
|
@ -272,7 +270,7 @@ __ASM_GLOBAL_FUNC( call_thread_entry_point,
|
||||||
"call " __ASM_NAME("call_thread_func") )
|
"call " __ASM_NAME("call_thread_func") )
|
||||||
|
|
||||||
/* wrapper for apps that don't declare the thread function correctly */
|
/* wrapper for apps that don't declare the thread function correctly */
|
||||||
extern DWORD call_thread_func_wrapper( LPTHREAD_START_ROUTINE entry, void *arg );
|
extern DWORD call_thread_func_wrapper( PRTL_THREAD_START_ROUTINE entry, void *arg );
|
||||||
__ASM_GLOBAL_FUNC(call_thread_func_wrapper,
|
__ASM_GLOBAL_FUNC(call_thread_func_wrapper,
|
||||||
"pushl %ebp\n\t"
|
"pushl %ebp\n\t"
|
||||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||||
|
@ -287,7 +285,7 @@ __ASM_GLOBAL_FUNC(call_thread_func_wrapper,
|
||||||
__ASM_CFI(".cfi_same_value %ebp\n\t")
|
__ASM_CFI(".cfi_same_value %ebp\n\t")
|
||||||
"ret" )
|
"ret" )
|
||||||
|
|
||||||
void DECLSPEC_HIDDEN call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg )
|
void DECLSPEC_HIDDEN call_thread_func( PRTL_THREAD_START_ROUTINE entry, void *arg )
|
||||||
{
|
{
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
|
@ -304,12 +302,12 @@ void DECLSPEC_HIDDEN call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg )
|
||||||
|
|
||||||
#else /* __i386__ */
|
#else /* __i386__ */
|
||||||
|
|
||||||
static void WINAPI call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
void WINAPI RtlUserThreadStart( PRTL_THREAD_START_ROUTINE entry, void *arg )
|
||||||
{
|
{
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
||||||
RtlExitUserThread( entry( arg ));
|
RtlExitUserThread( ((LPTHREAD_START_ROUTINE)entry)( arg ));
|
||||||
}
|
}
|
||||||
__EXCEPT(call_unhandled_exception_filter)
|
__EXCEPT(call_unhandled_exception_filter)
|
||||||
{
|
{
|
||||||
|
@ -330,29 +328,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle_ptr, ACCESS_MASK access, OBJECT
|
||||||
ULONG flags, SIZE_T zero_bits, SIZE_T stack_commit,
|
ULONG flags, SIZE_T zero_bits, SIZE_T stack_commit,
|
||||||
SIZE_T stack_reserve, PS_ATTRIBUTE_LIST *attr_list )
|
SIZE_T stack_reserve, PS_ATTRIBUTE_LIST *attr_list )
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
return unix_funcs->NtCreateThreadEx( handle_ptr, access, attr, process, start, param,
|
||||||
CLIENT_ID client_id;
|
flags, zero_bits, stack_commit, stack_reserve, attr_list );
|
||||||
|
|
||||||
if (!access) access = THREAD_ALL_ACCESS;
|
|
||||||
|
|
||||||
status = unix_funcs->create_thread( handle_ptr, access, attr, process,
|
|
||||||
start, param, call_thread_entry_point, flags,
|
|
||||||
stack_commit, stack_reserve, &client_id );
|
|
||||||
if (!status && attr_list)
|
|
||||||
{
|
|
||||||
SIZE_T i, count = (attr_list->TotalLength - sizeof(attr_list->TotalLength)) / sizeof(PS_ATTRIBUTE);
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
if (attr_list->Attributes[i].Attribute == PS_ATTRIBUTE_CLIENT_ID)
|
|
||||||
{
|
|
||||||
SIZE_T size = min( attr_list->Attributes[i].Size, sizeof(client_id) );
|
|
||||||
memcpy( attr_list->Attributes[i].ValuePtr, &client_id, size );
|
|
||||||
if (attr_list->Attributes[i].ReturnLength) *attr_list->Attributes[i].ReturnLength = size;
|
|
||||||
}
|
|
||||||
else FIXME( "Unsupported attribute %08lx\n", attr_list->Attributes[i].Attribute );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -993,6 +993,7 @@ static struct unix_funcs unix_funcs =
|
||||||
NtCreateMutant,
|
NtCreateMutant,
|
||||||
NtCreateSection,
|
NtCreateSection,
|
||||||
NtCreateSemaphore,
|
NtCreateSemaphore,
|
||||||
|
NtCreateThreadEx,
|
||||||
NtCreateTimer,
|
NtCreateTimer,
|
||||||
NtCurrentTeb,
|
NtCurrentTeb,
|
||||||
NtDelayExecution,
|
NtDelayExecution,
|
||||||
|
@ -1063,7 +1064,6 @@ static struct unix_funcs unix_funcs =
|
||||||
virtual_release_address_space,
|
virtual_release_address_space,
|
||||||
virtual_set_large_address_space,
|
virtual_set_large_address_space,
|
||||||
init_threading,
|
init_threading,
|
||||||
create_thread,
|
|
||||||
start_process,
|
start_process,
|
||||||
abort_thread,
|
abort_thread,
|
||||||
exit_thread,
|
exit_thread,
|
||||||
|
|
|
@ -123,7 +123,6 @@ struct startup_info
|
||||||
{
|
{
|
||||||
PRTL_THREAD_START_ROUTINE entry;
|
PRTL_THREAD_START_ROUTINE entry;
|
||||||
void *arg;
|
void *arg;
|
||||||
void *relay;
|
|
||||||
HANDLE actctx;
|
HANDLE actctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -150,17 +149,38 @@ static void start_thread( TEB *teb )
|
||||||
RtlActivateActivationContext( 0, info->actctx, &cookie );
|
RtlActivateActivationContext( 0, info->actctx, &cookie );
|
||||||
RtlReleaseActivationContext( info->actctx );
|
RtlReleaseActivationContext( info->actctx );
|
||||||
}
|
}
|
||||||
signal_start_thread( info->entry, info->arg, suspend, info->relay, teb );
|
signal_start_thread( info->entry, info->arg, suspend, RtlUserThreadStart, teb );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* create_thread
|
* update_attr_list
|
||||||
|
*
|
||||||
|
* Update the output attributes.
|
||||||
*/
|
*/
|
||||||
NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
static void update_attr_list( PS_ATTRIBUTE_LIST *attr, const CLIENT_ID *id )
|
||||||
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param, void *relay,
|
{
|
||||||
ULONG flags, SIZE_T stack_commit, SIZE_T stack_reserve,
|
SIZE_T i, count = (attr->TotalLength - sizeof(attr->TotalLength)) / sizeof(PS_ATTRIBUTE);
|
||||||
CLIENT_ID *id )
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (attr->Attributes[i].Attribute == PS_ATTRIBUTE_CLIENT_ID)
|
||||||
|
{
|
||||||
|
SIZE_T size = min( attr->Attributes[i].Size, sizeof(*id) );
|
||||||
|
memcpy( attr->Attributes[i].ValuePtr, id, size );
|
||||||
|
if (attr->Attributes[i].ReturnLength) *attr->Attributes[i].ReturnLength = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NtCreateThreadEx (NTDLL.@)
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
||||||
|
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param,
|
||||||
|
ULONG flags, SIZE_T zero_bits, SIZE_T stack_commit,
|
||||||
|
SIZE_T stack_reserve, PS_ATTRIBUTE_LIST *attr_list )
|
||||||
{
|
{
|
||||||
sigset_t sigset;
|
sigset_t sigset;
|
||||||
pthread_t pthread_id;
|
pthread_t pthread_id;
|
||||||
|
@ -172,6 +192,7 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||||
DWORD tid = 0;
|
DWORD tid = 0;
|
||||||
int request_pipe[2];
|
int request_pipe[2];
|
||||||
SIZE_T extra_stack = PTHREAD_STACK_MIN;
|
SIZE_T extra_stack = PTHREAD_STACK_MIN;
|
||||||
|
CLIENT_ID client_id;
|
||||||
HANDLE actctx;
|
HANDLE actctx;
|
||||||
TEB *teb;
|
TEB *teb;
|
||||||
INITIAL_TEB stack;
|
INITIAL_TEB stack;
|
||||||
|
@ -196,11 +217,9 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||||
if (result.create_thread.status == STATUS_SUCCESS)
|
if (result.create_thread.status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
*handle = wine_server_ptr_handle( result.create_thread.handle );
|
*handle = wine_server_ptr_handle( result.create_thread.handle );
|
||||||
if (id)
|
client_id.UniqueProcess = ULongToHandle( result.create_thread.pid );
|
||||||
{
|
client_id.UniqueThread = ULongToHandle( result.create_thread.tid );
|
||||||
id->UniqueProcess = ULongToHandle( result.create_thread.pid );
|
if (attr_list) update_attr_list( attr_list, &client_id );
|
||||||
id->UniqueThread = ULongToHandle( result.create_thread.tid );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result.create_thread.status;
|
return result.create_thread.status;
|
||||||
}
|
}
|
||||||
|
@ -214,6 +233,8 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||||
}
|
}
|
||||||
server_send_fd( request_pipe[0] );
|
server_send_fd( request_pipe[0] );
|
||||||
|
|
||||||
|
if (!access) access = THREAD_ALL_ACCESS;
|
||||||
|
|
||||||
SERVER_START_REQ( new_thread )
|
SERVER_START_REQ( new_thread )
|
||||||
{
|
{
|
||||||
req->process = wine_server_obj_handle( process );
|
req->process = wine_server_obj_handle( process );
|
||||||
|
@ -249,14 +270,13 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
teb->ClientId.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
|
client_id.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
|
||||||
teb->ClientId.UniqueThread = ULongToHandle( tid );
|
client_id.UniqueThread = ULongToHandle( tid );
|
||||||
if (id) *id = teb->ClientId;
|
teb->ClientId = client_id;
|
||||||
|
|
||||||
info = (struct startup_info *)(teb + 1);
|
info = (struct startup_info *)(teb + 1);
|
||||||
info->entry = start;
|
info->entry = start;
|
||||||
info->arg = param;
|
info->arg = param;
|
||||||
info->relay = relay;
|
|
||||||
info->actctx = actctx;
|
info->actctx = actctx;
|
||||||
|
|
||||||
teb->Tib.StackBase = stack.StackBase;
|
teb->Tib.StackBase = stack.StackBase;
|
||||||
|
@ -286,11 +306,15 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||||
|
|
||||||
done:
|
done:
|
||||||
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
|
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
|
||||||
if (!status) return STATUS_SUCCESS;
|
if (status)
|
||||||
NtClose( *handle );
|
{
|
||||||
RtlReleaseActivationContext( actctx );
|
NtClose( *handle );
|
||||||
close( request_pipe[1] );
|
RtlReleaseActivationContext( actctx );
|
||||||
return status;
|
close( request_pipe[1] );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
if (attr_list) update_attr_list( attr_list, &client_id );
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -97,10 +97,6 @@ extern void CDECL server_init_process_done(void) DECLSPEC_HIDDEN;
|
||||||
extern TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size,
|
extern TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size,
|
||||||
BOOL *suspend, unsigned int *cpus, BOOL *wow64,
|
BOOL *suspend, unsigned int *cpus, BOOL *wow64,
|
||||||
timeout_t *start_time ) DECLSPEC_HIDDEN;
|
timeout_t *start_time ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
|
||||||
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param, void *relay,
|
|
||||||
ULONG flags, SIZE_T stack_commit, SIZE_T stack_reserve,
|
|
||||||
CLIENT_ID *id ) DECLSPEC_HIDDEN;
|
|
||||||
extern void CDECL DECLSPEC_NORETURN start_process( PRTL_THREAD_START_ROUTINE entry, BOOL suspend, void *relay ) DECLSPEC_HIDDEN;
|
extern void CDECL DECLSPEC_NORETURN start_process( PRTL_THREAD_START_ROUTINE entry, BOOL suspend, void *relay ) DECLSPEC_HIDDEN;
|
||||||
extern void CDECL DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
|
extern void CDECL DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
|
||||||
extern void CDECL DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN;
|
extern void CDECL DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
||||||
struct msghdr;
|
struct msghdr;
|
||||||
|
|
||||||
/* increment this when you change the function table */
|
/* increment this when you change the function table */
|
||||||
#define NTDLL_UNIXLIB_VERSION 28
|
#define NTDLL_UNIXLIB_VERSION 29
|
||||||
|
|
||||||
struct unix_funcs
|
struct unix_funcs
|
||||||
{
|
{
|
||||||
|
@ -50,6 +50,10 @@ struct unix_funcs
|
||||||
ULONG protect, ULONG sec_flags, HANDLE file );
|
ULONG protect, ULONG sec_flags, HANDLE file );
|
||||||
NTSTATUS (WINAPI *NtCreateSemaphore)( HANDLE *handle, ACCESS_MASK access,
|
NTSTATUS (WINAPI *NtCreateSemaphore)( HANDLE *handle, ACCESS_MASK access,
|
||||||
const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max );
|
const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max );
|
||||||
|
NTSTATUS (WINAPI *NtCreateThreadEx)( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
||||||
|
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param,
|
||||||
|
ULONG flags, SIZE_T zero_bits, SIZE_T stack_commit,
|
||||||
|
SIZE_T stack_reserve, PS_ATTRIBUTE_LIST *attr_list );
|
||||||
NTSTATUS (WINAPI *NtCreateTimer)( HANDLE *handle, ACCESS_MASK access,
|
NTSTATUS (WINAPI *NtCreateTimer)( HANDLE *handle, ACCESS_MASK access,
|
||||||
const OBJECT_ATTRIBUTES *attr, TIMER_TYPE type );
|
const OBJECT_ATTRIBUTES *attr, TIMER_TYPE type );
|
||||||
TEB * (WINAPI *NtCurrentTeb)(void);
|
TEB * (WINAPI *NtCurrentTeb)(void);
|
||||||
|
@ -166,10 +170,6 @@ struct unix_funcs
|
||||||
/* thread/process functions */
|
/* thread/process functions */
|
||||||
TEB * (CDECL *init_threading)( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size,
|
TEB * (CDECL *init_threading)( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size,
|
||||||
BOOL *suspend, unsigned int *cpus, BOOL *wow64, timeout_t *start_time );
|
BOOL *suspend, unsigned int *cpus, BOOL *wow64, timeout_t *start_time );
|
||||||
NTSTATUS (CDECL *create_thread)( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
|
||||||
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param, void *relay,
|
|
||||||
ULONG flags, SIZE_T stack_commit, SIZE_T stack_reserve,
|
|
||||||
CLIENT_ID *id );
|
|
||||||
void (CDECL *start_process)( PRTL_THREAD_START_ROUTINE entry, BOOL suspend, void *relay );
|
void (CDECL *start_process)( PRTL_THREAD_START_ROUTINE entry, BOOL suspend, void *relay );
|
||||||
void (CDECL *abort_thread)( int status );
|
void (CDECL *abort_thread)( int status );
|
||||||
void (CDECL *exit_thread)( int status );
|
void (CDECL *exit_thread)( int status );
|
||||||
|
|
|
@ -3122,6 +3122,7 @@ NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeToOemN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWO
|
||||||
NTSYSAPI NTSTATUS WINAPI RtlUpdateTimer(HANDLE, HANDLE, DWORD, DWORD);
|
NTSYSAPI NTSTATUS WINAPI RtlUpdateTimer(HANDLE, HANDLE, DWORD, DWORD);
|
||||||
NTSYSAPI CHAR WINAPI RtlUpperChar(CHAR);
|
NTSYSAPI CHAR WINAPI RtlUpperChar(CHAR);
|
||||||
NTSYSAPI void WINAPI RtlUpperString(STRING *,const STRING *);
|
NTSYSAPI void WINAPI RtlUpperString(STRING *,const STRING *);
|
||||||
|
NTSYSAPI void WINAPI RtlUserThreadStart(PRTL_THREAD_START_ROUTINE,void*);
|
||||||
NTSYSAPI NTSTATUS WINAPI RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
|
NTSYSAPI NTSTATUS WINAPI RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
|
||||||
NTSYSAPI BOOLEAN WINAPI RtlValidRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR,ULONG,SECURITY_INFORMATION);
|
NTSYSAPI BOOLEAN WINAPI RtlValidRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR,ULONG,SECURITY_INFORMATION);
|
||||||
NTSYSAPI BOOLEAN WINAPI RtlValidAcl(PACL);
|
NTSYSAPI BOOLEAN WINAPI RtlValidAcl(PACL);
|
||||||
|
|
Loading…
Reference in New Issue