ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

process.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.