diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index 0d0174f0442..567e7b0bb7c 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -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 diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 67e9f70b584..18ba5d629eb 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -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 diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 1e21e1f0b12..c6402d4805d 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -191,8 +191,8 @@ ObpDeleteSymbolicLinkName( // NTSTATUS NTAPI -ObpCreateHandleTable( - IN PEPROCESS Parent, +ObInitProcess( + IN PEPROCESS Parent OPTIONAL, IN PEPROCESS Process ); diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index 0affbed6160..43fcd616181 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -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 diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 7a270e6422e..898c5a1677f 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -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); diff --git a/reactos/ntoskrnl/mm/procsup.c b/reactos/ntoskrnl/mm/procsup.c index 254e38d510f..876535e3fe3 100644 --- a/reactos/ntoskrnl/mm/procsup.c +++ b/reactos/ntoskrnl/mm/procsup.c @@ -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); } diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index 92bd85a653f..2f5458eb0d0 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -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; } /*++ diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 293b04d92d3..0ad27ee3aa0 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -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);