From 94c6132d79ee02079fc952e33cccf0d1f456a1ec Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Mon, 31 Aug 2020 23:00:16 -0500 Subject: [PATCH] ntdll: Implement NtAlertThreadByThreadId() and NtWaitForAlertByThreadId(). Signed-off-by: Zebediah Figura --- dlls/ntdll/ntdll.spec | 2 ++ dlls/ntdll/unix/sync.c | 45 ++++++++++++++++++++++++++++++++++ dlls/ntdll/unix/thread.c | 2 ++ dlls/ntdll/unix/unix_private.h | 3 +++ dlls/ntdll/unix/virtual.c | 5 ++-- include/winternl.h | 2 ++ 6 files changed, 57 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index ac7365a84b6..91959e19149 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -137,6 +137,7 @@ @ stdcall -syscall NtAdjustPrivilegesToken(long long ptr long ptr ptr) @ stdcall -syscall NtAlertResumeThread(long ptr) @ stdcall -syscall NtAlertThread(long) +@ stdcall -syscall NtAlertThreadByThreadId(ptr) @ stdcall -syscall NtAllocateLocallyUniqueId(ptr) # @ stub NtAllocateUserPhysicalPages @ stdcall -syscall NtAllocateUuids(ptr ptr ptr ptr) @@ -423,6 +424,7 @@ @ stub NtVdmControl @ stub NtW32Call @ stdcall -syscall NtWaitForDebugEvent(long long ptr ptr) +@ stdcall -syscall NtWaitForAlertByThreadId(ptr ptr) @ stdcall -syscall NtWaitForKeyedEvent(long ptr long ptr) @ stdcall -syscall NtWaitForMultipleObjects(long ptr long long ptr) @ stub NtWaitForProcessMutant diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 16635ee42fa..7e19fab1e97 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -81,6 +81,12 @@ static const LARGE_INTEGER zero_timeout; static pthread_mutex_t addr_mutex = PTHREAD_MUTEX_INITIALIZER; +static const char *debugstr_timeout( const LARGE_INTEGER *timeout ) +{ + if (!timeout) return "(infinite)"; + return wine_dbgstr_longlong( timeout->QuadPart ); +} + /* return a monotonic time counter, in Win32 ticks */ static inline ULONGLONG monotonic_counter(void) { @@ -2277,6 +2283,45 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl } +/*********************************************************************** + * NtAlertThreadByThreadId (NTDLL.@) + */ +NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid ) +{ + struct ntdll_thread_data *thread_data; + + TRACE( "%p\n", tid ); + + pthread_rwlock_rdlock( &teb_list_lock ); + + LIST_FOR_EACH_ENTRY( thread_data, &teb_list, struct ntdll_thread_data, entry ) + { + TEB *teb = CONTAINING_RECORD( thread_data, TEB, GdiTebBatch ); + + if (teb->ClientId.UniqueThread == tid) + { + pthread_rwlock_unlock( &teb_list_lock ); + NtSetEvent( thread_data->tid_alert_event, NULL ); + return STATUS_SUCCESS; + } + } + + pthread_rwlock_unlock( &teb_list_lock ); + return STATUS_INVALID_CID; +} + + +/*********************************************************************** + * NtWaitForAlertByThreadId (NTDLL.@) + */ +NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout ) +{ + TRACE( "%p %s\n", address, debugstr_timeout( timeout ) ); + + return NtWaitForSingleObject( ntdll_get_thread_data()->tid_alert_event, FALSE, timeout ); +} + + #ifdef __linux__ NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 00d29ae706b..87f5a97131e 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -252,6 +252,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT thread_data->start = start; thread_data->param = param; + NtCreateEvent( &thread_data->tid_alert_event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE ); + pthread_attr_init( &pthread_attr ); pthread_attr_setstack( &pthread_attr, teb->DeallocationStack, (char *)teb->Tib.StackBase + extra_stack - (char *)teb->DeallocationStack ); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index b8b6619c0a9..ae178fadd8b 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -58,6 +58,7 @@ struct ntdll_thread_data struct list entry; /* entry in TEB list */ PRTL_THREAD_START_ROUTINE start; /* thread entry point */ void *param; /* thread entry point parameter */ + HANDLE tid_alert_event; /* event for thread-id alerts */ }; C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) ); @@ -105,6 +106,8 @@ extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN; extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch, CONTEXT *context ) DECLSPEC_HIDDEN; +extern struct list teb_list DECLSPEC_HIDDEN; +extern pthread_rwlock_t teb_list_lock DECLSPEC_HIDDEN; extern const char *home_dir DECLSPEC_HIDDEN; extern const char *data_dir DECLSPEC_HIDDEN; extern const char *build_dir DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index d1d00b91345..3e3c9b5f00e 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -162,8 +162,9 @@ struct _KUSER_SHARED_DATA *user_shared_data = (void *)0x7ffe0000; static void *teb_block; static void **next_free_teb; static int teb_block_pos; -static struct list teb_list = LIST_INIT( teb_list ); -static pthread_rwlock_t teb_list_lock = PTHREAD_RWLOCK_INITIALIZER; + +struct list teb_list = LIST_INIT( teb_list ); +pthread_rwlock_t teb_list_lock = PTHREAD_RWLOCK_INITIALIZER; #define ROUND_ADDR(addr,mask) ((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask))) #define ROUND_SIZE(addr,size) (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask) diff --git a/include/winternl.h b/include/winternl.h index f0ab223ef2e..9a5a1b541b7 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -3229,6 +3229,7 @@ NTSYSAPI NTSTATUS WINAPI NtAdjustGroupsToken(HANDLE,BOOLEAN,PTOKEN_GROUPS,ULONG NTSYSAPI NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD); NTSYSAPI NTSTATUS WINAPI NtAlertResumeThread(HANDLE,PULONG); NTSYSAPI NTSTATUS WINAPI NtAlertThread(HANDLE ThreadHandle); +NTSYSAPI NTSTATUS WINAPI NtAlertThreadByThreadId(HANDLE); NTSYSAPI NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID lpLuid); NTSYSAPI NTSTATUS WINAPI NtAllocateUuids(PULARGE_INTEGER,PULONG,PULONG,PUCHAR); NTSYSAPI NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,ULONG_PTR,SIZE_T*,ULONG,ULONG); @@ -3467,6 +3468,7 @@ NTSYSAPI NTSTATUS WINAPI NtUnlockVirtualMemory(HANDLE,PVOID*,SIZE_T*,ULONG); NTSYSAPI NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID); NTSYSAPI NTSTATUS WINAPI NtVdmControl(ULONG,PVOID); NTSYSAPI NTSTATUS WINAPI NtWaitForDebugEvent(HANDLE,BOOLEAN,LARGE_INTEGER*,DBGUI_WAIT_STATE_CHANGE*); +NTSYSAPI NTSTATUS WINAPI NtWaitForAlertByThreadId(const void*,const LARGE_INTEGER*); NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE,const void*,BOOLEAN,const LARGE_INTEGER*); NTSYSAPI NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,const LARGE_INTEGER*); NTSYSAPI NTSTATUS WINAPI NtWaitForMultipleObjects(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*); -- 2.20.1