ReactOS 0.4.17-dev-573-g8315b8c
NtCreateThread.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: See COPYING in the top level directory
4 * PURPOSE: Test for NtCreateThread
5 * PROGRAMMER: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
6 * PROGRAMMER: Timo Kreuzer <timo.kreuzer@reactos.org>
7 */
8
9#include "precomp.h"
10
13DECLSPEC_ALIGN(16) UCHAR TestThreadStartupStack[PAGE_SIZE];
14BOOLEAN TestThreadFunctionCalled;
15extern void ThreadStartupThunk(void*);
16
17#define RPL_MASK 0x0003
18#define MODE_MASK 0x0001
19#define EFLAGS_INTERRUPT_MASK 0x200L
20#define KGDT_R3_CODE 0x0018
21#define KGDT_R3_DATA 0x0020
22#define KGDT_R3_TEB 0x0038
23#define KGDT64_R3_CMCODE 0x0020
24#define KGDT64_R3_DATA 0x0028
25#define KGDT64_R3_CODE 0x0030
26#define KGDT64_R3_CMTEB 0x0050
27
28static
29VOID
30InitializeTestContext(PCONTEXT Context)
31{
32 RtlFillMemory(Context, sizeof(*Context), 0xAA);
33
34 Context->ContextFlags = CONTEXT_ALL;
35
36#ifdef _M_AMD64
37
38 /* Control */
39 Context->Rsp = (ULONG64)(TestThreadStartupStack + PAGE_SIZE - 16);
40 Context->Rip = (ULONG64)ThreadStartupThunk;
41
42 /* Set Eflags. These get sanitized, but 0x100 (trap flag) makes it trap instantly. */
43 Context->EFlags = 0xFFFFFFFF;
44 Context->EFlags &= ~0x100;
45
46 /* Integer (these are copied) */
47 Context->Rax = 0xF000000000000000;
48 Context->Rcx = 0xF000000000000001;
49 Context->Rdx = 0xF000000000000002;
50 Context->Rbx = 0xF000000000000003;
51 Context->Rbp = 0xF000000000000005;
52 Context->Rsi = 0xF000000000000006;
53 Context->Rdi = 0xF000000000000007;
54 Context->R8 = 0xF000000000000008;
55 Context->R9 = 0xF000000000000009;
56 Context->R10 = 0xF00000000000000A;
57 Context->R11 = 0xF00000000000000B;
58 Context->R12 = 0xF00000000000000C;
59 Context->R13 = 0xF00000000000000D;
60 Context->R14 = 0xF00000000000000E;
61 Context->R15 = 0xF00000000000000F;
62
63#elif defined(_M_IX86)
64
65 /* Control */
66 Context->Esp = (ULONG)(TestThreadStartupStack + PAGE_SIZE - 16);
67 Context->Eip = (ULONG)ThreadStartupThunk;
68
69 /* Set Eflags. These get sanitized, but 0x100 (trap flag) makes it trap instantly. */
70 Context->EFlags = 0xFFFFFFFF;
71 Context->EFlags &= ~0x100; // Disable trap flag, because it would make the thread trap instantly
72 Context->EFlags &= ~0x00020000; // Disable V86 flag
73
74 /* Integer (these are copied) */
75 Context->Eax = 0xF0000000;
76 Context->Ecx = 0xF0000001;
77 Context->Edx = 0xF0000002;
78 Context->Ebx = 0xF0000003;
79 Context->Ebp = 0xF0000005;
80 Context->Esi = 0xF0000006;
81 Context->Edi = 0xF0000007;
82
83 /* FIXME: Initialize segments to prevent ReactOS from crashing in the kernel */
84 Context->SegCs = KGDT_R3_CODE | RPL_MASK;
85 Context->SegSs = KGDT_R3_DATA | RPL_MASK;
86 Context->SegDs = KGDT_R3_DATA | RPL_MASK;
87 Context->SegEs = KGDT_R3_DATA | RPL_MASK;
88 Context->SegFs = KGDT_R3_TEB | RPL_MASK;
89 Context->SegGs = 0;
90
91#else
92
93#pragma message("Missing CONTEXT setup in NtCreateThread test")
95
96#endif
97}
98
99VOID
100NTAPI
102{
103 TestThreadFunctionCalled = TRUE;
104
105#if defined(_M_IX86) || defined(_M_AMD64)
107
108 /* Get the debug registers and floating point */
117#if defined(_M_IX86)
119#endif
120#endif
121
122 /* Terminate current thread */
124}
125
127{
129 INITIAL_TEB InitialTeb;
130 HANDLE ThreadHandle;
133 PULONG_PTR StackPtr = &Stack[ARRAYSIZE(Stack) - 2];
136
139
141 ZeroMemory(&InitialTeb, sizeof(INITIAL_TEB));
142
143 Status = NtCreateThread(&ThreadHandle,
144 0,
145 &Attributes,
147 NULL,
148 (PCONTEXT)0x70000000, /* Aligned usermode address */
149 &InitialTeb,
150 FALSE);
151
153
154 InitialTeb.PreviousStackBase = NULL;
155 InitialTeb.PreviousStackLimit = NULL;
156 InitialTeb.StackBase = StackPtr;
157 InitialTeb.StackLimit = Stack;
158 InitialTeb.AllocatedStackBase = Stack;
159
161
163 InitializeTestContext(&Context);
164
165 Status = NtCreateThread(&ThreadHandle,
167 NULL,
169 &ClientId,
170 &Context,
171 &InitialTeb,
172 TRUE);
174
175 NtResumeThread(ThreadHandle, NULL);
176 WaitForSingleObject(ThreadHandle, INFINITE);
177 CloseHandle(ThreadHandle);
178
179 ok_eq_bool(TestThreadFunctionCalled, TRUE);
180 TestThreadFunctionCalled = FALSE;
181
182#ifdef _M_AMD64
183
184 /* Control */
189
190 /* Integer (copied) */
206
207 /* Segments (hardcoded) */
212
213 /* Floating point (hardcoded) */
216 ok_eq_hex(TestThreadStartupContext.FltSave.StatusWord, 0x0000);
217 ok_eq_hex(TestThreadStartupContext.FltSave.TagWord, 0x00);
218 ok_eq_hex(TestThreadStartupContext.FltSave.Reserved1, 0x00);
219 ok_eq_hex(TestThreadStartupContext.FltSave.ErrorOpcode, 0x0000);
220 ok_eq_hex(TestThreadStartupContext.FltSave.ErrorOffset, 0x00000000);
221 ok_eq_hex(TestThreadStartupContext.FltSave.ErrorSelector, 0x0000);
222 ok_eq_hex(TestThreadStartupContext.FltSave.Reserved2, 0x0000);
223 ok_eq_hex(TestThreadStartupContext.FltSave.DataOffset, 0x00000000);
224 ok_eq_hex(TestThreadStartupContext.FltSave.DataSelector, 0x0000);
225 ok_eq_hex(TestThreadStartupContext.FltSave.Reserved3, 0x0000);
227 ok_eq_hex(TestThreadStartupContext.FltSave.MxCsr_Mask, 0x0002FFFF);
228 for (ULONG i = 0; i < ARRAYSIZE(TestThreadStartupContext.FltSave.FloatRegisters); i++)
229 {
230 ok_eq_hex64(TestThreadStartupContext.FltSave.FloatRegisters[i].Low, 0x0000000000000000ull);
231 ok_eq_hex64(TestThreadStartupContext.FltSave.FloatRegisters[i].High, 0x0000000000000000ull);
232 }
233 PM128A XmmRegisters = &TestThreadStartupContext.Xmm0;
234 for (ULONG i = 0; i < 16; i++)
235 {
236 ok_eq_hex64(XmmRegisters[i].Low, 0x0000000000000000ull);
237 ok_eq_hex64(XmmRegisters[i].High, 0x0000000000000000ull);
238 }
239 for (ULONG i = 0; i < ARRAYSIZE(TestThreadStartupContext.VectorRegister); i++)
240 {
241 ok_eq_hex64(TestThreadStartupContext.VectorRegister[i].Low, 0xCCCCCCCCCCCCCCCCull);
242 ok_eq_hex64(TestThreadStartupContext.VectorRegister[i].High, 0xCCCCCCCCCCCCCCCCull);
243 }
244
245 /* Debug registers (reset to 0) */
246 ok_eq_hex64(TestThreadStartupContext.Dr0, 0x0000000000000000ull);
247 ok_eq_hex64(TestThreadStartupContext.Dr1, 0x0000000000000000ull);
248 ok_eq_hex64(TestThreadStartupContext.Dr2, 0x0000000000000000ull);
249 ok_eq_hex64(TestThreadStartupContext.Dr3, 0x0000000000000000ull);
250 ok_eq_hex64(TestThreadStartupContext.Dr6, 0x0000000000000000ull);
251 ok_eq_hex64(TestThreadStartupContext.Dr7, 0x0000000000000000ull);
252
253#elif defined(_M_IX86)
254
255 /* Control */
257 ok_eq_hex(TestThreadStartupContext.EFlags, IsWow64 ? 0x00240ED7 : 0x003C4ED7);
258
259 /* Integer (copied) */
267
268 /* Segments (hardcoded, the upper 16 bits are left uninitialized by RtlCaptureContext) */
275
276 /* Floating point (hardcoded) */
279 ok_eq_hex(TestThreadStartupContext.FloatSave.TagWord, IsWow64 ? 0x0000FFFF : 0xFFFF0000);
284
285 /* Debug registers (reset to 0) */
292
293#else
294
295#pragma message("Missing CONTEXT validation in NtCreateThread test")
296 ASSERT(FALSE);
297
298#endif
299
300#if defined(_M_AMD64) || defined(_M_IX86)
301 /* Test Eflags set to 0 */
302 Context.EFlags = 0;
303 TestThreadStartupContext.EFlags = 0xCCCCCCCC;
304 Status = NtCreateThread(&ThreadHandle,
306 NULL,
308 &ClientId,
309 &Context,
310 &InitialTeb,
311 TRUE);
313 NtResumeThread(ThreadHandle, NULL);
314 WaitForSingleObject(ThreadHandle, INFINITE);
315 CloseHandle(ThreadHandle);
317#endif
318
319#if !defined(_M_IX86) // FIXME: This crashes on x86
320 /* Test different InitialTeb values */
321 InitialTeb.PreviousStackBase = Stack;
322 InitialTeb.PreviousStackLimit = NULL;
323 Status = NtCreateThread(&ThreadHandle,
325 NULL,
327 &ClientId,
328 &Context,
329 &InitialTeb,
330 FALSE);
332
333 InitialTeb.PreviousStackBase = NULL;
334 InitialTeb.PreviousStackLimit = Stack;
335 Status = NtCreateThread(&ThreadHandle,
337 NULL,
339 &ClientId,
340 &Context,
341 &InitialTeb,
342 FALSE);
344#endif
345}
PVOID TestThreadProcPtr
#define KGDT_R3_DATA
#define KGDT_R3_CODE
#define KGDT_R3_TEB
#define KGDT64_R3_DATA
VOID NTAPI TestThreadProc(IN PVOID StartContext)
#define KGDT64_R3_CMCODE
#define KGDT64_R3_CMTEB
#define RPL_MASK
CONTEXT TestThreadStartupContext
#define IsWow64()
Definition: NtReadFile.c:37
unsigned char BOOLEAN
Definition: actypes.h:127
#define ok_eq_hex(value, expected)
Definition: apitest.h:134
#define ok_eq_hex64(value, expected)
Definition: apitest.h:146
#define GetNTVersion()
Definition: apitest.h:17
#define ok_eq_bool(value, expected)
Definition: apitest.h:137
#define ok_hex(expression, result)
Definition: atltest.h:94
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
#define GetCurrentProcess()
Definition: compat.h:759
#define IsWow64Process
Definition: compat.h:760
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:501
#define DECLSPEC_ALIGN(x)
Definition: corecrt.h:141
#define INFINITE
Definition: serial.h:102
#define PAGE_SIZE
Definition: env_spec_w32.h:49
unsigned int BOOL
Definition: ntddk_ex.h:94
#define STATUS_ACCESS_VIOLATION
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ZeroMemory
Definition: minwinbase.h:31
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1376
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1287
#define NtCurrentProcess()
Definition: nt_native.h:1660
#define CONTEXT_FLOATING_POINT
Definition: nt_native.h:1375
NTSYSAPI NTSTATUS NTAPI NtCreateThread(OUT PHANDLE phThread, IN ACCESS_MASK AccessMask, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE hProcess, OUT PCLIENT_ID pClientId, IN PCONTEXT pContext, OUT PSTACKINFO pStackInfo, IN BOOLEAN bSuspended)
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
unsigned short USHORT
Definition: pedump.c:61
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:603
#define INITIAL_FPCSR
#define CONTEXT_ALL
#define INITIAL_MXCSR
#define _WIN32_WINNT_WIN10
Definition: sdkddkver.h:32
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PVOID Context
Definition: storport.h:2269
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
ULONG Esp
Definition: nt_native.h:1482
ULONG SegFs
Definition: nt_native.h:1457
ULONG Dr3
Definition: nt_native.h:1440
ULONG Dr1
Definition: nt_native.h:1438
ULONG Edx
Definition: nt_native.h:1469
ULONG Esi
Definition: nt_native.h:1467
ULONG Ebp
Definition: nt_native.h:1478
ULONG R8
Definition: ke.h:263
ULONG Dr6
Definition: nt_native.h:1441
ULONG SegSs
Definition: nt_native.h:1483
ULONG Ecx
Definition: nt_native.h:1470
ULONG Dr0
Definition: nt_native.h:1437
ULONG R12
Definition: ke.h:267
ULONG SegCs
Definition: nt_native.h:1480
ULONG SegDs
Definition: nt_native.h:1459
ULONG R9
Definition: ke.h:264
ULONG EFlags
Definition: nt_native.h:1481
ULONG SegGs
Definition: nt_native.h:1456
ULONG Dr2
Definition: nt_native.h:1439
ULONG R10
Definition: ke.h:265
ULONG Eax
Definition: nt_native.h:1471
FLOATING_SAVE_AREA FloatSave
Definition: nt_native.h:1449
ULONG SegEs
Definition: nt_native.h:1458
ULONG Ebx
Definition: nt_native.h:1468
ULONG Edi
Definition: nt_native.h:1466
ULONG R11
Definition: ke.h:266
ULONG Dr7
Definition: nt_native.h:1442
PVOID StackBase
Definition: pstypes.h:727
PVOID PreviousStackBase
Definition: pstypes.h:725
PVOID AllocatedStackBase
Definition: pstypes.h:729
PVOID StackLimit
Definition: pstypes.h:728
PVOID PreviousStackLimit
Definition: pstypes.h:726
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint32_t * PULONG_PTR
Definition: typedefs.h:65
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define NtCurrentThread()
Definition: winternl.h:5372
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
* PM128A
Definition: ketypes.h:1008