Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprocess.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS system libraries 00004 * FILE: lib/rtl/process.c 00005 * PURPOSE: Process functions 00006 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 00007 * Ariadne (ariadne@xs4all.nl) 00008 * Eric Kohl 00009 */ 00010 00011 /* INCLUDES ****************************************************************/ 00012 00013 #include <rtl.h> 00014 00015 #define NDEBUG 00016 #include <debug.h> 00017 00018 /* INTERNAL FUNCTIONS *******************************************************/ 00019 00020 NTSTATUS 00021 NTAPI 00022 RtlpMapFile(PUNICODE_STRING ImageFileName, 00023 ULONG Attributes, 00024 PHANDLE Section) 00025 { 00026 OBJECT_ATTRIBUTES ObjectAttributes; 00027 NTSTATUS Status; 00028 HANDLE hFile = NULL; 00029 IO_STATUS_BLOCK IoStatusBlock; 00030 00031 /* Open the Image File */ 00032 InitializeObjectAttributes(&ObjectAttributes, 00033 ImageFileName, 00034 Attributes & (OBJ_CASE_INSENSITIVE | OBJ_INHERIT), 00035 NULL, 00036 NULL); 00037 Status = ZwOpenFile(&hFile, 00038 SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA, 00039 &ObjectAttributes, 00040 &IoStatusBlock, 00041 FILE_SHARE_DELETE | FILE_SHARE_READ, 00042 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); 00043 if (!NT_SUCCESS(Status)) 00044 { 00045 DPRINT1("Failed to read image file from disk\n"); 00046 return Status; 00047 } 00048 00049 /* Now create a section for this image */ 00050 Status = ZwCreateSection(Section, 00051 SECTION_ALL_ACCESS, 00052 NULL, 00053 NULL, 00054 PAGE_EXECUTE, 00055 SEC_IMAGE, 00056 hFile); 00057 if (!NT_SUCCESS(Status)) 00058 { 00059 DPRINT1("Failed to create section for image file\n"); 00060 } 00061 00062 ZwClose(hFile); 00063 return Status; 00064 } 00065 00066 /* FUNCTIONS ****************************************************************/ 00067 00068 NTSTATUS 00069 NTAPI 00070 RtlpInitEnvironment(HANDLE ProcessHandle, 00071 PPEB Peb, 00072 PRTL_USER_PROCESS_PARAMETERS ProcessParameters) 00073 { 00074 NTSTATUS Status; 00075 PVOID BaseAddress = NULL; 00076 SIZE_T EnviroSize; 00077 SIZE_T Size; 00078 PWCHAR Environment = 0; 00079 DPRINT("RtlpInitEnvironment (hProcess: %p, Peb: %p Params: %p)\n", 00080 ProcessHandle, Peb, ProcessParameters); 00081 00082 /* Give the caller 1MB if he requested it */ 00083 if (ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB) 00084 { 00085 /* Give 1MB starting at 0x4 */ 00086 BaseAddress = (PVOID)4; 00087 EnviroSize = (1024 * 1024) - 256; 00088 Status = ZwAllocateVirtualMemory(ProcessHandle, 00089 &BaseAddress, 00090 0, 00091 &EnviroSize, 00092 MEM_RESERVE, 00093 PAGE_READWRITE); 00094 if (!NT_SUCCESS(Status)) 00095 { 00096 DPRINT1("Failed to reserve 1MB of space \n"); 00097 return Status; 00098 } 00099 } 00100 00101 /* Find the end of the Enviroment Block */ 00102 if ((Environment = (PWCHAR)ProcessParameters->Environment)) 00103 { 00104 while (*Environment++) while (*Environment++); 00105 00106 /* Calculate the size of the block */ 00107 EnviroSize = (ULONG)((ULONG_PTR)Environment - 00108 (ULONG_PTR)ProcessParameters->Environment); 00109 00110 /* Allocate and Initialize new Environment Block */ 00111 Size = EnviroSize; 00112 Status = ZwAllocateVirtualMemory(ProcessHandle, 00113 &BaseAddress, 00114 0, 00115 &Size, 00116 MEM_RESERVE | MEM_COMMIT, 00117 PAGE_READWRITE); 00118 if (!NT_SUCCESS(Status)) 00119 { 00120 DPRINT1("Failed to allocate Environment Block\n"); 00121 return Status; 00122 } 00123 00124 /* Write the Environment Block */ 00125 ZwWriteVirtualMemory(ProcessHandle, 00126 BaseAddress, 00127 ProcessParameters->Environment, 00128 EnviroSize, 00129 NULL); 00130 00131 /* Save pointer */ 00132 ProcessParameters->Environment = BaseAddress; 00133 } 00134 00135 /* Now allocate space for the Parameter Block */ 00136 BaseAddress = NULL; 00137 Size = ProcessParameters->MaximumLength; 00138 Status = ZwAllocateVirtualMemory(ProcessHandle, 00139 &BaseAddress, 00140 0, 00141 &Size, 00142 MEM_COMMIT, 00143 PAGE_READWRITE); 00144 if (!NT_SUCCESS(Status)) 00145 { 00146 DPRINT1("Failed to allocate Parameter Block\n"); 00147 return Status; 00148 } 00149 00150 /* Write the Parameter Block */ 00151 ZwWriteVirtualMemory(ProcessHandle, 00152 BaseAddress, 00153 ProcessParameters, 00154 ProcessParameters->Length, 00155 NULL); 00156 00157 /* Write pointer to Parameter Block */ 00158 ZwWriteVirtualMemory(ProcessHandle, 00159 &Peb->ProcessParameters, 00160 &BaseAddress, 00161 sizeof(BaseAddress), 00162 NULL); 00163 00164 /* Return */ 00165 return STATUS_SUCCESS; 00166 } 00167 00168 /* 00169 * @implemented 00170 * 00171 * Creates a process and its initial thread. 00172 * 00173 * NOTES: 00174 * - The first thread is created suspended, so it needs a manual resume!!! 00175 * - If ParentProcess is NULL, current process is used 00176 * - ProcessParameters must be normalized 00177 * - Attributes are object attribute flags used when opening the ImageFileName. 00178 * Valid flags are OBJ_INHERIT and OBJ_CASE_INSENSITIVE. 00179 * 00180 * -Gunnar 00181 */ 00182 NTSTATUS 00183 NTAPI 00184 RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, 00185 IN ULONG Attributes, 00186 IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters, 00187 IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL, 00188 IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL, 00189 IN HANDLE ParentProcess OPTIONAL, 00190 IN BOOLEAN InheritHandles, 00191 IN HANDLE DebugPort OPTIONAL, 00192 IN HANDLE ExceptionPort OPTIONAL, 00193 OUT PRTL_USER_PROCESS_INFORMATION ProcessInfo) 00194 { 00195 NTSTATUS Status; 00196 HANDLE hSection; 00197 PROCESS_BASIC_INFORMATION ProcessBasicInfo; 00198 OBJECT_ATTRIBUTES ObjectAttributes; 00199 UNICODE_STRING DebugString = RTL_CONSTANT_STRING(L"\\WindowsSS"); 00200 DPRINT("RtlCreateUserProcess: %wZ\n", ImageFileName); 00201 00202 /* Map and Load the File */ 00203 Status = RtlpMapFile(ImageFileName, 00204 Attributes, 00205 &hSection); 00206 if(!NT_SUCCESS(Status)) 00207 { 00208 DPRINT1("Could not map process image\n"); 00209 return Status; 00210 } 00211 00212 /* Clean out the CurDir Handle if we won't use it */ 00213 if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL; 00214 00215 /* Use us as parent if none other specified */ 00216 if (!ParentProcess) ParentProcess = NtCurrentProcess(); 00217 00218 /* Initialize the Object Attributes */ 00219 InitializeObjectAttributes(&ObjectAttributes, 00220 NULL, 00221 0, 00222 NULL, 00223 ProcessSecurityDescriptor); 00224 00225 /* 00226 * If FLG_ENABLE_CSRDEBUG is used, then CSRSS is created under the 00227 * watch of WindowsSS 00228 */ 00229 if ((RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG) && 00230 (wcsstr(ImageFileName->Buffer, L"csrss"))) 00231 { 00232 ObjectAttributes.ObjectName = &DebugString; 00233 } 00234 00235 /* Create Kernel Process Object */ 00236 Status = ZwCreateProcess(&ProcessInfo->ProcessHandle, 00237 PROCESS_ALL_ACCESS, 00238 &ObjectAttributes, 00239 ParentProcess, 00240 InheritHandles, 00241 hSection, 00242 DebugPort, 00243 ExceptionPort); 00244 if (!NT_SUCCESS(Status)) 00245 { 00246 DPRINT1("Could not create Kernel Process Object\n"); 00247 ZwClose(hSection); 00248 return Status; 00249 } 00250 00251 /* Get some information on the image */ 00252 Status = ZwQuerySection(hSection, 00253 SectionImageInformation, 00254 &ProcessInfo->ImageInformation, 00255 sizeof(SECTION_IMAGE_INFORMATION), 00256 NULL); 00257 if (!NT_SUCCESS(Status)) 00258 { 00259 DPRINT1("Could not query Section Info\n"); 00260 ZwClose(ProcessInfo->ProcessHandle); 00261 ZwClose(hSection); 00262 return Status; 00263 } 00264 00265 /* Get some information about the process */ 00266 ZwQueryInformationProcess(ProcessInfo->ProcessHandle, 00267 ProcessBasicInformation, 00268 &ProcessBasicInfo, 00269 sizeof(ProcessBasicInfo), 00270 NULL); 00271 if (!NT_SUCCESS(Status)) 00272 { 00273 DPRINT1("Could not query Process Info\n"); 00274 ZwClose(ProcessInfo->ProcessHandle); 00275 ZwClose(hSection); 00276 return Status; 00277 } 00278 00279 /* Create Process Environment */ 00280 RtlpInitEnvironment(ProcessInfo->ProcessHandle, 00281 ProcessBasicInfo.PebBaseAddress, 00282 ProcessParameters); 00283 00284 /* Create the first Thread */ 00285 Status = RtlCreateUserThread(ProcessInfo->ProcessHandle, 00286 ThreadSecurityDescriptor, 00287 TRUE, 00288 ProcessInfo->ImageInformation.ZeroBits, 00289 ProcessInfo->ImageInformation.MaximumStackSize, 00290 ProcessInfo->ImageInformation.CommittedStackSize, 00291 ProcessInfo->ImageInformation.TransferAddress, 00292 ProcessBasicInfo.PebBaseAddress, 00293 &ProcessInfo->ThreadHandle, 00294 &ProcessInfo->ClientId); 00295 if (!NT_SUCCESS(Status)) 00296 { 00297 DPRINT1("Could not Create Thread\n"); 00298 ZwClose(ProcessInfo->ProcessHandle); 00299 ZwClose(hSection); /* Don't try to optimize this on top! */ 00300 return Status; 00301 } 00302 00303 /* Close the Section Handle and return */ 00304 ZwClose(hSection); 00305 return STATUS_SUCCESS; 00306 } 00307 00308 /* 00309 * @implemented 00310 */ 00311 PVOID 00312 NTAPI 00313 RtlEncodePointer(IN PVOID Pointer) 00314 { 00315 ULONG Cookie; 00316 NTSTATUS Status; 00317 00318 Status = ZwQueryInformationProcess(NtCurrentProcess(), 00319 ProcessCookie, 00320 &Cookie, 00321 sizeof(Cookie), 00322 NULL); 00323 if(!NT_SUCCESS(Status)) 00324 { 00325 DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status); 00326 return Pointer; 00327 } 00328 00329 return (PVOID)((ULONG_PTR)Pointer ^ Cookie); 00330 } 00331 00332 /* 00333 * @implemented 00334 */ 00335 PVOID 00336 NTAPI 00337 RtlDecodePointer(IN PVOID Pointer) 00338 { 00339 return RtlEncodePointer(Pointer); 00340 } 00341 00342 /* 00343 * @implemented 00344 */ 00345 PVOID 00346 NTAPI 00347 RtlEncodeSystemPointer(IN PVOID Pointer) 00348 { 00349 return (PVOID)((ULONG_PTR)Pointer ^ SharedUserData->Cookie); 00350 } 00351 00352 /* 00353 * @implemented 00354 * 00355 * NOTES: 00356 * Implementation based on the documentation from: 00357 * http://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/peb/setprocessiscritical.htm 00358 */ 00359 NTSTATUS 00360 NTAPI 00361 RtlSetProcessIsCritical(IN BOOLEAN NewValue, 00362 OUT PBOOLEAN OldValue OPTIONAL, 00363 IN BOOLEAN NeedBreaks) 00364 { 00365 ULONG BreakOnTermination; 00366 00367 /* Initialize to FALSE */ 00368 if (OldValue) *OldValue = FALSE; 00369 00370 /* Fail, if the critical breaks flag is required but is not set */ 00371 if ((NeedBreaks) && 00372 !(NtCurrentPeb()->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS)) 00373 { 00374 return STATUS_UNSUCCESSFUL; 00375 } 00376 00377 /* Check if the caller wants the old value */ 00378 if (OldValue) 00379 { 00380 /* Query and return the old break on termination flag for the process */ 00381 ZwQueryInformationProcess(NtCurrentProcess(), 00382 ProcessBreakOnTermination, 00383 &BreakOnTermination, 00384 sizeof(ULONG), 00385 NULL); 00386 *OldValue = (BOOLEAN)BreakOnTermination; 00387 } 00388 00389 /* Set the break on termination flag for the process */ 00390 BreakOnTermination = NewValue; 00391 return ZwSetInformationProcess(NtCurrentProcess(), 00392 ProcessBreakOnTermination, 00393 &BreakOnTermination, 00394 sizeof(ULONG)); 00395 } 00396 00397 ULONG 00398 NTAPI 00399 RtlGetCurrentProcessorNumber(VOID) 00400 { 00401 /* Forward to kernel */ 00402 return NtGetCurrentProcessorNumber(); 00403 } Generated on Sun May 27 2012 04:17:14 for ReactOS by
1.7.6.1
|