[RSHELL]
[reactos.git] / ntoskrnl / mm / section.c
index 8761620..243a837 100644 (file)
@@ -45,6 +45,8 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+#include "../cache/newcc.h"
+#include "../cache/section/newmm.h"
 #define NDEBUG
 #include <debug.h>
 #include <reactos/exeformat.h>
 #pragma alloc_text(INIT, MmInitSectionImplementation)
 #endif
 
+#include "ARM3/miarm.h"
+
+#undef MmSetPageEntrySectionSegment
+#define MmSetPageEntrySectionSegment(S,O,E) do { \
+        DPRINT("SetPageEntrySectionSegment(old,%p,%x,%x)\n",(S),(O)->LowPart,E); \
+        _MmSetPageEntrySectionSegment((S),(O),(E),__FILE__,__LINE__);   \
+       } while (0)
+
+extern MMSESSION MmSession;
+
+NTSTATUS
+NTAPI
+MiMapViewInSystemSpace(IN PVOID Section,
+IN PVOID Session,
+OUT PVOID *MappedBase,
+IN OUT PSIZE_T ViewSize);
+
+NTSTATUS
+NTAPI
+MmCreateArm3Section(OUT PVOID *SectionObject,
+IN ACCESS_MASK DesiredAccess,
+IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+IN PLARGE_INTEGER InputMaximumSize,
+IN ULONG SectionPageProtection,
+IN ULONG AllocationAttributes,
+IN HANDLE FileHandle OPTIONAL,
+IN PFILE_OBJECT FileObject OPTIONAL);
+
+NTSTATUS
+NTAPI
+MmMapViewOfArm3Section(IN PVOID SectionObject,
+                       IN PEPROCESS Process,
+                       IN OUT PVOID *BaseAddress,
+                       IN ULONG_PTR ZeroBits,
+                       IN SIZE_T CommitSize,
+                       IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
+                       IN OUT PSIZE_T ViewSize,
+                       IN SECTION_INHERIT InheritDisposition,
+                       IN ULONG AllocationType,
+                       IN ULONG Protect);
+
+//
+// PeFmtCreateSection depends on the following:
+//
+C_ASSERT(EXEFMT_LOAD_HEADER_SIZE >= sizeof(IMAGE_DOS_HEADER));
+C_ASSERT(sizeof(IMAGE_NT_HEADERS32) <= sizeof(IMAGE_NT_HEADERS64));
+
+C_ASSERT(TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) == TYPE_ALIGNMENT(IMAGE_NT_HEADERS64));
+C_ASSERT(RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader) == RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS64, FileHeader));
+C_ASSERT(FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader) == FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader));
+
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Magic));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SectionAlignment));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, FileAlignment));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Subsystem));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, AddressOfEntryPoint));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfCode));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfHeaders));
 
 /* TYPES *********************************************************************/
 
@@ -61,9 +123,11 @@ typedef struct
 {
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
-   ULONG Offset;
+   LARGE_INTEGER Offset;
    BOOLEAN WasDirty;
    BOOLEAN Private;
+   PEPROCESS CallingProcess;
+   ULONG_PTR SectionEntry;
 }
 MM_SECTION_PAGEOUT_CONTEXT;
 
@@ -71,25 +135,40 @@ MM_SECTION_PAGEOUT_CONTEXT;
 
 POBJECT_TYPE MmSectionObjectType = NULL;
 
-BOOLEAN MmAllocationFragment;
-
 ULONG_PTR MmSubsectionBase;
 
+static ULONG SectionCharacteristicsToProtect[16] =
+{
+    PAGE_NOACCESS,          /* 0 = NONE */
+    PAGE_NOACCESS,          /* 1 = SHARED */
+    PAGE_EXECUTE,           /* 2 = EXECUTABLE */
+    PAGE_EXECUTE,           /* 3 = EXECUTABLE, SHARED */
+    PAGE_READONLY,          /* 4 = READABLE */
+    PAGE_READONLY,          /* 5 = READABLE, SHARED */
+    PAGE_EXECUTE_READ,      /* 6 = READABLE, EXECUTABLE */
+    PAGE_EXECUTE_READ,      /* 7 = READABLE, EXECUTABLE, SHARED */
+    /*
+     * FIXME? do we really need the WriteCopy field in segments? can't we use
+     * PAGE_WRITECOPY here?
+     */
+    PAGE_READWRITE,         /* 8 = WRITABLE */
+    PAGE_READWRITE,         /* 9 = WRITABLE, SHARED */
+    PAGE_EXECUTE_READWRITE, /* 10 = WRITABLE, EXECUTABLE */
+    PAGE_EXECUTE_READWRITE, /* 11 = WRITABLE, EXECUTABLE, SHARED */
+    PAGE_READWRITE,         /* 12 = WRITABLE, READABLE */
+    PAGE_READWRITE,         /* 13 = WRITABLE, READABLE, SHARED */
+    PAGE_EXECUTE_READWRITE, /* 14 = WRITABLE, READABLE, EXECUTABLE */
+    PAGE_EXECUTE_READWRITE, /* 15 = WRITABLE, READABLE, EXECUTABLE, SHARED */
+};
+
+extern ULONG MmMakeFileAccess [];
+ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask(IN ACCESS_MASK SectionPageProtection);
 static GENERIC_MAPPING MmpSectionMapping = {
          STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY,
          STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE,
          STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE,
          SECTION_ALL_ACCESS};
 
-#define PAGE_FROM_SSE(E)         ((E) & 0xFFFFF000)
-#define PFN_FROM_SSE(E)          ((E) >> PAGE_SHIFT)
-#define SHARE_COUNT_FROM_SSE(E)  (((E) & 0x00000FFE) >> 1)
-#define IS_SWAP_FROM_SSE(E)      ((E) & 0x00000001)
-#define MAX_SHARE_COUNT          0x7FF
-#define MAKE_SSE(P, C)           ((P) | ((C) << 1))
-#define SWAPENTRY_FROM_SSE(E)    ((E) >> 1)
-#define MAKE_SWAP_SSE(S)         (((S) << 1) | 0x1)
-
 static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
 {
   ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */
@@ -98,183 +177,618 @@ static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
 
 /* FUNCTIONS *****************************************************************/
 
-PFILE_OBJECT
-NTAPI
-MmGetFileObjectForSection(IN PROS_SECTION_OBJECT Section)
+
+/*
+ References:
+  [1] Microsoft Corporation, "Microsoft Portable Executable and Common Object
+      File Format Specification", revision 6.0 (February 1999)
+*/
+NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
+                                  IN SIZE_T FileHeaderSize,
+                                  IN PVOID File,
+                                  OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
+                                  OUT PULONG Flags,
+                                  IN PEXEFMT_CB_READ_FILE ReadFileCb,
+                                  IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb)
 {
-    PAGED_CODE();
-    ASSERT(Section);
+    NTSTATUS nStatus;
+    ULONG cbFileHeaderOffsetSize = 0;
+    ULONG cbSectionHeadersOffset = 0;
+    ULONG cbSectionHeadersSize;
+    ULONG cbSectionHeadersOffsetSize = 0;
+    ULONG cbOptHeaderSize;
+    ULONG cbHeadersSize = 0;
+    ULONG nSectionAlignment;
+    ULONG nFileAlignment;
+    ULONG_PTR ImageBase;
+    const IMAGE_DOS_HEADER * pidhDosHeader;
+    const IMAGE_NT_HEADERS32 * pinhNtHeader;
+    const IMAGE_OPTIONAL_HEADER32 * piohOptHeader;
+    const IMAGE_SECTION_HEADER * pishSectionHeaders;
+    PMM_SECTION_SEGMENT pssSegments;
+    LARGE_INTEGER lnOffset;
+    PVOID pBuffer;
+    SIZE_T nPrevVirtualEndOfSegment = 0;
+    ULONG nFileSizeOfHeaders = 0;
+    ULONG i;
+
+    ASSERT(FileHeader);
+    ASSERT(FileHeaderSize > 0);
+    ASSERT(File);
+    ASSERT(ImageSectionObject);
+    ASSERT(ReadFileCb);
+    ASSERT(AllocateSegmentsCb);
+
+    ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize));
+
+    ASSERT(((UINT_PTR)FileHeader % TYPE_ALIGNMENT(IMAGE_DOS_HEADER)) == 0);
+
+#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; }
+
+    pBuffer = NULL;
+    pidhDosHeader = FileHeader;
+
+    /* DOS HEADER */
+    nStatus = STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
+
+    /* image too small to be an MZ executable */
+    if(FileHeaderSize < sizeof(IMAGE_DOS_HEADER))
+        DIE(("Too small to be an MZ executable, size is %lu\n", FileHeaderSize));
+
+    /* no MZ signature */
+    if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+        DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
+
+    /* not a Windows executable */
+    if(pidhDosHeader->e_lfanew <= 0)
+        DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
+
+    /* NT HEADER */
+    nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+    if(!Intsafe_AddULong32(&cbFileHeaderOffsetSize, pidhDosHeader->e_lfanew, RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)))
+        DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
+
+    if(FileHeaderSize < cbFileHeaderOffsetSize)
+        pinhNtHeader = NULL;
+    else
+    {
+        /*
+         * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
+         * and FileHeaderSize >= cbFileHeaderOffsetSize, so this holds true too
+         */
+        ASSERT(Intsafe_CanOffsetPointer(FileHeader, pidhDosHeader->e_lfanew));
+        pinhNtHeader = (PVOID)((UINT_PTR)FileHeader + pidhDosHeader->e_lfanew);
+    }
 
-    /* Return the file object */
-    return Section->FileObject; // Section->ControlArea->FileObject on NT
-}
+    /*
+     * the buffer doesn't contain the NT file header, or the alignment is wrong: we
+     * need to read the header from the file
+     */
+    if(FileHeaderSize < cbFileHeaderOffsetSize ||
+       (UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
+    {
+        ULONG cbNtHeaderSize;
+        ULONG cbReadSize;
+        PVOID pData;
 
-NTSTATUS
-NTAPI
-MmGetFileNameForSection(IN PROS_SECTION_OBJECT Section,
-                        OUT POBJECT_NAME_INFORMATION *ModuleName)
-{
-    POBJECT_NAME_INFORMATION ObjectNameInfo;
-    NTSTATUS Status;
-    ULONG ReturnLength;
+l_ReadHeaderFromFile:
+        cbNtHeaderSize = 0;
+        lnOffset.QuadPart = pidhDosHeader->e_lfanew;
+
+        /* read the header from the file */
+        nStatus = ReadFileCb(File, &lnOffset, sizeof(IMAGE_NT_HEADERS64), &pData, &pBuffer, &cbReadSize);
+
+        if(!NT_SUCCESS(nStatus))
+            DIE(("ReadFile failed, status %08X\n", nStatus));
 
-    /* Make sure it's an image section */
-    *ModuleName = NULL;
-    if (!(Section->AllocationAttributes & SEC_IMAGE))
+        ASSERT(pData);
+        ASSERT(pBuffer);
+        ASSERT(cbReadSize > 0);
+
+        nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+        /* the buffer doesn't contain the file header */
+        if(cbReadSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader))
+            DIE(("The file doesn't contain the PE file header\n"));
+
+        pinhNtHeader = pData;
+
+        /* object still not aligned: copy it to the beginning of the buffer */
+        if((UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
+        {
+            ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) == 0);
+            RtlMoveMemory(pBuffer, pData, cbReadSize);
+            pinhNtHeader = pBuffer;
+        }
+
+        /* invalid NT header */
+        nStatus = STATUS_INVALID_IMAGE_PROTECT;
+
+        if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
+            DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
+
+        nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+        if(!Intsafe_AddULong32(&cbNtHeaderSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
+            DIE(("The full NT header is too large\n"));
+
+        /* the buffer doesn't contain the whole NT header */
+        if(cbReadSize < cbNtHeaderSize)
+            DIE(("The file doesn't contain the full NT header\n"));
+    }
+    else
     {
-        /* It's not, fail */
-        return STATUS_SECTION_NOT_IMAGE;
+        ULONG cbOptHeaderOffsetSize = 0;
+
+        nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+        /* don't trust an invalid NT header */
+        if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
+            DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
+
+        if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
+            DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
+
+        if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
+            DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
+
+        /* the buffer doesn't contain the whole NT header: read it from the file */
+        if(cbOptHeaderOffsetSize > FileHeaderSize)
+            goto l_ReadHeaderFromFile;
     }
 
-    /* Allocate memory for our structure */
-    ObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
-                                           1024,
-                                           '  mM');
-    if (!ObjectNameInfo) return STATUS_NO_MEMORY;
-
-    /* Query the name */
-    Status = ObQueryNameString(Section->FileObject,
-                               ObjectNameInfo,
-                               1024,
-                               &ReturnLength);
-    if (!NT_SUCCESS(Status))
+    /* read information from the NT header */
+    piohOptHeader = &pinhNtHeader->OptionalHeader;
+    cbOptHeaderSize = pinhNtHeader->FileHeader.SizeOfOptionalHeader;
+
+    nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+    if(!RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Magic))
+        DIE(("The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
+
+    /* ASSUME: RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject)); */
+
+    switch(piohOptHeader->Magic)
     {
-        /* Failed, free memory */
-        ExFreePoolWithTag(ObjectNameInfo, '  mM');
-        return Status;
+        case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+        case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+            break;
+
+        default:
+            DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
     }
 
-    /* Success */
-    *ModuleName = ObjectNameInfo;
-    return STATUS_SUCCESS;
-}
+    if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SectionAlignment) &&
+        RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, FileAlignment))
+    {
+        /* See [1], section 3.4.2 */
+        if(piohOptHeader->SectionAlignment < PAGE_SIZE)
+        {
+            if(piohOptHeader->FileAlignment != piohOptHeader->SectionAlignment)
+                DIE(("Sections aren't page-aligned and the file alignment isn't the same\n"));
+        }
+        else if(piohOptHeader->SectionAlignment < piohOptHeader->FileAlignment)
+            DIE(("The section alignment is smaller than the file alignment\n"));
+
+        nSectionAlignment = piohOptHeader->SectionAlignment;
+        nFileAlignment = piohOptHeader->FileAlignment;
+
+        if(!IsPowerOf2(nSectionAlignment) || !IsPowerOf2(nFileAlignment))
+            DIE(("The section alignment (%u) and file alignment (%u) aren't both powers of 2\n", nSectionAlignment, nFileAlignment));
+    }
+    else
+    {
+        nSectionAlignment = PAGE_SIZE;
+        nFileAlignment = PAGE_SIZE;
+    }
 
-NTSTATUS
-NTAPI
-MmGetFileNameForAddress(IN PVOID Address,
-                        OUT PUNICODE_STRING ModuleName)
-{
-   PROS_SECTION_OBJECT Section;
-   PMEMORY_AREA MemoryArea;
-   PMMSUPPORT AddressSpace;
-   POBJECT_NAME_INFORMATION ModuleNameInformation;
-   NTSTATUS Status = STATUS_ADDRESS_NOT_ASSOCIATED;
+    ASSERT(IsPowerOf2(nSectionAlignment));
+    ASSERT(IsPowerOf2(nFileAlignment));
 
-   /* Get the MM_AVL_TABLE from EPROCESS */
-   if (Address >= MmSystemRangeStart)
-   {
-      AddressSpace = MmGetKernelAddressSpace();
-   }
-   else
-   {
-      AddressSpace = &PsGetCurrentProcess()->Vm;
-   }
+    switch(piohOptHeader->Magic)
+    {
+        /* PE32 */
+        case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+        {
+            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase))
+                ImageBase = piohOptHeader->ImageBase;
 
-   /* Lock address space */
-   MmLockAddressSpace(AddressSpace);
+            if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage))
+                ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->SizeOfImage;
 
-   /* Locate the memory area for the process by address */
-   MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
+            if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve))
+                ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->SizeOfStackReserve;
 
-   /* Make sure it's a section view type */
-   if ((MemoryArea != NULL) && (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW))
-   {
-      /* Get the section pointer to the SECTION_OBJECT */
-      Section = MemoryArea->Data.SectionData.Section;
+            if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit))
+                ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->SizeOfStackCommit;
 
-      /* Unlock address space */
-      MmUnlockAddressSpace(AddressSpace);
+            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem))
+            {
+                ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->Subsystem;
+
+                if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
+                    RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MajorSubsystemVersion))
+                {
+                    ImageSectionObject->ImageInformation.SubSystemMinorVersion = piohOptHeader->MinorSubsystemVersion;
+                    ImageSectionObject->ImageInformation.SubSystemMajorVersion = piohOptHeader->MajorSubsystemVersion;
+                }
+            }
 
-      /* Get the filename of the section */
-      Status = MmGetFileNameForSection(Section,&ModuleNameInformation);
+            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+            {
+                ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase +
+                    piohOptHeader->AddressOfEntryPoint);
+            }
 
-      if (NT_SUCCESS(Status))
-      {
-         /* Init modulename */
-         RtlCreateUnicodeString(ModuleName,
-                                ModuleNameInformation->Name.Buffer);
-
-         /* Free temp taged buffer from MmGetFileNameForSection() */
-         ExFreePoolWithTag(ModuleNameInformation, '  mM');
-         DPRINT("Found ModuleName %S by address %p\n",
-                ModuleName->Buffer,Address);
-      }
-   }
-   else
-   {
-      /* Unlock address space */
-      MmUnlockAddressSpace(AddressSpace);
-   }
+            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode))
+                ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->SizeOfCode != 0;
+            else
+                ImageSectionObject->ImageInformation.ImageContainsCode = TRUE;
 
-   return Status;
-}
+            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+            {
+                if (piohOptHeader->AddressOfEntryPoint == 0)
+                {
+                    ImageSectionObject->ImageInformation.ImageContainsCode = FALSE;
+                }
+            }
 
-/* Note: Mmsp prefix denotes "Memory Manager Section Private". */
+            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, LoaderFlags))
+                ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->LoaderFlags;
 
-/*
- * FUNCTION:  Waits in kernel mode up to ten seconds for an MM_PAGEOP event.
- * ARGUMENTS: PMM_PAGEOP which event we should wait for.
- * RETURNS:   Status of the wait.
- */
-static NTSTATUS
-MmspWaitForPageOpCompletionEvent(PMM_PAGEOP PageOp)
-{
-   LARGE_INTEGER Timeout;
-#ifdef __GNUC__ /* TODO: Use other macro to check for suffix to use? */
+            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, DllCharacteristics))
+            {
+                ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->DllCharacteristics;
+
+                /*
+                 * Since we don't really implement SxS yet and LD doesn't supoprt /ALLOWISOLATION:NO, hard-code
+                 * this flag here, which will prevent the loader and other code from doing any .manifest or SxS
+                 * magic to any binary.
+                 *
+                 * This will break applications that depend on SxS when running with real Windows Kernel32/SxS/etc
+                 * but honestly that's not tested. It will also break them when running no ReactOS once we implement
+                 * the SxS support -- at which point, duh, this should be removed.
+                 *
+                 * But right now, any app depending on SxS is already broken anyway, so this flag only helps.
+                 */
+                ImageSectionObject->ImageInformation.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
+            }
 
-   Timeout.QuadPart = -100000000LL; // 10 sec
-#else
+            break;
+        }
+#ifdef _WIN64
+        /* PE64 */
+        case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+        {
+            const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader;
+
+            pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader;
+
+            if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, ImageBase))
+            {
+                ImageBase = pioh64OptHeader->ImageBase;
+                if(pioh64OptHeader->ImageBase > MAXULONG_PTR)
+                    DIE(("ImageBase exceeds the address space\n"));
+            }
+
+            if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfImage))
+            {
+                if(pioh64OptHeader->SizeOfImage > MAXULONG_PTR)
+                    DIE(("SizeOfImage exceeds the address space\n"));
+
+                ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->SizeOfImage;
+            }
+
+            if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackReserve))
+            {
+                if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR)
+                    DIE(("SizeOfStackReserve exceeds the address space\n"));
+
+                ImageSectionObject->ImageInformation.MaximumStackSize = (ULONG_PTR) pioh64OptHeader->SizeOfStackReserve;
+            }
+
+            if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackCommit))
+            {
+                if(pioh64OptHeader->SizeOfStackCommit > MAXULONG_PTR)
+                    DIE(("SizeOfStackCommit exceeds the address space\n"));
+
+                ImageSectionObject->ImageInformation.CommittedStackSize = (ULONG_PTR) pioh64OptHeader->SizeOfStackCommit;
+            }
+
+            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, Subsystem))
+            {
+                ImageSectionObject->ImageInformation.SubSystemType = pioh64OptHeader->Subsystem;
+
+                if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
+                    RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MajorSubsystemVersion))
+                {
+                    ImageSectionObject->ImageInformation.SubSystemMinorVersion = pioh64OptHeader->MinorSubsystemVersion;
+                    ImageSectionObject->ImageInformation.SubSystemMajorVersion = pioh64OptHeader->MajorSubsystemVersion;
+                }
+            }
+
+            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+            {
+                ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase +
+                    pioh64OptHeader->AddressOfEntryPoint);
+            }
+
+            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfCode))
+                ImageSectionObject->ImageInformation.ImageContainsCode = pioh64OptHeader->SizeOfCode != 0;
+            else
+                ImageSectionObject->ImageInformation.ImageContainsCode = TRUE;
 
-   Timeout.QuadPart = -100000000; // 10 sec
+            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+            {
+                if (pioh64OptHeader->AddressOfEntryPoint == 0)
+                {
+                    ImageSectionObject->ImageInformation.ImageContainsCode = FALSE;
+                }
+            }
+
+            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, LoaderFlags))
+                ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->LoaderFlags;
+
+            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, DllCharacteristics))
+                ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->DllCharacteristics;
+
+            break;
+        }
+#endif // _WIN64
+    }
+
+    /* [1], section 3.4.2 */
+    if((ULONG_PTR)ImageBase % 0x10000)
+        DIE(("ImageBase is not aligned on a 64KB boundary"));
+
+    ImageSectionObject->ImageInformation.ImageCharacteristics = pinhNtHeader->FileHeader.Characteristics;
+    ImageSectionObject->ImageInformation.Machine = pinhNtHeader->FileHeader.Machine;
+    ImageSectionObject->ImageInformation.GpValue = 0;
+    ImageSectionObject->ImageInformation.ZeroBits = 0;
+    ImageSectionObject->BasedAddress = (PVOID)ImageBase;
+
+    /* SECTION HEADERS */
+    nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+    /* see [1], section 3.3 */
+    if(pinhNtHeader->FileHeader.NumberOfSections > 96)
+        DIE(("Too many sections, NumberOfSections is %u\n", pinhNtHeader->FileHeader.NumberOfSections));
+
+    /*
+     * the additional segment is for the file's headers. They need to be present for
+     * the benefit of the dynamic loader (to locate exports, defaults for thread
+     * parameters, resources, etc.)
+     */
+    ImageSectionObject->NrSegments = pinhNtHeader->FileHeader.NumberOfSections + 1;
+
+    /* file offset for the section headers */
+    if(!Intsafe_AddULong32(&cbSectionHeadersOffset, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
+        DIE(("Offset overflow\n"));
+
+    if(!Intsafe_AddULong32(&cbSectionHeadersOffset, cbSectionHeadersOffset, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
+        DIE(("Offset overflow\n"));
+
+    /* size of the section headers */
+    ASSERT(Intsafe_CanMulULong32(pinhNtHeader->FileHeader.NumberOfSections, sizeof(IMAGE_SECTION_HEADER)));
+    cbSectionHeadersSize = pinhNtHeader->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
+
+    if(!Intsafe_AddULong32(&cbSectionHeadersOffsetSize, cbSectionHeadersOffset, cbSectionHeadersSize))
+        DIE(("Section headers too large\n"));
+
+    /* size of the executable's headers */
+    if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfHeaders))
+    {
+//        if(!IsAligned(piohOptHeader->SizeOfHeaders, nFileAlignment))
+//            DIE(("SizeOfHeaders is not aligned\n"));
+
+        if(cbSectionHeadersSize > piohOptHeader->SizeOfHeaders)
+            DIE(("The section headers overflow SizeOfHeaders\n"));
+
+        cbHeadersSize = piohOptHeader->SizeOfHeaders;
+    }
+    else if(!AlignUp(&cbHeadersSize, cbSectionHeadersOffsetSize, nFileAlignment))
+        DIE(("Overflow aligning the size of headers\n"));
+
+    if(pBuffer)
+    {
+        ExFreePool(pBuffer);
+        pBuffer = NULL;
+    }
+    /* WARNING: pinhNtHeader IS NO LONGER USABLE */
+    /* WARNING: piohOptHeader IS NO LONGER USABLE */
+    /* WARNING: pioh64OptHeader IS NO LONGER USABLE */
+
+    if(FileHeaderSize < cbSectionHeadersOffsetSize)
+        pishSectionHeaders = NULL;
+    else
+    {
+        /*
+         * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
+         * and FileHeaderSize >= cbSectionHeadersOffsetSize, so this holds true too
+         */
+        ASSERT(Intsafe_CanOffsetPointer(FileHeader, cbSectionHeadersOffset));
+        pishSectionHeaders = (PVOID)((UINT_PTR)FileHeader + cbSectionHeadersOffset);
+    }
+
+    /*
+     * the buffer doesn't contain the section headers, or the alignment is wrong:
+     * read the headers from the file
+     */
+    if(FileHeaderSize < cbSectionHeadersOffsetSize ||
+       (UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
+    {
+        PVOID pData;
+        ULONG cbReadSize;
+
+        lnOffset.QuadPart = cbSectionHeadersOffset;
+
+        /* read the header from the file */
+        nStatus = ReadFileCb(File, &lnOffset, cbSectionHeadersSize, &pData, &pBuffer, &cbReadSize);
+
+        if(!NT_SUCCESS(nStatus))
+            DIE(("ReadFile failed with status %08X\n", nStatus));
+
+        ASSERT(pData);
+        ASSERT(pBuffer);
+        ASSERT(cbReadSize > 0);
+
+        nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+        /* the buffer doesn't contain all the section headers */
+        if(cbReadSize < cbSectionHeadersSize)
+            DIE(("The file doesn't contain all of the section headers\n"));
+
+        pishSectionHeaders = pData;
+
+        /* object still not aligned: copy it to the beginning of the buffer */
+        if((UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
+        {
+            ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) == 0);
+            RtlMoveMemory(pBuffer, pData, cbReadSize);
+            pishSectionHeaders = pBuffer;
+        }
+    }
+
+    /* SEGMENTS */
+    /* allocate the segments */
+    nStatus = STATUS_INSUFFICIENT_RESOURCES;
+    ImageSectionObject->Segments = AllocateSegmentsCb(ImageSectionObject->NrSegments);
+
+    if(ImageSectionObject->Segments == NULL)
+        DIE(("AllocateSegments failed\n"));
+
+    /* initialize the headers segment */
+    pssSegments = ImageSectionObject->Segments;
+
+//  ASSERT(IsAligned(cbHeadersSize, nFileAlignment));
+
+    if(!AlignUp(&nFileSizeOfHeaders, cbHeadersSize, nFileAlignment))
+        DIE(("Cannot align the size of the section headers\n"));
+
+    nPrevVirtualEndOfSegment = ALIGN_UP_BY(cbHeadersSize, nSectionAlignment);
+    if (nPrevVirtualEndOfSegment < cbHeadersSize)
+        DIE(("Cannot align the size of the section headers\n"));
+
+    pssSegments[0].Image.FileOffset = 0;
+    pssSegments[0].Protection = PAGE_READONLY;
+    pssSegments[0].Length.QuadPart = nPrevVirtualEndOfSegment;
+    pssSegments[0].RawLength.QuadPart = nFileSizeOfHeaders;
+    pssSegments[0].Image.VirtualAddress = 0;
+    pssSegments[0].Image.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA;
+    pssSegments[0].WriteCopy = TRUE;
+
+    /* skip the headers segment */
+    ++ pssSegments;
+
+    nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+    /* convert the executable sections into segments. See also [1], section 4 */
+    for(i = 0; i < ImageSectionObject->NrSegments - 1; ++ i)
+    {
+        ULONG nCharacteristics;
+
+        /* validate the alignment */
+        if(!IsAligned(pishSectionHeaders[i].VirtualAddress, nSectionAlignment))
+            DIE(("Image.VirtualAddress[%u] is not aligned\n", i));
+
+        /* sections must be contiguous, ordered by base address and non-overlapping */
+        if(pishSectionHeaders[i].VirtualAddress != nPrevVirtualEndOfSegment)
+            DIE(("Memory gap between section %u and the previous\n", i));
+
+        /* ignore explicit BSS sections */
+        if(pishSectionHeaders[i].SizeOfRawData != 0)
+        {
+            /* validate the alignment */
+#if 0
+            /* Yes, this should be a multiple of FileAlignment, but there's
+             * stuff out there that isn't. We can cope with that
+             */
+            if(!IsAligned(pishSectionHeaders[i].SizeOfRawData, nFileAlignment))
+                DIE(("SizeOfRawData[%u] is not aligned\n", i));
 #endif
 
-   return KeWaitForSingleObject(&PageOp->CompletionEvent, 0, KernelMode, FALSE, &Timeout);
-}
+//            if(!IsAligned(pishSectionHeaders[i].PointerToRawData, nFileAlignment))
+//                DIE(("PointerToRawData[%u] is not aligned\n", i));
 
+            /* conversion */
+            pssSegments[i].Image.FileOffset = pishSectionHeaders[i].PointerToRawData;
+            pssSegments[i].RawLength.QuadPart = pishSectionHeaders[i].SizeOfRawData;
+        }
+        else
+        {
+            ASSERT(pssSegments[i].Image.FileOffset == 0);
+            ASSERT(pssSegments[i].RawLength.QuadPart == 0);
+        }
 
-/*
- * FUNCTION:  Sets the page op completion event and releases the page op.
- * ARGUMENTS: PMM_PAGEOP.
- * RETURNS:   In shorter time than it takes you to even read this
- *            description, so don't even think about geting a mug of coffee.
- */
-static void
-MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp)
-{
-   KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
-   MmReleasePageOp(PageOp);
-}
+        ASSERT(Intsafe_CanAddLong64(pssSegments[i].Image.FileOffset, pssSegments[i].RawLength.QuadPart));
+
+        nCharacteristics = pishSectionHeaders[i].Characteristics;
+
+        /* no explicit protection */
+        if((nCharacteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == 0)
+        {
+            if(nCharacteristics & IMAGE_SCN_CNT_CODE)
+                nCharacteristics |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
 
+            if(nCharacteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
+                nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+
+            if(nCharacteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+                nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+        }
+
+        /* see table above */
+        pssSegments[i].Protection = SectionCharacteristicsToProtect[nCharacteristics >> 28];
+        pssSegments[i].WriteCopy = !(nCharacteristics & IMAGE_SCN_MEM_SHARED);
+
+        if(pishSectionHeaders[i].Misc.VirtualSize == 0 || pishSectionHeaders[i].Misc.VirtualSize < pishSectionHeaders[i].SizeOfRawData)
+            pssSegments[i].Length.QuadPart = pishSectionHeaders[i].SizeOfRawData;
+        else
+            pssSegments[i].Length.QuadPart = pishSectionHeaders[i].Misc.VirtualSize;
+
+        pssSegments[i].Length.LowPart = ALIGN_UP_BY(pssSegments[i].Length.LowPart, nSectionAlignment);
+        /* FIXME: always false */
+        if (pssSegments[i].Length.QuadPart < pssSegments[i].Length.QuadPart)
+            DIE(("Cannot align the virtual size of section %u\n", i));
+
+        if(pssSegments[i].Length.QuadPart == 0)
+            DIE(("Virtual size of section %u is null\n", i));
+
+        pssSegments[i].Image.VirtualAddress = pishSectionHeaders[i].VirtualAddress;
+        pssSegments[i].Image.Characteristics = pishSectionHeaders[i].Characteristics;
+
+        /* ensure the memory image is no larger than 4GB */
+        nPrevVirtualEndOfSegment = (ULONG_PTR)(pssSegments[i].Image.VirtualAddress + pssSegments[i].Length.QuadPart);
+        if (nPrevVirtualEndOfSegment < pssSegments[i].Image.VirtualAddress)
+            DIE(("The image is too large\n"));
+    }
+
+    if(nSectionAlignment >= PAGE_SIZE)
+        *Flags |= EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED;
+
+    /* Success */
+    nStatus = STATUS_SUCCESS;// STATUS_ROS_EXEFMT_LOADED_FORMAT | EXEFMT_LOADED_PE32;
+
+l_Return:
+    if(pBuffer)
+        ExFreePool(pBuffer);
+
+    return nStatus;
+}
 
 /*
  * FUNCTION:  Waits in kernel mode indefinitely for a file object lock.
  * ARGUMENTS: PFILE_OBJECT to wait for.
  * RETURNS:   Status of the wait.
  */
-static NTSTATUS
+NTSTATUS
 MmspWaitForFileLock(PFILE_OBJECT File)
 {
     return STATUS_SUCCESS;
    //return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL);
 }
 
-
-VOID
-MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment)
-{
-   ULONG i;
-   if (Segment->Length > NR_SECTION_PAGE_TABLES * PAGE_SIZE)
-   {
-      for (i = 0; i < NR_SECTION_PAGE_TABLES; i++)
-      {
-         if (Segment->PageDirectory.PageTables[i] != NULL)
-         {
-            ExFreePool(Segment->PageDirectory.PageTables[i]);
-         }
-      }
-   }
-}
-
 VOID
 NTAPI
 MmFreeSectionSegments(PFILE_OBJECT FileObject)
@@ -293,11 +807,11 @@ MmFreeSectionSegments(PFILE_OBJECT FileObject)
       {
          if (SectionSegments[i].ReferenceCount != 0)
          {
-            DPRINT1("Image segment %d still referenced (was %d)\n", i,
+            DPRINT1("Image segment %lu still referenced (was %lu)\n", i,
                     SectionSegments[i].ReferenceCount);
             KeBugCheck(MEMORY_MANAGEMENT);
          }
-         MmFreePageTablesSectionSegment(&SectionSegments[i]);
+         MmFreePageTablesSectionSegment(&SectionSegments[i], NULL);
       }
       ExFreePool(ImageSectionObject->Segments);
       ExFreePool(ImageSectionObject);
@@ -315,100 +829,18 @@ MmFreeSectionSegments(PFILE_OBJECT FileObject)
          DPRINT1("Data segment still referenced\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmFreePageTablesSectionSegment(Segment);
+      MmFreePageTablesSectionSegment(Segment, NULL);
       ExFreePool(Segment);
       FileObject->SectionObjectPointer->DataSectionObject = NULL;
    }
 }
 
-VOID
-NTAPI
-MmLockSectionSegment(PMM_SECTION_SEGMENT Segment)
-{
-   ExAcquireFastMutex(&Segment->Lock);
-}
-
-VOID
-NTAPI
-MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment)
-{
-   ExReleaseFastMutex(&Segment->Lock);
-}
-
-VOID
-NTAPI
-MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
-                             ULONG Offset,
-                             ULONG Entry)
-{
-   PSECTION_PAGE_TABLE Table;
-   ULONG DirectoryOffset;
-   ULONG TableOffset;
-
-   if (Segment->Length <= NR_SECTION_PAGE_TABLES * PAGE_SIZE)
-   {
-      Table = (PSECTION_PAGE_TABLE)&Segment->PageDirectory;
-   }
-   else
-   {
-      DirectoryOffset = PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(Offset);
-      Table = Segment->PageDirectory.PageTables[DirectoryOffset];
-      if (Table == NULL)
-      {
-         Table =
-            Segment->PageDirectory.PageTables[DirectoryOffset] =
-               ExAllocatePoolWithTag(NonPagedPool, sizeof(SECTION_PAGE_TABLE),
-                                     TAG_SECTION_PAGE_TABLE);
-         if (Table == NULL)
-         {
-            KeBugCheck(MEMORY_MANAGEMENT);
-         }
-         memset(Table, 0, sizeof(SECTION_PAGE_TABLE));
-         DPRINT("Table %x\n", Table);
-      }
-   }
-   TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
-   Table->Entry[TableOffset] = Entry;
-}
-
-
-ULONG
-NTAPI
-MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
-                             ULONG Offset)
-{
-   PSECTION_PAGE_TABLE Table;
-   ULONG Entry;
-   ULONG DirectoryOffset;
-   ULONG TableOffset;
-
-   DPRINT("MmGetPageEntrySection(Segment %x, Offset %x)\n", Segment, Offset);
-
-   if (Segment->Length <= NR_SECTION_PAGE_TABLES * PAGE_SIZE)
-   {
-      Table = (PSECTION_PAGE_TABLE)&Segment->PageDirectory;
-   }
-   else
-   {
-      DirectoryOffset = PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(Offset);
-      Table = Segment->PageDirectory.PageTables[DirectoryOffset];
-      DPRINT("Table %x\n", Table);
-      if (Table == NULL)
-      {
-         return(0);
-      }
-   }
-   TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
-   Entry = Table->Entry[TableOffset];
-   return(Entry);
-}
-
 VOID
 NTAPI
 MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
-                               ULONG Offset)
+                               PLARGE_INTEGER Offset)
 {
-   ULONG Entry;
+   ULONG_PTR Entry;
 
    Entry = MmGetPageEntrySectionSegment(Segment, Offset);
    if (Entry == 0)
@@ -433,14 +865,14 @@ BOOLEAN
 NTAPI
 MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
                                  PMM_SECTION_SEGMENT Segment,
-                                 ULONG Offset,
+                                 PLARGE_INTEGER Offset,
                                  BOOLEAN Dirty,
-                                 BOOLEAN PageOut)
+                                 BOOLEAN PageOut,
+                                 ULONG_PTR *InEntry)
 {
-   ULONG Entry;
+   ULONG_PTR Entry = InEntry ? *InEntry : MmGetPageEntrySectionSegment(Segment, Offset);
    BOOLEAN IsDirectMapped = FALSE;
 
-   Entry = MmGetPageEntrySectionSegment(Segment, Offset);
    if (Entry == 0)
    {
       DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n");
@@ -448,7 +880,7 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
    }
    if (SHARE_COUNT_FROM_SSE(Entry) == 0)
    {
-      DPRINT1("Zero share count for unshare\n");
+       DPRINT1("Zero share count for unshare (Seg %p Offset %x Page %x)\n", Segment, Offset->LowPart, PFN_FROM_SSE(Entry));
        KeBugCheck(MEMORY_MANAGEMENT);
    }
    if (IS_SWAP_FROM_SSE(Entry))
@@ -463,35 +895,43 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
    if (SHARE_COUNT_FROM_SSE(Entry) == 0)
    {
       PFILE_OBJECT FileObject;
+#ifndef NEWCC
       PBCB Bcb;
+#endif
       SWAPENTRY SavedSwapEntry;
       PFN_NUMBER Page;
       BOOLEAN IsImageSection;
-      ULONG FileOffset;
+      LARGE_INTEGER FileOffset;
 
-      FileOffset = Offset + Segment->FileOffset;
+      FileOffset.QuadPart = Offset->QuadPart + Segment->Image.FileOffset;
 
       IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
 
       Page = PFN_FROM_SSE(Entry);
       FileObject = Section->FileObject;
       if (FileObject != NULL &&
-            !(Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+            !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
       {
 
-         if ((FileOffset % PAGE_SIZE) == 0 &&
-               (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection))
+#ifndef NEWCC
+         if ((FileOffset.QuadPart % PAGE_SIZE) == 0 &&
+               (Offset->QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection))
          {
             NTSTATUS Status;
             Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
             IsDirectMapped = TRUE;
-            Status = CcRosUnmapCacheSegment(Bcb, FileOffset, Dirty);
+#ifndef NEWCC
+            Status = CcRosUnmapCacheSegment(Bcb, FileOffset.LowPart, Dirty);
+#else
+            Status = STATUS_SUCCESS;
+#endif
             if (!NT_SUCCESS(Status))
             {
                DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n", Status);
-                KeBugCheck(MEMORY_MANAGEMENT);
+               KeBugCheck(MEMORY_MANAGEMENT);
             }
          }
+#endif
       }
 
       SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
@@ -499,7 +939,7 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
       {
          if (!PageOut &&
                ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
-                (Segment->Characteristics & IMAGE_SCN_MEM_SHARED)))
+                (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)))
          {
             /*
              * FIXME:
@@ -509,10 +949,14 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
              *   page without a rmap entry.
              */
             MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+            if (InEntry) *InEntry = Entry;
+            MiSetPageEvent(NULL, NULL);
          }
          else
          {
             MmSetPageEntrySectionSegment(Segment, Offset, 0);
+            if (InEntry) *InEntry = 0;
+            MiSetPageEvent(NULL, NULL);
             if (!IsDirectMapped)
             {
                MmReleasePageMemoryConsumer(MC_USER, Page);
@@ -522,7 +966,7 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
       else
       {
          if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
-               (Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+               (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
          {
             if (!PageOut)
             {
@@ -542,7 +986,9 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
                   }
                }
                MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry));
+               if (InEntry) *InEntry = MAKE_SWAP_SSE(SavedSwapEntry);
                MmSetSavedSwapEntryPage(Page, 0);
+               MiSetPageEvent(NULL, NULL);
             }
             MmReleasePageMemoryConsumer(MC_USER, Page);
          }
@@ -555,7 +1001,10 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
    }
    else
    {
-      MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+      if (InEntry)
+          *InEntry = Entry;
+      else
+          MmSetPageEntrySectionSegment(Segment, Offset, Entry);
    }
    return(SHARE_COUNT_FROM_SSE(Entry) > 0);
 }
@@ -563,44 +1012,51 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
 BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
                        ULONG SegOffset)
 {
-   if (!(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+#ifndef NEWCC
+   if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
    {
       PBCB Bcb;
       PCACHE_SEGMENT CacheSeg;
       Bcb = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
-      CacheSeg = CcRosLookupCacheSegment(Bcb, SegOffset + MemoryArea->Data.SectionData.Segment->FileOffset);
+      CacheSeg = CcRosLookupCacheSegment(Bcb, (ULONG)(SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset));
       if (CacheSeg)
       {
          CcRosReleaseCacheSegment(Bcb, CacheSeg, CacheSeg->Valid, FALSE, TRUE);
          return TRUE;
       }
    }
+#endif
    return FALSE;
 }
 
 NTSTATUS
 NTAPI
-MiCopyFromUserPage(PFN_NUMBER DestPage, PVOID SourceAddress)
+MiCopyFromUserPage(PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
 {
     PEPROCESS Process;
-    KIRQL Irql;
-    PVOID TempAddress;
-    
+    KIRQL Irql, Irql2;
+    PVOID DestAddress, SrcAddress;
+
     Process = PsGetCurrentProcess();
-    TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
-    if (TempAddress == NULL)
+    DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
+    SrcAddress = MiMapPageInHyperSpace(Process, SrcPage, &Irql2);
+    if (DestAddress == NULL || SrcAddress == NULL)
     {
         return(STATUS_NO_MEMORY);
     }
-    memcpy(TempAddress, SourceAddress, PAGE_SIZE);
-    MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
+    ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
+    ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
+    RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
+    MiUnmapPageInHyperSpace(Process, SrcAddress, Irql2);
+    MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
     return(STATUS_SUCCESS);
 }
 
+#ifndef NEWCC
 NTSTATUS
 NTAPI
 MiReadPage(PMEMORY_AREA MemoryArea,
-           ULONG SegOffset,
+           ULONG_PTR SegOffset,
            PPFN_NUMBER Page)
 /*
  * FUNCTION: Read a page for a section backed memory area.
@@ -611,35 +1067,35 @@ MiReadPage(PMEMORY_AREA MemoryArea,
  */
 {
    ULONG BaseOffset;
-   ULONG FileOffset;
+   ULONGLONG FileOffset;
    PVOID BaseAddress;
    BOOLEAN UptoDate;
    PCACHE_SEGMENT CacheSeg;
    PFILE_OBJECT FileObject;
    NTSTATUS Status;
-   ULONG RawLength;
+   ULONG_PTR RawLength;
    PBCB Bcb;
    BOOLEAN IsImageSection;
-   ULONG Length;
+   ULONG_PTR Length;
 
    FileObject = MemoryArea->Data.SectionData.Section->FileObject;
    Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-   RawLength = MemoryArea->Data.SectionData.Segment->RawLength;
-   FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->FileOffset;
+   RawLength = (ULONG_PTR)(MemoryArea->Data.SectionData.Segment->RawLength.QuadPart);
+   FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset;
    IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
 
    ASSERT(Bcb);
 
-   DPRINT("%S %x\n", FileObject->FileName.Buffer, FileOffset);
+   DPRINT("%S %I64x\n", FileObject->FileName.Buffer, FileOffset);
 
    /*
     * If the file system is letting us go directly to the cache and the
     * memory area was mapped at an offset in the file which is page aligned
     * then get the related cache segment.
     */
-   if ((FileOffset % PAGE_SIZE) == 0 &&
-       (SegOffset + PAGE_SIZE <= RawLength || !IsImageSection) &&
-       !(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+   if (((FileOffset % PAGE_SIZE) == 0) &&
+       ((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) &&
+       !(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
    {
 
       /*
@@ -648,7 +1104,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
        * alignment less than the file system block size.
        */
       Status = CcRosGetCacheSegment(Bcb,
-                                    FileOffset,
+                                    (ULONG)FileOffset,
                                     &BaseOffset,
                                     &BaseAddress,
                                     &UptoDate,
@@ -670,6 +1126,10 @@ MiReadPage(PMEMORY_AREA MemoryArea,
             return Status;
          }
       }
+
+      /* Probe the page, since it's PDE might not be synced */
+      (void)*((volatile char*)BaseAddress + FileOffset - BaseOffset);
+
       /*
        * Retrieve the page from the cache segment that we actually want.
        */
@@ -683,19 +1143,21 @@ MiReadPage(PMEMORY_AREA MemoryArea,
       PEPROCESS Process;
       KIRQL Irql;
       PVOID PageAddr;
-      ULONG CacheSegOffset;
+      ULONG_PTR CacheSegOffset;
 
       /*
        * Allocate a page, this is rather complicated by the possibility
        * we might have to move other things out of memory
        */
+      MI_SET_USAGE(MI_USAGE_SECTION);
+      MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
       Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page);
       if (!NT_SUCCESS(Status))
       {
          return(Status);
       }
       Status = CcRosGetCacheSegment(Bcb,
-                                    FileOffset,
+                                    (ULONG)FileOffset,
                                     &BaseOffset,
                                     &BaseAddress,
                                     &UptoDate,
@@ -720,7 +1182,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
 
       Process = PsGetCurrentProcess();
       PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
-      CacheSegOffset = BaseOffset + CacheSeg->Bcb->CacheSegmentSize - FileOffset;
+      CacheSegOffset = (ULONG_PTR)(BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset);
       Length = RawLength - SegOffset;
       if (Length <= CacheSegOffset && Length <= PAGE_SIZE)
       {
@@ -736,7 +1198,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
          MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
          CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
          Status = CcRosGetCacheSegment(Bcb,
-                                       FileOffset + CacheSegOffset,
+                                       (ULONG)(FileOffset + CacheSegOffset),
                                        &BaseOffset,
                                        &BaseAddress,
                                        &UptoDate,
@@ -773,6 +1235,38 @@ MiReadPage(PMEMORY_AREA MemoryArea,
    }
    return(STATUS_SUCCESS);
 }
+#else
+NTSTATUS
+NTAPI
+MiReadPage(PMEMORY_AREA MemoryArea,
+           ULONG_PTR SegOffset,
+           PPFN_NUMBER Page)
+/*
+ * FUNCTION: Read a page for a section backed memory area.
+ * PARAMETERS:
+ *       MemoryArea - Memory area to read the page for.
+ *       Offset - Offset of the page to read.
+ *       Page - Variable that receives a page contains the read data.
+ */
+{
+   MM_REQUIRED_RESOURCES Resources;
+   NTSTATUS Status;
+
+   RtlZeroMemory(&Resources, sizeof(MM_REQUIRED_RESOURCES));
+
+   Resources.Context = MemoryArea->Data.SectionData.Section->FileObject;
+   Resources.FileOffset.QuadPart = SegOffset +
+       MemoryArea->Data.SectionData.Segment->Image.FileOffset;
+   Resources.Consumer = MC_USER;
+   Resources.Amount = PAGE_SIZE;
+
+   DPRINT("%S, offset 0x%x, len 0x%x, page 0x%x\n", ((PFILE_OBJECT)Resources.Context)->FileName.Buffer, Resources.FileOffset.LowPart, Resources.Amount, Resources.Page[0]);
+
+   Status = MiReadFilePage(MmGetKernelAddressSpace(), MemoryArea, &Resources);
+   *Page = Resources.Page[0];
+   return Status;
+}
+#endif
 
 NTSTATUS
 NTAPI
@@ -781,20 +1275,20 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
                              PVOID Address,
                              BOOLEAN Locked)
 {
-   ULONG Offset;
+   LARGE_INTEGER Offset;
    PFN_NUMBER Page;
    NTSTATUS Status;
-   PVOID PAddress;
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
-   ULONG Entry;
-   ULONG Entry1;
+   ULONG_PTR Entry;
+   ULONG_PTR Entry1;
    ULONG Attributes;
-   PMM_PAGEOP PageOp;
    PMM_REGION Region;
    BOOLEAN HasSwapEntry;
+   PVOID PAddress;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-    
+   SWAPENTRY SwapEntry;
+
    /*
     * There is a window between taking the page fault and locking the
     * address space when another thread could load the page so we check
@@ -805,24 +1299,38 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       return(STATUS_SUCCESS);
    }
 
+   if (MmIsDisabledPage(Process, Address))
+   {
+       return(STATUS_ACCESS_VIOLATION);
+   }
+
+   /*
+    * Check for the virtual memory area being deleted.
+    */
+   if (MemoryArea->DeleteInProgress)
+   {
+      return(STATUS_UNSUCCESSFUL);
+   }
+
    PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-   Offset = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
-            + MemoryArea->Data.SectionData.ViewOffset;
+   Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+            + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
    Segment = MemoryArea->Data.SectionData.Segment;
    Section = MemoryArea->Data.SectionData.Section;
    Region = MmFindRegion(MemoryArea->StartingAddress,
                          &MemoryArea->Data.SectionData.RegionListHead,
                          Address, NULL);
+   ASSERT(Region != NULL);
    /*
     * Lock the segment
     */
    MmLockSectionSegment(Segment);
-
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
    /*
     * Check if this page needs to be mapped COW
     */
-   if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if ((Segment->WriteCopy) &&
        (Region->Protect == PAGE_READWRITE ||
        Region->Protect == PAGE_EXECUTE_READWRITE))
    {
@@ -833,112 +1341,43 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       Attributes = Region->Protect;
    }
 
-   /*
-    * Get or create a page operation descriptor
-    */
-   PageOp = MmGetPageOp(MemoryArea, NULL, 0, Segment, Offset, MM_PAGEOP_PAGEIN, FALSE);
-   if (PageOp == NULL)
-   {
-      DPRINT1("MmGetPageOp failed\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
    /*
     * Check if someone else is already handling this fault, if so wait
     * for them
     */
-   if (PageOp->Thread != PsGetCurrentThread())
+   if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
    {
       MmUnlockSectionSegment(Segment);
       MmUnlockAddressSpace(AddressSpace);
-      Status = MmspWaitForPageOpCompletionEvent(PageOp);
-      /*
-       * Check for various strange conditions
-       */
-      if (Status != STATUS_SUCCESS)
-      {
-         DPRINT1("Failed to wait for page op, status = %x\n", Status);
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      if (PageOp->Status == STATUS_PENDING)
-      {
-         DPRINT1("Woke for page op before completion\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
+      MiWaitForPageEvent(NULL, NULL);
       MmLockAddressSpace(AddressSpace);
-      /*
-       * If this wasn't a pagein then restart the operation
-       */
-      if (PageOp->OpType != MM_PAGEOP_PAGEIN)
-      {
-         MmspCompleteAndReleasePageOp(PageOp);
-         DPRINT("Address 0x%.8X\n", Address);
-         return(STATUS_MM_RESTART_OPERATION);
-      }
-
-      /*
-      * If the thread handling this fault has failed then we don't retry
-      */
-      if (!NT_SUCCESS(PageOp->Status))
-      {
-         Status = PageOp->Status;
-         MmspCompleteAndReleasePageOp(PageOp);
-         DPRINT("Address 0x%.8X\n", Address);
-         return(Status);
-      }
-      MmLockSectionSegment(Segment);
-      /*
-       * If the completed fault was for another address space then set the
-       * page in this one.
-       */
-      if (!MmIsPagePresent(Process, Address))
-      {
-         Entry = MmGetPageEntrySectionSegment(Segment, Offset);
-         HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+      DPRINT("Address 0x%p\n", Address);
+      return(STATUS_MM_RESTART_OPERATION);
+   }
 
-         if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
-         {
-            /*
-             * The page was a private page in another or in our address space
-             */
-            MmUnlockSectionSegment(Segment);
-            MmspCompleteAndReleasePageOp(PageOp);
-            return(STATUS_MM_RESTART_OPERATION);
-         }
+   HasSwapEntry = MmIsPageSwapEntry(Process, Address);
 
-         Page = PFN_FROM_SSE(Entry);
+   if (HasSwapEntry)
+   {
+      SWAPENTRY DummyEntry;
 
-         MmSharePageEntrySectionSegment(Segment, Offset);
+      /*
+       * Is it a wait entry?
+       */
+      MmGetPageFileMapping(Process, Address, &SwapEntry);
 
-         /* FIXME: Should we call MmCreateVirtualMappingUnsafe if
-          * (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true?
-          */
-         Status = MmCreateVirtualMapping(Process,
-                                         Address,
-                                         Attributes,
-                                         &Page,
-                                         1);
-         if (!NT_SUCCESS(Status))
-         {
-            DPRINT1("Unable to create virtual mapping\n");
-            KeBugCheck(MEMORY_MANAGEMENT);
-         }
-         MmInsertRmap(Page, Process, (PVOID)PAddress);
+      if (SwapEntry == MM_WAIT_ENTRY)
+      {
+         MmUnlockSectionSegment(Segment);
+         MmUnlockAddressSpace(AddressSpace);
+         MiWaitForPageEvent(NULL, NULL);
+         MmLockAddressSpace(AddressSpace);
+         return STATUS_MM_RESTART_OPERATION;
       }
-      MmUnlockSectionSegment(Segment);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
-      return(STATUS_SUCCESS);
-   }
 
-   HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
-   if (HasSwapEntry)
-   {
       /*
        * Must be private page we have swapped out.
        */
-      SWAPENTRY SwapEntry;
 
       /*
        * Sanity check
@@ -950,9 +1389,13 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       }
 
       MmUnlockSectionSegment(Segment);
-      MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
+      MmDeletePageFileMapping(Process, Address, &SwapEntry);
+      MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
 
       MmUnlockAddressSpace(AddressSpace);
+      MI_SET_USAGE(MI_USAGE_SECTION);
+      if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+      if (!Process) MI_SET_PROCESS2("Kernel Section");
       Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
       if (!NT_SUCCESS(Status))
       {
@@ -966,8 +1409,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
           KeBugCheck(MEMORY_MANAGEMENT);
       }
       MmLockAddressSpace(AddressSpace);
+      MmDeletePageFileMapping(Process, PAddress, &DummyEntry);
       Status = MmCreateVirtualMapping(Process,
-                                      Address,
+                                      PAddress,
                                       Region->Protect,
                                       &Page,
                                       1);
@@ -986,14 +1430,12 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Add the page to the process's working set
        */
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
-
+      MmInsertRmap(Page, Process, Address);
       /*
        * Finish the operation
        */
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
+      MiSetPageEvent(Process, Address);
+      DPRINT("Address 0x%p\n", Address);
       return(STATUS_SUCCESS);
    }
 
@@ -1006,9 +1448,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Just map the desired physical page
        */
-      Page = Offset >> PAGE_SHIFT;
+      Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT);
       Status = MmCreateVirtualMappingUnsafe(Process,
-                                            Address,
+                                            PAddress,
                                             Region->Protect,
                                             &Page,
                                             1);
@@ -1022,58 +1464,20 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Cleanup and release locks
        */
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
-      return(STATUS_SUCCESS);
-   }
-
-   /*
-    * Map anonymous memory for BSS sections
-    */
-   if (Segment->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
-   {
-      MmUnlockSectionSegment(Segment);
-      Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
-      if (!NT_SUCCESS(Status))
-      {
-         MmUnlockAddressSpace(AddressSpace);
-         Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
-         MmLockAddressSpace(AddressSpace);
-      }
-      if (!NT_SUCCESS(Status))
-      {
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      Status = MmCreateVirtualMapping(Process,
-                                      Address,
-                                      Region->Protect,
-                                      &Page,
-                                      1);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-         return(Status);
-      }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
-
-      /*
-       * Cleanup and release locks
-       */
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
+      MiSetPageEvent(Process, Address);
+      DPRINT("Address 0x%p\n", Address);
       return(STATUS_SUCCESS);
    }
 
    /*
     * Get the entry corresponding to the offset within the section
     */
-   Entry = MmGetPageEntrySectionSegment(Segment, Offset);
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
 
    if (Entry == 0)
    {
+      SWAPENTRY FakeSwapEntry;
+
       /*
        * If the entry is zero (and it can't change because we have
        * locked the segment) then we need to load the page.
@@ -1082,21 +1486,28 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Release all our locks and read in the page from disk
        */
+      MmSetPageEntrySectionSegment(Segment, &Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
       MmUnlockSectionSegment(Segment);
+      MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY);
       MmUnlockAddressSpace(AddressSpace);
 
       if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
-          (Offset >= PAGE_ROUND_UP(Segment->RawLength) && Section->AllocationAttributes & SEC_IMAGE))
+          ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart) &&
+          (Section->AllocationAttributes & SEC_IMAGE))))
       {
+         MI_SET_USAGE(MI_USAGE_SECTION);
+         if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+         if (!Process) MI_SET_PROCESS2("Kernel Section");
          Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
          if (!NT_SUCCESS(Status))
          {
             DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status);
          }
+
       }
       else
       {
-         Status = MiReadPage(MemoryArea, Offset, &Page);
+         Status = MiReadPage(MemoryArea, (ULONG_PTR)Offset.QuadPart, &Page);
          if (!NT_SUCCESS(Status))
          {
             DPRINT1("MiReadPage failed (Status %x)\n", Status);
@@ -1111,38 +1522,26 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
           * Cleanup and release locks
           */
          MmLockAddressSpace(AddressSpace);
-         PageOp->Status = Status;
-         MmspCompleteAndReleasePageOp(PageOp);
-         DPRINT("Address 0x%.8X\n", Address);
+         MiSetPageEvent(Process, Address);
+         DPRINT("Address 0x%p\n", Address);
          return(Status);
       }
-      /*
-       * Relock the address space and segment
-       */
-      MmLockAddressSpace(AddressSpace);
-      MmLockSectionSegment(Segment);
-
-      /*
-       * Check the entry. No one should change the status of a page
-       * that has a pending page-in.
-       */
-      Entry1 = MmGetPageEntrySectionSegment(Segment, Offset);
-      if (Entry != Entry1)
-      {
-         DPRINT1("Someone changed ppte entry while we slept\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
 
       /*
        * Mark the offset within the section as having valid, in-memory
        * data
        */
+      MmLockAddressSpace(AddressSpace);
+      MmLockSectionSegment(Segment);
       Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
-      MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+      MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
       MmUnlockSectionSegment(Segment);
 
+      MmDeletePageFileMapping(Process, PAddress, &FakeSwapEntry);
+      DPRINT("CreateVirtualMapping Page %x Process %p PAddress %p Attributes %x\n",
+              Page, Process, PAddress, Attributes);
       Status = MmCreateVirtualMapping(Process,
-                                      Address,
+                                      PAddress,
                                       Attributes,
                                       &Page,
                                       1);
@@ -1151,11 +1550,11 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      ASSERT(MmIsPagePresent(Process, PAddress));
+      MmInsertRmap(Page, Process, Address);
 
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
+      MiSetPageEvent(Process, Address);
+      DPRINT("Address 0x%p\n", Address);
       return(STATUS_SUCCESS);
    }
    else if (IS_SWAP_FROM_SSE(Entry))
@@ -1170,7 +1569,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       MmUnlockSectionSegment(Segment);
 
       MmUnlockAddressSpace(AddressSpace);
-
+      MI_SET_USAGE(MI_USAGE_SECTION);
+      if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+      if (!Process) MI_SET_PROCESS2("Kernel Section");
       Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
       if (!NT_SUCCESS(Status))
       {
@@ -1193,10 +1594,10 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
        * Check the entry. No one should change the status of a page
        * that has a pending page-in.
        */
-      Entry1 = MmGetPageEntrySectionSegment(Segment, Offset);
+      Entry1 = MmGetPageEntrySectionSegment(Segment, &Offset);
       if (Entry != Entry1)
       {
-         DPRINT1("Someone changed ppte entry while we slept\n");
+          DPRINT1("Someone changed ppte entry while we slept (%x vs %x)\n", Entry, Entry1);
           KeBugCheck(MEMORY_MANAGEMENT);
       }
 
@@ -1205,7 +1606,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
        * data
        */
       Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
-      MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+      MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
       MmUnlockSectionSegment(Segment);
 
       /*
@@ -1213,7 +1614,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
        */
       MmSetSavedSwapEntryPage(Page, SwapEntry);
       Status = MmCreateVirtualMapping(Process,
-                                      Address,
+                                      PAddress,
                                       Region->Protect,
                                       &Page,
                                       1);
@@ -1222,10 +1623,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
+      MmInsertRmap(Page, Process, Address);
+      MiSetPageEvent(Process, Address);
+      DPRINT("Address 0x%p\n", Address);
       return(STATUS_SUCCESS);
    }
    else
@@ -1237,11 +1637,11 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
 
       Page = PFN_FROM_SSE(Entry);
 
-      MmSharePageEntrySectionSegment(Segment, Offset);
+      MmSharePageEntrySectionSegment(Segment, &Offset);
       MmUnlockSectionSegment(Segment);
 
       Status = MmCreateVirtualMapping(Process,
-                                      Address,
+                                      PAddress,
                                       Attributes,
                                       &Page,
                                       1);
@@ -1250,10 +1650,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
+      MmInsertRmap(Page, Process, Address);
+      MiSetPageEvent(Process, Address);
+      DPRINT("Address 0x%p\n", Address);
       return(STATUS_SUCCESS);
    }
 }
@@ -1262,8 +1661,7 @@ NTSTATUS
 NTAPI
 MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
                          MEMORY_AREA* MemoryArea,
-                         PVOID Address,
-                         BOOLEAN Locked)
+                         PVOID Address)
 {
    PMM_SECTION_SEGMENT Segment;
    PROS_SECTION_OBJECT Section;
@@ -1271,21 +1669,20 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    PFN_NUMBER NewPage;
    NTSTATUS Status;
    PVOID PAddress;
-   ULONG Offset;
-   PMM_PAGEOP PageOp;
+   LARGE_INTEGER Offset;
    PMM_REGION Region;
-   ULONG Entry;
+   ULONG_PTR Entry;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-    
-   DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address, Locked);
+   SWAPENTRY SwapEntry;
+
+   DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
 
    /*
-    * Check if the page has been paged out or has already been set readwrite
+    * Check if the page has already been set readwrite
     */
-   if (!MmIsPagePresent(Process, Address) ||
-         MmGetPageProtect(Process, Address) & PAGE_READWRITE)
+   if (MmGetPageProtect(Process, Address) & PAGE_READWRITE)
    {
-      DPRINT("Address 0x%.8X\n", Address);
+      DPRINT("Address 0x%p\n", Address);
       return(STATUS_SUCCESS);
    }
 
@@ -1293,32 +1690,33 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
     * Find the offset of the page
     */
    PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-   Offset = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
-            + MemoryArea->Data.SectionData.ViewOffset;
+   Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+            + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
    Segment = MemoryArea->Data.SectionData.Segment;
    Section = MemoryArea->Data.SectionData.Section;
    Region = MmFindRegion(MemoryArea->StartingAddress,
                          &MemoryArea->Data.SectionData.RegionListHead,
                          Address, NULL);
+   ASSERT(Region != NULL);
    /*
     * Lock the segment
     */
    MmLockSectionSegment(Segment);
 
-   OldPage = MmGetPfnForProcess(NULL, Address);
-   Entry = MmGetPageEntrySectionSegment(Segment, Offset);
+   OldPage = MmGetPfnForProcess(Process, Address);
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
 
    MmUnlockSectionSegment(Segment);
 
    /*
     * Check if we are doing COW
     */
-   if (!((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if (!((Segment->WriteCopy) &&
          (Region->Protect == PAGE_READWRITE ||
           Region->Protect == PAGE_EXECUTE_READWRITE)))
    {
-      DPRINT("Address 0x%.8X\n", Address);
+      DPRINT("Address 0x%p\n", Address);
       return(STATUS_ACCESS_VIOLATION);
    }
 
@@ -1326,58 +1724,51 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
        PFN_FROM_SSE(Entry) != OldPage)
    {
       /* This is a private page. We must only change the page protection. */
-      MmSetPageProtect(Process, PAddress, Region->Protect);
+      MmSetPageProtect(Process, Address, Region->Protect);
       return(STATUS_SUCCESS);
    }
 
+   if(OldPage == 0)
+      DPRINT("OldPage == 0!\n");
+
    /*
     * Get or create a pageop
     */
-   PageOp = MmGetPageOp(MemoryArea, NULL, 0, Segment, Offset,
-                        MM_PAGEOP_ACCESSFAULT, FALSE);
-   if (PageOp == NULL)
-   {
-      DPRINT1("MmGetPageOp failed\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
+   MmLockSectionSegment(Segment);
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
 
    /*
     * Wait for any other operations to complete
     */
-   if (PageOp->Thread != PsGetCurrentThread())
+   if (Entry == SWAPENTRY_FROM_SSE(MM_WAIT_ENTRY))
    {
-      MmUnlockAddressSpace(AddressSpace);
-      Status = MmspWaitForPageOpCompletionEvent(PageOp);
-      /*
-      * Check for various strange conditions
-      */
-      if (Status == STATUS_TIMEOUT)
-      {
-         DPRINT1("Failed to wait for page op, status = %x\n", Status);
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      if (PageOp->Status == STATUS_PENDING)
-      {
-         DPRINT1("Woke for page op before completion\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      /*
-      * Restart the operation
-      */
-      MmLockAddressSpace(AddressSpace);
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
-      return(STATUS_MM_RESTART_OPERATION);
+       MmUnlockSectionSegment(Segment);
+       MmUnlockAddressSpace(AddressSpace);
+       MiWaitForPageEvent(NULL, NULL);
+       /*
+        * Restart the operation
+        */
+       MmLockAddressSpace(AddressSpace);
+       DPRINT("Address 0x%p\n", Address);
+       return(STATUS_MM_RESTART_OPERATION);
    }
 
+   MmDeleteRmap(OldPage, Process, PAddress);
+   MmDeleteVirtualMapping(Process, PAddress, FALSE, NULL, NULL);
+   MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY);
+
    /*
     * Release locks now we have the pageop
     */
+   MmUnlockSectionSegment(Segment);
    MmUnlockAddressSpace(AddressSpace);
 
    /*
     * Allocate a page
     */
+   MI_SET_USAGE(MI_USAGE_SECTION);
+   if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+   if (!Process) MI_SET_PROCESS2("Kernel Section");
    Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage);
    if (!NT_SUCCESS(Status))
    {
@@ -1387,46 +1778,37 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Copy the old page
     */
-   MiCopyFromUserPage(NewPage, PAddress);
+   MiCopyFromUserPage(NewPage, OldPage);
 
    MmLockAddressSpace(AddressSpace);
-   /*
-    * Delete the old entry.
-    */
-   MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
 
    /*
     * Set the PTE to point to the new page
     */
+   MmDeletePageFileMapping(Process, PAddress, &SwapEntry);
    Status = MmCreateVirtualMapping(Process,
-                                   Address,
+                                   PAddress,
                                    Region->Protect,
                                    &NewPage,
                                    1);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-      return(Status);
-   }
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("Unable to create virtual mapping\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
+        KeBugCheck(MEMORY_MANAGEMENT);
+        return(Status);
+    }
 
    /*
     * Unshare the old page.
     */
-   MmDeleteRmap(OldPage, Process, PAddress);
+   DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
    MmInsertRmap(NewPage, Process, PAddress);
    MmLockSectionSegment(Segment);
-   MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE);
+   MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL);
    MmUnlockSectionSegment(Segment);
 
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
-   DPRINT("Address 0x%.8X\n", Address);
+   MiSetPageEvent(Process, Address);
+   DPRINT("Address 0x%p\n", Address);
    return(STATUS_SUCCESS);
 }
 
@@ -1435,7 +1817,7 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
 {
    MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
    BOOLEAN WasDirty;
-   PFN_NUMBER Page;
+   PFN_NUMBER Page = 0;
 
    PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
    if (Process)
@@ -1457,9 +1839,10 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
       MmLockSectionSegment(PageOutContext->Segment);
       MmUnsharePageEntrySectionSegment((PROS_SECTION_OBJECT)PageOutContext->Section,
                                        PageOutContext->Segment,
-                                       PageOutContext->Offset,
+                                       &PageOutContext->Offset,
                                        PageOutContext->WasDirty,
-                                       TRUE);
+                                       TRUE,
+                                       &PageOutContext->SectionEntry);
       MmUnlockSectionSegment(PageOutContext->Segment);
    }
    if (Process)
@@ -1471,30 +1854,28 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
    {
       MmReleasePageMemoryConsumer(MC_USER, Page);
    }
-
-   DPRINT("PhysicalAddress %x, Address %x\n", Page << PAGE_SHIFT, Address);
 }
 
 NTSTATUS
 NTAPI
 MmPageOutSectionView(PMMSUPPORT AddressSpace,
                      MEMORY_AREA* MemoryArea,
-                     PVOID Address,
-                     PMM_PAGEOP PageOp)
+                     PVOID Address, ULONG_PTR Entry)
 {
    PFN_NUMBER Page;
    MM_SECTION_PAGEOUT_CONTEXT Context;
    SWAPENTRY SwapEntry;
-   ULONG Entry;
-   ULONG FileOffset;
+   ULONGLONG FileOffset;
    NTSTATUS Status;
    PFILE_OBJECT FileObject;
+#ifndef NEWCC
    PBCB Bcb = NULL;
+#endif
    BOOLEAN DirectMapped;
    BOOLEAN IsImageSection;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
    KIRQL OldIrql;
-    
+
    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
    /*
@@ -1502,17 +1883,23 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
     */
    Context.Segment = MemoryArea->Data.SectionData.Segment;
    Context.Section = MemoryArea->Data.SectionData.Section;
+   Context.SectionEntry = Entry;
+   Context.CallingProcess = Process;
 
-   Context.Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-                    + MemoryArea->Data.SectionData.ViewOffset;
-   FileOffset = Context.Offset + Context.Segment->FileOffset;
+   Context.Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+                    + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
+   FileOffset = Context.Offset.QuadPart + Context.Segment->Image.FileOffset;
 
    IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
 
    FileObject = Context.Section->FileObject;
    DirectMapped = FALSE;
+
+   MmLockSectionSegment(Context.Segment);
+
+#ifndef NEWCC
    if (FileObject != NULL &&
-       !(Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+       !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
    {
       Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
 
@@ -1522,11 +1909,12 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
        * then note this is a direct mapped page.
        */
       if ((FileOffset % PAGE_SIZE) == 0 &&
-            (Context.Offset + PAGE_SIZE <= Context.Segment->RawLength || !IsImageSection))
+            (Context.Offset.QuadPart + PAGE_SIZE <= Context.Segment->RawLength.QuadPart || !IsImageSection))
       {
          DirectMapped = TRUE;
       }
    }
+#endif
 
 
    /*
@@ -1535,8 +1923,8 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
     */
    if (Context.Section->AllocationAttributes & SEC_PHYSICALMEMORY)
    {
-      DPRINT1("Trying to page out from physical memory section address 0x%X "
-              "process %d\n", Address,
+      DPRINT1("Trying to page out from physical memory section address 0x%p "
+              "process %p\n", Address,
               Process ? Process->UniqueProcessId : 0);
        KeBugCheck(MEMORY_MANAGEMENT);
    }
@@ -1544,21 +1932,33 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    /*
     * Get the section segment entry and the physical address.
     */
-   Entry = MmGetPageEntrySectionSegment(Context.Segment, Context.Offset);
    if (!MmIsPagePresent(Process, Address))
    {
-      DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n",
+      DPRINT1("Trying to page out not-present page at (%p,0x%p).\n",
               Process ? Process->UniqueProcessId : 0, Address);
        KeBugCheck(MEMORY_MANAGEMENT);
    }
    Page = MmGetPfnForProcess(Process, Address);
    SwapEntry = MmGetSavedSwapEntryPage(Page);
 
+   /*
+    * Check the reference count to ensure this page can be paged out
+    */
+   if (MmGetReferenceCountPage(Page) != 1)
+   {
+       DPRINT("Cannot page out locked section page: 0x%lu (RefCount: %lu)\n",
+               Page, MmGetReferenceCountPage(Page));
+       MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
+       MmUnlockSectionSegment(Context.Segment);
+       return STATUS_UNSUCCESSFUL;
+   }
+
    /*
     * Prepare the context structure for the rmap delete call.
     */
+   MmUnlockSectionSegment(Context.Segment);
    Context.WasDirty = FALSE;
-   if (Context.Segment->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
+   if (Context.Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
          IS_SWAP_FROM_SSE(Entry) ||
          PFN_FROM_SSE(Entry) != Page)
    {
@@ -1574,7 +1974,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
     */
    if (DirectMapped && !Context.Private)
    {
-      if(!MiIsPageFromCache(MemoryArea, Context.Offset))
+      if(!MiIsPageFromCache(MemoryArea, Context.Offset.LowPart))
       {
          DPRINT1("Direct mapped non private page is not associated with the cache.\n");
           KeBugCheck(MEMORY_MANAGEMENT);
@@ -1589,16 +1989,22 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
 
    MmDeleteAllRmaps(Page, (PVOID)&Context, MmPageOutDeleteMapping);
 
+   /* Since we passed in a surrogate, we'll get back the page entry
+    * state in our context.  This is intended to make intermediate
+    * decrements of share count not release the wait entry.
+    */
+   Entry = Context.SectionEntry;
+
    /*
     * If this wasn't a private page then we should have reduced the entry to
     * zero by deleting all the rmaps.
     */
-   if (!Context.Private && MmGetPageEntrySectionSegment(Context.Segment, Context.Offset) != 0)
+   if (!Context.Private && Entry != 0)
    {
       if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT) &&
-            !(Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+            !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
       {
-          KeBugCheck(MEMORY_MANAGEMENT);
+          KeBugCheckEx(MEMORY_MANAGEMENT, Entry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
       }
    }
 
@@ -1614,38 +2020,40 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    {
       if (Context.Private)
       {
-         DPRINT1("Found a %s private page (address %x) in a pagefile segment.\n",
+         DPRINT1("Found a %s private page (address %p) in a pagefile segment.\n",
                  Context.WasDirty ? "dirty" : "clean", Address);
-          KeBugCheck(MEMORY_MANAGEMENT);
+         KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
       }
       if (!Context.WasDirty && SwapEntry != 0)
       {
          MmSetSavedSwapEntryPage(Page, 0);
-         MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+         MmLockSectionSegment(Context.Segment);
+         MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+         MmUnlockSectionSegment(Context.Segment);
          MmReleasePageMemoryConsumer(MC_USER, Page);
-         PageOp->Status = STATUS_SUCCESS;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(NULL, NULL);
          return(STATUS_SUCCESS);
       }
    }
-   else if (Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED)
+   else if (Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
    {
       if (Context.Private)
       {
-         DPRINT1("Found a %s private page (address %x) in a shared section segment.\n",
+         DPRINT1("Found a %s private page (address %p) in a shared section segment.\n",
                  Context.WasDirty ? "dirty" : "clean", Address);
-          KeBugCheck(MEMORY_MANAGEMENT);
+         KeBugCheckEx(MEMORY_MANAGEMENT, Page, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
       }
       if (!Context.WasDirty || SwapEntry != 0)
       {
          MmSetSavedSwapEntryPage(Page, 0);
          if (SwapEntry != 0)
          {
-            MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+            MmLockSectionSegment(Context.Segment);
+            MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+            MmUnlockSectionSegment(Context.Segment);
          }
          MmReleasePageMemoryConsumer(MC_USER, Page);
-         PageOp->Status = STATUS_SUCCESS;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(NULL, NULL);
          return(STATUS_SUCCESS);
       }
    }
@@ -1653,35 +2061,40 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    {
       if (SwapEntry != 0)
       {
-         DPRINT1("Found a swapentry for a non private and direct mapped page (address %x)\n",
+         DPRINT1("Found a swapentry for a non private and direct mapped page (address %p)\n",
                  Address);
-         KeBugCheck(MEMORY_MANAGEMENT);
+         KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address);
       }
-      Status = CcRosUnmapCacheSegment(Bcb, FileOffset, FALSE);
+#ifndef NEWCC
+      Status = CcRosUnmapCacheSegment(Bcb, (ULONG)FileOffset, FALSE);
+#else
+      Status = STATUS_SUCCESS;
+#endif
+#ifndef NEWCC
       if (!NT_SUCCESS(Status))
       {
          DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status);
-         KeBugCheck(MEMORY_MANAGEMENT);
+         KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Bcb, (ULONG_PTR)FileOffset, (ULONG_PTR)Address);
       }
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+#endif
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_SUCCESS);
    }
    else if (!Context.WasDirty && !DirectMapped && !Context.Private)
    {
       if (SwapEntry != 0)
       {
-         DPRINT1("Found a swap entry for a non dirty, non private and not direct mapped page (address %x)\n",
+         DPRINT1("Found a swap entry for a non dirty, non private and not direct mapped page (address %p)\n",
                  Address);
-         KeBugCheck(MEMORY_MANAGEMENT);
+         KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, Page, (ULONG_PTR)Process, (ULONG_PTR)Address);
       }
       MmReleasePageMemoryConsumer(MC_USER, Page);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_SUCCESS);
    }
    else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
    {
+      DPRINT("Not dirty and private and not swapped (%p:%p)\n", Process, Address);
       MmSetSavedSwapEntryPage(Page, 0);
       MmLockAddressSpace(AddressSpace);
       Status = MmCreatePageFileMapping(Process,
@@ -1690,11 +2103,11 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
       MmUnlockAddressSpace(AddressSpace);
       if (!NT_SUCCESS(Status))
       {
-         KeBugCheck(MEMORY_MANAGEMENT);
+         DPRINT1("Status %x Swapping out %p:%p\n", Status, Process, Address);
+         KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Process, (ULONG_PTR)Address, SwapEntry);
       }
       MmReleasePageMemoryConsumer(MC_USER, Page);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_SUCCESS);
    }
 
@@ -1725,6 +2138,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
          }
          else
          {
+            ULONG_PTR OldEntry;
             /*
              * For non-private pages if the page wasn't direct mapped then
              * set it back into the section segment entry so we don't loose
@@ -1739,12 +2153,16 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
             MmInsertRmap(Page,
                          Process,
                          Address);
+            // If we got here, the previous entry should have been a wait
             Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
-            MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
+            MmLockSectionSegment(Context.Segment);
+            OldEntry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset);
+            ASSERT(OldEntry == 0 || OldEntry == MAKE_SWAP_SSE(MM_WAIT_ENTRY));
+            MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
+            MmUnlockSectionSegment(Context.Segment);
          }
          MmUnlockAddressSpace(AddressSpace);
-         PageOp->Status = STATUS_UNSUCCESSFUL;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(NULL, NULL);
          return(STATUS_PAGEFILE_QUOTA);
       }
    }
@@ -1786,11 +2204,10 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
                       Process,
                       Address);
          Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
-         MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
+         MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
       }
       MmUnlockAddressSpace(AddressSpace);
-      PageOp->Status = STATUS_UNSUCCESSFUL;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_UNSUCCESSFUL);
    }
 
@@ -1800,9 +2217,11 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
    MmSetSavedSwapEntryPage(Page, 0);
    if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT ||
-         Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED)
+         Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
    {
-      MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+      MmLockSectionSegment(Context.Segment);
+      MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+      MmUnlockSectionSegment(Context.Segment);
    }
    else
    {
@@ -1812,23 +2231,32 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    if (Context.Private)
    {
       MmLockAddressSpace(AddressSpace);
+      MmLockSectionSegment(Context.Segment);
       Status = MmCreatePageFileMapping(Process,
                                        Address,
                                        SwapEntry);
+      /* We had placed a wait entry upon entry ... replace it before leaving */
+      MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
+      MmUnlockSectionSegment(Context.Segment);
       MmUnlockAddressSpace(AddressSpace);
       if (!NT_SUCCESS(Status))
       {
-         KeBugCheck(MEMORY_MANAGEMENT);
+         DPRINT1("Status %x Creating page file mapping for %p:%p\n", Status, Process, Address);
+         KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Process, (ULONG_PTR)Address, SwapEntry);
       }
    }
    else
    {
+      MmLockAddressSpace(AddressSpace);
+      MmLockSectionSegment(Context.Segment);
       Entry = MAKE_SWAP_SSE(SwapEntry);
-      MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
+      /* We had placed a wait entry upon entry ... replace it before leaving */
+      MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
+      MmUnlockSectionSegment(Context.Segment);
+      MmUnlockAddressSpace(AddressSpace);
    }
 
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
+   MiSetPageEvent(NULL, NULL);
    return(STATUS_SUCCESS);
 }
 
@@ -1837,14 +2265,14 @@ NTAPI
 MmWritePageSectionView(PMMSUPPORT AddressSpace,
                        PMEMORY_AREA MemoryArea,
                        PVOID Address,
-                       PMM_PAGEOP PageOp)
+                       ULONG PageEntry)
 {
-   ULONG Offset;
+   LARGE_INTEGER Offset;
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
    PFN_NUMBER Page;
    SWAPENTRY SwapEntry;
-   ULONG Entry;
+   ULONG_PTR Entry;
    BOOLEAN Private;
    NTSTATUS Status;
    PFILE_OBJECT FileObject;
@@ -1855,8 +2283,8 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
 
    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
-   Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-            + MemoryArea->Data.SectionData.ViewOffset;
+   Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+            + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
    /*
     * Get the segment and section.
@@ -1868,7 +2296,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
    FileObject = Section->FileObject;
    DirectMapped = FALSE;
    if (FileObject != NULL &&
-         !(Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+         !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
    {
       Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
 
@@ -1877,8 +2305,8 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
        * memory area was mapped at an offset in the file which is page aligned
        * then note this is a direct mapped page.
        */
-      if (((Offset + Segment->FileOffset) % PAGE_SIZE) == 0 &&
-            (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection))
+      if (((Offset.QuadPart + Segment->Image.FileOffset) % PAGE_SIZE) == 0 &&
+            (Offset.QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection))
       {
          DirectMapped = TRUE;
       }
@@ -1890,8 +2318,8 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
     */
    if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
    {
-      DPRINT1("Trying to write back page from physical memory mapped at %X "
-              "process %d\n", Address,
+      DPRINT1("Trying to write back page from physical memory mapped at %p "
+              "process %p\n", Address,
               Process ? Process->UniqueProcessId : 0);
       KeBugCheck(MEMORY_MANAGEMENT);
    }
@@ -1899,10 +2327,10 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
    /*
     * Get the section segment entry and the physical address.
     */
-   Entry = MmGetPageEntrySectionSegment(Segment, Offset);
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
    if (!MmIsPagePresent(Process, Address))
    {
-      DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n",
+      DPRINT1("Trying to page out not-present page at (%p,0x%p).\n",
               Process ? Process->UniqueProcessId : 0, Address);
       KeBugCheck(MEMORY_MANAGEMENT);
    }
@@ -1912,7 +2340,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
    /*
     * Check for a private (COWed) page.
     */
-   if (Segment->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
+   if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
          IS_SWAP_FROM_SSE(Entry) ||
          PFN_FROM_SSE(Entry) != Page)
    {
@@ -1934,10 +2362,16 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
     */
    if (DirectMapped && !Private)
    {
+      //LARGE_INTEGER SOffset;
       ASSERT(SwapEntry == 0);
-      CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      //SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset;
+#ifndef NEWCC
+      CcRosMarkDirtyCacheSegment(Bcb, Offset.LowPart);
+#endif
+      MmLockSectionSegment(Segment);
+      MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry);
+      MmUnlockSectionSegment(Segment);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_SUCCESS);
    }
 
@@ -1950,8 +2384,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
       if (SwapEntry == 0)
       {
          MmSetDirtyAllRmaps(Page);
-         PageOp->Status = STATUS_UNSUCCESSFUL;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(NULL, NULL);
          return(STATUS_PAGEFILE_QUOTA);
       }
       MmSetSavedSwapEntryPage(Page, SwapEntry);
@@ -1966,8 +2399,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
       DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
               Status);
       MmSetDirtyAllRmaps(Page);
-      PageOp->Status = STATUS_UNSUCCESSFUL;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_UNSUCCESSFUL);
    }
 
@@ -1975,15 +2407,14 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
     * Otherwise we have succeeded.
     */
    DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
+   MiSetPageEvent(NULL, NULL);
    return(STATUS_SUCCESS);
 }
 
 static VOID
 MmAlterViewAttributes(PMMSUPPORT AddressSpace,
                       PVOID BaseAddress,
-                      ULONG RegionSize,
+                      SIZE_T RegionSize,
                       ULONG OldType,
                       ULONG OldProtect,
                       ULONG NewType,
@@ -1996,9 +2427,11 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
 
    MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+   ASSERT(MemoryArea != NULL);
    Segment = MemoryArea->Data.SectionData.Segment;
+   MmLockSectionSegment(Segment);
 
-   if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if ((Segment->WriteCopy) &&
          (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE))
    {
       DoCOW = TRUE;
@@ -2008,26 +2441,39 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
    {
       for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
       {
+         SWAPENTRY SwapEntry;
          PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE);
          ULONG Protect = NewProtect;
 
+         /* Wait for a wait entry to disappear */
+         do {
+             MmGetPageFileMapping(Process, Address, &SwapEntry);
+             if (SwapEntry != MM_WAIT_ENTRY)
+                 break;
+             MiWaitForPageEvent(Process, Address);
+         } while (TRUE);
+
          /*
           * If we doing COW for this segment then check if the page is
           * already private.
           */
          if (DoCOW && MmIsPagePresent(Process, Address))
          {
-            ULONG Offset;
-            ULONG Entry;
+            LARGE_INTEGER Offset;
+            ULONG_PTR Entry;
             PFN_NUMBER Page;
 
-            Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-                     + MemoryArea->Data.SectionData.ViewOffset;
-            Entry = MmGetPageEntrySectionSegment(Segment, Offset);
+            Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+                     + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
+            Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+            /*
+             * An MM_WAIT_ENTRY is ok in this case...  It'll just count as
+             * IS_SWAP_FROM_SSE and we'll do the right thing.
+             */
             Page = MmGetPfnForProcess(Process, Address);
 
             Protect = PAGE_READONLY;
-            if (Segment->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
+            if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
                   IS_SWAP_FROM_SSE(Entry) ||
                   PFN_FROM_SSE(Entry) != Page)
             {
@@ -2035,13 +2481,15 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
             }
          }
 
-         if (MmIsPagePresent(Process, Address))
+         if (MmIsPagePresent(Process, Address) || MmIsDisabledPage(Process, Address))
          {
             MmSetPageProtect(Process, Address,
                              Protect);
          }
       }
    }
+
+   MmUnlockSectionSegment(Segment);
 }
 
 NTSTATUS
@@ -2049,7 +2497,7 @@ NTAPI
 MmProtectSectionView(PMMSUPPORT AddressSpace,
                      PMEMORY_AREA MemoryArea,
                      PVOID BaseAddress,
-                     ULONG Length,
+                     SIZE_T Length,
                      ULONG Protect,
                      PULONG OldProtect)
 {
@@ -2059,11 +2507,13 @@ MmProtectSectionView(PMMSUPPORT AddressSpace,
 
    MaxLength = (ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)BaseAddress;
    if (Length > MaxLength)
-      Length = MaxLength;
+      Length = (ULONG)MaxLength;
 
    Region = MmFindRegion(MemoryArea->StartingAddress,
                          &MemoryArea->Data.SectionData.RegionListHead,
                          BaseAddress, NULL);
+   ASSERT(Region != NULL);
+
    if ((MemoryArea->Flags & SEC_NO_CHANGE) &&
        Region->Protect != Protect)
    {
@@ -2102,7 +2552,7 @@ MmQuerySectionView(PMEMORY_AREA MemoryArea,
    if (Section->AllocationAttributes & SEC_IMAGE)
    {
       Segment = MemoryArea->Data.SectionData.Segment;
-      Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->VirtualAddress;
+      Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->Image.VirtualAddress;
       Info->Type = MEM_IMAGE;
    }
    else
@@ -2125,19 +2575,22 @@ NTAPI
 MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
 {
    ULONG Length;
-   ULONG Offset;
-   ULONG Entry;
-   ULONG SavedSwapEntry;
+   LARGE_INTEGER Offset;
+   ULONG_PTR Entry;
+   SWAPENTRY SavedSwapEntry;
    PFN_NUMBER Page;
 
    Page = 0;
 
-   Length = PAGE_ROUND_UP(Segment->Length);
-   for (Offset = 0; Offset < Length; Offset += PAGE_SIZE)
+   MmLockSectionSegment(Segment);
+
+   Length = PAGE_ROUND_UP(Segment->Length.QuadPart);
+   for (Offset.QuadPart = 0; Offset.QuadPart < Length; Offset.QuadPart += PAGE_SIZE)
    {
-      Entry = MmGetPageEntrySectionSegment(Segment, Offset);
+      Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
       if (Entry)
       {
+         MmSetPageEntrySectionSegment(Segment, &Offset, 0);
          if (IS_SWAP_FROM_SSE(Entry))
          {
             MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry));
@@ -2153,9 +2606,10 @@ MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
             }
             MmReleasePageMemoryConsumer(MC_USER, Page);
          }
-         MmSetPageEntrySectionSegment(Segment, Offset, 0);
       }
    }
+
+   MmUnlockSectionSegment(Segment);
 }
 
 VOID NTAPI
@@ -2163,7 +2617,7 @@ MmpDeleteSection(PVOID ObjectBody)
 {
    PROS_SECTION_OBJECT Section = (PROS_SECTION_OBJECT)ObjectBody;
 
-   DPRINT("MmpDeleteSection(ObjectBody %x)\n", ObjectBody);
+   DPRINT("MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
    if (Section->AllocationAttributes & SEC_IMAGE)
    {
       ULONG i;
@@ -2185,21 +2639,40 @@ MmpDeleteSection(PVOID ObjectBody)
 
       for (i = 0; i < NrSegments; i++)
       {
-         if (SectionSegments[i].Characteristics & IMAGE_SCN_MEM_SHARED)
+         if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
          {
             MmLockSectionSegment(&SectionSegments[i]);
          }
          RefCount = InterlockedDecrementUL(&SectionSegments[i].ReferenceCount);
-         if (SectionSegments[i].Characteristics & IMAGE_SCN_MEM_SHARED)
+         if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
          {
+            MmUnlockSectionSegment(&SectionSegments[i]);
             if (RefCount == 0)
             {
                MmpFreePageFileSegment(&SectionSegments[i]);
             }
-            MmUnlockSectionSegment(&SectionSegments[i]);
          }
       }
    }
+#ifdef NEWCC
+   else if (Section->Segment && Section->Segment->Flags & MM_DATAFILE_SEGMENT)
+   {
+         ULONG RefCount = 0;
+         PMM_SECTION_SEGMENT Segment = Section->Segment;
+
+         if (Segment &&
+                 (RefCount = InterlockedDecrementUL(&Segment->ReferenceCount)) == 0)
+         {
+                 DPRINT("Freeing section segment\n");
+                 Section->Segment = NULL;
+                 MmFinalizeSegment(Segment);
+         }
+         else
+         {
+                 DPRINT("RefCount %d\n", RefCount);
+         }
+   }
+#endif
    else
    {
       /*
@@ -2212,7 +2685,7 @@ MmpDeleteSection(PVOID ObjectBody)
       if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT)
       {
          MmpFreePageFileSegment(Section->Segment);
-         MmFreePageTablesSectionSegment(Section->Segment);
+         MmFreePageTablesSectionSegment(Section->Segment, NULL);
          ExFreePool(Section->Segment);
          Section->Segment = NULL;
       }
@@ -2223,7 +2696,9 @@ MmpDeleteSection(PVOID ObjectBody)
    }
    if (Section->FileObject != NULL)
    {
+#ifndef NEWCC
       CcRosDereferenceCache(Section->FileObject);
+#endif
       ObDereferenceObject(Section->FileObject);
       Section->FileObject = NULL;
    }
@@ -2236,8 +2711,7 @@ MmpCloseSection(IN PEPROCESS Process OPTIONAL,
                 IN ULONG ProcessHandleCount,
                 IN ULONG SystemHandleCount)
 {
-   DPRINT("MmpCloseSection(OB %x, HC %d)\n",
-          Object, ProcessHandleCount);
+    DPRINT("MmpCloseSection(OB %p, HC %lu)\n", Object, ProcessHandleCount);
 }
 
 NTSTATUS
@@ -2266,7 +2740,7 @@ MmCreatePhysicalMemorySection(VOID)
                             &Obj,
                             &SectionSize,
                             PAGE_EXECUTE_READWRITE,
-                            0,
+                            SEC_PHYSICALMEMORY,
                             NULL,
                             NULL);
    if (!NT_SUCCESS(Status))
@@ -2301,6 +2775,10 @@ MmInitSectionImplementation(VOID)
 
    DPRINT("Creating Section Object Type\n");
 
+   /* Initialize the section based root */
+   ASSERT(MmSectionBasedRoot.NumberGenericTableElements == 0);
+   MmSectionBasedRoot.BalancedRoot.u1.Parent = &MmSectionBasedRoot.BalancedRoot;
+
    /* Initialize the Section object type  */
    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
    RtlInitUnicodeString(&Name, L"Section");
@@ -2312,8 +2790,9 @@ MmInitSectionImplementation(VOID)
    ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection;
    ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
    ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
+   ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
-    
+
    MmCreatePhysicalMemorySection();
 
    return(STATUS_SUCCESS);
@@ -2338,7 +2817,8 @@ MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject,
 
    if (UMaximumSize == NULL)
    {
-      return(STATUS_UNSUCCESSFUL);
+      DPRINT1("MmCreatePageFileSection: (UMaximumSize == NULL)\n");
+      return(STATUS_INVALID_PARAMETER);
    }
    MaximumSize = *UMaximumSize;
 
@@ -2356,6 +2836,7 @@ MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject,
                            (PVOID*)(PVOID)&Section);
    if (!NT_SUCCESS(Status))
    {
+      DPRINT1("MmCreatePageFileSection: failed to create object (0x%lx)\n", Status);
       return(Status);
    }
 
@@ -2363,6 +2844,8 @@ MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject,
     * Initialize it
     */
    RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
+   Section->Type = 'SC';
+   Section->Size = 'TN';
    Section->SectionPageProtection = SectionPageProtection;
    Section->AllocationAttributes = AllocationAttributes;
    Section->MaximumSize = MaximumSize;
@@ -2373,23 +2856,23 @@ MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject,
       ObDereferenceObject(Section);
       return(STATUS_NO_MEMORY);
    }
+   RtlZeroMemory(Segment, sizeof(MM_SECTION_SEGMENT));
    Section->Segment = Segment;
    Segment->ReferenceCount = 1;
    ExInitializeFastMutex(&Segment->Lock);
-   Segment->FileOffset = 0;
+   Segment->Image.FileOffset = 0;
    Segment->Protection = SectionPageProtection;
-   Segment->RawLength = MaximumSize.u.LowPart;
-   Segment->Length = PAGE_ROUND_UP(MaximumSize.u.LowPart);
+   Segment->RawLength.QuadPart = MaximumSize.u.LowPart;
+   Segment->Length.QuadPart = PAGE_ROUND_UP(MaximumSize.u.LowPart);
    Segment->Flags = MM_PAGEFILE_SEGMENT;
    Segment->WriteCopy = FALSE;
-   RtlZeroMemory(&Segment->PageDirectory, sizeof(SECTION_PAGE_DIRECTORY));
-   Segment->VirtualAddress = 0;
-   Segment->Characteristics = 0;
+   Segment->Image.VirtualAddress = 0;
+   Segment->Image.Characteristics = 0;
    *SectionObject = Section;
+   MiInitializeSectionPageTable(Segment);
    return(STATUS_SUCCESS);
 }
 
-
 NTSTATUS
 NTAPI
 MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
@@ -2426,7 +2909,7 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
                            sizeof(ROS_SECTION_OBJECT),
                            0,
                            0,
-                           (PVOID*)(PVOID)&Section);
+                           (PVOID*)&Section);
    if (!NT_SUCCESS(Status))
    {
       return(Status);
@@ -2435,26 +2918,16 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
     * Initialize it
     */
    RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
+   Section->Type = 'SC';
+   Section->Size = 'TN';
    Section->SectionPageProtection = SectionPageProtection;
    Section->AllocationAttributes = AllocationAttributes;
 
-   /*
-    * Check file access required
-    */
-   if (SectionPageProtection & PAGE_READWRITE ||
-         SectionPageProtection & PAGE_EXECUTE_READWRITE)
-   {
-      FileAccess = FILE_READ_DATA | FILE_WRITE_DATA;
-   }
-   else
-   {
-      FileAccess = FILE_READ_DATA;
-   }
-
    /*
     * Reference the file handle
     */
-   Status = ObReferenceObjectByHandle(FileHandle,
+    FileAccess = MiArm3GetCorrectFileAccessMask(SectionPageProtection);
+    Status = ObReferenceObjectByHandle(FileHandle,
                                       FileAccess,
                                       IoFileObjectType,
                                       ExGetPreviousMode(),
@@ -2588,22 +3061,23 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
       ExAcquireFastMutex(&Segment->Lock);
       FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
 
-      Segment->FileOffset = 0;
+      Segment->Image.FileOffset = 0;
       Segment->Protection = SectionPageProtection;
       Segment->Flags = MM_DATAFILE_SEGMENT;
-      Segment->Characteristics = 0;
-      Segment->WriteCopy = FALSE;
+      Segment->Image.Characteristics = 0;
+      Segment->WriteCopy = (SectionPageProtection & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY));
       if (AllocationAttributes & SEC_RESERVE)
       {
-         Segment->Length = Segment->RawLength = 0;
+         Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
       }
       else
       {
-         Segment->RawLength = MaximumSize.u.LowPart;
-         Segment->Length = PAGE_ROUND_UP(Segment->RawLength);
+         Segment->RawLength.QuadPart = MaximumSize.QuadPart;
+         Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
       }
-      Segment->VirtualAddress = 0;
-      RtlZeroMemory(&Segment->PageDirectory, sizeof(SECTION_PAGE_DIRECTORY));
+      Segment->Image.VirtualAddress = 0;
+      Segment->Locked = TRUE;
+      MiInitializeSectionPageTable(Segment);
    }
    else
    {
@@ -2618,17 +3092,19 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
       (void)InterlockedIncrementUL(&Segment->ReferenceCount);
       MmLockSectionSegment(Segment);
 
-      if (MaximumSize.u.LowPart > Segment->RawLength &&
+      if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
             !(AllocationAttributes & SEC_RESERVE))
       {
-         Segment->RawLength = MaximumSize.u.LowPart;
-         Segment->Length = PAGE_ROUND_UP(Segment->RawLength);
+         Segment->RawLength.QuadPart = MaximumSize.QuadPart;
+         Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
       }
    }
    MmUnlockSectionSegment(Segment);
    Section->FileObject = FileObject;
    Section->MaximumSize = MaximumSize;
+#ifndef NEWCC
    CcRosReferenceCache(FileObject);
+#endif
    //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
    *SectionObject = Section;
    return(STATUS_SUCCESS);
@@ -2711,6 +3187,8 @@ ExeFmtpReadFile(IN PVOID File,
    ULONG BufferSize;
    ULONG UsedSize;
    PVOID Buffer;
+   PFILE_OBJECT FileObject = File;
+   IO_STATUS_BLOCK Iosb;
 
    ASSERT_IRQL_LESS(DISPATCH_LEVEL);
 
@@ -2750,38 +3228,9 @@ ExeFmtpReadFile(IN PVOID File,
 
    UsedSize = 0;
 
-#if 0
-   Status = MmspPageRead(File,
-                         Buffer,
-                         BufferSize,
-                         &FileOffset,
-                         &UsedSize);
-#else
-/*
- * FIXME: if we don't use ZwReadFile, caching is not enabled for the file and
- * nothing will work. But using ZwReadFile is wrong, and using its side effects
- * to initialize internal state is even worse. Our cache manager is in need of
- * professional help
- */
-   {
-      IO_STATUS_BLOCK Iosb;
-
-      Status = ZwReadFile(File,
-                          NULL,
-                          NULL,
-                          NULL,
-                          &Iosb,
-                          Buffer,
-                          BufferSize,
-                          &FileOffset,
-                          NULL);
+   Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb);
 
-      if(NT_SUCCESS(Status))
-      {
-         UsedSize = Iosb.Information;
-      }
-   }
-#endif
+   UsedSize = (ULONG)Iosb.Information;
 
    if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
    {
@@ -2817,8 +3266,8 @@ MmspAssertSegmentsSorted(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 
    for( i = 1; i < ImageSectionObject->NrSegments; ++ i )
    {
-      ASSERT(ImageSectionObject->Segments[i].VirtualAddress >=
-             ImageSectionObject->Segments[i - 1].VirtualAddress);
+      ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >=
+             ImageSectionObject->Segments[i - 1].Image.VirtualAddress);
    }
 }
 
@@ -2833,13 +3282,13 @@ MmspAssertSegmentsNoOverlap(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 
    for( i = 0; i < ImageSectionObject->NrSegments; ++ i )
    {
-      ASSERT(ImageSectionObject->Segments[i].Length > 0);
+      ASSERT(ImageSectionObject->Segments[i].Length.QuadPart > 0);
 
       if(i > 0)
       {
-         ASSERT(ImageSectionObject->Segments[i].VirtualAddress >=
-                (ImageSectionObject->Segments[i - 1].VirtualAddress +
-                 ImageSectionObject->Segments[i - 1].Length));
+         ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >=
+                (ImageSectionObject->Segments[i - 1].Image.VirtualAddress +
+                 ImageSectionObject->Segments[i - 1].Length.QuadPart));
       }
    }
 }
@@ -2853,8 +3302,8 @@ MmspAssertSegmentsPageAligned(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 
    for( i = 0; i < ImageSectionObject->NrSegments; ++ i )
    {
-      ASSERT((ImageSectionObject->Segments[i].VirtualAddress % PAGE_SIZE) == 0);
-      ASSERT((ImageSectionObject->Segments[i].Length % PAGE_SIZE) == 0);
+      ASSERT((ImageSectionObject->Segments[i].Image.VirtualAddress % PAGE_SIZE) == 0);
+      ASSERT((ImageSectionObject->Segments[i].Length.QuadPart % PAGE_SIZE) == 0);
    }
 }
 #endif
@@ -2869,7 +3318,7 @@ MmspCompareSegments(const void * x,
    const MM_SECTION_SEGMENT *Segment2 = (const MM_SECTION_SEGMENT *)y;
 
    return
-      (Segment1->VirtualAddress - Segment2->VirtualAddress) >>
+      (Segment1->Image.VirtualAddress - Segment2->Image.VirtualAddress) >>
       ((sizeof(ULONG_PTR) - sizeof(int)) * 8);
 }
 
@@ -2922,7 +3371,7 @@ MmspCheckSegmentBounds
 
    for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
    {
-      if(ImageSectionObject->Segments[i].Length == 0)
+      if(ImageSectionObject->Segments[i].Length.QuadPart == 0)
       {
          return FALSE;
       }
@@ -2936,9 +3385,9 @@ MmspCheckSegmentBounds
           * (NtMapViewOfSection could then refuse to map them, and they could
           * e.g. only be allowed as parameters to NtCreateProcess, like on UNIX)
           */
-         if ((ImageSectionObject->Segments[i - 1].VirtualAddress +
-              ImageSectionObject->Segments[i - 1].Length) !=
-              ImageSectionObject->Segments[i].VirtualAddress)
+         if ((ImageSectionObject->Segments[i - 1].Image.VirtualAddress +
+              ImageSectionObject->Segments[i - 1].Length.QuadPart) !=
+              ImageSectionObject->Segments[i].Image.VirtualAddress)
          {
             return FALSE;
          }
@@ -2963,7 +3412,6 @@ MmspPageAlignSegments
 {
    ULONG i;
    ULONG LastSegment;
-   BOOLEAN Initialized;
    PMM_SECTION_SEGMENT EffectiveSegment;
 
    if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED)
@@ -2972,7 +3420,6 @@ MmspPageAlignSegments
       return TRUE;
    }
 
-   Initialized = FALSE;
    LastSegment = 0;
    EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
 
@@ -2986,19 +3433,19 @@ MmspPageAlignSegments
          ULONG_PTR VirtualAddress;
          ULONG_PTR VirtualOffset;
 
-         VirtualAddress = EffectiveSegment->VirtualAddress;
+         VirtualAddress = EffectiveSegment->Image.VirtualAddress;
 
          /* Round down the virtual address to the nearest page */
-         EffectiveSegment->VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress);
+         EffectiveSegment->Image.VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress);
 
          /* Round up the virtual size to the nearest page */
-         EffectiveSegment->Length = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length) -
-                                    EffectiveSegment->VirtualAddress;
+         EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length.QuadPart) -
+                                    EffectiveSegment->Image.VirtualAddress;
 
          /* Adjust the raw address and size */
-         VirtualOffset = VirtualAddress - EffectiveSegment->VirtualAddress;
+         VirtualOffset = VirtualAddress - EffectiveSegment->Image.VirtualAddress;
 
-         if (EffectiveSegment->FileOffset < VirtualOffset)
+         if (EffectiveSegment->Image.FileOffset < VirtualOffset)
          {
             return FALSE;
          }
@@ -3008,22 +3455,22 @@ MmspPageAlignSegments
           * offset point in curious and odd places, but that's what we were
           * asked for
           */
-         EffectiveSegment->FileOffset -= VirtualOffset;
-         EffectiveSegment->RawLength += VirtualOffset;
+         EffectiveSegment->Image.FileOffset -= VirtualOffset;
+         EffectiveSegment->RawLength.QuadPart += VirtualOffset;
       }
       else
       {
          PMM_SECTION_SEGMENT Segment = &ImageSectionObject->Segments[i];
          ULONG_PTR EndOfEffectiveSegment;
 
-         EndOfEffectiveSegment = EffectiveSegment->VirtualAddress + EffectiveSegment->Length;
+         EndOfEffectiveSegment = (ULONG_PTR)(EffectiveSegment->Image.VirtualAddress + EffectiveSegment->Length.QuadPart);
          ASSERT((EndOfEffectiveSegment % PAGE_SIZE) == 0);
 
          /*
           * The current segment begins exactly where the current effective
           * segment ended, therefore beginning a new effective segment
           */
-         if (EndOfEffectiveSegment == Segment->VirtualAddress)
+         if (EndOfEffectiveSegment == Segment->Image.VirtualAddress)
          {
             LastSegment ++;
             ASSERT(LastSegment <= i);
@@ -3044,14 +3491,14 @@ MmspPageAlignSegments
              * Page-align the virtual size. We know for sure the virtual address
              * already is
              */
-            ASSERT((EffectiveSegment->VirtualAddress % PAGE_SIZE) == 0);
-            EffectiveSegment->Length = PAGE_ROUND_UP(EffectiveSegment->Length);
+            ASSERT((EffectiveSegment->Image.VirtualAddress % PAGE_SIZE) == 0);
+            EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(EffectiveSegment->Length.QuadPart);
          }
          /*
           * The current segment is still part of the current effective segment:
           * extend the effective segment to reflect this
           */
-         else if (EndOfEffectiveSegment > Segment->VirtualAddress)
+         else if (EndOfEffectiveSegment > Segment->Image.VirtualAddress)
          {
             static const ULONG FlagsToProtection[16] =
             {
@@ -3080,21 +3527,21 @@ MmspPageAlignSegments
              */
 
             /* Unaligned segments must be contiguous within the file */
-            if (Segment->FileOffset != (EffectiveSegment->FileOffset +
-                                        EffectiveSegment->RawLength))
+            if (Segment->Image.FileOffset != (EffectiveSegment->Image.FileOffset +
+                                        EffectiveSegment->RawLength.QuadPart))
             {
                return FALSE;
             }
 
-            EffectiveSegment->RawLength += Segment->RawLength;
+            EffectiveSegment->RawLength.QuadPart += Segment->RawLength.QuadPart;
 
             /*
              * Extend the virtual size
              */
-            ASSERT(PAGE_ROUND_UP(Segment->VirtualAddress + Segment->Length) >= EndOfEffectiveSegment);
+            ASSERT(PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) >= EndOfEffectiveSegment);
 
-            EffectiveSegment->Length = PAGE_ROUND_UP(Segment->VirtualAddress + Segment->Length) -
-                                       EffectiveSegment->VirtualAddress;
+            EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) -
+                                       EffectiveSegment->Image.VirtualAddress;
 
             /*
              * Merge the protection
@@ -3226,18 +3673,18 @@ ExeFmtpCreateImageSection(HANDLE FileHandle,
     * Some defaults
     */
    /* FIXME? are these values platform-dependent? */
-   if(ImageSectionObject->StackReserve == 0)
-      ImageSectionObject->StackReserve = 0x40000;
+   if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
+       ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
 
-   if(ImageSectionObject->StackCommit == 0)
-      ImageSectionObject->StackCommit = 0x1000;
+   if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
+       ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
 
-   if(ImageSectionObject->ImageBase == 0)
+   if(ImageSectionObject->BasedAddress == NULL)
    {
-      if(ImageSectionObject->ImageCharacteristics & IMAGE_FILE_DLL)
-         ImageSectionObject->ImageBase = 0x10000000;
+      if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
+         ImageSectionObject->BasedAddress = (PVOID)0x10000000;
       else
-         ImageSectionObject->ImageBase = 0x00400000;
+         ImageSectionObject->BasedAddress = (PVOID)0x00400000;
    }
 
    /*
@@ -3282,9 +3729,7 @@ ExeFmtpCreateImageSection(HANDLE FileHandle,
    {
       ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
       ImageSectionObject->Segments[i].ReferenceCount = 1;
-
-      RtlZeroMemory(&ImageSectionObject->Segments[i].PageDirectory,
-                    sizeof(ImageSectionObject->Segments[i].PageDirectory));
+      MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
    }
 
    ASSERT(NT_SUCCESS(Status));
@@ -3298,51 +3743,16 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
                      PLARGE_INTEGER UMaximumSize,
                      ULONG SectionPageProtection,
                      ULONG AllocationAttributes,
-                     HANDLE FileHandle)
+                     PFILE_OBJECT FileObject)
 {
    PROS_SECTION_OBJECT Section;
    NTSTATUS Status;
-   PFILE_OBJECT FileObject;
    PMM_SECTION_SEGMENT SectionSegments;
    PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
    ULONG i;
-   ULONG FileAccess = 0;
-
-   /*
-    * Specifying a maximum size is meaningless for an image section
-    */
-   if (UMaximumSize != NULL)
-   {
-      return(STATUS_INVALID_PARAMETER_4);
-   }
-
-   /*
-    * Check file access required
-    */
-   if (SectionPageProtection & PAGE_READWRITE ||
-         SectionPageProtection & PAGE_EXECUTE_READWRITE)
-   {
-      FileAccess = FILE_READ_DATA | FILE_WRITE_DATA;
-   }
-   else
-   {
-      FileAccess = FILE_READ_DATA;
-   }
 
-   /*
-    * Reference the file handle
-    */
-   Status = ObReferenceObjectByHandle(FileHandle,
-                                      FileAccess,
-                                      IoFileObjectType,
-                                      ExGetPreviousMode(),
-                                      (PVOID*)(PVOID)&FileObject,
-                                      NULL);
-
-   if (!NT_SUCCESS(Status))
-   {
-      return Status;
-   }
+   if (FileObject == NULL)
+      return STATUS_INVALID_FILE_FOR_SECTION;
 
    /*
     * Create the section
@@ -3366,14 +3776,20 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
     * Initialize it
     */
    RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
+   Section->Type = 'SC';
+   Section->Size = 'TN';
    Section->SectionPageProtection = SectionPageProtection;
    Section->AllocationAttributes = AllocationAttributes;
 
+#ifndef NEWCC
    /*
     * Initialized caching for this file object if previously caching
     * was initialized for the same on disk file
     */
    Status = CcTryToInitializeFileCache(FileObject);
+#else
+   Status = STATUS_SUCCESS;
+#endif
 
    if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL)
    {
@@ -3389,14 +3805,14 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
 
       RtlZeroMemory(ImageSectionObject, sizeof(MM_IMAGE_SECTION_OBJECT));
 
-      StatusExeFmt = ExeFmtpCreateImageSection(FileHandle, ImageSectionObject);
+      StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
 
       if (!NT_SUCCESS(StatusExeFmt))
       {
          if(ImageSectionObject->Segments != NULL)
             ExFreePool(ImageSectionObject->Segments);
 
-         ExFreePool(ImageSectionObject);
+         ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
          ObDereferenceObject(Section);
          ObDereferenceObject(FileObject);
          return(StatusExeFmt);
@@ -3466,138 +3882,15 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
       Status = STATUS_SUCCESS;
    }
    Section->FileObject = FileObject;
+#ifndef NEWCC
    CcRosReferenceCache(FileObject);
+#endif
    //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
    *SectionObject = Section;
    return(Status);
 }
 
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-NtCreateSection (OUT PHANDLE SectionHandle,
-                 IN ACCESS_MASK DesiredAccess,
-                 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
-                 IN PLARGE_INTEGER MaximumSize OPTIONAL,
-                 IN ULONG SectionPageProtection OPTIONAL,
-                 IN ULONG AllocationAttributes,
-                 IN HANDLE FileHandle OPTIONAL)
-{
-   LARGE_INTEGER SafeMaximumSize;
-   PVOID SectionObject;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode != KernelMode)
-   {
-     _SEH2_TRY
-     {
-       if (MaximumSize != NULL)
-       {
-          /* make a copy on the stack */
-          SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
-          MaximumSize = &SafeMaximumSize;
-       }
-       ProbeForWriteHandle(SectionHandle);
-     }
-     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-     {
-         /* Return the exception code */
-         _SEH2_YIELD(return _SEH2_GetExceptionCode());
-     }
-     _SEH2_END;
-   }
-
-   Status = MmCreateSection(&SectionObject,
-                            DesiredAccess,
-                            ObjectAttributes,
-                            MaximumSize,
-                            SectionPageProtection,
-                            AllocationAttributes,
-                            FileHandle,
-                            NULL);
-   if (NT_SUCCESS(Status))
-   {
-      Status = ObInsertObject ((PVOID)SectionObject,
-                               NULL,
-                               DesiredAccess,
-                               0,
-                               NULL,
-                               SectionHandle);
-   }
-
-   return Status;
-}
-
-
-/**********************************************************************
- * NAME
- *  NtOpenSection
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *  SectionHandle
- *
- *  DesiredAccess
- *
- *  ObjectAttributes
- *
- * RETURN VALUE
- *
- * REVISIONS
- */
-NTSTATUS NTAPI
-NtOpenSection(PHANDLE   SectionHandle,
-              ACCESS_MASK  DesiredAccess,
-              POBJECT_ATTRIBUTES ObjectAttributes)
-{
-   HANDLE hSection;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode != KernelMode)
-   {
-     _SEH2_TRY
-     {
-       ProbeForWriteHandle(SectionHandle);
-     }
-     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-     {
-        /* Return the exception code */
-        _SEH2_YIELD(return _SEH2_GetExceptionCode());
-     }
-     _SEH2_END;
-   }
-
-   Status = ObOpenObjectByName(ObjectAttributes,
-                               MmSectionObjectType,
-                               PreviousMode,
-                               NULL,
-                               DesiredAccess,
-                               NULL,
-                               &hSection);
-
-   if(NT_SUCCESS(Status))
-   {
-     _SEH2_TRY
-     {
-       *SectionHandle = hSection;
-     }
-     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-     {
-       Status = _SEH2_GetExceptionCode();
-     }
-     _SEH2_END;
-   }
 
-   return(Status);
-}
 
 static NTSTATUS
 MmMapViewOfSegment(PMMSUPPORT AddressSpace,
@@ -3611,281 +3904,75 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace,
 {
    PMEMORY_AREA MArea;
    NTSTATUS Status;
-   PHYSICAL_ADDRESS BoundaryAddressMultiple;
-
-   BoundaryAddressMultiple.QuadPart = 0;
+   ULONG Granularity;
+
+   if (Segment->WriteCopy)
+   {
+       /* We have to do this because the not present fault
+        * and access fault handlers depend on the protection
+        * that should be granted AFTER the COW fault takes
+        * place to be in Region->Protect. The not present fault
+        * handler changes this to the correct protection for COW when
+        * mapping the pages into the process's address space. If a COW
+        * fault takes place, the access fault handler sets the page protection
+        * to these values for the newly copied pages
+        */
+       if (Protect == PAGE_WRITECOPY)
+           Protect = PAGE_READWRITE;
+       else if (Protect == PAGE_EXECUTE_WRITECOPY)
+           Protect = PAGE_EXECUTE_READWRITE;
+   }
+
+   if (*BaseAddress == NULL)
+      Granularity = MM_ALLOCATION_GRANULARITY;
+   else
+      Granularity = PAGE_SIZE;
 
+#ifdef NEWCC
+   if (Segment->Flags & MM_DATAFILE_SEGMENT) {
+      LARGE_INTEGER FileOffset;
+      FileOffset.QuadPart = ViewOffset;
+      ObReferenceObject(Section);
+      return _MiMapViewOfSegment(AddressSpace, Segment, BaseAddress, ViewSize, Protect, &FileOffset, AllocationType, __FILE__, __LINE__);
+   }
+#endif
    Status = MmCreateMemoryArea(AddressSpace,
                                MEMORY_AREA_SECTION_VIEW,
                                BaseAddress,
-                               ViewSize,
-                               Protect,
-                               &MArea,
-                               FALSE,
-                               AllocationType,
-                               BoundaryAddressMultiple);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("Mapping between 0x%.8X and 0x%.8X failed (%X).\n",
-              (*BaseAddress), (char*)(*BaseAddress) + ViewSize, Status);
-      return(Status);
-   }
-
-   ObReferenceObject((PVOID)Section);
-
-   MArea->Data.SectionData.Segment = Segment;
-   MArea->Data.SectionData.Section = Section;
-   MArea->Data.SectionData.ViewOffset = ViewOffset;
-   MArea->Data.SectionData.WriteCopyView = FALSE;
-   MmInitializeRegion(&MArea->Data.SectionData.RegionListHead,
-                      ViewSize, 0, Protect);
-
-   return(STATUS_SUCCESS);
-}
-
-
-/**********************************************************************
- * NAME       EXPORTED
- * NtMapViewOfSection
- *
- * DESCRIPTION
- * Maps a view of a section into the virtual address space of a
- * process.
- *
- * ARGUMENTS
- * SectionHandle
- *  Handle of the section.
- *
- * ProcessHandle
- *  Handle of the process.
- *
- * BaseAddress
- *  Desired base address (or NULL) on entry;
- *  Actual base address of the view on exit.
- *
- * ZeroBits
- *  Number of high order address bits that must be zero.
- *
- * CommitSize
- *  Size in bytes of the initially committed section of
- *  the view.
- *
- * SectionOffset
- *  Offset in bytes from the beginning of the section
- *  to the beginning of the view.
- *
- * ViewSize
- *  Desired length of map (or zero to map all) on entry
- *  Actual length mapped on exit.
- *
- * InheritDisposition
- *  Specified how the view is to be shared with
- *  child processes.
- *
- * AllocateType
- *  Type of allocation for the pages.
- *
- * Protect
- *  Protection for the committed region of the view.
- *
- * RETURN VALUE
- *  Status.
- *
- * @implemented
- */
-NTSTATUS NTAPI
-NtMapViewOfSection(IN HANDLE SectionHandle,
-                   IN HANDLE ProcessHandle,
-                   IN OUT PVOID* BaseAddress  OPTIONAL,
-                   IN ULONG_PTR ZeroBits  OPTIONAL,
-                   IN SIZE_T CommitSize,
-                   IN OUT PLARGE_INTEGER SectionOffset  OPTIONAL,
-                   IN OUT PSIZE_T ViewSize,
-                   IN SECTION_INHERIT InheritDisposition,
-                   IN ULONG AllocationType  OPTIONAL,
-                   IN ULONG Protect)
-{
-   PVOID SafeBaseAddress;
-   LARGE_INTEGER SafeSectionOffset;
-   SIZE_T SafeViewSize;
-   PROS_SECTION_OBJECT Section;
-   PEPROCESS Process;
-   KPROCESSOR_MODE PreviousMode;
-   PMMSUPPORT AddressSpace;
-   NTSTATUS Status;
-   ULONG tmpProtect;
-   ACCESS_MASK DesiredAccess;
-
-   /*
-    * Check the protection
-    */
-   if (Protect & ~PAGE_FLAGS_VALID_FROM_USER_MODE)
-   {
-     return STATUS_INVALID_PARAMETER_10;
-   }
-
-   tmpProtect = Protect & ~(PAGE_GUARD|PAGE_NOCACHE);
-   if (tmpProtect != PAGE_NOACCESS &&
-       tmpProtect != PAGE_READONLY &&
-       tmpProtect != PAGE_READWRITE &&
-       tmpProtect != PAGE_WRITECOPY &&
-       tmpProtect != PAGE_EXECUTE &&
-       tmpProtect != PAGE_EXECUTE_READ &&
-       tmpProtect != PAGE_EXECUTE_READWRITE &&
-       tmpProtect != PAGE_EXECUTE_WRITECOPY)
-   {
-     return STATUS_INVALID_PAGE_PROTECTION;
-   }
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode != KernelMode)
-   {
-     SafeBaseAddress = NULL;
-     SafeSectionOffset.QuadPart = 0;
-     SafeViewSize = 0;
-
-     _SEH2_TRY
-     {
-       if(BaseAddress != NULL)
-       {
-         ProbeForWritePointer(BaseAddress);
-         SafeBaseAddress = *BaseAddress;
-       }
-       if(SectionOffset != NULL)
-       {
-         ProbeForWriteLargeInteger(SectionOffset);
-         SafeSectionOffset = *SectionOffset;
-       }
-       ProbeForWriteSize_t(ViewSize);
-       SafeViewSize = *ViewSize;
-     }
-     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-     {
-         /* Return the exception code */
-         _SEH2_YIELD(return _SEH2_GetExceptionCode());
-     }
-     _SEH2_END;
-   }
-   else
-   {
-     SafeBaseAddress = (BaseAddress != NULL ? *BaseAddress : NULL);
-     SafeSectionOffset.QuadPart = (SectionOffset != NULL ? SectionOffset->QuadPart : 0);
-     SafeViewSize = (ViewSize != NULL ? *ViewSize : 0);
-   }
-
-   SafeSectionOffset.LowPart = PAGE_ROUND_DOWN(SafeSectionOffset.LowPart);
-
-   Status = ObReferenceObjectByHandle(ProcessHandle,
-                                      PROCESS_VM_OPERATION,
-                                      PsProcessType,
-                                      PreviousMode,
-                                      (PVOID*)(PVOID)&Process,
-                                      NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      return(Status);
-   }
-
-   AddressSpace = &Process->Vm;
-
-   /* Convert NT Protection Attr to Access Mask */
-   if (Protect == PAGE_READONLY)
-   {
-      DesiredAccess = SECTION_MAP_READ;
-   }
-   else if (Protect == PAGE_READWRITE)
-   {
-      DesiredAccess = SECTION_MAP_WRITE;
-   }
-   else if (Protect == PAGE_WRITECOPY)
-   {
-      DesiredAccess = SECTION_QUERY;
-   }
-   /* FIXME: Handle other Protection Attributes. For now keep previous behavior */
-   else
-   {
-      DesiredAccess = SECTION_MAP_READ;
-   }
-
-   Status = ObReferenceObjectByHandle(SectionHandle,
-                                      DesiredAccess,
-                                      MmSectionObjectType,
-                                      PreviousMode,
-                                      (PVOID*)(PVOID)&Section,
-                                      NULL);
-   if (!(NT_SUCCESS(Status)))
-   {
-      DPRINT("ObReference failed rc=%x\n",Status);
-      ObDereferenceObject(Process);
-      return(Status);
-   }
-
-   Status = MmMapViewOfSection(Section,
-                               (PEPROCESS)Process,
-                               (BaseAddress != NULL ? &SafeBaseAddress : NULL),
-                               ZeroBits,
-                               CommitSize,
-                               (SectionOffset != NULL ? &SafeSectionOffset : NULL),
-                               (ViewSize != NULL ? &SafeViewSize : NULL),
-                               InheritDisposition,
+                               ViewSize,
+                               Protect,
+                               &MArea,
+                               FALSE,
                                AllocationType,
-                               Protect);
-
-   /* Check if this is an image for the current process */
-   if ((Section->AllocationAttributes & SEC_IMAGE) &&
-       (Process == PsGetCurrentProcess()) &&
-       (Status != STATUS_IMAGE_NOT_AT_BASE))
+                               Granularity);
+   if (!NT_SUCCESS(Status))
    {
-        /* Notify the debugger */
-       DbgkMapViewOfSection(Section,
-                            SafeBaseAddress,
-                            SafeSectionOffset.LowPart,
-                            SafeViewSize);
+      DPRINT1("Mapping between 0x%p and 0x%p failed (%X).\n",
+              (*BaseAddress), (char*)(*BaseAddress) + ViewSize, Status);
+      return(Status);
    }
 
-   ObDereferenceObject(Section);
-   ObDereferenceObject(Process);
+   ObReferenceObject((PVOID)Section);
 
-   if(NT_SUCCESS(Status))
-   {
-     /* copy parameters back to the caller */
-     _SEH2_TRY
-     {
-       if(BaseAddress != NULL)
-       {
-         *BaseAddress = SafeBaseAddress;
-       }
-       if(SectionOffset != NULL)
-       {
-         *SectionOffset = SafeSectionOffset;
-       }
-       if(ViewSize != NULL)
-       {
-         *ViewSize = SafeViewSize;
-       }
-     }
-     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-     {
-       Status = _SEH2_GetExceptionCode();
-     }
-     _SEH2_END;
-   }
+   MArea->Data.SectionData.Segment = Segment;
+   MArea->Data.SectionData.Section = Section;
+   MArea->Data.SectionData.ViewOffset.QuadPart = ViewOffset;
+   MmInitializeRegion(&MArea->Data.SectionData.RegionListHead,
+                      ViewSize, 0, Protect);
 
-   return(Status);
+   return(STATUS_SUCCESS);
 }
 
+
 static VOID
 MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
                   PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
 {
-   ULONG Entry;
+   ULONG_PTR Entry;
    PFILE_OBJECT FileObject;
    PBCB Bcb;
-   ULONG Offset;
+   LARGE_INTEGER Offset;
    SWAPENTRY SavedSwapEntry;
-   PMM_PAGEOP PageOp;
-   NTSTATUS Status;
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
    PMMSUPPORT AddressSpace;
@@ -3896,34 +3983,25 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
 
    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
-   Offset = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
-            MemoryArea->Data.SectionData.ViewOffset;
+   Offset.QuadPart = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
+            MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
    Section = MemoryArea->Data.SectionData.Section;
    Segment = MemoryArea->Data.SectionData.Segment;
 
-   PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL, Segment, Offset);
-
-   while (PageOp)
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+   while (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
    {
       MmUnlockSectionSegment(Segment);
       MmUnlockAddressSpace(AddressSpace);
 
-      Status = MmspWaitForPageOpCompletionEvent(PageOp);
-      if (Status != STATUS_SUCCESS)
-      {
-         DPRINT1("Failed to wait for page op, status = %x\n", Status);
-         KeBugCheck(MEMORY_MANAGEMENT);
-      }
+      MiWaitForPageEvent(NULL, NULL);
 
       MmLockAddressSpace(AddressSpace);
       MmLockSectionSegment(Segment);
-      MmspCompleteAndReleasePageOp(PageOp);
-      PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL, Segment, Offset);
+      Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
    }
 
-   Entry = MmGetPageEntrySectionSegment(Segment, Offset);
-
    /*
     * For a dirty, datafile, non-private page mark it as dirty in the
     * cache manager.
@@ -3934,7 +4012,9 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
       {
          FileObject = MemoryArea->Data.SectionData.Section->FileObject;
          Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-         CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
+#ifndef NEWCC
+         CcRosMarkDirtyCacheSegment(Bcb, (ULONG)(Offset.QuadPart + Segment->Image.FileOffset));
+#endif
          ASSERT(SwapEntry == 0);
       }
    }
@@ -3979,7 +4059,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
       else
       {
          MmDeleteRmap(Page, Process, Address);
-         MmUnsharePageEntrySectionSegment(Section, Segment, Offset, Dirty, FALSE);
+         MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, Dirty, FALSE, NULL);
       }
    }
 }
@@ -4007,6 +4087,11 @@ MmUnmapViewOfSegment(PMMSUPPORT AddressSpace,
    Section = MemoryArea->Data.SectionData.Section;
    Segment = MemoryArea->Data.SectionData.Segment;
 
+#ifdef NEWCC
+   if (Segment->Flags & MM_DATAFILE_SEGMENT)
+      return MmUnmapViewOfCacheSegment(AddressSpace, BaseAddress);
+#endif
+
    MmLockSectionSegment(Segment);
 
    RegionListHead = &MemoryArea->Data.SectionData.RegionListHead;
@@ -4033,30 +4118,27 @@ MmUnmapViewOfSegment(PMMSUPPORT AddressSpace,
    }
    MmUnlockSectionSegment(Segment);
    ObDereferenceObject(Section);
-   return(STATUS_SUCCESS);
+   return(Status);
 }
 
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-MmUnmapViewOfSection(PEPROCESS Process,
-                     PVOID BaseAddress)
+NTSTATUS
+NTAPI
+MiRosUnmapViewOfSection(IN PEPROCESS Process,
+                        IN PVOID BaseAddress,
+                        IN ULONG Flags)
 {
    NTSTATUS Status;
    PMEMORY_AREA MemoryArea;
    PMMSUPPORT AddressSpace;
    PROS_SECTION_OBJECT Section;
-   PMM_PAGEOP PageOp;
-   ULONG_PTR Offset;
-    PVOID ImageBaseAddress = 0;
+   PVOID ImageBaseAddress = 0;
 
-   DPRINT("Opening memory area Process %x BaseAddress %x\n",
+   DPRINT("Opening memory area Process %p BaseAddress %p\n",
           Process, BaseAddress);
 
    ASSERT(Process);
 
-   AddressSpace = &Process->Vm;
+   AddressSpace = Process ? &Process->Vm : MmGetKernelAddressSpace();
 
    MmLockAddressSpace(AddressSpace);
    MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
@@ -4065,45 +4147,13 @@ MmUnmapViewOfSection(PEPROCESS Process,
        MemoryArea->Type != MEMORY_AREA_SECTION_VIEW ||
        MemoryArea->DeleteInProgress)
    {
+      if (MemoryArea) NT_ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
       MmUnlockAddressSpace(AddressSpace);
       return STATUS_NOT_MAPPED_VIEW;
    }
 
    MemoryArea->DeleteInProgress = TRUE;
 
-   while (MemoryArea->PageOpCount)
-   {
-      Offset = PAGE_ROUND_UP((ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)MemoryArea->StartingAddress);
-
-      while (Offset)
-      {
-         Offset -= PAGE_SIZE;
-         PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL,
-                                   MemoryArea->Data.SectionData.Segment,
-                                   Offset + MemoryArea->Data.SectionData.ViewOffset);
-         if (PageOp)
-         {
-            MmUnlockAddressSpace(AddressSpace);
-            Status = MmspWaitForPageOpCompletionEvent(PageOp);
-            if (Status != STATUS_SUCCESS)
-            {
-               DPRINT1("Failed to wait for page op, status = %x\n", Status);
-               KeBugCheck(MEMORY_MANAGEMENT);
-            }
-            MmLockAddressSpace(AddressSpace);
-            MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
-                                                     BaseAddress);
-            if (MemoryArea == NULL ||
-                MemoryArea->Type != MEMORY_AREA_SECTION_VIEW)
-            {
-               MmUnlockAddressSpace(AddressSpace);
-               return STATUS_NOT_MAPPED_VIEW;
-            }
-            break;
-         }
-      }
-   }
-
    Section = MemoryArea->Data.SectionData.Section;
 
    if (Section->AllocationAttributes & SEC_IMAGE)
@@ -4123,11 +4173,11 @@ MmUnmapViewOfSection(PEPROCESS Process,
        * and calculate the image base address */
       for (i = 0; i < NrSegments; i++)
       {
-         if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+         if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
          {
             if (Segment == &SectionSegments[i])
             {
-               ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress;
+               ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
                break;
             }
          }
@@ -4139,18 +4189,20 @@ MmUnmapViewOfSection(PEPROCESS Process,
 
       for (i = 0; i < NrSegments; i++)
       {
-         if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+         if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
          {
             PVOID SBaseAddress = (PVOID)
-                                 ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress);
+                                 ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
 
             Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
+            NT_ASSERT(NT_SUCCESS(Status));
          }
       }
    }
    else
    {
       Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
+      NT_ASSERT(NT_SUCCESS(Status));
    }
 
    MmUnlockAddressSpace(AddressSpace);
@@ -4161,54 +4213,7 @@ MmUnmapViewOfSection(PEPROCESS Process,
    return(STATUS_SUCCESS);
 }
 
-/**********************************************************************
- * NAME       EXPORTED
- * NtUnmapViewOfSection
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- * ProcessHandle
- *
- * BaseAddress
- *
- * RETURN VALUE
- * Status.
- *
- * REVISIONS
- */
-NTSTATUS NTAPI
-NtUnmapViewOfSection (HANDLE ProcessHandle,
-                      PVOID BaseAddress)
-{
-   PEPROCESS Process;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-
-   DPRINT("NtUnmapViewOfSection(ProcessHandle %x, BaseAddress %x)\n",
-          ProcessHandle, BaseAddress);
-
-   PreviousMode = ExGetPreviousMode();
-
-   DPRINT("Referencing process\n");
-   Status = ObReferenceObjectByHandle(ProcessHandle,
-                                      PROCESS_VM_OPERATION,
-                                      PsProcessType,
-                                      PreviousMode,
-                                      (PVOID*)(PVOID)&Process,
-                                      NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("ObReferenceObjectByHandle failed (Status %x)\n", Status);
-      return(Status);
-   }
 
-   Status = MmUnmapViewOfSection(Process, BaseAddress);
-
-   ObDereferenceObject(Process);
-
-   return Status;
-}
 
 
 /**
@@ -4251,7 +4256,7 @@ NtQuerySection(IN HANDLE SectionHandle,
                                         ExSectionInfoClass,
                                         sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]),
                                         SectionInformation,
-                                        SectionInformationLength,
+                                        (ULONG)SectionInformationLength,
                                         NULL,
                                         ResultLength,
                                         PreviousMode);
@@ -4286,8 +4291,8 @@ NtQuerySection(IN HANDLE SectionHandle,
                }
                else
                {
-                  Sbi->BaseAddress = (PVOID)Section->Segment->VirtualAddress;
-                  Sbi->Size.QuadPart = Section->Segment->Length;
+                  Sbi->BaseAddress = (PVOID)Section->Segment->Image.VirtualAddress;
+                  Sbi->Size.QuadPart = Section->Segment->Length.QuadPart;
                }
 
                if (ResultLength != NULL)
@@ -4311,21 +4316,12 @@ NtQuerySection(IN HANDLE SectionHandle,
 
             _SEH2_TRY
             {
-               memset(Sii, 0, sizeof(SECTION_IMAGE_INFORMATION));
                if (Section->AllocationAttributes & SEC_IMAGE)
                {
                   PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
                   ImageSectionObject = Section->ImageSection;
 
-                  Sii->TransferAddress = (PVOID)ImageSectionObject->EntryPoint;
-                  Sii->MaximumStackSize = ImageSectionObject->StackReserve;
-                  Sii->CommittedStackSize = ImageSectionObject->StackCommit;
-                  Sii->SubSystemType = ImageSectionObject->Subsystem;
-                  Sii->SubSystemMinorVersion = ImageSectionObject->MinorSubsystemVersion;
-                  Sii->SubSystemMajorVersion = ImageSectionObject->MajorSubsystemVersion;
-                  Sii->ImageCharacteristics = ImageSectionObject->ImageCharacteristics;
-                  Sii->Machine = ImageSectionObject->Machine;
-                  Sii->ImageContainsCode = ImageSectionObject->Executable;
+                  *Sii = ImageSectionObject->ImageInformation;
                }
 
                if (ResultLength != NULL)
@@ -4350,78 +4346,6 @@ NtQuerySection(IN HANDLE SectionHandle,
    return(Status);
 }
 
-
-/**
- * Extends size of file backed section.
- *
- * @param SectionHandle
- *        Handle to the section object. It must be opened with
- *        SECTION_EXTEND_SIZE access.
- * @param NewMaximumSize
- *        New maximum size of the section in bytes.
- *
- * @return Status.
- *
- * @todo Move the actual code to internal function MmExtendSection.
- * @unimplemented
- */
-NTSTATUS NTAPI
-NtExtendSection(IN HANDLE SectionHandle,
-                IN PLARGE_INTEGER NewMaximumSize)
-{
-   LARGE_INTEGER SafeNewMaximumSize;
-   PROS_SECTION_OBJECT Section;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode != KernelMode)
-   {
-     _SEH2_TRY
-     {
-       /* make a copy on the stack */
-       SafeNewMaximumSize = ProbeForReadLargeInteger(NewMaximumSize);
-       NewMaximumSize = &SafeNewMaximumSize;
-     }
-     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-     {
-        /* Return the exception code */
-        _SEH2_YIELD(return _SEH2_GetExceptionCode());
-     }
-     _SEH2_END;
-   }
-
-   Status = ObReferenceObjectByHandle(SectionHandle,
-                                      SECTION_EXTEND_SIZE,
-                                      MmSectionObjectType,
-                                      PreviousMode,
-                                      (PVOID*)&Section,
-                                      NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      return Status;
-   }
-
-   if (!(Section->AllocationAttributes & SEC_FILE))
-   {
-      ObDereferenceObject(Section);
-      return STATUS_INVALID_PARAMETER;
-   }
-
-   /*
-    * - Acquire file extneding resource.
-    * - Check if we're not resizing the section below it's actual size!
-    * - Extend segments if needed.
-    * - Set file information (FileAllocationInformation) to the new size.
-    * - Release file extending resource.
-    */
-
-   ObDereferenceObject(Section);
-
-   return STATUS_NOT_IMPLEMENTED;
-}
-
 /**********************************************************************
  * NAME       EXPORTED
  * MmMapViewOfSection
@@ -4487,6 +4411,22 @@ MmMapViewOfSection(IN PVOID SectionObject,
    PMMSUPPORT AddressSpace;
    ULONG ViewOffset;
    NTSTATUS Status = STATUS_SUCCESS;
+   BOOLEAN NotAtBase = FALSE;
+
+   if (MiIsRosSectionObject(SectionObject) == FALSE)
+   {
+       DPRINT("Mapping ARM3 section into %s\n", Process->ImageFileName);
+       return MmMapViewOfArm3Section(SectionObject,
+                                     Process,
+                                     BaseAddress,
+                                     ZeroBits,
+                                     CommitSize,
+                                     SectionOffset,
+                                     ViewSize,
+                                     InheritDisposition,
+                                     AllocationType,
+                                     Protect);
+   }
 
    ASSERT(Process);
 
@@ -4508,7 +4448,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
       ULONG i;
       ULONG NrSegments;
       ULONG_PTR ImageBase;
-      ULONG ImageSize;
+      SIZE_T ImageSize;
       PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
       PMM_SECTION_SEGMENT SectionSegments;
 
@@ -4516,26 +4456,41 @@ MmMapViewOfSection(IN PVOID SectionObject,
       SectionSegments = ImageSectionObject->Segments;
       NrSegments = ImageSectionObject->NrSegments;
 
-
       ImageBase = (ULONG_PTR)*BaseAddress;
       if (ImageBase == 0)
       {
-         ImageBase = ImageSectionObject->ImageBase;
+          ImageBase = (ULONG_PTR)ImageSectionObject->BasedAddress;
       }
 
       ImageSize = 0;
       for (i = 0; i < NrSegments; i++)
       {
-         if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+         if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
          {
             ULONG_PTR MaxExtent;
-            MaxExtent = (ULONG_PTR)SectionSegments[i].VirtualAddress +
-                        SectionSegments[i].Length;
+            MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
+                        SectionSegments[i].Length.QuadPart);
             ImageSize = max(ImageSize, MaxExtent);
          }
       }
 
-      ImageSectionObject->ImageSize = ImageSize;
+      ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize;
+
+      /* Check for an illegal base address */
+      if (((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress) ||
+          ((ImageBase + ImageSize) < ImageSize))
+      {
+         NT_ASSERT(*BaseAddress == NULL);
+         ImageBase = ALIGN_DOWN_BY((ULONG_PTR)MmHighestUserAddress - ImageSize,
+                                   MM_VIRTMEM_GRANULARITY);
+         NotAtBase = TRUE;
+      }
+      else if (ImageBase != ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY))
+      {
+         NT_ASSERT(*BaseAddress == NULL);
+         ImageBase = ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY);
+         NotAtBase = TRUE;
+      }
 
       /* Check there is enough space to map the section at that point. */
       if (MmLocateMemoryAreaByRegion(AddressSpace, (PVOID)ImageBase,
@@ -4545,29 +4500,31 @@ MmMapViewOfSection(IN PVOID SectionObject,
          if ((*BaseAddress) != NULL)
          {
             MmUnlockAddressSpace(AddressSpace);
-            return(STATUS_UNSUCCESSFUL);
+            return(STATUS_CONFLICTING_ADDRESSES);
          }
          /* Otherwise find a gap to map the image. */
-         ImageBase = (ULONG_PTR)MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), PAGE_SIZE, FALSE);
+         ImageBase = (ULONG_PTR)MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), MM_VIRTMEM_GRANULARITY, FALSE);
          if (ImageBase == 0)
          {
             MmUnlockAddressSpace(AddressSpace);
-            return(STATUS_UNSUCCESSFUL);
+            return(STATUS_CONFLICTING_ADDRESSES);
          }
+         /* Remember that we loaded image at a different base address */
+         NotAtBase = TRUE;
       }
 
       for (i = 0; i < NrSegments; i++)
       {
-         if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+         if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
          {
             PVOID SBaseAddress = (PVOID)
-                                 ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress);
+                                 ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
             MmLockSectionSegment(&SectionSegments[i]);
             Status = MmMapViewOfSegment(AddressSpace,
                                         Section,
                                         &SectionSegments[i],
                                         &SBaseAddress,
-                                        SectionSegments[i].Length,
+                                        SectionSegments[i].Length.LowPart,
                                         SectionSegments[i].Protection,
                                         0,
                                         0);
@@ -4581,6 +4538,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
       }
 
       *BaseAddress = (PVOID)ImageBase;
+      *ViewSize = ImageSize;
    }
    else
    {
@@ -4657,8 +4615,14 @@ MmMapViewOfSection(IN PVOID SectionObject,
    }
 
    MmUnlockAddressSpace(AddressSpace);
+   NT_ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
 
-   return(STATUS_SUCCESS);
+   if (NotAtBase)
+       Status = STATUS_IMAGE_NOT_AT_BASE;
+   else
+       Status = STATUS_SUCCESS;
+
+   return Status;
 }
 
 /*
@@ -4684,6 +4648,29 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
 
       if (Segment->ReferenceCount != 0)
       {
+#ifdef NEWCC
+         CC_FILE_SIZES FileSizes;
+         CcpLock();
+         if (SectionObjectPointer->SharedCacheMap && (Segment->ReferenceCount > CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap)))
+         {
+            CcpUnlock();
+            /* Check size of file */
+            if (SectionObjectPointer->SharedCacheMap)
+            {
+               if (!CcGetFileSizes(Segment->FileObject, &FileSizes))
+               {
+                  return FALSE;
+               }
+
+               if (NewFileSize->QuadPart <= FileSizes.FileSize.QuadPart)
+               {
+                  return FALSE;
+               }
+            }
+         }
+         else
+            CcpUnlock();
+#else
           /* Check size of file */
           if (SectionObjectPointer->SharedCacheMap)
           {
@@ -4693,11 +4680,12 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
                 return FALSE;
              }
           }
+#endif
       }
       else
       {
          /* Something must gone wrong
-          * how can we have a Section but no 
+          * how can we have a Section but no
           * reference? */
          DPRINT("ERROR: DataSectionObject without reference!\n");
       }
@@ -4709,15 +4697,7 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
 }
 
 
-/*
- * @unimplemented
- */
-BOOLEAN NTAPI
-MmDisableModifiedWriteOfSection (ULONG Unknown0)
-{
-   UNIMPLEMENTED;
-   return (FALSE);
-}
+
 
 /*
  * @implemented
@@ -4726,6 +4706,11 @@ BOOLEAN NTAPI
 MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
                      IN MMFLUSH_TYPE   FlushType)
 {
+   BOOLEAN Result = TRUE;
+#ifdef NEWCC
+   PMM_SECTION_SEGMENT Segment;
+#endif
+
    switch(FlushType)
    {
       case MmFlushForDelete:
@@ -4734,27 +4719,34 @@ MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
          {
             return FALSE;
          }
+#ifndef NEWCC
          CcRosSetRemoveOnClose(SectionObjectPointer);
+#endif
          return TRUE;
       case MmFlushForWrite:
-         break;
+      {
+         DPRINT("MmFlushImageSection(%d)\n", FlushType);
+#ifdef NEWCC
+         Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer->DataSectionObject;
+#endif
+
+         if (SectionObjectPointer->ImageSectionObject) {
+            DPRINT1("SectionObject has ImageSection\n");
+            return FALSE;
+         }
+
+#ifdef NEWCC
+         CcpLock();
+         Result = !SectionObjectPointer->SharedCacheMap || (Segment->ReferenceCount == CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap));
+         CcpUnlock();
+         DPRINT("Result %d\n", Result);
+#endif
+         return Result;
+      }
    }
    return FALSE;
 }
 
-/*
- * @unimplemented
- */
-BOOLEAN NTAPI
-MmForceSectionClosed (
-    IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
-    IN BOOLEAN                  DelayClose)
-{
-   UNIMPLEMENTED;
-   return (FALSE);
-}
-
-
 /*
  * @implemented
  */
@@ -4766,6 +4758,15 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
    PROS_SECTION_OBJECT Section;
    PMMSUPPORT AddressSpace;
    NTSTATUS Status;
+   PAGED_CODE();
+
+    if (MiIsRosSectionObject(SectionObject) == FALSE)
+    {
+        return MiMapViewInSystemSpace(SectionObject,
+                                      &MmSession,
+                                      MappedBase,
+                                      ViewSize);
+    }
 
    DPRINT("MmMapViewInSystemSpace() called\n");
 
@@ -4802,27 +4803,9 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
    return Status;
 }
 
-/*
- * @unimplemented
- */
 NTSTATUS
 NTAPI
-MmMapViewInSessionSpace (
-    IN PVOID Section,
-    OUT PVOID *MappedBase,
-    IN OUT PSIZE_T ViewSize
-    )
-{
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-MmUnmapViewInSystemSpace (IN PVOID MappedBase)
+MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
 {
    PMMSUPPORT AddressSpace;
    NTSTATUS Status;
@@ -4831,22 +4814,13 @@ MmUnmapViewInSystemSpace (IN PVOID MappedBase)
 
    AddressSpace = MmGetKernelAddressSpace();
 
+   MmLockAddressSpace(AddressSpace);
+
    Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
 
-   return Status;
-}
+   MmUnlockAddressSpace(AddressSpace);
 
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-MmUnmapViewInSessionSpace (
-    IN PVOID MappedBase
-    )
-{
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+   return Status;
 }
 
 /**********************************************************************
@@ -4912,64 +4886,155 @@ MmCreateSection (OUT PVOID  * Section,
                  IN ULONG   SectionPageProtection,
                  IN ULONG   AllocationAttributes,
                  IN HANDLE   FileHandle   OPTIONAL,
-                 IN PFILE_OBJECT  File      OPTIONAL)
+                 IN PFILE_OBJECT  FileObject  OPTIONAL)
 {
-   ULONG Protection;
-   PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
+    NTSTATUS Status;
+    ULONG Protection;
+    PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
 
-   /*
-    * Check the protection
-    */
-   Protection = SectionPageProtection & ~(PAGE_GUARD|PAGE_NOCACHE);
-   if (Protection != PAGE_READONLY &&
-       Protection != PAGE_READWRITE &&
-       Protection != PAGE_WRITECOPY &&
-       Protection != PAGE_EXECUTE &&
-       Protection != PAGE_EXECUTE_READ &&
-       Protection != PAGE_EXECUTE_READWRITE &&
-       Protection != PAGE_EXECUTE_WRITECOPY)
-   {
-     return STATUS_INVALID_PAGE_PROTECTION;
-   }
-
-   if (AllocationAttributes & SEC_IMAGE)
-   {
-      return(MmCreateImageSection(SectionObject,
-                                  DesiredAccess,
-                                  ObjectAttributes,
-                                  MaximumSize,
-                                  SectionPageProtection,
-                                  AllocationAttributes,
-                                  FileHandle));
-   }
-
-   if (FileHandle != NULL)
-   {
-      return(MmCreateDataFileSection(SectionObject,
-                                     DesiredAccess,
-                                     ObjectAttributes,
-                                     MaximumSize,
-                                     SectionPageProtection,
-                                     AllocationAttributes,
-                                     FileHandle));
-   }
-
-   return(MmCreatePageFileSection(SectionObject,
-                                  DesiredAccess,
-                                  ObjectAttributes,
-                                  MaximumSize,
-                                  SectionPageProtection,
-                                  AllocationAttributes));
-}
+    /* Check if an ARM3 section is being created instead */
+    if (!(AllocationAttributes & (SEC_IMAGE | SEC_PHYSICALMEMORY)))
+    {
+        if (!(FileObject) && !(FileHandle))
+        {
+            return MmCreateArm3Section(Section,
+                                       DesiredAccess,
+                                       ObjectAttributes,
+                                       MaximumSize,
+                                       SectionPageProtection,
+                                       AllocationAttributes &~ 1,
+                                       FileHandle,
+                                       FileObject);
+        }
+    }
 
-NTSTATUS
-NTAPI
-NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage,
-                        IN PVOID File2MappedAsFile)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+    /* Convert section flag to page flag */
+    if (AllocationAttributes & SEC_NOCACHE) SectionPageProtection |= PAGE_NOCACHE;
+
+    /* Check to make sure the protection is correct. Nt* does this already */
+    Protection = MiMakeProtectionMask(SectionPageProtection);
+    if (Protection == MM_INVALID_PROTECTION)
+    {
+        DPRINT1("Page protection is invalid\n");
+        return STATUS_INVALID_PAGE_PROTECTION;
+    }
+
+    /* Check if this is going to be a data or image backed file section */
+    if ((FileHandle) || (FileObject))
+    {
+        /* These cannot be mapped with large pages */
+        if (AllocationAttributes & SEC_LARGE_PAGES)
+        {
+            DPRINT1("Large pages cannot be used with an image mapping\n");
+            return STATUS_INVALID_PARAMETER_6;
+        }
+
+        /* Did the caller pass an object? */
+        if (FileObject)
+        {
+            /* Reference the object directly */
+            ObReferenceObject(FileObject);
+        }
+        else
+        {
+            /* Reference the file handle to get the object */
+            Status = ObReferenceObjectByHandle(FileHandle,
+                                               MmMakeFileAccess[Protection],
+                                               IoFileObjectType,
+                                               ExGetPreviousMode(),
+                                               (PVOID*)&FileObject,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
+                return Status;
+            }
+        }
+    }
+    else
+    {
+        /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
+        if (AllocationAttributes & SEC_IMAGE) return STATUS_INVALID_FILE_FOR_SECTION;
+    }
+
+#ifndef NEWCC // A hack for initializing caching.
+    // This is needed only in the old case.
+    if (FileHandle)
+    {
+        IO_STATUS_BLOCK Iosb;
+        NTSTATUS Status;
+        CHAR Buffer;
+        LARGE_INTEGER ByteOffset;
+        ByteOffset.QuadPart = 0;
+        Status = ZwReadFile(FileHandle,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &Iosb,
+                            &Buffer,
+                            sizeof(Buffer),
+                            &ByteOffset,
+                            NULL);
+        if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
+        {
+            DPRINT1("CC failure: %lx\n", Status);
+            return Status;
+        }
+        // Caching is initialized...
+    }
+#endif
+
+    if (AllocationAttributes & SEC_IMAGE)
+    {
+        Status = MmCreateImageSection(SectionObject,
+                                      DesiredAccess,
+                                      ObjectAttributes,
+                                      MaximumSize,
+                                      SectionPageProtection,
+                                      AllocationAttributes,
+                                      FileObject);
+    }
+#ifndef NEWCC
+    else if (FileHandle != NULL)
+    {
+        Status =  MmCreateDataFileSection(SectionObject,
+                                          DesiredAccess,
+                                          ObjectAttributes,
+                                          MaximumSize,
+                                          SectionPageProtection,
+                                          AllocationAttributes,
+                                          FileHandle);
+        if (FileObject)
+            ObDereferenceObject(FileObject);
+    }
+#else
+    else if (FileHandle != NULL || FileObject != NULL)
+    {
+        Status = MmCreateCacheSection(SectionObject,
+                                      DesiredAccess,
+                                      ObjectAttributes,
+                                      MaximumSize,
+                                      SectionPageProtection,
+                                      AllocationAttributes,
+                                      FileObject);
+    }
+#endif
+    else
+    {
+        if ((AllocationAttributes & SEC_PHYSICALMEMORY) == 0)
+        {
+            DPRINT1("Invalid path: %lx %p %p\n", AllocationAttributes, FileObject, FileHandle);
+        }
+//        ASSERT(AllocationAttributes & SEC_PHYSICALMEMORY);
+        Status = MmCreatePageFileSection(SectionObject,
+                                         DesiredAccess,
+                                         ObjectAttributes,
+                                         MaximumSize,
+                                         SectionPageProtection,
+                                         AllocationAttributes);
+    }
 
+    return Status;
+}
 
 /* EOF */