Merge 36852, 37322, 37333, 37334, 43428, 43451, 44259, 46404 from amd64 branch.
[reactos.git] / reactos / ntoskrnl / mm / anonmem.c
index 9a310bd..5645352 100644 (file)
@@ -53,7 +53,7 @@ MmWritePageVirtualMemory(PMMSUPPORT AddressSpace,
                          PMM_PAGEOP PageOp)
 {
    SWAPENTRY SwapEntry;
-   PFN_TYPE Page;
+   PFN_NUMBER Page;
    NTSTATUS Status;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
 
@@ -135,7 +135,7 @@ MmPageOutVirtualMemory(PMMSUPPORT AddressSpace,
                        PVOID Address,
                        PMM_PAGEOP PageOp)
 {
-   PFN_TYPE Page;
+   PFN_NUMBER Page;
    BOOLEAN WasDirty;
    SWAPENTRY SwapEntry;
    NTSTATUS Status;
@@ -253,7 +253,7 @@ MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
  * NOTES: This function is called with the address space lock held.
  */
 {
-   PFN_TYPE Page;
+   PFN_NUMBER Page;
    NTSTATUS Status;
    PMM_REGION Region;
    PMM_PAGEOP PageOp;
@@ -266,10 +266,6 @@ MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
     */
    if (MmIsPagePresent(NULL, Address))
    {
-      if (Locked)
-      {
-         MmLockPage(MmGetPfnForProcess(NULL, Address));
-      }
       return(STATUS_SUCCESS);
    }
 
@@ -360,10 +356,6 @@ MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
          return(Status);
       }
       MmLockAddressSpace(AddressSpace);
-      if (Locked)
-      {
-         MmLockPage(MmGetPfnForProcess(NULL, Address));
-      }
       KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
       MmReleasePageOp(PageOp);
       return(STATUS_SUCCESS);
@@ -435,10 +427,6 @@ MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
    /*
     * Finish the operation
     */
-   if (Locked)
-   {
-      MmLockPage(Page);
-   }
    PageOp->Status = STATUS_SUCCESS;
    KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
    MmReleasePageOp(PageOp);
@@ -469,7 +457,7 @@ MmModifyAttributes(PMMSUPPORT AddressSpace,
 
       for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
       {
-         PFN_TYPE Page;
+         PFN_NUMBER Page;
 
          if (MmIsPageSwapEntry(Process,
                                (char*)BaseAddress + (i * PAGE_SIZE)))
@@ -659,9 +647,8 @@ NtAllocateVirtualMemory(IN     HANDLE ProcessHandle,
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
-      /* Get the exception code */
-      Status = _SEH2_GetExceptionCode();
-      _SEH2_YIELD(return Status);
+      /* Return the exception code */
+      _SEH2_YIELD(return _SEH2_GetExceptionCode());
    }
    _SEH2_END;
 
@@ -730,6 +717,36 @@ NtAllocateVirtualMemory(IN     HANDLE ProcessHandle,
       {
          MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
                             (ULONG_PTR)MemoryArea->StartingAddress;
+
+         if (((ULONG_PTR)BaseAddress + RegionSize) > (ULONG_PTR)MemoryArea->EndingAddress)
+         {
+            DPRINT("BaseAddress + RegionSize %x is larger than MemoryArea's EndingAddress %x\n",
+                  (ULONG_PTR)BaseAddress + RegionSize, MemoryArea->EndingAddress);
+
+            MmUnlockAddressSpace(AddressSpace);
+            ObDereferenceObject(Process);
+
+            return STATUS_MEMORY_NOT_ALLOCATED;
+         }
+
+         if (AllocationType == MEM_RESET)
+         {
+            if (MmIsPagePresent(Process, BaseAddress))
+            {
+               /* FIXME: mark pages as not modified */
+            }
+            else
+            {
+               /* FIXME: if pages are in paging file discard them and bring in pages of zeros */
+            }
+
+            MmUnlockAddressSpace(AddressSpace);
+            ObDereferenceObject(Process);
+
+            /* MEM_RESET does not modify any attributes of region */
+            return STATUS_SUCCESS;
+         }
+
          if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY &&
              MemoryAreaLength >= RegionSize)
          {
@@ -836,7 +853,7 @@ static VOID
 MmFreeVirtualMemoryPage(PVOID Context,
                         MEMORY_AREA* MemoryArea,
                         PVOID Address,
-                        PFN_TYPE Page,
+                        PFN_NUMBER Page,
                         SWAPENTRY SwapEntry,
                         BOOLEAN Dirty)
 {
@@ -955,6 +972,8 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
    PVOID BaseAddress;
    ULONG RegionSize;
 
+   PAGED_CODE();
+
    DPRINT("NtFreeVirtualMemory(ProcessHandle %x, *PBaseAddress %x, "
           "*PRegionSize %x, FreeType %x)\n",ProcessHandle,*PBaseAddress,
           *PRegionSize,FreeType);
@@ -965,6 +984,22 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
         return STATUS_INVALID_PARAMETER_4;
     }
 
+    if (ExGetPreviousMode() != KernelMode)
+    {
+        _SEH2_TRY
+        {
+            /* Probe user pointers */
+            ProbeForWriteSize_t(PRegionSize);
+            ProbeForWritePointer(PBaseAddress);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
+        }
+        _SEH2_END;
+    }
+
    BaseAddress = (PVOID)PAGE_ROUND_DOWN((*PBaseAddress));
    RegionSize = PAGE_ROUND_UP((ULONG_PTR)(*PBaseAddress) + (*PRegionSize)) -
                 PAGE_ROUND_DOWN((*PBaseAddress));