From: Roger Zoellner Subject: [PATCH] ntdll/tests: Add basic tests for NtSetInformationThread(), class ThreadAffinityMask Message-Id: <20180909181601.22990-1-zoellner.roger@gmail.com> Date: Sun, 9 Sep 2018 20:16:01 +0200 Related to https://source.winehq.org/patches/data/150818 --- dlls/ntdll/tests/Makefile.in | 1 + dlls/ntdll/tests/thread.c | 83 ++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 dlls/ntdll/tests/thread.c diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in index 5c70f3f01a..26b7f8cd09 100644 --- a/dlls/ntdll/tests/Makefile.in +++ b/dlls/ntdll/tests/Makefile.in @@ -22,4 +22,5 @@ C_SRCS = \ rtlstr.c \ string.c \ threadpool.c \ + thread.c \ time.c diff --git a/dlls/ntdll/tests/thread.c b/dlls/ntdll/tests/thread.c new file mode 100644 index 0000000000..740d64fff5 --- /dev/null +++ b/dlls/ntdll/tests/thread.c @@ -0,0 +1,83 @@ +/* + * Unit test suite for ntdll thread functions + * + * Copyright 2018 Roger Zoellner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "ntdll_test.h" + +static NTSTATUS (WINAPI *pNtSetInformationThread)(HANDLE handle, THREADINFOCLASS class, LPCVOID data, ULONG length); + +static DWORD WINAPI thread_main(LPVOID lpParam) +{ + /* Thread is created with CREATE_SUSPENDED flag set and isn't doing anything */ +} + +static void test_NtSetInformationThread(HANDLE thread) +{ + /* class ThreadAffinityMask */ + THREADINFOCLASS class = ThreadAffinityMask; + DWORD_PTR req_aff; + ULONG req_aff_length = sizeof(req_aff); + NTSTATUS status; + + HANDLE process = GetCurrentProcess(); + DWORD_PTR system_aff; + DWORD_PTR process_aff; + BOOL success = GetProcessAffinityMask(process, &process_aff, &system_aff); + ok(success == TRUE, "GetProcessAffinityMask failed. Expected TRUE, got FALSE\n"); + + if (success == FALSE) return; + + /* Test required affinity mask, no bits set */ + req_aff = 0; + status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length); + ok(status == STATUS_INVALID_PARAMETER, "NtSetInformationThread failed. Expected STATUS_INVALID_PARAMETER, got %08x (class=ThreadAffinityMask, case 1, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff); + + /* Test required affinity mask, all bits set */ + req_aff = ~0u; + status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length); + ok(status == STATUS_SUCCESS, "NtSetInformationThread failed. Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 2, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff); + + /* Test required affinity mask = process affinity mask */ + req_aff = process_aff; + status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length); + ok(status == STATUS_SUCCESS, "NtSetInformationThread failed. Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 3, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff); + + /* Test required affinity mask = process affinity mask with a prepended bit set */ + req_aff = (process_aff << 1) | process_aff; + status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length); + ok(status == STATUS_SUCCESS, "NtSetInformationThread failed. Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 4, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff); +} + +START_TEST(thread) +{ + HMODULE mod = GetModuleHandleA("ntdll.dll"); + pNtSetInformationThread = (void *) GetProcAddress(mod ,"NtSetInformationThread"); + HANDLE thread; + + thread = CreateThread(NULL, 0, thread_main, NULL, CREATE_SUSPENDED, NULL); + ok(thread != NULL, "dlls/ntdll/tests/: Could not create new thread\n"); + + if (thread != NULL) + { + test_NtSetInformationThread(thread); + TerminateThread(thread, 0); + CloseHandle(thread); + } +} + -- 2.18.0