From: Changping Yu Subject: [PATCH V3 1/2] kernel32/tests: Add tests for getting main thread id by, toolhelp. Message-Id: Date: Fri, 19 Jun 2020 15:04:26 +0800 From 5b7b54c0fb594900cefae3ec291af4a986ef7f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=99=E6=98=8C=E5=B9=B3?= Date: Fri, 19 Jun 2020 14:24:53 +0800 Subject: [PATCH V3 1/2] kernel32/tests: Add tests for getting main thread id by toolhelp. v3: clean code style v2: add more tests for other thread Some software incorrectly uses the way to get the main thread id. Coincidentally, the threads of wine and windows return differently. The list of threads returned by flipping can be consistent with windows. Signed-off-by: Changping Yu --- dlls/kernel32/tests/toolhelp.c | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/dlls/kernel32/tests/toolhelp.c b/dlls/kernel32/tests/toolhelp.c index 9250f8dc54..e054f13c2a 100644 --- a/dlls/kernel32/tests/toolhelp.c +++ b/dlls/kernel32/tests/toolhelp.c @@ -41,6 +41,8 @@ static BOOL (WINAPI *pThread32Next)(HANDLE, LPTHREADENTRY32); /* 1 minute should be more than enough */ #define WAIT_TIME (60 * 1000) +/* Specify the number of simultaneous threads to test */ +#define NUM_THREADS 4 static DWORD WINAPI sub_thread(void* pmt) { @@ -150,6 +152,75 @@ static void test_process(DWORD curr_pid, DWORD sub_pcs_pid) ok(!pProcess32First( hSnapshot, &pe ), "shouldn't return a process\n"); } +static DWORD WINAPI get_id_thread(void* curr_pid) +{ + HANDLE hSnapshot; + THREADENTRY32 te; + HANDLE ev, threads[NUM_THREADS]; + DWORD tid, first_tid = 0; + BOOL found = FALSE; + + ev = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(ev != NULL, "Cannot create event\n"); + + for (int i = 0; i < NUM_THREADS; i++) + threads[i] = CreateThread(NULL, 0, sub_thread, ev, 0, &tid); + + ok(threads != NULL, "Cannot create thread\n"); + + hSnapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + ok(hSnapshot != NULL, "Cannot create snapshot\n"); + + /* check that this current process is enumerated */ + te.dwSize = sizeof(te); + if (pThread32First(hSnapshot, &te)) + { + do + { + /* first matched thread id */ + if (te.th32OwnerProcessID == (DWORD)curr_pid) { + found = TRUE; + first_tid = te.th32ThreadID; + break; + } + } + while (pThread32Next(hSnapshot, &te)); + } + + ok(found, "couldn't find self and/or sub-process in process list"); + + CreateThread(NULL, 0, sub_thread, ev, 0, &tid); + + SetEvent(ev); + for (int i = 0; i < NUM_THREADS; i++) + CloseHandle(threads[i]); + CloseHandle(ev); + CloseHandle(hSnapshot); + + return first_tid; +} + +static void test_main_thread(DWORD curr_pid, DWORD main_tid) +{ + HANDLE thread; + DWORD tid, first_tid = 0; + int error; + + /* check that the main thread id is first one in this thread. */ + first_tid = get_id_thread((void *)curr_pid); + todo_wine + ok(first_tid == main_tid, "check main thread is error, main is %d, %d\n", main_tid, first_tid); + + /* check that the main thread id is first one in other thread. */ + thread = CreateThread(NULL, 0, get_id_thread, (void *)curr_pid, 0, &tid); + error = WaitForSingleObject(thread, 10000); + ok(error == WAIT_OBJECT_0, "Thread did not complete within timelimit\n"); + + ok(GetExitCodeThread(thread, &first_tid), "Could not retrieve ext code\n"); + todo_wine + ok(first_tid == main_tid, "check main thread is error, main is %d, %d\n", main_tid, first_tid); +} + static void test_thread(DWORD curr_pid, DWORD sub_pcs_pid) { HANDLE hSnapshot; @@ -339,6 +410,7 @@ START_TEST(toolhelp) test_process(pid, info.dwProcessId); test_thread(pid, info.dwProcessId); + test_main_thread(pid, GetCurrentThreadId()); test_module(pid, curr_expected_modules, ARRAY_SIZE(curr_expected_modules)); test_module(info.dwProcessId, sub_expected_modules, ARRAY_SIZE(sub_expected_modules)); -- 2.26.1.windows.1