ReactOS 0.4.17-dev-37-g0bfb40d
thread.c
Go to the documentation of this file.
1/*
2 * Unit test suite for ntdll thread functions
3 *
4 * Copyright 2021 Paul Gofman for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 */
21
22#include <stdarg.h>
23
24#include "ntstatus.h"
25#define WIN32_NO_STATUS
26#include "windef.h"
27#include "winbase.h"
28#include "winternl.h"
29#include "wine/test.h"
30
31static NTSTATUS (WINAPI *pNtCreateThreadEx)( HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *,
34static int * (CDECL *p_errno)(void);
35
36static void init_function_pointers(void)
37{
38 HMODULE hntdll = GetModuleHandleA( "ntdll.dll" );
39#define GET_FUNC(name) p##name = (void *)GetProcAddress( hntdll, #name );
42#undef GET_FUNC
43}
44
46{
47}
48
50{
52 PS_CREATE_INFO create_info;
53 PS_ATTRIBUTE_LIST ps_attr;
54 WCHAR path[MAX_PATH + 4];
56 UNICODE_STRING imageW;
57 BOOLEAN dbg_hidden;
59
60 if (!pNtCreateThreadEx)
61 {
62 win_skip( "NtCreateThreadEx is not available.\n" );
63 return;
64 }
65
68 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
69
70 dbg_hidden = 0xcc;
71 status = NtQueryInformationThread( thread, ThreadHideFromDebugger, &dbg_hidden, sizeof(dbg_hidden), NULL );
72 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
73 ok( !dbg_hidden, "Got unexpected dbg_hidden %#x.\n", dbg_hidden );
74
76 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
79
82 0, 0, 0, NULL );
83 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
84
85 dbg_hidden = 0xcc;
86 status = NtQueryInformationThread( thread, ThreadHideFromDebugger, &dbg_hidden, sizeof(dbg_hidden), NULL );
87 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
88 ok( dbg_hidden == 1, "Got unexpected dbg_hidden %#x.\n", dbg_hidden );
89
91 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
94
95 lstrcpyW( path, L"\\??\\" );
97
98 RtlInitUnicodeString( &imageW, path );
99
100 memset( &ps_attr, 0, sizeof(ps_attr) );
102 ps_attr.Attributes[0].Size = lstrlenW(path) * sizeof(WCHAR);
103 ps_attr.Attributes[0].ValuePtr = path;
104 ps_attr.TotalLength = sizeof(ps_attr);
105
106#if !defined (__REACTOS__) || (DLL_EXPORT_VERSION >= 0x601)
108 NULL, NULL, NULL, NULL,
110 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
111
112 /* NtCreateUserProcess() may return STATUS_INVALID_PARAMETER with some uninitialized data in create_info. */
113 memset( &create_info, 0, sizeof(create_info) );
114 create_info.Size = sizeof(create_info);
115
119 &create_info, &ps_attr );
120 ok( status == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", status );
123 &create_info, &ps_attr );
124 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
126 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
129#endif
130}
131
133{
137};
138
140{
142 args->teb = NtCurrentTeb();
143 SetEvent( args->running_event );
144 WaitForSingleObject( args->quit_event, INFINITE );
145}
146
147static void test_unique_teb(void)
148{
149 HANDLE threads[2], running_events[2];
150 struct unique_teb_thread_args args1, args2;
152
153 if (!pNtCreateThreadEx)
154 {
155 win_skip( "NtCreateThreadEx is not available.\n" );
156 return;
157 }
158
159 args1.running_event = running_events[0] = CreateEventW( NULL, FALSE, FALSE, NULL );
160 ok( args1.running_event != NULL, "CreateEventW failed %lu.\n", GetLastError() );
161
162 args2.running_event = running_events[1] = CreateEventW( NULL, FALSE, FALSE, NULL );
163 ok( args2.running_event != NULL, "CreateEventW failed %lu.\n", GetLastError() );
164
165 args1.quit_event = args2.quit_event = CreateEventW( NULL, TRUE, FALSE, NULL );
166 ok( args1.quit_event != NULL, "CreateEventW failed %lu.\n", GetLastError() );
167
169 &args1, 0, 0, 0, 0, NULL );
170 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
171
173 &args2, 0, 0, 0, 0, NULL );
174 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
175
176 WaitForMultipleObjects( 2, running_events, TRUE, INFINITE );
177 SetEvent( args1.quit_event );
178
180 CloseHandle( threads[0] );
181 CloseHandle( threads[1] );
182 CloseHandle( args1.running_event );
183 CloseHandle( args2.running_event );
184 CloseHandle( args1.quit_event );
185
186 ok( NtCurrentTeb() != args1.teb, "Multiple threads have TEB %p.\n", args1.teb );
187 ok( NtCurrentTeb() != args2.teb, "Multiple threads have TEB %p.\n", args2.teb );
188 ok( args1.teb != args2.teb, "Multiple threads have TEB %p.\n", args1.teb );
189}
190
191static void test_errno(void)
192{
193 int val;
194
195 if (!p_errno)
196 {
197 win_skip( "_errno not available\n" );
198 return;
199 }
200 ok( NtCurrentTeb()->Peb->TlsBitmap->Buffer[0] & (1 << 16), "TLS entry 16 not allocated\n" );
201 *p_errno() = 0xdead;
202 val = PtrToLong( TlsGetValue( 16 ));
203 ok( val == 0xdead, "wrong value %x\n", val );
204 *p_errno() = 0xbeef;
205 val = PtrToLong( TlsGetValue( 16 ));
206 ok( val == 0xbeef, "wrong value %x\n", val );
207}
208
210{
212
215 test_errno();
216}
unsigned char BOOLEAN
Definition: actypes.h:127
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE thread
Definition: service.c:33
#define PtrToLong(p)
Definition: basetsd.h:78
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:19
#define CDECL
Definition: compat.h:29
#define CloseHandle
Definition: compat.h:739
@ ThreadHideFromDebugger
Definition: compat.h:952
#define GetCurrentProcess()
Definition: compat.h:759
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
PPEB Peb
Definition: dllmain.c:27
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1240
int *CDECL _errno(void)
Definition: errno.c:215
#define L(x)
Definition: resources.c:13
#define INFINITE
Definition: serial.h:102
#define ULONG_PTR
Definition: config.h:101
GLenum const GLfloat * params
Definition: glext.h:5645
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat param
Definition: glext.h:5796
#define NtCurrentTeb
#define win_skip
Definition: minitest.h:67
static HANDLE ULONG_PTR DWORD threads
Definition: process.c:83
static HINSTANCE hntdll
Definition: process.c:68
static HANDLE
Definition: thread.c:84
static ULONG
Definition: thread.c:81
static void CALLBACK test_unique_teb_proc(void *param)
Definition: thread.c:139
static ACCESS_MASK
Definition: thread.c:31
static void test_errno(void)
Definition: thread.c:191
static void init_function_pointers(void)
Definition: thread.c:36
static void CALLBACK test_NtCreateThreadEx_proc(void *param)
Definition: thread.c:45
static void test_unique_teb(void)
Definition: thread.c:147
static void test_dbg_hidden_thread_creation(void)
Definition: thread.c:49
static OBJECT_ATTRIBUTES void PS_ATTRIBUTE_LIST *static int *CDECL * p_errno(void)
#define GET_FUNC(name)
static OBJECT_ATTRIBUTES void SIZE_T
Definition: thread.c:33
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1327
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
NTSTATUS NTAPI NtQueryInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_writes_bytes_to_opt_(ThreadInformationLength, *ReturnLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:2985
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
short WCHAR
Definition: pedump.c:58
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID TlsBitmap
Definition: ntddk_ex.h:259
PS_ATTRIBUTE Attributes[1]
Definition: winternl.h:4198
SIZE_T Size
Definition: winternl.h:4186
ULONG_PTR Attribute
Definition: winternl.h:4185
void * ValuePtr
Definition: winternl.h:4190
Definition: compat.h:836
Definition: match.c:390
Definition: ps.c:97
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
NTSYSAPI NTSTATUS WINAPI NtCreateUserProcess(HANDLE *, HANDLE *, ACCESS_MASK, ACCESS_MASK, OBJECT_ATTRIBUTES *, OBJECT_ATTRIBUTES *, ULONG, ULONG, RTL_USER_PROCESS_PARAMETERS *, PS_CREATE_INFO *, PS_ATTRIBUTE_LIST *)
#define PS_ATTRIBUTE_IMAGE_NAME
Definition: winternl.h:4157
NTSYSAPI NTSTATUS WINAPI RtlCreateProcessParametersEx(RTL_USER_PROCESS_PARAMETERS **, const UNICODE_STRING *, const UNICODE_STRING *, const UNICODE_STRING *, const UNICODE_STRING *, PWSTR, const UNICODE_STRING *, const UNICODE_STRING *, const UNICODE_STRING *, const UNICODE_STRING *, ULONG)
NTSYSAPI NTSTATUS WINAPI NtCreateThreadEx(HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *, HANDLE, PRTL_THREAD_START_ROUTINE, void *, ULONG, ULONG_PTR, SIZE_T, SIZE_T, PS_ATTRIBUTE_LIST *)
#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER
Definition: winternl.h:4080
void(CALLBACK * PRTL_THREAD_START_ROUTINE)(LPVOID)
Definition: winternl.h:3492
#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED
Definition: winternl.h:4078
#define PROCESS_PARAMS_FLAG_NORMALIZED
Definition: winternl.h:299