ReactOS  0.4.13-dev-241-g63286c6
process.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: lib/rtl/process.c
5  * PURPOSE: Process functions
6  * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7  * Ariadne (ariadne@xs4all.nl)
8  * Eric Kohl
9  */
10 
11 /* INCLUDES ****************************************************************/
12 
13 #include <rtl.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 /* INTERNAL FUNCTIONS *******************************************************/
19 
21 NTAPI
24  PHANDLE Section)
25 {
28  HANDLE hFile = NULL;
30 
31  /* Open the Image File */
33  ImageFileName,
35  NULL,
36  NULL);
43  if (!NT_SUCCESS(Status))
44  {
45  DPRINT1("Failed to read image file from disk, Status = 0x%08X\n", Status);
46  return Status;
47  }
48 
49  /* Now create a section for this image */
50  Status = ZwCreateSection(Section,
52  NULL,
53  NULL,
55  SEC_IMAGE,
56  hFile);
57  if (!NT_SUCCESS(Status))
58  {
59  DPRINT1("Failed to create section for image file, Status = 0x%08X\n", Status);
60  }
61 
62  ZwClose(hFile);
63  return Status;
64 }
65 
66 /* FUNCTIONS ****************************************************************/
67 
69 NTAPI
71  PPEB Peb,
72  PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
73 {
76  SIZE_T EnviroSize;
77  SIZE_T Size;
79  DPRINT("RtlpInitEnvironment(ProcessHandle: %p, Peb: %p Params: %p)\n",
80  ProcessHandle, Peb, ProcessParameters);
81 
82  /* Give the caller 1MB if he requested it */
83  if (ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB)
84  {
85  /* Give 1MB starting at 0x4 */
86  BaseAddress = (PVOID)4;
87  EnviroSize = (1024 * 1024) - 256;
88  Status = ZwAllocateVirtualMemory(ProcessHandle,
89  &BaseAddress,
90  0,
91  &EnviroSize,
94  if (!NT_SUCCESS(Status))
95  {
96  DPRINT1("Failed to reserve 1MB of space \n");
97  return Status;
98  }
99  }
100 
101  /* Find the end of the Enviroment Block */
102  if ((Environment = (PWCHAR)ProcessParameters->Environment))
103  {
104  while (*Environment++) while (*Environment++);
105 
106  /* Calculate the size of the block */
107  EnviroSize = (ULONG)((ULONG_PTR)Environment -
108  (ULONG_PTR)ProcessParameters->Environment);
109 
110  /* Allocate and Initialize new Environment Block */
111  Size = EnviroSize;
112  Status = ZwAllocateVirtualMemory(ProcessHandle,
113  &BaseAddress,
114  0,
115  &Size,
118  if (!NT_SUCCESS(Status))
119  {
120  DPRINT1("Failed to allocate Environment Block\n");
121  return Status;
122  }
123 
124  /* Write the Environment Block */
126  BaseAddress,
127  ProcessParameters->Environment,
128  EnviroSize,
129  NULL);
130 
131  /* Save pointer */
132  ProcessParameters->Environment = BaseAddress;
133  }
134 
135  /* Now allocate space for the Parameter Block */
136  BaseAddress = NULL;
137  Size = ProcessParameters->MaximumLength;
138  Status = ZwAllocateVirtualMemory(ProcessHandle,
139  &BaseAddress,
140  0,
141  &Size,
142  MEM_COMMIT,
144  if (!NT_SUCCESS(Status))
145  {
146  DPRINT1("Failed to allocate Parameter Block\n");
147  return Status;
148  }
149 
150  /* Write the Parameter Block */
152  BaseAddress,
153  ProcessParameters,
154  ProcessParameters->Length,
155  NULL);
156  if (!NT_SUCCESS(Status))
157  {
158  DPRINT1("Failed to write the Parameter Block\n");
159  return Status;
160  }
161 
162  /* Write pointer to Parameter Block */
165  &BaseAddress,
166  sizeof(BaseAddress),
167  NULL);
168  if (!NT_SUCCESS(Status))
169  {
170  DPRINT1("Failed to write pointer to Parameter Block\n");
171  return Status;
172  }
173 
174  /* Return */
175  return STATUS_SUCCESS;
176 }
177 
178 /*
179  * @implemented
180  *
181  * Creates a process and its initial thread.
182  *
183  * NOTES:
184  * - The first thread is created suspended, so it needs a manual resume!!!
185  * - If ParentProcess is NULL, current process is used
186  * - ProcessParameters must be normalized
187  * - Attributes are object attribute flags used when opening the ImageFileName.
188  * Valid flags are OBJ_INHERIT and OBJ_CASE_INSENSITIVE.
189  *
190  * -Gunnar
191  */
192 NTSTATUS
193 NTAPI
196  IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
197  IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
198  IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
199  IN HANDLE ParentProcess OPTIONAL,
200  IN BOOLEAN InheritHandles,
201  IN HANDLE DebugPort OPTIONAL,
202  IN HANDLE ExceptionPort OPTIONAL,
204 {
207  PROCESS_BASIC_INFORMATION ProcessBasicInfo;
210  DPRINT("RtlCreateUserProcess: %wZ\n", ImageFileName);
211 
212  /* Map and Load the File */
213  Status = RtlpMapFile(ImageFileName,
214  Attributes,
215  &hSection);
216  if (!NT_SUCCESS(Status))
217  {
218  DPRINT1("Could not map process image\n");
219  return Status;
220  }
221 
222  /* Clean out the current directory handle if we won't use it */
223  if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL;
224 
225  /* Use us as parent if none other specified */
226  if (!ParentProcess) ParentProcess = NtCurrentProcess();
227 
228  /* Initialize the Object Attributes */
230  NULL,
231  0,
232  NULL,
233  ProcessSecurityDescriptor);
234 
235  /*
236  * If FLG_ENABLE_CSRDEBUG is used, then CSRSS is created under the
237  * watch of WindowsSS
238  */
240  (wcsstr(ImageFileName->Buffer, L"csrss")))
241  {
242  ObjectAttributes.ObjectName = &DebugString;
243  }
244 
245  /* Create Kernel Process Object */
246  Status = ZwCreateProcess(&ProcessInfo->ProcessHandle,
249  ParentProcess,
250  InheritHandles,
251  hSection,
252  DebugPort,
253  ExceptionPort);
254  if (!NT_SUCCESS(Status))
255  {
256  DPRINT1("Could not create Kernel Process Object\n");
257  ZwClose(hSection);
258  return Status;
259  }
260 
261  /* Get some information on the image */
264  &ProcessInfo->ImageInformation,
266  NULL);
267  if (!NT_SUCCESS(Status))
268  {
269  DPRINT1("Could not query Section Info\n");
270  ZwClose(ProcessInfo->ProcessHandle);
271  ZwClose(hSection);
272  return Status;
273  }
274 
275  /* Get some information about the process */
276  Status = ZwQueryInformationProcess(ProcessInfo->ProcessHandle,
278  &ProcessBasicInfo,
279  sizeof(ProcessBasicInfo),
280  NULL);
281  if (!NT_SUCCESS(Status))
282  {
283  DPRINT1("Could not query Process Info\n");
284  ZwClose(ProcessInfo->ProcessHandle);
285  ZwClose(hSection);
286  return Status;
287  }
288 
289  /* Duplicate the standard handles */
291  _SEH2_TRY
292  {
293  if (ProcessParameters->StandardInput)
294  {
295  Status = ZwDuplicateObject(ParentProcess,
296  ProcessParameters->StandardInput,
297  ProcessInfo->ProcessHandle,
298  &ProcessParameters->StandardInput,
299  0,
300  0,
303  if (!NT_SUCCESS(Status))
304  {
305  _SEH2_LEAVE;
306  }
307  }
308 
309  if (ProcessParameters->StandardOutput)
310  {
311  Status = ZwDuplicateObject(ParentProcess,
312  ProcessParameters->StandardOutput,
313  ProcessInfo->ProcessHandle,
314  &ProcessParameters->StandardOutput,
315  0,
316  0,
319  if (!NT_SUCCESS(Status))
320  {
321  _SEH2_LEAVE;
322  }
323  }
324 
325  if (ProcessParameters->StandardError)
326  {
327  Status = ZwDuplicateObject(ParentProcess,
328  ProcessParameters->StandardError,
329  ProcessInfo->ProcessHandle,
330  &ProcessParameters->StandardError,
331  0,
332  0,
335  if (!NT_SUCCESS(Status))
336  {
337  _SEH2_LEAVE;
338  }
339  }
340  }
342  {
343  if (!NT_SUCCESS(Status))
344  {
345  ZwClose(ProcessInfo->ProcessHandle);
346  ZwClose(hSection);
347  }
348  }
349  _SEH2_END;
350 
351  if (!NT_SUCCESS(Status))
352  return Status;
353 
354  /* Create Process Environment */
355  Status = RtlpInitEnvironment(ProcessInfo->ProcessHandle,
356  ProcessBasicInfo.PebBaseAddress,
357  ProcessParameters);
358  if (!NT_SUCCESS(Status))
359  {
360  DPRINT1("Could not Create Process Environment\n");
361  ZwClose(ProcessInfo->ProcessHandle);
362  ZwClose(hSection);
363  return Status;
364  }
365 
366  /* Create the first Thread */
367  Status = RtlCreateUserThread(ProcessInfo->ProcessHandle,
368  ThreadSecurityDescriptor,
369  TRUE,
370  ProcessInfo->ImageInformation.ZeroBits,
371  ProcessInfo->ImageInformation.MaximumStackSize,
372  ProcessInfo->ImageInformation.CommittedStackSize,
373  ProcessInfo->ImageInformation.TransferAddress,
374  ProcessBasicInfo.PebBaseAddress,
375  &ProcessInfo->ThreadHandle,
376  &ProcessInfo->ClientId);
377  if (!NT_SUCCESS(Status))
378  {
379  DPRINT1("Could not Create Thread\n");
380  ZwClose(ProcessInfo->ProcessHandle);
381  ZwClose(hSection); /* Don't try to optimize this on top! */
382  return Status;
383  }
384 
385  /* Close the Section Handle and return */
386  ZwClose(hSection);
387  return STATUS_SUCCESS;
388 }
389 
390 /*
391  * @implemented
392  */
393 PVOID
394 NTAPI
396 {
397  ULONG Cookie;
399 
402  &Cookie,
403  sizeof(Cookie),
404  NULL);
405  if(!NT_SUCCESS(Status))
406  {
407  DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status);
408  return Pointer;
409  }
410 
411  return (PVOID)((ULONG_PTR)Pointer ^ Cookie);
412 }
413 
414 /*
415  * @implemented
416  */
417 PVOID
418 NTAPI
420 {
421  return RtlEncodePointer(Pointer);
422 }
423 
424 /*
425  * @implemented
426  */
427 PVOID
428 NTAPI
430 {
431  return (PVOID)((ULONG_PTR)Pointer ^ SharedUserData->Cookie);
432 }
433 
434 /*
435  * @implemented
436  */
437 PVOID
438 NTAPI
440 {
441  return RtlEncodeSystemPointer(Pointer);
442 }
443 
444 /*
445  * @implemented
446  *
447  * NOTES:
448  * Implementation based on the documentation from:
449  * http://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/peb/setprocessiscritical.htm
450  */
451 NTSTATUS
452 __cdecl
454  OUT PBOOLEAN OldValue OPTIONAL,
455  IN BOOLEAN NeedBreaks)
456 {
457  ULONG BreakOnTermination;
458 
459  /* Initialize to FALSE */
460  if (OldValue) *OldValue = FALSE;
461 
462  /* Fail, if the critical breaks flag is required but is not set */
463  if ((NeedBreaks) &&
465  {
466  return STATUS_UNSUCCESSFUL;
467  }
468 
469  /* Check if the caller wants the old value */
470  if (OldValue)
471  {
472  /* Query and return the old break on termination flag for the process */
475  &BreakOnTermination,
476  sizeof(ULONG),
477  NULL);
478  *OldValue = (BOOLEAN)BreakOnTermination;
479  }
480 
481  /* Set the break on termination flag for the process */
482  BreakOnTermination = NewValue;
485  &BreakOnTermination,
486  sizeof(ULONG));
487 }
488 
489 ULONG
490 NTAPI
492 {
493  /* Forward to kernel */
495 }
PVOID NTAPI RtlEncodeSystemPointer(IN PVOID Pointer)
Definition: process.c:429
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:45
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI RtlpMapFile(PUNICODE_STRING ImageFileName, ULONG Attributes, PHANDLE Section)
Definition: process.c:22
PPEB Peb
Definition: dllmain.c:27
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
#define __cdecl
Definition: accygwin.h:79
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
PVOID NTAPI RtlDecodePointer(IN PVOID Pointer)
Definition: process.c:419
LONG NTSTATUS
Definition: precomp.h:26
#define FLG_ENABLE_CSRDEBUG
Definition: pstypes.h:72
uint16_t * PWCHAR
Definition: typedefs.h:54
#define FLG_ENABLE_SYSTEM_CRIT_BREAKS
Definition: pstypes.h:78
#define MEM_COMMIT
Definition: nt_native.h:1313
#define FILE_SHARE_READ
Definition: compat.h:125
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS NTAPI RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, IN ULONG Attributes, IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters, IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL, IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL, IN HANDLE ParentProcess OPTIONAL, IN BOOLEAN InheritHandles, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, OUT PRTL_USER_PROCESS_INFORMATION ProcessInfo)
Definition: process.c:194
ULONG NTAPI NtGetCurrentProcessorNumber(VOID)
Definition: sysinfo.c:2973
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define DUPLICATE_SAME_ACCESS
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FILE_READ_DATA
Definition: nt_native.h:628
#define MEM_RESERVE
Definition: nt_native.h:1314
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define PAGE_EXECUTE
Definition: nt_native.h:1306
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
void DPRINT(...)
Definition: polytest.cpp:61
NTSYSAPI NTSTATUS NTAPI ZwWriteVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _In_ PVOID Buffer, _In_ SIZE_T NumberOfBytesToWrite, _Out_opt_ PSIZE_T NumberOfBytesWritten)
PVOID NTAPI RtlEncodePointer(IN PVOID Pointer)
Definition: process.c:395
NTSTATUS __cdecl RtlSetProcessIsCritical(IN BOOLEAN NewValue, OUT PBOOLEAN OldValue OPTIONAL, IN BOOLEAN NeedBreaks)
Definition: process.c:453
#define NtCurrentProcess()
Definition: nt_native.h:1657
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB
Definition: rtltypes.h:46
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_INHERIT
Definition: winternl.h:225
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
#define SharedUserData
char * PBOOLEAN
Definition: retypes.h:11
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1851
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(_In_ PVOID ThreadContext, _Out_ HANDLE *OutThreadHandle, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2, _Reserved_ PVOID Reserved3, _Reserved_ PVOID Reserved4, _Reserved_ PVOID Reserved5, _Reserved_ PVOID Reserved6, _Reserved_ PVOID Reserved7, _Reserved_ PVOID Reserved8)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define SYNCHRONIZE
Definition: nt_native.h:61
_In_ HANDLE hFile
Definition: mswsock.h:90
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
static ULONG
Definition: process.c:83
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
_SEH2_END
Definition: create.c:4424
#define NtCurrentPeb()
Definition: FLS.c:19
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
_SEH2_FINALLY
Definition: create.c:4395
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
ULONG NTAPI RtlGetCurrentProcessorNumber(VOID)
Definition: process.c:491
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI NTSTATUS NTAPI ZwQuerySection(_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T Length, _Out_opt_ PSIZE_T ResultLength)
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
static PVOID
Definition: process.c:83
#define ULONG_PTR
Definition: config.h:101
#define SEC_IMAGE
Definition: mmtypes.h:96
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
CCHAR DebugString[256]
Definition: cmdline.c:22
NTSYSAPI NTSTATUS NTAPI ZwCreateProcess(_Out_ PHANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ HANDLE ParentProcess, _In_ BOOLEAN InheritObjectTable, _In_opt_ HANDLE SectionHandle, _In_opt_ HANDLE DebugPort, _In_opt_ HANDLE ExceptionPort)
#define _SEH2_LEAVE
Definition: filesup.c:20
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSTATUS NTAPI RtlpInitEnvironment(HANDLE ProcessHandle, PPEB Peb, PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
Definition: process.c:70
return STATUS_SUCCESS
Definition: btrfs.c:2745
ULONG NtGlobalFlag
Definition: init.c:51
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3217
ULONG NTAPI RtlGetNtGlobalFlags(VOID)
Definition: libsupp.c:93
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
NTSYSAPI NTSTATUS NTAPI ZwSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)