ReactOS  0.4.15-dev-2993-g14fbe80
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 }
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420

◆ 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 {
229  HANDLE Handle;
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
275  NtClose(Handle);
276  if (ClientId) *ClientId = ThreadCid;
277  }
278 
279  /* Return success or the previous failure */
280  return Status;
281 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
_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:182
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RtlInitializeContext(IN HANDLE ProcessHandle, OUT PCONTEXT ThreadContext, IN PVOID ThreadStartParam OPTIONAL, IN PTHREAD_START_ROUTINE ThreadStartAddress, IN PINITIAL_TEB InitialTeb)
Definition: thread.c:27
_In_ PVOID Parameter
Definition: ldrtypes.h:241
PVOID StackBase
Definition: pstypes.h:694
Status
Definition: gdiplustypes.h:24
VOID NTAPI RtlpFreeUserStack(IN HANDLE ProcessHandle, IN PINITIAL_TEB InitialTeb)
Definition: thread.c:153
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
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
#define NULL
Definition: types.h:112
_In_ HANDLE Handle
Definition: extypes.h:390
struct tagContext Context
Definition: acpixf.h:1034
#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)

◆ 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
#define NtCurrentThread()
Status
Definition: gdiplustypes.h:24
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
NTSTATUS NTAPI LdrShutdownThread(VOID)
Definition: ldrinit.c:1078

◆ 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,
315  sizeof(THREAD_BASIC_INFORMATION),
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 }
LONG NTSTATUS
Definition: precomp.h:26
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2624
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2805
ULONG_PTR SIZE_T
Definition: typedefs.h:80
Definition: compat.h:694
#define NULL
Definition: types.h:112
#define MEM_RELEASE
Definition: nt_native.h:1316
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5204

◆ 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,
119  MEM_COMMIT,
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 ROUND_UP(n, align)
Definition: eventvwr.h:31
#define TRUE
Definition: types.h:120
#define PAGE_GUARD
Definition: nt_native.h:1310
LONG NTSTATUS
Definition: precomp.h:26
static PVOID
Definition: thread.c:78
#define MEM_COMMIT
Definition: nt_native.h:1313
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define FALSE
Definition: types.h:117
#define MEM_RESERVE
Definition: nt_native.h:1314
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
unsigned char BOOLEAN
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
SYSTEM_BASIC_INFORMATION SystemBasicInfo
Definition: perfdata.c:45
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define NtCurrentPeb()
Definition: FLS.c:22
#define NULL
Definition: types.h:112
#define RtlImageNtHeader
Definition: compat.h:665
#define MEM_RELEASE
Definition: nt_native.h:1316
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
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

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,
162  MEM_RELEASE);
163 
164  /* Clear the initial TEB */
165  RtlZeroMemory(InitialTeb, sizeof(*InitialTeb));
166 }
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define MEM_RELEASE
Definition: nt_native.h:1316
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403

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 {
351  return STATUS_NOT_IMPLEMENTED;
352 }
return STATUS_NOT_IMPLEMENTED
#define UNIMPLEMENTED
Definition: debug.h:115

◆ 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 }
#define NtCurrentThread()
#define FLG_ENABLE_SYSTEM_CRIT_BREAKS
Definition: pstypes.h:78
#define FALSE
Definition: types.h:117
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define NtCurrentPeb()
Definition: FLS.c:22
#define NULL
Definition: types.h:112
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_ PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
#define BOOLEAN
Definition: pedump.c:73
unsigned int ULONG
Definition: retypes.h:1
ULONG NtGlobalFlag
Definition: init.c:52