3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/ntdll/rtl/process.c
6 * PURPOSE: Process functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
12 /* INCLUDES ****************************************************************/
19 /* INTERNAL FUNCTIONS *******************************************************/
23 RtlpMapFile(PUNICODE_STRING ImageFileName
,
27 OBJECT_ATTRIBUTES ObjectAttributes
;
30 IO_STATUS_BLOCK IoStatusBlock
;
32 /* Open the Image File */
33 InitializeObjectAttributes(&ObjectAttributes
,
35 Attributes
& (OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
),
38 Status
= ZwOpenFile(&hFile
,
39 SYNCHRONIZE
| FILE_EXECUTE
| FILE_READ_DATA
,
42 FILE_SHARE_DELETE
| FILE_SHARE_READ
,
43 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
);
44 if (!NT_SUCCESS(Status
))
46 DPRINT1("Failed to read image file from disk\n");
50 /* Now create a section for this image */
51 Status
= ZwCreateSection(Section
,
58 if (!NT_SUCCESS(Status
))
60 DPRINT1("Failed to create section for image file\n");
67 /* FUNCTIONS ****************************************************************/
71 RtlpInitEnvironment(HANDLE ProcessHandle
,
73 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
)
76 PVOID BaseAddress
= NULL
;
79 PWCHAR Environment
= 0;
81 DPRINT("RtlpInitEnvironment (hProcess: %lx, Peb: %p Params: %p)\n",
82 ProcessHandle
, Peb
, ProcessParameters
);
84 /* Give the caller 1MB if he requested it */
85 if (ProcessParameters
->Flags
& PPF_RESERVE_1MB
)
87 /* Give 1MB starting at 0x4 */
88 BaseAddress
= (PVOID
)4;
89 EnviroSize
= 1024 * 1024;
90 Status
= ZwAllocateVirtualMemory(ProcessHandle
,
96 if (!NT_SUCCESS(Status
))
98 DPRINT1("Failed to reserve 1MB of space \n");
103 /* Find the end of the Enviroment Block */
104 if ((Environment
= (PWCHAR
)ProcessParameters
->Environment
))
106 while (*Environment
++) while (*Environment
++);
108 /* Calculate the size of the block */
109 EnviroSize
= (ULONG
)((ULONG_PTR
)Environment
-
110 (ULONG_PTR
)ProcessParameters
->Environment
);
111 DPRINT("EnvironmentSize %ld\n", EnviroSize
);
113 /* Allocate and Initialize new Environment Block */
115 Status
= ZwAllocateVirtualMemory(ProcessHandle
,
119 MEM_RESERVE
| MEM_COMMIT
,
121 if (!NT_SUCCESS(Status
))
123 DPRINT1("Failed to allocate Environment Block\n");
127 /* Write the Environment Block */
128 ZwWriteVirtualMemory(ProcessHandle
,
130 ProcessParameters
->Environment
,
135 ProcessParameters
->Environment
= BaseAddress
;
138 DPRINT("EnvironmentPointer %p\n", BaseAddress
);
139 DPRINT("Ppb->MaximumLength %x\n", ProcessParameters
->MaximumLength
);
141 /* Now allocate space for the Parameter Block */
143 Size
= ProcessParameters
->MaximumLength
;
144 Status
= ZwAllocateVirtualMemory(ProcessHandle
,
150 if (!NT_SUCCESS(Status
))
152 DPRINT1("Failed to allocate Parameter Block\n");
156 /* Write the Parameter Block */
157 ZwWriteVirtualMemory(ProcessHandle
,
160 ProcessParameters
->Length
,
163 /* Write pointer to Parameter Block */
164 ZwWriteVirtualMemory(ProcessHandle
,
165 &Peb
->ProcessParameters
,
171 return STATUS_SUCCESS
;
177 * Creates a process and its initial thread.
180 * - The first thread is created suspended, so it needs a manual resume!!!
181 * - If ParentProcess is NULL, current process is used
182 * - ProcessParameters must be normalized
183 * - Attributes are object attribute flags used when opening the ImageFileName.
184 * Valid flags are OBJ_INHERIT and OBJ_CASE_INSENSITIVE.
190 RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName
,
192 IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters
,
193 IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL
,
194 IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL
,
195 IN HANDLE ParentProcess OPTIONAL
,
196 IN BOOLEAN InheritHandles
,
197 IN HANDLE DebugPort OPTIONAL
,
198 IN HANDLE ExceptionPort OPTIONAL
,
199 OUT PRTL_USER_PROCESS_INFORMATION ProcessInfo
)
203 PROCESS_BASIC_INFORMATION ProcessBasicInfo
;
204 OBJECT_ATTRIBUTES ObjectAttributes
;
206 DPRINT("RtlCreateUserProcess: %wZ\n", ImageFileName
);
208 /* Map and Load the File */
209 Status
= RtlpMapFile(ImageFileName
,
212 if(!NT_SUCCESS(Status
))
214 DPRINT1("Could not map process image\n");
218 /* Clean out the CurDir Handle if we won't use it */
219 if (!InheritHandles
) ProcessParameters
->CurrentDirectory
.Handle
= NULL
;
221 /* Use us as parent if none other specified */
222 if (!ParentProcess
) ParentProcess
= NtCurrentProcess();
224 /* Initialize the Object Attributes */
225 InitializeObjectAttributes(&ObjectAttributes
,
229 ProcessSecurityDescriptor
);
232 * If FLG_ENABLE_CSRDEBUG is used, then CSRSS is created under the
235 if ((RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG
) &&
236 (wcsstr(ImageFileName
->Buffer
, L
"csrss")))
238 UNICODE_STRING DebugString
= RTL_CONSTANT_STRING(L
"\\WindowsSS");
239 InitializeObjectAttributes(&ObjectAttributes
,
243 ProcessSecurityDescriptor
);
247 /* Create Kernel Process Object */
248 Status
= ZwCreateProcess(&ProcessInfo
->ProcessHandle
,
256 if (!NT_SUCCESS(Status
))
258 DPRINT1("Could not create Kernel Process Object\n");
263 /* Get some information on the image */
264 Status
= ZwQuerySection(hSection
,
265 SectionImageInformation
,
266 &ProcessInfo
->ImageInformation
,
267 sizeof(SECTION_IMAGE_INFORMATION
),
269 if (!NT_SUCCESS(Status
))
271 DPRINT1("Could not query Section Info\n");
272 ZwClose(ProcessInfo
->ProcessHandle
);
277 /* Get some information about the process */
278 ZwQueryInformationProcess(ProcessInfo
->ProcessHandle
,
279 ProcessBasicInformation
,
281 sizeof(ProcessBasicInfo
),
283 if (!NT_SUCCESS(Status
))
285 DPRINT1("Could not query Process Info\n");
286 ZwClose(ProcessInfo
->ProcessHandle
);
291 /* Create Process Environment */
292 RtlpInitEnvironment(ProcessInfo
->ProcessHandle
,
293 ProcessBasicInfo
.PebBaseAddress
,
296 /* Create the first Thread */
297 Status
= RtlCreateUserThread(ProcessInfo
->ProcessHandle
,
298 ThreadSecurityDescriptor
,
300 ProcessInfo
->ImageInformation
.ZeroBits
,
301 ProcessInfo
->ImageInformation
.MaximumStackSize
,
302 ProcessInfo
->ImageInformation
.CommittedStackSize
,
303 ProcessInfo
->ImageInformation
.TransferAddress
,
304 ProcessBasicInfo
.PebBaseAddress
,
305 &ProcessInfo
->ThreadHandle
,
306 &ProcessInfo
->ClientId
);
307 if (!NT_SUCCESS(Status
))
309 DPRINT1("Could not Create Thread\n");
310 ZwClose(ProcessInfo
->ProcessHandle
);
311 ZwClose(hSection
); /* Don't try to optimize this on top! */
315 /* Close the Section Handle and return */
317 return STATUS_SUCCESS
;