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)
10 /* INCLUDES ****************************************************************/
17 /* INTERNAL FUNCTIONS *******************************************************/
21 RtlpMapFile(PUNICODE_STRING ImageFileName
,
25 OBJECT_ATTRIBUTES ObjectAttributes
;
28 IO_STATUS_BLOCK IoStatusBlock
;
30 /* Open the Image File */
31 InitializeObjectAttributes(&ObjectAttributes
,
33 Attributes
& (OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
),
36 Status
= ZwOpenFile(&hFile
,
37 SYNCHRONIZE
| FILE_EXECUTE
| FILE_READ_DATA
,
40 FILE_SHARE_DELETE
| FILE_SHARE_READ
,
41 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
);
42 if (!NT_SUCCESS(Status
))
44 DPRINT1("Failed to read image file from disk\n");
48 /* Now create a section for this image */
49 Status
= ZwCreateSection(Section
,
56 if (!NT_SUCCESS(Status
))
58 DPRINT1("Failed to create section for image file\n");
65 /* FUNCTIONS ****************************************************************/
69 RtlpInitEnvironment(HANDLE ProcessHandle
,
71 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
)
74 PVOID BaseAddress
= NULL
;
77 PWCHAR Environment
= 0;
79 DPRINT("RtlpInitEnvironment (hProcess: %p, Peb: %p Params: %p)\n",
80 ProcessHandle
, Peb
, ProcessParameters
);
82 /* Give the caller 1MB if he requested it */
83 if (ProcessParameters
->Flags
& RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB
)
85 /* Give 1MB starting at 0x4 */
86 BaseAddress
= (PVOID
)4;
87 EnviroSize
= 1024 * 1024;
88 Status
= ZwAllocateVirtualMemory(ProcessHandle
,
94 if (!NT_SUCCESS(Status
))
96 DPRINT1("Failed to reserve 1MB of space \n");
101 /* Find the end of the Enviroment Block */
102 if ((Environment
= (PWCHAR
)ProcessParameters
->Environment
))
104 while (*Environment
++) while (*Environment
++);
106 /* Calculate the size of the block */
107 EnviroSize
= (ULONG
)((ULONG_PTR
)Environment
-
108 (ULONG_PTR
)ProcessParameters
->Environment
);
109 DPRINT("EnvironmentSize %ld\n", EnviroSize
);
111 /* Allocate and Initialize new Environment Block */
113 Status
= ZwAllocateVirtualMemory(ProcessHandle
,
117 MEM_RESERVE
| MEM_COMMIT
,
119 if (!NT_SUCCESS(Status
))
121 DPRINT1("Failed to allocate Environment Block\n");
125 /* Write the Environment Block */
126 ZwWriteVirtualMemory(ProcessHandle
,
128 ProcessParameters
->Environment
,
133 ProcessParameters
->Environment
= BaseAddress
;
136 DPRINT("EnvironmentPointer %p\n", BaseAddress
);
137 DPRINT("Ppb->MaximumLength 0x%lx\n", ProcessParameters
->MaximumLength
);
139 /* Now allocate space for the Parameter Block */
141 Size
= ProcessParameters
->MaximumLength
;
142 Status
= ZwAllocateVirtualMemory(ProcessHandle
,
148 if (!NT_SUCCESS(Status
))
150 DPRINT1("Failed to allocate Parameter Block\n");
154 /* Write the Parameter Block */
155 ZwWriteVirtualMemory(ProcessHandle
,
158 ProcessParameters
->Length
,
161 /* Write pointer to Parameter Block */
162 ZwWriteVirtualMemory(ProcessHandle
,
163 &Peb
->ProcessParameters
,
169 return STATUS_SUCCESS
;
175 * Creates a process and its initial thread.
178 * - The first thread is created suspended, so it needs a manual resume!!!
179 * - If ParentProcess is NULL, current process is used
180 * - ProcessParameters must be normalized
181 * - Attributes are object attribute flags used when opening the ImageFileName.
182 * Valid flags are OBJ_INHERIT and OBJ_CASE_INSENSITIVE.
188 RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName
,
190 IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters
,
191 IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL
,
192 IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL
,
193 IN HANDLE ParentProcess OPTIONAL
,
194 IN BOOLEAN InheritHandles
,
195 IN HANDLE DebugPort OPTIONAL
,
196 IN HANDLE ExceptionPort OPTIONAL
,
197 OUT PRTL_USER_PROCESS_INFORMATION ProcessInfo
)
201 PROCESS_BASIC_INFORMATION ProcessBasicInfo
;
202 OBJECT_ATTRIBUTES ObjectAttributes
;
204 DPRINT("RtlCreateUserProcess: %wZ\n", ImageFileName
);
206 /* Map and Load the File */
207 Status
= RtlpMapFile(ImageFileName
,
210 if(!NT_SUCCESS(Status
))
212 DPRINT1("Could not map process image\n");
216 /* Clean out the CurDir Handle if we won't use it */
217 if (!InheritHandles
) ProcessParameters
->CurrentDirectory
.Handle
= NULL
;
219 /* Use us as parent if none other specified */
220 if (!ParentProcess
) ParentProcess
= NtCurrentProcess();
222 /* Initialize the Object Attributes */
223 InitializeObjectAttributes(&ObjectAttributes
,
227 ProcessSecurityDescriptor
);
230 * If FLG_ENABLE_CSRDEBUG is used, then CSRSS is created under the
233 if ((RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG
) &&
234 (wcsstr(ImageFileName
->Buffer
, L
"csrss")))
236 UNICODE_STRING DebugString
= RTL_CONSTANT_STRING(L
"\\WindowsSS");
237 InitializeObjectAttributes(&ObjectAttributes
,
241 ProcessSecurityDescriptor
);
245 /* Create Kernel Process Object */
246 Status
= ZwCreateProcess(&ProcessInfo
->ProcessHandle
,
254 if (!NT_SUCCESS(Status
))
256 DPRINT1("Could not create Kernel Process Object\n");
261 /* Get some information on the image */
262 Status
= ZwQuerySection(hSection
,
263 SectionImageInformation
,
264 &ProcessInfo
->ImageInformation
,
265 sizeof(SECTION_IMAGE_INFORMATION
),
267 if (!NT_SUCCESS(Status
))
269 DPRINT1("Could not query Section Info\n");
270 ZwClose(ProcessInfo
->ProcessHandle
);
275 /* Get some information about the process */
276 ZwQueryInformationProcess(ProcessInfo
->ProcessHandle
,
277 ProcessBasicInformation
,
279 sizeof(ProcessBasicInfo
),
281 if (!NT_SUCCESS(Status
))
283 DPRINT1("Could not query Process Info\n");
284 ZwClose(ProcessInfo
->ProcessHandle
);
289 /* Create Process Environment */
290 RtlpInitEnvironment(ProcessInfo
->ProcessHandle
,
291 ProcessBasicInfo
.PebBaseAddress
,
294 /* Create the first Thread */
295 Status
= RtlCreateUserThread(ProcessInfo
->ProcessHandle
,
296 ThreadSecurityDescriptor
,
298 ProcessInfo
->ImageInformation
.ZeroBits
,
299 ProcessInfo
->ImageInformation
.MaximumStackSize
,
300 ProcessInfo
->ImageInformation
.CommittedStackSize
,
301 ProcessInfo
->ImageInformation
.TransferAddress
,
302 ProcessBasicInfo
.PebBaseAddress
,
303 &ProcessInfo
->ThreadHandle
,
304 &ProcessInfo
->ClientId
);
305 if (!NT_SUCCESS(Status
))
307 DPRINT1("Could not Create Thread\n");
308 ZwClose(ProcessInfo
->ProcessHandle
);
309 ZwClose(hSection
); /* Don't try to optimize this on top! */
313 /* Close the Section Handle and return */
315 return STATUS_SUCCESS
;
323 RtlEncodePointer(IN PVOID Pointer
)
328 Status
= ZwQueryInformationProcess(NtCurrentProcess(),
334 if(!NT_SUCCESS(Status
))
336 DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status
);
340 return (PVOID
)((ULONG_PTR
)Pointer
^ Cookie
);
349 RtlSetProcessIsCritical(
351 OUT PBOOLEAN OldValue OPTIONAL
,
352 IN BOOLEAN IsWinlogon
)