- PS_UNKNOWN_VALUE determines if the process should be created with large pages:...
authorAleksey Bragin <aleksey@reactos.org>
Wed, 26 Sep 2007 20:55:26 +0000 (20:55 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Wed, 26 Sep 2007 20:55:26 +0000 (20:55 +0000)
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.

Thanks to Alex for providing various information, and answering all my questions.

svn path=/trunk/; revision=29223

reactos/include/ndk/pstypes.h
reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/include/internal/ob.h
reactos/ntoskrnl/mm/i386/page.c
reactos/ntoskrnl/mm/mminit.c
reactos/ntoskrnl/mm/procsup.c
reactos/ntoskrnl/ob/obhandle.c
reactos/ntoskrnl/ps/process.c

index 0d0174f..567e7b0 100644 (file)
@@ -85,11 +85,11 @@ Author:
 #define PS_REQUEST_BREAKAWAY                    1
 #define PS_NO_DEBUG_INHERIT                     2
 #define PS_INHERIT_HANDLES                      4
-#define PS_UNKNOWN_VALUE                        8
+#define PS_LARGE_PAGES                          8
 #define PS_ALL_FLAGS                            (PS_REQUEST_BREAKAWAY | \
                                                  PS_NO_DEBUG_INHERIT  | \
                                                  PS_INHERIT_HANDLES   | \
-                                                 PS_UNKNOWN_VALUE)
+                                                 PS_LARGE_PAGES)
 
 //
 // Process base priorities
index 67e9f70..18ba5d6 100644 (file)
@@ -612,9 +612,9 @@ MmShowOutOfSpaceMessagePagingFile(VOID);
 
 NTSTATUS
 NTAPI
-MmCreateProcessAddressSpace(
+MmInitializeProcessAddressSpace(
     IN PEPROCESS Process,
-    IN PROS_SECTION_OBJECT Section OPTIONAL,
+    IN PVOID Section OPTIONAL,
     IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL
 );
 
@@ -1189,12 +1189,26 @@ MmGetPfnForProcess(
     PVOID Address
 );
 
+BOOLEAN
+NTAPI
+MmCreateProcessAddressSpace(
+    IN ULONG MinWs,
+    IN PEPROCESS Dest,
+    IN PLARGE_INTEGER DirectoryTableBase
+);
+
+NTSTATUS
+NTAPI
+MmInitializeHandBuiltProcess(
+    IN PEPROCESS Process,
+    IN PLARGE_INTEGER DirectoryTableBase
+);
+
+
 NTSTATUS
 NTAPI
-MmCopyMmInfo(
-    struct _EPROCESS *Src,
-    struct _EPROCESS *Dest,
-    PPHYSICAL_ADDRESS DirectoryTableBase
+MmInitializeHandBuiltProcess2(
+    IN PEPROCESS Process
 );
 
 NTSTATUS
index 1e21e1f..c6402d4 100644 (file)
@@ -191,8 +191,8 @@ ObpDeleteSymbolicLinkName(
 //
 NTSTATUS
 NTAPI
-ObpCreateHandleTable(
-    IN PEPROCESS Parent,
+ObInitProcess(
+    IN PEPROCESS Parent OPTIONAL,
     IN PEPROCESS Process
 );
 
index 0affbed..43fcd61 100644 (file)
@@ -325,17 +325,33 @@ Mmi386ReleaseMmInfo(PEPROCESS Process)
 }
 
 NTSTATUS
+NTAPI
+MmInitializeHandBuiltProcess(IN PEPROCESS Process,
+                             IN PLARGE_INTEGER DirectoryTableBase)
+{
+    /* Share the directory base with the idle process */
+    *DirectoryTableBase = PsGetCurrentProcess()->Pcb.DirectoryTableBase;
+    
+    /* Initialize the Addresss Space */
+    MmInitializeAddressSpace(Process, (PMADDRESS_SPACE)&Process->VadRoot);
+    
+    /* The process now has an address space */
+    Process->HasAddressSpace = TRUE;
+    return STATUS_SUCCESS;
+}
+
+BOOLEAN
 STDCALL
-MmCopyMmInfo(PEPROCESS Src,
-             PEPROCESS Dest,
-             PPHYSICAL_ADDRESS DirectoryTableBase)
+MmCreateProcessAddressSpace(IN ULONG MinWs,
+                            IN PEPROCESS Process,
+                            IN PLARGE_INTEGER DirectoryTableBase)
 {
    NTSTATUS Status;
    ULONG i, j;
    PFN_TYPE Pfn[7];
    ULONG Count;
 
-   DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
+   DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", MinWs, Process);
 
    Count = Ke386Pae ? 7 : 2;
 
@@ -344,11 +360,12 @@ MmCopyMmInfo(PEPROCESS Src,
       Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
       if (!NT_SUCCESS(Status))
       {
-        for (j = 0; j < i; j++)
-        {
-           MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
-        }
-        return Status;
+          for (j = 0; j < i; j++)
+          {
+              MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
+          }
+          
+          return FALSE;
       }
    }
 
@@ -400,7 +417,7 @@ MmCopyMmInfo(PEPROCESS Src,
 
    DirectoryTableBase->QuadPart = PFN_TO_PTE(Pfn[0]);
    DPRINT("Finished MmCopyMmInfo(): %I64x\n", DirectoryTableBase->QuadPart);
-   return(STATUS_SUCCESS);
+   return TRUE;
 }
 
 VOID
index 7a270e6..898c5a1 100644 (file)
@@ -432,6 +432,9 @@ MmInitSystem(IN ULONG Phase,
         /* Initialize the Loader Lock */
         KeInitializeMutant(&MmSystemLoadLock, FALSE);
 
+        /* Initialize the address space for the system process */
+        MmInitializeProcessAddressSpace(PsGetCurrentProcess(), NULL, NULL);
+
         /* Reload boot drivers */
         MiReloadBootLoadedDrivers(LoaderBlock);
 
index 254e38d..876535e 100644 (file)
@@ -471,10 +471,34 @@ MmCreateTeb(PEPROCESS Process,
 }
 
 NTSTATUS
-STDCALL
-MmCreateProcessAddressSpace(IN PEPROCESS Process,
-                            IN PROS_SECTION_OBJECT Section OPTIONAL,
-                            IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL)
+NTAPI
+MmInitializeHandBuiltProcess2(IN PEPROCESS Process)
+{
+    PVOID BaseAddress;
+    PMEMORY_AREA MemoryArea;
+    PHYSICAL_ADDRESS BoundaryAddressMultiple;
+    NTSTATUS Status;
+    PMADDRESS_SPACE ProcessAddressSpace = (PMADDRESS_SPACE)&Process->VadRoot;
+    
+    /* Create the shared data page */
+    BaseAddress = (PVOID)USER_SHARED_DATA;
+    Status = MmCreateMemoryArea(ProcessAddressSpace,
+                                MEMORY_AREA_SHARED_DATA,
+                                &BaseAddress,
+                                PAGE_SIZE,
+                                PAGE_EXECUTE_READ,
+                                &MemoryArea,
+                                FALSE,
+                                0,
+                                BoundaryAddressMultiple);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+MmInitializeProcessAddressSpace(IN PEPROCESS Process,
+                                IN PVOID Section OPTIONAL,
+                                IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL)
 {
     NTSTATUS Status;
     PMADDRESS_SPACE ProcessAddressSpace = (PMADDRESS_SPACE)&Process->VadRoot;
@@ -483,6 +507,7 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
     PHYSICAL_ADDRESS BoundaryAddressMultiple;
     SIZE_T ViewSize = 0;
     PVOID ImageBase = 0;
+    PROS_SECTION_OBJECT SectionObject = Section;
     BoundaryAddressMultiple.QuadPart = 0;
 
     /* Initialize the Addresss Space */
@@ -546,7 +571,7 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
     Process->HasAddressSpace = TRUE;
 
     /* Check if there's a Section Object */
-    if (Section)
+    if (SectionObject)
     {
         UNICODE_STRING FileName;
         PWCHAR szSrc;
@@ -558,7 +583,7 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
         MmUnlockAddressSpace(ProcessAddressSpace);
 
         DPRINT("Mapping process image. Section: %p, Process: %p, ImageBase: %p\n",
-                 Section, Process, &ImageBase);
+                 SectionObject, Process, &ImageBase);
         Status = MmMapViewOfSection(Section,
                                     (PEPROCESS)Process,
                                     (PVOID*)&ImageBase,
@@ -580,7 +605,7 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
 
         /* Determine the image file name and save it to EPROCESS */
         DPRINT("Getting Image name\n");
-        FileName = Section->FileObject->FileName;
+        FileName = SectionObject->FileObject->FileName;
         szSrc = (PWCHAR)(FileName.Buffer + FileName.Length);
         while (szSrc >= FileName.Buffer)
         {
@@ -608,7 +633,7 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
         if (AuditName)
         {
             /* Setup the audit name */
-            SeInitializeProcessAuditName(Section->FileObject,
+            SeInitializeProcessAuditName(SectionObject->FileObject,
                                          FALSE,
                                          AuditName);
         }
index 92bd85a..2f5458e 100644 (file)
@@ -1956,40 +1956,57 @@ ObClearProcessHandleTable(IN PEPROCESS Process)
 *--*/
 NTSTATUS
 NTAPI
-ObpCreateHandleTable(IN PEPROCESS Parent,
-                     IN PEPROCESS Process)
+ObInitProcess(IN PEPROCESS Parent OPTIONAL,
+              IN PEPROCESS Process)
 {
-    PHANDLE_TABLE HandleTable;
-    PAGED_CODE();
-
-    /* Check if we have a parent */
+    PHANDLE_TABLE ParentTable, ObjectTable;
+    
+    /* Check for a parent */
     if (Parent)
     {
-        /* Get the parent's table */
-        HandleTable = ObReferenceProcessHandleTable(Parent);
-        if (!HandleTable) return STATUS_PROCESS_IS_TERMINATING;
-
-        /* Duplicate the parent's */
-        HandleTable = ExDupHandleTable(Process,
-                                       HandleTable,
+        /* Reference the parent's table */
+        ParentTable = ObReferenceProcessHandleTable(Parent);
+        if (!ParentTable) return STATUS_PROCESS_IS_TERMINATING;
+        
+        /* Duplicate it */
+        ObjectTable = ExDupHandleTable(Process,
+                                       ParentTable,
                                        ObpDuplicateHandleCallback,
                                        OBJ_INHERIT);
     }
     else
     {
-        /* Create a new one */
-        HandleTable = ExCreateHandleTable(Process);
+        /* Otherwise just create a new table */
+        ParentTable = NULL;
+        ObjectTable = ExCreateHandleTable(Process);
+    }
+    
+    /* Make sure we have a table */
+    if (ObjectTable)
+    {
+        /* Associate it */       
+        Process->ObjectTable = ObjectTable;
+        
+        /* Check for auditing */
+        if (SeDetailedAuditingWithToken(NULL))
+        {
+            /* FIXME: TODO */
+            DPRINT1("Need auditing!\n");
+        }
+        
+        /* Get rid of the old table now */
+        if (ParentTable) ObDereferenceProcessHandleTable(Parent);
+        
+        /* We are done */
+        return STATUS_SUCCESS;
+    }
+    else
+    {
+        /* Fail */
+        Process->ObjectTable = NULL;
+        if (ParentTable) ObDereferenceProcessHandleTable(Parent);
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
-
-    /* Now write it */
-    Process->ObjectTable = HandleTable;
-
-    /* Dereference the parent's handle table if we have one */
-    if (Parent) ObDereferenceProcessHandleTable(Parent);
-
-    /* Fail or succeed depending on whether we got a handle table or not */
-    if (!HandleTable) return STATUS_INSUFFICIENT_RESOURCES;
-    return STATUS_SUCCESS;
 }
 
 /*++
index 293b04d..0ad27ee 100644 (file)
@@ -555,15 +555,28 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
 
     /* Set default exit code */
     Process->ExitStatus = STATUS_TIMEOUT;
-
-    /* Create or Clone the Handle Table */
-    ObpCreateHandleTable(Parent, Process);
-
-    /* Set Process's Directory Base */
-    MmCopyMmInfo(Parent ? Parent : PsInitialSystemProcess,
-                 Process,
-                 &DirectoryTableBase);
-
+    
+    /* Check if this is the initial process being built */
+    if (Parent)
+    {
+        /* Create the address space for the child */
+        if (!MmCreateProcessAddressSpace(MinWs,
+                                         Process,
+                                         &DirectoryTableBase))
+        {
+            /* Failed */
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto CleanupWithRef;
+        }
+    }
+    else
+    {
+        /* Otherwise, we are the boot process, we're already semi-initialized */
+        Process->ObjectTable = CurrentProcess->ObjectTable;
+        Status = MmInitializeHandBuiltProcess(Process, &DirectoryTableBase);
+        if (!NT_SUCCESS(Status)) goto CleanupWithRef;
+    }
+    
     /* We now have an address space */
     InterlockedOr((PLONG)&Process->Flags, PSF_HAS_ADDRESS_SPACE_BIT);
 
@@ -583,14 +596,81 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
 
     /* Set default priority class */
     Process->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
+    
+    /* Check if we have a parent */
+    if (Parent)
+    {
+        /* Check our priority class */
+        if (Parent->PriorityClass == PROCESS_PRIORITY_CLASS_IDLE ||
+            Parent->PriorityClass == PROCESS_PRIORITY_CLASS_BELOW_NORMAL) 
+        {
+            /* Normalize it */
+            Process->PriorityClass = Parent->PriorityClass;
+        }
+        
+        /* Initialize object manager for the process */
+        Status = ObInitProcess(Flags & PS_INHERIT_HANDLES ? Parent : NULL,
+                               Process);
+        if (!NT_SUCCESS(Status)) goto CleanupWithRef;
+    }
+    else
+    {
+        /* Do the second part of the boot process memory setup */
+        Status = MmInitializeHandBuiltProcess2(Process);
+        if (!NT_SUCCESS(Status)) goto CleanupWithRef;
+    }
+    
+    /* Set success for now */
+    Status = STATUS_SUCCESS;
 
-    /* Create the Process' Address Space */
-    Status = MmCreateProcessAddressSpace(Process,
-                                         (PROS_SECTION_OBJECT)SectionObject,
-                                         &Process->SeAuditProcessCreationInfo.
-                                         ImageFileName);
-    if (!NT_SUCCESS(Status)) goto CleanupWithRef;
-
+    /* Check if this is a real user-mode process */
+    if (SectionHandle)
+    {
+        /* Initialize the address space */
+        Status = MmInitializeProcessAddressSpace(Process,
+                                                 SectionObject,
+                                                 &Process->
+                                                 SeAuditProcessCreationInfo.
+                                                 ImageFileName);
+        if (!NT_SUCCESS(Status)) goto CleanupWithRef;    
+    }
+    else if (Parent)
+    {
+        /* Check if this is a child of the system process */
+        if (Parent != PsInitialSystemProcess)
+        {
+            /* This is a clone! */
+            ASSERTMSG("No support for cloning yet\n", FALSE);
+        }
+        else
+        {
+            /* This is a system process other than the boot one (MmInit1) */
+            Flags &= ~PS_LARGE_PAGES;
+            Status = MmInitializeProcessAddressSpace(Process,
+                                                     NULL,
+                                                     &Process->
+                                                     SeAuditProcessCreationInfo.
+                                                     ImageFileName);
+            if (!NT_SUCCESS(Status)) goto CleanupWithRef;
+            
+            /* Create a dummy image file name */
+            Process->SeAuditProcessCreationInfo.ImageFileName =
+                ExAllocatePoolWithTag(PagedPool,
+                                      sizeof(OBJECT_NAME_INFORMATION),
+                                      TAG('S', 'e', 'P', 'a'));
+            if (!Process->SeAuditProcessCreationInfo.ImageFileName)
+            {
+                /* Fail */
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                goto CleanupWithRef;
+            }
+            
+            /* Zero it out */
+            RtlZeroMemory(Process->SeAuditProcessCreationInfo.ImageFileName,
+                          sizeof(OBJECT_NAME_INFORMATION));
+        }
+    }
+    
     /* Check if we have a section object and map the system DLL */
     if (SectionObject) PspMapSystemDll(Process, NULL, FALSE);