From: Brendan Shanks bshanks@codeweavers.com
--- include/winternl.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/winternl.h b/include/winternl.h index c64ff0f9082..26e61463f35 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1894,7 +1894,10 @@ typedef enum _THREADINFOCLASS { ThreadManageWritesToExecutableMemory, ThreadPowerThrottlingState, ThreadWorkloadClass, - MaxThreadInfoClass + MaxThreadInfoClass, +#ifdef __WINESRC__ + ThreadWineNativeThreadName = 1000, +#endif } THREADINFOCLASS;
typedef struct _THREAD_BASIC_INFORMATION
From: Brendan Shanks bshanks@codeweavers.com
--- dlls/ntdll/ntdll_misc.h | 45 ++++++++++++++++++++++++++++++++++++++ dlls/ntdll/signal_arm.c | 2 ++ dlls/ntdll/signal_arm64.c | 2 ++ dlls/ntdll/signal_i386.c | 2 ++ dlls/ntdll/signal_x86_64.c | 2 ++ dlls/ntdll/unix/thread.c | 13 +++++++++++ 6 files changed, 66 insertions(+)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index d55083ae34c..20cc057c0c0 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -20,6 +20,7 @@ #define __WINE_NTDLL_MISC_H
#include <stdarg.h> +#include <stdlib.h> #include <sys/types.h>
#include "windef.h" @@ -125,4 +126,48 @@ static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len ) /* FLS data */ extern TEB_FLS_DATA *fls_alloc_data(void) DECLSPEC_HIDDEN;
+static inline void set_native_thread_name(DWORD tid, const char *name) +{ + THREAD_NAME_INFORMATION info; + HANDLE h = GetCurrentThread(); + NTSTATUS status; + WCHAR nameW[64]; + + if (tid != -1) + { + OBJECT_ATTRIBUTES attr; + CLIENT_ID cid; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.Attributes = 0; + attr.ObjectName = NULL; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + cid.UniqueProcess = 0; + cid.UniqueThread = ULongToHandle( tid ); + + status = NtOpenThread( &h, THREAD_QUERY_LIMITED_INFORMATION, &attr, &cid ); + if (status) + return; + } + + if (name) + { + mbstowcs( nameW, name, ARRAY_SIZE(nameW) ); + nameW[ARRAY_SIZE(nameW) - 1] = '\0'; + } + else + { + nameW[0] = '\0'; + } + + RtlInitUnicodeString( &info.ThreadName, nameW ); + NtSetInformationThread( h, ThreadWineNativeThreadName, &info, sizeof(info) ); + + if (h != GetCurrentThread()) + NtClose(h); +} + #endif diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index c3674487277..d59d9ce1382 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -482,6 +482,8 @@ NTSTATUS WINAPI KiUserExceptionDispatcher( EXCEPTION_RECORD *rec, CONTEXT *conte else WARN_(threadname)( "Thread ID %04x renamed to %s\n", (DWORD)rec->ExceptionInformation[2], debugstr_a((char *)rec->ExceptionInformation[1]) ); + + set_native_thread_name((DWORD)rec->ExceptionInformation[2], (char *)rec->ExceptionInformation[1]); } else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) { diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index ee3204ebce8..cc5b6842995 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -514,6 +514,8 @@ NTSTATUS WINAPI KiUserExceptionDispatcher( EXCEPTION_RECORD *rec, CONTEXT *conte else WARN_(threadname)( "Thread ID %04x renamed to %s\n", (DWORD)rec->ExceptionInformation[2], debugstr_a((char *)rec->ExceptionInformation[1]) ); + + set_native_thread_name((DWORD)rec->ExceptionInformation[2], (char *)rec->ExceptionInformation[1]); } else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) { diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index acb3937efa8..c8e1b495ac0 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -200,6 +200,8 @@ NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context ) else WARN_(threadname)( "Thread ID %04x renamed to %s\n", (DWORD)rec->ExceptionInformation[2], debugstr_a((char *)rec->ExceptionInformation[1]) ); + + set_native_thread_name((DWORD)rec->ExceptionInformation[2], (char *)rec->ExceptionInformation[1]); } else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) { diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index b1ab4933b93..b6fb0a2ff1f 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -531,6 +531,8 @@ NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context ) else WARN_(threadname)( "Thread ID %04x renamed to %s\n", (DWORD)rec->ExceptionInformation[2], debugstr_a((char *)rec->ExceptionInformation[1]) ); + + set_native_thread_name((DWORD)rec->ExceptionInformation[2], (char *)rec->ExceptionInformation[1]); } else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) { diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 3a737044407..21c59e0ab25 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2303,6 +2303,19 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, return status; }
+ case ThreadWineNativeThreadName: + { + const THREAD_NAME_INFORMATION *info = data; + + if (length != sizeof(*info)) return STATUS_INFO_LENGTH_MISMATCH; + if (!info) return STATUS_ACCESS_VIOLATION; + if (info->ThreadName.Length && !info->ThreadName.Buffer) return STATUS_ACCESS_VIOLATION; + + set_native_thread_name( handle, &info->ThreadName ); + + return STATUS_SUCCESS; + } + case ThreadWow64Context: return set_thread_wow64_context( handle, data, length );