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.cm…
==============================================================================
--- 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?r…
==============================================================================
--- 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/dr…
==============================================================================
--- 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/p…
==============================================================================
--- 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?r…
==============================================================================
--- 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?…
==============================================================================
--- 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_cl…
==============================================================================
--- 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/mmi…
==============================================================================
--- 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/pro…
==============================================================================
--- 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/sys…
==============================================================================
--- 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/vad…
==============================================================================
--- 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/vir…
==============================================================================
--- 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/zer…
==============================================================================
--- 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/pa…
==============================================================================
--- 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.…
==============================================================================
--- 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/pag…
==============================================================================
--- 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?…
==============================================================================
--- 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?…
==============================================================================
--- 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: