mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +00:00
Fixed memory manager bugs
Removed page directory references from machine independant code Implemented page table reference counting Added vm test application svn path=/trunk/; revision=1309
This commit is contained in:
parent
7c29439d2b
commit
8434fc42db
23 changed files with 632 additions and 254 deletions
|
@ -44,7 +44,7 @@ NET_DRIVERS = ndis tcpip tditest
|
||||||
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS)
|
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS)
|
||||||
|
|
||||||
APPS = args hello shell test cat bench apc shm lpc thread event file gditest \
|
APPS = args hello shell test cat bench apc shm lpc thread event file gditest \
|
||||||
pteb consume dump_shared_data
|
pteb consume dump_shared_data vmtest
|
||||||
|
|
||||||
# objdir
|
# objdir
|
||||||
|
|
||||||
|
|
42
reactos/apps/tests/vmtest/Makefile
Normal file
42
reactos/apps/tests/vmtest/Makefile
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
PATH_TO_TOP = ../..
|
||||||
|
|
||||||
|
OBJECTS = vmtest.o
|
||||||
|
PROGS = vmtest.exe
|
||||||
|
LIBS =
|
||||||
|
CLEAN_FILES = vmtest.o vmtest.exe
|
||||||
|
|
||||||
|
all: vmtest.exe
|
||||||
|
|
||||||
|
clean: $(CLEAN_FILES:%=%_clean)
|
||||||
|
|
||||||
|
$(CLEAN_FILES:%=%_clean): %_clean:
|
||||||
|
- $(RM) $*
|
||||||
|
|
||||||
|
.phony: clean $(CLEAN_FILES:%=%_clean)
|
||||||
|
|
||||||
|
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||||
|
|
||||||
|
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||||
|
ifeq ($(DOSCLI),yes)
|
||||||
|
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||||
|
else
|
||||||
|
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||||
|
endif
|
||||||
|
|
||||||
|
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||||
|
|
||||||
|
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||||
|
ifeq ($(DOSCLI),yes)
|
||||||
|
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||||
|
else
|
||||||
|
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||||
|
endif
|
||||||
|
|
||||||
|
vmtest.exe: $(OBJECTS)
|
||||||
|
$(CC) $(OBJECTS) -o vmtest.exe
|
||||||
|
|
||||||
|
BASE_CFLAGS = -I../../include
|
||||||
|
include ../../rules.mak
|
53
reactos/apps/tests/vmtest/vmtest.c
Normal file
53
reactos/apps/tests/vmtest/vmtest.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
PVOID Base;
|
||||||
|
PVOID Ret;
|
||||||
|
|
||||||
|
Base = VirtualAlloc(NULL,
|
||||||
|
1048576,
|
||||||
|
MEM_RESERVE,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (Base == NULL)
|
||||||
|
{
|
||||||
|
printf("VirtualAlloc failed 1\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = VirtualAlloc(Base + 4096,
|
||||||
|
4096,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (Ret == NULL)
|
||||||
|
{
|
||||||
|
printf("VirtualAlloc failed 2\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = VirtualAlloc(Base + 12288,
|
||||||
|
4096,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (Ret == NULL)
|
||||||
|
{
|
||||||
|
printf("VirtualAlloc failed 3\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = VirtualAlloc(Base + 20480,
|
||||||
|
4096,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (Ret == NULL)
|
||||||
|
{
|
||||||
|
printf("VirtualAlloc failed 4\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = VirtualAlloc(Base + 4096,
|
||||||
|
28672,
|
||||||
|
MEM_RESERVE,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (Ret == NULL)
|
||||||
|
{
|
||||||
|
printf("VirtualAlloc failed 5\n");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.13 2000/08/18 22:27:04 dwelch Exp $
|
# $Id: makefile,v 1.14 2000/08/20 17:02:09 dwelch Exp $
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
PATH_TO_TOP = ../../..
|
PATH_TO_TOP = ../../..
|
||||||
|
@ -20,6 +20,7 @@ clean:
|
||||||
- $(RM) base.tmp
|
- $(RM) base.tmp
|
||||||
- $(RM) temp.exp
|
- $(RM) temp.exp
|
||||||
- $(RM) blue.sys
|
- $(RM) blue.sys
|
||||||
|
- $(RM) blue.sys.unstripped
|
||||||
|
|
||||||
.phony: clean
|
.phony: clean
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.15 2000/08/18 22:27:04 dwelch Exp $
|
# $Id: makefile,v 1.16 2000/08/20 17:02:10 dwelch Exp $
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
PATH_TO_TOP = ../../..
|
PATH_TO_TOP = ../../..
|
||||||
|
@ -20,7 +20,7 @@ clean:
|
||||||
- $(RM) base.tmp
|
- $(RM) base.tmp
|
||||||
- $(RM) temp.exp
|
- $(RM) temp.exp
|
||||||
- $(RM) $(TARGET).sys
|
- $(RM) $(TARGET).sys
|
||||||
- $(RM) $(TARGET).nostrip.sys
|
- $(RM) $(TARGET).sys.unstripped
|
||||||
|
|
||||||
.phony: clean
|
.phony: clean
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.11 2000/08/18 22:27:05 dwelch Exp $
|
# $Id: makefile,v 1.12 2000/08/20 17:02:10 dwelch Exp $
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
PATH_TO_TOP = ../../..
|
PATH_TO_TOP = ../../..
|
||||||
|
@ -20,6 +20,7 @@ clean:
|
||||||
- $(RM) base.tmp
|
- $(RM) base.tmp
|
||||||
- $(RM) temp.exp
|
- $(RM) temp.exp
|
||||||
- $(RM) $(TARGET).sys
|
- $(RM) $(TARGET).sys
|
||||||
|
- $(RM) $(TARGET).sys.unstripped
|
||||||
|
|
||||||
.phony: clean
|
.phony: clean
|
||||||
|
|
||||||
|
|
|
@ -36,3 +36,4 @@ cp apps/pteb/pteb.exe $1/reactos/bin
|
||||||
cp apps/consume/consume.exe $1/reactos/bin
|
cp apps/consume/consume.exe $1/reactos/bin
|
||||||
cp apps/float/float.exe $1/reactos/bin
|
cp apps/float/float.exe $1/reactos/bin
|
||||||
cp apps/dump_shared_data/dump_shared_data.exe $1/reactos/bin
|
cp apps/dump_shared_data/dump_shared_data.exe $1/reactos/bin
|
||||||
|
cp apps/vmtest/vmtest.exe $1/reactos/bin
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: view.c,v 1.9 2000/07/04 08:52:36 dwelch Exp $
|
/* $Id: view.c,v 1.10 2000/08/20 17:02:07 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -119,7 +119,7 @@ NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb,
|
||||||
*BaseAddress = current->BaseAddress;
|
*BaseAddress = current->BaseAddress;
|
||||||
*CacheSeg = current;
|
*CacheSeg = current;
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
MmSetPage(NULL,
|
MmCreateVirtualMapping(NULL,
|
||||||
current->BaseAddress,
|
current->BaseAddress,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)MmAllocPage(0));
|
(ULONG)MmAllocPage(0));
|
||||||
|
|
|
@ -7,11 +7,6 @@
|
||||||
|
|
||||||
struct _EPROCESS;
|
struct _EPROCESS;
|
||||||
|
|
||||||
#define PAGESIZE (4096)
|
|
||||||
|
|
||||||
PULONG MmGetPageEntry(PVOID Address);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Page access attributes (or these together)
|
* Page access attributes (or these together)
|
||||||
*/
|
*/
|
||||||
|
@ -27,6 +22,10 @@ PULONG MmGetPageEntry(PVOID Address);
|
||||||
#define PA_USER (1<<2)
|
#define PA_USER (1<<2)
|
||||||
#define PA_SYSTEM (0)
|
#define PA_SYSTEM (0)
|
||||||
|
|
||||||
|
#define PAGESIZE (4096)
|
||||||
|
|
||||||
|
PULONG MmGetPageEntry(PVOID Address);
|
||||||
|
|
||||||
#define KERNEL_BASE (0xc0000000)
|
#define KERNEL_BASE (0xc0000000)
|
||||||
|
|
||||||
#define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t")
|
#define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t")
|
||||||
|
@ -49,7 +48,7 @@ extern inline PULONG get_page_directory(void)
|
||||||
#define VADDR_TO_PT_OFFSET(x) (((x/1024)%4096))
|
#define VADDR_TO_PT_OFFSET(x) (((x/1024)%4096))
|
||||||
#define VADDR_TO_PD_OFFSET(x) ((x)/(4*1024*1024))
|
#define VADDR_TO_PD_OFFSET(x) ((x)/(4*1024*1024))
|
||||||
|
|
||||||
VOID MmSetPage(struct _EPROCESS* Process,
|
NTSTATUS MmCreateVirtualMapping(struct _EPROCESS* Process,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
ULONG flProtect,
|
ULONG flProtect,
|
||||||
ULONG PhysicalAddress);
|
ULONG PhysicalAddress);
|
||||||
|
|
|
@ -108,6 +108,8 @@ typedef struct _MADDRESS_SPACE
|
||||||
ULONG WorkingSetLruFirst;
|
ULONG WorkingSetLruFirst;
|
||||||
ULONG WorkingSetLruLast;
|
ULONG WorkingSetLruLast;
|
||||||
ULONG WorkingSetPagesAllocated;
|
ULONG WorkingSetPagesAllocated;
|
||||||
|
PUSHORT PageTableRefCountTable;
|
||||||
|
ULONG PageTableRefCountTableSize;
|
||||||
} MADDRESS_SPACE, *PMADDRESS_SPACE;
|
} MADDRESS_SPACE, *PMADDRESS_SPACE;
|
||||||
|
|
||||||
/* FUNCTIONS */
|
/* FUNCTIONS */
|
||||||
|
@ -164,7 +166,7 @@ NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
|
||||||
struct _EPROCESS* Dest);
|
struct _EPROCESS* Dest);
|
||||||
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
|
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
|
||||||
NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
|
NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
|
||||||
VOID MmDeletePageEntry(struct _EPROCESS* Process,
|
VOID MmDeleteVirtualMapping(struct _EPROCESS* Process,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
BOOL FreePage);
|
BOOL FreePage);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: aspace.c,v 1.3 2000/07/04 08:52:42 dwelch Exp $
|
/* $Id: aspace.c,v 1.4 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -40,7 +40,6 @@ VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace)
|
||||||
VOID MmInitializeKernelAddressSpace(VOID)
|
VOID MmInitializeKernelAddressSpace(VOID)
|
||||||
{
|
{
|
||||||
MmInitializeAddressSpace(NULL, &KernelAddressSpace);
|
MmInitializeAddressSpace(NULL, &KernelAddressSpace);
|
||||||
KernelAddressSpace.LowestAddress = KERNEL_BASE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID)
|
PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID)
|
||||||
|
@ -58,12 +57,30 @@ NTSTATUS MmInitializeAddressSpace(PEPROCESS Process,
|
||||||
{
|
{
|
||||||
InitializeListHead(&AddressSpace->MAreaListHead);
|
InitializeListHead(&AddressSpace->MAreaListHead);
|
||||||
KeInitializeMutex(&AddressSpace->Lock, 1);
|
KeInitializeMutex(&AddressSpace->Lock, 1);
|
||||||
|
if (Process != NULL)
|
||||||
|
{
|
||||||
AddressSpace->LowestAddress = MM_LOWEST_USER_ADDRESS;
|
AddressSpace->LowestAddress = MM_LOWEST_USER_ADDRESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddressSpace->LowestAddress = KERNEL_BASE;
|
||||||
|
}
|
||||||
AddressSpace->Process = Process;
|
AddressSpace->Process = Process;
|
||||||
if (Process != NULL)
|
if (Process != NULL)
|
||||||
{
|
{
|
||||||
MmInitializeWorkingSet(Process, AddressSpace);
|
MmInitializeWorkingSet(Process, AddressSpace);
|
||||||
}
|
}
|
||||||
|
if (Process != NULL)
|
||||||
|
{
|
||||||
|
AddressSpace->PageTableRefCountTable =
|
||||||
|
ExAllocatePool(NonPagedPool, 768 * sizeof(USHORT));
|
||||||
|
AddressSpace->PageTableRefCountTableSize = 768;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddressSpace->PageTableRefCountTable = NULL;
|
||||||
|
AddressSpace->PageTableRefCountTableSize = 0;
|
||||||
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG Reserved;
|
ULONG Reserved;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("MmInitializePageList(FirstPhysKernelAddress %x, "
|
DPRINT("MmInitializePageList(FirstPhysKernelAddress %x, "
|
||||||
"LastPhysKernelAddress %x, "
|
"LastPhysKernelAddress %x, "
|
||||||
|
@ -100,10 +101,17 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
||||||
if (!MmIsPagePresent(NULL,
|
if (!MmIsPagePresent(NULL,
|
||||||
(PVOID)((ULONG)MmPageArray + (i * PAGESIZE))))
|
(PVOID)((ULONG)MmPageArray + (i * PAGESIZE))))
|
||||||
{
|
{
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)((ULONG)MmPageArray + (i * PAGESIZE)),
|
(PVOID)((ULONG)MmPageArray +
|
||||||
|
(i * PAGESIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)(LastPhysKernelAddress - (i * PAGESIZE)));
|
(ULONG)(LastPhysKernelAddress
|
||||||
|
- (i * PAGESIZE)));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: page.c,v 1.13 2000/07/19 14:18:19 dwelch Exp $
|
/* $Id: page.c,v 1.14 2000/08/20 17:02:09 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -56,6 +56,8 @@ static ULONG ProtectToPTE(ULONG flProtect)
|
||||||
return(Attributes);
|
return(Attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (4 * 1024 * 1024))
|
||||||
|
|
||||||
#define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \
|
#define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \
|
||||||
(((ULONG)v / (1024 * 1024))&(~0x3)))
|
(((ULONG)v / (1024 * 1024))&(~0x3)))
|
||||||
#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((((ULONG)v / 1024))&(~0x3)))
|
#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((((ULONG)v / 1024))&(~0x3)))
|
||||||
|
@ -121,6 +123,63 @@ VOID MmDeletePageTable(PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
|
||||||
|
{
|
||||||
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
PULONG PageTable;
|
||||||
|
ULONG i;
|
||||||
|
ULONG npage;
|
||||||
|
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeAttachProcess(Process);
|
||||||
|
}
|
||||||
|
PageTable = (PULONG)PAGE_ROUND_DOWN((PVOID)ADDR_TO_PTE(Address));
|
||||||
|
for (i = 0; i < 1024; i++)
|
||||||
|
{
|
||||||
|
if (PageTable[i] != 0)
|
||||||
|
{
|
||||||
|
DbgPrint("Page table entry not clear\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
npage = *(ADDR_TO_PDE(Address));
|
||||||
|
*(ADDR_TO_PDE(Address)) = 0;
|
||||||
|
MmDereferencePage((PVOID)PAGE_MASK(npage));
|
||||||
|
FLUSH_TLB;
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Get a pointer to the page table entry for a virtual address
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PULONG Pde;
|
||||||
|
ULONG Address = (ULONG)PAddress;
|
||||||
|
ULONG npage;
|
||||||
|
|
||||||
|
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
||||||
|
|
||||||
|
Pde = ADDR_TO_PDE(Address);
|
||||||
|
if ((*Pde) == 0)
|
||||||
|
{
|
||||||
|
npage = (ULONG)MmAllocPage(0);
|
||||||
|
if (npage == 0)
|
||||||
|
{
|
||||||
|
return(STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
(*Pde) = npage | 0x7;
|
||||||
|
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
|
||||||
|
FLUSH_TLB;
|
||||||
|
}
|
||||||
|
*Pte = ADDR_TO_PTE(Address);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
|
ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
|
@ -192,18 +251,21 @@ ULONG MmGetPhysicalAddressForProcess(PEPROCESS Process,
|
||||||
return(PAGE_MASK(PageEntry));
|
return(PAGE_MASK(PageEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage)
|
VOID MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Delete a virtual mapping
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
PULONG page_tlb;
|
PULONG Pte;
|
||||||
PULONG page_dir;
|
PULONG Pde;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
KeAttachProcess(Process);
|
KeAttachProcess(Process);
|
||||||
}
|
}
|
||||||
page_dir = ADDR_TO_PDE(Address);
|
Pde = ADDR_TO_PDE(Address);
|
||||||
if ((*page_dir) == 0)
|
if ((*Pde) == 0)
|
||||||
{
|
{
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
|
@ -211,20 +273,26 @@ VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
page_tlb = ADDR_TO_PTE(Address);
|
Pte = ADDR_TO_PTE(Address);
|
||||||
if (FreePage && PAGE_MASK(*page_tlb) != 0)
|
if (FreePage && PAGE_MASK(*Pte) != 0)
|
||||||
{
|
{
|
||||||
if (PAGE_MASK(*page_tlb) >= 0x400000)
|
MmDereferencePage((PVOID)PAGE_MASK(*Pte));
|
||||||
|
}
|
||||||
|
*Pte = 0;
|
||||||
|
if (Process != NULL &&
|
||||||
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
|
ADDR_TO_PAGE_TABLE(Address) < 768)
|
||||||
{
|
{
|
||||||
DbgPrint("MmDeletePageEntry(Address %x) Physical %x "
|
PUSHORT Ptrc;
|
||||||
"Entry %x\n",
|
|
||||||
Address, PAGE_MASK(*page_tlb),
|
Ptrc = Process->AddressSpace.PageTableRefCountTable;
|
||||||
*page_tlb);
|
|
||||||
KeBugCheck(0);
|
Ptrc[ADDR_TO_PAGE_TABLE(Address)]--;
|
||||||
|
if (Ptrc[ADDR_TO_PAGE_TABLE(Address)] == 0)
|
||||||
|
{
|
||||||
|
MmFreePageTable(Process, Address);
|
||||||
}
|
}
|
||||||
MmDereferencePage((PVOID)PAGE_MASK(*page_tlb));
|
|
||||||
}
|
}
|
||||||
*page_tlb = 0;
|
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
|
@ -323,20 +391,15 @@ BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID MmSetPage(PEPROCESS Process,
|
NTSTATUS MmCreateVirtualMapping(PEPROCESS Process,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
ULONG flProtect,
|
ULONG flProtect,
|
||||||
ULONG PhysicalAddress)
|
ULONG PhysicalAddress)
|
||||||
{
|
{
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
ULONG Attributes = 0;
|
ULONG Attributes = 0;
|
||||||
|
PULONG Pte;
|
||||||
if (((ULONG)PhysicalAddress) >= 0x400000)
|
NTSTATUS Status;
|
||||||
{
|
|
||||||
DbgPrint("MmSetPage(Process %x, Address %x, PhysicalAddress %x)\n",
|
|
||||||
Process, Address, PhysicalAddress);
|
|
||||||
KeBugCheck(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Attributes = ProtectToPTE(flProtect);
|
Attributes = ProtectToPTE(flProtect);
|
||||||
|
|
||||||
|
@ -344,12 +407,34 @@ VOID MmSetPage(PEPROCESS Process,
|
||||||
{
|
{
|
||||||
KeAttachProcess(Process);
|
KeAttachProcess(Process);
|
||||||
}
|
}
|
||||||
(*MmGetPageEntry(Address)) = PhysicalAddress | Attributes;
|
|
||||||
|
Status = MmGetPageEntry2(Address, &Pte);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
*Pte = PhysicalAddress | Attributes;
|
||||||
|
if (Process != NULL &&
|
||||||
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
|
ADDR_TO_PAGE_TABLE(Address) < 768 &&
|
||||||
|
Attributes & PA_PRESENT)
|
||||||
|
{
|
||||||
|
PUSHORT Ptrc;
|
||||||
|
|
||||||
|
Ptrc = Process->AddressSpace.PageTableRefCountTable;
|
||||||
|
|
||||||
|
Ptrc[ADDR_TO_PAGE_TABLE(Address)]++;
|
||||||
|
}
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmSetPageProtect(PEPROCESS Process,
|
VOID MmSetPageProtect(PEPROCESS Process,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: iospace.c,v 1.5 2000/07/04 08:52:42 dwelch Exp $
|
/* $Id: iospace.c,v 1.6 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -76,10 +76,15 @@ PVOID STDCALL MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||||
}
|
}
|
||||||
for (i = 0; (i <= (NumberOfBytes / PAGESIZE)); i++)
|
for (i = 0; (i <= (NumberOfBytes / PAGESIZE)); i++)
|
||||||
{
|
{
|
||||||
MmSetPage (NULL,
|
Status = MmCreateVirtualMapping (NULL,
|
||||||
(Result + (i * PAGESIZE)),
|
(Result + (i * PAGESIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(PhysicalAddress.u.LowPart + (i * PAGESIZE)));
|
(PhysicalAddress.u.LowPart + (i * PAGESIZE)));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ((PVOID)Result);
|
return ((PVOID)Result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: kmap.c,v 1.2 2000/07/04 08:52:42 dwelch Exp $
|
/* $Id: kmap.c,v 1.3 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -46,7 +46,7 @@ VOID ExUnmapPage(PVOID Addr)
|
||||||
DPRINT("i %x\n",i);
|
DPRINT("i %x\n",i);
|
||||||
|
|
||||||
KeAcquireSpinLock(&AllocMapLock, &oldIrql);
|
KeAcquireSpinLock(&AllocMapLock, &oldIrql);
|
||||||
MmSetPage(NULL, (PVOID)Addr, 0, 0);
|
MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE);
|
||||||
clear_bit(i%32, &alloc_map[i/32]);
|
clear_bit(i%32, &alloc_map[i/32]);
|
||||||
KeReleaseSpinLock(&AllocMapLock, oldIrql);
|
KeReleaseSpinLock(&AllocMapLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ PVOID ExAllocatePage(VOID)
|
||||||
ULONG addr;
|
ULONG addr;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG PhysPage;
|
ULONG PhysPage;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
PhysPage = (ULONG)MmAllocPage(0);
|
PhysPage = (ULONG)MmAllocPage(0);
|
||||||
DPRINT("Allocated page %x\n",PhysPage);
|
DPRINT("Allocated page %x\n",PhysPage);
|
||||||
|
@ -73,7 +74,15 @@ PVOID ExAllocatePage(VOID)
|
||||||
DPRINT("i %x\n",i);
|
DPRINT("i %x\n",i);
|
||||||
set_bit(i%32,&alloc_map[i/32]);
|
set_bit(i%32,&alloc_map[i/32]);
|
||||||
addr = (ULONG)(kernel_pool_base + (i*PAGESIZE));
|
addr = (ULONG)(kernel_pool_base + (i*PAGESIZE));
|
||||||
MmSetPage(NULL, (PVOID)addr, PAGE_READWRITE, PhysPage);
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
|
(PVOID)addr,
|
||||||
|
PAGE_READWRITE,
|
||||||
|
PhysPage);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
KeReleaseSpinLock(&AllocMapLock, oldlvl);
|
KeReleaseSpinLock(&AllocMapLock, oldlvl);
|
||||||
return((PVOID)addr);
|
return((PVOID)addr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,10 +312,9 @@ NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
// DPRINT("Freeing %x in kernel address space\n");
|
// DPRINT("Freeing %x in kernel address space\n");
|
||||||
}
|
}
|
||||||
MmSetPage(AddressSpace->Process,
|
MmDeleteVirtualMapping(AddressSpace->Process,
|
||||||
MemoryArea->BaseAddress + (i*PAGESIZE),
|
MemoryArea->BaseAddress + (i*PAGESIZE),
|
||||||
0,
|
FALSE);
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveEntryList(&(MemoryArea->Entry));
|
RemoveEntryList(&(MemoryArea->Entry));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mdl.c,v 1.24 2000/07/08 16:53:33 dwelch Exp $
|
/* $Id: mdl.c,v 1.25 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -112,10 +112,15 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
MdlPages = (PULONG)(Mdl + 1);
|
||||||
for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++)
|
for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++)
|
||||||
{
|
{
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)((ULONG)Base+(i*PAGESIZE)),
|
(PVOID)((ULONG)Base+(i*PAGESIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
MdlPages[i]);
|
MdlPages[i]);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||||
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
|
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mm.c,v 1.36 2000/08/18 22:27:03 dwelch Exp $
|
/* $Id: mm.c,v 1.37 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -56,7 +56,7 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
||||||
i < (Marea->BaseAddress + Marea->Length);
|
i < (Marea->BaseAddress + Marea->Length);
|
||||||
i = i+PAGESIZE)
|
i = i+PAGESIZE)
|
||||||
{
|
{
|
||||||
MmDeletePageEntry(Process, i, TRUE);
|
MmDeleteVirtualMapping(Process, i, TRUE);
|
||||||
}
|
}
|
||||||
ExFreePool(Marea);
|
ExFreePool(Marea);
|
||||||
|
|
||||||
|
@ -198,11 +198,10 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEMORY_AREA_SHARED_DATA:
|
case MEMORY_AREA_SHARED_DATA:
|
||||||
MmSetPage(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
(PVOID)PAGE_ROUND_DOWN(Address),
|
||||||
PAGE_READONLY,
|
PAGE_READONLY,
|
||||||
(ULONG)MmSharedDataPagePhysicalAddress);
|
(ULONG)MmSharedDataPagePhysicalAddress);
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mminit.c,v 1.5 2000/08/12 19:33:22 dwelch Exp $
|
/* $Id: mminit.c,v 1.6 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -85,6 +85,7 @@ VOID MmInitVirtualMemory(PLOADER_PARAMETER_BLOCK bp, ULONG LastKernelAddress)
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
ULONG ParamLength = kernel_len;
|
ULONG ParamLength = kernel_len;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("MmInitVirtualMemory(%x)\n",bp);
|
DPRINT("MmInitVirtualMemory(%x)\n",bp);
|
||||||
|
|
||||||
|
@ -155,10 +156,15 @@ VOID MmInitVirtualMemory(PLOADER_PARAMETER_BLOCK bp, ULONG LastKernelAddress)
|
||||||
0,
|
0,
|
||||||
&kernel_shared_data_desc);
|
&kernel_shared_data_desc);
|
||||||
MmSharedDataPagePhysicalAddress = MmAllocPage(0);
|
MmSharedDataPagePhysicalAddress = MmAllocPage(0);
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)KERNEL_SHARED_DATA_BASE,
|
(PVOID)KERNEL_SHARED_DATA_BASE,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)MmSharedDataPagePhysicalAddress);
|
(ULONG)MmSharedDataPagePhysicalAddress);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
((PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE)->TickCountLow = 0xdeadbeef;
|
((PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE)->TickCountLow = 0xdeadbeef;
|
||||||
DPRINT1("Finished creating shared data page\n");
|
DPRINT1("Finished creating shared data page\n");
|
||||||
|
|
||||||
|
@ -250,7 +256,7 @@ VOID MmInit1(PLOADER_PARAMETER_BLOCK bp, ULONG LastKernelAddress)
|
||||||
i<(KERNEL_BASE + PAGE_TABLE_SIZE);
|
i<(KERNEL_BASE + PAGE_TABLE_SIZE);
|
||||||
i=i+PAGESIZE)
|
i=i+PAGESIZE)
|
||||||
{
|
{
|
||||||
MmSetPage(NULL, (PVOID)(i), PAGE_NOACCESS, 0);
|
MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE);
|
||||||
}
|
}
|
||||||
DPRINT("Almost done MmInit()\n");
|
DPRINT("Almost done MmInit()\n");
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: ncache.c,v 1.5 2000/07/04 08:52:42 dwelch Exp $
|
/* $Id: ncache.c,v 1.6 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -65,10 +65,15 @@ PVOID STDCALL MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
|
||||||
}
|
}
|
||||||
for (i = 0; (i <= (NumberOfBytes / PAGESIZE)); i++)
|
for (i = 0; (i <= (NumberOfBytes / PAGESIZE)); i++)
|
||||||
{
|
{
|
||||||
MmSetPage (NULL,
|
Status = MmCreateVirtualMapping (NULL,
|
||||||
(Result + (i * PAGESIZE)),
|
(Result + (i * PAGESIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)MmAllocPage(0));
|
(ULONG)MmAllocPage(0));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ((PVOID)Result);
|
return ((PVOID)Result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: npool.c,v 1.30 2000/07/04 08:52:42 dwelch Exp $
|
/* $Id: npool.c,v 1.31 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -374,16 +374,22 @@ static block_hdr* grow_kernel_pool(unsigned int size)
|
||||||
block_hdr* used_blk=NULL;
|
block_hdr* used_blk=NULL;
|
||||||
block_hdr* free_blk=NULL;
|
block_hdr* free_blk=NULL;
|
||||||
int i;
|
int i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
OLD_DPRINT("growing heap for block size %d, ",size);
|
OLD_DPRINT("growing heap for block size %d, ",size);
|
||||||
OLD_DPRINT("start %x\n",start);
|
OLD_DPRINT("start %x\n",start);
|
||||||
|
|
||||||
for (i=0;i<nr_pages;i++)
|
for (i=0;i<nr_pages;i++)
|
||||||
{
|
{
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)(start + (i*PAGESIZE)),
|
(PVOID)(start + (i*PAGESIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)MmAllocPage(0));
|
(ULONG)MmAllocPage(0));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: section.c,v 1.37 2000/07/07 10:30:56 dwelch Exp $
|
/* $Id: section.c,v 1.38 2000/08/20 17:02:08 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -148,10 +148,15 @@ NTSTATUS MmUnalignedLoadPageForSection(PMADDRESS_SPACE AddressSpace,
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
MmLockSection(Section);
|
MmLockSection(Section);
|
||||||
|
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
(ULONG)Page);
|
(ULONG)Page);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -246,10 +251,15 @@ NTSTATUS MmWaitForPendingOperationSection(PMADDRESS_SPACE AddressSpace,
|
||||||
* and have a reference to a page containing valid data for the
|
* and have a reference to a page containing valid data for the
|
||||||
* section offset. Set the page and return success.
|
* section offset. Set the page and return success.
|
||||||
*/
|
*/
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
(ULONG)Page);
|
(ULONG)Page);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -350,10 +360,15 @@ NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Page = (PVOID)Entry;
|
Page = (PVOID)Entry;
|
||||||
MmReferencePage(Page);
|
MmReferencePage(Page);
|
||||||
|
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
(ULONG)Page);
|
(ULONG)Page);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -434,10 +449,15 @@ NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
MmSetWaitPage(Page);
|
MmSetWaitPage(Page);
|
||||||
|
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
(ULONG)Page);
|
(ULONG)Page);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -462,10 +482,15 @@ NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Page = (PVOID)Entry;
|
Page = (PVOID)Entry;
|
||||||
MmReferencePage(Page);
|
MmReferencePage(Page);
|
||||||
|
|
||||||
MmSetPage(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
(ULONG)Page);
|
(ULONG)Page);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -1024,10 +1049,15 @@ PVOID STDCALL MmAllocateSection (IN ULONG Length)
|
||||||
DPRINT("Result %p\n",Result);
|
DPRINT("Result %p\n",Result);
|
||||||
for (i = 0; (i <= (Length / PAGESIZE)); i++)
|
for (i = 0; (i <= (Length / PAGESIZE)); i++)
|
||||||
{
|
{
|
||||||
MmSetPage (NULL,
|
Status = MmCreateVirtualMapping (NULL,
|
||||||
(Result + (i * PAGESIZE)),
|
(Result + (i * PAGESIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)MmAllocPage(0));
|
(ULONG)MmAllocPage(0));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
return ((PVOID)Result);
|
return ((PVOID)Result);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: virtual.c,v 1.33 2000/08/18 22:27:03 dwelch Exp $
|
/* $Id: virtual.c,v 1.34 2000/08/20 17:02:09 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -189,10 +189,7 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
MmRemovePageFromWorkingSet(AddressSpace->Process,
|
MmRemovePageFromWorkingSet(AddressSpace->Process,
|
||||||
Address);
|
Address);
|
||||||
MmSetPage(PsGetCurrentProcess(),
|
MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE);
|
||||||
Address,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
MmDereferencePage((PVOID)PhysicalAddress.u.LowPart);
|
MmDereferencePage((PVOID)PhysicalAddress.u.LowPart);
|
||||||
*Ul = TRUE;
|
*Ul = TRUE;
|
||||||
return(1);
|
return(1);
|
||||||
|
@ -219,6 +216,9 @@ NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
PMM_SEGMENT Segment;
|
PMM_SEGMENT Segment;
|
||||||
PVOID CurrentAddress;
|
PVOID CurrentAddress;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the segment corresponding to the virtual address
|
||||||
|
*/
|
||||||
Segment = MmGetSegmentForAddress(MemoryArea, Address, &CurrentAddress);
|
Segment = MmGetSegmentForAddress(MemoryArea, Address, &CurrentAddress);
|
||||||
if (Segment == NULL)
|
if (Segment == NULL)
|
||||||
{
|
{
|
||||||
|
@ -234,6 +234,9 @@ NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to allocate a page
|
||||||
|
*/
|
||||||
Page = MmAllocPage(0);
|
Page = MmAllocPage(0);
|
||||||
while (Page == NULL)
|
while (Page == NULL)
|
||||||
{
|
{
|
||||||
|
@ -246,8 +249,21 @@ NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
Page = MmAllocPage(0);
|
Page = MmAllocPage(0);
|
||||||
}
|
}
|
||||||
Status = MmCreatePageTable(Address);
|
|
||||||
while (!NT_SUCCESS(Status))
|
/*
|
||||||
|
* Add the page to the process's working set
|
||||||
|
*/
|
||||||
|
MmAddPageToWorkingSet(PsGetCurrentProcess(), Address);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the page. If we fail because we are out of memory then
|
||||||
|
* try again
|
||||||
|
*/
|
||||||
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
|
Address,
|
||||||
|
MemoryArea->Attributes,
|
||||||
|
(ULONG)Page);
|
||||||
|
while (Status == STATUS_NO_MEMORY)
|
||||||
{
|
{
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
MmWaitForFreePages();
|
MmWaitForFreePages();
|
||||||
|
@ -257,13 +273,15 @@ NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MmDereferencePage(Page);
|
MmDereferencePage(Page);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
Status = MmCreatePageTable(Address);
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
}
|
|
||||||
MmAddPageToWorkingSet(PsGetCurrentProcess(), Address);
|
|
||||||
MmSetPage(PsGetCurrentProcess(),
|
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
(ULONG)Page);
|
(ULONG)Page);
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -275,6 +293,9 @@ VOID MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
ULONG OldProtect,
|
ULONG OldProtect,
|
||||||
ULONG NewType,
|
ULONG NewType,
|
||||||
ULONG NewProtect)
|
ULONG NewProtect)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Modify the attributes of a memory region
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
if (NewType == MEM_RESERVE &&
|
if (NewType == MEM_RESERVE &&
|
||||||
OldType == MEM_COMMIT)
|
OldType == MEM_COMMIT)
|
||||||
|
@ -314,6 +335,9 @@ VOID MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
VOID InsertAfterEntry(PLIST_ENTRY Previous,
|
VOID InsertAfterEntry(PLIST_ENTRY Previous,
|
||||||
PLIST_ENTRY Entry)
|
PLIST_ENTRY Entry)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Insert a list entry after another entry in the list
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
Previous->Flink->Blink = Entry;
|
Previous->Flink->Blink = Entry;
|
||||||
|
|
||||||
|
@ -323,78 +347,127 @@ VOID InsertAfterEntry(PLIST_ENTRY Previous,
|
||||||
Previous->Flink = Entry;
|
Previous->Flink = Entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID MmDumpSegmentsMemoryArea(PMEMORY_AREA MemoryArea)
|
||||||
|
{
|
||||||
|
PVOID CurrentAddress;
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PMM_SEGMENT CurrentSegment;
|
||||||
|
PLIST_ENTRY ListHead;
|
||||||
|
|
||||||
|
CurrentEntry = MemoryArea->Data.VirtualMemoryData.SegmentListHead.Flink;
|
||||||
|
ListHead = &MemoryArea->Data.VirtualMemoryData.SegmentListHead;
|
||||||
|
|
||||||
|
CurrentAddress = MemoryArea->BaseAddress;
|
||||||
|
while (CurrentEntry != ListHead)
|
||||||
|
{
|
||||||
|
CurrentSegment = CONTAINING_RECORD(CurrentEntry,
|
||||||
|
MM_SEGMENT,
|
||||||
|
SegmentListEntry);
|
||||||
|
|
||||||
|
DbgPrint("0x%x 0x%x %d %d\n",
|
||||||
|
CurrentAddress,
|
||||||
|
CurrentSegment->Length,
|
||||||
|
CurrentSegment->Type,
|
||||||
|
CurrentSegment->Protect);
|
||||||
|
|
||||||
|
CurrentAddress = CurrentAddress + CurrentSegment->Length;
|
||||||
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS MmSplitSegment(PMADDRESS_SPACE AddressSpace,
|
NTSTATUS MmSplitSegment(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MemoryArea,
|
PMEMORY_AREA MemoryArea,
|
||||||
PVOID BaseAddress,
|
PVOID RegionAddress,
|
||||||
ULONG RegionSize,
|
ULONG RegionLength,
|
||||||
ULONG Type,
|
ULONG Type,
|
||||||
ULONG Protect,
|
ULONG Protect,
|
||||||
PMM_SEGMENT CurrentSegment,
|
PMM_SEGMENT FirstSegment,
|
||||||
PVOID CurrentAddress)
|
PVOID FirstAddress)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Split a memory segment internally
|
* FUNCTION: Split a memory segment internally
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PMM_SEGMENT NewSegment;
|
|
||||||
PMM_SEGMENT NewTopSegment;
|
PMM_SEGMENT NewTopSegment;
|
||||||
PMM_SEGMENT PreviousSegment;
|
PMM_SEGMENT RegionSegment;
|
||||||
ULONG OldType;
|
ULONG OldType;
|
||||||
ULONG OldProtect;
|
ULONG OldProtect;
|
||||||
|
ULONG OldLength;
|
||||||
|
|
||||||
OldType = CurrentSegment->Type;
|
/*
|
||||||
OldProtect = CurrentSegment->Protect;
|
* Save the type and protection and length of the current segment
|
||||||
|
*/
|
||||||
|
OldType = FirstSegment->Type;
|
||||||
|
OldProtect = FirstSegment->Protect;
|
||||||
|
OldLength = FirstSegment->Length;
|
||||||
|
|
||||||
NewSegment = ExAllocatePool(NonPagedPool, sizeof(MM_SEGMENT));
|
/*
|
||||||
if (NewSegment == NULL)
|
* Allocate the segment we might need here because if the allocation
|
||||||
{
|
* fails below it will be difficult to undo what we've done already.
|
||||||
return(STATUS_NO_MEMORY);
|
*/
|
||||||
}
|
|
||||||
NewTopSegment = ExAllocatePool(NonPagedPool, sizeof(MM_SEGMENT));
|
NewTopSegment = ExAllocatePool(NonPagedPool, sizeof(MM_SEGMENT));
|
||||||
if (NewTopSegment == NULL)
|
if (NewTopSegment == NULL)
|
||||||
{
|
{
|
||||||
ExFreePool(NewSegment);
|
|
||||||
return(STATUS_NO_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentSegment->Type == Type &&
|
/*
|
||||||
CurrentSegment->Protect == Protect)
|
* If the segment is already of the right type and protection then
|
||||||
|
* there is nothing to do.
|
||||||
|
*/
|
||||||
|
if (FirstSegment->Type == Type && FirstSegment->Protect == Protect)
|
||||||
{
|
{
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentAddress < BaseAddress)
|
if (FirstAddress < RegionAddress)
|
||||||
{
|
{
|
||||||
NewSegment->Type = Type;
|
/*
|
||||||
NewSegment->Protect = Protect;
|
* If the region to be affected starts at a higher address than
|
||||||
NewSegment->Length = RegionSize;
|
* the current segment then create a new segment for the
|
||||||
|
* affected portion
|
||||||
|
*/
|
||||||
|
RegionSegment = ExAllocatePool(NonPagedPool, sizeof(MM_SEGMENT));
|
||||||
|
if (RegionSegment == NULL)
|
||||||
|
{
|
||||||
|
ExFreePool(NewTopSegment);
|
||||||
|
return(STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
CurrentSegment->Length = BaseAddress - CurrentAddress;
|
RegionSegment->Type = Type;
|
||||||
|
RegionSegment->Protect = Protect;
|
||||||
|
RegionSegment->Length = RegionLength;
|
||||||
|
|
||||||
InsertAfterEntry(&CurrentSegment->SegmentListEntry,
|
FirstSegment->Length = RegionAddress - FirstAddress;
|
||||||
&NewSegment->SegmentListEntry);
|
|
||||||
|
|
||||||
PreviousSegment = NewSegment;
|
InsertAfterEntry(&FirstSegment->SegmentListEntry,
|
||||||
|
&RegionSegment->SegmentListEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CurrentSegment->Type = Type;
|
/*
|
||||||
CurrentSegment->Protect = Protect;
|
* Otherwise just set its type and protection and length
|
||||||
|
*/
|
||||||
|
|
||||||
PreviousSegment = CurrentSegment;
|
FirstSegment->Type = Type;
|
||||||
|
FirstSegment->Protect = Protect;
|
||||||
|
FirstSegment->Length = RegionLength;
|
||||||
|
|
||||||
ExFreePool(NewSegment);
|
RegionSegment = FirstSegment;
|
||||||
NewSegment = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((CurrentAddress + CurrentSegment->Length) > (BaseAddress + RegionSize))
|
if ((FirstAddress + OldLength) > (RegionAddress + RegionLength))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* If the top of the current segment extends after the affected
|
||||||
|
* region then create a segment for the unaffected portion
|
||||||
|
*/
|
||||||
|
|
||||||
NewTopSegment->Type = OldType;
|
NewTopSegment->Type = OldType;
|
||||||
NewTopSegment->Protect = OldProtect;
|
NewTopSegment->Protect = OldProtect;
|
||||||
NewTopSegment->Length =
|
NewTopSegment->Length = (FirstAddress + OldLength) -
|
||||||
(CurrentAddress + CurrentSegment->Length) -
|
(RegionAddress + RegionLength);
|
||||||
(BaseAddress + RegionSize);
|
|
||||||
|
|
||||||
InsertAfterEntry(&PreviousSegment->SegmentListEntry,
|
InsertAfterEntry(&RegionSegment->SegmentListEntry,
|
||||||
&NewTopSegment->SegmentListEntry);
|
&NewTopSegment->SegmentListEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -403,19 +476,27 @@ NTSTATUS MmSplitSegment(PMADDRESS_SPACE AddressSpace,
|
||||||
NewTopSegment = NULL;
|
NewTopSegment = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
MmModifyAttributes(AddressSpace, BaseAddress, RegionSize,
|
/*
|
||||||
OldType, OldProtect, Type, Protect);
|
* Actually set the type and protection of the affected region
|
||||||
|
*/
|
||||||
|
MmModifyAttributes(AddressSpace,
|
||||||
|
RegionAddress,
|
||||||
|
RegionLength,
|
||||||
|
OldType,
|
||||||
|
OldProtect,
|
||||||
|
Type,
|
||||||
|
Protect);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS MmGatherSegment(PMADDRESS_SPACE AddressSpace,
|
NTSTATUS MmGatherSegment(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MemoryArea,
|
PMEMORY_AREA MemoryArea,
|
||||||
PVOID BaseAddress,
|
PVOID RegionAddress,
|
||||||
ULONG RegionSize,
|
ULONG RegionLength,
|
||||||
ULONG Type,
|
ULONG Type,
|
||||||
ULONG Protect,
|
ULONG Protect,
|
||||||
PMM_SEGMENT CurrentSegment,
|
PMM_SEGMENT FirstSegment,
|
||||||
PVOID CurrentAddress)
|
PVOID FirstAddress)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Do a virtual memory operation that will effect several
|
* FUNCTION: Do a virtual memory operation that will effect several
|
||||||
* memory segments.
|
* memory segments.
|
||||||
|
@ -432,53 +513,46 @@ NTSTATUS MmGatherSegment(PMADDRESS_SPACE AddressSpace,
|
||||||
* RETURNS: Status
|
* RETURNS: Status
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PMM_SEGMENT NewSegment;
|
PMM_SEGMENT RegionSegment;
|
||||||
PMM_SEGMENT NewTopSegment;
|
PVOID CurrentAddress;
|
||||||
PMM_SEGMENT PreviousSegment;
|
ULONG RemainingLength;
|
||||||
PVOID LAddress;
|
|
||||||
ULONG RSize;
|
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PLIST_ENTRY ListHead;
|
PLIST_ENTRY ListHead;
|
||||||
|
PMM_SEGMENT CurrentSegment;
|
||||||
|
|
||||||
/*
|
if (FirstAddress < RegionAddress)
|
||||||
* We will need a maximum of two new segments. Allocate them now
|
|
||||||
* because if we fail latter we may not be able to reverse the
|
|
||||||
* what we've already done
|
|
||||||
*/
|
|
||||||
NewSegment = ExAllocatePool(NonPagedPool, sizeof(MM_SEGMENT));
|
|
||||||
if (NewSegment == NULL)
|
|
||||||
{
|
|
||||||
return(STATUS_NO_MEMORY);
|
|
||||||
}
|
|
||||||
NewTopSegment = ExAllocatePool(NonPagedPool, sizeof(MM_SEGMENT));
|
|
||||||
if (NewTopSegment == NULL)
|
|
||||||
{
|
|
||||||
ExFreePool(NewSegment);
|
|
||||||
return(STATUS_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentAddress < BaseAddress)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If a portion of the first segment is not covered by the region then
|
* If a portion of the first segment is not covered by the region then
|
||||||
* we need to split it into two segments
|
* we need to split it into two segments
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NewSegment->Type = Type;
|
RegionSegment = ExAllocatePool(NonPagedPool, sizeof(MM_SEGMENT));
|
||||||
NewSegment->Protect = Protect;
|
if (RegionSegment == NULL)
|
||||||
NewSegment->Length = RegionSize;
|
{
|
||||||
|
return(STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
CurrentSegment->Length =
|
RegionSegment->Type = Type;
|
||||||
BaseAddress - CurrentAddress;
|
RegionSegment->Protect = Protect;
|
||||||
|
RegionSegment->Length = (FirstAddress + FirstSegment->Length) -
|
||||||
|
RegionAddress;
|
||||||
|
|
||||||
InsertAfterEntry(&CurrentSegment->SegmentListEntry,
|
FirstSegment->Length = RegionAddress - FirstAddress;
|
||||||
&NewSegment->SegmentListEntry);
|
|
||||||
|
|
||||||
PreviousSegment = NewSegment;
|
InsertAfterEntry(&FirstSegment->SegmentListEntry,
|
||||||
|
&RegionSegment->SegmentListEntry);
|
||||||
|
|
||||||
MmModifyAttributes(AddressSpace, BaseAddress, NewSegment->Length,
|
MmModifyAttributes(AddressSpace,
|
||||||
CurrentSegment->Type,
|
RegionAddress,
|
||||||
CurrentSegment->Protect, Type, Protect);
|
RegionSegment->Length,
|
||||||
|
FirstSegment->Type,
|
||||||
|
FirstSegment->Protect,
|
||||||
|
Type,
|
||||||
|
Protect);
|
||||||
|
|
||||||
|
CurrentAddress = FirstAddress + FirstSegment->Length +
|
||||||
|
RegionSegment->Length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -489,75 +563,106 @@ NTSTATUS MmGatherSegment(PMADDRESS_SPACE AddressSpace,
|
||||||
ULONG OldType;
|
ULONG OldType;
|
||||||
ULONG OldProtect;
|
ULONG OldProtect;
|
||||||
|
|
||||||
OldType = CurrentSegment->Type;
|
OldType = FirstSegment->Type;
|
||||||
OldProtect = CurrentSegment->Protect;
|
OldProtect = FirstSegment->Protect;
|
||||||
|
|
||||||
CurrentSegment->Type = Type;
|
FirstSegment->Type = Type;
|
||||||
CurrentSegment->Protect = Protect;
|
FirstSegment->Protect = Protect;
|
||||||
|
|
||||||
PreviousSegment = CurrentSegment;
|
RegionSegment = FirstSegment;
|
||||||
|
|
||||||
ExFreePool(NewSegment);
|
MmModifyAttributes(AddressSpace,
|
||||||
NewSegment = NULL;
|
RegionAddress,
|
||||||
|
FirstSegment->Length,
|
||||||
|
OldType,
|
||||||
|
OldProtect,
|
||||||
|
Type,
|
||||||
|
Protect);
|
||||||
|
|
||||||
MmModifyAttributes(AddressSpace, BaseAddress, CurrentSegment->Length,
|
CurrentAddress = FirstAddress + RegionSegment->Length;
|
||||||
OldType, OldProtect, Type, Protect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LAddress = BaseAddress + PreviousSegment->Length;
|
/*
|
||||||
RSize = RegionSize - PreviousSegment->Length;
|
* Change the attributes of all the complete segments lying inside the
|
||||||
CurrentEntry = PreviousSegment->SegmentListEntry.Flink;
|
* affected region
|
||||||
ListHead = &MemoryArea->Data.VirtualMemoryData.SegmentListHead;
|
*/
|
||||||
|
RemainingLength = RegionLength - RegionSegment->Length;
|
||||||
while (CurrentEntry != ListHead && RSize > 0)
|
CurrentEntry = RegionSegment->SegmentListEntry.Flink;
|
||||||
{
|
|
||||||
ULONG OldType;
|
|
||||||
ULONG OldProtect;
|
|
||||||
|
|
||||||
CurrentSegment = CONTAINING_RECORD(CurrentEntry,
|
CurrentSegment = CONTAINING_RECORD(CurrentEntry,
|
||||||
MM_SEGMENT,
|
MM_SEGMENT,
|
||||||
SegmentListEntry);
|
SegmentListEntry);
|
||||||
|
ListHead = &MemoryArea->Data.VirtualMemoryData.SegmentListHead;
|
||||||
|
|
||||||
if (CurrentSegment->Length > RSize)
|
while (CurrentEntry != ListHead && RemainingLength > 0)
|
||||||
|
{
|
||||||
|
ULONG OldType;
|
||||||
|
ULONG OldProtect;
|
||||||
|
ULONG OldLength;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this segment will not be completely covered by the
|
||||||
|
* affected region then break
|
||||||
|
*/
|
||||||
|
if (CurrentSegment->Length > RemainingLength)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
OldType = CurrentSegment->Type;
|
OldType = CurrentSegment->Type;
|
||||||
OldProtect = CurrentSegment->Protect;
|
OldProtect = CurrentSegment->Protect;
|
||||||
CurrentSegment->Type = Type;
|
OldLength = CurrentSegment->Length;
|
||||||
CurrentSegment->Protect = Protect;
|
|
||||||
|
|
||||||
MmModifyAttributes(AddressSpace, LAddress, CurrentSegment->Length,
|
|
||||||
OldType, OldProtect, Type, Protect);
|
|
||||||
|
|
||||||
RSize = RSize - CurrentSegment->Length;
|
|
||||||
LAddress = LAddress + CurrentSegment->Length;
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extend the length of the previous segment to cover this one
|
||||||
|
*/
|
||||||
|
RegionSegment->Length = RegionSegment->Length + OldLength;
|
||||||
|
RemainingLength = RemainingLength - OldLength;
|
||||||
|
CurrentAddress = CurrentAddress + OldLength;
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove the current segment from the list
|
||||||
|
*/
|
||||||
|
RemoveEntryList(&CurrentSegment->SegmentListEntry);
|
||||||
|
ExFreePool(CurrentSegment);
|
||||||
|
|
||||||
|
MmModifyAttributes(AddressSpace,
|
||||||
|
CurrentAddress,
|
||||||
|
OldLength,
|
||||||
|
OldType,
|
||||||
|
OldProtect,
|
||||||
|
Type,
|
||||||
|
Protect);
|
||||||
|
|
||||||
|
CurrentSegment = CONTAINING_RECORD(CurrentEntry,
|
||||||
|
MM_SEGMENT,
|
||||||
|
SegmentListEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentEntry == ListHead && RSize > 0)
|
/*
|
||||||
|
* If we've run off the top of the memory area then bug check
|
||||||
|
*/
|
||||||
|
if (CurrentEntry == ListHead && RemainingLength > 0)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RSize > 0)
|
/*
|
||||||
|
* We've only affected a portion of a segment then split it in two
|
||||||
|
*/
|
||||||
|
if (RemainingLength > 0)
|
||||||
{
|
{
|
||||||
NewTopSegment->Type = CurrentSegment->Type;
|
CurrentSegment->Length = CurrentSegment->Length - RemainingLength;
|
||||||
NewTopSegment->Protect = CurrentSegment->Protect;
|
|
||||||
NewTopSegment->Length = CurrentSegment->Length - RSize;
|
|
||||||
|
|
||||||
CurrentSegment->Length = RSize;
|
RegionSegment->Length = RegionSegment->Length + RemainingLength;
|
||||||
CurrentSegment->Type = Type;
|
|
||||||
CurrentSegment->Protect = Protect;
|
|
||||||
|
|
||||||
InsertAfterEntry(&CurrentSegment->SegmentListEntry,
|
MmModifyAttributes(AddressSpace,
|
||||||
&NewTopSegment->SegmentListEntry);
|
CurrentAddress,
|
||||||
|
RemainingLength,
|
||||||
MmModifyAttributes(AddressSpace, LAddress, RSize,
|
CurrentSegment->Type,
|
||||||
NewTopSegment->Type,
|
CurrentSegment->Protect,
|
||||||
NewTopSegment->Protect, Type, Protect);
|
Type,
|
||||||
|
Protect);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
|
Loading…
Reference in a new issue