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

ntdll: Move NtCreateThreadEx() to the Unix library.

parent 33c750f5
......@@ -1028,6 +1028,7 @@
@ stdcall RtlUpperChar(long)
@ stdcall RtlUpperString(ptr ptr)
@ stub RtlUsageHeap
@ stdcall -norelay RtlUserThreadStart(ptr ptr)
@ cdecl -i386 -norelay RtlUshortByteSwap() NTDLL_RtlUshortByteSwap
@ stdcall RtlValidAcl(ptr)
@ stdcall RtlValidRelativeSecurityDescriptor(ptr long long)
......
......@@ -256,12 +256,10 @@ void WINAPI RtlExitUserThread( ULONG status )
/***********************************************************************
* call_thread_entry_point
* RtlUserThreadStart (NTDLL.@)
*/
#ifdef __i386__
extern void call_thread_entry_point(void) DECLSPEC_HIDDEN;
__ASM_GLOBAL_FUNC( call_thread_entry_point,
__ASM_STDCALL_FUNC( RtlUserThreadStart, 8,
"pushl %ebp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 4\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") )
/* 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,
"pushl %ebp\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")
"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
{
......@@ -304,12 +302,12 @@ void DECLSPEC_HIDDEN call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg )
#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
{
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)
{
......@@ -330,29 +328,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle_ptr, ACCESS_MASK access, OBJECT
ULONG flags, SIZE_T zero_bits, SIZE_T stack_commit,
SIZE_T stack_reserve, PS_ATTRIBUTE_LIST *attr_list )
{
NTSTATUS status;
CLIENT_ID client_id;
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;
return unix_funcs->NtCreateThreadEx( handle_ptr, access, attr, process, start, param,
flags, zero_bits, stack_commit, stack_reserve, attr_list );
}
......
......@@ -993,6 +993,7 @@ static struct unix_funcs unix_funcs =
NtCreateMutant,
NtCreateSection,
NtCreateSemaphore,
NtCreateThreadEx,
NtCreateTimer,
NtCurrentTeb,
NtDelayExecution,
......@@ -1063,7 +1064,6 @@ static struct unix_funcs unix_funcs =
virtual_release_address_space,
virtual_set_large_address_space,
init_threading,
create_thread,
start_process,
abort_thread,
exit_thread,
......
......@@ -123,7 +123,6 @@ struct startup_info
{
PRTL_THREAD_START_ROUTINE entry;
void *arg;
void *relay;
HANDLE actctx;
};
......@@ -150,17 +149,38 @@ static void start_thread( TEB *teb )
RtlActivateActivationContext( 0, info->actctx, &cookie );
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,
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param, void *relay,
ULONG flags, SIZE_T stack_commit, SIZE_T stack_reserve,
CLIENT_ID *id )
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 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;
pthread_t pthread_id;
......@@ -172,6 +192,7 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
DWORD tid = 0;
int request_pipe[2];
SIZE_T extra_stack = PTHREAD_STACK_MIN;
CLIENT_ID client_id;
HANDLE actctx;
TEB *teb;
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)
{
*handle = wine_server_ptr_handle( result.create_thread.handle );
if (id)
{
id->UniqueProcess = ULongToHandle( result.create_thread.pid );
id->UniqueThread = ULongToHandle( result.create_thread.tid );
}
client_id.UniqueProcess = ULongToHandle( result.create_thread.pid );
client_id.UniqueThread = ULongToHandle( result.create_thread.tid );
if (attr_list) update_attr_list( attr_list, &client_id );
}
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] );
if (!access) access = THREAD_ALL_ACCESS;
SERVER_START_REQ( new_thread )
{
req->process = wine_server_obj_handle( process );
......@@ -249,14 +270,13 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
goto done;
}
teb->ClientId.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
teb->ClientId.UniqueThread = ULongToHandle( tid );
if (id) *id = teb->ClientId;
client_id.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
client_id.UniqueThread = ULongToHandle( tid );
teb->ClientId = client_id;
info = (struct startup_info *)(teb + 1);
info->entry = start;
info->arg = param;
info->relay = relay;
info->actctx = actctx;
teb->Tib.StackBase = stack.StackBase;
......@@ -286,11 +306,15 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
done:
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
if (!status) return STATUS_SUCCESS;
NtClose( *handle );
RtlReleaseActivationContext( actctx );
close( request_pipe[1] );
return status;
if (status)
{
NtClose( *handle );
RtlReleaseActivationContext( actctx );
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,
BOOL *suspend, unsigned int *cpus, BOOL *wow64,
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 abort_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;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 28
#define NTDLL_UNIXLIB_VERSION 29
struct unix_funcs
{
......@@ -50,6 +50,10 @@ struct unix_funcs
ULONG protect, ULONG sec_flags, HANDLE file );
NTSTATUS (WINAPI *NtCreateSemaphore)( HANDLE *handle, ACCESS_MASK access,
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,
const OBJECT_ATTRIBUTES *attr, TIMER_TYPE type );
TEB * (WINAPI *NtCurrentTeb)(void);
......@@ -166,10 +170,6 @@ struct unix_funcs
/* thread/process functions */
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 );
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 *abort_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 CHAR WINAPI RtlUpperChar(CHAR);
NTSYSAPI void WINAPI RtlUpperString(STRING *,const STRING *);
NTSYSAPI void WINAPI RtlUserThreadStart(PRTL_THREAD_START_ROUTINE,void*);
NTSYSAPI NTSTATUS WINAPI RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
NTSYSAPI BOOLEAN WINAPI RtlValidRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR,ULONG,SECURITY_INFORMATION);
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