ReactOS 0.4.17-dev-37-g0bfb40d
thread.c File Reference
#include <stdarg.h>
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/test.h"
Include dependency graph for thread.c:

Go to the source code of this file.

Classes

struct  unique_teb_thread_args
 

Macros

#define WIN32_NO_STATUS
 
#define GET_FUNC(name)   p##name = (void *)GetProcAddress( hntdll, #name );
 

Functions

static NTSTATUS (WINAPI *pNtCreateThreadEx)(HANDLE *
 
static OBJECT_ATTRIBUTES void PS_ATTRIBUTE_LIST *static int *CDECLp_errno (void)
 
static void init_function_pointers (void)
 
static void CALLBACK test_NtCreateThreadEx_proc (void *param)
 
static void test_dbg_hidden_thread_creation (void)
 
static void CALLBACK test_unique_teb_proc (void *param)
 
static void test_unique_teb (void)
 
static void test_errno (void)
 
 START_TEST (thread)
 

Variables

static ACCESS_MASK
 
static OBJECT_ATTRIBUTES HANDLE
 
static OBJECT_ATTRIBUTES PRTL_THREAD_START_ROUTINE
 
static OBJECT_ATTRIBUTES void ULONG
 
static OBJECT_ATTRIBUTES void ULONG_PTR
 
static OBJECT_ATTRIBUTES void SIZE_T
 

Macro Definition Documentation

◆ GET_FUNC

#define GET_FUNC (   name)    p##name = (void *)GetProcAddress( hntdll, #name );

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 25 of file thread.c.

Function Documentation

◆ init_function_pointers()

static void init_function_pointers ( void  )
static

Definition at line 36 of file thread.c.

37{
38 HMODULE hntdll = GetModuleHandleA( "ntdll.dll" );
39#define GET_FUNC(name) p##name = (void *)GetProcAddress( hntdll, #name );
42#undef GET_FUNC
43}
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
int *CDECL _errno(void)
Definition: errno.c:215
static HINSTANCE hntdll
Definition: process.c:68
#define GET_FUNC(name)
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 *)

Referenced by START_TEST().

◆ NTSTATUS()

static NTSTATUS ( WINAPI pNtCreateThreadEx)
static

◆ p_errno()

static OBJECT_ATTRIBUTES void PS_ATTRIBUTE_LIST *static int *CDECL * p_errno ( void  )
static

Referenced by test_errno().

◆ START_TEST()

START_TEST ( thread  )

Definition at line 209 of file thread.c.

210{
212
215 test_errno();
216}
static void test_errno(void)
Definition: thread.c:191
static void init_function_pointers(void)
Definition: thread.c:36
static void test_unique_teb(void)
Definition: thread.c:147
static void test_dbg_hidden_thread_creation(void)
Definition: thread.c:49

◆ test_dbg_hidden_thread_creation()

static void test_dbg_hidden_thread_creation ( void  )
static

Definition at line 49 of file thread.c.

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}
unsigned char BOOLEAN
Definition: actypes.h:127
#define ok(value,...)
Definition: atltest.h:57
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE thread
Definition: service.c:33
#define NULL
Definition: types.h:112
#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 lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
#define L(x)
Definition: resources.c:13
#define INFINITE
Definition: serial.h:102
GLenum const GLfloat * params
Definition: glext.h:5645
#define win_skip
Definition: minitest.h:67
static void CALLBACK test_NtCreateThreadEx_proc(void *param)
Definition: thread.c:45
#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
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: ps.c:97
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
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)
#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER
Definition: winternl.h:4080
#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED
Definition: winternl.h:4078
#define PROCESS_PARAMS_FLAG_NORMALIZED
Definition: winternl.h:299

Referenced by START_TEST().

◆ test_errno()

static void test_errno ( void  )
static

Definition at line 191 of file thread.c.

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}
#define PtrToLong(p)
Definition: basetsd.h:78
PPEB Peb
Definition: dllmain.c:27
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1240
GLuint GLfloat * val
Definition: glext.h:7180
#define NtCurrentTeb
static OBJECT_ATTRIBUTES void PS_ATTRIBUTE_LIST *static int *CDECL * p_errno(void)
PVOID TlsBitmap
Definition: ntddk_ex.h:259

Referenced by START_TEST().

◆ test_NtCreateThreadEx_proc()

static void CALLBACK test_NtCreateThreadEx_proc ( void param)
static

Definition at line 45 of file thread.c.

46{
47}

Referenced by test_dbg_hidden_thread_creation().

◆ test_unique_teb()

static void test_unique_teb ( void  )
static

Definition at line 147 of file thread.c.

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}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HANDLE ULONG_PTR DWORD threads
Definition: process.c:83
static void CALLBACK test_unique_teb_proc(void *param)
Definition: thread.c:139
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
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
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by START_TEST().

◆ test_unique_teb_proc()

static void CALLBACK test_unique_teb_proc ( void param)
static

Definition at line 139 of file thread.c.

140{
142 args->teb = NtCurrentTeb();
143 SetEvent( args->running_event );
144 WaitForSingleObject( args->quit_event, INFINITE );
145}
GLfloat param
Definition: glext.h:5796
Definition: match.c:390

Referenced by test_unique_teb().

Variable Documentation

◆ ACCESS_MASK

Definition at line 31 of file thread.c.

◆ HANDLE

Definition at line 32 of file thread.c.

◆ PRTL_THREAD_START_ROUTINE

OBJECT_ATTRIBUTES PRTL_THREAD_START_ROUTINE

Definition at line 32 of file thread.c.

◆ SIZE_T

Definition at line 33 of file thread.c.

◆ ULONG

Definition at line 33 of file thread.c.

◆ ULONG_PTR

Definition at line 33 of file thread.c.