ReactOS 0.4.15-dev-7918-g2a2556c
thread.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for thread.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI RtlpCreateUserStack (IN HANDLE ProcessHandle, IN SIZE_T StackReserve OPTIONAL, IN SIZE_T StackCommit OPTIONAL, IN ULONG StackZeroBits OPTIONAL, OUT PINITIAL_TEB InitialTeb)
 
VOID NTAPI RtlpFreeUserStack (IN HANDLE ProcessHandle, IN PINITIAL_TEB InitialTeb)
 
NTSTATUS __cdecl RtlSetThreadIsCritical (IN BOOLEAN NewValue, OUT PBOOLEAN OldValue OPTIONAL, IN BOOLEAN NeedBreaks)
 
NTSTATUS NTAPI RtlCreateUserThread (IN HANDLE ProcessHandle, IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN BOOLEAN CreateSuspended, IN ULONG StackZeroBits OPTIONAL, IN SIZE_T StackReserve OPTIONAL, IN SIZE_T StackCommit OPTIONAL, IN PTHREAD_START_ROUTINE StartAddress, IN PVOID Parameter OPTIONAL, OUT PHANDLE ThreadHandle OPTIONAL, OUT PCLIENT_ID ClientId OPTIONAL)
 
VOID NTAPI RtlExitUserThread (NTSTATUS Status)
 
VOID NTAPI RtlFreeUserThreadStack (HANDLE ProcessHandle, HANDLE ThreadHandle)
 
PTEB NTAPI _NtCurrentTeb (VOID)
 
NTSTATUS NTAPI RtlRemoteCall (IN HANDLE Process, IN HANDLE Thread, IN PVOID CallSite, IN ULONG ArgumentCount, IN PULONG Arguments, IN BOOLEAN PassContext, IN BOOLEAN AlreadySuspended)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file thread.c.

Function Documentation

◆ _NtCurrentTeb()

PTEB NTAPI _NtCurrentTeb ( VOID  )

Definition at line 334 of file thread.c.

335{
336 /* Return the TEB */
337 return NtCurrentTeb();
338}
#define NtCurrentTeb

◆ RtlCreateUserThread()

NTSTATUS NTAPI RtlCreateUserThread ( IN HANDLE  ProcessHandle,
IN PSECURITY_DESCRIPTOR SecurityDescriptor  OPTIONAL,
IN BOOLEAN  CreateSuspended,
IN ULONG StackZeroBits  OPTIONAL,
IN SIZE_T StackReserve  OPTIONAL,
IN SIZE_T StackCommit  OPTIONAL,
IN PTHREAD_START_ROUTINE  StartAddress,
IN PVOID Parameter  OPTIONAL,
OUT PHANDLE ThreadHandle  OPTIONAL,
OUT PCLIENT_ID ClientId  OPTIONAL 
)

Definition at line 217 of file thread.c.

227{
230 CLIENT_ID ThreadCid;
231 INITIAL_TEB InitialTeb;
234
235 /* First, we'll create the Stack */
237 StackReserve,
238 StackCommit,
239 StackZeroBits,
240 &InitialTeb);
241 if (!NT_SUCCESS(Status)) return Status;
242
243 /* Next, we'll set up the Initial Context */
245 &Context,
246 Parameter,
247 StartAddress,
248 InitialTeb.StackBase);
249
250 /* We are now ready to create the Kernel Thread Object */
252 NULL,
253 0,
254 NULL,
260 &ThreadCid,
261 &Context,
262 &InitialTeb,
263 CreateSuspended);
264 if (!NT_SUCCESS(Status))
265 {
266 /* Free the stack */
267 RtlpFreeUserStack(ProcessHandle, &InitialTeb);
268 }
269 else
270 {
271 /* Return thread data */
272 if (ThreadHandle)
273 *ThreadHandle = Handle;
274 else
276 if (ClientId) *ClientId = ThreadCid;
277 }
278
279 /* Return success or the previous failure */
280 return Status;
281}
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSYSAPI NTSTATUS NTAPI ZwCreateThread(_Out_ PHANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ HANDLE ProcessHandle, _Out_ PCLIENT_ID ClientId, _In_ PCONTEXT ThreadContext, _In_ PINITIAL_TEB UserStack, _In_ BOOLEAN CreateSuspended)
NTSYSAPI VOID NTAPI RtlInitializeContext(_In_ HANDLE ProcessHandle, _Out_ PCONTEXT ThreadContext, _In_opt_ PVOID ThreadStartParam, _In_ PTHREAD_START_ROUTINE ThreadStartAddress, _In_ PINITIAL_TEB InitialTeb)
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI RtlpCreateUserStack(IN HANDLE ProcessHandle, IN SIZE_T StackReserve OPTIONAL, IN SIZE_T StackCommit OPTIONAL, IN ULONG StackZeroBits OPTIONAL, OUT PINITIAL_TEB InitialTeb)
Definition: thread.c:23
VOID NTAPI RtlpFreeUserStack(IN HANDLE ProcessHandle, IN PINITIAL_TEB InitialTeb)
Definition: thread.c:153
PVOID StackBase
Definition: pstypes.h:694
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

◆ RtlExitUserThread()

VOID NTAPI RtlExitUserThread ( NTSTATUS  Status)

Definition at line 288 of file thread.c.

289{
290 /* Call the Loader and tell him to notify the DLLs */
292
293 /* Shut us down */
294 NtCurrentTeb()->FreeStackOnTermination = TRUE;
296}
#define TRUE
Definition: types.h:120
NTSYSAPI void WINAPI LdrShutdownThread(void)
Definition: ldrinit.c:1082
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1279
#define NtCurrentThread()

◆ RtlFreeUserThreadStack()

VOID NTAPI RtlFreeUserThreadStack ( HANDLE  ProcessHandle,
HANDLE  ThreadHandle 
)

Definition at line 303 of file thread.c.

305{
307 THREAD_BASIC_INFORMATION ThreadBasicInfo;
308 SIZE_T Dummy, Size = 0;
309 PVOID StackLocation;
310
311 /* Query the Basic Info */
312 Status = NtQueryInformationThread(ThreadHandle,
314 &ThreadBasicInfo,
316 NULL);
317 if (!NT_SUCCESS(Status) || !ThreadBasicInfo.TebBaseAddress) return;
318
319 /* Get the deallocation stack */
321 &((PTEB)ThreadBasicInfo.TebBaseAddress)->
322 DeallocationStack,
323 &StackLocation,
324 sizeof(PVOID),
325 &Dummy);
326 if (!NT_SUCCESS(Status) || !StackLocation) return;
327
328 /* Free it */
330}
@ ThreadBasicInformation
Definition: compat.h:935
#define MEM_RELEASE
Definition: nt_native.h:1316
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5230
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2816
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2624
Definition: compat.h:836
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

◆ RtlpCreateUserStack()

NTSTATUS NTAPI RtlpCreateUserStack ( IN HANDLE  ProcessHandle,
IN SIZE_T StackReserve  OPTIONAL,
IN SIZE_T StackCommit  OPTIONAL,
IN ULONG StackZeroBits  OPTIONAL,
OUT PINITIAL_TEB  InitialTeb 
)

Definition at line 23 of file thread.c.

28{
31 PIMAGE_NT_HEADERS Headers;
33 BOOLEAN UseGuard;
34 ULONG Dummy;
35 SIZE_T MinimumStackCommit, GuardPageSize;
36
37 /* Get some memory information */
41 NULL);
42 if (!NT_SUCCESS(Status)) return Status;
43
44 /* Use the Image Settings if we are dealing with the current Process */
46 {
47 /* Get the Image Headers */
48 Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
49 if (!Headers) return STATUS_INVALID_IMAGE_FORMAT;
50
51 /* If we didn't get the parameters, find them ourselves */
52 if (StackReserve == 0)
53 StackReserve = Headers->OptionalHeader.SizeOfStackReserve;
54 if (StackCommit == 0)
55 StackCommit = Headers->OptionalHeader.SizeOfStackCommit;
56
57 MinimumStackCommit = NtCurrentPeb()->MinimumStackCommit;
58 if ((MinimumStackCommit != 0) && (StackCommit < MinimumStackCommit))
59 {
60 StackCommit = MinimumStackCommit;
61 }
62 }
63 else
64 {
65 /* Use the System Settings if needed */
66 if (StackReserve == 0)
68 if (StackCommit == 0)
69 StackCommit = SystemBasicInfo.PageSize;
70 }
71
72 /* Check if the commit is higher than the reserve */
73 if (StackCommit >= StackReserve)
74 {
75 /* Grow the reserve beyond the commit, up to 1MB alignment */
76 StackReserve = ROUND_UP(StackCommit, 1024 * 1024);
77 }
78
79 /* Align everything to Page Size */
80 StackCommit = ROUND_UP(StackCommit, SystemBasicInfo.PageSize);
81 StackReserve = ROUND_UP(StackReserve, SystemBasicInfo.AllocationGranularity);
82
83 /* Reserve memory for the stack */
84 Stack = 0;
85 Status = ZwAllocateVirtualMemory(ProcessHandle,
86 (PVOID*)&Stack,
87 StackZeroBits,
88 &StackReserve,
91 if (!NT_SUCCESS(Status)) return Status;
92
93 /* Now set up some basic Initial TEB Parameters */
94 InitialTeb->AllocatedStackBase = (PVOID)Stack;
95 InitialTeb->StackBase = (PVOID)(Stack + StackReserve);
96 InitialTeb->PreviousStackBase = NULL;
97 InitialTeb->PreviousStackLimit = NULL;
98
99 /* Update the stack position */
100 Stack += StackReserve - StackCommit;
101
102 /* Check if we can add a guard page */
103 if (StackReserve >= StackCommit + SystemBasicInfo.PageSize)
104 {
106 StackCommit += SystemBasicInfo.PageSize;
107 UseGuard = TRUE;
108 }
109 else
110 {
111 UseGuard = FALSE;
112 }
113
114 /* Allocate memory for the stack */
115 Status = ZwAllocateVirtualMemory(ProcessHandle,
116 (PVOID*)&Stack,
117 0,
118 &StackCommit,
121 if (!NT_SUCCESS(Status))
122 {
123 GuardPageSize = 0;
124 ZwFreeVirtualMemory(ProcessHandle, (PVOID*)&Stack, &GuardPageSize, MEM_RELEASE);
125 return Status;
126 }
127
128 /* Now set the current Stack Limit */
129 InitialTeb->StackLimit = (PVOID)Stack;
130
131 /* Create a guard page if needed */
132 if (UseGuard)
133 {
134 GuardPageSize = SystemBasicInfo.PageSize;
136 (PVOID*)&Stack,
137 &GuardPageSize,
139 &Dummy);
140 if (!NT_SUCCESS(Status)) return Status;
141
142 /* Update the Stack Limit keeping in mind the Guard Page */
143 InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit +
144 GuardPageSize);
145 }
146
147 /* We are done! */
148 return STATUS_SUCCESS;
149}
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
#define FALSE
Definition: types.h:117
#define RtlImageNtHeader
Definition: compat.h:806
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
@ SystemBasicInformation
Definition: ntddk_ex.h:11
NTSYSAPI NTSTATUS NTAPI ZwProtectVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID *BaseAddress, _In_ SIZE_T *NumberOfBytesToProtect, _In_ ULONG NewAccessProtection, _Out_ PULONG OldAccessProtection)
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MEM_COMMIT
Definition: nt_native.h:1313
#define PAGE_GUARD
Definition: nt_native.h:1310
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
SYSTEM_BASIC_INFORMATION SystemBasicInfo
Definition: perfdata.c:30
#define STATUS_SUCCESS
Definition: shellext.h:65
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639

Referenced by RtlCreateUserThread().

◆ RtlpFreeUserStack()

VOID NTAPI RtlpFreeUserStack ( IN HANDLE  ProcessHandle,
IN PINITIAL_TEB  InitialTeb 
)

Definition at line 153 of file thread.c.

155{
156 SIZE_T Dummy = 0;
157
158 /* Free the Stack */
159 ZwFreeVirtualMemory(ProcessHandle,
160 &InitialTeb->AllocatedStackBase,
161 &Dummy,
163
164 /* Clear the initial TEB */
165 RtlZeroMemory(InitialTeb, sizeof(*InitialTeb));
166}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by RtlCreateUserThread().

◆ RtlRemoteCall()

NTSTATUS NTAPI RtlRemoteCall ( IN HANDLE  Process,
IN HANDLE  Thread,
IN PVOID  CallSite,
IN ULONG  ArgumentCount,
IN PULONG  Arguments,
IN BOOLEAN  PassContext,
IN BOOLEAN  AlreadySuspended 
)

Definition at line 342 of file thread.c.

349{
352}
#define UNIMPLEMENTED
Definition: debug.h:115
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ RtlSetThreadIsCritical()

NTSTATUS __cdecl RtlSetThreadIsCritical ( IN BOOLEAN  NewValue,
OUT PBOOLEAN OldValue  OPTIONAL,
IN BOOLEAN  NeedBreaks 
)

Definition at line 176 of file thread.c.

179{
180 ULONG BreakOnTermination;
181
182 /* Initialize to FALSE */
183 if (OldValue) *OldValue = FALSE;
184
185 /* Fail, if the critical breaks flag is required but is not set */
186 if ((NeedBreaks) &&
188 {
189 return STATUS_UNSUCCESSFUL;
190 }
191
192 /* Check if the caller wants the old value */
193 if (OldValue)
194 {
195 /* Query and return the old break on termination flag for the process */
198 &BreakOnTermination,
199 sizeof(ULONG),
200 NULL);
201 *OldValue = (BOOLEAN)BreakOnTermination;
202 }
203
204 /* Set the break on termination flag for the process */
205 BreakOnTermination = NewValue;
206 return ZwSetInformationThread(NtCurrentThread(),
208 &BreakOnTermination,
209 sizeof(ULONG));
210}
@ ThreadBreakOnTermination
Definition: compat.h:953
#define FLG_ENABLE_SYSTEM_CRIT_BREAKS
Definition: pstypes.h:78
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_ PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
ULONG NtGlobalFlag
Definition: init.c:54
#define BOOLEAN
Definition: pedump.c:73
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132