ReactOS 0.4.15-dev-7934-g1dc8d80
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
24 PHANDLE Section)
25{
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,
56 hFile);
57 if (!NT_SUCCESS(Status))
58 {
59 DPRINT1("Failed to create section for image file, Status = 0x%08X\n", Status);
60 }
61
63 return Status;
64}
65
66/* FUNCTIONS ****************************************************************/
67
71 PPEB Peb,
72 PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
73{
76 SIZE_T EnviroSize;
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,
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,
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 */
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 */
137 Size = ProcessParameters->MaximumLength;
138 Status = ZwAllocateVirtualMemory(ProcessHandle,
140 0,
141 &Size,
144 if (!NT_SUCCESS(Status))
145 {
146 DPRINT1("Failed to allocate Parameter Block\n");
147 return Status;
148 }
149
150 /* Write the Parameter Block */
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 */
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 */
193NTAPI
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,
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");
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);
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);
286 return Status;
287 }
288
289 /* Duplicate the standard handles */
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 {
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 {
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 {
338 }
339 }
340 }
342 {
343 if (!NT_SUCCESS(Status))
344 {
345 ZwClose(ProcessInfo->ProcessHandle);
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);
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 */
387 return STATUS_SUCCESS;
388}
389
390/*
391 * @implemented
392 */
393PVOID
394NTAPI
396{
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 */
417PVOID
418NTAPI
420{
421 return RtlEncodePointer(Pointer);
422}
423
424/*
425 * @implemented
426 */
427PVOID
428NTAPI
430{
431 return (PVOID)((ULONG_PTR)Pointer ^ SharedUserData->Cookie);
432}
433
434/*
435 * @implemented
436 */
437PVOID
438NTAPI
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 */
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
489ULONG
490NTAPI
492{
493 /* Forward to kernel */
495}
496
498ULONG
499NTAPI
500RtlRosGetAppcompatVersion(VOID)
501{
502 /* Get the current PEB */
504 if (Peb == NULL)
505 {
506 /* Default to Server 2003 */
507 return _WIN32_WINNT_WS03;
508 }
509
510 /* Calculate OS version from PEB fields */
511 return (Peb->OSMajorVersion << 8) | Peb->OSMinorVersion;
512}
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
#define __cdecl
Definition: accygwin.h:79
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
CCHAR DebugString[256]
Definition: cmdline.c:22
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_SHARE_READ
Definition: compat.h:136
PPEB Peb
Definition: dllmain.c:27
#define ULONG_PTR
Definition: config.h:101
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define FLG_ENABLE_SYSTEM_CRIT_BREAKS
Definition: pstypes.h:78
#define FLG_ENABLE_CSRDEBUG
Definition: pstypes.h:72
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ ProcessBreakOnTermination
Definition: winternl.h:398
@ ProcessBasicInformation
Definition: winternl.h:394
#define OBJ_INHERIT
Definition: winternl.h:225
NTSYSAPI ULONG WINAPI NtGetCurrentProcessorNumber(void)
Definition: sysinfo.c:3055
@ ProcessCookie
Definition: winternl.h:891
NTSYSAPI PEB *WINAPI RtlGetCurrentPeb(void)
Definition: libsupp.c:63
NTSYSAPI ULONG WINAPI RtlGetNtGlobalFlags(void)
Definition: libsupp.c:93
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:47
static ULONG
Definition: process.c:83
static PVOID
Definition: process.c:83
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE hFile
Definition: mswsock.h:90
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)
NTSYSAPI NTSTATUS NTAPI ZwQuerySection(_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T Length, _Out_opt_ PSIZE_T ResultLength)
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSYSAPI NTSTATUS NTAPI ZwWriteVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _In_ PVOID Buffer, _In_ SIZE_T NumberOfBytesToWrite, _Out_opt_ PSIZE_T NumberOfBytesWritten)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define SEC_IMAGE
Definition: mmtypes.h:97
@ SectionImageInformation
Definition: mmtypes.h:196
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
NTSYSAPI NTSTATUS NTAPI ZwSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
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)
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
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)
#define RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB
Definition: rtltypes.h:46
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MEM_COMMIT
Definition: nt_native.h:1313
ULONG NtGlobalFlag
Definition: init.c:54
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
#define BOOLEAN
Definition: pedump.c:73
#define SharedUserData
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
PVOID NTAPI RtlEncodeSystemPointer(IN PVOID Pointer)
Definition: process.c:429
NTSTATUS __cdecl RtlSetProcessIsCritical(IN BOOLEAN NewValue, OUT PBOOLEAN OldValue OPTIONAL, IN BOOLEAN NeedBreaks)
Definition: process.c:453
NTSTATUS NTAPI RtlpMapFile(PUNICODE_STRING ImageFileName, ULONG Attributes, PHANDLE Section)
Definition: process.c:22
NTSTATUS NTAPI RtlpInitEnvironment(HANDLE ProcessHandle, PPEB Peb, PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
Definition: process.c:70
PVOID NTAPI RtlDecodePointer(IN PVOID Pointer)
Definition: process.c:419
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
PVOID NTAPI RtlEncodePointer(IN PVOID Pointer)
Definition: process.c:395
ULONG NTAPI RtlGetCurrentProcessorNumber(VOID)
Definition: process.c:491
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
ULONG OSMinorVersion
Definition: ntddk_ex.h:301
ULONG OSMajorVersion
Definition: ntddk_ex.h:300
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3239
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14
#define DUPLICATE_SAME_ACCESS