diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 54425471fad..5a6809638ae 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -376,18 +376,7 @@ ULONG WINAPI RtlGetNtGlobalFlags(void) NTSTATUS WINAPI NtOpenThread( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, const CLIENT_ID *id ) { - NTSTATUS ret; - - SERVER_START_REQ( open_thread ) - { - req->tid = HandleToULong(id->UniqueThread); - req->access = access; - req->attributes = attr ? attr->Attributes : 0; - ret = wine_server_call( req ); - *handle = wine_server_ptr_handle( reply->handle ); - } - SERVER_END_REQ; - return ret; + return unix_funcs->NtOpenThread( handle, access, attr, id ); } @@ -397,18 +386,7 @@ NTSTATUS WINAPI NtOpenThread( HANDLE *handle, ACCESS_MASK access, */ NTSTATUS WINAPI NtSuspendThread( HANDLE handle, PULONG count ) { - NTSTATUS ret; - - SERVER_START_REQ( suspend_thread ) - { - req->handle = wine_server_obj_handle( handle ); - if (!(ret = wine_server_call( req ))) - { - if (count) *count = reply->count; - } - } - SERVER_END_REQ; - return ret; + return unix_funcs->NtSuspendThread( handle, count ); } @@ -418,18 +396,7 @@ NTSTATUS WINAPI NtSuspendThread( HANDLE handle, PULONG count ) */ NTSTATUS WINAPI NtResumeThread( HANDLE handle, PULONG count ) { - NTSTATUS ret; - - SERVER_START_REQ( resume_thread ) - { - req->handle = wine_server_obj_handle( handle ); - if (!(ret = wine_server_call( req ))) - { - if (count) *count = reply->count; - } - } - SERVER_END_REQ; - return ret; + return unix_funcs->NtResumeThread( handle, count ); } @@ -439,8 +406,7 @@ NTSTATUS WINAPI NtResumeThread( HANDLE handle, PULONG count ) */ NTSTATUS WINAPI NtAlertResumeThread( HANDLE handle, PULONG count ) { - FIXME( "stub: should alert thread %p\n", handle ); - return NtResumeThread( handle, count ); + return unix_funcs->NtAlertResumeThread( handle, count ); } @@ -450,8 +416,7 @@ NTSTATUS WINAPI NtAlertResumeThread( HANDLE handle, PULONG count ) */ NTSTATUS WINAPI NtAlertThread( HANDLE handle ) { - FIXME( "stub: %p\n", handle ); - return STATUS_NOT_IMPLEMENTED; + return unix_funcs->NtAlertThread( handle ); } @@ -461,22 +426,7 @@ NTSTATUS WINAPI NtAlertThread( HANDLE handle ) */ NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code ) { - NTSTATUS ret; - BOOL self = (handle == GetCurrentThread()); - - if (!self || exit_code) - { - SERVER_START_REQ( terminate_thread ) - { - req->handle = wine_server_obj_handle( handle ); - req->exit_code = exit_code; - ret = wine_server_call( req ); - self = !ret && reply->self; - } - SERVER_END_REQ; - } - if (self) unix_funcs->abort_thread( exit_code ); - return ret; + return unix_funcs->NtTerminateThread( handle, exit_code ); } @@ -486,23 +436,7 @@ NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code ) NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3 ) { - NTSTATUS ret; - SERVER_START_REQ( queue_apc ) - { - req->handle = wine_server_obj_handle( handle ); - if (func) - { - req->call.type = APC_USER; - req->call.user.user.func = wine_server_client_ptr( func ); - req->call.user.user.args[0] = arg1; - req->call.user.user.args[1] = arg2; - req->call.user.user.args[2] = arg3; - } - else req->call.type = APC_NONE; /* wake up only */ - ret = wine_server_call( req ); - } - SERVER_END_REQ; - return ret; + return unix_funcs->NtQueueApcThread( handle, func, arg1, arg2, arg3 ); } diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 34c2e8fdaf4..ac4bb2c31f5 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -983,6 +983,8 @@ static HMODULE load_ntdll(void) */ static struct unix_funcs unix_funcs = { + NtAlertResumeThread, + NtAlertThread, NtAllocateVirtualMemory, NtAreMappedFilesTheSame, NtCancelTimer, @@ -1010,6 +1012,7 @@ static struct unix_funcs unix_funcs = NtOpenMutant, NtOpenSection, NtOpenSemaphore, + NtOpenThread, NtOpenTimer, NtProtectVirtualMemory, NtPulseEvent, @@ -1019,6 +1022,7 @@ static struct unix_funcs unix_funcs = NtQuerySemaphore, NtQueryTimer, NtQueryVirtualMemory, + NtQueueApcThread, NtRaiseException, NtReadVirtualMemory, NtReleaseKeyedEvent, @@ -1026,11 +1030,14 @@ static struct unix_funcs unix_funcs = NtReleaseSemaphore, NtResetEvent, NtResetWriteWatch, + NtResumeThread, NtSetContextThread, NtSetEvent, NtSetLdtEntries, NtSetTimer, NtSignalAndWaitForSingleObject, + NtSuspendThread, + NtTerminateThread, NtUnlockVirtualMemory, NtUnmapViewOfSection, NtWaitForKeyedEvent, @@ -1062,7 +1069,6 @@ static struct unix_funcs unix_funcs = virtual_release_address_space, virtual_set_large_address_space, init_threading, - abort_thread, exit_thread, exit_process, get_thread_ldt_entry, diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 9e7a15e5dca..97b191e1a5b 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -323,7 +323,7 @@ done: /*********************************************************************** * abort_thread */ -void CDECL abort_thread( int status ) +void abort_thread( int status ) { pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); if (InterlockedDecrement( nb_threads ) <= 0) _exit( get_unix_exit_code( status )); @@ -461,6 +461,111 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL } +/*********************************************************************** + * NtOpenThread (NTDLL.@) + */ +NTSTATUS WINAPI NtOpenThread( HANDLE *handle, ACCESS_MASK access, + const OBJECT_ATTRIBUTES *attr, const CLIENT_ID *id ) +{ + NTSTATUS ret; + + SERVER_START_REQ( open_thread ) + { + req->tid = HandleToULong(id->UniqueThread); + req->access = access; + req->attributes = attr ? attr->Attributes : 0; + ret = wine_server_call( req ); + *handle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * NtSuspendThread (NTDLL.@) + */ +NTSTATUS WINAPI NtSuspendThread( HANDLE handle, ULONG *count ) +{ + NTSTATUS ret; + + SERVER_START_REQ( suspend_thread ) + { + req->handle = wine_server_obj_handle( handle ); + if (!(ret = wine_server_call( req ))) + { + if (count) *count = reply->count; + } + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * NtResumeThread (NTDLL.@) + */ +NTSTATUS WINAPI NtResumeThread( HANDLE handle, ULONG *count ) +{ + NTSTATUS ret; + + SERVER_START_REQ( resume_thread ) + { + req->handle = wine_server_obj_handle( handle ); + if (!(ret = wine_server_call( req ))) + { + if (count) *count = reply->count; + } + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * NtAlertResumeThread (NTDLL.@) + */ +NTSTATUS WINAPI NtAlertResumeThread( HANDLE handle, ULONG *count ) +{ + FIXME( "stub: should alert thread %p\n", handle ); + return NtResumeThread( handle, count ); +} + + +/****************************************************************************** + * NtAlertThread (NTDLL.@) + */ +NTSTATUS WINAPI NtAlertThread( HANDLE handle ) +{ + FIXME( "stub: %p\n", handle ); + return STATUS_NOT_IMPLEMENTED; +} + + +/****************************************************************************** + * NtTerminateThread (NTDLL.@) + */ +NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code ) +{ + NTSTATUS ret; + BOOL self = (handle == GetCurrentThread()); + + if (!self || exit_code) + { + SERVER_START_REQ( terminate_thread ) + { + req->handle = wine_server_obj_handle( handle ); + req->exit_code = exit_code; + ret = wine_server_call( req ); + self = !ret && reply->self; + } + SERVER_END_REQ; + } + if (self) abort_thread( exit_code ); + return ret; +} + + /*********************************************************************** * NtContinue (NTDLL.@) */ @@ -473,6 +578,33 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable ) } +/****************************************************************************** + * NtQueueApcThread (NTDLL.@) + */ +NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1, + ULONG_PTR arg2, ULONG_PTR arg3 ) +{ + NTSTATUS ret; + + SERVER_START_REQ( queue_apc ) + { + req->handle = wine_server_obj_handle( handle ); + if (func) + { + req->call.type = APC_USER; + req->call.user.user.func = wine_server_client_ptr( func ); + req->call.user.user.args[0] = arg1; + req->call.user.user.args[1] = arg2; + req->call.user.user.args[2] = arg3; + } + else req->call.type = APC_NONE; /* wake up only */ + ret = wine_server_call( req ); + } + SERVER_END_REQ; + return ret; +} + + /*********************************************************************** * set_thread_context */ diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index b8f7ddc8f32..b43af7809c9 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -96,7 +96,6 @@ extern void CDECL server_init_process_done( void *relay ) 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 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_process( int status ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_len ) DECLSPEC_HIDDEN; @@ -122,6 +121,7 @@ extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN; extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) DECLSPEC_HIDDEN; extern NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN; +extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN; extern void wait_suspend( CONTEXT *context ) DECLSPEC_HIDDEN; extern NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) DECLSPEC_HIDDEN; extern NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self ) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h index ffc4373ee21..b6a8d270d61 100644 --- a/dlls/ntdll/unixlib.h +++ b/dlls/ntdll/unixlib.h @@ -28,11 +28,13 @@ struct ldt_copy; struct msghdr; /* increment this when you change the function table */ -#define NTDLL_UNIXLIB_VERSION 33 +#define NTDLL_UNIXLIB_VERSION 34 struct unix_funcs { /* Nt* functions */ + NTSTATUS (WINAPI *NtAlertResumeThread)( HANDLE handle, ULONG *count ); + NTSTATUS (WINAPI *NtAlertThread)( HANDLE handle ); NTSTATUS (WINAPI *NtAllocateVirtualMemory)( HANDLE process, PVOID *ret, ULONG_PTR zero_bits, SIZE_T *size_ptr, ULONG type, ULONG protect ); NTSTATUS (WINAPI *NtAreMappedFilesTheSame)(PVOID addr1, PVOID addr2); @@ -84,6 +86,7 @@ struct unix_funcs const OBJECT_ATTRIBUTES *attr ); NTSTATUS (WINAPI *NtOpenSemaphore)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ); + NTSTATUS (WINAPI *NtOpenThread)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, const CLIENT_ID *id ); NTSTATUS (WINAPI *NtOpenTimer)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ); NTSTATUS (WINAPI *NtProtectVirtualMemory)( HANDLE process, PVOID *addr_ptr, SIZE_T *size_ptr, @@ -102,6 +105,8 @@ struct unix_funcs NTSTATUS (WINAPI *NtQueryVirtualMemory)( HANDLE process, LPCVOID addr, MEMORY_INFORMATION_CLASS info_class, PVOID buffer, SIZE_T len, SIZE_T *res_len ); + NTSTATUS (WINAPI *NtQueueApcThread)( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1, + ULONG_PTR arg2, ULONG_PTR arg3 ); NTSTATUS (WINAPI *NtRaiseException)( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ); NTSTATUS (WINAPI *NtReadVirtualMemory)( HANDLE process, const void *addr, void *buffer, SIZE_T size, SIZE_T *bytes_read ); @@ -111,6 +116,7 @@ struct unix_funcs NTSTATUS (WINAPI *NtReleaseSemaphore)( HANDLE handle, ULONG count, ULONG *previous ); NTSTATUS (WINAPI *NtResetEvent)( HANDLE handle, LONG *prev_state ); NTSTATUS (WINAPI *NtResetWriteWatch)( HANDLE process, PVOID base, SIZE_T size ); + NTSTATUS (WINAPI *NtResumeThread)( HANDLE handle, ULONG *count ); NTSTATUS (WINAPI *NtSetContextThread)( HANDLE handle, const CONTEXT *context ); NTSTATUS (WINAPI *NtSetEvent)( HANDLE handle, LONG *prev_state ); NTSTATUS (WINAPI *NtSetLdtEntries)( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2 ); @@ -119,6 +125,8 @@ struct unix_funcs BOOLEAN resume, ULONG period, BOOLEAN *state ); NTSTATUS (WINAPI *NtSignalAndWaitForSingleObject)( HANDLE signal, HANDLE wait, BOOLEAN alertable, const LARGE_INTEGER *timeout ); + NTSTATUS (WINAPI *NtSuspendThread)( HANDLE handle, ULONG *count ); + NTSTATUS (WINAPI *NtTerminateThread)( HANDLE handle, LONG exit_code ); NTSTATUS (WINAPI *NtUnlockVirtualMemory)( HANDLE process, PVOID *addr, SIZE_T *size, ULONG unknown ); NTSTATUS (WINAPI *NtUnmapViewOfSection)( HANDLE process, PVOID addr ); @@ -170,7 +178,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 ); - void (CDECL *abort_thread)( int status ); void (CDECL *exit_thread)( int status ); void (CDECL *exit_process)( int status ); NTSTATUS (CDECL *get_thread_ldt_entry)( HANDLE handle, void *data, ULONG len, ULONG *ret_len );