kernel32/tests: Add additional Get/SetThreadDescription() tests.

Signed-off-by: Brendan Shanks <bshanks@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Brendan Shanks 2022-03-03 11:50:55 -08:00 committed by Alexandre Julliard
parent 42c8860b23
commit a9a294d286
1 changed files with 95 additions and 0 deletions

View File

@ -100,6 +100,8 @@ static BOOL (WINAPI *pSetThreadGroupAffinity)(HANDLE,const GROUP_AFFINITY*,GROUP
static NTSTATUS (WINAPI *pNtSetInformationThread)(HANDLE,THREADINFOCLASS,LPCVOID,ULONG);
static HRESULT (WINAPI *pSetThreadDescription)(HANDLE,const WCHAR *);
static HRESULT (WINAPI *pGetThreadDescription)(HANDLE,WCHAR **);
static PVOID (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG,PVECTORED_EXCEPTION_HANDLER);
static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID);
static HANDLE create_target_process(const char *arg)
{
@ -2351,6 +2353,23 @@ static void test_thread_info(void)
CloseHandle(thread);
}
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; /* Must be 0x1000. */
LPCSTR szName; /* Pointer to name (in user addr space). */
DWORD dwThreadID; /* Thread ID (-1 = caller thread). */
DWORD dwFlags; /* Reserved for future use, must be zero. */
} THREADNAME_INFO;
static LONG CALLBACK msvc_threadname_vec_handler(EXCEPTION_POINTERS *ExceptionInfo)
{
if (ExceptionInfo->ExceptionRecord != NULL &&
ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_WINE_NAME_THREAD)
return EXCEPTION_CONTINUE_EXECUTION;
return EXCEPTION_CONTINUE_SEARCH;
}
static void test_thread_description(void)
{
THREAD_NAME_INFORMATION *thread_desc;
@ -2360,6 +2379,9 @@ static void test_thread_description(void)
char buff[128];
WCHAR *ptr;
HRESULT hr;
HANDLE thread;
PVOID vectored_handler;
THREADNAME_INFO info;
if (!pGetThreadDescription)
{
@ -2463,6 +2485,24 @@ static void test_thread_description(void)
ok(!lstrcmpW(ptr, L""), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
LocalFree(ptr);
/* Set with a string from RtlInitUnicodeString. */
hr = pSetThreadDescription(GetCurrentThread(), L"123");
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#x.\n", hr);
lstrcpyW((WCHAR *)(thread_desc + 1), L"desc");
RtlInitUnicodeString(&thread_desc->ThreadName, (WCHAR *)(thread_desc + 1));
status = pNtSetInformationThread(GetCurrentThread(), ThreadNameInformation, thread_desc, sizeof(*thread_desc));
todo_wine
ok(status == STATUS_SUCCESS, "Failed to set thread description, status %#x.\n", status);
ptr = NULL;
hr = pGetThreadDescription(GetCurrentThread(), &ptr);
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#x.\n", hr);
todo_wine
ok(!lstrcmpW(ptr, L"desc"), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
LocalFree(ptr);
/* Set with 0 length/NULL pointer. */
hr = pSetThreadDescription(GetCurrentThread(), L"123");
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#x.\n", hr);
@ -2476,6 +2516,59 @@ static void test_thread_description(void)
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#x.\n", hr);
ok(!lstrcmpW(ptr, L""), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
LocalFree(ptr);
/* Get with only THREAD_QUERY_LIMITED_INFORMATION access. */
thread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, GetCurrentThreadId());
ptr = NULL;
hr = pGetThreadDescription(thread, &ptr);
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#x.\n", hr);
ok(!lstrcmpW(ptr, L""), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
LocalFree(ptr);
len = 0;
status = pNtQueryInformationThread(thread, ThreadNameInformation, NULL, 0, &len);
ok(status == STATUS_BUFFER_TOO_SMALL, "Unexpected status %#x.\n", status);
ok(len == sizeof(*thread_desc), "Unexpected structure length %u.\n", len);
CloseHandle(thread);
/* Set with only THREAD_SET_LIMITED_INFORMATION access. */
thread = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, GetCurrentThreadId());
hr = pSetThreadDescription(thread, desc);
todo_wine
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#x.\n", hr);
ptr = NULL;
hr = pGetThreadDescription(GetCurrentThread(), &ptr);
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#x.\n", hr);
todo_wine
ok(!lstrcmpW(ptr, desc), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
LocalFree(ptr);
CloseHandle(thread);
/* The old exception-based thread name method should not affect GetThreadDescription. */
hr = pSetThreadDescription(GetCurrentThread(), desc);
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#x.\n", hr);
vectored_handler = pRtlAddVectoredExceptionHandler(FALSE, &msvc_threadname_vec_handler);
ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n");
info.dwType = 0x1000;
info.szName = "123";
info.dwThreadID = -1;
info.dwFlags = 0;
RaiseException(EXCEPTION_WINE_NAME_THREAD, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
pRtlRemoveVectoredExceptionHandler(vectored_handler);
ptr = NULL;
hr = pGetThreadDescription(GetCurrentThread(), &ptr);
ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#x.\n", hr);
ok(!lstrcmpW(ptr, desc), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
LocalFree(ptr);
}
static void init_funcs(void)
@ -2524,6 +2617,8 @@ static void init_funcs(void)
X(NtQueryInformationThread);
X(RtlGetThreadErrorMode);
X(NtSetInformationThread);
X(RtlAddVectoredExceptionHandler);
X(RtlRemoveVectoredExceptionHandler);
}
#undef X
}