ReactOS 0.4.17-dev-573-g8315b8c
NtCreateThread.c File Reference
#include "precomp.h"
Include dependency graph for NtCreateThread.c:

Go to the source code of this file.

Macros

#define RPL_MASK   0x0003
 
#define MODE_MASK   0x0001
 
#define EFLAGS_INTERRUPT_MASK   0x200L
 
#define KGDT_R3_CODE   0x0018
 
#define KGDT_R3_DATA   0x0020
 
#define KGDT_R3_TEB   0x0038
 
#define KGDT64_R3_CMCODE   0x0020
 
#define KGDT64_R3_DATA   0x0028
 
#define KGDT64_R3_CODE   0x0030
 
#define KGDT64_R3_CMTEB   0x0050
 

Functions

 DECLSPEC_ALIGN (16)
 
VOID NTAPI TestThreadProc (IN PVOID StartContext)
 
 START_TEST (NtCreateThread)
 

Variables

PVOID TestThreadProcPtr
 
CONTEXT TestThreadStartupContext
 

Macro Definition Documentation

◆ EFLAGS_INTERRUPT_MASK

#define EFLAGS_INTERRUPT_MASK   0x200L

◆ KGDT64_R3_CMCODE

#define KGDT64_R3_CMCODE   0x0020

◆ KGDT64_R3_CMTEB

#define KGDT64_R3_CMTEB   0x0050

◆ KGDT64_R3_CODE

#define KGDT64_R3_CODE   0x0030

◆ KGDT64_R3_DATA

#define KGDT64_R3_DATA   0x0028

◆ KGDT_R3_CODE

#define KGDT_R3_CODE   0x0018

◆ KGDT_R3_DATA

#define KGDT_R3_DATA   0x0020

◆ KGDT_R3_TEB

#define KGDT_R3_TEB   0x0038

◆ MODE_MASK

#define MODE_MASK   0x0001

◆ RPL_MASK

#define RPL_MASK   0x0003

Function Documentation

◆ DECLSPEC_ALIGN()

DECLSPEC_ALIGN ( 16  )

Definition at line 13 of file NtCreateThread.c.

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}
#define KGDT_R3_DATA
#define KGDT_R3_CODE
#define KGDT_R3_TEB
#define RPL_MASK
#define FALSE
Definition: types.h:117
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:603
#define CONTEXT_ALL
_In_ PVOID Context
Definition: storport.h:2269
uint32_t ULONG
Definition: typedefs.h:59

◆ START_TEST()

START_TEST ( NtCreateThread  )

Definition at line 126 of file NtCreateThread.c.

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 KGDT64_R3_DATA
VOID NTAPI TestThreadProc(IN PVOID StartContext)
#define KGDT64_R3_CMCODE
#define KGDT64_R3_CMTEB
CONTEXT TestThreadStartupContext
#define IsWow64()
Definition: NtReadFile.c:37
#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
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 ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
#define GetCurrentProcess()
Definition: compat.h:759
#define IsWow64Process
Definition: compat.h:760
#define DECLSPEC_ALIGN(x)
Definition: corecrt.h:141
#define INFINITE
Definition: serial.h:102
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 InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
#define NtCurrentProcess()
Definition: nt_native.h:1660
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 INITIAL_FPCSR
#define INITIAL_MXCSR
#define _WIN32_WINNT_WIN10
Definition: sdkddkver.h:32
#define STATUS_SUCCESS
Definition: shellext.h:65
@ 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
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
* PM128A
Definition: ketypes.h:1008

◆ TestThreadProc()

VOID NTAPI TestThreadProc ( IN PVOID  StartContext)

Definition at line 101 of file NtCreateThread.c.

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}
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:501
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1376
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1287
#define CONTEXT_FLOATING_POINT
Definition: nt_native.h:1375
#define NtCurrentThread()
Definition: winternl.h:5372

Referenced by START_TEST().

Variable Documentation

◆ TestThreadProcPtr

PVOID TestThreadProcPtr

Definition at line 11 of file NtCreateThread.c.

Referenced by START_TEST().

◆ TestThreadStartupContext

CONTEXT TestThreadStartupContext

Definition at line 12 of file NtCreateThread.c.

Referenced by START_TEST(), and TestThreadProc().