[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / section.c
index d590530..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:
 //
@@ -1309,13 +1309,11 @@ 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_PTR Entry;
@@ -1335,9 +1333,17 @@ 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)((ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+   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;
@@ -1425,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)
          {
@@ -1454,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;
@@ -1463,7 +1469,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       return(STATUS_SUCCESS);
    }
 
-   HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+   HasSwapEntry = MmIsPageSwapEntry(Process, Address);
    if (HasSwapEntry)
    {
       /*
@@ -1481,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);
@@ -1520,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
        */
@@ -1593,7 +1598,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
           KeBugCheck(MEMORY_MANAGEMENT);
          return(Status);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
 
       /*
        * Cleanup and release locks
@@ -1633,7 +1638,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
          {
             DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status);
          }
-                
+
       }
       else
       {
@@ -1692,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);
@@ -1765,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);
@@ -1793,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);
@@ -1805,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);
@@ -1835,8 +1837,8 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Find the offset of the page
     */
-   PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-   Offset = (ULONG)((ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+   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;
@@ -1849,7 +1851,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
     */
    MmLockSectionSegment(Segment);
 
-   OldPage = MmGetPfnForProcess(NULL, Address);
+   OldPage = MmGetPfnForProcess(Process, Address);
    Entry = MmGetPageEntrySectionSegment(Segment, Offset);
 
    MmUnlockSectionSegment(Segment);
@@ -1869,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);
    }
 
@@ -1933,7 +1935,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Copy the old page
     */
-   MiCopyFromUserPage(NewPage, PAddress);
+   MiCopyFromUserPage(NewPage, Address);
 
    MmLockAddressSpace(AddressSpace);
    /*
@@ -1964,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);
@@ -2104,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.
     */
@@ -2552,6 +2566,7 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
 
    MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+   ASSERT(MemoryArea);
    Segment = MemoryArea->Data.SectionData.Segment;
 
    if ((Segment->WriteCopy) &&
@@ -4626,6 +4641,12 @@ MmMapViewOfSection(IN PVOID SectionObject,
 
       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,
                                      PAGE_ROUND_UP(ImageSize)) != NULL)
@@ -4899,8 +4920,12 @@ MmUnmapViewInSystemSpace (IN PVOID MappedBase)
    DPRINT("MmUnmapViewInSystemSpace() called\n");
 
    AddressSpace = MmGetKernelAddressSpace();
+   
+   MmLockAddressSpace(AddressSpace);
 
    Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
+   
+   MmUnlockAddressSpace(AddressSpace);
 
    return Status;
 }