[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / section.c
index 2efc904..596be8a 100644 (file)
@@ -45,6 +45,9 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+#ifdef NEWCC
+#include "../cache/section/newmm.h"
+#endif
 #define NDEBUG
 #include <debug.h>
 #include <reactos/exeformat.h>
@@ -72,6 +75,39 @@ IN ULONG AllocationAttributes,
 IN HANDLE FileHandle OPTIONAL,
 IN PFILE_OBJECT FileObject OPTIONAL);
 
+NTSTATUS
+NTAPI
+MmMapViewOfArm3Section(IN PVOID SectionObject,
+                       IN PEPROCESS Process,
+                       IN OUT PVOID *BaseAddress,
+                       IN ULONG_PTR ZeroBits,
+                       IN SIZE_T CommitSize,
+                       IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
+                       IN OUT PSIZE_T ViewSize,
+                       IN SECTION_INHERIT InheritDisposition,
+                       IN ULONG AllocationType,
+                       IN ULONG Protect);
+
+//
+// PeFmtCreateSection depends on the following:
+//
+C_ASSERT(EXEFMT_LOAD_HEADER_SIZE >= sizeof(IMAGE_DOS_HEADER));
+C_ASSERT(sizeof(IMAGE_NT_HEADERS32) <= sizeof(IMAGE_NT_HEADERS64));
+
+C_ASSERT(TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) == TYPE_ALIGNMENT(IMAGE_NT_HEADERS64));
+C_ASSERT(RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader) == RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS64, FileHeader));
+C_ASSERT(FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader) == FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader));
+
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Magic));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SectionAlignment));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, FileAlignment));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Subsystem));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, AddressOfEntryPoint));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfCode));
+C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfHeaders));
+
 /* TYPES *********************************************************************/
 
 typedef struct
@@ -88,10 +124,32 @@ MM_SECTION_PAGEOUT_CONTEXT;
 
 POBJECT_TYPE MmSectionObjectType = NULL;
 
-SIZE_T MmAllocationFragment;
-
 ULONG_PTR MmSubsectionBase;
 
+static ULONG SectionCharacteristicsToProtect[16] =
+{
+    PAGE_NOACCESS,          /* 0 = NONE */
+    PAGE_NOACCESS,          /* 1 = SHARED */
+    PAGE_EXECUTE,           /* 2 = EXECUTABLE */
+    PAGE_EXECUTE,           /* 3 = EXECUTABLE, SHARED */
+    PAGE_READONLY,          /* 4 = READABLE */
+    PAGE_READONLY,          /* 5 = READABLE, SHARED */
+    PAGE_EXECUTE_READ,      /* 6 = READABLE, EXECUTABLE */
+    PAGE_EXECUTE_READ,      /* 7 = READABLE, EXECUTABLE, SHARED */
+    /*
+     * FIXME? do we really need the WriteCopy field in segments? can't we use
+     * PAGE_WRITECOPY here?
+     */
+    PAGE_READWRITE,         /* 8 = WRITABLE */
+    PAGE_READWRITE,         /* 9 = WRITABLE, SHARED */
+    PAGE_EXECUTE_READWRITE, /* 10 = WRITABLE, EXECUTABLE */
+    PAGE_EXECUTE_READWRITE, /* 11 = WRITABLE, EXECUTABLE, SHARED */
+    PAGE_READWRITE,         /* 12 = WRITABLE, READABLE */
+    PAGE_READWRITE,         /* 13 = WRITABLE, READABLE, SHARED */
+    PAGE_EXECUTE_READWRITE, /* 14 = WRITABLE, READABLE, EXECUTABLE */
+    PAGE_EXECUTE_READWRITE, /* 15 = WRITABLE, READABLE, EXECUTABLE, SHARED */
+};
+
 static GENERIC_MAPPING MmpSectionMapping = {
          STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY,
          STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE,
@@ -103,9 +161,9 @@ static GENERIC_MAPPING MmpSectionMapping = {
 #define SHARE_COUNT_FROM_SSE(E)  (((E) & 0x00000FFE) >> 1)
 #define IS_SWAP_FROM_SSE(E)      ((E) & 0x00000001)
 #define MAX_SHARE_COUNT          0x7FF
-#define MAKE_SSE(P, C)           ((P) | ((C) << 1))
+#define MAKE_SSE(P, C)           ((ULONG)(P) | ((C) << 1))
 #define SWAPENTRY_FROM_SSE(E)    ((E) >> 1)
-#define MAKE_SWAP_SSE(S)         (((S) << 1) | 0x1)
+#define MAKE_SWAP_SSE(S)         (((ULONG)(S) << 1) | 0x1)
 
 static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
 {
@@ -115,115 +173,533 @@ static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
 
 /* FUNCTIONS *****************************************************************/
 
-PFILE_OBJECT
-NTAPI
-MmGetFileObjectForSection(IN PROS_SECTION_OBJECT Section)
+
+/*
+ References:
+  [1] Microsoft Corporation, "Microsoft Portable Executable and Common Object
+      File Format Specification", revision 6.0 (February 1999)
+*/
+NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
+                                 IN SIZE_T FileHeaderSize,
+                                 IN PVOID File,
+                                 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
+                                 OUT PULONG Flags,
+                                 IN PEXEFMT_CB_READ_FILE ReadFileCb,
+                                 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb)
 {
-    PAGED_CODE();
-    ASSERT(Section);
+    NTSTATUS nStatus;
+    ULONG cbFileHeaderOffsetSize = 0;
+    ULONG cbSectionHeadersOffset = 0;
+    ULONG cbSectionHeadersSize;
+    ULONG cbSectionHeadersOffsetSize = 0;
+    ULONG cbOptHeaderSize;
+    ULONG cbHeadersSize = 0;
+    ULONG nSectionAlignment;
+    ULONG nFileAlignment;
+    const IMAGE_DOS_HEADER * pidhDosHeader;
+    const IMAGE_NT_HEADERS32 * pinhNtHeader;
+    const IMAGE_OPTIONAL_HEADER32 * piohOptHeader;
+    const IMAGE_SECTION_HEADER * pishSectionHeaders;
+    PMM_SECTION_SEGMENT pssSegments;
+    LARGE_INTEGER lnOffset;
+    PVOID pBuffer;
+    SIZE_T nPrevVirtualEndOfSegment = 0;
+    ULONG nFileSizeOfHeaders = 0;
+    ULONG i;
+
+    ASSERT(FileHeader);
+    ASSERT(FileHeaderSize > 0);
+    ASSERT(File);
+    ASSERT(ImageSectionObject);
+    ASSERT(ReadFileCb);
+    ASSERT(AllocateSegmentsCb);
+
+    ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize));
+
+    ASSERT(((UINT_PTR)FileHeader % TYPE_ALIGNMENT(IMAGE_DOS_HEADER)) == 0);
+
+#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; }
+
+    pBuffer = NULL;
+    pidhDosHeader = FileHeader;
+
+    /* DOS HEADER */
+    nStatus = STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
+
+    /* image too small to be an MZ executable */
+    if(FileHeaderSize < sizeof(IMAGE_DOS_HEADER))
+       DIE(("Too small to be an MZ executable, size is %lu\n", FileHeaderSize));
+
+    /* no MZ signature */
+    if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+       DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
+
+    /* not a Windows executable */
+    if(pidhDosHeader->e_lfanew <= 0)
+       DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
+
+    /* NT HEADER */
+    nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+    if(!Intsafe_AddULong32(&cbFileHeaderOffsetSize, pidhDosHeader->e_lfanew, RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)))
+       DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
+
+    if(FileHeaderSize < cbFileHeaderOffsetSize)
+       pinhNtHeader = NULL;
+    else
+    {
+       /*
+        * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
+        * and FileHeaderSize >= cbFileHeaderOffsetSize, so this holds true too
+        */
+       ASSERT(Intsafe_CanOffsetPointer(FileHeader, pidhDosHeader->e_lfanew));
+       pinhNtHeader = (PVOID)((UINT_PTR)FileHeader + pidhDosHeader->e_lfanew);
+    }
 
-    /* Return the file object */
-    return Section->FileObject; // Section->ControlArea->FileObject on NT
-}
+    /*
+     * the buffer doesn't contain the NT file header, or the alignment is wrong: we
+     * need to read the header from the file
+     */
+    if(FileHeaderSize < cbFileHeaderOffsetSize ||
+       (UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
+    {
+       ULONG cbNtHeaderSize;
+       ULONG cbReadSize;
+       PVOID pData;
 
-NTSTATUS
-NTAPI
-MmGetFileNameForSection(IN PROS_SECTION_OBJECT Section,
-                        OUT POBJECT_NAME_INFORMATION *ModuleName)
-{
-    POBJECT_NAME_INFORMATION ObjectNameInfo;
-    NTSTATUS Status;
-    ULONG ReturnLength;
+l_ReadHeaderFromFile:
+       cbNtHeaderSize = 0;
+       lnOffset.QuadPart = pidhDosHeader->e_lfanew;
+
+       /* read the header from the file */
+       nStatus = ReadFileCb(File, &lnOffset, sizeof(IMAGE_NT_HEADERS64), &pData, &pBuffer, &cbReadSize);
+
+       if(!NT_SUCCESS(nStatus))
+           DIE(("ReadFile failed, status %08X\n", nStatus));
+
+       ASSERT(pData);
+       ASSERT(pBuffer);
+       ASSERT(cbReadSize > 0);
+
+       nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+       /* the buffer doesn't contain the file header */
+       if(cbReadSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader))
+           DIE(("The file doesn't contain the PE file header\n"));
+
+       pinhNtHeader = pData;
 
-    /* Make sure it's an image section */
-    *ModuleName = NULL;
-    if (!(Section->AllocationAttributes & SEC_IMAGE))
+       /* object still not aligned: copy it to the beginning of the buffer */
+       if((UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
+       {
+           ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) == 0);
+           RtlMoveMemory(pBuffer, pData, cbReadSize);
+           pinhNtHeader = pBuffer;
+       }
+
+       /* invalid NT header */
+       nStatus = STATUS_INVALID_IMAGE_PROTECT;
+
+       if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
+           DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
+
+       nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+       if(!Intsafe_AddULong32(&cbNtHeaderSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
+           DIE(("The full NT header is too large\n"));
+
+       /* the buffer doesn't contain the whole NT header */
+       if(cbReadSize < cbNtHeaderSize)
+           DIE(("The file doesn't contain the full NT header\n"));
+    }
+    else
     {
-        /* It's not, fail */
-        return STATUS_SECTION_NOT_IMAGE;
+       ULONG cbOptHeaderOffsetSize = 0;
+
+       nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+       /* don't trust an invalid NT header */
+       if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
+           DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
+
+       if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
+           DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
+
+       if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
+           DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
+
+       /* the buffer doesn't contain the whole NT header: read it from the file */
+       if(cbOptHeaderOffsetSize > FileHeaderSize)
+           goto l_ReadHeaderFromFile;
     }
 
-    /* Allocate memory for our structure */
-    ObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
-                                           1024,
-                                           '  mM');
-    if (!ObjectNameInfo) return STATUS_NO_MEMORY;
-
-    /* Query the name */
-    Status = ObQueryNameString(Section->FileObject,
-                               ObjectNameInfo,
-                               1024,
-                               &ReturnLength);
-    if (!NT_SUCCESS(Status))
+    /* read information from the NT header */
+    piohOptHeader = &pinhNtHeader->OptionalHeader;
+    cbOptHeaderSize = pinhNtHeader->FileHeader.SizeOfOptionalHeader;
+
+    nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+    if(!RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Magic))
+       DIE(("The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
+
+    /* ASSUME: RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject)); */
+
+    switch(piohOptHeader->Magic)
     {
-        /* Failed, free memory */
-        ExFreePoolWithTag(ObjectNameInfo, '  mM');
-        return Status;
+       case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+       case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+           break;
+
+       default:
+           DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
     }
 
-    /* Success */
-    *ModuleName = ObjectNameInfo;
-    return STATUS_SUCCESS;
-}
+    if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SectionAlignment) &&
+        RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, FileAlignment))
+    {
+       /* See [1], section 3.4.2 */
+       if(piohOptHeader->SectionAlignment < PAGE_SIZE)
+       {
+           if(piohOptHeader->FileAlignment != piohOptHeader->SectionAlignment)
+               DIE(("Sections aren't page-aligned and the file alignment isn't the same\n"));
+       }
+       else if(piohOptHeader->SectionAlignment < piohOptHeader->FileAlignment)
+           DIE(("The section alignment is smaller than the file alignment\n"));
+
+       nSectionAlignment = piohOptHeader->SectionAlignment;
+       nFileAlignment = piohOptHeader->FileAlignment;
+
+       if(!IsPowerOf2(nSectionAlignment) || !IsPowerOf2(nFileAlignment))
+           DIE(("The section alignment (%u) and file alignment (%u) aren't both powers of 2\n", nSectionAlignment, nFileAlignment));
+    }
+    else
+    {
+       nSectionAlignment = PAGE_SIZE;
+       nFileAlignment = PAGE_SIZE;
+    }
 
-NTSTATUS
-NTAPI
-MmGetFileNameForAddress(IN PVOID Address,
-                        OUT PUNICODE_STRING ModuleName)
-{
-   PROS_SECTION_OBJECT Section;
-   PMEMORY_AREA MemoryArea;
-   PMMSUPPORT AddressSpace;
-   POBJECT_NAME_INFORMATION ModuleNameInformation;
-   NTSTATUS Status = STATUS_ADDRESS_NOT_ASSOCIATED;
+    ASSERT(IsPowerOf2(nSectionAlignment));
+    ASSERT(IsPowerOf2(nFileAlignment));
 
-   /* Get the MM_AVL_TABLE from EPROCESS */
-   if (Address >= MmSystemRangeStart)
-   {
-      AddressSpace = MmGetKernelAddressSpace();
-   }
-   else
-   {
-      AddressSpace = &PsGetCurrentProcess()->Vm;
-   }
+    switch(piohOptHeader->Magic)
+    {
+       /* PE32 */
+       case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+       {
+           if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase))
+               ImageSectionObject->ImageBase = piohOptHeader->ImageBase;
 
-   /* Lock address space */
-   MmLockAddressSpace(AddressSpace);
+           if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage))
+               ImageSectionObject->ImageSize = piohOptHeader->SizeOfImage;
 
-   /* Locate the memory area for the process by address */
-   MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
+           if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve))
+               ImageSectionObject->StackReserve = piohOptHeader->SizeOfStackReserve;
 
-   /* Make sure it's a section view type */
-   if ((MemoryArea != NULL) && (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW))
-   {
-      /* Get the section pointer to the SECTION_OBJECT */
-      Section = MemoryArea->Data.SectionData.Section;
+           if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit))
+               ImageSectionObject->StackCommit = piohOptHeader->SizeOfStackCommit;
 
-      /* Unlock address space */
-      MmUnlockAddressSpace(AddressSpace);
+           break;
+       }
 
-      /* Get the filename of the section */
-      Status = MmGetFileNameForSection(Section,&ModuleNameInformation);
+       /* PE32+ */
+       case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+       {
+           const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader;
 
-      if (NT_SUCCESS(Status))
-      {
-         /* Init modulename */
-         RtlCreateUnicodeString(ModuleName,
-                                ModuleNameInformation->Name.Buffer);
-
-         /* Free temp taged buffer from MmGetFileNameForSection() */
-         ExFreePoolWithTag(ModuleNameInformation, '  mM');
-         DPRINT("Found ModuleName %S by address %p\n",
-                ModuleName->Buffer,Address);
-      }
-   }
-   else
-   {
-      /* Unlock address space */
-      MmUnlockAddressSpace(AddressSpace);
-   }
+           pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader;
 
-   return Status;
+           if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, ImageBase))
+           {
+               if(pioh64OptHeader->ImageBase > MAXULONG_PTR)
+                   DIE(("ImageBase exceeds the address space\n"));
+
+               ImageSectionObject->ImageBase = (ULONG_PTR)pioh64OptHeader->ImageBase;
+           }
+
+           if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfImage))
+           {
+               if(pioh64OptHeader->SizeOfImage > MAXULONG_PTR)
+                   DIE(("SizeOfImage exceeds the address space\n"));
+
+               ImageSectionObject->ImageSize = pioh64OptHeader->SizeOfImage;
+           }
+
+           if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackReserve))
+           {
+               if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR)
+                   DIE(("SizeOfStackReserve exceeds the address space\n"));
+
+               ImageSectionObject->StackReserve = (ULONG_PTR)pioh64OptHeader->SizeOfStackReserve;
+           }
+
+           if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackCommit))
+           {
+               if(pioh64OptHeader->SizeOfStackCommit > MAXULONG_PTR)
+                   DIE(("SizeOfStackCommit exceeds the address space\n"));
+
+               ImageSectionObject->StackCommit = (ULONG_PTR)pioh64OptHeader->SizeOfStackCommit;
+           }
+
+           break;
+       }
+    }
+
+    /* [1], section 3.4.2 */
+    if((ULONG_PTR)ImageSectionObject->ImageBase % 0x10000)
+       DIE(("ImageBase is not aligned on a 64KB boundary"));
+
+    if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem))
+    {
+       ImageSectionObject->Subsystem = piohOptHeader->Subsystem;
+
+       if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
+          RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MajorSubsystemVersion))
+       {
+           ImageSectionObject->MinorSubsystemVersion = piohOptHeader->MinorSubsystemVersion;
+           ImageSectionObject->MajorSubsystemVersion = piohOptHeader->MajorSubsystemVersion;
+       }
+    }
+
+    if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
+    {
+       ImageSectionObject->EntryPoint = piohOptHeader->ImageBase +
+                                         piohOptHeader->AddressOfEntryPoint;
+    }
+
+    if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode))
+       ImageSectionObject->Executable = piohOptHeader->SizeOfCode != 0;
+    else
+       ImageSectionObject->Executable = TRUE;
+
+    ImageSectionObject->ImageCharacteristics = pinhNtHeader->FileHeader.Characteristics;
+    ImageSectionObject->Machine = pinhNtHeader->FileHeader.Machine;
+
+    /* SECTION HEADERS */
+    nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+    /* see [1], section 3.3 */
+    if(pinhNtHeader->FileHeader.NumberOfSections > 96)
+       DIE(("Too many sections, NumberOfSections is %u\n", pinhNtHeader->FileHeader.NumberOfSections));
+
+    /*
+     * the additional segment is for the file's headers. They need to be present for
+     * the benefit of the dynamic loader (to locate exports, defaults for thread
+     * parameters, resources, etc.)
+     */
+    ImageSectionObject->NrSegments = pinhNtHeader->FileHeader.NumberOfSections + 1;
+
+    /* file offset for the section headers */
+    if(!Intsafe_AddULong32(&cbSectionHeadersOffset, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
+       DIE(("Offset overflow\n"));
+
+    if(!Intsafe_AddULong32(&cbSectionHeadersOffset, cbSectionHeadersOffset, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
+       DIE(("Offset overflow\n"));
+
+    /* size of the section headers */
+    ASSERT(Intsafe_CanMulULong32(pinhNtHeader->FileHeader.NumberOfSections, sizeof(IMAGE_SECTION_HEADER)));
+    cbSectionHeadersSize = pinhNtHeader->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
+
+    if(!Intsafe_AddULong32(&cbSectionHeadersOffsetSize, cbSectionHeadersOffset, cbSectionHeadersSize))
+       DIE(("Section headers too large\n"));
+
+    /* size of the executable's headers */
+    if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfHeaders))
+    {
+//     if(!IsAligned(piohOptHeader->SizeOfHeaders, nFileAlignment))
+//         DIE(("SizeOfHeaders is not aligned\n"));
+
+       if(cbSectionHeadersSize > piohOptHeader->SizeOfHeaders)
+           DIE(("The section headers overflow SizeOfHeaders\n"));
+
+       cbHeadersSize = piohOptHeader->SizeOfHeaders;
+    }
+    else if(!AlignUp(&cbHeadersSize, cbSectionHeadersOffsetSize, nFileAlignment))
+       DIE(("Overflow aligning the size of headers\n"));
+
+    if(pBuffer)
+    {
+       ExFreePool(pBuffer);
+       pBuffer = NULL;
+    }
+    /* WARNING: pinhNtHeader IS NO LONGER USABLE */
+    /* WARNING: piohOptHeader IS NO LONGER USABLE */
+    /* WARNING: pioh64OptHeader IS NO LONGER USABLE */
+
+    if(FileHeaderSize < cbSectionHeadersOffsetSize)
+       pishSectionHeaders = NULL;
+    else
+    {
+       /*
+        * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
+        * and FileHeaderSize >= cbSectionHeadersOffsetSize, so this holds true too
+        */
+       ASSERT(Intsafe_CanOffsetPointer(FileHeader, cbSectionHeadersOffset));
+       pishSectionHeaders = (PVOID)((UINT_PTR)FileHeader + cbSectionHeadersOffset);
+    }
+
+    /*
+     * the buffer doesn't contain the section headers, or the alignment is wrong:
+     * read the headers from the file
+     */
+    if(FileHeaderSize < cbSectionHeadersOffsetSize ||
+       (UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
+    {
+       PVOID pData;
+       ULONG cbReadSize;
+
+       lnOffset.QuadPart = cbSectionHeadersOffset;
+
+       /* read the header from the file */
+       nStatus = ReadFileCb(File, &lnOffset, cbSectionHeadersSize, &pData, &pBuffer, &cbReadSize);
+
+       if(!NT_SUCCESS(nStatus))
+           DIE(("ReadFile failed with status %08X\n", nStatus));
+
+       ASSERT(pData);
+       ASSERT(pBuffer);
+       ASSERT(cbReadSize > 0);
+
+       nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+       /* the buffer doesn't contain all the section headers */
+       if(cbReadSize < cbSectionHeadersSize)
+           DIE(("The file doesn't contain all of the section headers\n"));
+
+       pishSectionHeaders = pData;
+
+       /* object still not aligned: copy it to the beginning of the buffer */
+       if((UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
+       {
+           ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) == 0);
+           RtlMoveMemory(pBuffer, pData, cbReadSize);
+           pishSectionHeaders = pBuffer;
+       }
+    }
+
+    /* SEGMENTS */
+    /* allocate the segments */
+    nStatus = STATUS_INSUFFICIENT_RESOURCES;
+    ImageSectionObject->Segments = AllocateSegmentsCb(ImageSectionObject->NrSegments);
+
+    if(ImageSectionObject->Segments == NULL)
+        DIE(("AllocateSegments failed\n"));
+
+    /* initialize the headers segment */
+       pssSegments = ImageSectionObject->Segments;
+
+//  ASSERT(IsAligned(cbHeadersSize, nFileAlignment));
+
+    if(!AlignUp(&nFileSizeOfHeaders, cbHeadersSize, nFileAlignment))
+        DIE(("Cannot align the size of the section headers\n"));
+
+    nPrevVirtualEndOfSegment = ALIGN_UP_BY(cbHeadersSize, nSectionAlignment);
+    if (nPrevVirtualEndOfSegment < cbHeadersSize)
+        DIE(("Cannot align the size of the section headers\n"));
+
+    pssSegments[0].FileOffset = 0;
+    pssSegments[0].Protection = PAGE_READONLY;
+    pssSegments[0].Length = nPrevVirtualEndOfSegment;
+    pssSegments[0].RawLength = nFileSizeOfHeaders;
+    pssSegments[0].VirtualAddress = 0;
+    pssSegments[0].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA;
+    pssSegments[0].WriteCopy = TRUE;
+
+    /* skip the headers segment */
+    ++ pssSegments;
+
+    nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+    /* convert the executable sections into segments. See also [1], section 4 */
+    for(i = 0; i < ImageSectionObject->NrSegments - 1; ++ i)
+    {
+       ULONG nCharacteristics;
+
+       /* validate the alignment */
+       if(!IsAligned(pishSectionHeaders[i].VirtualAddress, nSectionAlignment))
+           DIE(("VirtualAddress[%u] is not aligned\n", i));
+
+       /* sections must be contiguous, ordered by base address and non-overlapping */
+       if(pishSectionHeaders[i].VirtualAddress != nPrevVirtualEndOfSegment)
+           DIE(("Memory gap between section %u and the previous\n", i));
+
+       /* ignore explicit BSS sections */
+       if(pishSectionHeaders[i].SizeOfRawData != 0)
+       {
+           /* validate the alignment */
+#if 0
+           /* Yes, this should be a multiple of FileAlignment, but there's
+            * stuff out there that isn't. We can cope with that
+            */
+           if(!IsAligned(pishSectionHeaders[i].SizeOfRawData, nFileAlignment))
+               DIE(("SizeOfRawData[%u] is not aligned\n", i));
+#endif
+
+//         if(!IsAligned(pishSectionHeaders[i].PointerToRawData, nFileAlignment))
+//             DIE(("PointerToRawData[%u] is not aligned\n", i));
+
+           /* conversion */
+           pssSegments[i].FileOffset = pishSectionHeaders[i].PointerToRawData;
+           pssSegments[i].RawLength = pishSectionHeaders[i].SizeOfRawData;
+       }
+       else
+       {
+           ASSERT(pssSegments[i].FileOffset == 0);
+           ASSERT(pssSegments[i].RawLength == 0);
+       }
+
+       ASSERT(Intsafe_CanAddLong64(pssSegments[i].FileOffset, pssSegments[i].RawLength));
+
+       nCharacteristics = pishSectionHeaders[i].Characteristics;
+
+       /* no explicit protection */
+       if((nCharacteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == 0)
+       {
+           if(nCharacteristics & IMAGE_SCN_CNT_CODE)
+               nCharacteristics |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
+
+           if(nCharacteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
+               nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+
+           if(nCharacteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+               nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+       }
+
+       /* see table above */
+       pssSegments[i].Protection = SectionCharacteristicsToProtect[nCharacteristics >> 28];
+       pssSegments[i].WriteCopy = !(nCharacteristics & IMAGE_SCN_MEM_SHARED);
+
+       if(pishSectionHeaders[i].Misc.VirtualSize == 0 || pishSectionHeaders[i].Misc.VirtualSize < pishSectionHeaders[i].SizeOfRawData)
+           pssSegments[i].Length = pishSectionHeaders[i].SizeOfRawData;
+       else
+           pssSegments[i].Length = pishSectionHeaders[i].Misc.VirtualSize;
+
+    pssSegments[i].Length = ALIGN_UP_BY(pssSegments[i].Length, nSectionAlignment);
+    if (pssSegments[i].Length < pssSegments[i].Length)
+           DIE(("Cannot align the virtual size of section %u\n", i));
+
+       if(pssSegments[i].Length == 0)
+           DIE(("Virtual size of section %u is null\n", i));
+
+       pssSegments[i].VirtualAddress = pishSectionHeaders[i].VirtualAddress;
+       pssSegments[i].Characteristics = pishSectionHeaders[i].Characteristics;
+
+       /* ensure the memory image is no larger than 4GB */
+       nPrevVirtualEndOfSegment = pssSegments[i].VirtualAddress + pssSegments[i].Length;
+       if (nPrevVirtualEndOfSegment < pssSegments[i].VirtualAddress)
+           DIE(("The image is too large\n"));
+    }
+
+    if(nSectionAlignment >= PAGE_SIZE)
+       *Flags |= EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED;
+
+    /* Success */
+    nStatus = STATUS_ROS_EXEFMT_LOADED_FORMAT | EXEFMT_LOADED_PE32;
+
+l_Return:
+    if(pBuffer)
+       ExFreePool(pBuffer);
+
+    return nStatus;
 }
 
 /* Note: Mmsp prefix denotes "Memory Manager Section Private". */
@@ -268,7 +744,7 @@ MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp)
  * ARGUMENTS: PFILE_OBJECT to wait for.
  * RETURNS:   Status of the wait.
  */
-static NTSTATUS
+NTSTATUS
 MmspWaitForFileLock(PFILE_OBJECT File)
 {
     return STATUS_SUCCESS;
@@ -355,12 +831,12 @@ MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment)
 VOID
 NTAPI
 MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
-                             ULONG Offset,
-                             ULONG Entry)
+                             ULONG_PTR Offset,
+                             ULONG_PTR Entry)
 {
    PSECTION_PAGE_TABLE Table;
-   ULONG DirectoryOffset;
-   ULONG TableOffset;
+   ULONG_PTR DirectoryOffset;
+   ULONG_PTR TableOffset;
 
    if (Segment->Length <= NR_SECTION_PAGE_TABLES * PAGE_SIZE)
    {
@@ -385,19 +861,19 @@ MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
       }
    }
    TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
-   Table->Entry[TableOffset] = Entry;
+   Table->Entry[TableOffset] = (ULONG)Entry;
 }
 
 
 ULONG
 NTAPI
 MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
-                             ULONG Offset)
+                             ULONG_PTR Offset)
 {
    PSECTION_PAGE_TABLE Table;
    ULONG Entry;
-   ULONG DirectoryOffset;
-   ULONG TableOffset;
+   ULONG_PTR DirectoryOffset;
+   ULONG_PTR TableOffset;
 
    DPRINT("MmGetPageEntrySection(Segment %x, Offset %x)\n", Segment, Offset);
 
@@ -423,7 +899,7 @@ MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
 VOID
 NTAPI
 MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
-                               ULONG Offset)
+                               ULONG_PTR Offset)
 {
    ULONG Entry;
 
@@ -502,7 +978,11 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
             NTSTATUS Status;
             Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
             IsDirectMapped = TRUE;
+#ifndef NEWCC
             Status = CcRosUnmapCacheSegment(Bcb, FileOffset, Dirty);
+#else
+                       Status = STATUS_SUCCESS;
+#endif
             if (!NT_SUCCESS(Status))
             {
                DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n", Status);
@@ -580,6 +1060,7 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
 BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
                        ULONG SegOffset)
 {
+#ifndef NEWCC
    if (!(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
    {
       PBCB Bcb;
@@ -592,6 +1073,7 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
          return TRUE;
       }
    }
+#endif
    return FALSE;
 }
 
@@ -602,7 +1084,7 @@ MiCopyFromUserPage(PFN_NUMBER DestPage, PVOID SourceAddress)
     PEPROCESS Process;
     KIRQL Irql;
     PVOID TempAddress;
-    
+
     Process = PsGetCurrentProcess();
     TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
     if (TempAddress == NULL)
@@ -614,10 +1096,11 @@ MiCopyFromUserPage(PFN_NUMBER DestPage, PVOID SourceAddress)
     return(STATUS_SUCCESS);
 }
 
+#ifndef NEWCC
 NTSTATUS
 NTAPI
 MiReadPage(PMEMORY_AREA MemoryArea,
-           ULONG SegOffset,
+           ULONG_PTR SegOffset,
            PPFN_NUMBER Page)
 /*
  * FUNCTION: Read a page for a section backed memory area.
@@ -628,16 +1111,16 @@ MiReadPage(PMEMORY_AREA MemoryArea,
  */
 {
    ULONG BaseOffset;
-   ULONG FileOffset;
+   ULONG_PTR FileOffset;
    PVOID BaseAddress;
    BOOLEAN UptoDate;
    PCACHE_SEGMENT CacheSeg;
    PFILE_OBJECT FileObject;
    NTSTATUS Status;
-   ULONG RawLength;
+   ULONG_PTR RawLength;
    PBCB Bcb;
    BOOLEAN IsImageSection;
-   ULONG Length;
+   ULONG_PTR Length;
 
    FileObject = MemoryArea->Data.SectionData.Section->FileObject;
    Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
@@ -665,7 +1148,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
        * alignment less than the file system block size.
        */
       Status = CcRosGetCacheSegment(Bcb,
-                                    FileOffset,
+                                    (ULONG)FileOffset,
                                     &BaseOffset,
                                     &BaseAddress,
                                     &UptoDate,
@@ -700,19 +1183,21 @@ MiReadPage(PMEMORY_AREA MemoryArea,
       PEPROCESS Process;
       KIRQL Irql;
       PVOID PageAddr;
-      ULONG CacheSegOffset;
+      ULONG_PTR CacheSegOffset;
 
       /*
        * Allocate a page, this is rather complicated by the possibility
        * we might have to move other things out of memory
        */
+      MI_SET_USAGE(MI_USAGE_SECTION);
+      MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
       Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page);
       if (!NT_SUCCESS(Status))
       {
          return(Status);
       }
       Status = CcRosGetCacheSegment(Bcb,
-                                    FileOffset,
+                                    (ULONG)FileOffset,
                                     &BaseOffset,
                                     &BaseAddress,
                                     &UptoDate,
@@ -753,7 +1238,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
          MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
          CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
          Status = CcRosGetCacheSegment(Bcb,
-                                       FileOffset + CacheSegOffset,
+                                       (ULONG)(FileOffset + CacheSegOffset),
                                        &BaseOffset,
                                        &BaseAddress,
                                        &UptoDate,
@@ -790,28 +1275,55 @@ MiReadPage(PMEMORY_AREA MemoryArea,
    }
    return(STATUS_SUCCESS);
 }
+#else
+NTSTATUS
+NTAPI
+MiReadPage(PMEMORY_AREA MemoryArea,
+           ULONG SegOffset,
+           PPFN_NUMBER Page)
+/*
+ * FUNCTION: Read a page for a section backed memory area.
+ * PARAMETERS:
+ *       MemoryArea - Memory area to read the page for.
+ *       Offset - Offset of the page to read.
+ *       Page - Variable that receives a page contains the read data.
+ */
+{
+   MM_REQUIRED_RESOURCES Resources = { };
+
+   Resources.Context = MemoryArea->Data.SectionData.Section->FileObject;
+   Resources.FileOffset.QuadPart = SegOffset +
+          MemoryArea->Data.SectionData.Segment->FileOffset;
+   Resources.Consumer = MC_USER;
+   Resources.Amount = PAGE_SIZE;
+
+   DPRINT1("%S, offset %x, len %d, page %x\n", ((PFILE_OBJECT)Resources.Context)->FileName.Buffer, Resources.FileOffset.LowPart, Resources.Amount, Resources.Page[0]);
+
+   NTSTATUS Status = MiReadFilePage(NULL, NULL, &Resources);
+   *Page = Resources.Page[0];
+   return Status;
+}
+#endif
 
 NTSTATUS
 NTAPI
 MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
                              MEMORY_AREA* MemoryArea,
-                             PVOID Address,
-                             BOOLEAN Locked)
+                             PVOID Address)
 {
    ULONG Offset;
    PFN_NUMBER Page;
    NTSTATUS Status;
-   PVOID PAddress;
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
-   ULONG Entry;
-   ULONG Entry1;
+   ULONG_PTR Entry;
+   ULONG_PTR Entry1;
    ULONG Attributes;
    PMM_PAGEOP PageOp;
    PMM_REGION Region;
    BOOLEAN HasSwapEntry;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-    
+
    /*
     * There is a window between taking the page fault and locking the
     * address space when another thread could load the page so we check
@@ -821,10 +1333,18 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
    {
       return(STATUS_SUCCESS);
    }
+   
+   /*
+    * Check for the virtual memory area being deleted.
+    */
+   if (MemoryArea->DeleteInProgress)
+   {
+      return(STATUS_UNSUCCESSFUL);
+   }
 
-   PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-   Offset = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
-            + MemoryArea->Data.SectionData.ViewOffset;
+   Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
+   Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+            + MemoryArea->Data.SectionData.ViewOffset);
 
    Segment = MemoryArea->Data.SectionData.Segment;
    Section = MemoryArea->Data.SectionData.Section;
@@ -839,7 +1359,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Check if this page needs to be mapped COW
     */
-   if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if ((Segment->WriteCopy) &&
        (Region->Protect == PAGE_READWRITE ||
        Region->Protect == PAGE_EXECUTE_READWRITE))
    {
@@ -911,7 +1431,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       if (!MmIsPagePresent(Process, Address))
       {
          Entry = MmGetPageEntrySectionSegment(Segment, Offset);
-         HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+         HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)Address);
 
          if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
          {
@@ -940,7 +1460,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
             DPRINT1("Unable to create virtual mapping\n");
             KeBugCheck(MEMORY_MANAGEMENT);
          }
-         MmInsertRmap(Page, Process, (PVOID)PAddress);
+         MmInsertRmap(Page, Process, Address);
       }
       MmUnlockSectionSegment(Segment);
       PageOp->Status = STATUS_SUCCESS;
@@ -949,7 +1469,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       return(STATUS_SUCCESS);
    }
 
-   HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+   HasSwapEntry = MmIsPageSwapEntry(Process, Address);
    if (HasSwapEntry)
    {
       /*
@@ -967,9 +1487,12 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       }
 
       MmUnlockSectionSegment(Segment);
-      MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
+      MmDeletePageFileMapping(Process, Address, &SwapEntry);
 
       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))
       {
@@ -1003,8 +1526,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Add the page to the process's working set
        */
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
-
+      MmInsertRmap(Page, Process, Address);
       /*
        * Finish the operation
        */
@@ -1051,6 +1573,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
    if (Segment->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
    {
       MmUnlockSectionSegment(Segment);
+      MI_SET_USAGE(MI_USAGE_SECTION);
+      if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+      if (!Process) MI_SET_PROCESS2("Kernel Section");
       Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
       if (!NT_SUCCESS(Status))
       {
@@ -1073,7 +1598,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
           KeBugCheck(MEMORY_MANAGEMENT);
          return(Status);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
 
       /*
        * Cleanup and release locks
@@ -1105,11 +1630,15 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
           (Offset >= PAGE_ROUND_UP(Segment->RawLength) && 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
       {
@@ -1147,7 +1676,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       if (Entry != Entry1)
       {
          DPRINT1("Someone changed ppte entry while we slept\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
+                KeBugCheck(MEMORY_MANAGEMENT);
       }
 
       /*
@@ -1168,7 +1697,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
 
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
@@ -1187,7 +1716,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       MmUnlockSectionSegment(Segment);
 
       MmUnlockAddressSpace(AddressSpace);
-
+      MI_SET_USAGE(MI_USAGE_SECTION);
+      if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+      if (!Process) MI_SET_PROCESS2("Kernel Section");
       Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
       if (!NT_SUCCESS(Status))
       {
@@ -1239,7 +1770,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
       DPRINT("Address 0x%.8X\n", Address);
@@ -1267,7 +1798,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
       DPRINT("Address 0x%.8X\n", Address);
@@ -1279,28 +1810,25 @@ NTSTATUS
 NTAPI
 MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
                          MEMORY_AREA* MemoryArea,
-                         PVOID Address,
-                         BOOLEAN Locked)
+                         PVOID Address)
 {
    PMM_SECTION_SEGMENT Segment;
    PROS_SECTION_OBJECT Section;
    PFN_NUMBER OldPage;
    PFN_NUMBER NewPage;
    NTSTATUS Status;
-   PVOID PAddress;
    ULONG Offset;
    PMM_PAGEOP PageOp;
    PMM_REGION Region;
    ULONG Entry;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-    
-   DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address, Locked);
+
+   DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address);
 
    /*
-    * Check if the page has been paged out or has already been set readwrite
+    * Check if the page has already been set readwrite
     */
-   if (!MmIsPagePresent(Process, Address) ||
-         MmGetPageProtect(Process, Address) & PAGE_READWRITE)
+   if (MmGetPageProtect(Process, Address) & PAGE_READWRITE)
    {
       DPRINT("Address 0x%.8X\n", Address);
       return(STATUS_SUCCESS);
@@ -1309,9 +1837,9 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Find the offset of the page
     */
-   PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-   Offset = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
-            + MemoryArea->Data.SectionData.ViewOffset;
+   Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
+   Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+            + MemoryArea->Data.SectionData.ViewOffset);
 
    Segment = MemoryArea->Data.SectionData.Segment;
    Section = MemoryArea->Data.SectionData.Section;
@@ -1323,7 +1851,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
     */
    MmLockSectionSegment(Segment);
 
-   OldPage = MmGetPfnForProcess(NULL, Address);
+   OldPage = MmGetPfnForProcess(Process, Address);
    Entry = MmGetPageEntrySectionSegment(Segment, Offset);
 
    MmUnlockSectionSegment(Segment);
@@ -1331,7 +1859,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Check if we are doing COW
     */
-   if (!((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if (!((Segment->WriteCopy) &&
          (Region->Protect == PAGE_READWRITE ||
           Region->Protect == PAGE_EXECUTE_READWRITE)))
    {
@@ -1343,7 +1871,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
        PFN_FROM_SSE(Entry) != OldPage)
    {
       /* This is a private page. We must only change the page protection. */
-      MmSetPageProtect(Process, PAddress, Region->Protect);
+      MmSetPageProtect(Process, Address, Region->Protect);
       return(STATUS_SUCCESS);
    }
 
@@ -1395,6 +1923,9 @@ MmAccessFaultSectionView(PMMSUPPORT 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))
    {
@@ -1404,7 +1935,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Copy the old page
     */
-   MiCopyFromUserPage(NewPage, PAddress);
+   MiCopyFromUserPage(NewPage, Address);
 
    MmLockAddressSpace(AddressSpace);
    /*
@@ -1435,8 +1966,8 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Unshare the old page.
     */
-   MmDeleteRmap(OldPage, Process, PAddress);
-   MmInsertRmap(NewPage, Process, PAddress);
+   MmDeleteRmap(OldPage, Process, Address);
+   MmInsertRmap(NewPage, Process, Address);
    MmLockSectionSegment(Segment);
    MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE);
    MmUnlockSectionSegment(Segment);
@@ -1506,12 +2037,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    ULONG FileOffset;
    NTSTATUS Status;
    PFILE_OBJECT FileObject;
+#ifndef NEWCC
    PBCB Bcb = NULL;
+#endif
    BOOLEAN DirectMapped;
    BOOLEAN IsImageSection;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
    KIRQL OldIrql;
-    
+
    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
    /*
@@ -1520,14 +2053,15 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    Context.Segment = MemoryArea->Data.SectionData.Segment;
    Context.Section = MemoryArea->Data.SectionData.Section;
 
-   Context.Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-                    + MemoryArea->Data.SectionData.ViewOffset;
+   Context.Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+                    + MemoryArea->Data.SectionData.ViewOffset);
    FileOffset = Context.Offset + Context.Segment->FileOffset;
 
    IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
 
    FileObject = Context.Section->FileObject;
    DirectMapped = FALSE;
+#ifndef NEWCC
    if (FileObject != NULL &&
        !(Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
    {
@@ -1544,6 +2078,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
          DirectMapped = TRUE;
       }
    }
+#endif
 
 
    /*
@@ -1571,6 +2106,18 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    Page = MmGetPfnForProcess(Process, Address);
    SwapEntry = MmGetSavedSwapEntryPage(Page);
 
+   /*
+    * Check the reference count to ensure this page can be paged out
+    */
+   if (MmGetReferenceCountPage(Page) != 1)
+   {
+       DPRINT1("Cannot page out locked section page: 0x%p (RefCount: %d)\n",
+               Page, MmGetReferenceCountPage(Page));
+       PageOp->Status = STATUS_UNSUCCESSFUL;
+       MmspCompleteAndReleasePageOp(PageOp);
+       return STATUS_UNSUCCESSFUL;
+   }
+
    /*
     * Prepare the context structure for the rmap delete call.
     */
@@ -1674,7 +2221,11 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
                  Address);
          KeBugCheck(MEMORY_MANAGEMENT);
       }
+#ifndef NEWCC
       Status = CcRosUnmapCacheSegment(Bcb, FileOffset, FALSE);
+#else
+         Status = STATUS_SUCCESS;
+#endif
       if (!NT_SUCCESS(Status))
       {
          DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status);
@@ -1856,7 +2407,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
                        PVOID Address,
                        PMM_PAGEOP PageOp)
 {
-   ULONG Offset;
+   ULONG_PTR Offset;
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
    PFN_NUMBER Page;
@@ -1952,7 +2503,9 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
    if (DirectMapped && !Private)
    {
       ASSERT(SwapEntry == 0);
-      CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
+#ifndef NEWCC
+      CcRosMarkDirtyCacheSegment(Bcb, (ULONG)Offset + Segment->FileOffset);
+#endif
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
       return(STATUS_SUCCESS);
@@ -2000,7 +2553,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
 static VOID
 MmAlterViewAttributes(PMMSUPPORT AddressSpace,
                       PVOID BaseAddress,
-                      ULONG RegionSize,
+                      SIZE_T RegionSize,
                       ULONG OldType,
                       ULONG OldProtect,
                       ULONG NewType,
@@ -2013,9 +2566,10 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
 
    MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+   ASSERT(MemoryArea);
    Segment = MemoryArea->Data.SectionData.Segment;
 
-   if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if ((Segment->WriteCopy) &&
          (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE))
    {
       DoCOW = TRUE;
@@ -2034,7 +2588,7 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
           */
          if (DoCOW && MmIsPagePresent(Process, Address))
          {
-            ULONG Offset;
+            ULONG_PTR Offset;
             ULONG Entry;
             PFN_NUMBER Page;
 
@@ -2066,7 +2620,7 @@ NTAPI
 MmProtectSectionView(PMMSUPPORT AddressSpace,
                      PMEMORY_AREA MemoryArea,
                      PVOID BaseAddress,
-                     ULONG Length,
+                     SIZE_T Length,
                      ULONG Protect,
                      PULONG OldProtect)
 {
@@ -2076,7 +2630,7 @@ MmProtectSectionView(PMMSUPPORT AddressSpace,
 
    MaxLength = (ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)BaseAddress;
    if (Length > MaxLength)
-      Length = MaxLength;
+      Length = (ULONG)MaxLength;
 
    Region = MmFindRegion(MemoryArea->StartingAddress,
                          &MemoryArea->Data.SectionData.RegionListHead,
@@ -2144,7 +2698,7 @@ MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
    ULONG Length;
    ULONG Offset;
    ULONG Entry;
-   ULONG SavedSwapEntry;
+   SWAPENTRY SavedSwapEntry;
    PFN_NUMBER Page;
 
    Page = 0;
@@ -2240,7 +2794,9 @@ MmpDeleteSection(PVOID ObjectBody)
    }
    if (Section->FileObject != NULL)
    {
+#ifndef NEWCC
       CcRosDereferenceCache(Section->FileObject);
+#endif
       ObDereferenceObject(Section->FileObject);
       Section->FileObject = NULL;
    }
@@ -2330,7 +2886,7 @@ MmInitSectionImplementation(VOID)
    ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
    ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
-    
+
    MmCreatePhysicalMemorySection();
 
    return(STATUS_SUCCESS);
@@ -2645,7 +3201,9 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
    MmUnlockSectionSegment(Segment);
    Section->FileObject = FileObject;
    Section->MaximumSize = MaximumSize;
+#ifndef NEWCC
    CcRosReferenceCache(FileObject);
+#endif
    //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
    *SectionObject = Section;
    return(STATUS_SUCCESS);
@@ -2795,7 +3353,7 @@ ExeFmtpReadFile(IN PVOID File,
 
       if(NT_SUCCESS(Status))
       {
-         UsedSize = Iosb.Information;
+         UsedSize = (ULONG)Iosb.Information;
       }
    }
 #endif
@@ -3007,13 +3565,13 @@ MmspPageAlignSegments
          EffectiveSegment->VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress);
 
          /* Round up the virtual size to the nearest page */
-         EffectiveSegment->Length = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length) -
-                                    EffectiveSegment->VirtualAddress;
+         EffectiveSegment->Length = (ULONG)(PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length) -
+                                    EffectiveSegment->VirtualAddress);
 
          /* Adjust the raw address and size */
          VirtualOffset = VirtualAddress - EffectiveSegment->VirtualAddress;
 
-         if (EffectiveSegment->FileOffset < VirtualOffset)
+         if (EffectiveSegment->FileOffset < (LONG_PTR)VirtualOffset)
          {
             return FALSE;
          }
@@ -3023,8 +3581,8 @@ MmspPageAlignSegments
           * offset point in curious and odd places, but that's what we were
           * asked for
           */
-         EffectiveSegment->FileOffset -= VirtualOffset;
-         EffectiveSegment->RawLength += VirtualOffset;
+         EffectiveSegment->FileOffset -= (ULONG)VirtualOffset;
+         EffectiveSegment->RawLength += (ULONG)VirtualOffset;
       }
       else
       {
@@ -3108,8 +3666,8 @@ MmspPageAlignSegments
              */
             ASSERT(PAGE_ROUND_UP(Segment->VirtualAddress + Segment->Length) >= EndOfEffectiveSegment);
 
-            EffectiveSegment->Length = PAGE_ROUND_UP(Segment->VirtualAddress + Segment->Length) -
-                                       EffectiveSegment->VirtualAddress;
+            EffectiveSegment->Length = (ULONG)(PAGE_ROUND_UP(Segment->VirtualAddress + Segment->Length) -
+                                       EffectiveSegment->VirtualAddress);
 
             /*
              * Merge the protection
@@ -3376,11 +3934,15 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
    Section->SectionPageProtection = SectionPageProtection;
    Section->AllocationAttributes = AllocationAttributes;
 
+#ifndef NEWCC
    /*
     * Initialized caching for this file object if previously caching
     * was initialized for the same on disk file
     */
    Status = CcTryToInitializeFileCache(FileObject);
+#else
+   Status = STATUS_SUCCESS;
+#endif
 
    if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL)
    {
@@ -3473,7 +4035,9 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
       Status = STATUS_SUCCESS;
    }
    Section->FileObject = FileObject;
+#ifndef NEWCC
    CcRosReferenceCache(FileObject);
+#endif
    //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
    *SectionObject = Section;
    return(Status);
@@ -3518,7 +4082,6 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace,
    MArea->Data.SectionData.Segment = Segment;
    MArea->Data.SectionData.Section = Section;
    MArea->Data.SectionData.ViewOffset = ViewOffset;
-   MArea->Data.SectionData.WriteCopyView = FALSE;
    MmInitializeRegion(&MArea->Data.SectionData.RegionListHead,
                       ViewSize, 0, Protect);
 
@@ -3548,8 +4111,8 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
 
    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
-   Offset = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
-            MemoryArea->Data.SectionData.ViewOffset;
+   Offset = (ULONG)(((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
+            MemoryArea->Data.SectionData.ViewOffset);
 
    Section = MemoryArea->Data.SectionData.Section;
    Segment = MemoryArea->Data.SectionData.Segment;
@@ -3586,7 +4149,9 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
       {
          FileObject = MemoryArea->Data.SectionData.Section->FileObject;
          Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+#ifndef NEWCC
          CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
+#endif
          ASSERT(SwapEntry == 0);
       }
    }
@@ -3732,7 +4297,7 @@ MmUnmapViewOfSection(PEPROCESS Process,
          Offset -= PAGE_SIZE;
          PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL,
                                    MemoryArea->Data.SectionData.Segment,
-                                   Offset + MemoryArea->Data.SectionData.ViewOffset);
+                                   (ULONG)Offset + MemoryArea->Data.SectionData.ViewOffset);
          if (PageOp)
          {
             MmUnlockAddressSpace(AddressSpace);
@@ -3775,14 +4340,11 @@ MmUnmapViewOfSection(PEPROCESS Process,
        * and calculate the image base address */
       for (i = 0; i < NrSegments; i++)
       {
-         if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-         {
-            if (Segment == &SectionSegments[i])
-            {
-               ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress;
-               break;
-            }
-         }
+          if (Segment == &SectionSegments[i])
+          {
+              ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress;
+              break;
+          }
       }
       if (i >= NrSegments)
       {
@@ -3791,13 +4353,10 @@ MmUnmapViewOfSection(PEPROCESS Process,
 
       for (i = 0; i < NrSegments; i++)
       {
-         if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-         {
-            PVOID SBaseAddress = (PVOID)
-                                 ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress);
+          PVOID SBaseAddress = (PVOID)
+                               ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress);
 
-            Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
-         }
+          Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
       }
    }
    else
@@ -3856,7 +4415,7 @@ NtQuerySection(IN HANDLE SectionHandle,
                                         ExSectionInfoClass,
                                         sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]),
                                         SectionInformation,
-                                        SectionInformationLength,
+                                        (ULONG)SectionInformationLength,
                                         NULL,
                                         ResultLength,
                                         PreviousMode);
@@ -3955,9 +4514,6 @@ NtQuerySection(IN HANDLE SectionHandle,
    return(Status);
 }
 
-
-
-
 /**********************************************************************
  * NAME       EXPORTED
  * MmMapViewOfSection
@@ -4023,6 +4579,21 @@ MmMapViewOfSection(IN PVOID SectionObject,
    PMMSUPPORT AddressSpace;
    ULONG ViewOffset;
    NTSTATUS Status = STATUS_SUCCESS;
+   BOOLEAN NotAtBase = FALSE;
+
+   if ((ULONG_PTR)SectionObject & 1)
+   {
+       return MmMapViewOfArm3Section((PVOID)((ULONG_PTR)SectionObject & ~1),
+                                     Process,
+                                     BaseAddress,
+                                     ZeroBits,
+                                     CommitSize,
+                                     SectionOffset,
+                                     ViewSize,
+                                     InheritDisposition,
+                                     AllocationType,
+                                     Protect);
+   }
 
    ASSERT(Process);
 
@@ -4044,7 +4615,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
       ULONG i;
       ULONG NrSegments;
       ULONG_PTR ImageBase;
-      ULONG ImageSize;
+      SIZE_T ImageSize;
       PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
       PMM_SECTION_SEGMENT SectionSegments;
 
@@ -4062,16 +4633,19 @@ MmMapViewOfSection(IN PVOID SectionObject,
       ImageSize = 0;
       for (i = 0; i < NrSegments; i++)
       {
-         if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-         {
-            ULONG_PTR MaxExtent;
-            MaxExtent = (ULONG_PTR)SectionSegments[i].VirtualAddress +
-                        SectionSegments[i].Length;
-            ImageSize = max(ImageSize, MaxExtent);
-         }
+          ULONG_PTR MaxExtent;
+          MaxExtent = (ULONG_PTR)SectionSegments[i].VirtualAddress +
+                      SectionSegments[i].Length;
+          ImageSize = max(ImageSize, MaxExtent);
       }
 
-      ImageSectionObject->ImageSize = ImageSize;
+      ImageSectionObject->ImageSize = (ULONG)ImageSize;
+
+      /* Check for an illegal base address */
+      if ((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress)
+      {
+          ImageBase = PAGE_ROUND_DOWN((ULONG_PTR)MmHighestUserAddress - ImageSize);
+      }
 
       /* Check there is enough space to map the section at that point. */
       if (MmLocateMemoryAreaByRegion(AddressSpace, (PVOID)ImageBase,
@@ -4090,33 +4664,33 @@ MmMapViewOfSection(IN PVOID SectionObject,
             MmUnlockAddressSpace(AddressSpace);
             return(STATUS_UNSUCCESSFUL);
          }
+         /* Remember that we loaded image at a different base address */
+         NotAtBase = TRUE;
       }
 
       for (i = 0; i < NrSegments; i++)
       {
-         if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-         {
-            PVOID SBaseAddress = (PVOID)
-                                 ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress);
-            MmLockSectionSegment(&SectionSegments[i]);
-            Status = MmMapViewOfSegment(AddressSpace,
-                                        Section,
-                                        &SectionSegments[i],
-                                        &SBaseAddress,
-                                        SectionSegments[i].Length,
-                                        SectionSegments[i].Protection,
-                                        0,
-                                        0);
-            MmUnlockSectionSegment(&SectionSegments[i]);
-            if (!NT_SUCCESS(Status))
-            {
-               MmUnlockAddressSpace(AddressSpace);
-               return(Status);
-            }
-         }
+          PVOID SBaseAddress = (PVOID)
+                               ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress);
+          MmLockSectionSegment(&SectionSegments[i]);
+          Status = MmMapViewOfSegment(AddressSpace,
+                                      Section,
+                                      &SectionSegments[i],
+                                      &SBaseAddress,
+                                      SectionSegments[i].Length,
+                                      SectionSegments[i].Protection,
+                                      0,
+                                      0);
+          MmUnlockSectionSegment(&SectionSegments[i]);
+          if (!NT_SUCCESS(Status))
+          {
+              MmUnlockAddressSpace(AddressSpace);
+              return(Status);
+          }
       }
 
       *BaseAddress = (PVOID)ImageBase;
+      *ViewSize = ImageSize;
    }
    else
    {
@@ -4194,7 +4768,12 @@ MmMapViewOfSection(IN PVOID SectionObject,
 
    MmUnlockAddressSpace(AddressSpace);
 
-   return(STATUS_SUCCESS);
+   if (NotAtBase)
+       Status = STATUS_IMAGE_NOT_AT_BASE;
+   else
+       Status = STATUS_SUCCESS;
+
+   return Status;
 }
 
 /*
@@ -4233,7 +4812,7 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
       else
       {
          /* Something must gone wrong
-          * how can we have a Section but no 
+          * how can we have a Section but no
           * reference? */
          DPRINT("ERROR: DataSectionObject without reference!\n");
       }
@@ -4262,7 +4841,9 @@ MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
          {
             return FALSE;
          }
+#ifndef NEWCC
          CcRosSetRemoveOnClose(SectionObjectPointer);
+#endif
          return TRUE;
       case MmFlushForWrite:
          break;
@@ -4281,10 +4862,10 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
    PROS_SECTION_OBJECT Section;
    PMMSUPPORT AddressSpace;
    NTSTATUS Status;
+   PAGED_CODE();
 
     if ((ULONG_PTR)SectionObject & 1)
     {
-        PAGED_CODE();
         extern PVOID MmSession;
         return MiMapViewInSystemSpace((PVOID)((ULONG_PTR)SectionObject & ~1),
                                       &MmSession,
@@ -4339,8 +4920,12 @@ MmUnmapViewInSystemSpace (IN PVOID MappedBase)
    DPRINT("MmUnmapViewInSystemSpace() called\n");
 
    AddressSpace = MmGetKernelAddressSpace();
+   
+   MmLockAddressSpace(AddressSpace);
 
    Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
+   
+   MmUnlockAddressSpace(AddressSpace);
 
    return Status;
 }
@@ -4413,9 +4998,9 @@ MmCreateSection (OUT PVOID  * Section,
 {
    ULONG Protection;
    PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
-   
+
     /* Check if an ARM3 section is being created instead */
-    if (AllocationAttributes & 0xC0000000)
+    if (AllocationAttributes & 1)
     {
         DPRINT1("arm 3 path\n");
         return MmCreateArm3Section(Section,
@@ -4423,7 +5008,7 @@ MmCreateSection (OUT PVOID  * Section,
                                    ObjectAttributes,
                                    MaximumSize,
                                    SectionPageProtection,
-                                   AllocationAttributes &~ 0xC0000000,
+                                   AllocationAttributes &~ 1,
                                    FileHandle,
                                    File);
     }