[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / section.c
index 6948d47..596be8a 100644 (file)
@@ -87,7 +87,7 @@ MmMapViewOfArm3Section(IN PVOID SectionObject,
                        IN SECTION_INHERIT InheritDisposition,
                        IN ULONG AllocationType,
                        IN ULONG Protect);
-                       
+
 //
 // PeFmtCreateSection depends on the following:
 //
@@ -161,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[] =
 {
@@ -203,7 +203,7 @@ NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
     PMM_SECTION_SEGMENT pssSegments;
     LARGE_INTEGER lnOffset;
     PVOID pBuffer;
-    ULONG nPrevVirtualEndOfSegment = 0;
+    SIZE_T nPrevVirtualEndOfSegment = 0;
     ULONG nFileSizeOfHeaders = 0;
     ULONG i;
 
@@ -429,7 +429,7 @@ l_ReadHeaderFromFile:
                if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR)
                    DIE(("SizeOfStackReserve exceeds the address space\n"));
 
-               ImageSectionObject->StackReserve = pioh64OptHeader->SizeOfStackReserve;
+               ImageSectionObject->StackReserve = (ULONG_PTR)pioh64OptHeader->SizeOfStackReserve;
            }
 
            if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackCommit))
@@ -437,7 +437,7 @@ l_ReadHeaderFromFile:
                if(pioh64OptHeader->SizeOfStackCommit > MAXULONG_PTR)
                    DIE(("SizeOfStackCommit exceeds the address space\n"));
 
-               ImageSectionObject->StackCommit = pioh64OptHeader->SizeOfStackCommit;
+               ImageSectionObject->StackCommit = (ULONG_PTR)pioh64OptHeader->SizeOfStackCommit;
            }
 
            break;
@@ -582,7 +582,7 @@ l_ReadHeaderFromFile:
     ImageSectionObject->Segments = AllocateSegmentsCb(ImageSectionObject->NrSegments);
 
     if(ImageSectionObject->Segments == NULL)
-       DIE(("AllocateSegments failed\n"));
+        DIE(("AllocateSegments failed\n"));
 
     /* initialize the headers segment */
        pssSegments = ImageSectionObject->Segments;
@@ -590,10 +590,11 @@ l_ReadHeaderFromFile:
 //  ASSERT(IsAligned(cbHeadersSize, nFileAlignment));
 
     if(!AlignUp(&nFileSizeOfHeaders, cbHeadersSize, nFileAlignment))
-       DIE(("Cannot align the size of the section headers\n"));
+        DIE(("Cannot align the size of the section headers\n"));
 
-    if(!AlignUp(&nPrevVirtualEndOfSegment, cbHeadersSize, nSectionAlignment))
-       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;
@@ -672,11 +673,10 @@ l_ReadHeaderFromFile:
        else
            pssSegments[i].Length = pishSectionHeaders[i].Misc.VirtualSize;
 
-       if(!AlignUp(&pssSegments[i].Length, pssSegments[i].Length, nSectionAlignment))
+    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));
 
-       ASSERT(IsAligned(pssSegments[i].Length, nSectionAlignment));
-
        if(pssSegments[i].Length == 0)
            DIE(("Virtual size of section %u is null\n", i));
 
@@ -684,8 +684,9 @@ l_ReadHeaderFromFile:
        pssSegments[i].Characteristics = pishSectionHeaders[i].Characteristics;
 
        /* ensure the memory image is no larger than 4GB */
-       if(!Intsafe_AddULong32(&nPrevVirtualEndOfSegment, pssSegments[i].VirtualAddress, pssSegments[i].Length))
-           DIE(("The image is larger than 4GB\n"));
+       nPrevVirtualEndOfSegment = pssSegments[i].VirtualAddress + pssSegments[i].Length;
+       if (nPrevVirtualEndOfSegment < pssSegments[i].VirtualAddress)
+           DIE(("The image is too large\n"));
     }
 
     if(nSectionAlignment >= PAGE_SIZE)
@@ -830,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)
    {
@@ -860,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);
 
@@ -898,7 +899,7 @@ MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
 VOID
 NTAPI
 MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
-                               ULONG Offset)
+                               ULONG_PTR Offset)
 {
    ULONG Entry;
 
@@ -1083,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)
@@ -1099,7 +1100,7 @@ MiCopyFromUserPage(PFN_NUMBER DestPage, PVOID SourceAddress)
 NTSTATUS
 NTAPI
 MiReadPage(PMEMORY_AREA MemoryArea,
-           ULONG SegOffset,
+           ULONG_PTR SegOffset,
            PPFN_NUMBER Page)
 /*
  * FUNCTION: Read a page for a section backed memory area.
@@ -1110,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;
@@ -1147,7 +1148,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
        * alignment less than the file system block size.
        */
       Status = CcRosGetCacheSegment(Bcb,
-                                    FileOffset,
+                                    (ULONG)FileOffset,
                                     &BaseOffset,
                                     &BaseAddress,
                                     &UptoDate,
@@ -1182,7 +1183,7 @@ 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
@@ -1196,7 +1197,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
          return(Status);
       }
       Status = CcRosGetCacheSegment(Bcb,
-                                    FileOffset,
+                                    (ULONG)FileOffset,
                                     &BaseOffset,
                                     &BaseAddress,
                                     &UptoDate,
@@ -1237,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,
@@ -1289,9 +1290,9 @@ MiReadPage(PMEMORY_AREA MemoryArea,
  */
 {
    MM_REQUIRED_RESOURCES Resources = { };
-   
+
    Resources.Context = MemoryArea->Data.SectionData.Section->FileObject;
-   Resources.FileOffset.QuadPart = SegOffset + 
+   Resources.FileOffset.QuadPart = SegOffset +
           MemoryArea->Data.SectionData.Segment->FileOffset;
    Resources.Consumer = MC_USER;
    Resources.Amount = PAGE_SIZE;
@@ -1308,23 +1309,21 @@ 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
@@ -1334,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;
@@ -1424,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)
          {
@@ -1453,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;
@@ -1462,7 +1469,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       return(STATUS_SUCCESS);
    }
 
-   HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+   HasSwapEntry = MmIsPageSwapEntry(Process, Address);
    if (HasSwapEntry)
    {
       /*
@@ -1480,7 +1487,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       }
 
       MmUnlockSectionSegment(Segment);
-      MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
+      MmDeletePageFileMapping(Process, Address, &SwapEntry);
 
       MmUnlockAddressSpace(AddressSpace);
       MI_SET_USAGE(MI_USAGE_SECTION);
@@ -1519,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
        */
@@ -1592,7 +1598,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
           KeBugCheck(MEMORY_MANAGEMENT);
          return(Status);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
 
       /*
        * Cleanup and release locks
@@ -1632,7 +1638,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
          {
             DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status);
          }
-                
+
       }
       else
       {
@@ -1691,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);
@@ -1764,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);
@@ -1792,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);
@@ -1804,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);
@@ -1834,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;
@@ -1848,7 +1851,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
     */
    MmLockSectionSegment(Segment);
 
-   OldPage = MmGetPfnForProcess(NULL, Address);
+   OldPage = MmGetPfnForProcess(Process, Address);
    Entry = MmGetPageEntrySectionSegment(Segment, Offset);
 
    MmUnlockSectionSegment(Segment);
@@ -1868,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);
    }
 
@@ -1932,7 +1935,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Copy the old page
     */
-   MiCopyFromUserPage(NewPage, PAddress);
+   MiCopyFromUserPage(NewPage, Address);
 
    MmLockAddressSpace(AddressSpace);
    /*
@@ -1963,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);
@@ -2041,7 +2044,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    BOOLEAN IsImageSection;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
    KIRQL OldIrql;
-    
+
    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
    /*
@@ -2050,8 +2053,8 @@ 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;
@@ -2103,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.
     */
@@ -2392,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;
@@ -2489,7 +2504,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
    {
       ASSERT(SwapEntry == 0);
 #ifndef NEWCC
-      CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
+      CcRosMarkDirtyCacheSegment(Bcb, (ULONG)Offset + Segment->FileOffset);
 #endif
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
@@ -2538,7 +2553,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
 static VOID
 MmAlterViewAttributes(PMMSUPPORT AddressSpace,
                       PVOID BaseAddress,
-                      ULONG RegionSize,
+                      SIZE_T RegionSize,
                       ULONG OldType,
                       ULONG OldProtect,
                       ULONG NewType,
@@ -2551,6 +2566,7 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
 
    MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+   ASSERT(MemoryArea);
    Segment = MemoryArea->Data.SectionData.Segment;
 
    if ((Segment->WriteCopy) &&
@@ -2572,7 +2588,7 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
           */
          if (DoCOW && MmIsPagePresent(Process, Address))
          {
-            ULONG Offset;
+            ULONG_PTR Offset;
             ULONG Entry;
             PFN_NUMBER Page;
 
@@ -2604,7 +2620,7 @@ NTAPI
 MmProtectSectionView(PMMSUPPORT AddressSpace,
                      PMEMORY_AREA MemoryArea,
                      PVOID BaseAddress,
-                     ULONG Length,
+                     SIZE_T Length,
                      ULONG Protect,
                      PULONG OldProtect)
 {
@@ -2614,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,
@@ -2682,7 +2698,7 @@ MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
    ULONG Length;
    ULONG Offset;
    ULONG Entry;
-   ULONG SavedSwapEntry;
+   SWAPENTRY SavedSwapEntry;
    PFN_NUMBER Page;
 
    Page = 0;
@@ -2870,7 +2886,7 @@ MmInitSectionImplementation(VOID)
    ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
    ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
-    
+
    MmCreatePhysicalMemorySection();
 
    return(STATUS_SUCCESS);
@@ -3337,7 +3353,7 @@ ExeFmtpReadFile(IN PVOID File,
 
       if(NT_SUCCESS(Status))
       {
-         UsedSize = Iosb.Information;
+         UsedSize = (ULONG)Iosb.Information;
       }
    }
 #endif
@@ -3549,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;
          }
@@ -3565,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
       {
@@ -3650,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
@@ -4095,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;
@@ -4281,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);
@@ -4399,7 +4415,7 @@ NtQuerySection(IN HANDLE SectionHandle,
                                         ExSectionInfoClass,
                                         sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]),
                                         SectionInformation,
-                                        SectionInformationLength,
+                                        (ULONG)SectionInformationLength,
                                         NULL,
                                         ResultLength,
                                         PreviousMode);
@@ -4497,7 +4513,7 @@ NtQuerySection(IN HANDLE SectionHandle,
 
    return(Status);
 }
-                       
+
 /**********************************************************************
  * NAME       EXPORTED
  * MmMapViewOfSection
@@ -4578,7 +4594,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
                                      AllocationType,
                                      Protect);
    }
-   
+
    ASSERT(Process);
 
    if (!Protect || Protect & ~PAGE_FLAGS_VALID_FOR_SECTION)
@@ -4599,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;
 
@@ -4623,7 +4639,13 @@ MmMapViewOfSection(IN PVOID SectionObject,
           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,
@@ -4790,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");
       }
@@ -4841,7 +4863,7 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
    PMMSUPPORT AddressSpace;
    NTSTATUS Status;
    PAGED_CODE();
-        
+
     if ((ULONG_PTR)SectionObject & 1)
     {
         extern PVOID MmSession;
@@ -4898,8 +4920,12 @@ MmUnmapViewInSystemSpace (IN PVOID MappedBase)
    DPRINT("MmUnmapViewInSystemSpace() called\n");
 
    AddressSpace = MmGetKernelAddressSpace();
+   
+   MmLockAddressSpace(AddressSpace);
 
    Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
+   
+   MmUnlockAddressSpace(AddressSpace);
 
    return Status;
 }
@@ -4972,7 +4998,7 @@ 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 & 1)
     {