Proper cleanup after processes

svn path=/trunk/; revision=1676
This commit is contained in:
David Welch 2001-03-08 22:06:02 +00:00
parent 03e327f37f
commit 6e89a9d21c
16 changed files with 235 additions and 136 deletions

View file

@ -1,4 +1,4 @@
/* $Id: cleanup.c,v 1.1 2001/03/07 13:44:40 ekohl Exp $
/* $Id: cleanup.c,v 1.2 2001/03/08 22:06:02 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -44,7 +44,7 @@ VfatCleanup (PDEVICE_OBJECT DeviceObject, PIRP Irp)
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status;
DPRINT1("VfatCleanup(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
DPRINT("VfatCleanup(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
Status = VfatCleanupFile(DeviceExtension, FileObject);

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.13 2001/03/07 08:57:08 dwelch Exp $
# $Id: Makefile,v 1.14 2001/03/08 22:06:00 dwelch Exp $
#
# ReactOS Operating System
#
@ -10,6 +10,8 @@ OBJECTS_PATH = objects
ASFLAGS = -Iinclude
CFLAGS = -Iinclude -D__NTOSKRNL__ -DDBG -g -Wall -Werror
# -W -Wpointer-arith -Wconversion -Wstrict-prototypes -Wundef \
# -Wmissing-prototypes -Wshadow\
#CFLAGS += -DDBGPRINT_FILE_LOG
all: \
@ -37,7 +39,7 @@ OBJECTS_NT = \
nt/profile.o \
nt/zw.o \
nt/vdm.o
# Run-Time Library (Rtl)
OBJECTS_RTL = \
rtl/bitmap.o \
@ -100,7 +102,8 @@ OBJECTS_KE_I386 = \
ke/i386/tskswitch.o \
ke/i386/v86m.o \
ke/i386/v86m_sup.o \
ke/i386/bios.o
ke/i386/bios.o \
ke/i386/i386-mcount.o
# Memory Manager (Mm)
OBJECTS_MM = \

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: view.c,v 1.16 2001/03/07 16:48:40 dwelch Exp $
/* $Id: view.c,v 1.17 2001/03/08 22:06:01 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -191,11 +191,8 @@ CcRequestCacheSegment(PBCB Bcb,
}
static
VOID CcFreeCachePage(PVOID Context, PVOID Address)
VOID CcFreeCachePage(PVOID Context, PVOID Address, ULONG PhysAddr)
{
ULONG PhysAddr;
PhysAddr = MmGetPhysicalAddressForProcess(NULL, Address);
if (PhysAddr != 0)
{
MmDereferencePage((PVOID)PhysAddr);

View file

@ -183,7 +183,8 @@ VOID ExInitNonPagedPool(ULONG BaseAddress);
NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
PVOID BaseAddress,
ULONG Length,
VOID (*FreePage)(PVOID Context, PVOID Address),
VOID (*FreePage)(PVOID Context, PVOID Address,
ULONG PhysAddr),
PVOID FreePageContext);
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
@ -416,5 +417,9 @@ VOID
MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
VOID
MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
VOID
MmMarkPageMapped(PVOID PhysicalAddress);
VOID
MmMarkPageUnmapped(PVOID PhysicalAddress);
#endif

View file

@ -0,0 +1,52 @@
/* i386-specific implemetation of profiling support.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* We need a special version of the `mcount' function since for ix86 it
must not clobber any register. This has several reasons:
- there is a bug in gcc as of version 2.7.2.2 which prohibits the
use of profiling together with nested functions
- the ELF `fixup' function uses GCC's regparm feature
- some (future) systems might want to pass parameters in registers. */
/* dwelch: Alerted for ReactOS to output the files to port 0xe9 for processing
by bochs. */
.globl _mcount
_mcount:
/* Save the caller-clobbered registers. */
pushl %eax
pushl %ecx
pushl %edx
movw $0xe9, %dx
movl 4(%ebp), %eax
outl %eax, %dx
movl 12(%esp), %eax
outl %eax, %dx
/* Pop the saved registers. Please note that `mcount' has no
return value. */
popl %edx
popl %ecx
popl %eax
ret

View file

@ -88,29 +88,7 @@ KeValidateUserContext(PCONTEXT Context)
return(STATUS_SUCCESS);
}
NTSTATUS
HalReleaseTask(PETHREAD Thread)
/*
* FUNCTION: Releases the resource allocated for a thread by
* HalInitTaskWithContext or HalInitTask
* NOTE: The thread had better not be running when this is called
*/
{
#if 0
extern BYTE init_stack[MM_STACK_SIZE];
KeFreeGdtSelector(Thread->Tcb.Context.nr / 8);
if (Thread->Tcb.Context.KernelStackBase != init_stack)
{
ExFreePool(Thread->Tcb.Context.KernelStackBase);
}
if (Thread->Tcb.Context.SavedKernelStackBase != NULL)
{
ExFreePool(Thread->Tcb.Context.SavedKernelStackBase);
}
#endif
return(STATUS_SUCCESS);
}
NTSTATUS
Ke386InitThreadWithContext(PKTHREAD Thread, PCONTEXT Context)

View file

@ -17,19 +17,16 @@
/* FUNCTIONS *****************************************************************/
VOID InsertBeforeEntryInList(PLIST_ENTRY Head, PLIST_ENTRY After,
PLIST_ENTRY Entry)
VOID
InsertBeforeEntryInList(PLIST_ENTRY Head, PLIST_ENTRY After, PLIST_ENTRY Entry)
{
InsertHeadList(After, Entry);
}
BOOLEAN
STDCALL
KeInsertByKeyDeviceQueue (
PKDEVICE_QUEUE DeviceQueue,
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
ULONG SortKey
)
BOOLEAN STDCALL
KeInsertByKeyDeviceQueue (PKDEVICE_QUEUE DeviceQueue,
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
ULONG SortKey)
{
KIRQL oldlvl;
PLIST_ENTRY current;

View file

@ -58,6 +58,27 @@ PiSuspendThreadNormalRoutine(PVOID NormalContext,
/* FUNCTIONS *****************************************************************/
NTSTATUS
HalReleaseTask(PETHREAD Thread)
/*
* FUNCTION: Releases the resource allocated for a thread by
* HalInitTaskWithContext or HalInitTask
* NOTE: The thread had better not be running when this is called
*/
{
extern unsigned int init_stack;
if (Thread->Tcb.StackLimit != (ULONG)&init_stack)
{
ExFreePool((PVOID)Thread->Tcb.StackLimit);
}
Thread->Tcb.StackLimit = 0;
Thread->Tcb.InitialStack = NULL;
Thread->Tcb.StackBase = NULL;
Thread->Tcb.KernelStack = NULL;
return(STATUS_SUCCESS);
}
VOID
KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
/*
@ -87,7 +108,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->InitialStack = (PVOID)&init_stack_top;
Thread->StackBase = (PVOID)&init_stack_top;
Thread->StackLimit = (ULONG)&init_stack;
Thread->KernelStack = (PVOID)&init_stack;
Thread->KernelStack = (PVOID)&init_stack_top;
}
/*
* The Native API function will initialize the TEB field later

View file

@ -1,4 +1,4 @@
/* $Id: cont.c,v 1.8 2001/02/28 18:23:32 dwelch Exp $
/* $Id: cont.c,v 1.9 2001/03/08 22:06:01 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -18,12 +18,9 @@
/* FUNCTIONS *****************************************************************/
VOID static
MmFreeContinuousPage(PVOID Context, PVOID Address)
VOID STATIC
MmFreeContinuousPage(PVOID Context, PVOID Address, ULONG PhysAddr)
{
ULONG PhysAddr;
PhysAddr = MmGetPhysicalAddressForProcess(NULL, Address);
if (PhysAddr != 0)
{
MmDereferencePage((PVOID)PhysAddr);

View file

@ -29,12 +29,13 @@
typedef struct _PHYSICAL_PAGE
{
ULONG Flags;
LIST_ENTRY ListEntry;
ULONG ReferenceCount;
KEVENT Event;
SWAPENTRY SavedSwapEntry;
ULONG LockCount;
ULONG Flags;
LIST_ENTRY ListEntry;
ULONG ReferenceCount;
KEVENT Event;
SWAPENTRY SavedSwapEntry;
ULONG LockCount;
ULONG MapCount;
} PHYSICAL_PAGE, *PPHYSICAL_PAGE;
/* GLOBALS ****************************************************************/
@ -104,6 +105,7 @@ MmGetContinuousPages(ULONG NumberOfBytes,
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_USED;
MmPageArray[i].ReferenceCount = 1;
MmPageArray[i].LockCount = 0;
MmPageArray[i].MapCount = 0;
MmPageArray[i].SavedSwapEntry = 0;
InsertTailList(&UsedPageListHead, &MmPageArray[i].ListEntry);
}
@ -302,6 +304,28 @@ VOID MmSetFlagsPage(PVOID PhysicalAddress,
KeReleaseSpinLock(&PageListLock, oldIrql);
}
VOID
MmMarkPageMapped(PVOID PhysicalAddress)
{
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
KIRQL oldIrql;
KeAcquireSpinLock(&PageListLock, &oldIrql);
MmPageArray[Start].MapCount++;
KeReleaseSpinLock(&PageListLock, oldIrql);
}
VOID
MmMarkPageUnmapped(PVOID PhysicalAddress)
{
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
KIRQL oldIrql;
KeAcquireSpinLock(&PageListLock, &oldIrql);
MmPageArray[Start].MapCount--;
KeReleaseSpinLock(&PageListLock, oldIrql);
}
ULONG MmGetFlagsPage(PVOID PhysicalAddress)
{
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
@ -427,20 +451,26 @@ VOID MmDereferencePage(PVOID PhysicalAddress)
}
KeAcquireSpinLock(&PageListLock, &oldIrql);
if (MM_PTYPE(MmPageArray[Start].Flags) != MM_PHYSICAL_PAGE_USED)
{
DbgPrint("Dereferencing free page\n");
KeBugCheck(0);
}
MmPageArray[Start].ReferenceCount--;
if (MmPageArray[Start].ReferenceCount == 0)
{
MmStats.NrFreePages++;
MmStats.NrSystemPages--;
RemoveEntryList(&MmPageArray[Start].ListEntry);
if (MmPageArray[Start].MapCount != 0)
{
DbgPrint("Freeing mapped page (0x%x count %d)\n",
PhysicalAddress, MmPageArray[Start].MapCount);
KeBugCheck(0);
}
if (MmPageArray[Start].LockCount > 0)
{
DbgPrint("Freeing locked page\n");
@ -561,6 +591,7 @@ MmAllocPage(SWAPENTRY SavedSwapEntry)
PageDescriptor->Flags = MM_PHYSICAL_PAGE_USED;
PageDescriptor->ReferenceCount = 1;
PageDescriptor->LockCount = 0;
PageDescriptor->MapCount = 0;
PageDescriptor->SavedSwapEntry = SavedSwapEntry;
ExInterlockedInsertTailList(&UsedPageListHead, ListEntry,
&PageListLock);

View file

@ -1,4 +1,4 @@
/* $Id: page.c,v 1.21 2001/02/18 22:16:05 dwelch Exp $
/* $Id: page.c,v 1.22 2001/03/08 22:06:02 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
@ -349,6 +349,10 @@ VOID MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage)
}
Pte = ADDR_TO_PTE(Address);
WasValid = (PAGE_MASK(*Pte) != 0);
if (WasValid)
{
MmMarkPageUnmapped((PVOID)PAGE_MASK(*Pte));
}
if (FreePage && WasValid)
{
MmDereferencePage((PVOID)PAGE_MASK(*Pte));
@ -528,6 +532,7 @@ NTSTATUS MmCreateVirtualMapping(PEPROCESS Process,
DPRINT1("Setting kernel address with process context\n");
KeBugCheck(0);
}
MmMarkPageMapped((PVOID)PhysicalAddress);
Attributes = ProtectToPTE(flProtect);
@ -545,6 +550,10 @@ NTSTATUS MmCreateVirtualMapping(PEPROCESS Process,
}
return(Status);
}
if (PAGE_MASK((*Pte)) != 0)
{
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte)));
}
*Pte = PhysicalAddress | Attributes;
if (Process != NULL &&
Process->AddressSpace.PageTableRefCountTable != NULL &&

View file

@ -278,7 +278,8 @@ NTSTATUS
MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
PVOID BaseAddress,
ULONG Length,
VOID (*FreePage)(PVOID Context, PVOID Address),
VOID (*FreePage)(PVOID Context, PVOID Address,
ULONG PhysAddr),
PVOID FreePageContext)
{
MEMORY_AREA* MemoryArea;
@ -294,32 +295,24 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
KeBugCheck(0);
return(STATUS_UNSUCCESSFUL);
}
if (FreePage != NULL)
for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGESIZE); i++)
{
for (i=0;i<=(MemoryArea->Length/PAGESIZE);i++)
{
FreePage(FreePageContext,
MemoryArea->BaseAddress + (i * PAGESIZE));
}
}
for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++)
{
if (AddressSpace->Process != NULL)
{
DPRINT("Freeing %x in %d\n",
MemoryArea->BaseAddress + (i*PAGESIZE),
AddressSpace->Process->UniqueProcessId);
}
else
{
// DPRINT("Freeing %x in kernel address space\n");
}
ULONG PhysAddr;
PhysAddr =
MmGetPhysicalAddressForProcess(AddressSpace->Process,
MemoryArea->BaseAddress + (i*PAGESIZE));
MmDeleteVirtualMapping(AddressSpace->Process,
MemoryArea->BaseAddress + (i*PAGESIZE),
FALSE);
if (FreePage != NULL)
{
FreePage(FreePageContext,
MemoryArea->BaseAddress + (i * PAGESIZE), PhysAddr);
}
}
RemoveEntryList(&(MemoryArea->Entry));
RemoveEntryList(&MemoryArea->Entry);
ExFreePool(MemoryArea);
DPRINT("MmFreeMemoryArea() succeeded\n");

View file

@ -1,4 +1,4 @@
/* $Id: mm.c,v 1.43 2001/03/07 16:48:43 dwelch Exp $
/* $Id: mm.c,v 1.44 2001/03/08 22:06:01 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
@ -32,33 +32,53 @@ extern PVOID MmSharedDataPagePhysicalAddress;
/* FUNCTIONS ****************************************************************/
VOID STATIC
MmFreeVirtualMemoryPage(PVOID Context, PVOID Address, ULONG PhysicalAddr)
{
PEPROCESS Process = (PEPROCESS)Context;
if (PhysicalAddr != 0)
{
DPRINT("Freeing page at 0x%x (pa 0x%x)\n",
Address, PhysicalAddr);
MmRemovePageFromWorkingSet(Process, Address);
MmDereferencePage((PVOID)PhysicalAddr);
}
}
NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
{
PVOID i;
NTSTATUS Status;
DPRINT("MmReleaseMemoryArea(Process %x, Marea %x)\n",Process,Marea);
DPRINT("Releasing %x between %x %x\n",
Marea, Marea->BaseAddress, Marea->BaseAddress + Marea->Length);
DPRINT("Releasing %x between %x %x (type %d)\n",
Marea, Marea->BaseAddress, Marea->BaseAddress + Marea->Length,
Marea->Type);
switch (Marea->Type)
{
case MEMORY_AREA_SECTION_VIEW_COMMIT:
case MEMORY_AREA_SECTION_VIEW_RESERVE:
MmUnmapViewOfSection(Process, Marea->BaseAddress);
Status = MmUnmapViewOfSection(Process, Marea->BaseAddress);
assert(Status == STATUS_SUCCESS);
return(STATUS_SUCCESS);
case MEMORY_AREA_VIRTUAL_MEMORY:
for (i = Marea->BaseAddress;
i < (Marea->BaseAddress + Marea->Length);
i = i + PAGESIZE)
{
MmDeleteVirtualMapping(Process, i, TRUE);
}
ExFreePool(Marea);
break;
Status = MmFreeMemoryArea(&Process->AddressSpace,
Marea->BaseAddress,
0,
MmFreeVirtualMemoryPage,
(PVOID)Process);
assert(Status == STATUS_SUCCESS);
break;
case MEMORY_AREA_SHARED_DATA:
Status = MmFreeMemoryArea(&Process->AddressSpace,
Marea->BaseAddress,
0,
NULL,
NULL);
break;
default:
@ -73,14 +93,16 @@ NTSTATUS MmReleaseMmInfo(PEPROCESS Process)
PLIST_ENTRY CurrentEntry;
PMEMORY_AREA Current;
DPRINT("MmReleaseMmInfo(Process %x)\n",Process);
DPRINT("MmReleaseMmInfo(Process %x (%s))\n", Process,
Process->ImageFileName);
MmLockAddressSpace(&Process->AddressSpace);
while (!IsListEmpty(&Process->AddressSpace.MAreaListHead))
CurrentEntry = Process->AddressSpace.MAreaListHead.Flink;
while (CurrentEntry != &Process->AddressSpace.MAreaListHead)
{
CurrentEntry = RemoveHeadList(&Process->AddressSpace.MAreaListHead);
Current = CONTAINING_RECORD(CurrentEntry, MEMORY_AREA, Entry);
CurrentEntry = CurrentEntry->Flink;
MmReleaseMemoryArea(Process, Current);
}

View file

@ -1,4 +1,4 @@
/* $Id: ncache.c,v 1.8 2001/02/10 22:51:10 dwelch Exp $
/* $Id: ncache.c,v 1.9 2001/03/08 22:06:02 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -80,12 +80,9 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
return ((PVOID)Result);
}
VOID static
MmFreeNonCachedPage(PVOID Context, PVOID Address)
VOID STATIC
MmFreeNonCachedPage(PVOID Context, PVOID Address, ULONG PhysAddr)
{
ULONG PhysAddr;
PhysAddr = MmGetPhysicalAddressForProcess(NULL, Address);
if (PhysAddr != 0)
{
MmDereferencePage((PVOID)PhysAddr);

View file

@ -1,4 +1,4 @@
/* $Id: section.c,v 1.48 2001/03/07 16:48:44 dwelch Exp $
/* $Id: section.c,v 1.49 2001/03/08 22:06:02 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -1512,7 +1512,11 @@ MmMapViewOfSegment(PEPROCESS Process,
InsertTailList(&Section->ViewListHead,
&MArea->Data.SectionData.ViewListEntry);
KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
ObReferenceObjectByPointer((PVOID)Section,
SECTION_MAP_READ,
NULL,
ExGetPreviousMode());
MArea->Data.SectionData.Segment = Segment;
MArea->Data.SectionData.Section = Section;
MArea->Data.SectionData.ViewOffset = ViewOffset;
@ -1695,20 +1699,19 @@ NtMapViewOfSection(HANDLE SectionHandle,
MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process);
ObDereferenceObject(Section);
ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
VOID STATIC
MmFreeSectionPage(PVOID Context, PVOID Address)
MmFreeSectionPage(PVOID Context, PVOID Address, ULONG PhysAddr)
{
ULONG PhysAddr;
PMEMORY_AREA MArea;
MArea = (PMEMORY_AREA)Context;
PhysAddr = MmGetPhysicalAddressForProcess(NULL, Address);
if (PhysAddr != 0)
{
if (MmGetReferenceCountPage((PVOID)PhysAddr) == 1)
@ -1729,7 +1732,7 @@ MmFreeSectionPage(PVOID Context, PVOID Address)
NTSTATUS STDCALL
MmUnmapViewOfSection(PEPROCESS Process,
PVOID BaseAddress)
PVOID BaseAddress)
{
NTSTATUS Status;
PMEMORY_AREA MemoryArea;
@ -1774,9 +1777,9 @@ MmUnmapViewOfSection(PEPROCESS Process,
MmFreeSectionPage,
MemoryArea);
}
ObDereferenceObject(Section);
MmUnlockSection(Section);
MmUnlockSectionSegment(Segment);
ObDereferenceObject(Section);
MmUnlockAddressSpace(AddressSpace);
return(STATUS_SUCCESS);
}

View file

@ -1,4 +1,4 @@
/* $Id: virtual.c,v 1.40 2001/03/07 16:48:44 dwelch Exp $
/* $Id: virtual.c,v 1.41 2001/03/08 22:06:02 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
@ -269,7 +269,8 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
/*
* Add the page to the process's working set
*/
MmAddPageToWorkingSet(PsGetCurrentProcess(), Address);
MmAddPageToWorkingSet(PsGetCurrentProcess(),
(PVOID)PAGE_ROUND_DOWN(Address));
/*
* Set the page. If we fail because we are out of memory then
@ -338,15 +339,15 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
LARGE_INTEGER PhysicalAddr;
PhysicalAddr = MmGetPhysicalAddress(BaseAddress + (i*PAGESIZE));
MmDeleteVirtualMapping(AddressSpace->Process,
BaseAddress + (i*PAGESIZE),
FALSE);
if (PhysicalAddr.u.LowPart != 0)
{
MmRemovePageFromWorkingSet(AddressSpace->Process,
BaseAddress + (i*PAGESIZE));
MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart));
}
MmDeleteVirtualMapping(AddressSpace->Process,
BaseAddress + (i*PAGESIZE),
FALSE);
}
}
@ -947,6 +948,17 @@ NtFlushVirtualMemory(IN HANDLE ProcessHandle,
UNIMPLEMENTED;
}
VOID STATIC
MmFreeVirtualMemoryPage(PVOID Context, PVOID Address, ULONG PhysicalAddr)
{
PEPROCESS Process = (PEPROCESS)Context;
if (PhysicalAddr != 0)
{
MmRemovePageFromWorkingSet(Process, Address);
MmDereferencePage((PVOID)PhysicalAddr);
}
}
NTSTATUS STDCALL
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
@ -970,7 +982,6 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
NTSTATUS Status;
PEPROCESS Process;
PMADDRESS_SPACE AddressSpace;
ULONG i;
PVOID BaseAddress;
ULONG RegionSize;
@ -1023,28 +1034,11 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
}
#endif
for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++)
{
ULONG PhysicalAddr;
PhysicalAddr =
MmGetPhysicalAddressForProcess(Process,
MemoryArea->BaseAddress +
(i*PAGESIZE));
if (PhysicalAddr != 0)
{
MmRemovePageFromWorkingSet(AddressSpace->Process,
MemoryArea->BaseAddress +
(i*PAGESIZE));
MmDereferencePage((PVOID)(ULONG)(PhysicalAddr));
}
}
MmFreeMemoryArea(&Process->AddressSpace,
BaseAddress,
0,
NULL,
NULL);
MmFreeVirtualMemoryPage,
(PVOID)Process);
MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process);
return(STATUS_SUCCESS);