Commit 245efd04 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Move NtCreateThreadEx() to the Unix library.

parent 33c750f5
...@@ -1028,6 +1028,7 @@ ...@@ -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 ) ...@@ -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, ...@@ -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, ...@@ -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 ) ...@@ -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 ...@@ -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 = ...@@ -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 = ...@@ -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 ...@@ -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 ) ...@@ -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.
*/
static void update_attr_list( PS_ATTRIBUTE_LIST *attr, const CLIENT_ID *id )
{
SIZE_T i, count = (attr->TotalLength - sizeof(attr->TotalLength)) / sizeof(PS_ATTRIBUTE);
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 CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr, NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param, void *relay, HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param,
ULONG flags, SIZE_T stack_commit, SIZE_T stack_reserve, ULONG flags, SIZE_T zero_bits, SIZE_T stack_commit,
CLIENT_ID *id ) 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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ); NtClose( *handle );
RtlReleaseActivationContext( actctx ); RtlReleaseActivationContext( actctx );
close( request_pipe[1] ); close( request_pipe[1] );
return status; 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; ...@@ -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; ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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);
......
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