[NTOS:MM] Fix NtFreeVirtualMemory() FreeType parameter checks. CORE-13126
[reactos.git] / ntoskrnl / mm / ARM3 / virtual.c
index 95c1571..fc4ea2e 100644 (file)
@@ -267,7 +267,7 @@ MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress,
     while (!MmIsAddressValid(VirtualAddress))
     {
         /* Release the PFN database */
-        KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+        MiReleasePfnLock(OldIrql);
 
         /* Fault it in */
         Status = MmAccessFault(FALSE, VirtualAddress, KernelMode, NULL);
@@ -285,7 +285,7 @@ MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress,
         LockChange = TRUE;
 
         /* Lock the PFN database */
-        OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+        OldIrql = MiAcquirePfnLock();
     }
 
     /* Let caller know what the lock state is */
@@ -337,7 +337,7 @@ MiDeleteSystemPageableVm(IN PMMPTE PointerPte,
                 Pfn2 = MiGetPfnEntry(PageTableIndex);
 
                 /* Lock the PFN database */
-                OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+                OldIrql = MiAcquirePfnLock();
 
                 /* Delete it the page */
                 MI_SET_PFN_DELETED(Pfn1);
@@ -347,7 +347,7 @@ MiDeleteSystemPageableVm(IN PMMPTE PointerPte,
                 MiDecrementShareCount(Pfn2, PageTableIndex);
 
                 /* Release the PFN database */
-                KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+                MiReleasePfnLock(OldIrql);
 
                 /* Destroy the PTE */
                 MI_ERASE_PTE(PointerPte);
@@ -399,7 +399,7 @@ MiDeletePte(IN PMMPTE PointerPte,
     PMMPDE PointerPde;
 
     /* PFN lock must be held */
-    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    MI_ASSERT_PFN_LOCK_HELD();
 
     /* Capture the PTE */
     TempPte = *PointerPte;
@@ -419,6 +419,9 @@ MiDeletePte(IN PMMPTE PointerPte,
 
             DPRINT("Pte %p is transitional!\n", PointerPte);
 
+            /* Make sure the saved PTE address is valid */
+            ASSERT((PMMPTE)((ULONG_PTR)Pfn1->PteAddress & ~0x1) == PointerPte);
+
             /* Destroy the PTE */
             MI_ERASE_PTE(PointerPte);
 
@@ -428,17 +431,14 @@ MiDeletePte(IN PMMPTE PointerPte,
             ASSERT(Pfn1->u3.e1.PrototypePte == 0);
 
             /* Make the page free. For prototypes, it will be made free when deleting the section object */
-            if (Pfn1->u2.ShareCount == 0)
+            if (Pfn1->u3.e2.ReferenceCount == 0)
             {
-                ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
-
                 /* And it should be in standby or modified list */
                 ASSERT((Pfn1->u3.e1.PageLocation == ModifiedPageList) || (Pfn1->u3.e1.PageLocation == StandbyPageList));
 
-                /* Unlink it and temporarily mark it as active */
+                /* Unlink it and set its reference count to one */
                 MiUnlinkPageFromList(Pfn1);
                 Pfn1->u3.e2.ReferenceCount++;
-                Pfn1->u3.e1.PageLocation = ActiveAndValid;
 
                 /* This will put it back in free list and clean properly up */
                 MI_SET_PFN_DELETED(Pfn1);
@@ -626,7 +626,7 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
         }
 
         /* Lock the PFN Database while we delete the PTEs */
-        OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+        OldIrql = MiAcquirePfnLock();
         do
         {
             /* Capture the PDE and make sure it exists */
@@ -708,7 +708,7 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
         }
 
         /* Release the lock and get out if we're done */
-        KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+        MiReleasePfnLock(OldIrql);
         if (Va > EndingAddress) return;
 
         /* Otherwise, we exited because we hit a new PDE boundary, so start over */
@@ -1379,7 +1379,7 @@ MiGetPageProtection(IN PMMPTE PointerPte)
         {
             /* The PTE is valid, so we might need to get the protection from
                the PFN. Lock the PFN database */
-            OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+            OldIrql = MiAcquirePfnLock();
 
             /* Check if the PDE is still valid */
             if (MiAddressToPte(PointerPte)->u.Hard.Valid == 0)
@@ -1407,7 +1407,7 @@ MiGetPageProtection(IN PMMPTE PointerPte)
             }
 
             /* Release the PFN database */
-            KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+            MiReleasePfnLock(OldIrql);
         }
 
         /* Lock the working set again */
@@ -2301,7 +2301,7 @@ MiProtectVirtualMemory(IN PEPROCESS Process,
                 if ((NewAccessProtection & PAGE_NOACCESS) ||
                     (NewAccessProtection & PAGE_GUARD))
                 {
-                    KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+                    KIRQL OldIrql = MiAcquirePfnLock();
 
                     /* Mark the PTE as transition and change its protection */
                     PteContents.u.Hard.Valid = 0;
@@ -2318,7 +2318,7 @@ MiProtectVirtualMemory(IN PEPROCESS Process,
                     KeInvalidateTlbEntry(MiPteToAddress(PointerPte));
 
                     /* We are done for this PTE */
-                    KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+                    MiReleasePfnLock(OldIrql);
                 }
                 else
                 {
@@ -2459,7 +2459,7 @@ MiProcessValidPteList(IN PMMPTE *ValidPteList,
     //
     // Acquire the PFN lock and loop all the PTEs in the list
     //
-    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+    OldIrql = MiAcquirePfnLock();
     for (i = 0; i != Count; i++)
     {
         //
@@ -2494,7 +2494,7 @@ MiProcessValidPteList(IN PMMPTE *ValidPteList,
     // and then release the PFN lock
     //
     KeFlushCurrentTb();
-    KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+    MiReleasePfnLock(OldIrql);
 }
 
 ULONG
@@ -2670,7 +2670,7 @@ MmSecureVirtualMemory(IN PVOID Address,
                       IN SIZE_T Length,
                       IN ULONG Mode)
 {
-    static BOOLEAN Warn; if (!Warn++) UNIMPLEMENTED;
+    static ULONG Warn; if (!Warn++) UNIMPLEMENTED;
     return Address;
 }
 
@@ -2681,7 +2681,7 @@ VOID
 NTAPI
 MmUnsecureVirtualMemory(IN PVOID SecureMem)
 {
-    static BOOLEAN Warn; if (!Warn++) UNIMPLEMENTED;
+    static ULONG Warn; if (!Warn++) UNIMPLEMENTED;
 }
 
 /* SYSTEM CALLS ***************************************************************/
@@ -5108,21 +5108,11 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
     PAGED_CODE();
 
     //
-    // Only two flags are supported
-    //
-    if (!(FreeType & (MEM_RELEASE | MEM_DECOMMIT)))
-    {
-        DPRINT1("Invalid FreeType\n");
-        return STATUS_INVALID_PARAMETER_4;
-    }
-
-    //
-    // Check if no flag was used, or if both flags were used
+    // Only two flags are supported, exclusively.
     //
-    if (!((FreeType & (MEM_DECOMMIT | MEM_RELEASE))) ||
-         ((FreeType & (MEM_DECOMMIT | MEM_RELEASE)) == (MEM_DECOMMIT | MEM_RELEASE)))
+    if (FreeType != MEM_RELEASE && FreeType != MEM_DECOMMIT)
     {
-        DPRINT1("Invalid FreeType combination\n");
+        DPRINT1("Invalid FreeType (0x%08lx)\n", FreeType);
         return STATUS_INVALID_PARAMETER_4;
     }
 
@@ -5200,8 +5190,8 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
         }
     }
 
-    DPRINT("NtFreeVirtualMemory: Process 0x%p, Adress 0x%p, size 0x%x, FreeType %x.\n",
-        Process, PBaseAddress, PRegionSize, FreeType);
+    DPRINT("NtFreeVirtualMemory: Process 0x%p, Address 0x%p, Size 0x%Ix, FreeType 0x%08lx\n",
+           Process, PBaseAddress, PRegionSize, FreeType);
 
     //
     // Lock the address space
@@ -5383,10 +5373,10 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
                     Vad->u.VadFlags.CommitCharge -= CommitReduction;
                     // For ReactOS: shrink the corresponding memory area
                     MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)StartingAddress);
-                    ASSERT(Vad->StartingVpn == MemoryArea->StartingVpn);
-                    ASSERT(Vad->EndingVpn == MemoryArea->EndingVpn);
+                    ASSERT(Vad->StartingVpn == MemoryArea->VadNode.StartingVpn);
+                    ASSERT(Vad->EndingVpn == MemoryArea->VadNode.EndingVpn);
                     Vad->EndingVpn = (StartingAddress - 1) >> PAGE_SHIFT;
-                    MemoryArea->EndingVpn = Vad->EndingVpn;
+                    MemoryArea->VadNode.EndingVpn = Vad->EndingVpn;
                 }
                 else
                 {