- 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.

svn path=/trunk/; revision=29223
This commit is contained in:
Aleksey Bragin 2007-09-26 20:55:26 +00:00
parent 6433b53657
commit 2c239e0bd6
8 changed files with 225 additions and 69 deletions

View 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

View 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
MmCopyMmInfo(
struct _EPROCESS *Src,
struct _EPROCESS *Dest,
PPHYSICAL_ADDRESS DirectoryTableBase
MmInitializeHandBuiltProcess(
IN PEPROCESS Process,
IN PLARGE_INTEGER DirectoryTableBase
);
NTSTATUS
NTAPI
MmInitializeHandBuiltProcess2(
IN PEPROCESS Process
);
NTSTATUS

View file

@ -191,8 +191,8 @@ ObpDeleteSymbolicLinkName(
//
NTSTATUS
NTAPI
ObpCreateHandleTable(
IN PEPROCESS Parent,
ObInitProcess(
IN PEPROCESS Parent OPTIONAL,
IN PEPROCESS Process
);

View 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;
@ -348,7 +364,8 @@ MmCopyMmInfo(PEPROCESS Src,
{
MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
}
return Status;
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

View 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);

View file

@ -471,9 +471,33 @@ MmCreateTeb(PEPROCESS Process,
}
NTSTATUS
STDCALL
MmCreateProcessAddressSpace(IN PEPROCESS Process,
IN PROS_SECTION_OBJECT Section 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;
@ -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);
}

View file

@ -1956,40 +1956,57 @@ ObClearProcessHandleTable(IN PEPROCESS Process)
*--*/
NTSTATUS
NTAPI
ObpCreateHandleTable(IN PEPROCESS Parent,
ObInitProcess(IN PEPROCESS Parent OPTIONAL,
IN PEPROCESS Process)
{
PHANDLE_TABLE HandleTable;
PAGED_CODE();
PHANDLE_TABLE ParentTable, ObjectTable;
/* Check if we have a parent */
/* Check for a parent */
if (Parent)
{
/* Get the parent's table */
HandleTable = ObReferenceProcessHandleTable(Parent);
if (!HandleTable) return STATUS_PROCESS_IS_TERMINATING;
/* Reference the parent's table */
ParentTable = ObReferenceProcessHandleTable(Parent);
if (!ParentTable) return STATUS_PROCESS_IS_TERMINATING;
/* Duplicate the parent's */
HandleTable = ExDupHandleTable(Process,
HandleTable,
/* 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);
}
/* Now write it */
Process->ObjectTable = HandleTable;
/* Make sure we have a table */
if (ObjectTable)
{
/* Associate it */
Process->ObjectTable = ObjectTable;
/* Dereference the parent's handle table if we have one */
if (Parent) ObDereferenceProcessHandleTable(Parent);
/* Check for auditing */
if (SeDetailedAuditingWithToken(NULL))
{
/* FIXME: TODO */
DPRINT1("Need auditing!\n");
}
/* Fail or succeed depending on whether we got a handle table or not */
if (!HandleTable) return STATUS_INSUFFICIENT_RESOURCES;
/* 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;
}
}
/*++

View file

@ -556,13 +556,26 @@ 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,
/* Check if this is the initial process being built */
if (Parent)
{
/* Create the address space for the child */
if (!MmCreateProcessAddressSpace(MinWs,
Process,
&DirectoryTableBase);
&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);
@ -584,12 +597,79 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
/* Set default priority class */
Process->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
/* Create the Process' Address Space */
Status = MmCreateProcessAddressSpace(Process,
(PROS_SECTION_OBJECT)SectionObject,
&Process->SeAuditProcessCreationInfo.
/* 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);