[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / section.c
index acde62a..80f193b 100644 (file)
@@ -45,8 +45,8 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
-#include "../cache/newcc.h"
-#include "../cache/section/newmm.h"
+#include <cache/newcc.h>
+#include <cache/section/newmm.h>
 #define NDEBUG
 #include <debug.h>
 #include <reactos/exeformat.h>
@@ -69,20 +69,20 @@ extern MMSESSION MmSession;
 NTSTATUS
 NTAPI
 MiMapViewInSystemSpace(IN PVOID Section,
-IN PVOID Session,
-OUT PVOID *MappedBase,
-IN OUT PSIZE_T ViewSize);
+                       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);
+                    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
@@ -121,13 +121,13 @@ C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Si
 
 typedef struct
 {
-   PROS_SECTION_OBJECT Section;
-   PMM_SECTION_SEGMENT Segment;
-   LARGE_INTEGER Offset;
-   BOOLEAN WasDirty;
-   BOOLEAN Private;
-   PEPROCESS CallingProcess;
-   ULONG_PTR SectionEntry;
+    PROS_SECTION_OBJECT Section;
+    PMM_SECTION_SEGMENT Segment;
+    LARGE_INTEGER Offset;
+    BOOLEAN WasDirty;
+    BOOLEAN Private;
+    PEPROCESS CallingProcess;
+    ULONG_PTR SectionEntry;
 }
 MM_SECTION_PAGEOUT_CONTEXT;
 
@@ -163,18 +163,15 @@ static ULONG SectionCharacteristicsToProtect[16] =
 
 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};
-
-static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
+static GENERIC_MAPPING MmpSectionMapping =
 {
-  ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */
-  ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionImageInformation */
+    STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY,
+    STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE,
+    STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE,
+    SECTION_ALL_ACCESS
 };
 
+
 /* FUNCTIONS *****************************************************************/
 
 
@@ -211,6 +208,7 @@ NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
     SIZE_T nPrevVirtualEndOfSegment = 0;
     ULONG nFileSizeOfHeaders = 0;
     ULONG i;
+    ULONG AlignedLength;
 
     ASSERT(FileHeader);
     ASSERT(FileHeaderSize > 0);
@@ -239,13 +237,13 @@ NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
     if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
         DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
 
+    /* NT HEADER */
+    nStatus = STATUS_INVALID_IMAGE_PROTECT;
+
     /* 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));
 
@@ -266,7 +264,7 @@ NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
      * need to read the header from the file
      */
     if(FileHeaderSize < cbFileHeaderOffsetSize ||
-       (UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
+            (UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
     {
         ULONG cbNtHeaderSize;
         ULONG cbReadSize;
@@ -280,7 +278,14 @@ l_ReadHeaderFromFile:
         nStatus = ReadFileCb(File, &lnOffset, sizeof(IMAGE_NT_HEADERS64), &pData, &pBuffer, &cbReadSize);
 
         if(!NT_SUCCESS(nStatus))
-            DIE(("ReadFile failed, status %08X\n", nStatus));
+        {
+            NTSTATUS ReturnedStatus = nStatus;
+
+            /* If it attempted to read past the end of the file, it means e_lfanew is invalid */
+            if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_INVALID_IMAGE_PROTECT;
+
+            DIE(("ReadFile failed, status %08X\n", ReturnedStatus));
+        }
 
         ASSERT(pData);
         ASSERT(pBuffer);
@@ -321,7 +326,7 @@ l_ReadHeaderFromFile:
     {
         ULONG cbOptHeaderOffsetSize = 0;
 
-        nStatus = STATUS_INVALID_IMAGE_FORMAT;
+        nStatus = STATUS_INVALID_IMAGE_PROTECT;
 
         /* don't trust an invalid NT header */
         if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
@@ -330,6 +335,8 @@ l_ReadHeaderFromFile:
         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));
 
+        nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
         if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
             DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
 
@@ -351,16 +358,18 @@ l_ReadHeaderFromFile:
 
     switch(piohOptHeader->Magic)
     {
-        case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
-        case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
-            break;
+    case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+#ifdef _WIN64
+    case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+#endif // _WIN64
+        break;
 
-        default:
-            DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
+    default:
+        DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
     }
 
     if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SectionAlignment) &&
-        RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, FileAlignment))
+            RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, FileAlignment))
     {
         /* See [1], section 3.4.2 */
         if(piohOptHeader->SectionAlignment < PAGE_SIZE)
@@ -388,153 +397,153 @@ l_ReadHeaderFromFile:
 
     switch(piohOptHeader->Magic)
     {
-        /* PE32 */
-        case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
-        {
-            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase))
-                ImageBase = piohOptHeader->ImageBase;
+    /* PE32 */
+    case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+    {
+        if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase))
+            ImageBase = piohOptHeader->ImageBase;
 
-            if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage))
-                ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->SizeOfImage;
+        if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage))
+            ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->SizeOfImage;
 
-            if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve))
-                ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->SizeOfStackReserve;
+        if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve))
+            ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->SizeOfStackReserve;
 
-            if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit))
-                ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->SizeOfStackCommit;
+        if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit))
+            ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->SizeOfStackCommit;
 
-            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem))
-            {
-                ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->Subsystem;
+        if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem))
+        {
+            ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->Subsystem;
 
-                if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
+            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
                     RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MajorSubsystemVersion))
-                {
-                    ImageSectionObject->ImageInformation.SubSystemMinorVersion = piohOptHeader->MinorSubsystemVersion;
-                    ImageSectionObject->ImageInformation.SubSystemMajorVersion = piohOptHeader->MajorSubsystemVersion;
-                }
+            {
+                ImageSectionObject->ImageInformation.SubSystemMinorVersion = piohOptHeader->MinorSubsystemVersion;
+                ImageSectionObject->ImageInformation.SubSystemMajorVersion = piohOptHeader->MajorSubsystemVersion;
             }
+        }
 
-            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
-            {
-                ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase +
+        if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+        {
+            ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase +
                     piohOptHeader->AddressOfEntryPoint);
-            }
+        }
 
-            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode))
-                ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->SizeOfCode != 0;
-            else
-                ImageSectionObject->ImageInformation.ImageContainsCode = TRUE;
+        if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode))
+            ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->SizeOfCode != 0;
+        else
+            ImageSectionObject->ImageInformation.ImageContainsCode = TRUE;
 
-            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+        if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+        {
+            if (piohOptHeader->AddressOfEntryPoint == 0)
             {
-                if (piohOptHeader->AddressOfEntryPoint == 0)
-                {
-                    ImageSectionObject->ImageInformation.ImageContainsCode = FALSE;
-                }
+                ImageSectionObject->ImageInformation.ImageContainsCode = FALSE;
             }
+        }
 
-            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, LoaderFlags))
-                ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->LoaderFlags;
-
-            if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, DllCharacteristics))
-            {
-                ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->DllCharacteristics;
+        if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, LoaderFlags))
+            ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->LoaderFlags;
 
-                /*
-                 * 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;
-            }
+        if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, DllCharacteristics))
+        {
+            ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->DllCharacteristics;
 
-            break;
+            /*
+             * 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;
         }
+
+        break;
+    }
 #ifdef _WIN64
-        /* PE64 */
-        case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
-        {
-            const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader;
+    /* PE64 */
+    case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+    {
+        const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader;
 
-            pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader;
+        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, 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"));
+        if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfImage))
+        {
+            if(pioh64OptHeader->SizeOfImage > MAXULONG_PTR)
+                DIE(("SizeOfImage exceeds the address space\n"));
 
-                ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->SizeOfImage;
-            }
+            ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->SizeOfImage;
+        }
 
-            if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackReserve))
-            {
-                if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR)
-                    DIE(("SizeOfStackReserve exceeds the address space\n"));
+        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;
-            }
+            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"));
+        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;
-            }
+            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, Subsystem))
+        {
+            ImageSectionObject->ImageInformation.SubSystemType = pioh64OptHeader->Subsystem;
 
-                if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
+            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
                     RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MajorSubsystemVersion))
-                {
-                    ImageSectionObject->ImageInformation.SubSystemMinorVersion = pioh64OptHeader->MinorSubsystemVersion;
-                    ImageSectionObject->ImageInformation.SubSystemMajorVersion = pioh64OptHeader->MajorSubsystemVersion;
-                }
+            {
+                ImageSectionObject->ImageInformation.SubSystemMinorVersion = pioh64OptHeader->MinorSubsystemVersion;
+                ImageSectionObject->ImageInformation.SubSystemMajorVersion = pioh64OptHeader->MajorSubsystemVersion;
             }
+        }
 
-            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint))
-            {
-                ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase +
+        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;
+        if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfCode))
+            ImageSectionObject->ImageInformation.ImageContainsCode = pioh64OptHeader->SizeOfCode != 0;
+        else
+            ImageSectionObject->ImageInformation.ImageContainsCode = TRUE;
 
-            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+        if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+        {
+            if (pioh64OptHeader->AddressOfEntryPoint == 0)
             {
-                if (pioh64OptHeader->AddressOfEntryPoint == 0)
-                {
-                    ImageSectionObject->ImageInformation.ImageContainsCode = FALSE;
-                }
+                ImageSectionObject->ImageInformation.ImageContainsCode = FALSE;
             }
+        }
 
-            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, LoaderFlags))
-                ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->LoaderFlags;
+        if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, LoaderFlags))
+            ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->LoaderFlags;
 
-            if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, DllCharacteristics))
-                ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->DllCharacteristics;
+        if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, DllCharacteristics))
+            ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->DllCharacteristics;
 
-            break;
-        }
+        break;
+    }
 #endif // _WIN64
     }
 
@@ -616,7 +625,7 @@ l_ReadHeaderFromFile:
      * read the headers from the file
      */
     if(FileHeaderSize < cbSectionHeadersOffsetSize ||
-       (UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
+            (UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
     {
         PVOID pData;
         ULONG cbReadSize;
@@ -747,11 +756,12 @@ l_ReadHeaderFromFile:
         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)
+        AlignedLength = ALIGN_UP_BY(pssSegments[i].Length.LowPart, nSectionAlignment);
+        if(AlignedLength < pssSegments[i].Length.LowPart)
             DIE(("Cannot align the virtual size of section %u\n", i));
 
+        pssSegments[i].Length.LowPart = AlignedLength;
+
         if(pssSegments[i].Length.QuadPart == 0)
             DIE(("Virtual size of section %u is null\n", i));
 
@@ -786,53 +796,53 @@ NTSTATUS
 MmspWaitForFileLock(PFILE_OBJECT File)
 {
     return STATUS_SUCCESS;
-   //return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL);
+    //return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL);
 }
 
 VOID
 NTAPI
 MmFreeSectionSegments(PFILE_OBJECT FileObject)
 {
-   if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
-   {
-      PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
-      PMM_SECTION_SEGMENT SectionSegments;
-      ULONG NrSegments;
-      ULONG i;
-
-      ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)FileObject->SectionObjectPointer->ImageSectionObject;
-      NrSegments = ImageSectionObject->NrSegments;
-      SectionSegments = ImageSectionObject->Segments;
-      for (i = 0; i < NrSegments; i++)
-      {
-         if (SectionSegments[i].ReferenceCount != 0)
-         {
-            DPRINT1("Image segment %lu still referenced (was %lu)\n", i,
-                    SectionSegments[i].ReferenceCount);
+    if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
+    {
+        PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
+        PMM_SECTION_SEGMENT SectionSegments;
+        ULONG NrSegments;
+        ULONG i;
+
+        ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)FileObject->SectionObjectPointer->ImageSectionObject;
+        NrSegments = ImageSectionObject->NrSegments;
+        SectionSegments = ImageSectionObject->Segments;
+        for (i = 0; i < NrSegments; i++)
+        {
+            if (SectionSegments[i].ReferenceCount != 0)
+            {
+                DPRINT1("Image segment %lu still referenced (was %lu)\n", i,
+                        SectionSegments[i].ReferenceCount);
+                KeBugCheck(MEMORY_MANAGEMENT);
+            }
+            MmFreePageTablesSectionSegment(&SectionSegments[i], NULL);
+        }
+        ExFreePool(ImageSectionObject->Segments);
+        ExFreePool(ImageSectionObject);
+        FileObject->SectionObjectPointer->ImageSectionObject = NULL;
+    }
+    if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
+    {
+        PMM_SECTION_SEGMENT Segment;
+
+        Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
+                  DataSectionObject;
+
+        if (Segment->ReferenceCount != 0)
+        {
+            DPRINT1("Data segment still referenced\n");
             KeBugCheck(MEMORY_MANAGEMENT);
-         }
-         MmFreePageTablesSectionSegment(&SectionSegments[i], NULL);
-      }
-      ExFreePool(ImageSectionObject->Segments);
-      ExFreePool(ImageSectionObject);
-      FileObject->SectionObjectPointer->ImageSectionObject = NULL;
-   }
-   if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
-   {
-      PMM_SECTION_SEGMENT Segment;
-
-      Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
-                DataSectionObject;
-
-      if (Segment->ReferenceCount != 0)
-      {
-         DPRINT1("Data segment still referenced\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      MmFreePageTablesSectionSegment(Segment, NULL);
-      ExFreePool(Segment);
-      FileObject->SectionObjectPointer->DataSectionObject = NULL;
-   }
+        }
+        MmFreePageTablesSectionSegment(Segment, NULL);
+        ExFreePool(Segment);
+        FileObject->SectionObjectPointer->DataSectionObject = NULL;
+    }
 }
 
 VOID
@@ -840,25 +850,25 @@ NTAPI
 MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
                                PLARGE_INTEGER Offset)
 {
-   ULONG_PTR Entry;
-
-   Entry = MmGetPageEntrySectionSegment(Segment, Offset);
-   if (Entry == 0)
-   {
-      DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-   if (SHARE_COUNT_FROM_SSE(Entry) == MAX_SHARE_COUNT)
-   {
-      DPRINT1("Maximum share count reached\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-   if (IS_SWAP_FROM_SSE(Entry))
-   {
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-   Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) + 1);
-   MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+    ULONG_PTR Entry;
+
+    Entry = MmGetPageEntrySectionSegment(Segment, Offset);
+    if (Entry == 0)
+    {
+        DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n");
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+    if (SHARE_COUNT_FROM_SSE(Entry) == MAX_SHARE_COUNT)
+    {
+        DPRINT1("Maximum share count reached\n");
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+    if (IS_SWAP_FROM_SSE(Entry))
+    {
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+    Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) + 1);
+    MmSetPageEntrySectionSegment(Segment, Offset, Entry);
 }
 
 BOOLEAN
@@ -870,163 +880,162 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
                                  BOOLEAN PageOut,
                                  ULONG_PTR *InEntry)
 {
-   ULONG_PTR Entry = InEntry ? *InEntry : MmGetPageEntrySectionSegment(Segment, Offset);
-   BOOLEAN IsDirectMapped = FALSE;
-
-   if (Entry == 0)
-   {
-      DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-   if (SHARE_COUNT_FROM_SSE(Entry) == 0)
-   {
-       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))
-   {
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-   Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) - 1);
-   /*
-    * If we reducing the share count of this entry to zero then set the entry
-    * to zero and tell the cache the page is no longer mapped.
-    */
-   if (SHARE_COUNT_FROM_SSE(Entry) == 0)
-   {
-      PFILE_OBJECT FileObject;
-#ifndef NEWCC
-      PBCB Bcb;
-#endif
-      SWAPENTRY SavedSwapEntry;
-      PFN_NUMBER Page;
-      BOOLEAN IsImageSection;
-      LARGE_INTEGER FileOffset;
+    ULONG_PTR Entry = InEntry ? *InEntry : MmGetPageEntrySectionSegment(Segment, Offset);
+    BOOLEAN IsDirectMapped = FALSE;
 
-      FileOffset.QuadPart = Offset->QuadPart + Segment->Image.FileOffset;
+    if (Entry == 0)
+    {
+        DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n");
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+    if (SHARE_COUNT_FROM_SSE(Entry) == 0)
+    {
+        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))
+    {
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+    Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) - 1);
+    /*
+     * If we reducing the share count of this entry to zero then set the entry
+     * to zero and tell the cache the page is no longer mapped.
+     */
+    if (SHARE_COUNT_FROM_SSE(Entry) == 0)
+    {
+        PFILE_OBJECT FileObject;
+        SWAPENTRY SavedSwapEntry;
+        PFN_NUMBER Page;
+#ifndef NEWCC
+        PROS_SHARED_CACHE_MAP SharedCacheMap;
+        BOOLEAN IsImageSection;
+        LARGE_INTEGER FileOffset;
 
-      IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
+        FileOffset.QuadPart = Offset->QuadPart + Segment->Image.FileOffset;
+        IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
+#endif
 
-      Page = PFN_FROM_SSE(Entry);
-      FileObject = Section->FileObject;
-      if (FileObject != NULL &&
-            !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
-      {
+        Page = PFN_FROM_SSE(Entry);
+        FileObject = Section->FileObject;
+        if (FileObject != NULL &&
+                !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
+        {
 
 #ifndef NEWCC
-         if ((FileOffset.QuadPart % PAGE_SIZE) == 0 &&
-               (Offset->QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection))
-         {
-            NTSTATUS Status;
-            Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-            IsDirectMapped = TRUE;
+            if ((FileOffset.QuadPart % PAGE_SIZE) == 0 &&
+                    (Offset->QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection))
+            {
+                NTSTATUS Status;
+                SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
+                IsDirectMapped = TRUE;
 #ifndef NEWCC
-            Status = CcRosUnmapVacb(Bcb, FileOffset.LowPart, Dirty);
+                Status = CcRosUnmapVacb(SharedCacheMap, FileOffset.QuadPart, Dirty);
 #else
-            Status = STATUS_SUCCESS;
+                Status = STATUS_SUCCESS;
 #endif
-            if (!NT_SUCCESS(Status))
-            {
-               DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status);
-               KeBugCheck(MEMORY_MANAGEMENT);
+                if (!NT_SUCCESS(Status))
+                {
+                    DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status);
+                    KeBugCheck(MEMORY_MANAGEMENT);
+                }
             }
-         }
 #endif
-      }
-
-      SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
-      if (SavedSwapEntry == 0)
-      {
-         if (!PageOut &&
-               ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
-                (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)))
-         {
-            /*
-             * FIXME:
-             *   Try to page out this page and set the swap entry
-             *   within the section segment. There exist no rmap entry
-             *   for this page. The pager thread can't page out a
-             *   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)
+        }
+
+        SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
+        if (SavedSwapEntry == 0)
+        {
+            if (!PageOut &&
+                    ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
+                     (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)))
             {
-               MmReleasePageMemoryConsumer(MC_USER, Page);
+                /*
+                 * FIXME:
+                 *   Try to page out this page and set the swap entry
+                 *   within the section segment. There exist no rmap entry
+                 *   for this page. The pager thread can't page out a
+                 *   page without a rmap entry.
+                 */
+                MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+                if (InEntry) *InEntry = Entry;
+                MiSetPageEvent(NULL, NULL);
             }
-         }
-      }
-      else
-      {
-         if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
-               (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
-         {
-            if (!PageOut)
+            else
             {
-               if (Dirty)
-               {
-                  /*
-                   * FIXME:
-                   *   We hold all locks. Nobody can do something with the current
-                   *   process and the current segment (also not within an other process).
-                   */
-                  NTSTATUS Status;
-                  Status = MmWriteToSwapPage(SavedSwapEntry, Page);
-                  if (!NT_SUCCESS(Status))
-                  {
-                     DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status);
-                      KeBugCheck(MEMORY_MANAGEMENT);
-                  }
-               }
-               MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry));
-               if (InEntry) *InEntry = MAKE_SWAP_SSE(SavedSwapEntry);
-               MmSetSavedSwapEntryPage(Page, 0);
-               MiSetPageEvent(NULL, NULL);
+                MmSetPageEntrySectionSegment(Segment, Offset, 0);
+                if (InEntry) *InEntry = 0;
+                MiSetPageEvent(NULL, NULL);
+                if (!IsDirectMapped)
+                {
+                    MmReleasePageMemoryConsumer(MC_USER, Page);
+                }
             }
-            MmReleasePageMemoryConsumer(MC_USER, Page);
-         }
-         else
-         {
-            DPRINT1("Found a swapentry for a non private page in an image or data file sgment\n");
-            KeBugCheck(MEMORY_MANAGEMENT);
-         }
-      }
-   }
-   else
-   {
-      if (InEntry)
-          *InEntry = Entry;
-      else
-          MmSetPageEntrySectionSegment(Segment, Offset, Entry);
-   }
-   return(SHARE_COUNT_FROM_SSE(Entry) > 0);
+        }
+        else
+        {
+            if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
+                    (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
+            {
+                if (!PageOut)
+                {
+                    if (Dirty)
+                    {
+                        /*
+                         * FIXME:
+                         *   We hold all locks. Nobody can do something with the current
+                         *   process and the current segment (also not within an other process).
+                         */
+                        NTSTATUS Status;
+                        Status = MmWriteToSwapPage(SavedSwapEntry, Page);
+                        if (!NT_SUCCESS(Status))
+                        {
+                            DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status);
+                            KeBugCheck(MEMORY_MANAGEMENT);
+                        }
+                    }
+                    MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry));
+                    if (InEntry) *InEntry = MAKE_SWAP_SSE(SavedSwapEntry);
+                    MmSetSavedSwapEntryPage(Page, 0);
+                    MiSetPageEvent(NULL, NULL);
+                }
+                MmReleasePageMemoryConsumer(MC_USER, Page);
+            }
+            else
+            {
+                DPRINT1("Found a swapentry for a non private page in an image or data file sgment\n");
+                KeBugCheck(MEMORY_MANAGEMENT);
+            }
+        }
+    }
+    else
+    {
+        if (InEntry)
+            *InEntry = Entry;
+        else
+            MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+    }
+    return(SHARE_COUNT_FROM_SSE(Entry) > 0);
 }
 
 BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
-                       ULONG SegOffset)
+                          LONGLONG SegOffset)
 {
 #ifndef NEWCC
-   if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
-   {
-      PBCB Bcb;
-      PROS_VACB Vacb;
-      Bcb = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
-      Vacb = CcRosLookupVacb(Bcb, (ULONG)(SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset));
-      if (Vacb)
-      {
-         CcRosReleaseVacb(Bcb, Vacb, Vacb->Valid, FALSE, TRUE);
-         return TRUE;
-      }
-   }
+    if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
+    {
+        PROS_SHARED_CACHE_MAP SharedCacheMap;
+        PROS_VACB Vacb;
+        SharedCacheMap = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
+        Vacb = CcRosLookupVacb(SharedCacheMap, SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset);
+        if (Vacb)
+        {
+            CcRosReleaseVacb(SharedCacheMap, Vacb, Vacb->Valid, FALSE, TRUE);
+            return TRUE;
+        }
+    }
 #endif
-   return FALSE;
+    return FALSE;
 }
 
 NTSTATUS
@@ -1056,7 +1065,7 @@ MiCopyFromUserPage(PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
 NTSTATUS
 NTAPI
 MiReadPage(PMEMORY_AREA MemoryArea,
-           ULONG_PTR SegOffset,
+           LONGLONG SegOffset,
            PPFN_NUMBER Page)
 /*
  * FUNCTION: Read a page for a section backed memory area.
@@ -1066,149 +1075,108 @@ MiReadPage(PMEMORY_AREA MemoryArea,
  *       Page - Variable that receives a page contains the read data.
  */
 {
-   ULONG BaseOffset;
-   ULONGLONG FileOffset;
-   PVOID BaseAddress;
-   BOOLEAN UptoDate;
-   PROS_VACB Vacb;
-   PFILE_OBJECT FileObject;
-   NTSTATUS Status;
-   ULONG_PTR RawLength;
-   PBCB Bcb;
-   BOOLEAN IsImageSection;
-   ULONG_PTR Length;
-
-   FileObject = MemoryArea->Data.SectionData.Section->FileObject;
-   Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-   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 %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 VACB.
-    */
-   if (((FileOffset % PAGE_SIZE) == 0) &&
-       ((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) &&
-       !(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
-   {
-
-      /*
-       * Get the related VACB; we use a lower level interface than
-       * filesystems do because it is safe for us to use an offset with an
-       * alignment less than the file system block size.
-       */
-      Status = CcRosGetVacb(Bcb,
-                            (ULONG)FileOffset,
-                            &BaseOffset,
-                            &BaseAddress,
-                            &UptoDate,
-                            &Vacb);
-      if (!NT_SUCCESS(Status))
-      {
-         return(Status);
-      }
-      if (!UptoDate)
-      {
-         /*
-          * If the VACB isn't up to date then call the file
-          * system to read in the data.
-          */
-         Status = CcReadVirtualAddress(Vacb);
-         if (!NT_SUCCESS(Status))
-         {
-            CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
-            return Status;
-         }
-      }
-
-      /* Probe the page, since it's PDE might not be synced */
-      (void)*((volatile char*)BaseAddress + FileOffset - BaseOffset);
-
-      /*
-       * Retrieve the page from the view that we actually want.
-       */
-      (*Page) = MmGetPhysicalAddress((char*)BaseAddress +
-                                     FileOffset - BaseOffset).LowPart >> PAGE_SHIFT;
-
-      CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, TRUE);
-   }
-   else
-   {
-      PEPROCESS Process;
-      KIRQL Irql;
-      PVOID PageAddr;
-      ULONG_PTR VacbOffset;
-
-      /*
-       * 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 = CcRosGetVacb(Bcb,
-                            (ULONG)FileOffset,
-                            &BaseOffset,
-                            &BaseAddress,
-                            &UptoDate,
-                            &Vacb);
-      if (!NT_SUCCESS(Status))
-      {
-         return(Status);
-      }
-      if (!UptoDate)
-      {
-         /*
-          * If the VACB isn't up to date then call the file
-          * system to read in the data.
-          */
-         Status = CcReadVirtualAddress(Vacb);
-         if (!NT_SUCCESS(Status))
-         {
-            CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
-            return Status;
-         }
-      }
-
-      Process = PsGetCurrentProcess();
-      PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
-      VacbOffset = (ULONG_PTR)(BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset);
-      Length = RawLength - SegOffset;
-      if (Length <= VacbOffset && Length <= PAGE_SIZE)
-      {
-         memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, Length);
-      }
-      else if (VacbOffset >= PAGE_SIZE)
-      {
-         memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, PAGE_SIZE);
-      }
-      else
-      {
-         memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, VacbOffset);
-         MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
-         CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
-         Status = CcRosGetVacb(Bcb,
-                               (ULONG)(FileOffset + VacbOffset),
-                               &BaseOffset,
-                               &BaseAddress,
-                               &UptoDate,
-                               &Vacb);
-         if (!NT_SUCCESS(Status))
-         {
+    LONGLONG BaseOffset;
+    LONGLONG FileOffset;
+    PVOID BaseAddress;
+    BOOLEAN UptoDate;
+    PROS_VACB Vacb;
+    PFILE_OBJECT FileObject;
+    NTSTATUS Status;
+    LONGLONG RawLength;
+    PROS_SHARED_CACHE_MAP SharedCacheMap;
+    BOOLEAN IsImageSection;
+    LONGLONG Length;
+
+    FileObject = MemoryArea->Data.SectionData.Section->FileObject;
+    SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
+    RawLength = 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(SharedCacheMap);
+
+    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 VACB.
+     */
+    if (((FileOffset % PAGE_SIZE) == 0) &&
+            ((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) &&
+            !(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
+    {
+
+        /*
+         * Get the related VACB; we use a lower level interface than
+         * filesystems do because it is safe for us to use an offset with an
+         * alignment less than the file system block size.
+         */
+        Status = CcRosGetVacb(SharedCacheMap,
+                              FileOffset,
+                              &BaseOffset,
+                              &BaseAddress,
+                              &UptoDate,
+                              &Vacb);
+        if (!NT_SUCCESS(Status))
+        {
+            return(Status);
+        }
+        if (!UptoDate)
+        {
+            /*
+             * If the VACB isn't up to date then call the file
+             * system to read in the data.
+             */
+            Status = CcReadVirtualAddress(Vacb);
+            if (!NT_SUCCESS(Status))
+            {
+                CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                return Status;
+            }
+        }
+
+        /* Probe the page, since it's PDE might not be synced */
+        (void)*((volatile char*)BaseAddress + FileOffset - BaseOffset);
+
+        /*
+         * Retrieve the page from the view that we actually want.
+         */
+        (*Page) = MmGetPhysicalAddress((char*)BaseAddress +
+                                       FileOffset - BaseOffset).LowPart >> PAGE_SHIFT;
+
+        CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, TRUE);
+    }
+    else
+    {
+        PEPROCESS Process;
+        KIRQL Irql;
+        PVOID PageAddr;
+        LONGLONG VacbOffset;
+
+        /*
+         * 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 = CcRosGetVacb(SharedCacheMap,
+                              FileOffset,
+                              &BaseOffset,
+                              &BaseAddress,
+                              &UptoDate,
+                              &Vacb);
+        if (!NT_SUCCESS(Status))
+        {
             return(Status);
-         }
-         if (!UptoDate)
-         {
+        }
+        if (!UptoDate)
+        {
             /*
              * If the VACB isn't up to date then call the file
              * system to read in the data.
@@ -1216,30 +1184,71 @@ MiReadPage(PMEMORY_AREA MemoryArea,
             Status = CcReadVirtualAddress(Vacb);
             if (!NT_SUCCESS(Status))
             {
-               CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
-               return Status;
+                CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                return Status;
+            }
+        }
+
+        Process = PsGetCurrentProcess();
+        PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
+        VacbOffset = BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset;
+        Length = RawLength - SegOffset;
+        if (Length <= VacbOffset && Length <= PAGE_SIZE)
+        {
+            memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, Length);
+        }
+        else if (VacbOffset >= PAGE_SIZE)
+        {
+            memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, PAGE_SIZE);
+        }
+        else
+        {
+            memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, VacbOffset);
+            MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
+            CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
+            Status = CcRosGetVacb(SharedCacheMap,
+                                  FileOffset + VacbOffset,
+                                  &BaseOffset,
+                                  &BaseAddress,
+                                  &UptoDate,
+                                  &Vacb);
+            if (!NT_SUCCESS(Status))
+            {
+                return(Status);
+            }
+            if (!UptoDate)
+            {
+                /*
+                 * If the VACB isn't up to date then call the file
+                 * system to read in the data.
+                 */
+                Status = CcReadVirtualAddress(Vacb);
+                if (!NT_SUCCESS(Status))
+                {
+                    CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                    return Status;
+                }
+            }
+            PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
+            if (Length < PAGE_SIZE)
+            {
+                memcpy((char*)PageAddr + VacbOffset, BaseAddress, Length - VacbOffset);
+            }
+            else
+            {
+                memcpy((char*)PageAddr + VacbOffset, BaseAddress, PAGE_SIZE - VacbOffset);
             }
-         }
-         PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
-         if (Length < PAGE_SIZE)
-         {
-            memcpy((char*)PageAddr + VacbOffset, BaseAddress, Length - VacbOffset);
-         }
-         else
-         {
-            memcpy((char*)PageAddr + VacbOffset, BaseAddress, PAGE_SIZE - VacbOffset);
-         }
-      }
-      MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
-      CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
-   }
-   return(STATUS_SUCCESS);
+        }
+        MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
+        CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
+    }
+    return(STATUS_SUCCESS);
 }
 #else
 NTSTATUS
 NTAPI
 MiReadPage(PMEMORY_AREA MemoryArea,
-           ULONG_PTR SegOffset,
+           LONGLONG SegOffset,
            PPFN_NUMBER Page)
 /*
  * FUNCTION: Read a page for a section backed memory area.
@@ -1249,22 +1258,22 @@ MiReadPage(PMEMORY_AREA MemoryArea,
  *       Page - Variable that receives a page contains the read data.
  */
 {
-   MM_REQUIRED_RESOURCES Resources;
-   NTSTATUS Status;
+    MM_REQUIRED_RESOURCES Resources;
+    NTSTATUS Status;
 
-   RtlZeroMemory(&Resources, sizeof(MM_REQUIRED_RESOURCES));
+    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;
+    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]);
+    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;
+    Status = MiReadFilePage(MmGetKernelAddressSpace(), MemoryArea, &Resources);
+    *Page = Resources.Page[0];
+    return Status;
 }
 #endif
 
@@ -1275,585 +1284,576 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
                              PVOID Address,
                              BOOLEAN Locked)
 {
-   LARGE_INTEGER Offset;
-   PFN_NUMBER Page;
-   NTSTATUS Status;
-   PROS_SECTION_OBJECT Section;
-   PMM_SECTION_SEGMENT Segment;
-   ULONG_PTR Entry;
-   ULONG_PTR Entry1;
-   ULONG Attributes;
-   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
-    * that.
-    */
-   if (MmIsPagePresent(Process, Address))
-   {
-      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.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) &&
-       (Region->Protect == PAGE_READWRITE ||
-       Region->Protect == PAGE_EXECUTE_READWRITE))
-   {
-      Attributes = Region->Protect == PAGE_READWRITE ? PAGE_READONLY : PAGE_EXECUTE_READ;
-   }
-   else
-   {
-      Attributes = Region->Protect;
-   }
-
-   /*
-    * Check if someone else is already handling this fault, if so wait
-    * for them
-    */
-   if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
-   {
-      MmUnlockSectionSegment(Segment);
-      MmUnlockAddressSpace(AddressSpace);
-      MiWaitForPageEvent(NULL, NULL);
-      MmLockAddressSpace(AddressSpace);
-      DPRINT("Address 0x%p\n", Address);
-      return(STATUS_MM_RESTART_OPERATION);
-   }
-
-   HasSwapEntry = MmIsPageSwapEntry(Process, Address);
-
-   if (HasSwapEntry)
-   {
-      SWAPENTRY DummyEntry;
-
-      /*
-       * Is it a wait entry?
-       */
-      MmGetPageFileMapping(Process, Address, &SwapEntry);
-
-      if (SwapEntry == MM_WAIT_ENTRY)
-      {
-         MmUnlockSectionSegment(Segment);
-         MmUnlockAddressSpace(AddressSpace);
-         MiWaitForPageEvent(NULL, NULL);
-         MmLockAddressSpace(AddressSpace);
-         return STATUS_MM_RESTART_OPERATION;
-      }
-
-      /*
-       * Must be private page we have swapped out.
-       */
-
-      /*
-       * Sanity check
-       */
-      if (Segment->Flags & MM_PAGEFILE_SEGMENT)
-      {
-         DPRINT1("Found a swaped out private page in a pagefile section.\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-
-      MmUnlockSectionSegment(Segment);
-      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))
-      {
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-
-      Status = MmReadFromSwapPage(SwapEntry, Page);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      MmLockAddressSpace(AddressSpace);
-      MmDeletePageFileMapping(Process, PAddress, &DummyEntry);
-      Status = MmCreateVirtualMapping(Process,
-                                      PAddress,
-                                      Region->Protect,
-                                      &Page,
-                                      1);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-         return(Status);
-      }
-
-      /*
-       * Store the swap entry for later use.
-       */
-      MmSetSavedSwapEntryPage(Page, SwapEntry);
-
-      /*
-       * Add the page to the process's working set
-       */
-      MmInsertRmap(Page, Process, Address);
-      /*
-       * Finish the operation
-       */
-      MiSetPageEvent(Process, Address);
-      DPRINT("Address 0x%p\n", Address);
-      return(STATUS_SUCCESS);
-   }
-
-   /*
-    * Satisfying a page fault on a map of /Device/PhysicalMemory is easy
-    */
-   if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
-   {
-      MmUnlockSectionSegment(Segment);
-      /*
-       * Just map the desired physical page
-       */
-      Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT);
-      Status = MmCreateVirtualMappingUnsafe(Process,
-                                            PAddress,
-                                            Region->Protect,
-                                            &Page,
-                                            1);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-         return(Status);
-      }
-
-      /*
-       * Cleanup and release locks
-       */
-      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);
-
-   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.
-       */
-
-      /*
-       * 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.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, (ULONG_PTR)Offset.QuadPart, &Page);
-         if (!NT_SUCCESS(Status))
-         {
-            DPRINT1("MiReadPage failed (Status %x)\n", Status);
-         }
-      }
-      if (!NT_SUCCESS(Status))
-      {
-         /*
-          * FIXME: What do we know in this case?
-          */
-         /*
-          * Cleanup and release locks
-          */
-         MmLockAddressSpace(AddressSpace);
-         MiSetPageEvent(Process, Address);
-         DPRINT("Address 0x%p\n", Address);
-         return(Status);
-      }
-
-      /*
-       * 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);
-      MmUnlockSectionSegment(Segment);
-
-      MmDeletePageFileMapping(Process, PAddress, &FakeSwapEntry);
-      DPRINT("CreateVirtualMapping Page %x Process %p PAddress %p Attributes %x\n",
-              Page, Process, PAddress, Attributes);
-      Status = MmCreateVirtualMapping(Process,
-                                      PAddress,
-                                      Attributes,
-                                      &Page,
-                                      1);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT1("Unable to create virtual mapping\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      ASSERT(MmIsPagePresent(Process, PAddress));
-      MmInsertRmap(Page, Process, Address);
-
-      MiSetPageEvent(Process, Address);
-      DPRINT("Address 0x%p\n", Address);
-      return(STATUS_SUCCESS);
-   }
-   else if (IS_SWAP_FROM_SSE(Entry))
-   {
-      SWAPENTRY SwapEntry;
-
-      SwapEntry = SWAPENTRY_FROM_SSE(Entry);
-
-      /*
-      * Release all our locks and read in the page from disk
-      */
-      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))
-      {
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-
-      Status = MmReadFromSwapPage(SwapEntry, Page);
-      if (!NT_SUCCESS(Status))
-      {
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-
-      /*
-       * 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 (%x vs %x)\n", Entry, Entry1);
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-
-      /*
-       * Mark the offset within the section as having valid, in-memory
-       * data
-       */
-      Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
-      MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
-      MmUnlockSectionSegment(Segment);
-
-      /*
-       * Save the swap entry.
-       */
-      MmSetSavedSwapEntryPage(Page, SwapEntry);
-      Status = MmCreateVirtualMapping(Process,
-                                      PAddress,
-                                      Region->Protect,
-                                      &Page,
-                                      1);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT1("Unable to create virtual mapping\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      MmInsertRmap(Page, Process, Address);
-      MiSetPageEvent(Process, Address);
-      DPRINT("Address 0x%p\n", Address);
-      return(STATUS_SUCCESS);
-   }
-   else
-   {
-      /*
-       * If the section offset is already in-memory and valid then just
-       * take another reference to the page
-       */
-
-      Page = PFN_FROM_SSE(Entry);
-
-      MmSharePageEntrySectionSegment(Segment, &Offset);
-      MmUnlockSectionSegment(Segment);
-
-      Status = MmCreateVirtualMapping(Process,
-                                      PAddress,
-                                      Attributes,
-                                      &Page,
-                                      1);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT1("Unable to create virtual mapping\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      MmInsertRmap(Page, Process, Address);
-      MiSetPageEvent(Process, Address);
-      DPRINT("Address 0x%p\n", Address);
-      return(STATUS_SUCCESS);
-   }
-}
+    LARGE_INTEGER Offset;
+    PFN_NUMBER Page;
+    NTSTATUS Status;
+    PROS_SECTION_OBJECT Section;
+    PMM_SECTION_SEGMENT Segment;
+    ULONG_PTR Entry;
+    ULONG_PTR Entry1;
+    ULONG Attributes;
+    PMM_REGION Region;
+    BOOLEAN HasSwapEntry;
+    PVOID PAddress;
+    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+    SWAPENTRY SwapEntry;
 
-NTSTATUS
-NTAPI
-MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
-                         MEMORY_AREA* MemoryArea,
-                         PVOID Address)
-{
-   PMM_SECTION_SEGMENT Segment;
-   PROS_SECTION_OBJECT Section;
-   PFN_NUMBER OldPage;
-   PFN_NUMBER NewPage;
-   NTSTATUS Status;
-   PVOID PAddress;
-   LARGE_INTEGER Offset;
-   PMM_REGION Region;
-   ULONG_PTR Entry;
-   PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-   SWAPENTRY SwapEntry;
-
-   DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
-
-   /*
-    * Check if the page has already been set readwrite
-    */
-   if (MmGetPageProtect(Process, Address) & PAGE_READWRITE)
-   {
-      DPRINT("Address 0x%p\n", Address);
-      return(STATUS_SUCCESS);
-   }
-
-   /*
-    * Find the offset of the page
-    */
-   PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-   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(Process, Address);
-   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-
-   MmUnlockSectionSegment(Segment);
-
-   /*
-    * Check if we are doing COW
-    */
-   if (!((Segment->WriteCopy) &&
-         (Region->Protect == PAGE_READWRITE ||
-          Region->Protect == PAGE_EXECUTE_READWRITE)))
-   {
-      DPRINT("Address 0x%p\n", Address);
-      return(STATUS_ACCESS_VIOLATION);
-   }
-
-   if (IS_SWAP_FROM_SSE(Entry) ||
-       PFN_FROM_SSE(Entry) != OldPage)
-   {
-      /* This is a private page. We must only change the page protection. */
-      MmSetPageProtect(Process, Address, Region->Protect);
-      return(STATUS_SUCCESS);
-   }
-
-   if(OldPage == 0)
-      DPRINT("OldPage == 0!\n");
-
-   /*
-    * Get or create a pageop
-    */
-   MmLockSectionSegment(Segment);
-   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-
-   /*
-    * Wait for any other operations to complete
-    */
-   if (Entry == SWAPENTRY_FROM_SSE(MM_WAIT_ENTRY))
-   {
-       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))
-   {
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
-   /*
-    * Copy the old page
-    */
-   MiCopyFromUserPage(NewPage, OldPage);
-
-   MmLockAddressSpace(AddressSpace);
-
-   /*
-    * Set the PTE to point to the new page
-    */
-   MmDeletePageFileMapping(Process, PAddress, &SwapEntry);
-   Status = MmCreateVirtualMapping(Process,
-                                   PAddress,
-                                   Region->Protect,
-                                   &NewPage,
-                                   1);
-    if (!NT_SUCCESS(Status))
+    /*
+     * There is a window between taking the page fault and locking the
+     * address space when another thread could load the page so we check
+     * that.
+     */
+    if (MmIsPagePresent(Process, Address))
     {
-        DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
-        KeBugCheck(MEMORY_MANAGEMENT);
-        return(Status);
+        return(STATUS_SUCCESS);
     }
 
-   /*
-    * Unshare the old page.
-    */
-   DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
-   MmInsertRmap(NewPage, Process, PAddress);
-   MmLockSectionSegment(Segment);
-   MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL);
-   MmUnlockSectionSegment(Segment);
-
-   MiSetPageEvent(Process, Address);
-   DPRINT("Address 0x%p\n", Address);
-   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.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
+                      + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
+
+    Segment = MemoryArea->Data.SectionData.Segment;
+    Section = MemoryArea->Data.SectionData.Section;
+    Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
+                          &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) &&
+            (Region->Protect == PAGE_READWRITE ||
+             Region->Protect == PAGE_EXECUTE_READWRITE))
+    {
+        Attributes = Region->Protect == PAGE_READWRITE ? PAGE_READONLY : PAGE_EXECUTE_READ;
+    }
+    else
+    {
+        Attributes = Region->Protect;
+    }
+
+    /*
+     * Check if someone else is already handling this fault, if so wait
+     * for them
+     */
+    if (Entry && MM_IS_WAIT_PTE(Entry))
+    {
+        MmUnlockSectionSegment(Segment);
+        MmUnlockAddressSpace(AddressSpace);
+        MiWaitForPageEvent(NULL, NULL);
+        MmLockAddressSpace(AddressSpace);
+        DPRINT("Address 0x%p\n", Address);
+        return(STATUS_MM_RESTART_OPERATION);
+    }
+
+    HasSwapEntry = MmIsPageSwapEntry(Process, Address);
+
+    /* See if we should use a private page */
+    if ((HasSwapEntry) || (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA))
+    {
+        SWAPENTRY DummyEntry;
+
+        /*
+         * Is it a wait entry?
+         */
+        if (HasSwapEntry)
+        {
+            MmGetPageFileMapping(Process, Address, &SwapEntry);
+
+            if (SwapEntry == MM_WAIT_ENTRY)
+            {
+                MmUnlockSectionSegment(Segment);
+                MmUnlockAddressSpace(AddressSpace);
+                MiWaitForPageEvent(NULL, NULL);
+                MmLockAddressSpace(AddressSpace);
+                return STATUS_MM_RESTART_OPERATION;
+            }
+
+            /*
+             * Must be private page we have swapped out.
+             */
+
+            /*
+             * Sanity check
+             */
+            if (Segment->Flags & MM_PAGEFILE_SEGMENT)
+            {
+                DPRINT1("Found a swaped out private page in a pagefile section.\n");
+                KeBugCheck(MEMORY_MANAGEMENT);
+            }
+            MmDeletePageFileMapping(Process, Address, &SwapEntry);
+        }
+
+        MmUnlockSectionSegment(Segment);
+
+        /* Tell everyone else we are serving the fault. */
+        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))
+        {
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+
+        if (HasSwapEntry)
+        {
+            Status = MmReadFromSwapPage(SwapEntry, Page);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
+                KeBugCheck(MEMORY_MANAGEMENT);
+            }
+        }
+
+        MmLockAddressSpace(AddressSpace);
+        MmDeletePageFileMapping(Process, PAddress, &DummyEntry);
+        Status = MmCreateVirtualMapping(Process,
+                                        PAddress,
+                                        Region->Protect,
+                                        &Page,
+                                        1);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
+            KeBugCheck(MEMORY_MANAGEMENT);
+            return(Status);
+        }
+
+        /*
+         * Store the swap entry for later use.
+         */
+        if (HasSwapEntry)
+            MmSetSavedSwapEntryPage(Page, SwapEntry);
+
+        /*
+         * Add the page to the process's working set
+         */
+        MmInsertRmap(Page, Process, Address);
+        /*
+         * Finish the operation
+         */
+        MiSetPageEvent(Process, Address);
+        DPRINT("Address 0x%p\n", Address);
+        return(STATUS_SUCCESS);
+    }
+
+    /*
+     * Satisfying a page fault on a map of /Device/PhysicalMemory is easy
+     */
+    if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
+    {
+        MmUnlockSectionSegment(Segment);
+        /*
+         * Just map the desired physical page
+         */
+        Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT);
+        Status = MmCreateVirtualMappingUnsafe(Process,
+                                              PAddress,
+                                              Region->Protect,
+                                              &Page,
+                                              1);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");
+            KeBugCheck(MEMORY_MANAGEMENT);
+            return(Status);
+        }
+
+        /*
+         * Cleanup and release locks
+         */
+        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);
+
+    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.
+         */
+
+        /*
+         * 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.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.QuadPart, &Page);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("MiReadPage failed (Status %x)\n", Status);
+            }
+        }
+        if (!NT_SUCCESS(Status))
+        {
+            /*
+             * FIXME: What do we know in this case?
+             */
+            /*
+             * Cleanup and release locks
+             */
+            MmLockAddressSpace(AddressSpace);
+            MiSetPageEvent(Process, Address);
+            DPRINT("Address 0x%p\n", Address);
+            return(Status);
+        }
+
+        /* Lock both segment and process address space while we proceed. */
+        MmLockAddressSpace(AddressSpace);
+        MmLockSectionSegment(Segment);
+
+        MmDeletePageFileMapping(Process, PAddress, &FakeSwapEntry);
+        DPRINT("CreateVirtualMapping Page %x Process %p PAddress %p Attributes %x\n",
+               Page, Process, PAddress, Attributes);
+        Status = MmCreateVirtualMapping(Process,
+                                        PAddress,
+                                        Attributes,
+                                        &Page,
+                                        1);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Unable to create virtual mapping\n");
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+        ASSERT(MmIsPagePresent(Process, PAddress));
+        MmInsertRmap(Page, Process, Address);
+
+        /* Set this section offset has being backed by our new page. */
+        Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
+        MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
+        MmUnlockSectionSegment(Segment);
+
+        MiSetPageEvent(Process, Address);
+        DPRINT("Address 0x%p\n", Address);
+        return(STATUS_SUCCESS);
+    }
+    else if (IS_SWAP_FROM_SSE(Entry))
+    {
+        SWAPENTRY SwapEntry;
+
+        SwapEntry = SWAPENTRY_FROM_SSE(Entry);
+
+        /* See if a page op is running on this segment. */
+        if (SwapEntry == MM_WAIT_ENTRY)
+        {
+            MmUnlockSectionSegment(Segment);
+            MmUnlockAddressSpace(AddressSpace);
+            MiWaitForPageEvent(NULL, NULL);
+            MmLockAddressSpace(AddressSpace);
+            return STATUS_MM_RESTART_OPERATION;
+        }
+
+        /*
+        * Release all our locks and read in the page from disk
+        */
+        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))
+        {
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+
+        Status = MmReadFromSwapPage(SwapEntry, Page);
+        if (!NT_SUCCESS(Status))
+        {
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+
+        /*
+         * 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 (%x vs %x)\n", Entry, Entry1);
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+
+        /*
+         * Save the swap entry.
+         */
+        MmSetSavedSwapEntryPage(Page, SwapEntry);
+
+        /* Map the page into the process address space */
+        Status = MmCreateVirtualMapping(Process,
+                                        PAddress,
+                                        Region->Protect,
+                                        &Page,
+                                        1);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Unable to create virtual mapping\n");
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+        MmInsertRmap(Page, Process, Address);
+
+        /*
+         * Mark the offset within the section as having valid, in-memory
+         * data
+         */
+        Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
+        MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
+        MmUnlockSectionSegment(Segment);
+
+        MiSetPageEvent(Process, Address);
+        DPRINT("Address 0x%p\n", Address);
+        return(STATUS_SUCCESS);
+    }
+    else
+    {
+        /* We already have a page on this section offset. Map it into the process address space. */
+        Page = PFN_FROM_SSE(Entry);
+
+        Status = MmCreateVirtualMapping(Process,
+                                        PAddress,
+                                        Attributes,
+                                        &Page,
+                                        1);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Unable to create virtual mapping\n");
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+        MmInsertRmap(Page, Process, Address);
+
+        /* Take a reference on it */
+        MmSharePageEntrySectionSegment(Segment, &Offset);
+        MmUnlockSectionSegment(Segment);
+
+        MiSetPageEvent(Process, Address);
+        DPRINT("Address 0x%p\n", Address);
+        return(STATUS_SUCCESS);
+    }
+}
+
+NTSTATUS
+NTAPI
+MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
+                         MEMORY_AREA* MemoryArea,
+                         PVOID Address)
+{
+    PMM_SECTION_SEGMENT Segment;
+    PROS_SECTION_OBJECT Section;
+    PFN_NUMBER OldPage;
+    PFN_NUMBER NewPage;
+    NTSTATUS Status;
+    PVOID PAddress;
+    LARGE_INTEGER Offset;
+    PMM_REGION Region;
+    ULONG_PTR Entry;
+    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
+    DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
+
+    /* Make sure we have a page mapping for this address.  */
+    Status = MmNotPresentFaultSectionView(AddressSpace, MemoryArea, Address, TRUE);
+    if (!NT_SUCCESS(Status))
+    {
+        /* This is invalid access ! */
+        return Status;
+    }
+
+    /*
+     * Check if the page has already been set readwrite
+     */
+    if (MmGetPageProtect(Process, Address) & PAGE_READWRITE)
+    {
+        DPRINT("Address 0x%p\n", Address);
+        return(STATUS_SUCCESS);
+    }
+
+    /*
+     * Find the offset of the page
+     */
+    PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
+    Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
+                      + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
+
+    Segment = MemoryArea->Data.SectionData.Segment;
+    Section = MemoryArea->Data.SectionData.Section;
+    Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
+                          &MemoryArea->Data.SectionData.RegionListHead,
+                          Address, NULL);
+    ASSERT(Region != NULL);
+
+    /*
+     * Check if we are doing COW
+     */
+    if (!((Segment->WriteCopy) &&
+            (Region->Protect == PAGE_READWRITE ||
+             Region->Protect == PAGE_EXECUTE_READWRITE)))
+    {
+        DPRINT("Address 0x%p\n", Address);
+        return(STATUS_ACCESS_VIOLATION);
+    }
+
+    /* Get the page mapping this section offset. */
+    MmLockSectionSegment(Segment);
+    Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+
+    /* Get the current page mapping for the process */
+    ASSERT(MmIsPagePresent(Process, PAddress));
+    OldPage = MmGetPfnForProcess(Process, PAddress);
+    ASSERT(OldPage != 0);
+
+    if (IS_SWAP_FROM_SSE(Entry) ||
+            PFN_FROM_SSE(Entry) != OldPage)
+    {
+        MmUnlockSectionSegment(Segment);
+        /* This is a private page. We must only change the page protection. */
+        MmSetPageProtect(Process, PAddress, Region->Protect);
+        return(STATUS_SUCCESS);
+    }
+
+    /*
+     * 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))
+    {
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+
+    /*
+     * Copy the old page
+     */
+    MiCopyFromUserPage(NewPage, OldPage);
+
+    /*
+     * Unshare the old page.
+     */
+    DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
+    MmDeleteVirtualMapping(Process, PAddress, NULL, NULL);
+    MmDeleteRmap(OldPage, Process, PAddress);
+    MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL);
+    MmUnlockSectionSegment(Segment);
+
+    /*
+     * Set the PTE to point to the new page
+     */
+    Status = MmCreateVirtualMapping(Process,
+                                    PAddress,
+                                    Region->Protect,
+                                    &NewPage,
+                                    1);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
+        KeBugCheck(MEMORY_MANAGEMENT);
+        return(Status);
+    }
+    MmInsertRmap(NewPage, Process, PAddress);
+
+    MiSetPageEvent(Process, Address);
+    DPRINT("Address 0x%p\n", Address);
+    return(STATUS_SUCCESS);
 }
 
 VOID
 MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
 {
-   MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
-   BOOLEAN WasDirty;
-   PFN_NUMBER Page = 0;
-
-   PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
-   if (Process)
-   {
-      MmLockAddressSpace(&Process->Vm);
-   }
-
-   MmDeleteVirtualMapping(Process,
-                          Address,
-                          FALSE,
-                          &WasDirty,
-                          &Page);
-   if (WasDirty)
-   {
-      PageOutContext->WasDirty = TRUE;
-   }
-   if (!PageOutContext->Private)
-   {
-      MmLockSectionSegment(PageOutContext->Segment);
-      MmUnsharePageEntrySectionSegment((PROS_SECTION_OBJECT)PageOutContext->Section,
-                                       PageOutContext->Segment,
-                                       &PageOutContext->Offset,
-                                       PageOutContext->WasDirty,
-                                       TRUE,
-                                       &PageOutContext->SectionEntry);
-      MmUnlockSectionSegment(PageOutContext->Segment);
-   }
-   if (Process)
-   {
-      MmUnlockAddressSpace(&Process->Vm);
-   }
-
-   if (PageOutContext->Private)
-   {
-      MmReleasePageMemoryConsumer(MC_USER, Page);
-   }
+    MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
+    BOOLEAN WasDirty;
+    PFN_NUMBER Page = 0;
+
+    PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
+    if (Process)
+    {
+        MmLockAddressSpace(&Process->Vm);
+    }
+
+    MmDeleteVirtualMapping(Process,
+                           Address,
+                           &WasDirty,
+                           &Page);
+    if (WasDirty)
+    {
+        PageOutContext->WasDirty = TRUE;
+    }
+    if (!PageOutContext->Private)
+    {
+        MmLockSectionSegment(PageOutContext->Segment);
+        MmUnsharePageEntrySectionSegment((PROS_SECTION_OBJECT)PageOutContext->Section,
+                                         PageOutContext->Segment,
+                                         &PageOutContext->Offset,
+                                         PageOutContext->WasDirty,
+                                         TRUE,
+                                         &PageOutContext->SectionEntry);
+        MmUnlockSectionSegment(PageOutContext->Segment);
+    }
+    if (Process)
+    {
+        MmUnlockAddressSpace(&Process->Vm);
+    }
+
+    if (PageOutContext->Private)
+    {
+        MmReleasePageMemoryConsumer(MC_USER, Page);
+    }
 }
 
 NTSTATUS
@@ -1862,270 +1862,328 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
                      MEMORY_AREA* MemoryArea,
                      PVOID Address, ULONG_PTR Entry)
 {
-   PFN_NUMBER Page;
-   MM_SECTION_PAGEOUT_CONTEXT Context;
-   SWAPENTRY SwapEntry;
-   ULONGLONG FileOffset;
-   NTSTATUS Status;
-   PFILE_OBJECT FileObject;
+    PFN_NUMBER Page;
+    MM_SECTION_PAGEOUT_CONTEXT Context;
+    SWAPENTRY SwapEntry;
+    NTSTATUS Status;
 #ifndef NEWCC
-   PBCB Bcb = NULL;
+    ULONGLONG FileOffset;
+    PFILE_OBJECT FileObject;
+    PROS_SHARED_CACHE_MAP SharedCacheMap = NULL;
+    BOOLEAN IsImageSection;
 #endif
-   BOOLEAN DirectMapped;
-   BOOLEAN IsImageSection;
-   PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-   KIRQL OldIrql;
+    BOOLEAN DirectMapped;
+    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+    KIRQL OldIrql;
 
-   Address = (PVOID)PAGE_ROUND_DOWN(Address);
+    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
-   /*
-    * Get the segment and section.
-    */
-   Context.Segment = MemoryArea->Data.SectionData.Segment;
-   Context.Section = MemoryArea->Data.SectionData.Section;
-   Context.SectionEntry = Entry;
-   Context.CallingProcess = Process;
-
-   Context.Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-                    + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
-   FileOffset = Context.Offset.QuadPart + Context.Segment->Image.FileOffset;
+    /*
+     * Get the segment and section.
+     */
+    Context.Segment = MemoryArea->Data.SectionData.Segment;
+    Context.Section = MemoryArea->Data.SectionData.Section;
+    Context.SectionEntry = Entry;
+    Context.CallingProcess = Process;
 
-   IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
+    Context.Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
+                              + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
-   FileObject = Context.Section->FileObject;
-   DirectMapped = FALSE;
+    DirectMapped = FALSE;
 
-   MmLockSectionSegment(Context.Segment);
+    MmLockSectionSegment(Context.Segment);
 
 #ifndef NEWCC
-   if (FileObject != NULL &&
-       !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
-   {
-      Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-
-      /*
-       * 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 note this is a direct mapped page.
-       */
-      if ((FileOffset % PAGE_SIZE) == 0 &&
-            (Context.Offset.QuadPart + PAGE_SIZE <= Context.Segment->RawLength.QuadPart || !IsImageSection))
-      {
-         DirectMapped = TRUE;
-      }
-   }
+    FileOffset = Context.Offset.QuadPart + Context.Segment->Image.FileOffset;
+    IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
+    FileObject = Context.Section->FileObject;
+
+    if (FileObject != NULL &&
+            !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
+    {
+        SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
+
+        /*
+         * 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 note this is a direct mapped page.
+         */
+        if ((FileOffset % PAGE_SIZE) == 0 &&
+                (Context.Offset.QuadPart + PAGE_SIZE <= Context.Segment->RawLength.QuadPart || !IsImageSection))
+        {
+            DirectMapped = TRUE;
+        }
+    }
 #endif
 
 
-   /*
-    * This should never happen since mappings of physical memory are never
-    * placed in the rmap lists.
-    */
-   if (Context.Section->AllocationAttributes & SEC_PHYSICALMEMORY)
-   {
-      DPRINT1("Trying to page out from physical memory section address 0x%p "
-              "process %p\n", Address,
-              Process ? Process->UniqueProcessId : 0);
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
-   /*
-    * Get the section segment entry and the physical address.
-    */
-   if (!MmIsPagePresent(Process, Address))
-   {
-      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",
+    /*
+     * This should never happen since mappings of physical memory are never
+     * placed in the rmap lists.
+     */
+    if (Context.Section->AllocationAttributes & SEC_PHYSICALMEMORY)
+    {
+        DPRINT1("Trying to page out from physical memory section address 0x%p "
+                "process %p\n", Address,
+                Process ? Process->UniqueProcessId : 0);
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+
+    /*
+     * Get the section segment entry and the physical address.
+     */
+    if (!MmIsPagePresent(Process, Address))
+    {
+        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->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
-         IS_SWAP_FROM_SSE(Entry) ||
-         PFN_FROM_SSE(Entry) != Page)
-   {
-      Context.Private = TRUE;
-   }
-   else
-   {
-      Context.Private = FALSE;
-   }
-
-   /*
-    * Take an additional reference to the page or the VACB.
-    */
-   if (DirectMapped && !Context.Private)
-   {
-      if(!MiIsPageFromCache(MemoryArea, Context.Offset.LowPart))
-      {
-         DPRINT1("Direct mapped non private page is not associated with the cache.\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-   }
-   else
-   {
-      OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
-      MmReferencePage(Page);
-      KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
-   }
-
-   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 && Entry != 0)
-   {
-      if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT) &&
-            !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
-      {
-          KeBugCheckEx(MEMORY_MANAGEMENT, Entry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
-      }
-   }
-
-   /*
-    * If the page wasn't dirty then we can just free it as for a readonly page.
-    * Since we unmapped all the mappings above we know it will not suddenly
-    * become dirty.
-    * If the page is from a pagefile section and has no swap entry,
-    * we can't free the page at this point.
-    */
-   SwapEntry = MmGetSavedSwapEntryPage(Page);
-   if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT)
-   {
-      if (Context.Private)
-      {
-         DPRINT1("Found a %s private page (address %p) in a pagefile segment.\n",
-                 Context.WasDirty ? "dirty" : "clean", Address);
-         KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
-      }
-      if (!Context.WasDirty && SwapEntry != 0)
-      {
-         MmSetSavedSwapEntryPage(Page, 0);
-         MmLockSectionSegment(Context.Segment);
-         MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
-         MmUnlockSectionSegment(Context.Segment);
-         MmReleasePageMemoryConsumer(MC_USER, Page);
-         MiSetPageEvent(NULL, NULL);
-         return(STATUS_SUCCESS);
-      }
-   }
-   else if (Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
-   {
-      if (Context.Private)
-      {
-         DPRINT1("Found a %s private page (address %p) in a shared section segment.\n",
-                 Context.WasDirty ? "dirty" : "clean", Address);
-         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, 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->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
+            IS_SWAP_FROM_SSE(Entry) ||
+            PFN_FROM_SSE(Entry) != Page)
+    {
+        Context.Private = TRUE;
+    }
+    else
+    {
+        Context.Private = FALSE;
+    }
+
+    /*
+     * Take an additional reference to the page or the VACB.
+     */
+    if (DirectMapped && !Context.Private)
+    {
+        if(!MiIsPageFromCache(MemoryArea, Context.Offset.QuadPart))
+        {
+            DPRINT1("Direct mapped non private page is not associated with the cache.\n");
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+    }
+    else
+    {
+        OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+        MmReferencePage(Page);
+        KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+    }
+
+    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 && Entry != 0)
+    {
+        if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT) &&
+                !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
+        {
+            KeBugCheckEx(MEMORY_MANAGEMENT, Entry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
+        }
+    }
+
+    /*
+     * If the page wasn't dirty then we can just free it as for a readonly page.
+     * Since we unmapped all the mappings above we know it will not suddenly
+     * become dirty.
+     * If the page is from a pagefile section and has no swap entry,
+     * we can't free the page at this point.
+     */
+    SwapEntry = MmGetSavedSwapEntryPage(Page);
+    if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT)
+    {
+        if (Context.Private)
+        {
+            DPRINT1("Found a %s private page (address %p) in a pagefile segment.\n",
+                    Context.WasDirty ? "dirty" : "clean", Address);
+            KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
+        }
+        if (!Context.WasDirty && SwapEntry != 0)
+        {
+            MmSetSavedSwapEntryPage(Page, 0);
             MmLockSectionSegment(Context.Segment);
             MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
             MmUnlockSectionSegment(Context.Segment);
-         }
-         MmReleasePageMemoryConsumer(MC_USER, Page);
-         MiSetPageEvent(NULL, NULL);
-         return(STATUS_SUCCESS);
-      }
-   }
-   else if (!Context.Private && DirectMapped)
-   {
-      if (SwapEntry != 0)
-      {
-         DPRINT1("Found a swapentry for a non private and direct mapped page (address %p)\n",
-                 Address);
-         KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address);
-      }
+            MmReleasePageMemoryConsumer(MC_USER, Page);
+            MiSetPageEvent(NULL, NULL);
+            return(STATUS_SUCCESS);
+        }
+    }
+    else if (Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
+    {
+        if (Context.Private)
+        {
+            DPRINT1("Found a %s private page (address %p) in a shared section segment.\n",
+                    Context.WasDirty ? "dirty" : "clean", Address);
+            KeBugCheckEx(MEMORY_MANAGEMENT, Page, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
+        }
+        if (!Context.WasDirty || SwapEntry != 0)
+        {
+            MmSetSavedSwapEntryPage(Page, 0);
+            if (SwapEntry != 0)
+            {
+                MmLockSectionSegment(Context.Segment);
+                MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+                MmUnlockSectionSegment(Context.Segment);
+            }
+            MmReleasePageMemoryConsumer(MC_USER, Page);
+            MiSetPageEvent(NULL, NULL);
+            return(STATUS_SUCCESS);
+        }
+    }
+    else if (!Context.Private && DirectMapped)
+    {
+        if (SwapEntry != 0)
+        {
+            DPRINT1("Found a swapentry for a non private and direct mapped page (address %p)\n",
+                    Address);
+            KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address);
+        }
 #ifndef NEWCC
-      Status = CcRosUnmapVacb(Bcb, (ULONG)FileOffset, FALSE);
+        Status = CcRosUnmapVacb(SharedCacheMap, FileOffset, FALSE);
 #else
-      Status = STATUS_SUCCESS;
+        Status = STATUS_SUCCESS;
 #endif
 #ifndef NEWCC
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status);
-         KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Bcb, (ULONG_PTR)FileOffset, (ULONG_PTR)Address);
-      }
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status);
+            KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)SharedCacheMap, (ULONG_PTR)FileOffset, (ULONG_PTR)Address);
+        }
 #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 %p)\n",
-                 Address);
-         KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, Page, (ULONG_PTR)Process, (ULONG_PTR)Address);
-      }
-      MmReleasePageMemoryConsumer(MC_USER, Page);
-      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,
-                                       Address,
-                                       SwapEntry);
-      MmUnlockAddressSpace(AddressSpace);
-      if (!NT_SUCCESS(Status))
-      {
-         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);
-      MiSetPageEvent(NULL, NULL);
-      return(STATUS_SUCCESS);
-   }
-
-   /*
-    * If necessary, allocate an entry in the paging file for this page
-    */
-   if (SwapEntry == 0)
-   {
-      SwapEntry = MmAllocSwapPage();
-      if (SwapEntry == 0)
-      {
-         MmShowOutOfSpaceMessagePagingFile();
-         MmLockAddressSpace(AddressSpace);
-         /*
-          * For private pages restore the old mappings.
-          */
-         if (Context.Private)
-         {
+        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 %p)\n",
+                    Address);
+            KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, Page, (ULONG_PTR)Process, (ULONG_PTR)Address);
+        }
+        MmReleasePageMemoryConsumer(MC_USER, Page);
+        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,
+                                         Address,
+                                         SwapEntry);
+        MmUnlockAddressSpace(AddressSpace);
+        if (!NT_SUCCESS(Status))
+        {
+            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);
+        MiSetPageEvent(NULL, NULL);
+        return(STATUS_SUCCESS);
+    }
+
+    /*
+     * If necessary, allocate an entry in the paging file for this page
+     */
+    if (SwapEntry == 0)
+    {
+        SwapEntry = MmAllocSwapPage();
+        if (SwapEntry == 0)
+        {
+            MmShowOutOfSpaceMessagePagingFile();
+            MmLockAddressSpace(AddressSpace);
+            /*
+             * For private pages restore the old mappings.
+             */
+            if (Context.Private)
+            {
+                Status = MmCreateVirtualMapping(Process,
+                                                Address,
+                                                MemoryArea->Protect,
+                                                &Page,
+                                                1);
+                MmSetDirtyPage(Process, Address);
+                MmInsertRmap(Page,
+                             Process,
+                             Address);
+            }
+            else
+            {
+                ULONG_PTR OldEntry;
+
+                MmLockSectionSegment(Context.Segment);
+
+                /*
+                 * 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
+                 * our copy. Otherwise it will be handled by the cache manager.
+                 */
+                Status = MmCreateVirtualMapping(Process,
+                                                Address,
+                                                MemoryArea->Protect,
+                                                &Page,
+                                                1);
+                MmSetDirtyPage(Process, Address);
+                MmInsertRmap(Page,
+                             Process,
+                             Address);
+                // If we got here, the previous entry should have been a wait
+                Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
+                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);
+            MiSetPageEvent(NULL, NULL);
+            return(STATUS_PAGEFILE_QUOTA);
+        }
+    }
+
+    /*
+     * Write the page to the pagefile
+     */
+    Status = MmWriteToSwapPage(SwapEntry, Page);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
+                Status);
+        /*
+         * As above: undo our actions.
+         * FIXME: Also free the swap page.
+         */
+        MmLockAddressSpace(AddressSpace);
+        if (Context.Private)
+        {
             Status = MmCreateVirtualMapping(Process,
                                             Address,
                                             MemoryArea->Protect,
@@ -2135,15 +2193,10 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
             MmInsertRmap(Page,
                          Process,
                          Address);
-         }
-         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
-             * our copy. Otherwise it will be handled by the cache manager.
-             */
+        }
+        else
+        {
+            MmLockSectionSegment(Context.Segment);
             Status = MmCreateVirtualMapping(Process,
                                             Address,
                                             MemoryArea->Protect,
@@ -2153,111 +2206,62 @@ 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);
-            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);
-         MiSetPageEvent(NULL, NULL);
-         return(STATUS_PAGEFILE_QUOTA);
-      }
-   }
-
-   /*
-    * Write the page to the pagefile
-    */
-   Status = MmWriteToSwapPage(SwapEntry, Page);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
-              Status);
-      /*
-       * As above: undo our actions.
-       * FIXME: Also free the swap page.
-       */
-      MmLockAddressSpace(AddressSpace);
-      if (Context.Private)
-      {
-         Status = MmCreateVirtualMapping(Process,
-                                         Address,
-                                         MemoryArea->Protect,
-                                         &Page,
-                                         1);
-         MmSetDirtyPage(Process, Address);
-         MmInsertRmap(Page,
-                      Process,
-                      Address);
-      }
-      else
-      {
-         Status = MmCreateVirtualMapping(Process,
+        }
+        MmUnlockAddressSpace(AddressSpace);
+        MiSetPageEvent(NULL, NULL);
+        return(STATUS_UNSUCCESSFUL);
+    }
+
+    /*
+     * Otherwise we have succeeded.
+     */
+    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->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
+    {
+        MmLockSectionSegment(Context.Segment);
+        MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+        MmUnlockSectionSegment(Context.Segment);
+    }
+    else
+    {
+        MmReleasePageMemoryConsumer(MC_USER, Page);
+    }
+
+    if (Context.Private)
+    {
+        MmLockAddressSpace(AddressSpace);
+        MmLockSectionSegment(Context.Segment);
+        Status = MmCreatePageFileMapping(Process,
                                          Address,
-                                         MemoryArea->Protect,
-                                         &Page,
-                                         1);
-         MmSetDirtyPage(Process, Address);
-         MmInsertRmap(Page,
-                      Process,
-                      Address);
-         Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
-         MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
-      }
-      MmUnlockAddressSpace(AddressSpace);
-      MiSetPageEvent(NULL, NULL);
-      return(STATUS_UNSUCCESSFUL);
-   }
-
-   /*
-    * Otherwise we have succeeded.
-    */
-   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->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
-   {
-      MmLockSectionSegment(Context.Segment);
-      MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
-      MmUnlockSectionSegment(Context.Segment);
-   }
-   else
-   {
-      MmReleasePageMemoryConsumer(MC_USER, Page);
-   }
-
-   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))
-      {
-         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);
-      /* We had placed a wait entry upon entry ... replace it before leaving */
-      MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
-      MmUnlockSectionSegment(Context.Segment);
-      MmUnlockAddressSpace(AddressSpace);
-   }
-
-   MiSetPageEvent(NULL, NULL);
-   return(STATUS_SUCCESS);
+                                         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))
+        {
+            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);
+        /* We had placed a wait entry upon entry ... replace it before leaving */
+        MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
+        MmUnlockSectionSegment(Context.Segment);
+        MmUnlockAddressSpace(AddressSpace);
+    }
+
+    MiSetPageEvent(NULL, NULL);
+    return(STATUS_SUCCESS);
 }
 
 NTSTATUS
@@ -2267,148 +2271,152 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
                        PVOID Address,
                        ULONG PageEntry)
 {
-   LARGE_INTEGER Offset;
-   PROS_SECTION_OBJECT Section;
-   PMM_SECTION_SEGMENT Segment;
-   PFN_NUMBER Page;
-   SWAPENTRY SwapEntry;
-   ULONG_PTR Entry;
-   BOOLEAN Private;
-   NTSTATUS Status;
-   PFILE_OBJECT FileObject;
-   PBCB Bcb = NULL;
-   BOOLEAN DirectMapped;
-   BOOLEAN IsImageSection;
-   PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
-   Address = (PVOID)PAGE_ROUND_DOWN(Address);
-
-   Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-            + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
-
-   /*
-    * Get the segment and section.
-    */
-   Segment = MemoryArea->Data.SectionData.Segment;
-   Section = MemoryArea->Data.SectionData.Section;
-   IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
-
-   FileObject = Section->FileObject;
-   DirectMapped = FALSE;
-   if (FileObject != NULL &&
-         !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
-   {
-      Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-
-      /*
-       * 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 note this is a direct mapped page.
-       */
-      if (((Offset.QuadPart + Segment->Image.FileOffset) % PAGE_SIZE) == 0 &&
-            (Offset.QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection))
-      {
-         DirectMapped = TRUE;
-      }
-   }
-
-   /*
-    * This should never happen since mappings of physical memory are never
-    * placed in the rmap lists.
-    */
-   if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
-   {
-      DPRINT1("Trying to write back page from physical memory mapped at %p "
-              "process %p\n", Address,
-              Process ? Process->UniqueProcessId : 0);
-      KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
-   /*
-    * Get the section segment entry and the physical address.
-    */
-   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-   if (!MmIsPagePresent(Process, Address))
-   {
-      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 for a private (COWed) page.
-    */
-   if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
-         IS_SWAP_FROM_SSE(Entry) ||
-         PFN_FROM_SSE(Entry) != Page)
-   {
-      Private = TRUE;
-   }
-   else
-   {
-      Private = FALSE;
-   }
-
-   /*
-    * Speculatively set all mappings of the page to clean.
-    */
-   MmSetCleanAllRmaps(Page);
-
-   /*
-    * If this page was direct mapped from the cache then the cache manager
-    * will take care of writing it back to disk.
-    */
-   if (DirectMapped && !Private)
-   {
-      //LARGE_INTEGER SOffset;
-      ASSERT(SwapEntry == 0);
-      //SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset;
+    LARGE_INTEGER Offset;
+    PROS_SECTION_OBJECT Section;
+    PMM_SECTION_SEGMENT Segment;
+    PFN_NUMBER Page;
+    SWAPENTRY SwapEntry;
+    ULONG_PTR Entry;
+    BOOLEAN Private;
+    NTSTATUS Status;
+    PFILE_OBJECT FileObject;
+#ifndef NEWCC
+    PROS_SHARED_CACHE_MAP SharedCacheMap = NULL;
+#endif
+    BOOLEAN DirectMapped;
+    BOOLEAN IsImageSection;
+    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
+    Address = (PVOID)PAGE_ROUND_DOWN(Address);
+
+    Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
+                      + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
+
+    /*
+     * Get the segment and section.
+     */
+    Segment = MemoryArea->Data.SectionData.Segment;
+    Section = MemoryArea->Data.SectionData.Section;
+    IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
+
+    FileObject = Section->FileObject;
+    DirectMapped = FALSE;
+    if (FileObject != NULL &&
+            !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
+    {
+#ifndef NEWCC
+        SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
+#endif
+
+        /*
+         * 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 note this is a direct mapped page.
+         */
+        if (((Offset.QuadPart + Segment->Image.FileOffset) % PAGE_SIZE) == 0 &&
+                (Offset.QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection))
+        {
+            DirectMapped = TRUE;
+        }
+    }
+
+    /*
+     * This should never happen since mappings of physical memory are never
+     * placed in the rmap lists.
+     */
+    if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
+    {
+        DPRINT1("Trying to write back page from physical memory mapped at %p "
+                "process %p\n", Address,
+                Process ? Process->UniqueProcessId : 0);
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+
+    /*
+     * Get the section segment entry and the physical address.
+     */
+    Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+    if (!MmIsPagePresent(Process, Address))
+    {
+        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 for a private (COWed) page.
+     */
+    if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
+            IS_SWAP_FROM_SSE(Entry) ||
+            PFN_FROM_SSE(Entry) != Page)
+    {
+        Private = TRUE;
+    }
+    else
+    {
+        Private = FALSE;
+    }
+
+    /*
+     * Speculatively set all mappings of the page to clean.
+     */
+    MmSetCleanAllRmaps(Page);
+
+    /*
+     * If this page was direct mapped from the cache then the cache manager
+     * will take care of writing it back to disk.
+     */
+    if (DirectMapped && !Private)
+    {
+        //LARGE_INTEGER SOffset;
+        ASSERT(SwapEntry == 0);
+        //SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset;
 #ifndef NEWCC
-      CcRosMarkDirtyVacb(Bcb, Offset.LowPart);
+        CcRosMarkDirtyVacb(SharedCacheMap, Offset.QuadPart);
 #endif
-      MmLockSectionSegment(Segment);
-      MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry);
-      MmUnlockSectionSegment(Segment);
-      MiSetPageEvent(NULL, NULL);
-      return(STATUS_SUCCESS);
-   }
-
-   /*
-    * If necessary, allocate an entry in the paging file for this page
-    */
-   if (SwapEntry == 0)
-   {
-      SwapEntry = MmAllocSwapPage();
-      if (SwapEntry == 0)
-      {
-         MmSetDirtyAllRmaps(Page);
-         MiSetPageEvent(NULL, NULL);
-         return(STATUS_PAGEFILE_QUOTA);
-      }
-      MmSetSavedSwapEntryPage(Page, SwapEntry);
-   }
-
-   /*
-    * Write the page to the pagefile
-    */
-   Status = MmWriteToSwapPage(SwapEntry, Page);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
-              Status);
-      MmSetDirtyAllRmaps(Page);
-      MiSetPageEvent(NULL, NULL);
-      return(STATUS_UNSUCCESSFUL);
-   }
-
-   /*
-    * Otherwise we have succeeded.
-    */
-   DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
-   MiSetPageEvent(NULL, NULL);
-   return(STATUS_SUCCESS);
+        MmLockSectionSegment(Segment);
+        MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry);
+        MmUnlockSectionSegment(Segment);
+        MiSetPageEvent(NULL, NULL);
+        return(STATUS_SUCCESS);
+    }
+
+    /*
+     * If necessary, allocate an entry in the paging file for this page
+     */
+    if (SwapEntry == 0)
+    {
+        SwapEntry = MmAllocSwapPage();
+        if (SwapEntry == 0)
+        {
+            MmSetDirtyAllRmaps(Page);
+            MiSetPageEvent(NULL, NULL);
+            return(STATUS_PAGEFILE_QUOTA);
+        }
+        MmSetSavedSwapEntryPage(Page, SwapEntry);
+    }
+
+    /*
+     * Write the page to the pagefile
+     */
+    Status = MmWriteToSwapPage(SwapEntry, Page);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
+                Status);
+        MmSetDirtyAllRmaps(Page);
+        MiSetPageEvent(NULL, NULL);
+        return(STATUS_UNSUCCESSFUL);
+    }
+
+    /*
+     * Otherwise we have succeeded.
+     */
+    DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
+    MiSetPageEvent(NULL, NULL);
+    return(STATUS_SUCCESS);
 }
 
 static VOID
@@ -2420,76 +2428,78 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
                       ULONG NewType,
                       ULONG NewProtect)
 {
-   PMEMORY_AREA MemoryArea;
-   PMM_SECTION_SEGMENT Segment;
-   BOOLEAN DoCOW = FALSE;
-   ULONG i;
-   PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
-   MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
-   ASSERT(MemoryArea != NULL);
-   Segment = MemoryArea->Data.SectionData.Segment;
-   MmLockSectionSegment(Segment);
-
-   if ((Segment->WriteCopy) &&
-         (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE))
-   {
-      DoCOW = TRUE;
-   }
-
-   if (OldProtect != NewProtect)
-   {
-      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))
-         {
-            LARGE_INTEGER Offset;
-            ULONG_PTR Entry;
-            PFN_NUMBER Page;
-
-            Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-                     + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
-            Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+    PMEMORY_AREA MemoryArea;
+    PMM_SECTION_SEGMENT Segment;
+    BOOLEAN DoCOW = FALSE;
+    ULONG i;
+    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
+    MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+    ASSERT(MemoryArea != NULL);
+    Segment = MemoryArea->Data.SectionData.Segment;
+    MmLockSectionSegment(Segment);
+
+    if ((Segment->WriteCopy) &&
+            (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE))
+    {
+        DoCOW = TRUE;
+    }
+
+    if (OldProtect != NewProtect)
+    {
+        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);
+
             /*
-             * 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.
+             * If we doing COW for this segment then check if the page is
+             * already private.
              */
-            Page = MmGetPfnForProcess(Process, Address);
-
-            Protect = PAGE_READONLY;
-            if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
-                  IS_SWAP_FROM_SSE(Entry) ||
-                  PFN_FROM_SSE(Entry) != Page)
+            if (DoCOW && MmIsPagePresent(Process, Address))
             {
-               Protect = NewProtect;
+                LARGE_INTEGER Offset;
+                ULONG_PTR Entry;
+                PFN_NUMBER Page;
+
+                Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
+                                  + 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->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
+                        IS_SWAP_FROM_SSE(Entry) ||
+                        PFN_FROM_SSE(Entry) != Page)
+                {
+                    Protect = NewProtect;
+                }
             }
-         }
 
-         if (MmIsPagePresent(Process, Address) || MmIsDisabledPage(Process, Address))
-         {
-            MmSetPageProtect(Process, Address,
-                             Protect);
-         }
-      }
-   }
+            if (MmIsPagePresent(Process, Address) || MmIsDisabledPage(Process, Address))
+            {
+                MmSetPageProtect(Process, Address,
+                                 Protect);
+            }
+        }
+    }
 
-   MmUnlockSectionSegment(Segment);
+    MmUnlockSectionSegment(Segment);
 }
 
 NTSTATUS
@@ -2501,32 +2511,32 @@ MmProtectSectionView(PMMSUPPORT AddressSpace,
                      ULONG Protect,
                      PULONG OldProtect)
 {
-   PMM_REGION Region;
-   NTSTATUS Status;
-   ULONG_PTR MaxLength;
-
-   MaxLength = (ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)BaseAddress;
-   if (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)
-   {
-      return STATUS_INVALID_PAGE_PROTECTION;
-   }
-
-   *OldProtect = Region->Protect;
-   Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress,
+    PMM_REGION Region;
+    NTSTATUS Status;
+    ULONG_PTR MaxLength;
+
+    MaxLength = MA_GetEndingAddress(MemoryArea) - (ULONG_PTR)BaseAddress;
+    if (Length > MaxLength)
+        Length = (ULONG)MaxLength;
+
+    Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
                           &MemoryArea->Data.SectionData.RegionListHead,
-                          BaseAddress, Length, Region->Type, Protect,
-                          MmAlterViewAttributes);
+                          BaseAddress, NULL);
+    ASSERT(Region != NULL);
+
+    if ((MemoryArea->Flags & SEC_NO_CHANGE) &&
+            Region->Protect != Protect)
+    {
+        return STATUS_INVALID_PAGE_PROTECTION;
+    }
 
-   return(Status);
+    *OldProtect = Region->Protect;
+    Status = MmAlterRegion(AddressSpace, (PVOID)MA_GetStartingAddress(MemoryArea),
+                           &MemoryArea->Data.SectionData.RegionListHead,
+                           BaseAddress, Length, Region->Type, Protect,
+                           MmAlterViewAttributes);
+
+    return(Status);
 }
 
 NTSTATUS NTAPI
@@ -2535,173 +2545,180 @@ MmQuerySectionView(PMEMORY_AREA MemoryArea,
                    PMEMORY_BASIC_INFORMATION Info,
                    PSIZE_T ResultLength)
 {
-   PMM_REGION Region;
-   PVOID RegionBaseAddress;
-   PROS_SECTION_OBJECT Section;
-   PMM_SECTION_SEGMENT Segment;
-
-   Region = MmFindRegion((PVOID)MemoryArea->StartingAddress,
-                         &MemoryArea->Data.SectionData.RegionListHead,
-                         Address, &RegionBaseAddress);
-   if (Region == NULL)
-   {
-      return STATUS_UNSUCCESSFUL;
-   }
-
-   Section = MemoryArea->Data.SectionData.Section;
-   if (Section->AllocationAttributes & SEC_IMAGE)
-   {
-      Segment = MemoryArea->Data.SectionData.Segment;
-      Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->Image.VirtualAddress;
-      Info->Type = MEM_IMAGE;
-   }
-   else
-   {
-      Info->AllocationBase = MemoryArea->StartingAddress;
-      Info->Type = MEM_MAPPED;
-   }
-   Info->BaseAddress = RegionBaseAddress;
-   Info->AllocationProtect = MemoryArea->Protect;
-   Info->RegionSize = Region->Length;
-   Info->State = MEM_COMMIT;
-   Info->Protect = Region->Protect;
-
-   *ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
-   return(STATUS_SUCCESS);
+    PMM_REGION Region;
+    PVOID RegionBaseAddress;
+    PROS_SECTION_OBJECT Section;
+    PMM_SECTION_SEGMENT Segment;
+
+    Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
+                          &MemoryArea->Data.SectionData.RegionListHead,
+                          Address, &RegionBaseAddress);
+    if (Region == NULL)
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    Section = MemoryArea->Data.SectionData.Section;
+    if (Section->AllocationAttributes & SEC_IMAGE)
+    {
+        Segment = MemoryArea->Data.SectionData.Segment;
+        Info->AllocationBase = (PUCHAR)MA_GetStartingAddress(MemoryArea) - Segment->Image.VirtualAddress;
+        Info->Type = MEM_IMAGE;
+    }
+    else
+    {
+        Info->AllocationBase = (PVOID)MA_GetStartingAddress(MemoryArea);
+        Info->Type = MEM_MAPPED;
+    }
+    Info->BaseAddress = RegionBaseAddress;
+    Info->AllocationProtect = MemoryArea->Protect;
+    Info->RegionSize = Region->Length;
+    Info->State = MEM_COMMIT;
+    Info->Protect = Region->Protect;
+
+    *ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
+    return(STATUS_SUCCESS);
 }
 
 VOID
 NTAPI
 MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
 {
-   ULONG Length;
-   LARGE_INTEGER Offset;
-   ULONG_PTR Entry;
-   SWAPENTRY SavedSwapEntry;
-   PFN_NUMBER Page;
-
-   Page = 0;
-
-   MmLockSectionSegment(Segment);
-
-   Length = PAGE_ROUND_UP(Segment->Length.QuadPart);
-   for (Offset.QuadPart = 0; Offset.QuadPart < Length; Offset.QuadPart += PAGE_SIZE)
-   {
-      Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-      if (Entry)
-      {
-         MmSetPageEntrySectionSegment(Segment, &Offset, 0);
-         if (IS_SWAP_FROM_SSE(Entry))
-         {
-            MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry));
-         }
-         else
-         {
-            Page = PFN_FROM_SSE(Entry);
-            SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
-            if (SavedSwapEntry != 0)
+    ULONG Length;
+    LARGE_INTEGER Offset;
+    ULONG_PTR Entry;
+    SWAPENTRY SavedSwapEntry;
+    PFN_NUMBER Page;
+
+    Page = 0;
+
+    MmLockSectionSegment(Segment);
+
+    Length = PAGE_ROUND_UP(Segment->Length.QuadPart);
+    for (Offset.QuadPart = 0; Offset.QuadPart < Length; Offset.QuadPart += PAGE_SIZE)
+    {
+        Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+        if (Entry)
+        {
+            MmSetPageEntrySectionSegment(Segment, &Offset, 0);
+            if (IS_SWAP_FROM_SSE(Entry))
             {
-               MmSetSavedSwapEntryPage(Page, 0);
-               MmFreeSwapPage(SavedSwapEntry);
+                MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry));
             }
-            MmReleasePageMemoryConsumer(MC_USER, Page);
-         }
-      }
-   }
+            else
+            {
+                Page = PFN_FROM_SSE(Entry);
+                SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
+                if (SavedSwapEntry != 0)
+                {
+                    MmSetSavedSwapEntryPage(Page, 0);
+                    MmFreeSwapPage(SavedSwapEntry);
+                }
+                MmReleasePageMemoryConsumer(MC_USER, Page);
+            }
+        }
+    }
 
-   MmUnlockSectionSegment(Segment);
+    MmUnlockSectionSegment(Segment);
 }
 
 VOID NTAPI
 MmpDeleteSection(PVOID ObjectBody)
 {
-   PROS_SECTION_OBJECT Section = (PROS_SECTION_OBJECT)ObjectBody;
-
-   DPRINT("MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
-   if (Section->AllocationAttributes & SEC_IMAGE)
-   {
-      ULONG i;
-      ULONG NrSegments;
-      ULONG RefCount;
-      PMM_SECTION_SEGMENT SectionSegments;
-
-      /*
-       * NOTE: Section->ImageSection can be NULL for short time
-       * during the section creating. If we fail for some reason
-       * until the image section is properly initialized we shouldn't
-       * process further here.
-       */
-      if (Section->ImageSection == NULL)
-         return;
-
-      SectionSegments = Section->ImageSection->Segments;
-      NrSegments = Section->ImageSection->NrSegments;
-
-      for (i = 0; i < NrSegments; i++)
-      {
-         if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
-         {
-            MmLockSectionSegment(&SectionSegments[i]);
-         }
-         RefCount = InterlockedDecrementUL(&SectionSegments[i].ReferenceCount);
-         if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
-         {
-            MmUnlockSectionSegment(&SectionSegments[i]);
-            if (RefCount == 0)
+    PROS_SECTION_OBJECT Section = (PROS_SECTION_OBJECT)ObjectBody;
+
+    /* Check if it's an ARM3, or ReactOS section */
+    if (!MiIsRosSectionObject(Section))
+    {
+        MiDeleteARM3Section(ObjectBody);
+        return;
+    }
+
+    DPRINT("MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
+    if (Section->AllocationAttributes & SEC_IMAGE)
+    {
+        ULONG i;
+        ULONG NrSegments;
+        ULONG RefCount;
+        PMM_SECTION_SEGMENT SectionSegments;
+
+        /*
+         * NOTE: Section->ImageSection can be NULL for short time
+         * during the section creating. If we fail for some reason
+         * until the image section is properly initialized we shouldn't
+         * process further here.
+         */
+        if (Section->ImageSection == NULL)
+            return;
+
+        SectionSegments = Section->ImageSection->Segments;
+        NrSegments = Section->ImageSection->NrSegments;
+
+        for (i = 0; i < NrSegments; i++)
+        {
+            if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
+            {
+                MmLockSectionSegment(&SectionSegments[i]);
+            }
+            RefCount = InterlockedDecrementUL(&SectionSegments[i].ReferenceCount);
+            if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
             {
-               MmpFreePageFileSegment(&SectionSegments[i]);
+                MmUnlockSectionSegment(&SectionSegments[i]);
+                if (RefCount == 0)
+                {
+                    MmpFreePageFileSegment(&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);
-         }
-   }
+    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
-   {
-      /*
-       * NOTE: Section->Segment can be NULL for short time
-       * during the section creating.
-       */
-      if (Section->Segment == NULL)
-         return;
-
-      if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT)
-      {
-         MmpFreePageFileSegment(Section->Segment);
-         MmFreePageTablesSectionSegment(Section->Segment, NULL);
-         ExFreePool(Section->Segment);
-         Section->Segment = NULL;
-      }
-      else
-      {
-         (void)InterlockedDecrementUL(&Section->Segment->ReferenceCount);
-      }
-   }
-   if (Section->FileObject != NULL)
-   {
+    else
+    {
+        /*
+         * NOTE: Section->Segment can be NULL for short time
+         * during the section creating.
+         */
+        if (Section->Segment == NULL)
+            return;
+
+        if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT)
+        {
+            MmpFreePageFileSegment(Section->Segment);
+            MmFreePageTablesSectionSegment(Section->Segment, NULL);
+            ExFreePool(Section->Segment);
+            Section->Segment = NULL;
+        }
+        else
+        {
+            (void)InterlockedDecrementUL(&Section->Segment->ReferenceCount);
+        }
+    }
+    if (Section->FileObject != NULL)
+    {
 #ifndef NEWCC
-      CcRosDereferenceCache(Section->FileObject);
+        CcRosDereferenceCache(Section->FileObject);
 #endif
-      ObDereferenceObject(Section->FileObject);
-      Section->FileObject = NULL;
-   }
+        ObDereferenceObject(Section->FileObject);
+        Section->FileObject = NULL;
+    }
 }
 
 VOID NTAPI
@@ -2719,50 +2736,50 @@ INIT_FUNCTION
 NTAPI
 MmCreatePhysicalMemorySection(VOID)
 {
-   PROS_SECTION_OBJECT PhysSection;
-   NTSTATUS Status;
-   OBJECT_ATTRIBUTES Obj;
-   UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
-   LARGE_INTEGER SectionSize;
-   HANDLE Handle;
-
-   /*
-    * Create the section mapping physical memory
-    */
-   SectionSize.QuadPart = 0xFFFFFFFF;
-   InitializeObjectAttributes(&Obj,
-                              &Name,
-                              OBJ_PERMANENT,
-                              NULL,
-                              NULL);
-   Status = MmCreateSection((PVOID)&PhysSection,
+    PROS_SECTION_OBJECT PhysSection;
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES Obj;
+    UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
+    LARGE_INTEGER SectionSize;
+    HANDLE Handle;
+
+    /*
+     * Create the section mapping physical memory
+     */
+    SectionSize.QuadPart = 0xFFFFFFFF;
+    InitializeObjectAttributes(&Obj,
+                               &Name,
+                               OBJ_PERMANENT | OBJ_KERNEL_EXCLUSIVE,
+                               NULL,
+                               NULL);
+    Status = MmCreateSection((PVOID)&PhysSection,
+                             SECTION_ALL_ACCESS,
+                             &Obj,
+                             &SectionSize,
+                             PAGE_EXECUTE_READWRITE,
+                             SEC_PHYSICALMEMORY,
+                             NULL,
+                             NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create PhysicalMemory section\n");
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+    Status = ObInsertObject(PhysSection,
+                            NULL,
                             SECTION_ALL_ACCESS,
-                            &Obj,
-                            &SectionSize,
-                            PAGE_EXECUTE_READWRITE,
-                            SEC_PHYSICALMEMORY,
+                            0,
                             NULL,
-                            NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("Failed to create PhysicalMemory section\n");
-      KeBugCheck(MEMORY_MANAGEMENT);
-   }
-   Status = ObInsertObject(PhysSection,
-                           NULL,
-                           SECTION_ALL_ACCESS,
-                           0,
-                           NULL,
-                           &Handle);
-   if (!NT_SUCCESS(Status))
-   {
-      ObDereferenceObject(PhysSection);
-   }
-   ObCloseHandle(Handle, KernelMode);
-   PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY;
-   PhysSection->Segment->Flags &= ~MM_PAGEFILE_SEGMENT;
-
-   return(STATUS_SUCCESS);
+                            &Handle);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(PhysSection);
+    }
+    ObCloseHandle(Handle, KernelMode);
+    PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY;
+    PhysSection->Segment->Flags &= ~MM_PAGEFILE_SEGMENT;
+
+    return(STATUS_SUCCESS);
 }
 
 NTSTATUS
@@ -2770,32 +2787,32 @@ INIT_FUNCTION
 NTAPI
 MmInitSectionImplementation(VOID)
 {
-   OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
-   UNICODE_STRING Name;
-
-   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");
-   ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
-   ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(ROS_SECTION_OBJECT);
-   ObjectTypeInitializer.PoolType = PagedPool;
-   ObjectTypeInitializer.UseDefaultObject = TRUE;
-   ObjectTypeInitializer.GenericMapping = MmpSectionMapping;
-   ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection;
-   ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
-   ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
-   ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
-   ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
-
-   MmCreatePhysicalMemorySection();
-
-   return(STATUS_SUCCESS);
+    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+    UNICODE_STRING Name;
+
+    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");
+    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+    ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(ROS_SECTION_OBJECT);
+    ObjectTypeInitializer.PoolType = PagedPool;
+    ObjectTypeInitializer.UseDefaultObject = TRUE;
+    ObjectTypeInitializer.GenericMapping = MmpSectionMapping;
+    ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection;
+    ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
+    ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
+    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
+    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
+
+    MmCreatePhysicalMemorySection();
+
+    return(STATUS_SUCCESS);
 }
 
 NTSTATUS
@@ -2810,67 +2827,67 @@ MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject,
  * Create a section which is backed by the pagefile
  */
 {
-   LARGE_INTEGER MaximumSize;
-   PROS_SECTION_OBJECT Section;
-   PMM_SECTION_SEGMENT Segment;
-   NTSTATUS Status;
-
-   if (UMaximumSize == NULL)
-   {
-      DPRINT1("MmCreatePageFileSection: (UMaximumSize == NULL)\n");
-      return(STATUS_INVALID_PARAMETER);
-   }
-   MaximumSize = *UMaximumSize;
-
-   /*
-    * Create the section
-    */
-   Status = ObCreateObject(ExGetPreviousMode(),
-                           MmSectionObjectType,
-                           ObjectAttributes,
-                           ExGetPreviousMode(),
-                           NULL,
-                           sizeof(ROS_SECTION_OBJECT),
-                           0,
-                           0,
-                           (PVOID*)(PVOID)&Section);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("MmCreatePageFileSection: failed to create object (0x%lx)\n", Status);
-      return(Status);
-   }
-
-   /*
-    * Initialize it
-    */
-   RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
-   Section->Type = 'SC';
-   Section->Size = 'TN';
-   Section->SectionPageProtection = SectionPageProtection;
-   Section->AllocationAttributes = AllocationAttributes;
-   Section->MaximumSize = MaximumSize;
-   Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
-                                   TAG_MM_SECTION_SEGMENT);
-   if (Segment == NULL)
-   {
-      ObDereferenceObject(Section);
-      return(STATUS_NO_MEMORY);
-   }
-   RtlZeroMemory(Segment, sizeof(MM_SECTION_SEGMENT));
-   Section->Segment = Segment;
-   Segment->ReferenceCount = 1;
-   ExInitializeFastMutex(&Segment->Lock);
-   Segment->Image.FileOffset = 0;
-   Segment->Protection = SectionPageProtection;
-   Segment->RawLength.QuadPart = MaximumSize.u.LowPart;
-   Segment->Length.QuadPart = PAGE_ROUND_UP(MaximumSize.u.LowPart);
-   Segment->Flags = MM_PAGEFILE_SEGMENT;
-   Segment->WriteCopy = FALSE;
-   Segment->Image.VirtualAddress = 0;
-   Segment->Image.Characteristics = 0;
-   *SectionObject = Section;
-   MiInitializeSectionPageTable(Segment);
-   return(STATUS_SUCCESS);
+    LARGE_INTEGER MaximumSize;
+    PROS_SECTION_OBJECT Section;
+    PMM_SECTION_SEGMENT Segment;
+    NTSTATUS Status;
+
+    if (UMaximumSize == NULL)
+    {
+        DPRINT1("MmCreatePageFileSection: (UMaximumSize == NULL)\n");
+        return(STATUS_INVALID_PARAMETER);
+    }
+    MaximumSize = *UMaximumSize;
+
+    /*
+     * Create the section
+     */
+    Status = ObCreateObject(ExGetPreviousMode(),
+                            MmSectionObjectType,
+                            ObjectAttributes,
+                            ExGetPreviousMode(),
+                            NULL,
+                            sizeof(ROS_SECTION_OBJECT),
+                            0,
+                            0,
+                            (PVOID*)(PVOID)&Section);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("MmCreatePageFileSection: failed to create object (0x%lx)\n", Status);
+        return(Status);
+    }
+
+    /*
+     * Initialize it
+     */
+    RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
+    Section->Type = 'SC';
+    Section->Size = 'TN';
+    Section->SectionPageProtection = SectionPageProtection;
+    Section->AllocationAttributes = AllocationAttributes;
+    Section->MaximumSize = MaximumSize;
+    Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
+                                    TAG_MM_SECTION_SEGMENT);
+    if (Segment == NULL)
+    {
+        ObDereferenceObject(Section);
+        return(STATUS_NO_MEMORY);
+    }
+    RtlZeroMemory(Segment, sizeof(MM_SECTION_SEGMENT));
+    Section->Segment = Segment;
+    Segment->ReferenceCount = 1;
+    ExInitializeFastMutex(&Segment->Lock);
+    Segment->Image.FileOffset = 0;
+    Segment->Protection = SectionPageProtection;
+    Segment->RawLength.QuadPart = MaximumSize.u.LowPart;
+    Segment->Length.QuadPart = PAGE_ROUND_UP(MaximumSize.u.LowPart);
+    Segment->Flags = MM_PAGEFILE_SEGMENT;
+    Segment->WriteCopy = FALSE;
+    Segment->Image.VirtualAddress = 0;
+    Segment->Image.Characteristics = 0;
+    *SectionObject = Section;
+    MiInitializeSectionPageTable(Segment);
+    return(STATUS_SUCCESS);
 }
 
 NTSTATUS
@@ -2886,228 +2903,198 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
  * Create a section backed by a data file
  */
 {
-   PROS_SECTION_OBJECT Section;
-   NTSTATUS Status;
-   LARGE_INTEGER MaximumSize;
-   PFILE_OBJECT FileObject;
-   PMM_SECTION_SEGMENT Segment;
-   ULONG FileAccess;
-   IO_STATUS_BLOCK Iosb;
-   LARGE_INTEGER Offset;
-   CHAR Buffer;
-   FILE_STANDARD_INFORMATION FileInfo;
-   ULONG Length;
-
-   /*
-    * Create the section
-    */
-   Status = ObCreateObject(ExGetPreviousMode(),
-                           MmSectionObjectType,
-                           ObjectAttributes,
-                           ExGetPreviousMode(),
-                           NULL,
-                           sizeof(ROS_SECTION_OBJECT),
-                           0,
-                           0,
-                           (PVOID*)&Section);
-   if (!NT_SUCCESS(Status))
-   {
-      return(Status);
-   }
-   /*
-    * Initialize it
-    */
-   RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
-   Section->Type = 'SC';
-   Section->Size = 'TN';
-   Section->SectionPageProtection = SectionPageProtection;
-   Section->AllocationAttributes = AllocationAttributes;
-
-   /*
-    * Reference the file handle
-    */
+    PROS_SECTION_OBJECT Section;
+    NTSTATUS Status;
+    LARGE_INTEGER MaximumSize;
+    PFILE_OBJECT FileObject;
+    PMM_SECTION_SEGMENT Segment;
+    ULONG FileAccess;
+    FILE_STANDARD_INFORMATION FileInfo;
+    ULONG Length;
+
+    /*
+     * Create the section
+     */
+    Status = ObCreateObject(ExGetPreviousMode(),
+                            MmSectionObjectType,
+                            ObjectAttributes,
+                            ExGetPreviousMode(),
+                            NULL,
+                            sizeof(ROS_SECTION_OBJECT),
+                            0,
+                            0,
+                            (PVOID*)&Section);
+    if (!NT_SUCCESS(Status))
+    {
+        return(Status);
+    }
+    /*
+     * Initialize it
+     */
+    RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
+    Section->Type = 'SC';
+    Section->Size = 'TN';
+    Section->SectionPageProtection = SectionPageProtection;
+    Section->AllocationAttributes = AllocationAttributes;
+
+    /*
+     * Reference the file handle
+     */
     FileAccess = MiArm3GetCorrectFileAccessMask(SectionPageProtection);
     Status = ObReferenceObjectByHandle(FileHandle,
-                                      FileAccess,
-                                      IoFileObjectType,
-                                      ExGetPreviousMode(),
-                                      (PVOID*)(PVOID)&FileObject,
-                                      NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      ObDereferenceObject(Section);
-      return(Status);
-   }
-
-   /*
-    * FIXME: This is propably not entirely correct. We can't look into
-    * the standard FCB header because it might not be initialized yet
-    * (as in case of the EXT2FS driver by Manoj Paul Joseph where the
-    * standard file information is filled on first request).
-    */
-   Status = IoQueryFileInformation(FileObject,
-                                   FileStandardInformation,
-                                   sizeof(FILE_STANDARD_INFORMATION),
-                                   &FileInfo,
-                                   &Length);
-   Iosb.Information = Length;
-   if (!NT_SUCCESS(Status))
-   {
-      ObDereferenceObject(Section);
-      ObDereferenceObject(FileObject);
-      return Status;
-   }
-
-   /*
-    * FIXME: Revise this once a locking order for file size changes is
-    * decided
-    */
-   if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
-   {
-         MaximumSize = *UMaximumSize;
-   }
-   else
-   {
-      MaximumSize = FileInfo.EndOfFile;
-      /* Mapping zero-sized files isn't allowed. */
-      if (MaximumSize.QuadPart == 0)
-      {
-         ObDereferenceObject(Section);
-         ObDereferenceObject(FileObject);
-         return STATUS_FILE_INVALID;
-      }
-   }
-
-   if (MaximumSize.QuadPart > FileInfo.EndOfFile.QuadPart)
-   {
-      Status = IoSetInformation(FileObject,
-                                FileAllocationInformation,
-                                sizeof(LARGE_INTEGER),
-                                &MaximumSize);
-      if (!NT_SUCCESS(Status))
-      {
-         ObDereferenceObject(Section);
-         ObDereferenceObject(FileObject);
-         return(STATUS_SECTION_NOT_EXTENDED);
-      }
-   }
-
-   if (FileObject->SectionObjectPointer == NULL ||
-         FileObject->SectionObjectPointer->SharedCacheMap == NULL)
-   {
-      /*
-       * Read a bit so caching is initiated for the file object.
-       * This is only needed because MiReadPage currently cannot
-       * handle non-cached streams.
-       */
-      Offset.QuadPart = 0;
-      Status = ZwReadFile(FileHandle,
-                          NULL,
-                          NULL,
-                          NULL,
-                          &Iosb,
-                          &Buffer,
-                          sizeof (Buffer),
-                          &Offset,
-                          0);
-      if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
-      {
-         ObDereferenceObject(Section);
-         ObDereferenceObject(FileObject);
-         return(Status);
-      }
-      if (FileObject->SectionObjectPointer == NULL ||
+                                       FileAccess,
+                                       IoFileObjectType,
+                                       ExGetPreviousMode(),
+                                       (PVOID*)(PVOID)&FileObject,
+                                       NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(Section);
+        return(Status);
+    }
+
+    /*
+     * FIXME: This is propably not entirely correct. We can't look into
+     * the standard FCB header because it might not be initialized yet
+     * (as in case of the EXT2FS driver by Manoj Paul Joseph where the
+     * standard file information is filled on first request).
+     */
+    Status = IoQueryFileInformation(FileObject,
+                                    FileStandardInformation,
+                                    sizeof(FILE_STANDARD_INFORMATION),
+                                    &FileInfo,
+                                    &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(Section);
+        ObDereferenceObject(FileObject);
+        return Status;
+    }
+
+    /*
+     * FIXME: Revise this once a locking order for file size changes is
+     * decided
+     */
+    if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
+    {
+        MaximumSize = *UMaximumSize;
+    }
+    else
+    {
+        MaximumSize = FileInfo.EndOfFile;
+        /* Mapping zero-sized files isn't allowed. */
+        if (MaximumSize.QuadPart == 0)
+        {
+            ObDereferenceObject(Section);
+            ObDereferenceObject(FileObject);
+            return STATUS_MAPPED_FILE_SIZE_ZERO;
+        }
+    }
+
+    if (MaximumSize.QuadPart > FileInfo.EndOfFile.QuadPart)
+    {
+        Status = IoSetInformation(FileObject,
+                                  FileEndOfFileInformation,
+                                  sizeof(LARGE_INTEGER),
+                                  &MaximumSize);
+        if (!NT_SUCCESS(Status))
+        {
+            ObDereferenceObject(Section);
+            ObDereferenceObject(FileObject);
+            return(STATUS_SECTION_NOT_EXTENDED);
+        }
+    }
+
+    if (FileObject->SectionObjectPointer == NULL ||
             FileObject->SectionObjectPointer->SharedCacheMap == NULL)
-      {
-         /* FIXME: handle this situation */
-         ObDereferenceObject(Section);
-         ObDereferenceObject(FileObject);
-         return STATUS_INVALID_PARAMETER;
-      }
-   }
-
-   /*
-    * Lock the file
-    */
-   Status = MmspWaitForFileLock(FileObject);
-   if (Status != STATUS_SUCCESS)
-   {
-      ObDereferenceObject(Section);
-      ObDereferenceObject(FileObject);
-      return(Status);
-   }
-
-   /*
-    * If this file hasn't been mapped as a data file before then allocate a
-    * section segment to describe the data file mapping
-    */
-   if (FileObject->SectionObjectPointer->DataSectionObject == NULL)
-   {
-      Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
-                                      TAG_MM_SECTION_SEGMENT);
-      if (Segment == NULL)
-      {
-         //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
-         ObDereferenceObject(Section);
-         ObDereferenceObject(FileObject);
-         return(STATUS_NO_MEMORY);
-      }
-      Section->Segment = Segment;
-      Segment->ReferenceCount = 1;
-      ExInitializeFastMutex(&Segment->Lock);
-      /*
-       * Set the lock before assigning the segment to the file object
-       */
-      ExAcquireFastMutex(&Segment->Lock);
-      FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
-
-      Segment->Image.FileOffset = 0;
-      Segment->Protection = SectionPageProtection;
-      Segment->Flags = MM_DATAFILE_SEGMENT;
-      Segment->Image.Characteristics = 0;
-      Segment->WriteCopy = (SectionPageProtection & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY));
-      if (AllocationAttributes & SEC_RESERVE)
-      {
-         Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
-      }
-      else
-      {
-         Segment->RawLength.QuadPart = MaximumSize.QuadPart;
-         Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
-      }
-      Segment->Image.VirtualAddress = 0;
-      Segment->Locked = TRUE;
-      MiInitializeSectionPageTable(Segment);
-   }
-   else
-   {
-      /*
-       * If the file is already mapped as a data file then we may need
-       * to extend it
-       */
-      Segment =
-         (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
-         DataSectionObject;
-      Section->Segment = Segment;
-      (void)InterlockedIncrementUL(&Segment->ReferenceCount);
-      MmLockSectionSegment(Segment);
-
-      if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
-            !(AllocationAttributes & SEC_RESERVE))
-      {
-         Segment->RawLength.QuadPart = MaximumSize.QuadPart;
-         Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
-      }
-   }
-   MmUnlockSectionSegment(Segment);
-   Section->FileObject = FileObject;
-   Section->MaximumSize = MaximumSize;
+    {
+        ObDereferenceObject(Section);
+        ObDereferenceObject(FileObject);
+        return STATUS_INVALID_FILE_FOR_SECTION;
+    }
+
+    /*
+     * Lock the file
+     */
+    Status = MmspWaitForFileLock(FileObject);
+    if (Status != STATUS_SUCCESS)
+    {
+        ObDereferenceObject(Section);
+        ObDereferenceObject(FileObject);
+        return(Status);
+    }
+
+    /*
+     * If this file hasn't been mapped as a data file before then allocate a
+     * section segment to describe the data file mapping
+     */
+    if (FileObject->SectionObjectPointer->DataSectionObject == NULL)
+    {
+        Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
+                                        TAG_MM_SECTION_SEGMENT);
+        if (Segment == NULL)
+        {
+            //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
+            ObDereferenceObject(Section);
+            ObDereferenceObject(FileObject);
+            return(STATUS_NO_MEMORY);
+        }
+        Section->Segment = Segment;
+        Segment->ReferenceCount = 1;
+        ExInitializeFastMutex(&Segment->Lock);
+        /*
+         * Set the lock before assigning the segment to the file object
+         */
+        ExAcquireFastMutex(&Segment->Lock);
+        FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
+
+        Segment->Image.FileOffset = 0;
+        Segment->Protection = SectionPageProtection;
+        Segment->Flags = MM_DATAFILE_SEGMENT;
+        Segment->Image.Characteristics = 0;
+        Segment->WriteCopy = (SectionPageProtection & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY));
+        if (AllocationAttributes & SEC_RESERVE)
+        {
+            Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
+        }
+        else
+        {
+            Segment->RawLength.QuadPart = MaximumSize.QuadPart;
+            Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
+        }
+        Segment->Image.VirtualAddress = 0;
+        Segment->Locked = TRUE;
+        MiInitializeSectionPageTable(Segment);
+    }
+    else
+    {
+        /*
+         * If the file is already mapped as a data file then we may need
+         * to extend it
+         */
+        Segment =
+            (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
+            DataSectionObject;
+        Section->Segment = Segment;
+        (void)InterlockedIncrementUL(&Segment->ReferenceCount);
+        MmLockSectionSegment(Segment);
+
+        if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
+                !(AllocationAttributes & SEC_RESERVE))
+        {
+            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);
+    CcRosReferenceCache(FileObject);
 #endif
-   //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
-   *SectionObject = Section;
-   return(STATUS_SUCCESS);
+    //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
+    *SectionObject = Section;
+    return(STATUS_SUCCESS);
 }
 
 /*
@@ -3116,36 +3103,31 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
 */
 extern 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
   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
 );
 
 extern NTSTATUS NTAPI ElfFmtCreateSection
 (
- 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
   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
 );
 
-/* TODO: this is a standard DDK/PSDK macro */
-#ifndef RTL_NUMBER_OF
-#define RTL_NUMBER_OF(ARR_) (sizeof(ARR_) / sizeof((ARR_)[0]))
-#endif
-
 static PEXEFMT_LOADER ExeFmtpLoaders[] =
 {
- PeFmtCreateSection,
   PeFmtCreateSection,
 #ifdef __ELF
- ElfFmtCreateSection
   ElfFmtCreateSection
 #endif
 };
 
@@ -3154,20 +3136,20 @@ PMM_SECTION_SEGMENT
 NTAPI
 ExeFmtpAllocateSegments(IN ULONG NrSegments)
 {
- SIZE_T SizeOfSegments;
- PMM_SECTION_SEGMENT Segments;
   SIZE_T SizeOfSegments;
   PMM_SECTION_SEGMENT Segments;
 
- /* TODO: check for integer overflow */
- SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
   /* TODO: check for integer overflow */
   SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
 
- Segments = ExAllocatePoolWithTag(NonPagedPool,
-                                  SizeOfSegments,
-                                  TAG_MM_SECTION_SEGMENT);
   Segments = ExAllocatePoolWithTag(NonPagedPool,
+                                     SizeOfSegments,
+                                     TAG_MM_SECTION_SEGMENT);
 
- if(Segments)
-  RtlZeroMemory(Segments, SizeOfSegments);
   if(Segments)
+        RtlZeroMemory(Segments, SizeOfSegments);
 
- return Segments;
   return Segments;
 }
 
 static
@@ -3180,76 +3162,82 @@ ExeFmtpReadFile(IN PVOID File,
                 OUT PVOID * AllocBase,
                 OUT PULONG ReadSize)
 {
-   NTSTATUS Status;
-   LARGE_INTEGER FileOffset;
-   ULONG AdjustOffset;
-   ULONG OffsetAdjustment;
-   ULONG BufferSize;
-   ULONG UsedSize;
-   PVOID Buffer;
-   PFILE_OBJECT FileObject = File;
-   IO_STATUS_BLOCK Iosb;
-
-   ASSERT_IRQL_LESS(DISPATCH_LEVEL);
-
-   if(Length == 0)
-   {
-      KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
-   FileOffset = *Offset;
-
-   /* Negative/special offset: it cannot be used in this context */
-   if(FileOffset.u.HighPart < 0)
-   {
-      KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
-   AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
-   OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
-   FileOffset.u.LowPart = AdjustOffset;
-
-   BufferSize = Length + OffsetAdjustment;
-   BufferSize = PAGE_ROUND_UP(BufferSize);
-
-   /*
-    * It's ok to use paged pool, because this is a temporary buffer only used in
-    * the loading of executables. The assumption is that MmCreateSection is
-    * always called at low IRQLs and that these buffers don't survive a brief
-    * initialization phase
-    */
-   Buffer = ExAllocatePoolWithTag(PagedPool,
-                                  BufferSize,
-                                  'rXmM');
-   if (!Buffer)
-   {
-      KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
-   UsedSize = 0;
-
-   Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb);
-
-   UsedSize = (ULONG)Iosb.Information;
-
-   if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
-   {
-      Status = STATUS_IN_PAGE_ERROR;
-      ASSERT(!NT_SUCCESS(Status));
-   }
-
-   if(NT_SUCCESS(Status))
-   {
-      *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
-      *AllocBase = Buffer;
-      *ReadSize = UsedSize - OffsetAdjustment;
-   }
-   else
-   {
-      ExFreePoolWithTag(Buffer, 'rXmM');
-   }
-
-   return Status;
+    NTSTATUS Status;
+    LARGE_INTEGER FileOffset;
+    ULONG AdjustOffset;
+    ULONG OffsetAdjustment;
+    ULONG BufferSize;
+    ULONG UsedSize;
+    PVOID Buffer;
+    PFILE_OBJECT FileObject = File;
+    IO_STATUS_BLOCK Iosb;
+
+    ASSERT_IRQL_LESS(DISPATCH_LEVEL);
+
+    if(Length == 0)
+    {
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+
+    FileOffset = *Offset;
+
+    /* Negative/special offset: it cannot be used in this context */
+    if(FileOffset.u.HighPart < 0)
+    {
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+
+    AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
+    OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
+    FileOffset.u.LowPart = AdjustOffset;
+
+    BufferSize = Length + OffsetAdjustment;
+    BufferSize = PAGE_ROUND_UP(BufferSize);
+
+    /* Flush data since we're about to perform a non-cached read */
+    CcFlushCache(FileObject->SectionObjectPointer,
+                 &FileOffset,
+                 BufferSize,
+                 &Iosb);
+
+    /*
+     * It's ok to use paged pool, because this is a temporary buffer only used in
+     * the loading of executables. The assumption is that MmCreateSection is
+     * always called at low IRQLs and that these buffers don't survive a brief
+     * initialization phase
+     */
+    Buffer = ExAllocatePoolWithTag(PagedPool,
+                                   BufferSize,
+                                   'rXmM');
+    if (!Buffer)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    UsedSize = 0;
+
+    Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb);
+
+    UsedSize = (ULONG)Iosb.Information;
+
+    if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
+    {
+        Status = STATUS_IN_PAGE_ERROR;
+        ASSERT(!NT_SUCCESS(Status));
+    }
+
+    if(NT_SUCCESS(Status))
+    {
+        *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
+        *AllocBase = Buffer;
+        *ReadSize = UsedSize - OffsetAdjustment;
+    }
+    else
+    {
+        ExFreePoolWithTag(Buffer, 'rXmM');
+    }
+
+    return Status;
 }
 
 #ifdef NASSERT
@@ -3262,13 +3250,13 @@ VOID
 NTAPI
 MmspAssertSegmentsSorted(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 {
-   ULONG i;
+    ULONG i;
 
-   for( i = 1; i < ImageSectionObject->NrSegments; ++ i )
-   {
-      ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >=
-             ImageSectionObject->Segments[i - 1].Image.VirtualAddress);
-   }
+    for( i = 1; i < ImageSectionObject->NrSegments; ++ i )
+    {
+        ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >=
+               ImageSectionObject->Segments[i - 1].Image.VirtualAddress);
+    }
 }
 
 static
@@ -3276,21 +3264,21 @@ VOID
 NTAPI
 MmspAssertSegmentsNoOverlap(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 {
-   ULONG i;
+    ULONG i;
 
-   MmspAssertSegmentsSorted(ImageSectionObject);
+    MmspAssertSegmentsSorted(ImageSectionObject);
 
-   for( i = 0; i < ImageSectionObject->NrSegments; ++ i )
-   {
-      ASSERT(ImageSectionObject->Segments[i].Length.QuadPart > 0);
+    for( i = 0; i < ImageSectionObject->NrSegments; ++ i )
+    {
+        ASSERT(ImageSectionObject->Segments[i].Length.QuadPart > 0);
 
-      if(i > 0)
-      {
-         ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >=
-                (ImageSectionObject->Segments[i - 1].Image.VirtualAddress +
-                 ImageSectionObject->Segments[i - 1].Length.QuadPart));
-      }
-   }
+        if(i > 0)
+        {
+            ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >=
+                   (ImageSectionObject->Segments[i - 1].Image.VirtualAddress +
+                    ImageSectionObject->Segments[i - 1].Length.QuadPart));
+        }
+    }
 }
 
 static
@@ -3298,13 +3286,13 @@ VOID
 NTAPI
 MmspAssertSegmentsPageAligned(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 {
-   ULONG i;
+    ULONG i;
 
-   for( i = 0; i < ImageSectionObject->NrSegments; ++ i )
-   {
-      ASSERT((ImageSectionObject->Segments[i].Image.VirtualAddress % PAGE_SIZE) == 0);
-      ASSERT((ImageSectionObject->Segments[i].Length.QuadPart % PAGE_SIZE) == 0);
-   }
+    for( i = 0; i < ImageSectionObject->NrSegments; ++ i )
+    {
+        ASSERT((ImageSectionObject->Segments[i].Image.VirtualAddress % PAGE_SIZE) == 0);
+        ASSERT((ImageSectionObject->Segments[i].Length.QuadPart % PAGE_SIZE) == 0);
+    }
 }
 #endif
 
@@ -3314,12 +3302,12 @@ __cdecl
 MmspCompareSegments(const void * x,
                     const void * y)
 {
-   const MM_SECTION_SEGMENT *Segment1 = (const MM_SECTION_SEGMENT *)x;
-   const MM_SECTION_SEGMENT *Segment2 = (const MM_SECTION_SEGMENT *)y;
+    const MM_SECTION_SEGMENT *Segment1 = (const MM_SECTION_SEGMENT *)x;
+    const MM_SECTION_SEGMENT *Segment2 = (const MM_SECTION_SEGMENT *)y;
 
-   return
-      (Segment1->Image.VirtualAddress - Segment2->Image.VirtualAddress) >>
-      ((sizeof(ULONG_PTR) - sizeof(int)) * 8);
+    return
+        (Segment1->Image.VirtualAddress - Segment2->Image.VirtualAddress) >>
+        ((sizeof(ULONG_PTR) - sizeof(int)) * 8);
 }
 
 /*
@@ -3331,17 +3319,17 @@ NTAPI
 MmspSortSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
                  IN ULONG Flags)
 {
-   if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED)
-   {
-      MmspAssertSegmentsSorted(ImageSectionObject);
-   }
-   else
-   {
-      qsort(ImageSectionObject->Segments,
-            ImageSectionObject->NrSegments,
-            sizeof(ImageSectionObject->Segments[0]),
-            MmspCompareSegments);
-   }
+    if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED)
+    {
+        MmspAssertSegmentsSorted(ImageSectionObject);
+    }
+    else
+    {
+        qsort(ImageSectionObject->Segments,
+              ImageSectionObject->NrSegments,
+              sizeof(ImageSectionObject->Segments[0]),
+              MmspCompareSegments);
+    }
 }
 
 
@@ -3355,46 +3343,46 @@ BOOLEAN
 NTAPI
 MmspCheckSegmentBounds
 (
- IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
- IN ULONG Flags
   IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
   IN ULONG Flags
 )
 {
-   ULONG i;
-
-   if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP)
-   {
-      MmspAssertSegmentsNoOverlap(ImageSectionObject);
-      return TRUE;
-   }
-
-   ASSERT(ImageSectionObject->NrSegments >= 1);
-
-   for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
-   {
-      if(ImageSectionObject->Segments[i].Length.QuadPart == 0)
-      {
-         return FALSE;
-      }
-
-      if(i > 0)
-      {
-         /*
-          * TODO: relax the limitation on gaps. For example, gaps smaller than a
-          * page could be OK (Windows seems to be OK with them), and larger gaps
-          * could lead to image sections spanning several discontiguous regions
-          * (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].Image.VirtualAddress +
-              ImageSectionObject->Segments[i - 1].Length.QuadPart) !=
-              ImageSectionObject->Segments[i].Image.VirtualAddress)
-         {
+    ULONG i;
+
+    if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP)
+    {
+        MmspAssertSegmentsNoOverlap(ImageSectionObject);
+        return TRUE;
+    }
+
+    ASSERT(ImageSectionObject->NrSegments >= 1);
+
+    for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
+    {
+        if(ImageSectionObject->Segments[i].Length.QuadPart == 0)
+        {
             return FALSE;
-         }
-      }
-   }
+        }
+
+        if(i > 0)
+        {
+            /*
+             * TODO: relax the limitation on gaps. For example, gaps smaller than a
+             * page could be OK (Windows seems to be OK with them), and larger gaps
+             * could lead to image sections spanning several discontiguous regions
+             * (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].Image.VirtualAddress +
+                    ImageSectionObject->Segments[i - 1].Length.QuadPart) !=
+                    ImageSectionObject->Segments[i].Image.VirtualAddress)
+            {
+                return FALSE;
+            }
+        }
+    }
 
-   return TRUE;
+    return TRUE;
 }
 
 /*
@@ -3406,334 +3394,332 @@ BOOLEAN
 NTAPI
 MmspPageAlignSegments
 (
- IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
- IN ULONG Flags
   IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
   IN ULONG Flags
 )
 {
-   ULONG i;
-   ULONG LastSegment;
-   PMM_SECTION_SEGMENT EffectiveSegment;
-
-   if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED)
-   {
-      MmspAssertSegmentsPageAligned(ImageSectionObject);
-      return TRUE;
-   }
-
-   LastSegment = 0;
-   EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
-
-   for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
-   {
-      /*
-       * The first segment requires special handling
-       */
-      if (i == 0)
-      {
-         ULONG_PTR VirtualAddress;
-         ULONG_PTR VirtualOffset;
-
-         VirtualAddress = EffectiveSegment->Image.VirtualAddress;
-
-         /* Round down the virtual address to the nearest page */
-         EffectiveSegment->Image.VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress);
-
-         /* Round up the virtual size to the nearest page */
-         EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length.QuadPart) -
-                                    EffectiveSegment->Image.VirtualAddress;
-
-         /* Adjust the raw address and size */
-         VirtualOffset = VirtualAddress - EffectiveSegment->Image.VirtualAddress;
-
-         if (EffectiveSegment->Image.FileOffset < VirtualOffset)
-         {
-            return FALSE;
-         }
-
-         /*
-          * Garbage in, garbage out: unaligned base addresses make the file
-          * offset point in curious and odd places, but that's what we were
-          * asked for
-          */
-         EffectiveSegment->Image.FileOffset -= VirtualOffset;
-         EffectiveSegment->RawLength.QuadPart += VirtualOffset;
-      }
-      else
-      {
-         PMM_SECTION_SEGMENT Segment = &ImageSectionObject->Segments[i];
-         ULONG_PTR EndOfEffectiveSegment;
-
-         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->Image.VirtualAddress)
-         {
-            LastSegment ++;
-            ASSERT(LastSegment <= i);
-            ASSERT(LastSegment < ImageSectionObject->NrSegments);
-
-            EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
-
-            if (LastSegment != i)
+    ULONG i;
+    ULONG LastSegment;
+    PMM_SECTION_SEGMENT EffectiveSegment;
+
+    if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED)
+    {
+        MmspAssertSegmentsPageAligned(ImageSectionObject);
+        return TRUE;
+    }
+
+    LastSegment = 0;
+    EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
+
+    for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
+    {
+        /*
+         * The first segment requires special handling
+         */
+        if (i == 0)
+        {
+            ULONG_PTR VirtualAddress;
+            ULONG_PTR VirtualOffset;
+
+            VirtualAddress = EffectiveSegment->Image.VirtualAddress;
+
+            /* Round down the virtual address to the nearest page */
+            EffectiveSegment->Image.VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress);
+
+            /* Round up the virtual size to the nearest page */
+            EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length.QuadPart) -
+                                                EffectiveSegment->Image.VirtualAddress;
+
+            /* Adjust the raw address and size */
+            VirtualOffset = VirtualAddress - EffectiveSegment->Image.VirtualAddress;
+
+            if (EffectiveSegment->Image.FileOffset < VirtualOffset)
             {
-               /*
-                * Copy the current segment. If necessary, the effective segment
-                * will be expanded later
-                */
-               *EffectiveSegment = *Segment;
+                return FALSE;
             }
 
             /*
-             * Page-align the virtual size. We know for sure the virtual address
-             * already is
+             * Garbage in, garbage out: unaligned base addresses make the file
+             * offset point in curious and odd places, but that's what we were
+             * asked for
              */
-            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->Image.VirtualAddress)
-         {
-            static const ULONG FlagsToProtection[16] =
-            {
-               PAGE_NOACCESS,
-               PAGE_READONLY,
-               PAGE_READWRITE,
-               PAGE_READWRITE,
-               PAGE_EXECUTE_READ,
-               PAGE_EXECUTE_READ,
-               PAGE_EXECUTE_READWRITE,
-               PAGE_EXECUTE_READWRITE,
-               PAGE_WRITECOPY,
-               PAGE_WRITECOPY,
-               PAGE_WRITECOPY,
-               PAGE_WRITECOPY,
-               PAGE_EXECUTE_WRITECOPY,
-               PAGE_EXECUTE_WRITECOPY,
-               PAGE_EXECUTE_WRITECOPY,
-               PAGE_EXECUTE_WRITECOPY
-            };
-
-            unsigned ProtectionFlags;
+            EffectiveSegment->Image.FileOffset -= VirtualOffset;
+            EffectiveSegment->RawLength.QuadPart += VirtualOffset;
+        }
+        else
+        {
+            PMM_SECTION_SEGMENT Segment = &ImageSectionObject->Segments[i];
+            ULONG_PTR EndOfEffectiveSegment;
+
+            EndOfEffectiveSegment = (ULONG_PTR)(EffectiveSegment->Image.VirtualAddress + EffectiveSegment->Length.QuadPart);
+            ASSERT((EndOfEffectiveSegment % PAGE_SIZE) == 0);
 
             /*
-             * Extend the file size
+             * The current segment begins exactly where the current effective
+             * segment ended, therefore beginning a new effective segment
              */
-
-            /* Unaligned segments must be contiguous within the file */
-            if (Segment->Image.FileOffset != (EffectiveSegment->Image.FileOffset +
-                                        EffectiveSegment->RawLength.QuadPart))
+            if (EndOfEffectiveSegment == Segment->Image.VirtualAddress)
             {
-               return FALSE;
-            }
+                LastSegment ++;
+                ASSERT(LastSegment <= i);
+                ASSERT(LastSegment < ImageSectionObject->NrSegments);
 
-            EffectiveSegment->RawLength.QuadPart += Segment->RawLength.QuadPart;
+                EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
+
+                if (LastSegment != i)
+                {
+                    /*
+                     * Copy the current segment. If necessary, the effective segment
+                     * will be expanded later
+                     */
+                    *EffectiveSegment = *Segment;
+                }
 
+                /*
+                 * Page-align the virtual size. We know for sure the virtual address
+                 * already is
+                 */
+                ASSERT((EffectiveSegment->Image.VirtualAddress % PAGE_SIZE) == 0);
+                EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(EffectiveSegment->Length.QuadPart);
+            }
             /*
-             * Extend the virtual size
+             * The current segment is still part of the current effective segment:
+             * extend the effective segment to reflect this
              */
-            ASSERT(PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) >= EndOfEffectiveSegment);
+            else if (EndOfEffectiveSegment > Segment->Image.VirtualAddress)
+            {
+                static const ULONG FlagsToProtection[16] =
+                {
+                    PAGE_NOACCESS,
+                    PAGE_READONLY,
+                    PAGE_READWRITE,
+                    PAGE_READWRITE,
+                    PAGE_EXECUTE_READ,
+                    PAGE_EXECUTE_READ,
+                    PAGE_EXECUTE_READWRITE,
+                    PAGE_EXECUTE_READWRITE,
+                    PAGE_WRITECOPY,
+                    PAGE_WRITECOPY,
+                    PAGE_WRITECOPY,
+                    PAGE_WRITECOPY,
+                    PAGE_EXECUTE_WRITECOPY,
+                    PAGE_EXECUTE_WRITECOPY,
+                    PAGE_EXECUTE_WRITECOPY,
+                    PAGE_EXECUTE_WRITECOPY
+                };
+
+                unsigned ProtectionFlags;
 
-            EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) -
-                                       EffectiveSegment->Image.VirtualAddress;
+                /*
+                 * Extend the file size
+                 */
 
-            /*
-             * Merge the protection
-             */
-            EffectiveSegment->Protection |= Segment->Protection;
+                /* Unaligned segments must be contiguous within the file */
+                if (Segment->Image.FileOffset != (EffectiveSegment->Image.FileOffset +
+                                                  EffectiveSegment->RawLength.QuadPart))
+                {
+                    return FALSE;
+                }
 
-            /* Clean up redundance */
-            ProtectionFlags = 0;
+                EffectiveSegment->RawLength.QuadPart += Segment->RawLength.QuadPart;
 
-            if(EffectiveSegment->Protection & PAGE_IS_READABLE)
-               ProtectionFlags |= 1 << 0;
+                /*
+                 * Extend the virtual size
+                 */
+                ASSERT(PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) >= EndOfEffectiveSegment);
+
+                EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) -
+                                                    EffectiveSegment->Image.VirtualAddress;
+
+                /*
+                 * Merge the protection
+                 */
+                EffectiveSegment->Protection |= Segment->Protection;
+
+                /* Clean up redundance */
+                ProtectionFlags = 0;
+
+                if(EffectiveSegment->Protection & PAGE_IS_READABLE)
+                    ProtectionFlags |= 1 << 0;
 
-            if(EffectiveSegment->Protection & PAGE_IS_WRITABLE)
-               ProtectionFlags |= 1 << 1;
+                if(EffectiveSegment->Protection & PAGE_IS_WRITABLE)
+                    ProtectionFlags |= 1 << 1;
 
-            if(EffectiveSegment->Protection & PAGE_IS_EXECUTABLE)
-               ProtectionFlags |= 1 << 2;
+                if(EffectiveSegment->Protection & PAGE_IS_EXECUTABLE)
+                    ProtectionFlags |= 1 << 2;
 
-            if(EffectiveSegment->Protection & PAGE_IS_WRITECOPY)
-               ProtectionFlags |= 1 << 3;
+                if(EffectiveSegment->Protection & PAGE_IS_WRITECOPY)
+                    ProtectionFlags |= 1 << 3;
 
-            ASSERT(ProtectionFlags < 16);
-            EffectiveSegment->Protection = FlagsToProtection[ProtectionFlags];
+                ASSERT(ProtectionFlags < 16);
+                EffectiveSegment->Protection = FlagsToProtection[ProtectionFlags];
 
-            /* If a segment was required to be shared and cannot, fail */
-            if(!(Segment->Protection & PAGE_IS_WRITECOPY) &&
-               EffectiveSegment->Protection & PAGE_IS_WRITECOPY)
+                /* If a segment was required to be shared and cannot, fail */
+                if(!(Segment->Protection & PAGE_IS_WRITECOPY) &&
+                        EffectiveSegment->Protection & PAGE_IS_WRITECOPY)
+                {
+                    return FALSE;
+                }
+            }
+            /*
+             * We assume no holes between segments at this point
+             */
+            else
             {
-               return FALSE;
+                KeBugCheck(MEMORY_MANAGEMENT);
             }
-         }
-         /*
-          * We assume no holes between segments at this point
-          */
-         else
-         {
-            KeBugCheck(MEMORY_MANAGEMENT);
-         }
-      }
-   }
-   ImageSectionObject->NrSegments = LastSegment + 1;
+        }
+    }
+    ImageSectionObject->NrSegments = LastSegment + 1;
 
-   return TRUE;
+    return TRUE;
 }
 
 NTSTATUS
-ExeFmtpCreateImageSection(HANDLE FileHandle,
+ExeFmtpCreateImageSection(PFILE_OBJECT FileObject,
                           PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 {
-   LARGE_INTEGER Offset;
-   PVOID FileHeader;
-   PVOID FileHeaderBuffer;
-   ULONG FileHeaderSize;
-   ULONG Flags;
-   ULONG OldNrSegments;
-   NTSTATUS Status;
-   ULONG i;
-
-   /*
-    * Read the beginning of the file (2 pages). Should be enough to contain
-    * all (or most) of the headers
-    */
-   Offset.QuadPart = 0;
-
-   /* FIXME: use FileObject instead of FileHandle */
-   Status = ExeFmtpReadFile (FileHandle,
-                             &Offset,
-                             PAGE_SIZE * 2,
-                             &FileHeader,
-                             &FileHeaderBuffer,
-                             &FileHeaderSize);
-
-   if (!NT_SUCCESS(Status))
-      return Status;
-
-   if (FileHeaderSize == 0)
-   {
-      ExFreePool(FileHeaderBuffer);
-      return STATUS_UNSUCCESSFUL;
-   }
-
-   /*
-    * Look for a loader that can handle this executable
-    */
-   for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
-   {
-      RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject));
-      Flags = 0;
-
-      /* FIXME: use FileObject instead of FileHandle */
-      Status = ExeFmtpLoaders[i](FileHeader,
-                                 FileHeaderSize,
-                                 FileHandle,
-                                 ImageSectionObject,
-                                 &Flags,
-                                 ExeFmtpReadFile,
-                                 ExeFmtpAllocateSegments);
-
-      if (!NT_SUCCESS(Status))
-      {
-         if (ImageSectionObject->Segments)
-         {
-            ExFreePool(ImageSectionObject->Segments);
-            ImageSectionObject->Segments = NULL;
-         }
-      }
-
-      if (Status != STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
-         break;
-   }
-
-   ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
-
-   /*
-    * No loader handled the format
-    */
-   if (Status == STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
-   {
-      Status = STATUS_INVALID_IMAGE_NOT_MZ;
-      ASSERT(!NT_SUCCESS(Status));
-   }
-
-   if (!NT_SUCCESS(Status))
-      return Status;
-
-   ASSERT(ImageSectionObject->Segments != NULL);
-
-   /*
-    * Some defaults
-    */
-   /* FIXME? are these values platform-dependent? */
-   if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
-       ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
-
-   if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
-       ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
-
-   if(ImageSectionObject->BasedAddress == NULL)
-   {
-      if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
-         ImageSectionObject->BasedAddress = (PVOID)0x10000000;
-      else
-         ImageSectionObject->BasedAddress = (PVOID)0x00400000;
-   }
-
-   /*
-    * And now the fun part: fixing the segments
-    */
-
-   /* Sort them by virtual address */
-   MmspSortSegments(ImageSectionObject, Flags);
-
-   /* Ensure they don't overlap in memory */
-   if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
-      return STATUS_INVALID_IMAGE_FORMAT;
-
-   /* Ensure they are aligned */
-   OldNrSegments = ImageSectionObject->NrSegments;
-
-   if (!MmspPageAlignSegments(ImageSectionObject, Flags))
-      return STATUS_INVALID_IMAGE_FORMAT;
-
-   /* Trim them if the alignment phase merged some of them */
-   if (ImageSectionObject->NrSegments < OldNrSegments)
-   {
-      PMM_SECTION_SEGMENT Segments;
-      SIZE_T SizeOfSegments;
-
-      SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
-
-      Segments = ExAllocatePoolWithTag(PagedPool,
-                                       SizeOfSegments,
-                                       TAG_MM_SECTION_SEGMENT);
-
-      if (Segments == NULL)
-         return STATUS_INSUFFICIENT_RESOURCES;
-
-      RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
-      ExFreePool(ImageSectionObject->Segments);
-      ImageSectionObject->Segments = Segments;
-   }
-
-   /* And finish their initialization */
-   for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
-   {
-      ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
-      ImageSectionObject->Segments[i].ReferenceCount = 1;
-      MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
-   }
-
-   ASSERT(NT_SUCCESS(Status));
-   return Status;
+    LARGE_INTEGER Offset;
+    PVOID FileHeader;
+    PVOID FileHeaderBuffer;
+    ULONG FileHeaderSize;
+    ULONG Flags;
+    ULONG OldNrSegments;
+    NTSTATUS Status;
+    ULONG i;
+
+    /*
+     * Read the beginning of the file (2 pages). Should be enough to contain
+     * all (or most) of the headers
+     */
+    Offset.QuadPart = 0;
+
+    Status = ExeFmtpReadFile (FileObject,
+                              &Offset,
+                              PAGE_SIZE * 2,
+                              &FileHeader,
+                              &FileHeaderBuffer,
+                              &FileHeaderSize);
+
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    if (FileHeaderSize == 0)
+    {
+        ExFreePool(FileHeaderBuffer);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /*
+     * Look for a loader that can handle this executable
+     */
+    for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
+    {
+        RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject));
+        Flags = 0;
+
+        Status = ExeFmtpLoaders[i](FileHeader,
+                                   FileHeaderSize,
+                                   FileObject,
+                                   ImageSectionObject,
+                                   &Flags,
+                                   ExeFmtpReadFile,
+                                   ExeFmtpAllocateSegments);
+
+        if (!NT_SUCCESS(Status))
+        {
+            if (ImageSectionObject->Segments)
+            {
+                ExFreePool(ImageSectionObject->Segments);
+                ImageSectionObject->Segments = NULL;
+            }
+        }
+
+        if (Status != STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
+            break;
+    }
+
+    ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
+
+    /*
+     * No loader handled the format
+     */
+    if (Status == STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
+    {
+        Status = STATUS_INVALID_IMAGE_NOT_MZ;
+        ASSERT(!NT_SUCCESS(Status));
+    }
+
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    ASSERT(ImageSectionObject->Segments != NULL);
+
+    /*
+     * Some defaults
+     */
+    /* FIXME? are these values platform-dependent? */
+    if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
+        ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
+
+    if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
+        ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
+
+    if(ImageSectionObject->BasedAddress == NULL)
+    {
+        if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
+            ImageSectionObject->BasedAddress = (PVOID)0x10000000;
+        else
+            ImageSectionObject->BasedAddress = (PVOID)0x00400000;
+    }
+
+    /*
+     * And now the fun part: fixing the segments
+     */
+
+    /* Sort them by virtual address */
+    MmspSortSegments(ImageSectionObject, Flags);
+
+    /* Ensure they don't overlap in memory */
+    if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
+        return STATUS_INVALID_IMAGE_FORMAT;
+
+    /* Ensure they are aligned */
+    OldNrSegments = ImageSectionObject->NrSegments;
+
+    if (!MmspPageAlignSegments(ImageSectionObject, Flags))
+        return STATUS_INVALID_IMAGE_FORMAT;
+
+    /* Trim them if the alignment phase merged some of them */
+    if (ImageSectionObject->NrSegments < OldNrSegments)
+    {
+        PMM_SECTION_SEGMENT Segments;
+        SIZE_T SizeOfSegments;
+
+        SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
+
+        Segments = ExAllocatePoolWithTag(PagedPool,
+                                         SizeOfSegments,
+                                         TAG_MM_SECTION_SEGMENT);
+
+        if (Segments == NULL)
+            return STATUS_INSUFFICIENT_RESOURCES;
+
+        RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
+        ExFreePool(ImageSectionObject->Segments);
+        ImageSectionObject->Segments = Segments;
+    }
+
+    /* And finish their initialization */
+    for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
+    {
+        ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
+        ImageSectionObject->Segments[i].ReferenceCount = 1;
+        MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
+    }
+
+    ASSERT(NT_SUCCESS(Status));
+    return Status;
 }
 
 NTSTATUS
@@ -3745,149 +3731,166 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
                      ULONG AllocationAttributes,
                      PFILE_OBJECT FileObject)
 {
-   PROS_SECTION_OBJECT Section;
-   NTSTATUS Status;
-   PMM_SECTION_SEGMENT SectionSegments;
-   PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
-   ULONG i;
-
-   if (FileObject == NULL)
-      return STATUS_INVALID_FILE_FOR_SECTION;
-
-   /*
-    * Create the section
-    */
-   Status = ObCreateObject (ExGetPreviousMode(),
-                            MmSectionObjectType,
-                            ObjectAttributes,
-                            ExGetPreviousMode(),
-                            NULL,
-                            sizeof(ROS_SECTION_OBJECT),
-                            0,
-                            0,
-                            (PVOID*)(PVOID)&Section);
-   if (!NT_SUCCESS(Status))
-   {
-      ObDereferenceObject(FileObject);
-      return(Status);
-   }
-
-   /*
-    * Initialize it
-    */
-   RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
-   Section->Type = 'SC';
-   Section->Size = 'TN';
-   Section->SectionPageProtection = SectionPageProtection;
-   Section->AllocationAttributes = AllocationAttributes;
+    PROS_SECTION_OBJECT Section;
+    NTSTATUS Status;
+    PMM_SECTION_SEGMENT SectionSegments;
+    PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
+    ULONG i;
+
+    if (FileObject == NULL)
+        return STATUS_INVALID_FILE_FOR_SECTION;
+
+#ifndef NEWCC
+    if (FileObject->SectionObjectPointer->SharedCacheMap == NULL)
+    {
+        DPRINT1("Denying section creation due to missing cache initialization\n");
+        return STATUS_INVALID_FILE_FOR_SECTION;
+    }
+#endif
+
+    /*
+     * Create the section
+     */
+    Status = ObCreateObject (ExGetPreviousMode(),
+                             MmSectionObjectType,
+                             ObjectAttributes,
+                             ExGetPreviousMode(),
+                             NULL,
+                             sizeof(ROS_SECTION_OBJECT),
+                             0,
+                             0,
+                             (PVOID*)(PVOID)&Section);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(FileObject);
+        return(Status);
+    }
+
+    /*
+     * 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);
+    /*
+     * Initialized caching for this file object if previously caching
+     * was initialized for the same on disk file
+     */
+    Status = CcTryToInitializeFileCache(FileObject);
 #else
-   Status = STATUS_SUCCESS;
+    Status = STATUS_SUCCESS;
 #endif
 
-   if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL)
-   {
-      NTSTATUS StatusExeFmt;
+    if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL)
+    {
+        NTSTATUS StatusExeFmt;
+
+        ImageSectionObject = ExAllocatePoolWithTag(PagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT);
+        if (ImageSectionObject == NULL)
+        {
+            ObDereferenceObject(FileObject);
+            ObDereferenceObject(Section);
+            return(STATUS_NO_MEMORY);
+        }
+
+        RtlZeroMemory(ImageSectionObject, sizeof(MM_IMAGE_SECTION_OBJECT));
+
+        StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
+
+        if (!NT_SUCCESS(StatusExeFmt))
+        {
+            if(ImageSectionObject->Segments != NULL)
+                ExFreePool(ImageSectionObject->Segments);
+
+            /*
+             * If image file is empty, then return that the file is invalid for section
+             */
+            Status = StatusExeFmt;
+            if (StatusExeFmt == STATUS_END_OF_FILE)
+            {
+                Status = STATUS_INVALID_FILE_FOR_SECTION;
+            }
 
-      ImageSectionObject = ExAllocatePoolWithTag(PagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT);
-      if (ImageSectionObject == NULL)
-      {
-         ObDereferenceObject(FileObject);
-         ObDereferenceObject(Section);
-         return(STATUS_NO_MEMORY);
-      }
+            ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
+            ObDereferenceObject(Section);
+            ObDereferenceObject(FileObject);
+            return(Status);
+        }
 
-      RtlZeroMemory(ImageSectionObject, sizeof(MM_IMAGE_SECTION_OBJECT));
+        Section->ImageSection = ImageSectionObject;
+        ASSERT(ImageSectionObject->Segments);
 
-      StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
+        /*
+         * Lock the file
+         */
+        Status = MmspWaitForFileLock(FileObject);
+        if (!NT_SUCCESS(Status))
+        {
+            ExFreePool(ImageSectionObject->Segments);
+            ExFreePool(ImageSectionObject);
+            ObDereferenceObject(Section);
+            ObDereferenceObject(FileObject);
+            return(Status);
+        }
 
-      if (!NT_SUCCESS(StatusExeFmt))
-      {
-         if(ImageSectionObject->Segments != NULL)
+        if (NULL != InterlockedCompareExchangePointer(&FileObject->SectionObjectPointer->ImageSectionObject,
+                ImageSectionObject, NULL))
+        {
+            /*
+             * An other thread has initialized the same image in the background
+             */
             ExFreePool(ImageSectionObject->Segments);
+            ExFreePool(ImageSectionObject);
+            ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
+            Section->ImageSection = ImageSectionObject;
+            SectionSegments = ImageSectionObject->Segments;
+
+            for (i = 0; i < ImageSectionObject->NrSegments; i++)
+            {
+                (void)InterlockedIncrementUL(&SectionSegments[i].ReferenceCount);
+            }
+        }
+
+        Status = StatusExeFmt;
+    }
+    else
+    {
+        /*
+         * Lock the file
+         */
+        Status = MmspWaitForFileLock(FileObject);
+        if (Status != STATUS_SUCCESS)
+        {
+            ObDereferenceObject(Section);
+            ObDereferenceObject(FileObject);
+            return(Status);
+        }
+
+        ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
+        Section->ImageSection = ImageSectionObject;
+        SectionSegments = ImageSectionObject->Segments;
 
-         ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
-         ObDereferenceObject(Section);
-         ObDereferenceObject(FileObject);
-         return(StatusExeFmt);
-      }
-
-      Section->ImageSection = ImageSectionObject;
-      ASSERT(ImageSectionObject->Segments);
-
-      /*
-       * Lock the file
-       */
-      Status = MmspWaitForFileLock(FileObject);
-      if (!NT_SUCCESS(Status))
-      {
-         ExFreePool(ImageSectionObject->Segments);
-         ExFreePool(ImageSectionObject);
-         ObDereferenceObject(Section);
-         ObDereferenceObject(FileObject);
-         return(Status);
-      }
-
-      if (NULL != InterlockedCompareExchangePointer(&FileObject->SectionObjectPointer->ImageSectionObject,
-                                                    ImageSectionObject, NULL))
-      {
-         /*
-          * An other thread has initialized the same image in the background
-          */
-         ExFreePool(ImageSectionObject->Segments);
-         ExFreePool(ImageSectionObject);
-         ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
-         Section->ImageSection = ImageSectionObject;
-         SectionSegments = ImageSectionObject->Segments;
-
-         for (i = 0; i < ImageSectionObject->NrSegments; i++)
-         {
+        /*
+         * Otherwise just reference all the section segments
+         */
+        for (i = 0; i < ImageSectionObject->NrSegments; i++)
+        {
             (void)InterlockedIncrementUL(&SectionSegments[i].ReferenceCount);
-         }
-      }
-
-      Status = StatusExeFmt;
-   }
-   else
-   {
-      /*
-       * Lock the file
-       */
-      Status = MmspWaitForFileLock(FileObject);
-      if (Status != STATUS_SUCCESS)
-      {
-         ObDereferenceObject(Section);
-         ObDereferenceObject(FileObject);
-         return(Status);
-      }
-
-      ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
-      Section->ImageSection = ImageSectionObject;
-      SectionSegments = ImageSectionObject->Segments;
-
-      /*
-       * Otherwise just reference all the section segments
-       */
-      for (i = 0; i < ImageSectionObject->NrSegments; i++)
-      {
-         (void)InterlockedIncrementUL(&SectionSegments[i].ReferenceCount);
-      }
-
-      Status = STATUS_SUCCESS;
-   }
-   Section->FileObject = FileObject;
+        }
+
+        Status = STATUS_SUCCESS;
+    }
+    Section->FileObject = FileObject;
 #ifndef NEWCC
-   CcRosReferenceCache(FileObject);
+    CcRosReferenceCache(FileObject);
 #endif
-   //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
-   *SectionObject = Section;
-   return(Status);
+    //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
+    *SectionObject = Section;
+    return(Status);
 }
 
 
@@ -3902,65 +3905,70 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace,
                    ULONG ViewOffset,
                    ULONG AllocationType)
 {
-   PMEMORY_AREA MArea;
-   NTSTATUS Status;
-   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;
-   }
+    PMEMORY_AREA MArea;
+    NTSTATUS Status;
+    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;
+    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__);
-   }
+    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,
-                               Granularity);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("Mapping between 0x%p and 0x%p 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.QuadPart = ViewOffset;
-   MmInitializeRegion(&MArea->Data.SectionData.RegionListHead,
-                      ViewSize, 0, Protect);
-
-   return(STATUS_SUCCESS);
+    Status = MmCreateMemoryArea(AddressSpace,
+                                MEMORY_AREA_SECTION_VIEW,
+                                BaseAddress,
+                                ViewSize,
+                                Protect,
+                                &MArea,
+                                AllocationType,
+                                Granularity);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Mapping between 0x%p and 0x%p 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.QuadPart = ViewOffset;
+    if (Section->AllocationAttributes & SEC_IMAGE)
+    {
+        MArea->VadNode.u.VadFlags.VadType = VadImageMap;
+    }
+
+    MmInitializeRegion(&MArea->Data.SectionData.RegionListHead,
+                       ViewSize, 0, Protect);
+
+    return(STATUS_SUCCESS);
 }
 
 
@@ -3968,157 +3976,166 @@ static VOID
 MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
                   PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
 {
-   ULONG_PTR Entry;
-   PFILE_OBJECT FileObject;
-   PBCB Bcb;
-   LARGE_INTEGER Offset;
-   SWAPENTRY SavedSwapEntry;
-   PROS_SECTION_OBJECT Section;
-   PMM_SECTION_SEGMENT Segment;
-   PMMSUPPORT AddressSpace;
-   PEPROCESS Process;
-
-   AddressSpace = (PMMSUPPORT)Context;
-   Process = MmGetAddressSpaceOwner(AddressSpace);
-
-   Address = (PVOID)PAGE_ROUND_DOWN(Address);
-
-   Offset.QuadPart = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
-            MemoryArea->Data.SectionData.ViewOffset.QuadPart;
-
-   Section = MemoryArea->Data.SectionData.Section;
-   Segment = MemoryArea->Data.SectionData.Segment;
-
-   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-   while (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
-   {
-      MmUnlockSectionSegment(Segment);
-      MmUnlockAddressSpace(AddressSpace);
-
-      MiWaitForPageEvent(NULL, NULL);
-
-      MmLockAddressSpace(AddressSpace);
-      MmLockSectionSegment(Segment);
-      Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-   }
-
-   /*
-    * For a dirty, datafile, non-private page mark it as dirty in the
-    * cache manager.
-    */
-   if (Segment->Flags & MM_DATAFILE_SEGMENT)
-   {
-      if (Page == PFN_FROM_SSE(Entry) && Dirty)
-      {
-         FileObject = MemoryArea->Data.SectionData.Section->FileObject;
-         Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+    ULONG_PTR Entry;
+#ifndef NEWCC
+    PFILE_OBJECT FileObject;
+    PROS_SHARED_CACHE_MAP SharedCacheMap;
+#endif
+    LARGE_INTEGER Offset;
+    SWAPENTRY SavedSwapEntry;
+    PROS_SECTION_OBJECT Section;
+    PMM_SECTION_SEGMENT Segment;
+    PMMSUPPORT AddressSpace;
+    PEPROCESS Process;
+
+    AddressSpace = (PMMSUPPORT)Context;
+    Process = MmGetAddressSpaceOwner(AddressSpace);
+
+    Address = (PVOID)PAGE_ROUND_DOWN(Address);
+
+    Offset.QuadPart = ((ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)) +
+                      MemoryArea->Data.SectionData.ViewOffset.QuadPart;
+
+    Section = MemoryArea->Data.SectionData.Section;
+    Segment = MemoryArea->Data.SectionData.Segment;
+
+    Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+    while (Entry && MM_IS_WAIT_PTE(Entry))
+    {
+        MmUnlockSectionSegment(Segment);
+        MmUnlockAddressSpace(AddressSpace);
+
+        MiWaitForPageEvent(NULL, NULL);
+
+        MmLockAddressSpace(AddressSpace);
+        MmLockSectionSegment(Segment);
+        Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+    }
+
+    /*
+     * For a dirty, datafile, non-private page mark it as dirty in the
+     * cache manager.
+     */
+    if (Segment->Flags & MM_DATAFILE_SEGMENT)
+    {
+        if (Page == PFN_FROM_SSE(Entry) && Dirty)
+        {
 #ifndef NEWCC
-         CcRosMarkDirtyVacb(Bcb, (ULONG)(Offset.QuadPart + Segment->Image.FileOffset));
+            FileObject = MemoryArea->Data.SectionData.Section->FileObject;
+            SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
+            CcRosMarkDirtyVacb(SharedCacheMap, Offset.QuadPart + Segment->Image.FileOffset);
 #endif
-         ASSERT(SwapEntry == 0);
-      }
-   }
-
-   if (SwapEntry != 0)
-   {
-      /*
-       * Sanity check
-       */
-      if (Segment->Flags & MM_PAGEFILE_SEGMENT)
-      {
-         DPRINT1("Found a swap entry for a page in a pagefile section.\n");
-         KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      MmFreeSwapPage(SwapEntry);
-   }
-   else if (Page != 0)
-   {
-      if (IS_SWAP_FROM_SSE(Entry) ||
-          Page != PFN_FROM_SSE(Entry))
-      {
-         /*
-          * Sanity check
-          */
-         if (Segment->Flags & MM_PAGEFILE_SEGMENT)
-         {
-            DPRINT1("Found a private page in a pagefile section.\n");
+            ASSERT(SwapEntry == 0);
+        }
+    }
+
+    if (SwapEntry != 0)
+    {
+        /*
+         * Sanity check
+         */
+        if (Segment->Flags & MM_PAGEFILE_SEGMENT)
+        {
+            DPRINT1("Found a swap entry for a page in a pagefile section.\n");
             KeBugCheck(MEMORY_MANAGEMENT);
-         }
-         /*
-          * Just dereference private pages
-          */
-         SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
-         if (SavedSwapEntry != 0)
-         {
-            MmFreeSwapPage(SavedSwapEntry);
-            MmSetSavedSwapEntryPage(Page, 0);
-         }
-         MmDeleteRmap(Page, Process, Address);
-         MmReleasePageMemoryConsumer(MC_USER, Page);
-      }
-      else
-      {
-         MmDeleteRmap(Page, Process, Address);
-         MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, Dirty, FALSE, NULL);
-      }
-   }
+        }
+        MmFreeSwapPage(SwapEntry);
+    }
+    else if (Page != 0)
+    {
+        if (IS_SWAP_FROM_SSE(Entry) ||
+                Page != PFN_FROM_SSE(Entry))
+        {
+            /*
+             * Sanity check
+             */
+            if (Segment->Flags & MM_PAGEFILE_SEGMENT)
+            {
+                DPRINT1("Found a private page in a pagefile section.\n");
+                KeBugCheck(MEMORY_MANAGEMENT);
+            }
+            /*
+             * Just dereference private pages
+             */
+            SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
+            if (SavedSwapEntry != 0)
+            {
+                MmFreeSwapPage(SavedSwapEntry);
+                MmSetSavedSwapEntryPage(Page, 0);
+            }
+            MmDeleteRmap(Page, Process, Address);
+            MmReleasePageMemoryConsumer(MC_USER, Page);
+        }
+        else
+        {
+            MmDeleteRmap(Page, Process, Address);
+            MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, Dirty, FALSE, NULL);
+        }
+    }
 }
 
 static NTSTATUS
 MmUnmapViewOfSegment(PMMSUPPORT AddressSpace,
                      PVOID BaseAddress)
 {
-   NTSTATUS Status;
-   PMEMORY_AREA MemoryArea;
-   PROS_SECTION_OBJECT Section;
-   PMM_SECTION_SEGMENT Segment;
-   PLIST_ENTRY CurrentEntry;
-   PMM_REGION CurrentRegion;
-   PLIST_ENTRY RegionListHead;
-
-   MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
-                                            BaseAddress);
-   if (MemoryArea == NULL)
-   {
-      return(STATUS_UNSUCCESSFUL);
-   }
-
-   MemoryArea->DeleteInProgress = TRUE;
-   Section = MemoryArea->Data.SectionData.Section;
-   Segment = MemoryArea->Data.SectionData.Segment;
+    NTSTATUS Status;
+    PMEMORY_AREA MemoryArea;
+    PROS_SECTION_OBJECT Section;
+    PMM_SECTION_SEGMENT Segment;
+    PLIST_ENTRY CurrentEntry;
+    PMM_REGION CurrentRegion;
+    PLIST_ENTRY RegionListHead;
+
+    MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
+                 BaseAddress);
+    if (MemoryArea == NULL)
+    {
+        return(STATUS_UNSUCCESSFUL);
+    }
+
+    Section = MemoryArea->Data.SectionData.Section;
+    Segment = MemoryArea->Data.SectionData.Segment;
 
 #ifdef NEWCC
-   if (Segment->Flags & MM_DATAFILE_SEGMENT)
-      return MmUnmapViewOfCacheSegment(AddressSpace, BaseAddress);
+    if (Segment->Flags & MM_DATAFILE_SEGMENT)
+    {
+        MmUnlockAddressSpace(AddressSpace);
+        Status = MmUnmapViewOfCacheSegment(AddressSpace, BaseAddress);
+        MmLockAddressSpace(AddressSpace);
+
+        return Status;
+    }
 #endif
 
-   MmLockSectionSegment(Segment);
-
-   RegionListHead = &MemoryArea->Data.SectionData.RegionListHead;
-   while (!IsListEmpty(RegionListHead))
-   {
-      CurrentEntry = RemoveHeadList(RegionListHead);
-      CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry);
-      ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
-   }
-
-   if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
-   {
-      Status = MmFreeMemoryArea(AddressSpace,
-                                MemoryArea,
-                                NULL,
-                                NULL);
-   }
-   else
-   {
-      Status = MmFreeMemoryArea(AddressSpace,
-                                MemoryArea,
-                                MmFreeSectionPage,
-                                AddressSpace);
-   }
-   MmUnlockSectionSegment(Segment);
-   ObDereferenceObject(Section);
-   return(Status);
+    MemoryArea->DeleteInProgress = TRUE;
+
+    MmLockSectionSegment(Segment);
+
+    RegionListHead = &MemoryArea->Data.SectionData.RegionListHead;
+    while (!IsListEmpty(RegionListHead))
+    {
+        CurrentEntry = RemoveHeadList(RegionListHead);
+        CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry);
+        ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
+    }
+
+    if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
+    {
+        Status = MmFreeMemoryArea(AddressSpace,
+                                  MemoryArea,
+                                  NULL,
+                                  NULL);
+    }
+    else
+    {
+        Status = MmFreeMemoryArea(AddressSpace,
+                                  MemoryArea,
+                                  MmFreeSectionPage,
+                                  AddressSpace);
+    }
+    MmUnlockSectionSegment(Segment);
+    ObDereferenceObject(Section);
+    return(Status);
 }
 
 NTSTATUS
@@ -4127,90 +4144,95 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process,
                         IN PVOID BaseAddress,
                         IN ULONG Flags)
 {
-   NTSTATUS Status;
-   PMEMORY_AREA MemoryArea;
-   PMMSUPPORT AddressSpace;
-   PROS_SECTION_OBJECT Section;
-   PVOID ImageBaseAddress = 0;
-
-   DPRINT("Opening memory area Process %p BaseAddress %p\n",
-          Process, BaseAddress);
-
-   ASSERT(Process);
-
-   AddressSpace = Process ? &Process->Vm : MmGetKernelAddressSpace();
-
-   MmLockAddressSpace(AddressSpace);
-   MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
-                                            BaseAddress);
-   if (MemoryArea == NULL ||
-       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;
-
-   Section = MemoryArea->Data.SectionData.Section;
-
-   if (Section->AllocationAttributes & SEC_IMAGE)
-   {
-      ULONG i;
-      ULONG NrSegments;
-      PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
-      PMM_SECTION_SEGMENT SectionSegments;
-      PMM_SECTION_SEGMENT Segment;
-
-      Segment = MemoryArea->Data.SectionData.Segment;
-      ImageSectionObject = Section->ImageSection;
-      SectionSegments = ImageSectionObject->Segments;
-      NrSegments = ImageSectionObject->NrSegments;
-
-      /* Search for the current segment within the section segments
-       * and calculate the image base address */
-      for (i = 0; i < NrSegments; i++)
-      {
-         if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-         {
+    NTSTATUS Status;
+    PMEMORY_AREA MemoryArea;
+    PMMSUPPORT AddressSpace;
+    PROS_SECTION_OBJECT Section;
+    PVOID ImageBaseAddress = 0;
+
+    DPRINT("Opening memory area Process %p BaseAddress %p\n",
+           Process, BaseAddress);
+
+    ASSERT(Process);
+
+    AddressSpace = Process ? &Process->Vm : MmGetKernelAddressSpace();
+
+    MmLockAddressSpace(AddressSpace);
+    MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
+                 BaseAddress);
+    if (MemoryArea == NULL ||
+            ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) &&
+             (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
+            MemoryArea->DeleteInProgress)
+    {
+        if (MemoryArea) ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
+        MmUnlockAddressSpace(AddressSpace);
+        return STATUS_NOT_MAPPED_VIEW;
+    }
+
+    Section = MemoryArea->Data.SectionData.Section;
+
+    if ((Section != NULL) && (Section->AllocationAttributes & SEC_IMAGE))
+    {
+        ULONG i;
+        ULONG NrSegments;
+        PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
+        PMM_SECTION_SEGMENT SectionSegments;
+        PMM_SECTION_SEGMENT Segment;
+
+        Segment = MemoryArea->Data.SectionData.Segment;
+        ImageSectionObject = Section->ImageSection;
+        SectionSegments = ImageSectionObject->Segments;
+        NrSegments = ImageSectionObject->NrSegments;
+
+        MemoryArea->DeleteInProgress = TRUE;
+
+        /* Search for the current segment within the section segments
+         * and calculate the image base address */
+        for (i = 0; i < NrSegments; i++)
+        {
             if (Segment == &SectionSegments[i])
             {
-               ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
-               break;
+                ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
+                break;
             }
-         }
-      }
-      if (i >= NrSegments)
-      {
-         KeBugCheck(MEMORY_MANAGEMENT);
-      }
-
-      for (i = 0; i < NrSegments; i++)
-      {
-         if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-         {
+        }
+        if (i >= NrSegments)
+        {
+            KeBugCheck(MEMORY_MANAGEMENT);
+        }
+
+        for (i = 0; i < NrSegments; i++)
+        {
             PVOID SBaseAddress = (PVOID)
                                  ((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);
-
-   /* Notify debugger */
-   if (ImageBaseAddress) DbgkUnMapViewOfSection(ImageBaseAddress);
-
-   return(STATUS_SUCCESS);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
+                        SBaseAddress, Process, Status);
+                ASSERT(NT_SUCCESS(Status));
+            }
+        }
+    }
+    else
+    {
+        Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
+                    BaseAddress, Process, Status);
+            ASSERT(NT_SUCCESS(Status));
+        }
+    }
+
+    MmUnlockAddressSpace(AddressSpace);
+
+    /* Notify debugger */
+    if (ImageBaseAddress) DbgkUnMapViewOfSection(ImageBaseAddress);
+
+    return(STATUS_SUCCESS);
 }
 
 
@@ -4238,112 +4260,199 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process,
  *
  * @implemented
  */
-NTSTATUS NTAPI
-NtQuerySection(IN HANDLE SectionHandle,
-               IN SECTION_INFORMATION_CLASS SectionInformationClass,
-               OUT PVOID SectionInformation,
-               IN SIZE_T SectionInformationLength,
-               OUT PSIZE_T ResultLength  OPTIONAL)
+NTSTATUS
+NTAPI
+NtQuerySection(
+    _In_ HANDLE SectionHandle,
+    _In_ SECTION_INFORMATION_CLASS SectionInformationClass,
+    _Out_ PVOID SectionInformation,
+    _In_ SIZE_T SectionInformationLength,
+    _Out_opt_ PSIZE_T ResultLength)
 {
-   PROS_SECTION_OBJECT Section;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   Status = DefaultQueryInfoBufferCheck(SectionInformationClass,
-                                        ExSectionInfoClass,
-                                        sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]),
-                                        SectionInformation,
-                                        (ULONG)SectionInformationLength,
-                                        NULL,
-                                        ResultLength,
-                                        PreviousMode);
-
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtQuerySection() failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-
-   Status = ObReferenceObjectByHandle(SectionHandle,
-                                      SECTION_QUERY,
-                                      MmSectionObjectType,
-                                      PreviousMode,
-                                      (PVOID*)(PVOID)&Section,
-                                      NULL);
-   if (NT_SUCCESS(Status))
-   {
-      switch (SectionInformationClass)
-      {
-         case SectionBasicInformation:
-         {
-            PSECTION_BASIC_INFORMATION Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation;
-
-            _SEH2_TRY
+    PSECTION Section;
+    KPROCESSOR_MODE PreviousMode;
+    NTSTATUS Status;
+    PAGED_CODE();
+
+    PreviousMode = ExGetPreviousMode();
+    if (PreviousMode != KernelMode)
+    {
+        _SEH2_TRY
+        {
+            ProbeForWrite(SectionInformation,
+                          SectionInformationLength,
+                          __alignof(ULONG));
+            if (ResultLength != NULL)
             {
-               Sbi->Attributes = Section->AllocationAttributes;
-               if (Section->AllocationAttributes & SEC_IMAGE)
-               {
-                  Sbi->BaseAddress = 0;
-                  Sbi->Size.QuadPart = 0;
-               }
-               else
-               {
-                  Sbi->BaseAddress = (PVOID)Section->Segment->Image.VirtualAddress;
-                  Sbi->Size.QuadPart = Section->Segment->Length.QuadPart;
-               }
-
-               if (ResultLength != NULL)
-               {
-                  *ResultLength = sizeof(SECTION_BASIC_INFORMATION);
-               }
-               Status = STATUS_SUCCESS;
+                ProbeForWrite(ResultLength,
+                              sizeof(*ResultLength),
+                              __alignof(SIZE_T));
             }
-            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
+        }
+        _SEH2_END;
+    }
+
+    if (SectionInformationClass == SectionBasicInformation)
+    {
+        if (SectionInformationLength < sizeof(SECTION_BASIC_INFORMATION))
+        {
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+    }
+    else if (SectionInformationClass == SectionImageInformation)
+    {
+        if (SectionInformationLength < sizeof(SECTION_IMAGE_INFORMATION))
+        {
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+    }
+    else
+    {
+        return STATUS_INVALID_INFO_CLASS;
+    }
+
+    Status = ObReferenceObjectByHandle(SectionHandle,
+                                       SECTION_QUERY,
+                                       MmSectionObjectType,
+                                       PreviousMode,
+                                       (PVOID*)(PVOID)&Section,
+                                       NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to reference section: 0x%lx\n", Status);
+        return Status;
+    }
+
+    if (MiIsRosSectionObject(Section))
+    {
+        PROS_SECTION_OBJECT RosSection = (PROS_SECTION_OBJECT)Section;
+
+        switch (SectionInformationClass)
+        {
+            case SectionBasicInformation:
             {
-               Status = _SEH2_GetExceptionCode();
+                PSECTION_BASIC_INFORMATION Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation;
+
+                _SEH2_TRY
+                {
+                    Sbi->Attributes = RosSection->AllocationAttributes;
+                    if (RosSection->AllocationAttributes & SEC_IMAGE)
+                    {
+                        Sbi->BaseAddress = 0;
+                        Sbi->Size.QuadPart = 0;
+                    }
+                    else
+                    {
+                        Sbi->BaseAddress = (PVOID)RosSection->Segment->Image.VirtualAddress;
+                        Sbi->Size.QuadPart = RosSection->Segment->Length.QuadPart;
+                    }
+
+                    if (ResultLength != NULL)
+                    {
+                        *ResultLength = sizeof(SECTION_BASIC_INFORMATION);
+                    }
+                    Status = STATUS_SUCCESS;
+                }
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+                {
+                    Status = _SEH2_GetExceptionCode();
+                }
+                _SEH2_END;
+
+                break;
             }
-            _SEH2_END;
 
-            break;
-         }
+            case SectionImageInformation:
+            {
+                PSECTION_IMAGE_INFORMATION Sii = (PSECTION_IMAGE_INFORMATION)SectionInformation;
 
-         case SectionImageInformation:
-         {
-            PSECTION_IMAGE_INFORMATION Sii = (PSECTION_IMAGE_INFORMATION)SectionInformation;
+                _SEH2_TRY
+                {
+                    if (RosSection->AllocationAttributes & SEC_IMAGE)
+                    {
+                        PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
+                        ImageSectionObject = RosSection->ImageSection;
+
+                        *Sii = ImageSectionObject->ImageInformation;
+                    }
+
+                    if (ResultLength != NULL)
+                    {
+                        *ResultLength = sizeof(SECTION_IMAGE_INFORMATION);
+                    }
+                    Status = STATUS_SUCCESS;
+                }
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+                {
+                    Status = _SEH2_GetExceptionCode();
+                }
+                _SEH2_END;
 
-            _SEH2_TRY
+                break;
+            }
+        }
+    }
+    else
+    {
+        switch(SectionInformationClass)
+        {
+            case SectionBasicInformation:
             {
-               if (Section->AllocationAttributes & SEC_IMAGE)
-               {
-                  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
-                  ImageSectionObject = Section->ImageSection;
-
-                  *Sii = ImageSectionObject->ImageInformation;
-               }
-
-               if (ResultLength != NULL)
-               {
-                  *ResultLength = sizeof(SECTION_IMAGE_INFORMATION);
-               }
-               Status = STATUS_SUCCESS;
+                SECTION_BASIC_INFORMATION Sbi;
+
+                Sbi.Size = Section->SizeOfSection;
+                Sbi.BaseAddress = (PVOID)Section->Address.StartingVpn;
+
+                Sbi.Attributes = 0;
+                if (Section->u.Flags.Image)
+                    Sbi.Attributes |= SEC_IMAGE;
+                if (Section->u.Flags.Commit)
+                    Sbi.Attributes |= SEC_COMMIT;
+                if (Section->u.Flags.Reserve)
+                    Sbi.Attributes |= SEC_RESERVE;
+                if (Section->u.Flags.File)
+                    Sbi.Attributes |= SEC_FILE;
+                if (Section->u.Flags.Image)
+                    Sbi.Attributes |= SEC_IMAGE;
+
+                /* FIXME : Complete/test the list of flags passed back from NtCreateSection */
+
+                _SEH2_TRY
+                {
+                    *((SECTION_BASIC_INFORMATION*)SectionInformation) = Sbi;
+                    if (ResultLength)
+                        *ResultLength = sizeof(Sbi);
+                }
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+                {
+                    Status = _SEH2_GetExceptionCode();
+                }
+                _SEH2_END;
+                break;
             }
-            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            case SectionImageInformation:
             {
-               Status = _SEH2_GetExceptionCode();
+                if (!Section->u.Flags.Image)
+                {
+                    Status = STATUS_SECTION_NOT_IMAGE;
+                }
+                else
+                {
+                    /* Currently not supported */
+                    ASSERT(FALSE);
+                }
+                break;
             }
-            _SEH2_END;
-
-            break;
-         }
-      }
+        }
+    }
 
-      ObDereferenceObject(Section);
-   }
+    ObDereferenceObject(Section);
 
-   return(Status);
+    return(Status);
 }
 
 /**********************************************************************
@@ -4407,116 +4516,113 @@ MmMapViewOfSection(IN PVOID SectionObject,
                    IN ULONG AllocationType,
                    IN ULONG Protect)
 {
-   PROS_SECTION_OBJECT Section;
-   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);
-
-   if (!Protect || Protect & ~PAGE_FLAGS_VALID_FOR_SECTION)
-   {
-      return STATUS_INVALID_PAGE_PROTECTION;
-   }
-
-
-   Section = (PROS_SECTION_OBJECT)SectionObject;
-   AddressSpace = &Process->Vm;
-
-   AllocationType |= (Section->AllocationAttributes & SEC_NO_CHANGE);
-
-   MmLockAddressSpace(AddressSpace);
-
-   if (Section->AllocationAttributes & SEC_IMAGE)
-   {
-      ULONG i;
-      ULONG NrSegments;
-      ULONG_PTR ImageBase;
-      SIZE_T ImageSize;
-      PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
-      PMM_SECTION_SEGMENT SectionSegments;
-
-      ImageSectionObject = Section->ImageSection;
-      SectionSegments = ImageSectionObject->Segments;
-      NrSegments = ImageSectionObject->NrSegments;
-
-      ImageBase = (ULONG_PTR)*BaseAddress;
-      if (ImageBase == 0)
-      {
-          ImageBase = (ULONG_PTR)ImageSectionObject->BasedAddress;
-      }
-
-      ImageSize = 0;
-      for (i = 0; i < NrSegments; i++)
-      {
-         if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-         {
+    PROS_SECTION_OBJECT Section;
+    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);
+
+    if (!Protect || Protect & ~PAGE_FLAGS_VALID_FOR_SECTION)
+    {
+        return STATUS_INVALID_PAGE_PROTECTION;
+    }
+
+    /* FIXME: We should keep this, but it would break code checking equality */
+    Protect &= ~PAGE_NOCACHE;
+
+    Section = (PROS_SECTION_OBJECT)SectionObject;
+    AddressSpace = &Process->Vm;
+
+    AllocationType |= (Section->AllocationAttributes & SEC_NO_CHANGE);
+
+    MmLockAddressSpace(AddressSpace);
+
+    if (Section->AllocationAttributes & SEC_IMAGE)
+    {
+        ULONG i;
+        ULONG NrSegments;
+        ULONG_PTR ImageBase;
+        SIZE_T ImageSize;
+        PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
+        PMM_SECTION_SEGMENT SectionSegments;
+
+        ImageSectionObject = Section->ImageSection;
+        SectionSegments = ImageSectionObject->Segments;
+        NrSegments = ImageSectionObject->NrSegments;
+
+        ImageBase = (ULONG_PTR)*BaseAddress;
+        if (ImageBase == 0)
+        {
+            ImageBase = (ULONG_PTR)ImageSectionObject->BasedAddress;
+        }
+
+        ImageSize = 0;
+        for (i = 0; i < NrSegments; i++)
+        {
             ULONG_PTR MaxExtent;
             MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
-                        SectionSegments[i].Length.QuadPart);
+                                    SectionSegments[i].Length.QuadPart);
             ImageSize = max(ImageSize, MaxExtent);
-         }
-      }
-
-      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,
-                                     PAGE_ROUND_UP(ImageSize)) != NULL)
-      {
-         /* Fail if the user requested a fixed base address. */
-         if ((*BaseAddress) != NULL)
-         {
-            MmUnlockAddressSpace(AddressSpace);
-            return(STATUS_CONFLICTING_ADDRESSES);
-         }
-         /* Otherwise find a gap to map the image. */
-         ImageBase = (ULONG_PTR)MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), MM_VIRTMEM_GRANULARITY, FALSE);
-         if (ImageBase == 0)
-         {
-            MmUnlockAddressSpace(AddressSpace);
-            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].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-         {
+        }
+
+        ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize;
+
+        /* Check for an illegal base address */
+        if (((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress) ||
+                ((ImageBase + ImageSize) < ImageSize))
+        {
+            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))
+        {
+            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,
+                                       PAGE_ROUND_UP(ImageSize)) != NULL)
+        {
+            /* Fail if the user requested a fixed base address. */
+            if ((*BaseAddress) != NULL)
+            {
+                MmUnlockAddressSpace(AddressSpace);
+                return(STATUS_CONFLICTING_ADDRESSES);
+            }
+            /* Otherwise find a gap to map the image. */
+            ImageBase = (ULONG_PTR)MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), MM_VIRTMEM_GRANULARITY, FALSE);
+            if (ImageBase == 0)
+            {
+                MmUnlockAddressSpace(AddressSpace);
+                return(STATUS_CONFLICTING_ADDRESSES);
+            }
+            /* Remember that we loaded image at a different base address */
+            NotAtBase = TRUE;
+        }
+
+        for (i = 0; i < NrSegments; i++)
+        {
             PVOID SBaseAddress = (PVOID)
                                  ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
             MmLockSectionSegment(&SectionSegments[i]);
@@ -4531,98 +4637,90 @@ MmMapViewOfSection(IN PVOID SectionObject,
             MmUnlockSectionSegment(&SectionSegments[i]);
             if (!NT_SUCCESS(Status))
             {
-               MmUnlockAddressSpace(AddressSpace);
-               return(Status);
+                MmUnlockAddressSpace(AddressSpace);
+                return(Status);
             }
-         }
-      }
-
-      *BaseAddress = (PVOID)ImageBase;
-      *ViewSize = ImageSize;
-   }
-   else
-   {
-      /* check for write access */
-      if ((Protect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) &&
-          !(Section->SectionPageProtection & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)))
-      {
-         MmUnlockAddressSpace(AddressSpace);
-         return STATUS_SECTION_PROTECTION;
-      }
-      /* check for read access */
-      if ((Protect & (PAGE_READONLY|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_WRITECOPY)) &&
-          !(Section->SectionPageProtection & (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)))
-      {
-         MmUnlockAddressSpace(AddressSpace);
-         return STATUS_SECTION_PROTECTION;
-      }
-      /* check for execute access */
-      if ((Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) &&
-          !(Section->SectionPageProtection & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)))
-      {
-         MmUnlockAddressSpace(AddressSpace);
-         return STATUS_SECTION_PROTECTION;
-      }
-
-      if (ViewSize == NULL)
-      {
-         /* Following this pointer would lead to us to the dark side */
-         /* What to do? Bugcheck? Return status? Do the mambo? */
-         KeBugCheck(MEMORY_MANAGEMENT);
-      }
-
-      if (SectionOffset == NULL)
-      {
-         ViewOffset = 0;
-      }
-      else
-      {
-         ViewOffset = SectionOffset->u.LowPart;
-      }
-
-      if ((ViewOffset % PAGE_SIZE) != 0)
-      {
-         MmUnlockAddressSpace(AddressSpace);
-         return(STATUS_MAPPED_ALIGNMENT);
-      }
-
-      if ((*ViewSize) == 0)
-      {
-         (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset;
-      }
-      else if (((*ViewSize)+ViewOffset) > Section->MaximumSize.u.LowPart)
-      {
-         (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset;
-      }
-
-      *ViewSize = PAGE_ROUND_UP(*ViewSize);
-
-      MmLockSectionSegment(Section->Segment);
-      Status = MmMapViewOfSegment(AddressSpace,
-                                  Section,
-                                  Section->Segment,
-                                  BaseAddress,
-                                  *ViewSize,
-                                  Protect,
-                                  ViewOffset,
-                                  AllocationType & (MEM_TOP_DOWN|SEC_NO_CHANGE));
-      MmUnlockSectionSegment(Section->Segment);
-      if (!NT_SUCCESS(Status))
-      {
-         MmUnlockAddressSpace(AddressSpace);
-         return(Status);
-      }
-   }
-
-   MmUnlockAddressSpace(AddressSpace);
-   NT_ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
-
-   if (NotAtBase)
-       Status = STATUS_IMAGE_NOT_AT_BASE;
-   else
-       Status = STATUS_SUCCESS;
-
-   return Status;
+        }
+
+        *BaseAddress = (PVOID)ImageBase;
+        *ViewSize = ImageSize;
+    }
+    else
+    {
+        /* check for write access */
+        if ((Protect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) &&
+                !(Section->SectionPageProtection & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)))
+        {
+            MmUnlockAddressSpace(AddressSpace);
+            return STATUS_SECTION_PROTECTION;
+        }
+        /* check for read access */
+        if ((Protect & (PAGE_READONLY|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_WRITECOPY)) &&
+                !(Section->SectionPageProtection & (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)))
+        {
+            MmUnlockAddressSpace(AddressSpace);
+            return STATUS_SECTION_PROTECTION;
+        }
+        /* check for execute access */
+        if ((Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) &&
+                !(Section->SectionPageProtection & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)))
+        {
+            MmUnlockAddressSpace(AddressSpace);
+            return STATUS_SECTION_PROTECTION;
+        }
+
+        if (SectionOffset == NULL)
+        {
+            ViewOffset = 0;
+        }
+        else
+        {
+            ViewOffset = SectionOffset->u.LowPart;
+        }
+
+        if ((ViewOffset % PAGE_SIZE) != 0)
+        {
+            MmUnlockAddressSpace(AddressSpace);
+            return(STATUS_MAPPED_ALIGNMENT);
+        }
+
+        if ((*ViewSize) == 0)
+        {
+            (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset;
+        }
+        else if (((*ViewSize)+ViewOffset) > Section->MaximumSize.u.LowPart)
+        {
+            (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset;
+        }
+
+        *ViewSize = PAGE_ROUND_UP(*ViewSize);
+
+        MmLockSectionSegment(Section->Segment);
+        Status = MmMapViewOfSegment(AddressSpace,
+                                    Section,
+                                    Section->Segment,
+                                    BaseAddress,
+                                    *ViewSize,
+                                    Protect,
+                                    ViewOffset,
+                                    AllocationType & (MEM_TOP_DOWN|SEC_NO_CHANGE));
+        MmUnlockSectionSegment(Section->Segment);
+        if (!NT_SUCCESS(Status))
+        {
+            MmUnlockAddressSpace(AddressSpace);
+            return(Status);
+        }
+    }
+
+    MmUnlockAddressSpace(AddressSpace);
+    ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
+
+    if (NotAtBase)
+        Status = STATUS_IMAGE_NOT_AT_BASE;
+    else
+        Status = STATUS_SUCCESS;
+
+    return Status;
 }
 
 /*
@@ -4632,68 +4730,68 @@ BOOLEAN NTAPI
 MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
                       IN PLARGE_INTEGER   NewFileSize)
 {
-   /* Check whether an ImageSectionObject exists */
-   if (SectionObjectPointer->ImageSectionObject != NULL)
-   {
-      DPRINT1("ERROR: File can't be truncated because it has an image section\n");
-      return FALSE;
-   }
-
-   if (SectionObjectPointer->DataSectionObject != NULL)
-   {
-      PMM_SECTION_SEGMENT Segment;
-
-      Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer->
-                DataSectionObject;
-
-      if (Segment->ReferenceCount != 0)
-      {
+    /* Check whether an ImageSectionObject exists */
+    if (SectionObjectPointer->ImageSectionObject != NULL)
+    {
+        DPRINT1("ERROR: File can't be truncated because it has an image section\n");
+        return FALSE;
+    }
+
+    if (SectionObjectPointer->DataSectionObject != NULL)
+    {
+        PMM_SECTION_SEGMENT Segment;
+
+        Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer->
+                  DataSectionObject;
+
+        if (Segment->ReferenceCount != 0)
+        {
 #ifdef NEWCC
-         CC_FILE_SIZES FileSizes;
-         CcpLock();
-         if (SectionObjectPointer->SharedCacheMap && (Segment->ReferenceCount > CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap)))
-         {
-            CcpUnlock();
+            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)
             {
-               if (!CcGetFileSizes(Segment->FileObject, &FileSizes))
-               {
-                  return FALSE;
-               }
-
-               if (NewFileSize->QuadPart <= FileSizes.FileSize.QuadPart)
-               {
-                  return FALSE;
-               }
+                PROS_SHARED_CACHE_MAP SharedCacheMap = SectionObjectPointer->SharedCacheMap;
+                if (NewFileSize->QuadPart <= SharedCacheMap->FileSize.QuadPart)
+                {
+                    return FALSE;
+                }
             }
-         }
-         else
-            CcpUnlock();
-#else
-          /* Check size of file */
-          if (SectionObjectPointer->SharedCacheMap)
-          {
-             PBCB Bcb = SectionObjectPointer->SharedCacheMap;
-             if (NewFileSize->QuadPart <= Bcb->FileSize.QuadPart)
-             {
-                return FALSE;
-             }
-          }
 #endif
-      }
-      else
-      {
-         /* Something must gone wrong
-          * how can we have a Section but no
-          * reference? */
-         DPRINT("ERROR: DataSectionObject without reference!\n");
-      }
-   }
-
-   DPRINT("FIXME: didn't check for outstanding write probes\n");
-
-   return TRUE;
+        }
+        else
+        {
+            /* Something must gone wrong
+             * how can we have a Section but no
+             * reference? */
+            DPRINT("ERROR: DataSectionObject without reference!\n");
+        }
+    }
+
+    DPRINT("FIXME: didn't check for outstanding write probes\n");
+
+    return TRUE;
 }
 
 
@@ -4706,45 +4804,46 @@ BOOLEAN NTAPI
 MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
                      IN MMFLUSH_TYPE   FlushType)
 {
-   BOOLEAN Result = TRUE;
+    BOOLEAN Result = TRUE;
 #ifdef NEWCC
-   PMM_SECTION_SEGMENT Segment;
+    PMM_SECTION_SEGMENT Segment;
 #endif
 
-   switch(FlushType)
-   {
-      case MmFlushForDelete:
-         if (SectionObjectPointer->ImageSectionObject ||
-               SectionObjectPointer->DataSectionObject)
-         {
+    switch(FlushType)
+    {
+    case MmFlushForDelete:
+        if (SectionObjectPointer->ImageSectionObject ||
+                SectionObjectPointer->DataSectionObject)
+        {
             return FALSE;
-         }
+        }
 #ifndef NEWCC
-         CcRosRemoveIfClosed(SectionObjectPointer);
+        CcRosRemoveIfClosed(SectionObjectPointer);
 #endif
-         return TRUE;
-      case MmFlushForWrite:
-      {
-         DPRINT("MmFlushImageSection(%d)\n", FlushType);
+        return TRUE;
+    case MmFlushForWrite:
+    {
+        DPRINT("MmFlushImageSection(%d)\n", FlushType);
 #ifdef NEWCC
-         Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer->DataSectionObject;
+        Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer->DataSectionObject;
 #endif
 
-         if (SectionObjectPointer->ImageSectionObject) {
+        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);
+        CcpLock();
+        Result = !SectionObjectPointer->SharedCacheMap || (Segment->ReferenceCount == CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap));
+        CcpUnlock();
+        DPRINT("Result %d\n", Result);
 #endif
-         return Result;
-      }
-   }
-   return FALSE;
+        return Result;
+    }
+    }
+    return FALSE;
 }
 
 /*
@@ -4755,10 +4854,10 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
                         OUT PVOID * MappedBase,
                         IN OUT PSIZE_T ViewSize)
 {
-   PROS_SECTION_OBJECT Section;
-   PMMSUPPORT AddressSpace;
-   NTSTATUS Status;
-   PAGED_CODE();
+    PROS_SECTION_OBJECT Section;
+    PMMSUPPORT AddressSpace;
+    NTSTATUS Status;
+    PAGED_CODE();
 
     if (MiIsRosSectionObject(SectionObject) == FALSE)
     {
@@ -4768,59 +4867,59 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
                                       ViewSize);
     }
 
-   DPRINT("MmMapViewInSystemSpace() called\n");
+    DPRINT("MmMapViewInSystemSpace() called\n");
 
-   Section = (PROS_SECTION_OBJECT)SectionObject;
-   AddressSpace = MmGetKernelAddressSpace();
+    Section = (PROS_SECTION_OBJECT)SectionObject;
+    AddressSpace = MmGetKernelAddressSpace();
 
-   MmLockAddressSpace(AddressSpace);
+    MmLockAddressSpace(AddressSpace);
 
 
-   if ((*ViewSize) == 0)
-   {
-      (*ViewSize) = Section->MaximumSize.u.LowPart;
-   }
-   else if ((*ViewSize) > Section->MaximumSize.u.LowPart)
-   {
-      (*ViewSize) = Section->MaximumSize.u.LowPart;
-   }
+    if ((*ViewSize) == 0)
+    {
+        (*ViewSize) = Section->MaximumSize.u.LowPart;
+    }
+    else if ((*ViewSize) > Section->MaximumSize.u.LowPart)
+    {
+        (*ViewSize) = Section->MaximumSize.u.LowPart;
+    }
 
-   MmLockSectionSegment(Section->Segment);
+    MmLockSectionSegment(Section->Segment);
 
 
-   Status = MmMapViewOfSegment(AddressSpace,
-                               Section,
-                               Section->Segment,
-                               MappedBase,
-                               *ViewSize,
-                               PAGE_READWRITE,
-                               0,
-                               0);
+    Status = MmMapViewOfSegment(AddressSpace,
+                                Section,
+                                Section->Segment,
+                                MappedBase,
+                                *ViewSize,
+                                PAGE_READWRITE,
+                                0,
+                                0);
 
-   MmUnlockSectionSegment(Section->Segment);
-   MmUnlockAddressSpace(AddressSpace);
+    MmUnlockSectionSegment(Section->Segment);
+    MmUnlockAddressSpace(AddressSpace);
 
-   return Status;
+    return Status;
 }
 
 NTSTATUS
 NTAPI
 MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
 {
-   PMMSUPPORT AddressSpace;
-   NTSTATUS Status;
+    PMMSUPPORT AddressSpace;
+    NTSTATUS Status;
 
-   DPRINT("MmUnmapViewInSystemSpace() called\n");
+    DPRINT("MmUnmapViewInSystemSpace() called\n");
 
-   AddressSpace = MmGetKernelAddressSpace();
+    AddressSpace = MmGetKernelAddressSpace();
 
-   MmLockAddressSpace(AddressSpace);
+    MmLockAddressSpace(AddressSpace);
 
-   Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
+    Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
 
-   MmUnlockAddressSpace(AddressSpace);
+    MmUnlockAddressSpace(AddressSpace);
 
-   return Status;
+    return Status;
 }
 
 /**********************************************************************
@@ -4981,6 +5080,33 @@ MmCreateSection (OUT PVOID  * Section,
             return Status;
         }
         // Caching is initialized...
+
+        // Hack of the hack: actually, it might not be initialized if FSD init on effective right and if file is null-size
+        // In such case, force cache by initiating a write IRP
+        if (Status == STATUS_END_OF_FILE && !(AllocationAttributes & SEC_IMAGE) && FileObject != NULL &&
+            (FileObject->SectionObjectPointer == NULL || FileObject->SectionObjectPointer->SharedCacheMap == NULL))
+        {
+            Status = ZwWriteFile(FileHandle,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 &Iosb,
+                                 &Buffer,
+                                 sizeof(Buffer),
+                                 &ByteOffset,
+                                 NULL);
+            if (NT_SUCCESS(Status))
+            {
+                LARGE_INTEGER Zero;
+                Zero.QuadPart = 0LL;
+
+                Status = IoSetInformation(FileObject,
+                                          FileEndOfFileInformation,
+                                          sizeof(LARGE_INTEGER),
+                                          &Zero);
+                ASSERT(NT_SUCCESS(Status));
+            }
+        }
     }
 #endif