kernel
Loading...
Searching...
No Matches
thread.c
Go to the documentation of this file.
1#include "../../includes/ps.h"
2#include "../../assert.h"
3#include "../../includes/mg.h"
4#include "../../includes/ob.h"
5
6#define MIN_TID 3u
7#define MAX_TID 0xFFFFFFFCu
8#define ALIGN_DELTA 3u
9#define MAX_FREE_POOL 1024u
10
11#define THREAD_STACK_SIZE (1024*24) // 24 KiB
12#define THREAD_ALIGNMENT 16
13
14// Clean exit for a thread—never returns!
15static void ThreadExit(void) {
16#ifdef DEBUG
17 // if you are asking why i dont print the tid, its because i (fucking) hate the gop function
18 // so many stack overflows, it makes my blood boil.
19 gop_printf(COLOR_RED, "Reached ThreadExit, terminating system thread.\n");
20#endif
21 // Terminate the thread.
22 assert(PsIsKernelThread(PsGetCurrentThread()) == true, "A user thread has entered kernel thread termination.");
24 Schedule();
25}
26
27// Kernel threads only.
28static void ThreadWrapperEx(ThreadEntry thread_entry, THREAD_PARAMETER parameter) {
29 // thread_entry(parameters) -> void func(void*)
30 thread_entry(parameter); // If thread entry takes no parameters, passing NULL is still fine.
32 ThreadExit();
33}
34
36
39 HANDLE ProcessHandle,
40 PHANDLE ThreadHandle,
41 ThreadEntry EntryPoint,
42 THREAD_PARAMETER ThreadParameter,
43 TimeSliceTicks TimeSlice,
44 ThreadEntry MtdllEntrypoint
45)
46
47{
48 // Checks.
49 if (!ProcessHandle || !EntryPoint || !TimeSlice) return MT_INVALID_PARAM;
50 MTSTATUS Status;
51 PEPROCESS ParentProcess;
52
53 Status = ObReferenceObjectByHandle(ProcessHandle, MT_PROCESS_CREATE_THREAD, PsProcessType, (void**)&ParentProcess, NULL);
54 if (MT_FAILURE(Status)) return Status;
55
56 // Acquire process rundown protection.
57 if (!MsAcquireRundownProtection(&ParentProcess->ProcessRundown)) {
58 // Process is, being terminated?
59 ObDereferenceObject(ParentProcess);
61 }
62
63 // Create a new thread.
64 PETHREAD Thread;
65 Status = ObCreateObject(PsThreadType, sizeof(ETHREAD), (void**) & Thread);
66 if (MT_FAILURE(Status)) {
67 ObDereferenceObject(ParentProcess);
69 goto Cleanup;
70 }
71
72 // Set parent process.
73 Thread->ParentProcess = ParentProcess;
74
75 // Initialize list head.
77
78 // Create a TID for the thread.
79 Thread->TID = PsAllocateThreadId(Thread);
80 if (Thread->TID == MT_INVALID_HANDLE) goto CleanupWithRef;
81
82 // Write the PID into the thread.
83 Thread->PID = ParentProcess->PID;
84
85 // Create a new stack for the thread's kernel environment.
87 Thread->InternalThread.IsLargeStack = false;
88 if (!Thread->InternalThread.KernelStack) goto CleanupWithRef;
89
90 // Create user mode stack.
91 void* BaseAddress = NULL;
92 size_t StackSize = MI_DEFAULT_USER_STACK_SIZE;
93 Status = MmCreateUserStack(ParentProcess, &BaseAddress, StackSize);
94 if (MT_FAILURE(Status)) goto CleanupWithRef;
95 Thread->InternalThread.StackBase = BaseAddress; // Stack grows downward.
96
97 // Setup timeslice.
98 Thread->InternalThread.TimeSlice = TimeSlice;
99 Thread->InternalThread.TimeSliceAllocated = TimeSlice;
100
101 // Set registers
102 TRAP_FRAME ContextFrame;
103 kmemset(&ContextFrame, 0, sizeof(TRAP_FRAME));
104
105 ContextFrame.rsp = (uint64_t)Thread->InternalThread.StackBase;
106 ContextFrame.rip = (uint64_t)EntryPoint; // Entry point parameter should be removed when mtdll comes around, as it should handle new thread creations
107 ContextFrame.rdi = (uint64_t)ThreadParameter;
108 ContextFrame.rflags = USER_RFLAGS;
109 ContextFrame.cs = USER_CS;
110 ContextFrame.ss = USER_SS;
111 Thread->InternalThread.TrapRegisters = ContextFrame;
112 Thread->SystemThread = false;
113
114 // Set state
116 Thread->InternalThread.ApcState.SavedApcProcess = ParentProcess;
117
118 // Get TEB.
119 PTEB Teb = NULL;
120 Status = MmCreateTeb(Thread, (void**) & Teb);
121 if (MT_FAILURE(Status)) goto CleanupWithRef;
122
123 APC_STATE ApcState;
124 MeAttachProcess(&ParentProcess->InternalProcess, &ApcState);
125
126 // Write some basic information to TEB.
127 try {
128 Teb->UniqueThreadId = Thread->TID;
129 Teb->UniqueProcessId = ParentProcess->PID;
131 Teb->MtTib.StackLimit = (void*)(((uintptr_t)Thread->InternalThread.StackBase - StackSize));
132 Status = MT_SUCCESS;
133 } except{
134 // Page fault on user addr.
135 Status = GetExceptionCode();
136 } end_try;
137
138 // Detach
139 MeDetachProcess(&ApcState);
140
141 if (MT_FAILURE(Status)) goto CleanupWithRef;
142
143 // Set process's thread properties.
144 if (!ParentProcess->MainThread) {
145 ParentProcess->MainThread = Thread;
146
147 // Main thread means ThreadParameter is actually the 3rd argument to LdrInitializeProcess in mtdll
148 // RDI - Pointer to PEB.
149 // RSI - Pointer to TEB.
150 // RDX - Thread entry point.
151 // RCX - Pointer to MTDLL_BASIC_TYPES.
153 Trap->rdi = (uint64_t)ParentProcess->Peb;
154 Trap->rsi = (uint64_t)Teb;
155 Trap->rdx = (uint64_t)EntryPoint;
156 Trap->rcx = (uint64_t)ThreadParameter;
157 Trap->rip = (uint64_t)MtdllEntrypoint;
158 }
159 else {
160 // There is a process main thread, this thread's return address must be to ExitThread(), since after the function return of
161 // EntryPoint (if it returns), it will POP an invalid value from the stack to return, and so a probable page fault and termination
162 // of thread (or process, havent decided yet, look at MiPageFault if it updated)
163 // FIXME.
164 // (main threads pop back to crt0 runtime, where ExitProcess is ran)
165 // Set MTDLL
166 }
167
168 // Create a handle for the thread (and place it in the process's handle table).
169 Status = ObCreateHandleForObjectEx(Thread, MT_THREAD_ALL_ACCESS, ThreadHandle, ParentProcess->ObjectTable);
170 if (MT_FAILURE(Status)) goto CleanupWithRef;
171
172 // Add to list of all threads in the parent process. (acquire its push lock)
174
175 InsertTailList(&ParentProcess->AllThreads, &Thread->ThreadListEntry);
176 ParentProcess->NumThreads++;
177
179 Status = MT_SUCCESS;
180 // Insert thread to processor queue.
181 MeEnqueueThreadWithLock(&MeGetCurrentProcessor()->readyQueue, Thread);
182
183CleanupWithRef:
184 // If failure on status, we destroy the thread, if not.
185 // We are left with PointerCount == 2 and HandleCount == 1, why? Because if we access the thread and dereference it there still must be left HandleCount == 1 and PointerCount == 1 (the handles)
186 // With processes however, its different.
188 if (MT_FAILURE(Status)) {
189 ObDereferenceObject(Thread);
190 ObDereferenceObject(ParentProcess);
191 }
192Cleanup:
193 return Status;
194}
195
197 if (unlikely(!PsInitialSystemProcess.PID)) return MT_NOT_FOUND; // The system process, somehow, hasn't been setupped yet.
198 if (!entry || !TIMESLICE) return MT_INVALID_PARAM;
199
200 // First, allocate a new thread. (using our shiny and glossy new object manager!!!)
201 MTSTATUS Status;
202 PETHREAD thread;
203 Status = ObCreateObject(PsThreadType, sizeof(ETHREAD), (void*) & thread);
204 if (MT_FAILURE(Status)) {
205 return Status;
206 }
207
208 // Initialize list head.
210
211 // Create stack
212 bool LargeStack = false;
213 void* stackStart = MiCreateKernelStack(LargeStack);
214
215 if (!stackStart) {
216 // free thread
217 ObDereferenceObject(thread);
218 return MT_NO_MEMORY;
219 }
220
221 uintptr_t StackTop = (uintptr_t)stackStart;
222
223 StackTop &= ~0xF; // Align to 16 bytes (clear lower 4 bits)
224 StackTop -= 8; // Decrement by 8 to keep 16-byte alignment. (after pushes)
225
226 thread->InternalThread.StackBase = stackStart; // The stackbase must be the one gotten from MiCreateKernelStack, as freeing with StackTop will result in incorrect arithmetic, and so assertion failure.
227 thread->InternalThread.IsLargeStack = LargeStack;
228 thread->InternalThread.KernelStack = stackStart;
229
231 kmemset(cfm, 0, sizeof * cfm);
232
233 // Set our timeslice.
234 thread->InternalThread.TimeSlice = TIMESLICE;
235 thread->InternalThread.TimeSliceAllocated = TIMESLICE;
236
237 // saved rsp must point to the top (aligned), not sp-8
238 cfm->rsp = (uint64_t)StackTop;
239 cfm->rip = (uint64_t)ThreadWrapperEx;
240 cfm->rdi = (uint64_t)entry; // first argument to ThreadWrapperEx (the entry point)
241 cfm->rsi = (uint64_t)parameter; // second arugment to ThreadWrapperEx (the parameter pointer)
242
243 cfm->ss = KERNEL_SS;
244 cfm->cs = KERNEL_CS;
245
246 // Create it's RFLAGS with IF bit set to 1.
247 cfm->rflags |= (1 << 9ULL);
248
249 // Set it's registers and others.
250 thread->InternalThread.TrapRegisters = *cfm;
252 thread->TID = PsAllocateThreadId(thread);
253 if (thread->TID == MT_INVALID_HANDLE) {
254 ObDereferenceObject(thread);
255 return MT_INVALID_HANDLE;
256 }
257 thread->CurrentEvent = NULL;
260 thread->SystemThread = true;
261
262 // Process stuffz
263 thread->ParentProcess = &PsInitialSystemProcess; // The parent process for the system thread, is the system process.
264 // Use the push lock to insert it into AllThreads.
266
268 PsInitialSystemProcess.NumThreads++;
269
271
272 // Enqueue it into processor. TODO START SUSPENDED?
273 MeEnqueueThreadWithLock(&MeGetCurrentProcessor()->readyQueue, thread);
274 if (OutThread) *OutThread = thread;
275 return MT_SUCCESS;
276}
277
280 return CONTAINING_RECORD(MeGetCurrentThread(), ETHREAD, InternalThread);
281}
282
285 IN PETHREAD Thread,
286 IN MTSTATUS ExitStatus
287)
288
289{
290 // Non complete function, this should queue a thread Apc to call MtTerminateThread (PspExitThread) on itself.
291 // Or if it is the current thread, we just terminate ourselves.
292 if (Thread == PsGetCurrentThread()) {
293 // Exit current thread.
294 PspExitThread(ExitStatus);
295 return MT_SUCCESS;
296 }
297
298 assert(false, "Termination called upon remote thread, unimplemented. Need APCs");
299 MeBugCheckEx((BUGCHECK_CODES)MT_NOT_IMPLEMENTED, (void*)(uintptr_t)Thread, (void*)(uintptr_t)ExitStatus, NULL, NULL);
300
301 return MT_NOT_IMPLEMENTED;
302}
303
304void
306 IN void* Object
307)
308
309{
310 // This function is called when the reference count for this thread has reached 0 (e.g, it is no longer in use)
311 // (it is called after thread termination)
312 // We free everything that the ETHREAD uses.
313 PETHREAD Thread = (PETHREAD)Object;
314
315 bool IsKernelThread = PsIsKernelThread(Thread);
316
317 // Free TID.
318 PsFreeCid(Thread->TID);
319
320 // Free its stack.
321 if (IsKernelThread) {
323 }
324 else {
325 // Dereference the parent process, and free its kernel stack..
328 }
329
330 // When we reach here, the function returns, and the ETHREAD is deleted.
331}
332
334void
336 IN MTSTATUS ExitStatus
337)
338
339{
340 // This exits the current running thread on the processor.
341 PETHREAD Thread = PsGetCurrentThread();
342 PEPROCESS CurrentProcess = Thread->InternalThread.ApcState.SavedApcProcess;
343
344 // Cannot terminate this thread if we are attached to a different process (since we would use another process fields)
345 if (MeIsAttachedProcess()) {
348 (void*)(uintptr_t)CurrentProcess,
349 (void*)(uintptr_t)Thread->InternalThread.ApcState.SavedApcProcess,
350 (void*)(uintptr_t)Thread,
351 NULL
352 );
353 }
354
355 // Lower IRQL to passive level.
357
358 // We cannot terminate a worker thread.
359 if (Thread->WorkerThread) {
362 (void*)(uintptr_t)Thread,
363 NULL,
364 NULL,
365 NULL
366 );
367 }
368
369 // Todo check for pending APCs, if so bugcheck.
370
371 // Wait for rundown protection release
373
374 // Acquire process lock before we modify thread entries.
376
377 // Decrease thread count and check if we are the last thread (if so, terminate process)
378 // No need for interlocked decrement as we hold push lock
379 bool LastThread = false;
380 if (!(--CurrentProcess->NumThreads)) {
381 LastThread = true;
382 }
383
384 // Remove us from the process thread list.
385 PDOUBLY_LINKED_LIST listHead = &CurrentProcess->AllThreads;
386 PDOUBLY_LINKED_LIST entry = listHead->Flink;
387
388 while (entry != listHead) {
389 PETHREAD iter = CONTAINING_RECORD(entry, ETHREAD, ThreadListEntry);
390 if (iter == Thread) {
391 // Remove entry
392 entry->Blink->Flink = entry->Flink;
393 entry->Flink->Blink = entry->Blink;
394
395 // Set entry to point at itself
397 break;
398 }
399 entry = entry->Flink;
400 }
401
402 // Release it now.
404
405 if (LastThread && (CurrentProcess->Flags & ProcessBreakOnTermination)) {
406 // This is the last thread termination of a critical process, this MUST not happen.
409 (void*)(uintptr_t)CurrentProcess,
410 NULL,
411 NULL,
412 NULL
413 );
414 }
415
416 if (LastThread) {
417 // This is the last thread of the process, we clear its handle table.
418 HtDeleteHandleTable(CurrentProcess->ObjectTable);
419 CurrentProcess->ObjectTable = NULL;
420 }
421
422 // Todo termination ports for a process (so when it dies the user process can like show a message to parent process or sum shit)
423
424 // Todo process the thread's mutexes and waits (unwait all threads waiting on this), along with flushing its APCs.
425
426 // Finally, terminate this thread from the scheduler.
428 Thread->ExitStatus = ExitStatus;
430
431 // Schedule away.
432 Schedule();
433}
#define _Out_Opt
Definition annotations.h:11
#define NORETURN
Definition annotations.h:14
#define IN
Definition annotations.h:8
#define assert(...)
Definition assert.h:57
void MeDetachProcess(IN PAPC_STATE ApcState)
Definition attach.c:90
void MeAttachProcess(IN PIPROCESS Process, OUT PAPC_STATE ApcState)
Definition attach.c:24
NORETURN void MeBugCheckEx(IN enum _BUGCHECK_CODES BugCheckCode, IN void *BugCheckParameter1, IN void *BugCheckParameter2, IN void *BugCheckParameter3, IN void *BugCheckParameter4)
Definition bugcheck.c:245
HANDLE PsAllocateThreadId(IN PETHREAD Thread)
Definition cid.c:89
void PsFreeCid(IN HANDLE Cid)
Definition cid.c:164
struct _EPROCESS EPROCESS
Definition core.h:51
struct _TRAP_FRAME TRAP_FRAME
Definition core.h:55
int32_t * PHANDLE
Definition core.h:58
struct _DOUBLY_LINKED_LIST * PDOUBLY_LINKED_LIST
@ PASSIVE_LEVEL
Definition core.h:15
int32_t HANDLE
Definition core.h:58
EPROCESS * PEPROCESS
Definition core.h:52
TRAP_FRAME * PTRAP_FRAME
Definition core.h:56
struct _ETHREAD ETHREAD
Definition core.h:43
ETHREAD * PETHREAD
Definition core.h:44
#define end_try
Definition exception.h:145
#define except
Definition exception.h:131
void gop_printf(uint32_t color, const char *fmt,...)
Definition gop.c:633
void HtDeleteHandleTable(IN PHANDLE_TABLE Table)
Definition handle.c:442
bool MeDisableInterrupts(void)
Definition irql.c:203
void MeLowerIrql(IN IRQL NewIrql)
Definition irql.c:102
#define CONTAINING_RECORD(ptr, type, member)
Definition macros.h:11
#define unlikely(x)
Definition macros.h:62
#define KERNEL_SS
Definition me.h:245
#define USER_CS
Definition me.h:247
struct _APC_STATE APC_STATE
@ CRITICAL_PROCESS_DIED
Definition me.h:135
@ WORKER_THREAD_ATTEMPTED_TERMINATION
Definition me.h:136
@ INVALID_PROCESS_ATTACH_ATTEMPT
Definition me.h:134
#define USER_RFLAGS
Definition me.h:250
FORCEINLINE PITHREAD MeGetCurrentThread(void)
Definition me.h:444
FORCEINLINE bool MeIsAttachedProcess(void)
Definition me.h:474
#define KERNEL_CS
Definition me.h:243
#define USER_SS
Definition me.h:248
FORCEINLINE PPROCESSOR MeGetCurrentProcessor(void)
Definition me.h:369
enum _TimeSliceTicks TimeSliceTicks
enum _BUGCHECK_CODES BUGCHECK_CODES
#define COLOR_RED
Colors definitions for easier access.
Definition mg.h:30
FORCEINLINE void * kmemset(void *dest, int64_t val, uint64_t len)
Definition mm.h:655
#define MI_DEFAULT_USER_STACK_SIZE
Definition mm.h:245
void * MiCreateKernelStack(IN bool LargeStack)
Definition mmproc.c:26
MTSTATUS MmCreateUserStack(IN PEPROCESS Process, OUT void **OutStackTop, _In_Opt size_t StackReserveSize)
Definition mmproc.c:436
MTSTATUS MmCreateTeb(IN PETHREAD Thread, OUT void **OutTeb)
Definition mmproc.c:536
FORCEINLINE void InitializeListHead(PDOUBLY_LINKED_LIST Head)
Definition ms.h:223
FORCEINLINE void InsertTailList(PDOUBLY_LINKED_LIST Head, PDOUBLY_LINKED_LIST Entry)
Definition ms.h:236
#define MT_NO_MEMORY
Definition mtstatus.h:42
#define MT_SUCCESS
Definition mtstatus.h:22
#define MT_PROCESS_IS_TERMINATING
Definition mtstatus.h:124
#define MT_NOT_IMPLEMENTED
Definition mtstatus.h:23
#define MT_FAILURE(Status)
Definition mtstatus.h:16
#define MT_INVALID_PARAM
Definition mtstatus.h:24
int32_t MTSTATUS
Definition mtstatus.h:12
#define MT_INVALID_HANDLE
Definition mtstatus.h:36
#define MT_NOT_FOUND
Definition mtstatus.h:30
MTSTATUS ObReferenceObjectByHandle(IN HANDLE Handle, IN uint32_t DesiredAccess, IN POBJECT_TYPE DesiredType, OUT void **Object, _Out_Opt PHANDLE_TABLE_ENTRY HandleInformation)
Definition ob.c:277
MTSTATUS ObCreateHandleForObjectEx(IN void *Object, IN ACCESS_MASK DesiredAccess, OUT PHANDLE ReturnedHandle, IN PHANDLE_TABLE ObjectTable)
Definition ob.c:440
void ObDereferenceObject(IN void *Object)
Definition ob.c:554
MTSTATUS ObCreateObject(IN POBJECT_TYPE ObjectType, IN uint32_t ObjectSize, OUT void **ObjectCreated)
Definition ob.c:118
FORCEINLINE void MeEnqueueThreadWithLock(Queue *queue, PETHREAD thread)
Definition ps.h:385
FORCEINLINE MTSTATUS GetExceptionCode(void)
Definition ps.h:346
struct _TEB * PTEB
void(* ThreadEntry)(THREAD_PARAMETER)
Definition ps.h:218
#define MT_THREAD_ALL_ACCESS
Definition ps.h:72
#define MT_PROCESS_CREATE_THREAD
Definition ps.h:79
@ THREAD_TERMINATING
Definition ps.h:41
@ THREAD_READY
Definition ps.h:39
FORCEINLINE bool PsIsKernelThread(IN PETHREAD Thread)
Definition ps.h:335
@ ProcessBreakOnTermination
Definition ps.h:92
void * THREAD_PARAMETER
Definition ps.h:217
POBJECT_TYPE PsThreadType
Definition psmgr.c:31
POBJECT_TYPE PsProcessType
Definition psmgr.c:30
void PsDeferKernelStackDeletion(void *StackBase, bool IsLarge)
Definition pswork.c:65
void MsAcquirePushLockExclusive(IN PUSH_LOCK *Lock)
Definition pushlock.c:80
void MsReleasePushLockExclusive(IN PUSH_LOCK *Lock)
Definition pushlock.c:99
bool MsAcquireRundownProtection(IN PRUNDOWN_REF rundown)
Definition rundown.c:8
void MsReleaseRundownProtection(IN PRUNDOWN_REF rundown)
Definition rundown.c:41
void MsWaitForRundownProtectionRelease(IN PRUNDOWN_REF rundown)
Definition rundown.c:64
NORETURN void Schedule(void)
Definition scheduler.c:110
EPROCESS PsInitialSystemProcess
Definition kernel.c:165
bool AttachedToProcess
Definition me.h:255
PEPROCESS SavedApcProcess
Definition me.h:254
struct _DOUBLY_LINKED_LIST * Blink
Definition core.h:30
struct _DOUBLY_LINKED_LIST * Flink
Definition core.h:31
uint32_t NumThreads
Definition ps.h:166
struct _RUNDOWN_REF ProcessRundown
Definition ps.h:159
HANDLE PID
Definition ps.h:148
PHANDLE_TABLE ObjectTable
Definition ps.h:171
PPEB Peb
Definition ps.h:154
PUSH_LOCK ThreadListLock
Definition ps.h:164
enum _PROCESS_FLAGS Flags
Definition ps.h:174
struct _ETHREAD * MainThread
Definition ps.h:163
struct _IPROCESS InternalProcess
Definition ps.h:146
DOUBLY_LINKED_LIST AllThreads
Definition ps.h:165
struct _RUNDOWN_REF ThreadRundown
Definition ps.h:193
struct _EPROCESS * ParentProcess
Definition ps.h:190
struct _ITHREAD InternalThread
Definition ps.h:183
HANDLE PID
Definition ps.h:188
HANDLE TID
Definition ps.h:187
bool SystemThread
Definition ps.h:200
bool WorkerThread
Definition ps.h:201
MTSTATUS ExitStatus
Definition ps.h:195
struct _EVENT * CurrentEvent
Definition ps.h:189
struct _DOUBLY_LINKED_LIST ThreadListEntry
Definition ps.h:191
uint32_t ThreadState
Definition me.h:268
void * StackBase
Definition me.h:269
bool IsLargeStack
Definition me.h:270
enum _TimeSliceTicks TimeSlice
Definition me.h:272
void * KernelStack
Definition me.h:271
struct _TRAP_FRAME TrapRegisters
Definition me.h:267
enum _TimeSliceTicks TimeSliceAllocated
Definition me.h:273
struct _APC_STATE ApcState
Definition me.h:275
void * StackBase
Definition ps.h:120
void * StackLimit
Definition ps.h:121
uint64_t UniqueProcessId
Definition ps.h:126
MT_TIB MtTib
Definition ps.h:125
uint64_t UniqueThreadId
Definition ps.h:127
uint64_t ss
Definition me.h:164
uint64_t rdi
Definition me.h:157
uint64_t rdx
Definition me.h:157
uint64_t rsp
Definition me.h:163
uint64_t rip
Definition me.h:160
uint64_t rcx
Definition me.h:157
uint64_t rflags
Definition me.h:162
uint64_t rsi
Definition me.h:157
uint64_t cs
Definition me.h:161
NORETURN void PspExitThread(IN MTSTATUS ExitStatus)
Definition thread.c:335
MTSTATUS PsTerminateThread(IN PETHREAD Thread, IN MTSTATUS ExitStatus)
Definition thread.c:284
MTSTATUS PsCreateThread(HANDLE ProcessHandle, PHANDLE ThreadHandle, ThreadEntry EntryPoint, THREAD_PARAMETER ThreadParameter, TimeSliceTicks TimeSlice, ThreadEntry MtdllEntrypoint)
Definition thread.c:38
PETHREAD PsGetCurrentThread(void)
Definition thread.c:279
MTSTATUS PsCreateSystemThread(ThreadEntry entry, THREAD_PARAMETER parameter, TimeSliceTicks TIMESLICE, _Out_Opt PETHREAD *OutThread)
Definition thread.c:196
void PsDeleteThread(IN void *Object)
Definition thread.c:305