Author: fireball
Date: Thu Sep 27 00:55:26 2007
New Revision: 29223
URL:
http://svn.reactos.org/svn/reactos?rev=29223&view=rev
Log:
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to
PS_LARGE_PAGES
- 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.
Modified:
trunk/reactos/include/ndk/pstypes.h
trunk/reactos/ntoskrnl/include/internal/mm.h
trunk/reactos/ntoskrnl/include/internal/ob.h
trunk/reactos/ntoskrnl/mm/i386/page.c
trunk/reactos/ntoskrnl/mm/mminit.c
trunk/reactos/ntoskrnl/mm/procsup.c
trunk/reactos/ntoskrnl/ob/obhandle.c
trunk/reactos/ntoskrnl/ps/process.c
Modified: trunk/reactos/include/ndk/pstypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/pstypes.h?rev=…
==============================================================================
--- trunk/reactos/include/ndk/pstypes.h (original)
+++ trunk/reactos/include/ndk/pstypes.h Thu Sep 27 00:55:26 2007
@@ -85,11 +85,11 @@
#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
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/mm.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h Thu Sep 27 00:55:26 2007
@@ -612,9 +612,9 @@
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 @@
PVOID Address
);
-NTSTATUS
-NTAPI
-MmCopyMmInfo(
- struct _EPROCESS *Src,
- struct _EPROCESS *Dest,
- PPHYSICAL_ADDRESS DirectoryTableBase
+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
+MmInitializeHandBuiltProcess2(
+ IN PEPROCESS Process
);
NTSTATUS
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h Thu Sep 27 00:55:26 2007
@@ -191,8 +191,8 @@
//
NTSTATUS
NTAPI
-ObpCreateHandleTable(
- IN PEPROCESS Parent,
+ObInitProcess(
+ IN PEPROCESS Parent OPTIONAL,
IN PEPROCESS Process
);
Modified: trunk/reactos/ntoskrnl/mm/i386/page.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/i386/page.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/i386/page.c (original)
+++ trunk/reactos/ntoskrnl/mm/i386/page.c Thu Sep 27 00:55:26 2007
@@ -325,17 +325,33 @@
}
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 @@
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 @@
DirectoryTableBase->QuadPart = PFN_TO_PTE(Pfn[0]);
DPRINT("Finished MmCopyMmInfo(): %I64x\n",
DirectoryTableBase->QuadPart);
- return(STATUS_SUCCESS);
+ return TRUE;
}
VOID
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c Thu Sep 27 00:55:26 2007
@@ -432,6 +432,9 @@
/* Initialize the Loader Lock */
KeInitializeMutant(&MmSystemLoadLock, FALSE);
+ /* Initialize the address space for the system process */
+ MmInitializeProcessAddressSpace(PsGetCurrentProcess(), NULL, NULL);
+
/* Reload boot drivers */
MiReloadBootLoadedDrivers(LoaderBlock);
Modified: trunk/reactos/ntoskrnl/mm/procsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/procsup.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/procsup.c (original)
+++ trunk/reactos/ntoskrnl/mm/procsup.c Thu Sep 27 00:55:26 2007
@@ -471,10 +471,34 @@
}
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 @@
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 @@
Process->HasAddressSpace = TRUE;
/* Check if there's a Section Object */
- if (Section)
+ if (SectionObject)
{
UNICODE_STRING FileName;
PWCHAR szSrc;
@@ -558,7 +583,7 @@
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 @@
/* 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 @@
if (AuditName)
{
/* Setup the audit name */
- SeInitializeProcessAuditName(Section->FileObject,
+ SeInitializeProcessAuditName(SectionObject->FileObject,
FALSE,
AuditName);
}
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Thu Sep 27 00:55:26 2007
@@ -1956,40 +1956,57 @@
*--*/
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);
- }
-
- /* 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;
+ /* 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;
+ }
}
/*++
Modified: trunk/reactos/ntoskrnl/ps/process.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/process.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ps/process.c (original)
+++ trunk/reactos/ntoskrnl/ps/process.c Thu Sep 27 00:55:26 2007
@@ -555,15 +555,28 @@
/* 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 @@
/* Set default priority class */
Process->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
-
- /* Create the Process' Address Space */
- Status = MmCreateProcessAddressSpace(Process,
- (PROS_SECTION_OBJECT)SectionObject,
- &Process->SeAuditProcessCreationInfo.
- ImageFileName);
- if (!NT_SUCCESS(Status)) goto CleanupWithRef;
-
+
+ /* 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;
+
+ /* 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);