Author: akhaldi Date: Sat Feb 18 22:29:24 2012 New Revision: 55683
URL: http://svn.reactos.org/svn/reactos?rev=55683&view=rev Log: [NEWCC] * Update the kernel with the recent trunk changes. * Alter some base addresses in the cmake build. * We boot to 3rd stage now in NEWCC=0.
Modified: branches/arty-newcc/cmake/baseaddress.cmake branches/arty-newcc/ntoskrnl/ex/init.c branches/arty-newcc/ntoskrnl/io/iomgr/driver.c branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpmgr.c branches/arty-newcc/ntoskrnl/kd/kdinit.c branches/arty-newcc/ntoskrnl/kd/kdio.c branches/arty-newcc/ntoskrnl/kd64/kdinit.c branches/arty-newcc/ntoskrnl/kdbg/kdb.c branches/arty-newcc/ntoskrnl/kdbg/kdb_cli.c branches/arty-newcc/ntoskrnl/mm/ARM3/mminit.c branches/arty-newcc/ntoskrnl/mm/ARM3/procsup.c branches/arty-newcc/ntoskrnl/mm/ARM3/sysldr.c branches/arty-newcc/ntoskrnl/mm/ARM3/vadnode.c branches/arty-newcc/ntoskrnl/mm/ARM3/virtual.c branches/arty-newcc/ntoskrnl/mm/ARM3/zeropage.c branches/arty-newcc/ntoskrnl/mm/amd64/page.c branches/arty-newcc/ntoskrnl/mm/anonmem.c branches/arty-newcc/ntoskrnl/mm/i386/page.c branches/arty-newcc/ntoskrnl/mm/marea.c branches/arty-newcc/ntoskrnl/ob/oblife.c branches/arty-newcc/ntoskrnl/ps/query.c
Modified: branches/arty-newcc/cmake/baseaddress.cmake URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/cmake/baseaddress.cma... ============================================================================== --- branches/arty-newcc/cmake/baseaddress.cmake [iso-8859-1] (original) +++ branches/arty-newcc/cmake/baseaddress.cmake [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -219,14 +219,14 @@ set(baseaddress_authz 0x77690000) set(baseaddress_cfgmgr32 0x77700000) set(baseaddress_sensapi 0x77700000) -set(baseaddress_msafd 0x77780000) +set(baseaddress_msafd 0x77720000) set(baseaddress_packet 0x77780000) set(baseaddress_msi 0x77790000) -set(baseaddress_snmpapi 0x777a0000) -set(baseaddress_usp10 0x777b0000) -set(baseaddress_iprtprio 0x777c0000) -set(baseaddress_ws2help 0x777e0000) -set(baseaddress_wshirda 0x777f0000) +set(baseaddress_snmpapi 0x77900000) +set(baseaddress_usp10 0x77910000) +set(baseaddress_iprtprio 0x77920000) +set(baseaddress_ws2help 0x77930000) +set(baseaddress_wshirda 0x77940000) set(baseaddress_ole32 0x77a50000) set(baseaddress_olepro32 0x77b20000) set(baseaddress_activeds 0x77cb0000)
Modified: branches/arty-newcc/ntoskrnl/ex/init.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/ex/init.c?re... ============================================================================== --- branches/arty-newcc/ntoskrnl/ex/init.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/ex/init.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -66,7 +66,7 @@ UNICODE_STRING NtSystemRoot;
/* NT Initial User Application */ -WCHAR NtInitialUserProcessBuffer[128] = L"\SystemRoot\System32\smss2.exe"; +WCHAR NtInitialUserProcessBuffer[128] = L"\SystemRoot\System32\smss.exe"; ULONG NtInitialUserProcessBufferLength = sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR); ULONG NtInitialUserProcessBufferType = REG_SZ; @@ -400,7 +400,7 @@ (PVOID*)&ProcessParams, 0, &Size, - MEM_COMMIT, + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { @@ -429,7 +429,7 @@ &EnvironmentPtr, 0, &Size, - MEM_COMMIT, + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { @@ -1285,6 +1285,10 @@ SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_NATIVE; SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_NATIVE; } + +VOID +NTAPI +MmFreeLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID NTAPI @@ -1906,6 +1910,7 @@
/* Make sure nobody touches the loader block again */ if (LoaderBlock == KeLoaderBlock) KeLoaderBlock = NULL; + MmFreeLoaderBlock(LoaderBlock); LoaderBlock = Context = NULL;
/* Update progress bar */
Modified: branches/arty-newcc/ntoskrnl/io/iomgr/driver.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/io/iomgr/dri... ============================================================================== --- branches/arty-newcc/ntoskrnl/io/iomgr/driver.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/io/iomgr/driver.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -422,6 +422,10 @@ return Status; }
+VOID +NTAPI +MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry); + /* * IopInitializeDriverModule * @@ -513,6 +517,8 @@ DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status); return Status; } + + MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)Driver->DriverSection);
/* Set the driver as initialized */ IopReadyDeviceObjects(Driver);
Modified: branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpmgr.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/io/pnpmgr/pn... ============================================================================== --- branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -2691,9 +2691,6 @@ ULONG BootResourcesLength; NTSTATUS Status;
- const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI"); - UNICODE_STRING HardwareIdPci = RTL_CONSTANT_STRING(L"*PNP0A03\0"); - static ULONG DeviceIndexPci = 0; const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController"); UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0"); static ULONG DeviceIndexSerial = 0; @@ -2709,9 +2706,6 @@ const UNICODE_STRING IdentifierFloppy = RTL_CONSTANT_STRING(L"FloppyDiskPeripheral"); UNICODE_STRING HardwareIdFloppy = RTL_CONSTANT_STRING(L"*PNP0700\0"); static ULONG DeviceIndexFloppy = 0; - const UNICODE_STRING IdentifierIsa = RTL_CONSTANT_STRING(L"ISA"); - UNICODE_STRING HardwareIdIsa = RTL_CONSTANT_STRING(L"*PNP0A00\0"); - static ULONG DeviceIndexIsa = 0; UNICODE_STRING HardwareIdKey; PUNICODE_STRING pHardwareId; ULONG DeviceIndex = 0; @@ -2963,25 +2957,6 @@ { pHardwareId = &HardwareIdFloppy; DeviceIndex = DeviceIndexFloppy++; - } - else if (NT_SUCCESS(Status)) - { - /* Try to also match the device identifier */ - if (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0) - { - pHardwareId = &HardwareIdPci; - DeviceIndex = DeviceIndexPci++; - } - else if (RtlCompareUnicodeString(&ValueName, &IdentifierIsa, FALSE) == 0) - { - pHardwareId = &HardwareIdIsa; - DeviceIndex = DeviceIndexIsa++; - } - else - { - DPRINT("Unknown device '%wZ'\n", &ValueName); - goto nextdevice; - } } else {
Modified: branches/arty-newcc/ntoskrnl/kd/kdinit.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/kd/kdinit.c?... ============================================================================== --- branches/arty-newcc/ntoskrnl/kd/kdinit.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/kd/kdinit.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -10,11 +10,6 @@ #include <ntoskrnl.h> #define NDEBUG #include <debug.h> - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, KdInitSystem) -#endif -
/* Make bochs debug output in the very early boot phase available */ //#define AUTO_ENABLE_BOCHS @@ -172,7 +167,6 @@ }
BOOLEAN -INIT_FUNCTION NTAPI KdInitSystem(ULONG BootPhase, PLOADER_PARAMETER_BLOCK LoaderBlock)
Modified: branches/arty-newcc/ntoskrnl/kd/kdio.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/kd/kdio.c?re... ============================================================================== --- branches/arty-newcc/ntoskrnl/kd/kdio.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/kd/kdio.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -488,7 +488,7 @@ /* Take control of the display */ InbvAcquireDisplayOwnership(); InbvResetDisplay(); - InbvSolidColorFill(0, 0, 639, 479, 6); + InbvSolidColorFill(0, 0, 639, 479, 0); InbvSetTextColor(15); InbvSetScrollRegion(0, 0, 639, 479); InbvInstallDisplayStringFilter(NULL);
Modified: branches/arty-newcc/ntoskrnl/kd64/kdinit.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/kd64/kdinit.... ============================================================================== --- branches/arty-newcc/ntoskrnl/kd64/kdinit.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/kd64/kdinit.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -70,7 +70,6 @@
BOOLEAN NTAPI -INIT_FUNCTION KdInitSystem(IN ULONG BootPhase, IN PLOADER_PARAMETER_BLOCK LoaderBlock) {
Modified: branches/arty-newcc/ntoskrnl/kdbg/kdb.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/kdbg/kdb.c?r... ============================================================================== --- branches/arty-newcc/ntoskrnl/kdbg/kdb.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/kdbg/kdb.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -1250,8 +1250,8 @@ InbvAcquireDisplayOwnership(); InbvResetDisplay();
- /* Display blue screen */ - InbvSolidColorFill(0, 0, 639, 479, 6); + /* Display debugger prompt */ + InbvSolidColorFill(0, 0, 639, 479, 0); InbvSetTextColor(15); InbvInstallDisplayStringFilter(NULL); InbvEnableDisplayString(TRUE);
Modified: branches/arty-newcc/ntoskrnl/kdbg/kdb_cli.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/kdbg/kdb_cli... ============================================================================== --- branches/arty-newcc/ntoskrnl/kdbg/kdb_cli.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/kdbg/kdb_cli.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -3161,8 +3161,8 @@ if (Buffer != Orig) { KdbRepeatLastCommand = TRUE; + *Buffer = '\0'; RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Orig); - *Buffer = '\0'; } else if (KdbRepeatLastCommand) RtlStringCbCopyA(Buffer, Size, LastCommand);
Modified: branches/arty-newcc/ntoskrnl/mm/ARM3/mminit.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/ARM3/mmin... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -1067,6 +1067,116 @@ VOID NTAPI INIT_FUNCTION +MmFreeLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PLIST_ENTRY NextMd; + PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; + ULONG i; + PFN_NUMBER BasePage, LoaderPages; + PMMPFN Pfn1; + KIRQL OldIrql; + PPHYSICAL_MEMORY_RUN Buffer, Entry; + + /* Loop the descriptors in order to count them */ + i = 0; + NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; + while (NextMd != &LoaderBlock->MemoryDescriptorListHead) + { + MdBlock = CONTAINING_RECORD(NextMd, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + i++; + NextMd = MdBlock->ListEntry.Flink; + } + + /* Allocate a structure to hold the physical runs */ + Buffer = ExAllocatePoolWithTag(NonPagedPool, + i * sizeof(PHYSICAL_MEMORY_RUN), + 'lMmM'); + ASSERT(Buffer != NULL); + Entry = Buffer; + + /* Loop the descriptors again */ + NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; + while (NextMd != &LoaderBlock->MemoryDescriptorListHead) + { + /* Check what kind this was */ + MdBlock = CONTAINING_RECORD(NextMd, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + switch (MdBlock->MemoryType) + { + /* Registry, NLS, and heap data */ + case LoaderRegistryData: + case LoaderOsloaderHeap: + case LoaderNlsData: + /* Are all a candidate for deletion */ + Entry->BasePage = MdBlock->BasePage; + Entry->PageCount = MdBlock->PageCount; + Entry++; + + /* We keep the rest */ + default: + break; + } + + /* Move to the next descriptor */ + NextMd = MdBlock->ListEntry.Flink; + } + + /* Acquire the PFN lock */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + + /* Loop the runs */ + LoaderPages = 0; + while (--Entry >= Buffer) + { + /* See how many pages are in this run */ + i = Entry->PageCount; + BasePage = Entry->BasePage; + + /* Loop each page */ + Pfn1 = MiGetPfnEntry(BasePage); + while (i--) + { + /* Check if it has references or is in any kind of list */ + if (!(Pfn1->u3.e2.ReferenceCount) && (!Pfn1->u1.Flink)) + { + /* Set the new PTE address and put this page into the free list */ + Pfn1->PteAddress = (PMMPTE)(BasePage << PAGE_SHIFT); + MiInsertPageInFreeList(BasePage); + LoaderPages++; + } + else if (BasePage) + { + /* It has a reference, so simply drop it */ + ASSERT(MI_IS_PHYSICAL_ADDRESS(MiPteToAddress(Pfn1->PteAddress)) == FALSE); + + /* Drop a dereference on this page, which should delete it */ + Pfn1->PteAddress->u.Long = 0; + MI_SET_PFN_DELETED(Pfn1); + MiDecrementShareCount(Pfn1, BasePage); + LoaderPages++; + } + + /* Move to the next page */ + Pfn1++; + BasePage++; + } + } + + /* Release the PFN lock and flush the TLB */ + DPRINT1("Loader pages freed: %lx\n", LoaderPages); + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + KeFlushCurrentTb(); + + /* Free our run structure */ + ExFreePool(Buffer); +} + +VOID +NTAPI +INIT_FUNCTION MiAdjustWorkingSetManagerParameters(IN BOOLEAN Client) { /* This function needs to do more work, for now, we tune page minimums */
Modified: branches/arty-newcc/ntoskrnl/mm/ARM3/procsup.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/ARM3/proc... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -199,6 +199,9 @@ ASSERT(VadTree->NumberGenericTableElements >= 1); MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree);
+ /* Delete the pages */ + MiDeleteVirtualAddresses((ULONG_PTR)Teb, TebEnd, NULL); + /* Release the working set */ MiUnlockProcessWorkingSet(Process, Thread);
@@ -219,7 +222,7 @@ IN BOOLEAN GuiStack) { PMMPTE PointerPte; - PFN_NUMBER PageFrameNumber;//, PageTableFrameNumber; + PFN_NUMBER PageFrameNumber, PageTableFrameNumber; PFN_COUNT StackPages; PMMPFN Pfn1;//, Pfn2; ULONG i; @@ -253,13 +256,14 @@ /* Get the PTE's page */ PageFrameNumber = PFN_FROM_PTE(PointerPte); Pfn1 = MiGetPfnEntry(PageFrameNumber); -#if 0 // ARM3 might not own the page table, so don't take this risk. Leak it instead! +#if 1 // ARM3 might not own the page table, so don't take this risk. Leak it instead! /* Now get the page of the page table mapping it */ PageTableFrameNumber = Pfn1->u4.PteFrame; - Pfn2 = MiGetPfnEntry(PageTableFrameNumber); + //Pfn2 = MiGetPfnEntry(PageTableFrameNumber);
/* Remove a shared reference, since the page is going away */ - MiDecrementShareCount(Pfn2, PageTableFrameNumber); + DPRINT("SystemPTE PDE: %lx\n", PageTableFrameNumber); + //MiDecrementShareCount(Pfn2, PageTableFrameNumber); #endif /* Set the special pending delete marker */ MI_SET_PFN_DELETED(Pfn1); @@ -1340,6 +1344,79 @@ MmUnlockAddressSpace(&Process->Vm); }
+VOID +NTAPI +MmDeleteProcessAddressSpace2(IN PEPROCESS Process) +{ + PMMPFN Pfn1, Pfn2; + KIRQL OldIrql; + PFN_NUMBER PageFrameIndex; + + //ASSERT(Process->CommitCharge == 0); + + /* Delete the shared user data section (Should be done in clean, not delete) */ + ASSERT(MmHighestUserAddress > (PVOID)USER_SHARED_DATA); + KeAttachProcess(&Process->Pcb); + //DPRINT1("Killing shared user data page no longer works -- has someone changed ARM3 in a way to make this fail now?\n"); + //MiDeleteVirtualAddresses(USER_SHARED_DATA, USER_SHARED_DATA, NULL); + //DPRINT1("Done\n"); + KeDetachProcess(); + + /* Acquire the PFN lock */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + + /* Check for fully initialized process */ + if (Process->AddressSpaceInitialized == 2) + { + /* Map the working set page and its page table */ + Pfn1 = MiGetPfnEntry(Process->WorkingSetPage); + Pfn2 = MiGetPfnEntry(Pfn1->u4.PteFrame); + + /* Nuke it */ + MI_SET_PFN_DELETED(Pfn1); + MiDecrementShareCount(Pfn2, Pfn1->u4.PteFrame); + MiDecrementShareCount(Pfn1, Process->WorkingSetPage); + ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress)); + + /* Now map hyperspace and its page table */ + PageFrameIndex = Process->Pcb.DirectoryTableBase[1] >> PAGE_SHIFT; + Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn2 = MiGetPfnEntry(Pfn1->u4.PteFrame); + + /* Nuke it */ + MI_SET_PFN_DELETED(Pfn1); + MiDecrementShareCount(Pfn2, Pfn1->u4.PteFrame); + MiDecrementShareCount(Pfn1, PageFrameIndex); + ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress)); + + /* Finally, nuke the PDE itself */ + PageFrameIndex = Process->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT; + Pfn1 = MiGetPfnEntry(PageFrameIndex); + MI_SET_PFN_DELETED(Pfn1); + MiDecrementShareCount(Pfn1, PageFrameIndex); + MiDecrementShareCount(Pfn1, PageFrameIndex); + + /* HACK: In Richard's original patch this ASSERT did work */ + //DPRINT1("Ref count: %lx %lx\n", Pfn1->u3.e2.ReferenceCount, Pfn1->u2.ShareCount); + //ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress)); + } + else + { + /* A partly-initialized process should never exit through here */ + ASSERT(FALSE); + } + + /* Release the PFN lock */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + + /* No support for sessions yet */ + ASSERT(Process->Session == 0); + + /* Clear out the PDE pages */ + Process->Pcb.DirectoryTableBase[0] = 0; + Process->Pcb.DirectoryTableBase[1] = 0; +} + /* SESSION CODE TO MOVE TO SESSION.C ******************************************/
KGUARDED_MUTEX MiSessionIdMutex;
Modified: branches/arty-newcc/ntoskrnl/mm/ARM3/sysldr.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/ARM3/sysl... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/ARM3/sysldr.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/ARM3/sysldr.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -1373,6 +1373,243 @@
VOID NTAPI +MiFreeInitializationCode(IN PVOID InitStart, + IN PVOID InitEnd) +{ + PMMPTE PointerPte; + PFN_NUMBER PagesFreed; + + /* Get the start PTE */ + PointerPte = MiAddressToPte(InitStart); + ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE); + + /* Compute the number of pages we expect to free */ + PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte + 1); + + /* Try to actually free them */ + PagesFreed = MiDeleteSystemPageableVm(PointerPte, + PagesFreed, + 0, + NULL); +} + +VOID +NTAPI +INIT_FUNCTION +MiFindInitializationCode(OUT PVOID *StartVa, + OUT PVOID *EndVa) +{ + ULONG Size, SectionCount, Alignment; + PLDR_DATA_TABLE_ENTRY LdrEntry; + ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode; + PLIST_ENTRY NextEntry; + PIMAGE_NT_HEADERS NtHeader; + PIMAGE_SECTION_HEADER Section, LastSection; + BOOLEAN InitFound; + + /* So we don't free our own code yet */ + InitCode = (ULONG_PTR)&MiFindInitializationCode; + + /* Assume failure */ + *StartVa = NULL; + + /* Enter a critical region while we loop the list */ + KeEnterCriticalRegion(); + + /* Loop all loaded modules */ + NextEntry = PsLoadedModuleList.Flink; + while (NextEntry != &PsLoadedModuleList) + { + /* Get the loader entry and its DLL base */ + LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + DllBase = (ULONG_PTR)LdrEntry->DllBase; + + /* Get the NT header */ + NtHeader = RtlImageNtHeader((PVOID)DllBase); + if (!NtHeader) + { + /* Keep going */ + NextEntry = NextEntry->Flink; + continue; + } + + /* Get the first section, the section count, and scan them all */ + Section = IMAGE_FIRST_SECTION(NtHeader); + SectionCount = NtHeader->FileHeader.NumberOfSections; + InitStart = 0; + while (SectionCount > 0) + { + /* Assume failure */ + InitFound = FALSE; + + /* Is this the INIT section or a discardable section? */ + if ((*(PULONG)Section->Name == 'TINI') || + ((Section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE))) + { + /* Remember this */ + InitFound = TRUE; + } + + if (InitFound) + { + /* Pick the biggest size -- either raw or virtual */ + Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize); + + /* Read the section alignment */ + Alignment = NtHeader->OptionalHeader.SectionAlignment; + + /* Align the start and end addresses appropriately */ + InitStart = DllBase + Section->VirtualAddress; + InitEnd = ((Alignment + InitStart + Size - 2) & 0xFFFFF000) - 1; + InitStart = (InitStart + (PAGE_SIZE - 1)) & 0xFFFFF000; + + /* Have we reached the last section? */ + if (SectionCount == 1) + { + /* Remember this */ + LastSection = Section; + } + else + { + /* We have not, loop all the sections */ + LastSection = NULL; + do + { + /* Keep going until we find a non-discardable section range */ + SectionCount--; + Section++; + if (Section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) + { + /* Discardable, so record it, then keep going */ + LastSection = Section; + } + else + { + /* Non-contigous discard flag, or no flag, break out */ + break; + } + } + while (SectionCount > 1); + } + + /* Have we found a discardable or init section? */ + if (LastSection) + { + /* Pick the biggest size -- either raw or virtual */ + Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize); + + /* Use this as the end of the section address */ + InitEnd = DllBase + LastSection->VirtualAddress + Size - 1; + + /* Have we reached the last section yet? */ + if (SectionCount != 1) + { + /* Then align this accross the session boundary */ + InitEnd = ((Alignment + InitEnd - 1) & 0XFFFFF000) - 1; + } + } + + /* Make sure we don't let the init section go past the image */ + ImageEnd = DllBase + LdrEntry->SizeOfImage; + if (InitEnd > ImageEnd) InitEnd = (ImageEnd - 1) | (PAGE_SIZE - 1); + + /* Make sure we have a valid, non-zero init section */ + if (InitStart <= InitEnd) + { + /* Make sure we are not within this code itself */ + if ((InitCode >= InitStart) && (InitCode <= InitEnd)) + { + /* Return it, we can't free ourselves now */ + ASSERT(*StartVa == 0); + *StartVa = (PVOID)InitStart; + *EndVa = (PVOID)InitEnd; + } + else + { + /* This isn't us -- go ahead and free it */ + ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE); + MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd); + } + } + } + + /* Move to the next section */ + SectionCount--; + Section++; + } + + /* Move to the next module */ + NextEntry = NextEntry->Flink; + } + + /* Leave the critical region and return */ + KeLeaveCriticalRegion(); +} + +/* + * Note: This function assumes that all discardable sections are at the end of + * the PE file. It searches backwards until it finds the non-discardable section + */ +VOID +NTAPI +MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry) +{ + PMMPTE StartPte, EndPte; + PFN_NUMBER PageCount; + PVOID DllBase; + ULONG i; + PIMAGE_NT_HEADERS NtHeader; + PIMAGE_SECTION_HEADER Section, DiscardSection; + ULONG PagesDeleted; + + /* Get the base address and the page count */ + DllBase = LdrEntry->DllBase; + PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT; + + /* Get the last PTE in this image */ + EndPte = MiAddressToPte(DllBase) + PageCount; + + /* Get the NT header */ + NtHeader = RtlImageNtHeader(DllBase); + if (!NtHeader) return; + + /* Get the last section and loop each section backwards */ + Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections; + DiscardSection = NULL; + for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++) + { + /* Go back a section and check if it's discardable */ + Section--; + if (Section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) + { + /* It is, select it for freeing */ + DiscardSection = Section; + } + else + { + /* No more discardable sections exist, bail out */ + break; + } + } + + /* Bail out if there's nothing to free */ + if (!DiscardSection) return; + + /* Push the DLL base to the first disacrable section, and get its PTE */ + DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress); + ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE); + StartPte = MiAddressToPte(DllBase); + + /* Check how many pages to free total */ + PageCount = (PFN_NUMBER)(EndPte - StartPte); + if (!PageCount) return; + + /* Delete this many PTEs */ + PagesDeleted = MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL); +} + +VOID +NTAPI INIT_FUNCTION MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock) {
Modified: branches/arty-newcc/ntoskrnl/mm/ARM3/vadnode.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/ARM3/vadn... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/ARM3/vadnode.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/ARM3/vadnode.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -380,7 +380,7 @@ /* Compute page length, make sure the boundary address is valid */ Length = ROUND_TO_PAGES(Length); PageCount = Length >> PAGE_SHIFT; - if ((BoundaryAddress + 1) < Length) return STATUS_NO_MEMORY; + if ((BoundaryAddress + 1) < Length) return TableFoundNode;
/* Check if the table is empty */ if (Table->NumberGenericTableElements == 0)
Modified: branches/arty-newcc/ntoskrnl/mm/ARM3/virtual.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/ARM3/virt... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -240,7 +240,7 @@ if (Pfn1->u3.e1.PrototypePte == 1) { /* Get the PDE and make sure it's faulted in */ - PointerPde = MiAddressToPde(PointerPte); + PointerPde = MiPteToPde(PointerPte); if (PointerPde->u.Hard.Valid == 0) { #if (_MI_PAGING_LEVELS == 2) @@ -258,14 +258,27 @@ #if (_MI_PAGING_LEVELS == 2) } #endif - /* FIXME: Drop the reference on the page table. For now, leak it until RosMM is gone */ - //MiDecrementShareCount(MiGetPfnEntry(PFN_FROM_PTE(PointerPde)), PFN_FROM_PTE(PointerPde)); + /* Drop the reference on the page table. */ + MiDecrementShareCount(MiGetPfnEntry(PFN_FROM_PTE(PointerPde)), PFN_FROM_PTE(PointerPde));
/* Drop the share count */ MiDecrementShareCount(Pfn1, PageFrameIndex);
- /* No fork yet */ - if (PointerPte <= MiHighestUserPte) ASSERT(PrototypePte == Pfn1->PteAddress); + /* Either a fork, or this is the shared user data page */ + if (PointerPte <= MiHighestUserPte) + { + /* If it's not the shared user page, then crash, since there's no fork() yet */ + if ((PAGE_ALIGN(VirtualAddress) != (PVOID)USER_SHARED_DATA) || + (MmHighestUserAddress <= (PVOID)USER_SHARED_DATA)) + { + /* Must be some sort of memory corruption */ + KeBugCheckEx(MEMORY_MANAGEMENT, + 0x400, + (ULONG_PTR)PointerPte, + (ULONG_PTR)PrototypePte, + (ULONG_PTR)Pfn1->PteAddress); + } + } } else { @@ -284,7 +297,8 @@ ASSERT(Pfn1->u2.ShareCount == 1);
/* FIXME: Drop the reference on the page table. For now, leak it until RosMM is gone */ - //MiDecrementShareCount(MiGetPfnEntry(Pfn1->u4.PteFrame), Pfn1->u4.PteFrame); + //DPRINT1("Dropping a ref...\n"); + MiDecrementShareCount(MiGetPfnEntry(Pfn1->u4.PteFrame), Pfn1->u4.PteFrame);
/* Mark the PFN for deletion and dereference what should be the last ref */ MI_SET_PFN_DELETED(Pfn1); @@ -312,6 +326,7 @@ KIRQL OldIrql; BOOLEAN AddressGap = FALSE; PSUBSECTION Subsection; + PUSHORT UsedPageTableEntries;
/* Get out if this is a fake VAD, RosMm will free the marea pages */ if ((Vad) && (Vad->u.VadFlags.Spare == 1)) return; @@ -368,6 +383,7 @@ /* Now we should have a valid PDE, mapped in, and still have some VA */ ASSERT(PointerPde->u.Hard.Valid == 1); ASSERT(Va <= EndingAddress); + UsedPageTableEntries = &MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Va)];
/* Check if this is a section VAD with gaps in it */ if ((AddressGap) && (LastPrototypePte)) @@ -397,6 +413,11 @@ TempPte = *PointerPte; if (TempPte.u.Long) { + DPRINT("Decrement used PTEs by address: %lx\n", Va); + (*UsedPageTableEntries)--; + ASSERT((*UsedPageTableEntries) < PTE_COUNT); + DPRINT("Refs: %lx\n", (*UsedPageTableEntries)); + /* Check if the PTE is actually mapped in */ if (TempPte.u.Long & 0xFFFFFC01) { @@ -456,6 +477,22 @@ /* The PDE should still be valid at this point */ ASSERT(PointerPde->u.Hard.Valid == 1);
+ DPRINT("Should check if handles for: %p are zero (PDE: %lx)\n", Va, PointerPde->u.Hard.PageFrameNumber); + if (!(*UsedPageTableEntries)) + { + DPRINT("They are!\n"); + if (PointerPde->u.Long != 0) + { + DPRINT("PDE active: %lx in %16s\n", PointerPde->u.Hard.PageFrameNumber, CurrentProcess->ImageFileName); + + /* Delete the PTE proper */ + MiDeletePte(PointerPde, + MiPteToAddress(PointerPde), + CurrentProcess, + NULL); + } + } + /* Release the lock and get out if we're done */ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); if (Va > EndingAddress) return; @@ -2773,4 +2810,359 @@ return Status; }
+#ifdef __USE_ARM3__ +/* +* @implemented +*/ +NTSTATUS +NTAPI +NtAllocateVirtualMemory(IN HANDLE ProcessHandle, + IN OUT PVOID* UBaseAddress, + IN ULONG_PTR ZeroBits, + IN OUT PSIZE_T URegionSize, + IN ULONG AllocationType, + IN ULONG Protect) +{ + PEPROCESS Process; + ULONG Type; + NTSTATUS Status = STATUS_SUCCESS; + PVOID BaseAddress; + ULONG RegionSize; + PMMVAD Vad; + PMMADDRESS_NODE ParentNode; + ULONG_PTR StartVpn, EndVpn; + PHYSICAL_ADDRESS BoundaryAddressMultiple; + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); + KAPC_STATE ApcState; + ULONG ProtectionMask; + BOOLEAN Attached = FALSE; + BoundaryAddressMultiple.QuadPart = 0; + TABLE_SEARCH_RESULT Result; + + PAGED_CODE(); + + /* Check for valid Zero bits */ + if (ZeroBits > 21) + { + DPRINT1("Too many zero bits\n"); + return STATUS_INVALID_PARAMETER_3; + } + + /* Check for valid Allocation Types */ + if ((AllocationType & ~(MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_PHYSICAL | + MEM_TOP_DOWN | MEM_WRITE_WATCH))) + { + DPRINT1("Invalid Allocation Type\n"); + return STATUS_INVALID_PARAMETER_5; + } + + /* Check for at least one of these Allocation Types to be set */ + if (!(AllocationType & (MEM_COMMIT | MEM_RESERVE | MEM_RESET))) + { + DPRINT1("No memory allocation base type\n"); + return STATUS_INVALID_PARAMETER_5; + } + + /* MEM_RESET is an exclusive flag, make sure that is valid too */ + if ((AllocationType & MEM_RESET) && (AllocationType != MEM_RESET)) + { + DPRINT1("Invalid use of MEM_RESET\n"); + return STATUS_INVALID_PARAMETER_5; + } + + /* Check if large pages are being used */ + if (AllocationType & MEM_LARGE_PAGES) + { + /* Large page allocations MUST be committed */ + if (!(AllocationType & MEM_COMMIT)) + { + DPRINT1("Must supply MEM_COMMIT with MEM_LARGE_PAGES\n"); + return STATUS_INVALID_PARAMETER_5; + } + + /* These flags are not allowed with large page allocations */ + if (AllocationType & (MEM_PHYSICAL | MEM_RESET | MEM_WRITE_WATCH)) + { + DPRINT1("Using illegal flags with MEM_LARGE_PAGES\n"); + return STATUS_INVALID_PARAMETER_5; + } + } + + /* MEM_WRITE_WATCH can only be used if MEM_RESERVE is also used */ + if ((AllocationType & MEM_WRITE_WATCH) && !(AllocationType & MEM_RESERVE)) + { + DPRINT1("MEM_WRITE_WATCH used without MEM_RESERVE\n"); + return STATUS_INVALID_PARAMETER_5; + } + + /* MEM_PHYSICAL can only be used if MEM_RESERVE is also used */ + if ((AllocationType & MEM_PHYSICAL) && !(AllocationType & MEM_RESERVE)) + { + DPRINT1("MEM_WRITE_WATCH used without MEM_RESERVE\n"); + return STATUS_INVALID_PARAMETER_5; + } + + /* Check for valid MEM_PHYSICAL usage */ + if (AllocationType & MEM_PHYSICAL) + { + /* Only these flags are allowed with MEM_PHYSIAL */ + if (AllocationType & ~(MEM_RESERVE | MEM_TOP_DOWN | MEM_PHYSICAL)) + { + DPRINT1("Using illegal flags with MEM_PHYSICAL\n"); + return STATUS_INVALID_PARAMETER_5; + } + + /* Then make sure PAGE_READWRITE is used */ + if (Protect != PAGE_READWRITE) + { + DPRINT1("MEM_PHYSICAL used without PAGE_READWRITE\n"); + return STATUS_INVALID_PARAMETER_6; + } + } + + /* Calculate the protection mask and make sure it's valid */ + ProtectionMask = MiMakeProtectionMask(Protect); + if (ProtectionMask == MM_INVALID_PROTECTION) + { + DPRINT1("Invalid protection mask\n"); + return STATUS_INVALID_PAGE_PROTECTION; + } + + /* Enter SEH */ + _SEH2_TRY + { + /* Check for user-mode parameters */ + if (PreviousMode != KernelMode) + { + /* Make sure they are writable */ + ProbeForWritePointer(UBaseAddress); + ProbeForWriteUlong(URegionSize); + } + + /* Capture their values */ + BaseAddress = *UBaseAddress; + RegionSize = *URegionSize; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + /* Make sure there's a size specified */ + if (!RegionSize) + { + DPRINT1("Region size is invalid (zero)\n"); + return STATUS_INVALID_PARAMETER_4; + } + + RegionSize = PAGE_ROUND_UP((ULONG_PTR)BaseAddress + RegionSize) - + PAGE_ROUND_DOWN(BaseAddress); + BaseAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress); + StartVpn = (ULONG_PTR)BaseAddress >> PAGE_SHIFT; + EndVpn = ((ULONG_PTR)BaseAddress + RegionSize - 1) >> PAGE_SHIFT; + + /* Make sure the allocation isn't past the VAD area */ + if (BaseAddress >= MM_HIGHEST_VAD_ADDRESS) + { + DPRINT1("Virtual allocation base above User Space\n"); + return STATUS_INVALID_PARAMETER_2; + } + + /* Make sure the allocation wouldn't overflow past the VAD area */ + if ((((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) - (ULONG_PTR)BaseAddress) < RegionSize) + { + DPRINT1("Region size would overflow into kernel-memory\n"); + return STATUS_INVALID_PARAMETER_4; + } + + /* Check if this is for the current process */ + if (ProcessHandle == NtCurrentProcess()) + { + /* We already have the current process, no need to go through Ob */ + Process = CurrentProcess; + } + else + { + /* Reference the handle for correct permissions */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if not running in the current process */ + if (CurrentProcess != Process) + { + /* Attach to it */ + KeStackAttachProcess(&Process->Pcb, &ApcState); + Attached = TRUE; + } + } + + /* Check for large page allocations */ + if (AllocationType & MEM_LARGE_PAGES) + { + /* The lock memory privilege is required */ + if (!SeSinglePrivilegeCheck(SeLockMemoryPrivilege, PreviousMode)) + { + /* Fail without it */ + DPRINT1("Privilege not held for MEM_LARGE_PAGES\n"); + if (Attached) KeUnstackDetachProcess(&ApcState); + if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); + return STATUS_PRIVILEGE_NOT_HELD; + } + } + + + /* + * Copy on Write is reserved for system use. This case is a certain failure + * but there may be other cases...needs more testing + */ + if ((!BaseAddress || (AllocationType & MEM_RESERVE)) && + (Protect & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY))) + { + DPRINT1("Copy on write is not supported by VirtualAlloc\n"); + if (Attached) KeUnstackDetachProcess(&ApcState); + if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); + return STATUS_INVALID_PAGE_PROTECTION; + } + + Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE; + DPRINT("Type %x\n", Type); + + /* Lock the process address space */ + KeAcquireGuardedMutex(&Process->AddressCreationLock); + + if(BaseAddress != 0) + { + /* + * An address was provided. Let's see if we've already + * something there + */ + if(MiCheckForConflictingNode(StartVpn, EndVpn, &Process->VadRoot) != NULL) + { + /* Can't reserve twice the same range */ + if(AllocationType & MEM_RESERVE) + { + Status = STATUS_CONFLICTING_ADDRESSES; + DPRINT1("Trying to reserve twice the same range.\n"); + goto cleanup; + } + /* Great there's already something there. What shall we do ? */ + if(AllocationType == MEM_RESET) + { + UNIMPLEMENTED; + /* Reset the dirty bits for each PTEs */ + goto cleanup; + } + else + { + ASSERT(AllocationType & MEM_COMMIT); + UNIMPLEMENTED; + /* Mark the VAD as committed */ + goto cleanup; + } + } + + /* There's nothing */ + if(!(AllocationType & MEM_RESERVE)) + { + Status = STATUS_ACCESS_DENIED; + goto cleanup; + } + + /* Now we can reserve our chunk of memory */ + goto buildVad; + } + + /* No base address was given. */ + if(!(AllocationType & MEM_RESERVE)) + { + DPRINT1("Providing NULL base address witout MEM_RESERVE.\n"); + ASSERT(FALSE); + Status = STATUS_INVALID_PARAMETER_5; + goto cleanup; + } + + /* Find an empty range in Address Space */ + if(AllocationType & MEM_TOP_DOWN) + { + /* Top down allocation */ + Result = MiFindEmptyAddressRangeDownTree(RegionSize, + (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS, + (ZeroBits > PAGE_SHIFT) ? 1 << ZeroBits : PAGE_SIZE, + &Process->VadRoot, + (PULONG_PTR)&BaseAddress, + &ParentNode); + + if(Result == TableFoundNode) + { + /* This means failure */ + Status = STATUS_NO_MEMORY; + goto cleanup; + } + } + else + { + /* Good old bottom up allocation */ + Status = MiFindEmptyAddressRangeInTree(RegionSize, + (ZeroBits > PAGE_SHIFT) ? 1 << ZeroBits : PAGE_SIZE, + &Process->VadRoot, + &ParentNode, + (PULONG_PTR)&BaseAddress); + if(!NT_SUCCESS(Status)) + { + /* Failed... */ + goto cleanup; + } + } + StartVpn = (ULONG_PTR)BaseAddress >> PAGE_SHIFT; + EndVpn = ((ULONG_PTR)BaseAddress + RegionSize - 1) >> PAGE_SHIFT; + + /* Build the Vad */ +buildVad: + Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD), TAG_MVAD); + if(!Vad) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + RtlZeroMemory(Vad, sizeof(MMVAD)); + + /* Set min/max */ + Vad->StartingVpn = StartVpn; + Vad->EndingVpn = EndVpn; + /* Set protection */ + Vad->u.VadFlags.Protection = ProtectionMask; + /* Should it be already marked as committed ? */ + if(AllocationType & MEM_COMMIT) + Vad->u.VadFlags.MemCommit = 1; + if(AllocationType & MEM_PHYSICAL) + { + UNIMPLEMENTED; + Vad->u.VadFlags.VadType = VadAwe; + } + /* Add it */ + MiLockProcessWorkingSet(Process, PsGetCurrentThread()); + MiInsertVad(Vad, Process); + MiUnlockProcessWorkingSet(Process, PsGetCurrentThread()); + + /* we're done */ +cleanup: + KeReleaseGuardedMutex(&Process->AddressCreationLock); + if (Attached) KeUnstackDetachProcess(&ApcState); + if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); + + *UBaseAddress = BaseAddress; + *URegionSize = RegionSize; + DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize); + + return Status; +} +#endif /* EOF */
Modified: branches/arty-newcc/ntoskrnl/mm/ARM3/zeropage.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/ARM3/zero... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/ARM3/zeropage.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/ARM3/zeropage.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -24,19 +24,29 @@
VOID NTAPI +MiFindInitializationCode(OUT PVOID *StartVa, +OUT PVOID *EndVa); + +VOID +NTAPI +MiFreeInitializationCode(IN PVOID StartVa, +IN PVOID EndVa); + +VOID +NTAPI MmZeroPageThread(VOID) { PKTHREAD Thread = KeGetCurrentThread(); - //PVOID StartAddress, EndAddress; + PVOID StartAddress, EndAddress; PVOID WaitObjects[2]; KIRQL OldIrql; PVOID ZeroAddress; PFN_NUMBER PageIndex, FreePage; PMMPFN Pfn1;
- /* FIXME: Get the discardable sections to free them */ -// MiFindInitializationCode(&StartAddress, &EndAddress); -// if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress); + /* Get the discardable sections to free them */ + MiFindInitializationCode(&StartAddress, &EndAddress); + if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress); DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
/* Set our priority to 0 */
Modified: branches/arty-newcc/ntoskrnl/mm/amd64/page.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/amd64/pag... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/amd64/page.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/amd64/page.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -188,29 +188,6 @@ } }
-VOID -NTAPI -MmDeleteProcessPageDirectory(PEPROCESS Process) -{ - PFN_NUMBER TableBasePfn; - PMMPTE PageDir; - - /* Get the page directory PFN */ - TableBasePfn = Process->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT; - - /* Map the page directory in hyperspace */ - PageDir = (PMMPTE)MmCreateHyperspaceMapping(TableBasePfn); - - /* Free the hyperspace mapping page (ARM3) */ - //MmDeletePageTablePfn(PageDir[ADDR_TO_PDE_OFFSET(HYPERSPACE)].u.Hard.PageFrameNumber, 3); - - /* Delete the hyperspace mapping */ - MmDeleteHyperspaceMapping(PageDir); - - /* Recursively free the page directories */ - MmDeletePageTablePfn(TableBasePfn, 4); -} - static PMMPTE MiGetPteForProcess(
Modified: branches/arty-newcc/ntoskrnl/mm/anonmem.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/anonmem.c... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/anonmem.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/anonmem.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -528,6 +528,7 @@ return Status; }
+#ifndef __USE_ARM3__ /* * @implemented */ @@ -900,6 +901,7 @@
return(STATUS_SUCCESS); } +#endif // __USE_ARM3__
static VOID MmFreeVirtualMemoryPage(PVOID Context,
Modified: branches/arty-newcc/ntoskrnl/mm/i386/page.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/i386/page... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/i386/page.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/i386/page.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -42,8 +42,6 @@
#define HYPERSPACE (0xc0400000) #define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000)) - -ULONG MmGlobalKernelPageDirectory[1024];
#define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT) #define PFN_TO_PTE(X) ((X) << PAGE_SHIFT) @@ -200,72 +198,45 @@ return(Attributes); }
-static -VOID -MmDeletePageDirectoryEntry(ULONG PdeEntry) -{ - KIRQL OldIrql; - PMMPFN Page; - - Page = MiGetPfnEntry(PTE_TO_PFN(PdeEntry)); - - /* Check if this is a legacy allocation */ - if (MI_IS_ROS_PFN(Page)) - { - /* Free it using the legacy API */ - MmReleasePageMemoryConsumer(MC_SYSTEM, PTE_TO_PFN(PdeEntry)); - } - else - { - OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - - /* Free it using the ARM3 API */ - MI_SET_PFN_DELETED(Page); - MiDecrementShareCount(Page, PTE_TO_PFN(PdeEntry)); - - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - } -} - -VOID -NTAPI -MmDeleteProcessPageDirectory(PEPROCESS Process) -{ - PULONG PageDir; - ULONG PdeOffset; - - /* Map the page directory in hyperspace */ - PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0])); - - /* Loop the user land page directory */ - for (PdeOffset = 0; PdeOffset < ADDR_TO_PDE_OFFSET(MmSystemRangeStart); PdeOffset++) - { - /* Check if a valid PDE exists here */ - if (PageDir[PdeOffset] != 0) - { - /* Free the page that backs it */ - MmDeletePageDirectoryEntry(PageDir[PdeOffset]); - } - } - - /* Free the hyperspace mapping page (ARM3) */ - MmDeletePageDirectoryEntry(PageDir[ADDR_TO_PDE_OFFSET(HYPERSPACE)]); - - /* Delete the hyperspace mapping */ - MmDeleteHyperspaceMapping(PageDir); - - /* Free the PDE page itself (ARM3) */ - MmDeletePageDirectoryEntry(Process->Pcb.DirectoryTableBase[0]); -} +/* Taken from ARM3/pagfault.c */ +BOOLEAN +FORCEINLINE +MiSynchronizeSystemPde(PMMPDE PointerPde) +{ + MMPDE SystemPde; + ULONG Index; + + /* Get the Index from the PDE */ + Index = ((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE); + + /* Copy the PDE from the double-mapped system page directory */ + SystemPde = MmSystemPagePtes[Index]; + *PointerPde = SystemPde; + + /* Make sure we re-read the PDE and PTE */ + KeMemoryBarrierWithoutFence(); + + /* Return, if we had success */ + return (BOOLEAN)SystemPde.u.Hard.Valid; +} + +NTSTATUS +NTAPI +MiResolveDemandZeroFault(IN PVOID Address, + IN ULONG Protection, + IN PEPROCESS Process, + IN KIRQL OldIrql); +VOID +NTAPI +MiFillSystemPageDirectory(IN PVOID Base, + IN SIZE_T NumberOfBytes);
static PULONG MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create) { - ULONG PdeOffset = ADDR_TO_PDE_OFFSET(Address); - NTSTATUS Status; PFN_NUMBER Pfn; - ULONG Entry; - PULONG Pt, PageDir; + PULONG Pt; + PMMPDE PointerPde;
if (Address < MmSystemRangeStart) { @@ -274,39 +245,28 @@
if(Process != PsGetCurrentProcess()) { - PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0])); - if (PageDir == NULL) + PMMPDE PdeBase; + ULONG PdeOffset = MiGetPdeOffset(Address); + + PdeBase = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0])); + if (PdeBase == NULL) { KeBugCheck(MEMORY_MANAGEMENT); } - if (0 == InterlockedCompareExchangePte(&PageDir[PdeOffset], 0, 0)) + PointerPde = PdeBase + PdeOffset; + if (PointerPde->u.Hard.Valid == 0) { - if (Create == FALSE) - { - MmDeleteHyperspaceMapping(PageDir); - return NULL; - } - MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY); - - MI_SET_PROCESS2(Process->ImageFileName); - - Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn); - if (!NT_SUCCESS(Status) || Pfn == 0) - { - KeBugCheck(MEMORY_MANAGEMENT); - } - Entry = InterlockedCompareExchangePte(&PageDir[PdeOffset], PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0); - if (Entry != 0) - { - MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn); - Pfn = PTE_TO_PFN(Entry); - } + /* Nobody but page fault should ask for creating the PDE, + * Which imples that Process is the current one */ + ASSERT(Create == FALSE); + MmDeleteHyperspaceMapping(PdeBase); + return NULL; } else { - Pfn = PTE_TO_PFN(PageDir[PdeOffset]); + Pfn = PointerPde->u.Hard.PageFrameNumber; } - MmDeleteHyperspaceMapping(PageDir); + MmDeleteHyperspaceMapping(PdeBase); Pt = MmCreateHyperspaceMapping(Pfn); if (Pt == NULL) { @@ -315,59 +275,38 @@ return Pt + MiAddressToPteOffset(Address); } /* This is for our process */ - PageDir = (PULONG)MiAddressToPde(Address); - if (0 == InterlockedCompareExchangePte(PageDir, 0, 0)) + PointerPde = MiAddressToPde(Address); + Pt = (PULONG)MiAddressToPte(Address); + if (PointerPde->u.Hard.Valid == 0) { if (Create == FALSE) { return NULL; } - MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY); - MI_SET_PROCESS2(Process->ImageFileName); - - Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn); - if (!NT_SUCCESS(Status) || Pfn == 0) - { - KeBugCheck(MEMORY_MANAGEMENT); - } - Entry = InterlockedCompareExchangePte(PageDir, PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0); - if (Entry != 0) - { - MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn); - } + MiResolveDemandZeroFault(Pt, + MM_READWRITE, + Process, + MM_NOIRQL); + ASSERT(PointerPde->u.Hard.Valid == 1); } return (PULONG)MiAddressToPte(Address); }
/* This is for kernel land address */ - PageDir = (PULONG)MiAddressToPde(Address); - if (0 == InterlockedCompareExchangePte(PageDir, 0, 0)) - { - if (0 == InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], 0, 0)) - { - if (Create == FALSE) - { + PointerPde = MiAddressToPde(Address); + Pt = (PULONG)MiAddressToPte(Address); + if (PointerPde->u.Hard.Valid == 0) + { + /* Let ARM3 synchronize the PDE */ + if(!MiSynchronizeSystemPde(PointerPde)) + { + /* PDE (still) not valid, let ARM3 allocate one if asked */ + if(Create == FALSE) return NULL; - } - MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY); - if (Process) MI_SET_PROCESS2(Process->ImageFileName); - if (!Process) MI_SET_PROCESS2("Kernel Legacy"); - Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn); - if (!NT_SUCCESS(Status) || Pfn == 0) - { - KeBugCheck(MEMORY_MANAGEMENT); - } - Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE; - if(0 != InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 0)) - { - MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn); - } - InterlockedExchangePte(PageDir, MmGlobalKernelPageDirectory[PdeOffset]); - return (PULONG)MiAddressToPte(Address); - } - InterlockedExchangePte(PageDir, MmGlobalKernelPageDirectory[PdeOffset]); - } - return (PULONG)MiAddressToPte(Address); + MiFillSystemPageDirectory(Address, PAGE_SIZE); + } + } + return Pt; }
BOOLEAN MmUnmapPageTable(PULONG Pt) @@ -599,19 +538,18 @@ }
BOOLEAN -Mmi386MakeKernelPageTableGlobal(PVOID PAddress) -{ - PULONG Pt, Pde; - Pde = (PULONG)MiAddressToPde(PAddress); - if (*Pde == 0) - { - Pt = MmGetPageTableForProcess(NULL, PAddress, FALSE); - if (Pt != NULL) - { - return TRUE; - } - } - return(FALSE); +Mmi386MakeKernelPageTableGlobal(PVOID Address) +{ + PMMPDE PointerPde = MiAddressToPde(Address); + PMMPTE PointerPte = MiAddressToPte(Address); + + if (PointerPde->u.Hard.Valid == 0) + { + if(!MiSynchronizeSystemPde(PointerPde)) + return FALSE; + return PointerPte->u.Hard.Valid; + } + return FALSE; }
BOOLEAN @@ -1034,20 +972,7 @@ NTAPI MmInitGlobalKernelPageDirectory(VOID) { - ULONG i; - PULONG CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP; - - DPRINT("MmInitGlobalKernelPageDirectory()\n"); - - for (i = ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 1024; i++) - { - if (i != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) && - i != ADDR_TO_PDE_OFFSET(HYPERSPACE) && - 0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i]) - { - MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i]; - } - } + /* Nothing to do here */ }
/* EOF */
Modified: branches/arty-newcc/ntoskrnl/mm/marea.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/marea.c?r... ============================================================================== --- branches/arty-newcc/ntoskrnl/mm/marea.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/mm/marea.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -746,7 +746,7 @@ { ASSERT(MemoryArea->EndingAddress < MmSystemRangeStart); ASSERT(MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY || MemoryArea->Type == MEMORY_AREA_SECTION_VIEW || MemoryArea->Type == MEMORY_AREA_CACHE); - + /* MmCleanProcessAddressSpace might have removed it (and this would be MmDeleteProcessAdressSpace) */ ASSERT(((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare != 0); if (((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare == 1) @@ -995,6 +995,10 @@ } }
+VOID +NTAPI +MmDeleteProcessAddressSpace2(IN PEPROCESS Process); + NTSTATUS NTAPI MmDeleteProcessAddressSpace(PEPROCESS Process) @@ -1044,11 +1048,10 @@ } }
- MmDeleteProcessPageDirectory(Process); - MmUnlockAddressSpace(&Process->Vm);
DPRINT("Finished MmReleaseMmInfo()\n"); + MmDeleteProcessAddressSpace2(Process); return(STATUS_SUCCESS); }
Modified: branches/arty-newcc/ntoskrnl/ob/oblife.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/ob/oblife.c?... ============================================================================== --- branches/arty-newcc/ntoskrnl/ob/oblife.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/ob/oblife.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -1605,7 +1605,7 @@ _SEH2_END;
/* Dereference the object if we had referenced it */ - if (Object) ObDereferenceObject (Object); + if (Object) ObDereferenceObject(Object);
/* Return status */ return Status; @@ -1645,91 +1645,128 @@ OBP_SET_HANDLE_ATTRIBUTES_CONTEXT Context; PVOID ObjectTable; KAPC_STATE ApcState; + POBJECT_DIRECTORY Directory; + KPROCESSOR_MODE PreviousMode; BOOLEAN AttachedToProcess = FALSE; PAGED_CODE();
/* Validate the information class */ - if (ObjectInformationClass != ObjectHandleFlagInformation) - { - /* Invalid class */ - return STATUS_INVALID_INFO_CLASS; - } - - /* Validate the length */ - if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) - { - /* Invalid length */ - return STATUS_INFO_LENGTH_MISMATCH; - } - - /* Save the previous mode */ - Context.PreviousMode = ExGetPreviousMode(); - - /* Check if we were called from user mode */ - if (Context.PreviousMode != KernelMode) - { - /* Enter SEH */ - _SEH2_TRY - { - /* Probe and capture the attribute buffer */ - ProbeForRead(ObjectInformation, - sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION), - sizeof(BOOLEAN)); - Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION) - ObjectInformation; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - else - { - /* Just copy the buffer directly */ - Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION) - ObjectInformation; - } - - /* Check if this is a kernel handle */ - if (ObIsKernelHandle(ObjectHandle, Context.PreviousMode)) - { - /* Get the actual handle */ - ObjectHandle = ObKernelHandleToHandle(ObjectHandle); - ObjectTable = ObpKernelHandleTable; - - /* Check if we're not in the system process */ - if (PsGetCurrentProcess() != PsInitialSystemProcess) - { - /* Attach to it */ - KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState); - AttachedToProcess = TRUE; - } - } - else - { - /* Use the current table */ - ObjectTable = PsGetCurrentProcess()->ObjectTable; - } - - /* Change the handle attributes */ - if (!ExChangeHandle(ObjectTable, - ObjectHandle, - ObpSetHandleAttributes, - (ULONG_PTR)&Context)) - { - /* Some failure */ - Status = STATUS_ACCESS_DENIED; - } - else - { - /* We are done */ - Status = STATUS_SUCCESS; - } - - /* De-attach if we were attached, and return status */ - if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); + switch (ObjectInformationClass) + { + case ObjectHandleFlagInformation: + + /* Validate the length */ + if (Length != sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) + { + /* Invalid length */ + return STATUS_INFO_LENGTH_MISMATCH; + } + + /* Save the previous mode */ + Context.PreviousMode = ExGetPreviousMode(); + + /* Check if we were called from user mode */ + if (Context.PreviousMode != KernelMode) + { + /* Enter SEH */ + _SEH2_TRY + { + /* Probe and capture the attribute buffer */ + ProbeForRead(ObjectInformation, + sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION), + sizeof(BOOLEAN)); + Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION) + ObjectInformation; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + /* Just copy the buffer directly */ + Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION) + ObjectInformation; + } + + /* Check if this is a kernel handle */ + if (ObIsKernelHandle(ObjectHandle, Context.PreviousMode)) + { + /* Get the actual handle */ + ObjectHandle = ObKernelHandleToHandle(ObjectHandle); + ObjectTable = ObpKernelHandleTable; + + /* Check if we're not in the system process */ + if (PsGetCurrentProcess() != PsInitialSystemProcess) + { + /* Attach to it */ + KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState); + AttachedToProcess = TRUE; + } + } + else + { + /* Use the current table */ + ObjectTable = PsGetCurrentProcess()->ObjectTable; + } + + /* Change the handle attributes */ + if (!ExChangeHandle(ObjectTable, + ObjectHandle, + ObpSetHandleAttributes, + (ULONG_PTR)&Context)) + { + /* Some failure */ + Status = STATUS_ACCESS_DENIED; + } + else + { + /* We are done */ + Status = STATUS_SUCCESS; + } + + /* De-attach if we were attached, and return status */ + if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); + break; + + case ObjectSessionInformation: + + /* Only a system process can do this */ + PreviousMode = ExGetPreviousMode(); + if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) + { + /* Fail */ + DPRINT1("Privilege not held\n"); + Status = STATUS_PRIVILEGE_NOT_HELD; + } + else + { + /* Get the object directory */ + Status = ObReferenceObjectByHandle(ObjectHandle, + 0, + ObDirectoryType, + PreviousMode, + (PVOID*)&Directory, + NULL); + if (NT_SUCCESS(Status)) + { + /* FIXME: Missng locks */ + /* Set its session ID */ + Directory->SessionId = PsGetCurrentProcessSessionId(); + ObDereferenceObject(Directory); + } + } + break; + + default: + /* Unsupported class */ + Status = STATUS_INVALID_INFO_CLASS; + break; + } + return Status; }
Modified: branches/arty-newcc/ntoskrnl/ps/query.c URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/ps/query.c?r... ============================================================================== --- branches/arty-newcc/ntoskrnl/ps/query.c [iso-8859-1] (original) +++ branches/arty-newcc/ntoskrnl/ps/query.c [iso-8859-1] Sat Feb 18 22:29:24 2012 @@ -835,8 +835,29 @@ break;
case ProcessLUIDDeviceMapsEnabled: - DPRINT1("LUID Device Maps Not implemented: %lx\n", ProcessInformationClass); - Status = STATUS_NOT_IMPLEMENTED; + /* Set the return length */ + Length = sizeof(ULONG); + if (ProcessInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Indicate success */ + Status = STATUS_SUCCESS; + + /* Protect write in SEH */ + _SEH2_TRY + { + /* Return the count of handles */ + *(PULONG)ProcessInformation = FALSE; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; break;
case ProcessExecuteFlags: