mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 18:35:41 +00:00
2002-08-10 David Welch <welch@computer2.darkstar.org>
* ntoskrnl/mm/i386/page.c (MmSetPageProtect): Fixed behaviour when called on the system address space. 2002-08-10 David Welch <welch@computer2.darkstar.org> * ntoskrnl/mm/virtual.c (MmQueryAnonMem, MmProtectAnonMem, NtAllocateVirtualMemory, NtFreeVirtualMemory): Renamed segments to regions; moved region code to seperate file. Implemented NtQueryVirtualMemory and NtProtectVirtualMemory for anonymous memory areas. 2002-08-10 David Welch <welch@computer2.darkstar.org> * ntoskrnl/mm/anonmem.c: Moved functions relating to areas created with NtAllocateVirtualMemory to a seperate file. 2002-08-10 David Welch <welch@computer2.darkstar.org> * ntoskrnl/mm/section.c (MmQuerySectionView): Implemented NtQueryVirtualMemory for section views. 2002-08-10 David Welch <welch@computer2.darkstar.org> * ntoskrnl/mm/section.c (MmAccessFaultSectionView, MmNotPresentFaultSectionView, MmProtectSectionView, MmMapViewOfSegment, MmAlterViewAttributes): Implemented NtProtectVirtualMemory for section views. 2002-08-10 David Welch <welch@computer2.darkstar.org> * ntoskrnl/ke/main.c: Removed SEH test code. 2002-08-10 David Welch <welch@computer2.darkstar.org> * lib/ntdll/ldr/utils.c (LdrFixupImports): Remove the readonly protection from the IAT before writing to it. 2002-08-10 David Welch <welch@computer2.darkstar.org> * lib/ntdll/ldr/utils.c (LdrAdjustDllName): Properly null terminate the base name of the DLL. 2002-08-10 David Welch <welch@computer2.darkstar.org> * ntoskrnl/ldr/loader.c (LdrPEProcessModule): Set the text segment of modules to readonly after loading. svn path=/trunk/; revision=3327
This commit is contained in:
parent
6809339d27
commit
383eddd11e
16 changed files with 1670 additions and 1646 deletions
|
@ -1,3 +1,53 @@
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/mm/i386/page.c (MmSetPageProtect): Fixed
|
||||||
|
behaviour when called on the system address space.
|
||||||
|
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/mm/virtual.c (MmQueryAnonMem, MmProtectAnonMem,
|
||||||
|
NtAllocateVirtualMemory, NtFreeVirtualMemory): Renamed
|
||||||
|
segments to regions; moved region code to seperate file.
|
||||||
|
Implemented NtQueryVirtualMemory and NtProtectVirtualMemory
|
||||||
|
for anonymous memory areas.
|
||||||
|
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/mm/anonmem.c: Moved functions relating to
|
||||||
|
areas created with NtAllocateVirtualMemory to a
|
||||||
|
seperate file.
|
||||||
|
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/mm/section.c (MmQuerySectionView): Implemented
|
||||||
|
NtQueryVirtualMemory for section views.
|
||||||
|
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/mm/section.c (MmAccessFaultSectionView,
|
||||||
|
MmNotPresentFaultSectionView, MmProtectSectionView,
|
||||||
|
MmMapViewOfSegment, MmAlterViewAttributes): Implemented
|
||||||
|
NtProtectVirtualMemory for section views.
|
||||||
|
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/ke/main.c: Removed SEH test code.
|
||||||
|
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* lib/ntdll/ldr/utils.c (LdrFixupImports): Remove the readonly
|
||||||
|
protection from the IAT before writing to it.
|
||||||
|
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* lib/ntdll/ldr/utils.c (LdrAdjustDllName): Properly null terminate
|
||||||
|
the base name of the DLL.
|
||||||
|
|
||||||
|
2002-08-10 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/ldr/loader.c (LdrPEProcessModule): Set the text segment
|
||||||
|
of modules to readonly after loading.
|
||||||
|
|
||||||
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
* ntoskrnl/ps/create.c (NtCreateThread): Call PsSuspendThread
|
* ntoskrnl/ps/create.c (NtCreateThread): Call PsSuspendThread
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: utils.c,v 1.52 2002/08/08 17:54:13 dwelch Exp $
|
/* $Id: utils.c,v 1.53 2002/08/10 16:41:17 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,11 +112,13 @@ LdrAdjustDllName (PUNICODE_STRING FullDllName,
|
||||||
Pointer++;
|
Pointer++;
|
||||||
Length = Extension - Pointer;
|
Length = Extension - Pointer;
|
||||||
memmove (Buffer, Pointer, Length * sizeof(WCHAR));
|
memmove (Buffer, Pointer, Length * sizeof(WCHAR));
|
||||||
|
Buffer[Length] = L'\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* get the full dll name */
|
/* get the full dll name */
|
||||||
memmove (Buffer, DllName->Buffer, DllName->Length);
|
memmove (Buffer, DllName->Buffer, DllName->Length);
|
||||||
|
Buffer[DllName->Length / sizeof(WCHAR)] = L'\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build the DLL's absolute name */
|
/* Build the DLL's absolute name */
|
||||||
|
@ -941,6 +943,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
ULONG Ordinal;
|
ULONG Ordinal;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG IATSize;
|
||||||
|
|
||||||
DPRINT("LdrFixupImports(NTHeaders %x, ImageBase %x)\n", NTHeaders,
|
DPRINT("LdrFixupImports(NTHeaders %x, ImageBase %x)\n", NTHeaders,
|
||||||
ImageBase);
|
ImageBase);
|
||||||
|
@ -961,6 +964,8 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
UNICODE_STRING DllName;
|
UNICODE_STRING DllName;
|
||||||
DWORD pName;
|
DWORD pName;
|
||||||
WORD pHint;
|
WORD pHint;
|
||||||
|
PVOID IATBase;
|
||||||
|
ULONG OldProtect;
|
||||||
|
|
||||||
DPRINT("ImportModule->Directory->dwRVAModuleName %s\n",
|
DPRINT("ImportModule->Directory->dwRVAModuleName %s\n",
|
||||||
(PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName));
|
(PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName));
|
||||||
|
@ -1008,6 +1013,31 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
(PULONG)(ImageBase
|
(PULONG)(ImageBase
|
||||||
+ ImportModuleDirectory->dwRVAFunctionAddressList);
|
+ ImportModuleDirectory->dwRVAFunctionAddressList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the size of IAT.
|
||||||
|
*/
|
||||||
|
IATSize = 0;
|
||||||
|
while (FunctionNameList[IATSize] != 0L)
|
||||||
|
{
|
||||||
|
IATSize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unprotect the region we are about to write into.
|
||||||
|
*/
|
||||||
|
IATBase = (PVOID)ImportAddressList;
|
||||||
|
Status = NtProtectVirtualMemory(NtCurrentProcess(),
|
||||||
|
IATBase,
|
||||||
|
IATSize * sizeof(PVOID*),
|
||||||
|
PAGE_READWRITE,
|
||||||
|
&OldProtect);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("LDR: Failed to unprotect IAT.\n");
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Walk through function list and fixup addresses.
|
* Walk through function list and fixup addresses.
|
||||||
*/
|
*/
|
||||||
|
@ -1036,6 +1066,21 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
ImportAddressList++;
|
ImportAddressList++;
|
||||||
FunctionNameList++;
|
FunctionNameList++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Protect the region we are about to write into.
|
||||||
|
*/
|
||||||
|
Status = NtProtectVirtualMemory(NtCurrentProcess(),
|
||||||
|
IATBase,
|
||||||
|
IATSize * sizeof(PVOID*),
|
||||||
|
OldProtect,
|
||||||
|
&OldProtect);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("LDR: Failed to protect IAT.\n");
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
ImportModuleDirectory++;
|
ImportModuleDirectory++;
|
||||||
}
|
}
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: Makefile,v 1.78 2002/07/25 13:18:31 ekohl Exp $
|
# $Id: Makefile,v 1.79 2002/08/10 16:41:17 dwelch Exp $
|
||||||
#
|
#
|
||||||
# ReactOS Operating System
|
# ReactOS Operating System
|
||||||
#
|
#
|
||||||
|
@ -158,7 +158,9 @@ OBJECTS_MM = \
|
||||||
mm/pageop.o \
|
mm/pageop.o \
|
||||||
mm/balance.o \
|
mm/balance.o \
|
||||||
mm/rmap.o \
|
mm/rmap.o \
|
||||||
mm/slab.o
|
mm/slab.o \
|
||||||
|
mm/anonmem.o \
|
||||||
|
mm/region.o
|
||||||
|
|
||||||
# I/O Subsystem (Io)
|
# I/O Subsystem (Io)
|
||||||
OBJECTS_IO = \
|
OBJECTS_IO = \
|
||||||
|
|
|
@ -17,19 +17,17 @@ struct _MM_PAGEOP;
|
||||||
typedef ULONG SWAPENTRY;
|
typedef ULONG SWAPENTRY;
|
||||||
|
|
||||||
#define MEMORY_AREA_INVALID (0)
|
#define MEMORY_AREA_INVALID (0)
|
||||||
#define MEMORY_AREA_SECTION_VIEW_COMMIT (1)
|
#define MEMORY_AREA_SECTION_VIEW (1)
|
||||||
#define MEMORY_AREA_CONTINUOUS_MEMORY (2)
|
#define MEMORY_AREA_CONTINUOUS_MEMORY (2)
|
||||||
#define MEMORY_AREA_NO_CACHE (3)
|
#define MEMORY_AREA_NO_CACHE (3)
|
||||||
#define MEMORY_AREA_IO_MAPPING (4)
|
#define MEMORY_AREA_IO_MAPPING (4)
|
||||||
#define MEMORY_AREA_SYSTEM (5)
|
#define MEMORY_AREA_SYSTEM (5)
|
||||||
#define MEMORY_AREA_MDL_MAPPING (7)
|
#define MEMORY_AREA_MDL_MAPPING (7)
|
||||||
#define MEMORY_AREA_VIRTUAL_MEMORY (8)
|
#define MEMORY_AREA_VIRTUAL_MEMORY (8)
|
||||||
#define MEMORY_AREA_SECTION_VIEW_RESERVE (9)
|
#define MEMORY_AREA_CACHE_SEGMENT (9)
|
||||||
#define MEMORY_AREA_CACHE_SEGMENT (10)
|
#define MEMORY_AREA_SHARED_DATA (10)
|
||||||
#define MEMORY_AREA_SHARED_DATA (11)
|
#define MEMORY_AREA_KERNEL_STACK (11)
|
||||||
#define MEMORY_AREA_WORKING_SET (12)
|
#define MEMORY_AREA_PAGED_POOL (12)
|
||||||
#define MEMORY_AREA_KERNEL_STACK (13)
|
|
||||||
#define MEMORY_AREA_PAGED_POOL (14)
|
|
||||||
|
|
||||||
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
|
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
|
||||||
((x) / (4*1024*1024))
|
((x) / (4*1024*1024))
|
||||||
|
@ -137,10 +135,11 @@ typedef struct
|
||||||
LIST_ENTRY ViewListEntry;
|
LIST_ENTRY ViewListEntry;
|
||||||
PMM_SECTION_SEGMENT Segment;
|
PMM_SECTION_SEGMENT Segment;
|
||||||
BOOLEAN WriteCopyView;
|
BOOLEAN WriteCopyView;
|
||||||
|
LIST_ENTRY RegionListHead;
|
||||||
} SectionData;
|
} SectionData;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
LIST_ENTRY SegmentListHead;
|
LIST_ENTRY RegionListHead;
|
||||||
} VirtualMemoryData;
|
} VirtualMemoryData;
|
||||||
} Data;
|
} Data;
|
||||||
} MEMORY_AREA, *PMEMORY_AREA;
|
} MEMORY_AREA, *PMEMORY_AREA;
|
||||||
|
@ -547,4 +546,52 @@ MmDumpToPagingFile(ULONG BugCode,
|
||||||
ULONG BugCodeParameter4,
|
ULONG BugCodeParameter4,
|
||||||
struct _KTRAP_FRAME* TrapFrame);
|
struct _KTRAP_FRAME* TrapFrame);
|
||||||
|
|
||||||
|
typedef VOID (*PMM_ALTER_REGION_FUNC)(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID BaseAddress, ULONG Length,
|
||||||
|
ULONG OldType, ULONG OldProtect,
|
||||||
|
ULONG NewType, ULONG NewProtect);
|
||||||
|
|
||||||
|
typedef struct _MM_REGION
|
||||||
|
{
|
||||||
|
ULONG Type;
|
||||||
|
ULONG Protect;
|
||||||
|
ULONG Length;
|
||||||
|
LIST_ENTRY RegionListEntry;
|
||||||
|
} MM_REGION, *PMM_REGION;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress,
|
||||||
|
PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length,
|
||||||
|
ULONG NewType, ULONG NewProtect,
|
||||||
|
PMM_ALTER_REGION_FUNC AlterFunc);
|
||||||
|
VOID
|
||||||
|
MmInitialiseRegion(PLIST_ENTRY RegionListHead, ULONG Length, ULONG Type,
|
||||||
|
ULONG Protect);
|
||||||
|
PMM_REGION
|
||||||
|
MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address,
|
||||||
|
PVOID* RegionBaseAddress);
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
MmQueryAnonMem(PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PMEMORY_BASIC_INFORMATION Info,
|
||||||
|
PULONG ResultLength);
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
MmQuerySectionView(PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PMEMORY_BASIC_INFORMATION Info,
|
||||||
|
PULONG ResultLength);
|
||||||
|
NTSTATUS
|
||||||
|
MmProtectAnonMem(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG Length,
|
||||||
|
ULONG Protect,
|
||||||
|
PULONG OldProtect);
|
||||||
|
NTSTATUS
|
||||||
|
MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG Length,
|
||||||
|
ULONG Protect,
|
||||||
|
PULONG OldProtect);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: main.c,v 1.132 2002/07/29 15:27:59 ekohl Exp $
|
/* $Id: main.c,v 1.133 2002/08/10 16:41:18 dwelch Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/main.c
|
* FILE: ntoskrnl/ke/main.c
|
||||||
|
@ -282,194 +282,6 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
|
|
||||||
VOID DumpBIOSMemoryMap(VOID)
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
DbgPrint("Dumping BIOS memory map:\n");
|
|
||||||
DbgPrint("Memory map base: %d\n", KeLoaderBlock.MmapAddr);
|
|
||||||
DbgPrint("Memory map size: %d\n", KeLoaderBlock.MmapLength);
|
|
||||||
DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount);
|
|
||||||
for (i = 0; i < KeMemoryMapRangeCount; i++)
|
|
||||||
{
|
|
||||||
DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
|
|
||||||
KeMemoryMap[i].BaseAddrLow,
|
|
||||||
KeMemoryMap[i].LengthLow,
|
|
||||||
KeMemoryMap[i].Type);
|
|
||||||
}
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !NDEBUG */
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
// SEH Test
|
|
||||||
|
|
||||||
static ULONG Scratch;
|
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
|
||||||
ExpUnhandledException1(
|
|
||||||
PEXCEPTION_RECORD ExceptionRecord,
|
|
||||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
|
||||||
PCONTEXT Context,
|
|
||||||
PVOID DispatcherContext)
|
|
||||||
{
|
|
||||||
DbgPrint("ExpUnhandledException1() called\n");
|
|
||||||
DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
|
|
||||||
DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
|
|
||||||
DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
|
|
||||||
DbgPrint("Context 0x%X\n", Context);
|
|
||||||
DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
|
|
||||||
|
|
||||||
Context->Eax = (ULONG)&Scratch;
|
|
||||||
|
|
||||||
return ExceptionContinueExecution;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
|
||||||
ExpUnhandledException2(
|
|
||||||
PEXCEPTION_RECORD ExceptionRecord,
|
|
||||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
|
||||||
PCONTEXT Context,
|
|
||||||
PVOID DispatcherContext)
|
|
||||||
{
|
|
||||||
DbgPrint("ExpUnhandledException2() called\n");
|
|
||||||
DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
|
|
||||||
DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
|
|
||||||
DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
|
|
||||||
DbgPrint("Context 0x%X\n", Context);
|
|
||||||
DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
Context->Eax = (ULONG)&Scratch;
|
|
||||||
|
|
||||||
return ExceptionContinueExecution;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
return ExceptionContinueSearch;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
// Put in mingw headers
|
|
||||||
extern VOID
|
|
||||||
CDECL
|
|
||||||
_local_unwind2(
|
|
||||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
|
||||||
DWORD TryLevel);
|
|
||||||
|
|
||||||
extern VOID
|
|
||||||
CDECL
|
|
||||||
_global_unwind2(
|
|
||||||
PVOID RegistrationFrame);
|
|
||||||
|
|
||||||
extern EXCEPTION_DISPOSITION
|
|
||||||
CDECL
|
|
||||||
_except_handler2(
|
|
||||||
PEXCEPTION_RECORD ExceptionRecord,
|
|
||||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
|
||||||
PCONTEXT Context,
|
|
||||||
PVOID DispatcherContext);
|
|
||||||
|
|
||||||
extern EXCEPTION_DISPOSITION
|
|
||||||
CDECL
|
|
||||||
_except_handler3(
|
|
||||||
PEXCEPTION_RECORD ExceptionRecord,
|
|
||||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
|
||||||
PCONTEXT Context,
|
|
||||||
PVOID DispatcherContext);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PRTL_EXCEPTION_REGISTRATION
|
|
||||||
CurrentRER(VOID)
|
|
||||||
{
|
|
||||||
ULONG Value;
|
|
||||||
|
|
||||||
__asm__("movl %%ebp, %0\n\t" : "=a" (Value));
|
|
||||||
|
|
||||||
return((PRTL_EXCEPTION_REGISTRATION)Value) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
PULONG x;
|
|
||||||
PRTL_EXCEPTION_REGISTRATION TestER;
|
|
||||||
SCOPETABLE_ENTRY ScopeTable;
|
|
||||||
PEXCEPTION_REGISTRATION OSPtr;
|
|
||||||
|
|
||||||
|
|
||||||
DWORD CDECL SEHFilterRoutine(VOID)
|
|
||||||
{
|
|
||||||
DbgPrint("Within filter routine.\n");
|
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
|
||||||
//return EXCEPTION_CONTINUE_EXECUTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID CDECL SEHHandlerRoutine(VOID)
|
|
||||||
{
|
|
||||||
DbgPrint("Within exception handler.\n");
|
|
||||||
DbgPrint("System halted.\n");
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID SEHTest()
|
|
||||||
{
|
|
||||||
RTL_EXCEPTION_REGISTRATION ER;
|
|
||||||
LPEXCEPTION_POINTERS ExceptionPointers;
|
|
||||||
PVOID StandardESPInFrame;
|
|
||||||
|
|
||||||
__asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame));
|
|
||||||
DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame);
|
|
||||||
|
|
||||||
ExceptionPointers = NULL;
|
|
||||||
|
|
||||||
ER.OS.handler = _except_handler3;
|
|
||||||
__asm__ ("movl %%fs:0,%%eax;" : "=a" (ER.OS.prev));
|
|
||||||
DbgPrint("ER.OS.prev: 0x%X\n", ER.OS.prev);
|
|
||||||
|
|
||||||
ER.ScopeTable = &ScopeTable;
|
|
||||||
DbgPrint("ER.ScopeTable: 0x%X\n", ER.ScopeTable);
|
|
||||||
ER.TryLevel = -1;
|
|
||||||
__asm__ ("movl %%ebp,%%eax;" : "=a" (ER.Ebp));
|
|
||||||
DbgPrint("ER.Ebp: 0x%X\n", ER.Ebp);
|
|
||||||
|
|
||||||
ScopeTable.PreviousTryLevel = -1;
|
|
||||||
ScopeTable.FilterRoutine = SEHFilterRoutine;
|
|
||||||
DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable.FilterRoutine);
|
|
||||||
ScopeTable.HandlerRoutine = SEHHandlerRoutine;
|
|
||||||
DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable.HandlerRoutine);
|
|
||||||
|
|
||||||
|
|
||||||
OSPtr = &ER.OS;
|
|
||||||
DbgPrint("OSPtr: 0x%X\n", OSPtr);
|
|
||||||
|
|
||||||
__asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr));
|
|
||||||
|
|
||||||
/*__try1(__except_handler3)*/ if(1) {
|
|
||||||
ER.TryLevel = 0; // Entered first try... block
|
|
||||||
|
|
||||||
DbgPrint("Within guarded section.\n");
|
|
||||||
x = (PULONG)0xf2000000; *x = 0;
|
|
||||||
DbgPrint("After exception.\n");
|
|
||||||
} /* __except1 */ if(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DbgPrint("After exception2.\n");
|
|
||||||
|
|
||||||
__asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER.OS.prev));
|
|
||||||
//KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
|
|
||||||
|
|
||||||
DbgPrint("Exiting.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ExpInitializeExecutive(VOID)
|
ExpInitializeExecutive(VOID)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: loader.c,v 1.118 2002/07/18 00:25:31 dwelch Exp $
|
/* $Id: loader.c,v 1.119 2002/08/10 16:41:18 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
#include <internal/ldr.h>
|
#include <internal/ldr.h>
|
||||||
#include <internal/pool.h>
|
#include <internal/pool.h>
|
||||||
#include <internal/kd.h>
|
#include <internal/kd.h>
|
||||||
|
#include <ntos/minmax.h>
|
||||||
|
|
||||||
#ifdef HALDBG
|
#ifdef HALDBG
|
||||||
#include <internal/ntosdbg.h>
|
#include <internal/ntosdbg.h>
|
||||||
|
@ -1098,6 +1099,30 @@ LdrPEProcessModule(PVOID ModuleLoadBase,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the protections for the various parts of the driver */
|
||||||
|
for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
|
||||||
|
{
|
||||||
|
ULONG Characteristics = PESectionHeaders[Idx].Characteristics;
|
||||||
|
ULONG Length;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
ULONG i;
|
||||||
|
Length =
|
||||||
|
max(PESectionHeaders[Idx].Misc.VirtualSize,
|
||||||
|
PESectionHeaders[Idx].SizeOfRawData);
|
||||||
|
BaseAddress = PESectionHeaders[Idx].VirtualAddress + DriverBase;
|
||||||
|
if (Characteristics & IMAGE_SECTION_CHAR_CODE &&
|
||||||
|
!(Characteristics & IMAGE_SECTION_CHAR_WRITABLE ||
|
||||||
|
Characteristics & IMAGE_SECTION_CHAR_DATA ||
|
||||||
|
Characteristics & IMAGE_SECTION_CHAR_BSS))
|
||||||
|
{
|
||||||
|
for (i = 0; i < PAGE_ROUND_DOWN(Length); i++)
|
||||||
|
{
|
||||||
|
MmSetPageProtect(NULL, BaseAddress + (i * PAGESIZE),
|
||||||
|
PAGE_READONLY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the module */
|
/* Create the module */
|
||||||
CreatedModuleObject = ExAllocatePool(NonPagedPool, sizeof(MODULE_OBJECT));
|
CreatedModuleObject = ExAllocatePool(NonPagedPool, sizeof(MODULE_OBJECT));
|
||||||
if (CreatedModuleObject == NULL)
|
if (CreatedModuleObject == NULL)
|
||||||
|
|
809
reactos/ntoskrnl/mm/anonmem.c
Normal file
809
reactos/ntoskrnl/mm/anonmem.c
Normal file
|
@ -0,0 +1,809 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
/* $Id: anonmem.c,v 1.1 2002/08/10 16:41:19 dwelch Exp $
|
||||||
|
*
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: ntoskrnl/mm/anonmem.c
|
||||||
|
* PURPOSE: Implementing anonymous memory.
|
||||||
|
* PROGRAMMER: David Welch
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDE *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/mm.h>
|
||||||
|
#include <internal/ob.h>
|
||||||
|
#include <internal/io.h>
|
||||||
|
#include <internal/ps.h>
|
||||||
|
#include <internal/pool.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MArea,
|
||||||
|
PVOID Address)
|
||||||
|
{
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PMM_PAGEOP PageOp)
|
||||||
|
{
|
||||||
|
PHYSICAL_ADDRESS PhysicalAddress;
|
||||||
|
BOOL WasDirty;
|
||||||
|
SWAPENTRY SwapEntry;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PMDL Mdl;
|
||||||
|
|
||||||
|
DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n",
|
||||||
|
Address, MemoryArea->Process->UniqueProcessId);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for paging out from a deleted virtual memory area.
|
||||||
|
*/
|
||||||
|
if (MemoryArea->DeleteInProgress)
|
||||||
|
{
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Paging out code or readonly data is easy.
|
||||||
|
*/
|
||||||
|
if ((MemoryArea->Attributes & PAGE_READONLY) ||
|
||||||
|
(MemoryArea->Attributes & PAGE_EXECUTE_READ))
|
||||||
|
{
|
||||||
|
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE,
|
||||||
|
NULL, &PhysicalAddress);
|
||||||
|
MmDeleteAllRmaps(PhysicalAddress, NULL, NULL);
|
||||||
|
if (MmGetSavedSwapEntryPage(PhysicalAddress) != 0)
|
||||||
|
{
|
||||||
|
DPRINT1("Read-only page was swapped out.\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
||||||
|
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Otherwise this is read-write data
|
||||||
|
*/
|
||||||
|
MmDisableVirtualMapping(MemoryArea->Process, Address,
|
||||||
|
&WasDirty, (PULONG)&PhysicalAddress);
|
||||||
|
if (PhysicalAddress.QuadPart == 0)
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
if (!WasDirty)
|
||||||
|
{
|
||||||
|
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
|
||||||
|
MmDeleteAllRmaps(PhysicalAddress, NULL, NULL);
|
||||||
|
if ((SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress)) != 0)
|
||||||
|
{
|
||||||
|
MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry);
|
||||||
|
MmSetSavedSwapEntryPage(PhysicalAddress, 0);
|
||||||
|
}
|
||||||
|
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If necessary, allocate an entry in the paging file for this page
|
||||||
|
*/
|
||||||
|
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
||||||
|
if (SwapEntry == 0)
|
||||||
|
{
|
||||||
|
SwapEntry = MmAllocSwapPage();
|
||||||
|
if (SwapEntry == 0)
|
||||||
|
{
|
||||||
|
MmEnableVirtualMapping(MemoryArea->Process, Address);
|
||||||
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write the page to the pagefile
|
||||||
|
*/
|
||||||
|
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
|
||||||
|
MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress);
|
||||||
|
Status = MmWriteToSwapPage(SwapEntry, Mdl);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
||||||
|
Status);
|
||||||
|
MmEnableVirtualMapping(MemoryArea->Process, Address);
|
||||||
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Otherwise we have succeeded, free the page
|
||||||
|
*/
|
||||||
|
DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", PhysicalAddress);
|
||||||
|
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
|
||||||
|
MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry);
|
||||||
|
MmDeleteAllRmaps(PhysicalAddress, NULL, NULL);
|
||||||
|
MmSetSavedSwapEntryPage(PhysicalAddress, 0);
|
||||||
|
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
|
MEMORY_AREA* MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
BOOLEAN Locked)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Move data into memory to satisfy a page not present fault
|
||||||
|
* ARGUMENTS:
|
||||||
|
* AddressSpace = Address space within which the fault occurred
|
||||||
|
* MemoryArea = The memory area within which the fault occurred
|
||||||
|
* Address = The absolute address of fault
|
||||||
|
* RETURNS: Status
|
||||||
|
* NOTES: This function is called with the address space lock held.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PHYSICAL_ADDRESS Page;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PMM_REGION Region;
|
||||||
|
PMM_PAGEOP PageOp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is a window between taking the page fault and locking the
|
||||||
|
* address space when another thread could load the page so we check
|
||||||
|
* that.
|
||||||
|
*/
|
||||||
|
if (MmIsPagePresent(NULL, Address))
|
||||||
|
{
|
||||||
|
if (Locked)
|
||||||
|
{
|
||||||
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
|
}
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for the virtual memory area being deleted.
|
||||||
|
*/
|
||||||
|
if (MemoryArea->DeleteInProgress)
|
||||||
|
{
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the segment corresponding to the virtual address
|
||||||
|
*/
|
||||||
|
Region = MmFindRegion(MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||||
|
Address, NULL);
|
||||||
|
if (Region->Type == MEM_RESERVE)
|
||||||
|
{
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get or create a page operation
|
||||||
|
*/
|
||||||
|
PageOp = MmGetPageOp(MemoryArea, (ULONG)PsGetCurrentProcessId(),
|
||||||
|
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
|
||||||
|
MM_PAGEOP_PAGEIN);
|
||||||
|
if (PageOp == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("MmGetPageOp failed");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if someone else is already handling this fault, if so wait
|
||||||
|
* for them
|
||||||
|
*/
|
||||||
|
if (PageOp->Thread != PsGetCurrentThread())
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
|
||||||
|
0,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
/*
|
||||||
|
* Check for various strange conditions
|
||||||
|
*/
|
||||||
|
if (Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to wait for page op\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
if (PageOp->Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT1("Woke for page op before completion\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If this wasn't a pagein then we need to restart the handling
|
||||||
|
*/
|
||||||
|
if (PageOp->OpType != MM_PAGEOP_PAGEIN)
|
||||||
|
{
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_MM_RESTART_OPERATION);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If the thread handling this fault has failed then we don't retry
|
||||||
|
*/
|
||||||
|
if (!NT_SUCCESS(PageOp->Status))
|
||||||
|
{
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
if (Locked)
|
||||||
|
{
|
||||||
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
|
}
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to allocate a page
|
||||||
|
*/
|
||||||
|
Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
|
||||||
|
if (Status == STATUS_NO_MEMORY)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle swapped out pages.
|
||||||
|
*/
|
||||||
|
if (MmIsPageSwapEntry(NULL, Address))
|
||||||
|
{
|
||||||
|
SWAPENTRY SwapEntry;
|
||||||
|
PMDL Mdl;
|
||||||
|
|
||||||
|
MmDeletePageFileMapping(NULL, Address, &SwapEntry);
|
||||||
|
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
|
||||||
|
MmBuildMdlFromPages(Mdl, (PULONG)&Page);
|
||||||
|
Status = MmReadFromSwapPage(SwapEntry, Mdl);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
MmSetSavedSwapEntryPage(Page, SwapEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the page. If we fail because we are out of memory then
|
||||||
|
* try again
|
||||||
|
*/
|
||||||
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
|
Address,
|
||||||
|
MemoryArea->Attributes,
|
||||||
|
Page,
|
||||||
|
FALSE);
|
||||||
|
while (Status == STATUS_NO_MEMORY)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
|
Address,
|
||||||
|
MemoryArea->Attributes,
|
||||||
|
Page,
|
||||||
|
TRUE);
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the page to the process's working set
|
||||||
|
*/
|
||||||
|
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finish the operation
|
||||||
|
*/
|
||||||
|
if (Locked)
|
||||||
|
{
|
||||||
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
|
}
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID STATIC
|
||||||
|
MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG RegionSize,
|
||||||
|
ULONG OldType,
|
||||||
|
ULONG OldProtect,
|
||||||
|
ULONG NewType,
|
||||||
|
ULONG NewProtect)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Modify the attributes of a memory region
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we are switching a previously committed region to reserved then
|
||||||
|
* free any allocated pages within the region
|
||||||
|
*/
|
||||||
|
if (NewType == MEM_RESERVE && OldType == MEM_COMMIT)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i=0; i <= (RegionSize/PAGESIZE); i++)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER PhysicalAddr;
|
||||||
|
|
||||||
|
if (MmIsPageSwapEntry(AddressSpace->Process,
|
||||||
|
BaseAddress + (i * PAGESIZE)))
|
||||||
|
{
|
||||||
|
SWAPENTRY SwapEntry;
|
||||||
|
|
||||||
|
MmDeletePageFileMapping(AddressSpace->Process,
|
||||||
|
BaseAddress + (i * PAGESIZE),
|
||||||
|
&SwapEntry);
|
||||||
|
MmFreeSwapPage(SwapEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhysicalAddr = MmGetPhysicalAddress(BaseAddress + (i*PAGESIZE));
|
||||||
|
MmDeleteVirtualMapping(AddressSpace->Process,
|
||||||
|
BaseAddress + (i*PAGESIZE),
|
||||||
|
FALSE, NULL, NULL);
|
||||||
|
if (PhysicalAddr.QuadPart != 0)
|
||||||
|
{
|
||||||
|
MmDeleteRmap(PhysicalAddr, AddressSpace->Process,
|
||||||
|
BaseAddress + (i * PAGESIZE));
|
||||||
|
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are changing the protection attributes of a committed region then
|
||||||
|
* alter the attributes for any allocated pages within the region
|
||||||
|
*/
|
||||||
|
if (NewType == MEM_COMMIT && OldType == MEM_COMMIT &&
|
||||||
|
OldProtect != NewProtect)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i=0; i <= (RegionSize/PAGESIZE); i++)
|
||||||
|
{
|
||||||
|
if (MmIsPagePresent(AddressSpace->Process,
|
||||||
|
BaseAddress + (i*PAGESIZE)))
|
||||||
|
{
|
||||||
|
MmSetPageProtect(AddressSpace->Process,
|
||||||
|
BaseAddress + (i*PAGESIZE),
|
||||||
|
NewProtect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
|
IN OUT PVOID* UBaseAddress,
|
||||||
|
IN ULONG ZeroBits,
|
||||||
|
IN OUT PULONG URegionSize,
|
||||||
|
IN ULONG AllocationType,
|
||||||
|
IN ULONG Protect)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Allocates a block of virtual memory in the process address space
|
||||||
|
* ARGUMENTS:
|
||||||
|
* ProcessHandle = The handle of the process which owns the virtual memory
|
||||||
|
* BaseAddress = A pointer to the virtual memory allocated. If you
|
||||||
|
* supply a non zero value the system will try to
|
||||||
|
* allocate the memory at the address supplied. It round
|
||||||
|
* it down to a multiple of the page size.
|
||||||
|
* ZeroBits = (OPTIONAL) You can specify the number of high order bits
|
||||||
|
* that must be zero, ensuring that the memory will be
|
||||||
|
* allocated at a address below a certain value.
|
||||||
|
* RegionSize = The number of bytes to allocate
|
||||||
|
* AllocationType = Indicates the type of virtual memory you like to
|
||||||
|
* allocated, can be a combination of MEM_COMMIT,
|
||||||
|
* MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN.
|
||||||
|
* Protect = Indicates the protection type of the pages allocated, can be
|
||||||
|
* a combination of PAGE_READONLY, PAGE_READWRITE,
|
||||||
|
* PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD,
|
||||||
|
* PAGE_NOACCESS
|
||||||
|
* REMARKS:
|
||||||
|
* This function maps to the win32 VirtualAllocEx. Virtual memory is
|
||||||
|
* process based so the protocol starts with a ProcessHandle. I
|
||||||
|
* splitted the functionality of obtaining the actual address and
|
||||||
|
* specifying the start address in two parameters ( BaseAddress and
|
||||||
|
* StartAddress ) The NumberOfBytesAllocated specify the range and the
|
||||||
|
* AllocationType and ProctectionType map to the other two parameters.
|
||||||
|
* RETURNS: Status
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PEPROCESS Process;
|
||||||
|
MEMORY_AREA* MemoryArea;
|
||||||
|
ULONG Type;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PMADDRESS_SPACE AddressSpace;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
ULONG RegionSize;
|
||||||
|
PVOID PBaseAddress;
|
||||||
|
ULONG PRegionSize;
|
||||||
|
|
||||||
|
DPRINT("NtAllocateVirtualMemory(*UBaseAddress %x, "
|
||||||
|
"ZeroBits %d, *URegionSize %x, AllocationType %x, Protect %x)\n",
|
||||||
|
*UBaseAddress,ZeroBits,*URegionSize,AllocationType,
|
||||||
|
Protect);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the validity of the parameters
|
||||||
|
*/
|
||||||
|
if ((Protect & PAGE_FLAGS_VALID_FROM_USER_MODE) != Protect)
|
||||||
|
{
|
||||||
|
return(STATUS_INVALID_PAGE_PROTECTION);
|
||||||
|
}
|
||||||
|
if ((AllocationType & (MEM_COMMIT | MEM_RESERVE)) == 0)
|
||||||
|
{
|
||||||
|
return(STATUS_INVALID_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
PBaseAddress = *UBaseAddress;
|
||||||
|
PRegionSize = *URegionSize;
|
||||||
|
|
||||||
|
|
||||||
|
BaseAddress = (PVOID)PAGE_ROUND_DOWN(PBaseAddress);
|
||||||
|
RegionSize = PAGE_ROUND_UP(PBaseAddress + PRegionSize) -
|
||||||
|
PAGE_ROUND_DOWN(PBaseAddress);
|
||||||
|
|
||||||
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
|
PROCESS_VM_OPERATION,
|
||||||
|
NULL,
|
||||||
|
UserMode,
|
||||||
|
(PVOID*)(&Process),
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE;
|
||||||
|
DPRINT("Type %x\n", Type);
|
||||||
|
|
||||||
|
AddressSpace = &Process->AddressSpace;
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
|
||||||
|
if (PBaseAddress != 0)
|
||||||
|
{
|
||||||
|
MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace,
|
||||||
|
BaseAddress);
|
||||||
|
|
||||||
|
if (MemoryArea != NULL &&
|
||||||
|
MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY &&
|
||||||
|
MemoryArea->Length >= RegionSize)
|
||||||
|
{
|
||||||
|
Status =
|
||||||
|
MmAlterRegion(&Process->AddressSpace,
|
||||||
|
MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||||
|
PBaseAddress, RegionSize,
|
||||||
|
Type, Protect, MmModifyAttributes);
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
else if (MemoryArea != NULL)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmCreateMemoryArea(Process,
|
||||||
|
&Process->AddressSpace,
|
||||||
|
MEMORY_AREA_VIRTUAL_MEMORY,
|
||||||
|
&BaseAddress,
|
||||||
|
RegionSize,
|
||||||
|
Protect,
|
||||||
|
&MemoryArea,
|
||||||
|
PBaseAddress != 0);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||||
|
RegionSize, Type, Protect);
|
||||||
|
|
||||||
|
if ((AllocationType & MEM_COMMIT) &&
|
||||||
|
((Protect & PAGE_READWRITE) ||
|
||||||
|
(Protect & PAGE_EXECUTE_READWRITE)))
|
||||||
|
{
|
||||||
|
MmReserveSwapPages(RegionSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
*UBaseAddress = BaseAddress;
|
||||||
|
*URegionSize = RegionSize;
|
||||||
|
DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize);
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID STATIC
|
||||||
|
MmFreeVirtualMemoryPage(PVOID Context,
|
||||||
|
MEMORY_AREA* MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PHYSICAL_ADDRESS PhysicalAddr,
|
||||||
|
SWAPENTRY SwapEntry,
|
||||||
|
BOOLEAN Dirty)
|
||||||
|
{
|
||||||
|
PEPROCESS Process = (PEPROCESS)Context;
|
||||||
|
|
||||||
|
if (PhysicalAddr.QuadPart != 0)
|
||||||
|
{
|
||||||
|
MmDeleteRmap(PhysicalAddr, Process, Address);
|
||||||
|
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddr);
|
||||||
|
}
|
||||||
|
else if (SwapEntry != 0)
|
||||||
|
{
|
||||||
|
MmFreeSwapPage(SwapEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmFreeVirtualMemory(PEPROCESS Process,
|
||||||
|
PMEMORY_AREA MemoryArea)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY current_entry;
|
||||||
|
PMM_REGION current;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
DPRINT("MmFreeVirtualMemory(Process %p MemoryArea %p)\n", Process,
|
||||||
|
MemoryArea);
|
||||||
|
|
||||||
|
/* Mark this memory area as about to be deleted. */
|
||||||
|
MemoryArea->DeleteInProgress = TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for any ongoing paging operations. Notice that since we have
|
||||||
|
* flagged this memory area as deleted no more page ops will be added.
|
||||||
|
*/
|
||||||
|
if (MemoryArea->PageOpCount > 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < (PAGE_ROUND_UP(MemoryArea->Length) / PAGESIZE); i++)
|
||||||
|
{
|
||||||
|
PMM_PAGEOP PageOp;
|
||||||
|
|
||||||
|
if (MemoryArea->PageOpCount == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId,
|
||||||
|
MemoryArea->BaseAddress + (i * PAGESIZE),
|
||||||
|
NULL, 0);
|
||||||
|
if (PageOp != NULL)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
MmUnlockAddressSpace(&Process->AddressSpace);
|
||||||
|
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
|
||||||
|
0,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
if (Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to wait for page op\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
MmLockAddressSpace(&Process->AddressSpace);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free all the individual segments. */
|
||||||
|
current_entry = MemoryArea->Data.VirtualMemoryData.RegionListHead.Flink;
|
||||||
|
while (current_entry != &MemoryArea->Data.VirtualMemoryData.RegionListHead)
|
||||||
|
{
|
||||||
|
current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry);
|
||||||
|
current_entry = current_entry->Flink;
|
||||||
|
ExFreePool(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Actually free the memory area. */
|
||||||
|
MmFreeMemoryArea(&Process->AddressSpace,
|
||||||
|
MemoryArea->BaseAddress,
|
||||||
|
0,
|
||||||
|
MmFreeVirtualMemoryPage,
|
||||||
|
(PVOID)Process);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
|
IN PVOID* PBaseAddress,
|
||||||
|
IN PULONG PRegionSize,
|
||||||
|
IN ULONG FreeType)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Frees a range of virtual memory
|
||||||
|
* ARGUMENTS:
|
||||||
|
* ProcessHandle = Points to the process that allocated the virtual
|
||||||
|
* memory
|
||||||
|
* BaseAddress = Points to the memory address, rounded down to a
|
||||||
|
* multiple of the pagesize
|
||||||
|
* RegionSize = Limits the range to free, rounded up to a multiple of
|
||||||
|
* the paging size
|
||||||
|
* FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE
|
||||||
|
* RETURNS: Status
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
MEMORY_AREA* MemoryArea;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PEPROCESS Process;
|
||||||
|
PMADDRESS_SPACE AddressSpace;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
ULONG RegionSize;
|
||||||
|
|
||||||
|
DPRINT("NtFreeVirtualMemory(ProcessHandle %x, *PBaseAddress %x, "
|
||||||
|
"*PRegionSize %x, FreeType %x)\n",ProcessHandle,*PBaseAddress,
|
||||||
|
*PRegionSize,FreeType);
|
||||||
|
|
||||||
|
BaseAddress = (PVOID)PAGE_ROUND_DOWN((*PBaseAddress));
|
||||||
|
RegionSize = PAGE_ROUND_UP((*PBaseAddress) + (*PRegionSize)) -
|
||||||
|
PAGE_ROUND_DOWN((*PBaseAddress));
|
||||||
|
|
||||||
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
|
PROCESS_VM_OPERATION,
|
||||||
|
PsProcessType,
|
||||||
|
UserMode,
|
||||||
|
(PVOID*)(&Process),
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressSpace = &Process->AddressSpace;
|
||||||
|
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
|
||||||
|
BaseAddress);
|
||||||
|
if (MemoryArea == NULL)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (FreeType)
|
||||||
|
{
|
||||||
|
case MEM_RELEASE:
|
||||||
|
/* We can only free a memory area in one step. */
|
||||||
|
if (MemoryArea->BaseAddress != BaseAddress)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
MmFreeVirtualMemory(Process, MemoryArea);
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
|
||||||
|
case MEM_DECOMMIT:
|
||||||
|
Status =
|
||||||
|
MmAlterRegion(AddressSpace,
|
||||||
|
MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||||
|
BaseAddress,
|
||||||
|
RegionSize,
|
||||||
|
MEM_RESERVE,
|
||||||
|
PAGE_NOACCESS,
|
||||||
|
MmModifyAttributes);
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
return(STATUS_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmProtectAnonMem(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG Length,
|
||||||
|
ULONG Protect,
|
||||||
|
PULONG OldProtect)
|
||||||
|
{
|
||||||
|
PMM_REGION Region;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Region = MmFindRegion(MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||||
|
BaseAddress, NULL);
|
||||||
|
*OldProtect = Region->Protect;
|
||||||
|
Status = MmAlterRegion(AddressSpace, MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||||
|
BaseAddress, Length, Region->Type, Protect,
|
||||||
|
MmModifyAttributes);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
MmQueryAnonMem(PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PMEMORY_BASIC_INFORMATION Info,
|
||||||
|
PULONG ResultLength)
|
||||||
|
{
|
||||||
|
PMM_REGION Region;
|
||||||
|
PVOID RegionBase;
|
||||||
|
|
||||||
|
Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
|
||||||
|
|
||||||
|
Region = MmFindRegion(MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||||
|
Address, &RegionBase);
|
||||||
|
Info->AllocationBase = RegionBase;
|
||||||
|
Info->AllocationProtect = Region->Protect; /* FIXME */
|
||||||
|
Info->RegionSize = Region->Length;
|
||||||
|
Info->State = Region->Type;
|
||||||
|
Info->Protect = Region->Protect;
|
||||||
|
Info->Type = MEM_PRIVATE;
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: page.c,v 1.38 2002/06/10 21:34:38 hbirr Exp $
|
/* $Id: page.c,v 1.39 2002/08/10 16:41:20 dwelch Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/i386/page.c
|
* FILE: ntoskrnl/mm/i386/page.c
|
||||||
|
@ -1082,14 +1082,14 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
|
||||||
Process, Address, flProtect);
|
Process, Address, flProtect);
|
||||||
|
|
||||||
Attributes = ProtectToPTE(flProtect);
|
Attributes = ProtectToPTE(flProtect);
|
||||||
if (Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
KeAttachProcess(Process);
|
KeAttachProcess(Process);
|
||||||
}
|
}
|
||||||
PageEntry = MmGetPageEntry(Address);
|
PageEntry = MmGetPageEntry(Address);
|
||||||
(*PageEntry) = PAGE_MASK(*PageEntry) | Attributes;
|
(*PageEntry) = PAGE_MASK(*PageEntry) | Attributes;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
if (Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: mm.c,v 1.57 2002/06/04 15:26:56 dwelch Exp $
|
/* $Id: mm.c,v 1.58 2002/08/10 16:41:19 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -59,8 +59,7 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
||||||
|
|
||||||
switch (Marea->Type)
|
switch (Marea->Type)
|
||||||
{
|
{
|
||||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
case MEMORY_AREA_SECTION_VIEW:
|
||||||
case MEMORY_AREA_SECTION_VIEW_RESERVE:
|
|
||||||
Status = MmUnmapViewOfSection(Process, Marea->BaseAddress);
|
Status = MmUnmapViewOfSection(Process, Marea->BaseAddress);
|
||||||
assert(Status == STATUS_SUCCESS);
|
assert(Status == STATUS_SUCCESS);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -214,7 +213,7 @@ NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode,
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
case MEMORY_AREA_SECTION_VIEW:
|
||||||
Status = MmAccessFaultSectionView(AddressSpace,
|
Status = MmAccessFaultSectionView(AddressSpace,
|
||||||
MemoryArea,
|
MemoryArea,
|
||||||
(PVOID)Address,
|
(PVOID)Address,
|
||||||
|
@ -346,7 +345,7 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
case MEMORY_AREA_SECTION_VIEW:
|
||||||
Status = MmNotPresentFaultSectionView(AddressSpace,
|
Status = MmNotPresentFaultSectionView(AddressSpace,
|
||||||
MemoryArea,
|
MemoryArea,
|
||||||
(PVOID)Address,
|
(PVOID)Address,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: pageop.c,v 1.10 2002/06/11 22:09:02 dwelch Exp $
|
/* $Id: pageop.c,v 1.11 2002/08/10 16:41:19 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -80,7 +80,7 @@ MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
/*
|
/*
|
||||||
* Calcuate the hash value for pageop structure
|
* Calcuate the hash value for pageop structure
|
||||||
*/
|
*/
|
||||||
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
|
||||||
{
|
{
|
||||||
Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE));
|
Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE));
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
PageOp = MmPageOpHashTable[Hash];
|
PageOp = MmPageOpHashTable[Hash];
|
||||||
while (PageOp != NULL)
|
while (PageOp != NULL)
|
||||||
{
|
{
|
||||||
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
|
||||||
{
|
{
|
||||||
if (PageOp->Segment == Segment &&
|
if (PageOp->Segment == Segment &&
|
||||||
PageOp->Offset == Offset)
|
PageOp->Offset == Offset)
|
||||||
|
@ -147,7 +147,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
/*
|
/*
|
||||||
* Calcuate the hash value for pageop structure
|
* Calcuate the hash value for pageop structure
|
||||||
*/
|
*/
|
||||||
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
|
||||||
{
|
{
|
||||||
Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE));
|
Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE));
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
PageOp = MmPageOpHashTable[Hash];
|
PageOp = MmPageOpHashTable[Hash];
|
||||||
while (PageOp != NULL)
|
while (PageOp != NULL)
|
||||||
{
|
{
|
||||||
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
|
||||||
{
|
{
|
||||||
if (PageOp->Segment == Segment &&
|
if (PageOp->Segment == Segment &&
|
||||||
PageOp->Offset == Offset)
|
PageOp->Offset == Offset)
|
||||||
|
@ -206,7 +206,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MArea->Type != MEMORY_AREA_SECTION_VIEW_COMMIT)
|
if (MArea->Type != MEMORY_AREA_SECTION_VIEW)
|
||||||
{
|
{
|
||||||
PageOp->Pid = Pid;
|
PageOp->Pid = Pid;
|
||||||
PageOp->Address = Address;
|
PageOp->Address = Address;
|
||||||
|
|
303
reactos/ntoskrnl/mm/region.c
Normal file
303
reactos/ntoskrnl/mm/region.c
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
/* $Id: region.c,v 1.1 2002/08/10 16:41:19 dwelch Exp $
|
||||||
|
*
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: ntoskrnl/mm/region.c
|
||||||
|
* PROGRAMMER: David Welch
|
||||||
|
* PURPOSE:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDE *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/mm.h>
|
||||||
|
#include <internal/ob.h>
|
||||||
|
#include <internal/io.h>
|
||||||
|
#include <internal/ps.h>
|
||||||
|
#include <internal/pool.h>
|
||||||
|
#include <ntos/minmax.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
#define TAG_MM_REGION TAG('M', 'R', 'G', 'N')
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
VOID STATIC
|
||||||
|
InsertAfterEntry(PLIST_ENTRY Previous,
|
||||||
|
PLIST_ENTRY Entry)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Insert a list entry after another entry in the list
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
Previous->Flink->Blink = Entry;
|
||||||
|
|
||||||
|
Entry->Flink = Previous->Flink;
|
||||||
|
Entry->Blink = Previous;
|
||||||
|
|
||||||
|
Previous->Flink = Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
PMM_REGION STATIC
|
||||||
|
MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress,
|
||||||
|
PVOID StartAddress, ULONG Length, ULONG NewType,
|
||||||
|
ULONG NewProtect, PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMM_ALTER_REGION_FUNC AlterFunc)
|
||||||
|
{
|
||||||
|
PMM_REGION NewRegion1;
|
||||||
|
PMM_REGION NewRegion2;
|
||||||
|
ULONG InternalLength;
|
||||||
|
|
||||||
|
/* Allocate this in front otherwise the failure case is too difficult. */
|
||||||
|
NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
|
||||||
|
TAG_MM_REGION);
|
||||||
|
if (NewRegion2 == NULL)
|
||||||
|
{
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the new region. */
|
||||||
|
NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
|
||||||
|
TAG_MM_REGION);
|
||||||
|
if (NewRegion1 == NULL)
|
||||||
|
{
|
||||||
|
ExFreePool(NewRegion2);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
NewRegion1->Type = NewType;
|
||||||
|
NewRegion1->Protect = NewProtect;
|
||||||
|
InternalLength = (InitialBaseAddress + InitialRegion->Length) - StartAddress;
|
||||||
|
InternalLength = min(InternalLength, Length);
|
||||||
|
NewRegion1->Length = InternalLength;
|
||||||
|
InsertAfterEntry(&InitialRegion->RegionListEntry,
|
||||||
|
&NewRegion1->RegionListEntry);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call our helper function to do the changes on the addresses contained
|
||||||
|
* in the initial region.
|
||||||
|
*/
|
||||||
|
AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type,
|
||||||
|
InitialRegion->Protect, NewType, NewProtect);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If necessary create a new region for the portion of the initial region
|
||||||
|
* beyond the range of addresses to alter.
|
||||||
|
*/
|
||||||
|
if ((InitialBaseAddress + InitialRegion->Length) > (StartAddress + Length))
|
||||||
|
{
|
||||||
|
NewRegion2->Type = InitialRegion->Type;
|
||||||
|
NewRegion2->Protect = InitialRegion->Protect;
|
||||||
|
NewRegion2->Length = (InitialBaseAddress + InitialRegion->Length) -
|
||||||
|
(StartAddress + Length);
|
||||||
|
InsertAfterEntry(&NewRegion1->RegionListEntry,
|
||||||
|
&NewRegion2->RegionListEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExFreePool(NewRegion2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Either remove or shrink the initial region. */
|
||||||
|
if (InitialBaseAddress == StartAddress)
|
||||||
|
{
|
||||||
|
RemoveEntryList(&InitialRegion->RegionListEntry);
|
||||||
|
ExFreePool(InitialRegion);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InitialRegion->Length = StartAddress - InitialBaseAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(NewRegion1);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress,
|
||||||
|
PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length,
|
||||||
|
ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc)
|
||||||
|
{
|
||||||
|
PMM_REGION InitialRegion;
|
||||||
|
PVOID InitialBaseAddress;
|
||||||
|
PMM_REGION NewRegion;
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PMM_REGION CurrentRegion;
|
||||||
|
PVOID CurrentBaseAddress;
|
||||||
|
ULONG RemainingLength;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the first region containing part of the range of addresses to
|
||||||
|
* be altered.
|
||||||
|
*/
|
||||||
|
InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress,
|
||||||
|
&InitialBaseAddress);
|
||||||
|
if ((StartAddress + Length) >
|
||||||
|
(InitialBaseAddress + InitialRegion->Length))
|
||||||
|
{
|
||||||
|
RemainingLength = (StartAddress + Length) -
|
||||||
|
(InitialBaseAddress + InitialRegion->Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RemainingLength = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If necessary then split the region into the affected and unaffected parts.
|
||||||
|
*/
|
||||||
|
if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect)
|
||||||
|
{
|
||||||
|
NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress,
|
||||||
|
StartAddress, Length, NewType, NewProtect,
|
||||||
|
AddressSpace, AlterFunc);
|
||||||
|
if (NewRegion == NULL)
|
||||||
|
{
|
||||||
|
return(STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NewRegion = InitialRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free any complete regions that are containing in the range of addresses
|
||||||
|
* and call the helper function to actually do the changes.
|
||||||
|
*/
|
||||||
|
CurrentEntry = NewRegion->RegionListEntry.Flink;
|
||||||
|
CurrentBaseAddress = StartAddress + NewRegion->Length;
|
||||||
|
while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength)
|
||||||
|
{
|
||||||
|
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
|
||||||
|
RegionListEntry);
|
||||||
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
if (CurrentRegion->Type != NewType &&
|
||||||
|
CurrentRegion->Protect != NewProtect)
|
||||||
|
{
|
||||||
|
AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length,
|
||||||
|
CurrentRegion->Type, CurrentRegion->Protect,
|
||||||
|
NewType, NewProtect);
|
||||||
|
}
|
||||||
|
CurrentBaseAddress += CurrentRegion->Length;
|
||||||
|
NewRegion->Length += CurrentRegion->Length;
|
||||||
|
RemainingLength -= CurrentRegion->Length;
|
||||||
|
RemoveEntryList(&CurrentRegion->RegionListEntry);
|
||||||
|
ExFreePool(CurrentRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Split any final region.
|
||||||
|
*/
|
||||||
|
if (RemainingLength > 0)
|
||||||
|
{
|
||||||
|
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
|
||||||
|
RegionListEntry);
|
||||||
|
if (CurrentRegion->Type != NewType &&
|
||||||
|
CurrentRegion->Protect != NewProtect)
|
||||||
|
{
|
||||||
|
AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length,
|
||||||
|
CurrentRegion->Type, CurrentRegion->Protect,
|
||||||
|
NewType, NewProtect);
|
||||||
|
}
|
||||||
|
NewRegion->Length += RemainingLength;
|
||||||
|
CurrentRegion->Length -= RemainingLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the region after the new region has the same type then merge them.
|
||||||
|
*/
|
||||||
|
if (NewRegion->RegionListEntry.Flink != RegionListHead)
|
||||||
|
{
|
||||||
|
CurrentEntry = NewRegion->RegionListEntry.Flink;
|
||||||
|
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
|
||||||
|
RegionListEntry);
|
||||||
|
if (CurrentRegion->Type == NewRegion->Type &&
|
||||||
|
CurrentRegion->Protect == NewRegion->Protect)
|
||||||
|
{
|
||||||
|
NewRegion->Length += CurrentRegion->Length;
|
||||||
|
RemoveEntryList(&CurrentRegion->RegionListEntry);
|
||||||
|
ExFreePool(CurrentRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the region before the new region has the same type then merge them.
|
||||||
|
*/
|
||||||
|
if (NewRegion->RegionListEntry.Blink != RegionListHead)
|
||||||
|
{
|
||||||
|
CurrentEntry = NewRegion->RegionListEntry.Blink;
|
||||||
|
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
|
||||||
|
RegionListEntry);
|
||||||
|
if (CurrentRegion->Type == NewRegion->Type &&
|
||||||
|
CurrentRegion->Protect == NewRegion->Protect)
|
||||||
|
{
|
||||||
|
NewRegion->Length += CurrentRegion->Length;
|
||||||
|
RemoveEntryList(&CurrentRegion->RegionListEntry);
|
||||||
|
ExFreePool(CurrentRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmInitialiseRegion(PLIST_ENTRY RegionListHead, ULONG Length, ULONG Type,
|
||||||
|
ULONG Protect)
|
||||||
|
{
|
||||||
|
PMM_REGION Region;
|
||||||
|
|
||||||
|
Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
|
||||||
|
TAG_MM_REGION);
|
||||||
|
Region->Type = Type;
|
||||||
|
Region->Protect = Protect;
|
||||||
|
Region->Length = Length;
|
||||||
|
InitializeListHead(RegionListHead);
|
||||||
|
InsertHeadList(RegionListHead, &Region->RegionListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
PMM_REGION
|
||||||
|
MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address,
|
||||||
|
PVOID* RegionBaseAddress)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY current_entry;
|
||||||
|
PMM_REGION current;
|
||||||
|
PVOID StartAddress = BaseAddress;
|
||||||
|
|
||||||
|
current_entry = RegionListHead->Flink;
|
||||||
|
while (current_entry != RegionListHead)
|
||||||
|
{
|
||||||
|
current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry);
|
||||||
|
|
||||||
|
if (StartAddress <= Address &&
|
||||||
|
(StartAddress + current->Length) > Address)
|
||||||
|
{
|
||||||
|
if (RegionBaseAddress != NULL)
|
||||||
|
{
|
||||||
|
*RegionBaseAddress = StartAddress;
|
||||||
|
}
|
||||||
|
return(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_entry = current_entry->Flink;
|
||||||
|
StartAddress += current->Length;
|
||||||
|
}
|
||||||
|
return(NULL);
|
||||||
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: rmap.c,v 1.6 2002/06/04 15:26:57 dwelch Exp $
|
/* $Id: rmap.c,v 1.7 2002/08/10 16:41:19 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -86,7 +86,7 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
MmLockAddressSpace(&Process->AddressSpace);
|
MmLockAddressSpace(&Process->AddressSpace);
|
||||||
MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace, Address);
|
MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace, Address);
|
||||||
Type = MemoryArea->Type;
|
Type = MemoryArea->Type;
|
||||||
if (Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
if (Type == MEMORY_AREA_SECTION_VIEW)
|
||||||
{
|
{
|
||||||
Offset.QuadPart = (ULONG)((Address - (ULONG)MemoryArea->BaseAddress) +
|
Offset.QuadPart = (ULONG)((Address - (ULONG)MemoryArea->BaseAddress) +
|
||||||
MemoryArea->Data.SectionData.ViewOffset);
|
MemoryArea->Data.SectionData.ViewOffset);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: section.c,v 1.87 2002/08/08 17:54:15 dwelch Exp $
|
/* $Id: section.c,v 1.88 2002/08/10 16:41:19 dwelch Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/section.c
|
* FILE: ntoskrnl/mm/section.c
|
||||||
|
@ -36,6 +36,7 @@
|
||||||
#include <internal/pool.h>
|
#include <internal/pool.h>
|
||||||
#include <internal/cc.h>
|
#include <internal/cc.h>
|
||||||
#include <ddk/ntifs.h>
|
#include <ddk/ntifs.h>
|
||||||
|
#include <ntos/minmax.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
@ -432,6 +433,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
ULONG Entry1;
|
ULONG Entry1;
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
PMM_PAGEOP PageOp;
|
PMM_PAGEOP PageOp;
|
||||||
|
PMM_REGION Region;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is a window between taking the page fault and locking the
|
* There is a window between taking the page fault and locking the
|
||||||
|
@ -456,6 +458,9 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
Segment = MemoryArea->Data.SectionData.Segment;
|
Segment = MemoryArea->Data.SectionData.Segment;
|
||||||
Section = MemoryArea->Data.SectionData.Section;
|
Section = MemoryArea->Data.SectionData.Section;
|
||||||
|
Region = MmFindRegion(MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.SectionData.RegionListHead,
|
||||||
|
Address, NULL);
|
||||||
MmLockSection(Section);
|
MmLockSection(Section);
|
||||||
MmLockSectionSegment(Segment);
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
|
@ -591,7 +596,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
Region->Protect,
|
||||||
Page,
|
Page,
|
||||||
FALSE);
|
FALSE);
|
||||||
while (Status == STATUS_NO_MEMORY)
|
while (Status == STATUS_NO_MEMORY)
|
||||||
|
@ -599,7 +604,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
Region->Protect,
|
||||||
Page,
|
Page,
|
||||||
TRUE);
|
TRUE);
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
@ -646,7 +651,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
Region->Protect,
|
||||||
Offset,
|
Offset,
|
||||||
FALSE);
|
FALSE);
|
||||||
/*
|
/*
|
||||||
|
@ -689,7 +694,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
Region->Protect,
|
||||||
Page,
|
Page,
|
||||||
FALSE);
|
FALSE);
|
||||||
MmInsertRmap(Page, PsGetCurrentProcess(),
|
MmInsertRmap(Page, PsGetCurrentProcess(),
|
||||||
|
@ -715,14 +720,14 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* Check if this page needs to be mapped COW
|
* Check if this page needs to be mapped COW
|
||||||
*/
|
*/
|
||||||
if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
|
if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
|
||||||
(MemoryArea->Attributes == PAGE_READWRITE ||
|
(Region->Protect == PAGE_READWRITE ||
|
||||||
MemoryArea->Attributes == PAGE_EXECUTE_READWRITE))
|
Region->Protect == PAGE_EXECUTE_READWRITE))
|
||||||
{
|
{
|
||||||
Attributes = PAGE_READONLY;
|
Attributes = PAGE_READONLY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Attributes = MemoryArea->Attributes;
|
Attributes = Region->Protect;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -971,6 +976,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
ULONG PAddress;
|
ULONG PAddress;
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
PMM_PAGEOP PageOp;
|
PMM_PAGEOP PageOp;
|
||||||
|
PMM_REGION Region;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the page has been paged out or has already been set readwrite
|
* Check if the page has been paged out or has already been set readwrite
|
||||||
|
@ -993,6 +999,9 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
Segment = MemoryArea->Data.SectionData.Segment;
|
Segment = MemoryArea->Data.SectionData.Segment;
|
||||||
Section = MemoryArea->Data.SectionData.Section;
|
Section = MemoryArea->Data.SectionData.Section;
|
||||||
|
Region = MmFindRegion(MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.SectionData.RegionListHead,
|
||||||
|
Address, NULL);
|
||||||
MmLockSection(Section);
|
MmLockSection(Section);
|
||||||
MmLockSectionSegment(Segment);
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
|
@ -1009,8 +1018,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* Check if we are doing COW
|
* Check if we are doing COW
|
||||||
*/
|
*/
|
||||||
if (!((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
|
if (!((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
|
||||||
(MemoryArea->Attributes == PAGE_READWRITE ||
|
(Region->Protect == PAGE_READWRITE ||
|
||||||
MemoryArea->Attributes == PAGE_EXECUTE_READWRITE)))
|
Region->Protect == PAGE_EXECUTE_READWRITE)))
|
||||||
{
|
{
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
|
@ -1094,7 +1103,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
Region->Protect,
|
||||||
NewPage,
|
NewPage,
|
||||||
FALSE);
|
FALSE);
|
||||||
MmInsertRmap(NewPage, PsGetCurrentProcess(),
|
MmInsertRmap(NewPage, PsGetCurrentProcess(),
|
||||||
|
@ -1494,6 +1503,125 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID STATIC
|
||||||
|
MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG RegionSize,
|
||||||
|
ULONG OldType,
|
||||||
|
ULONG OldProtect,
|
||||||
|
ULONG NewType,
|
||||||
|
ULONG NewProtect)
|
||||||
|
{
|
||||||
|
PMEMORY_AREA MemoryArea;
|
||||||
|
PMM_SECTION_SEGMENT Segment;
|
||||||
|
BOOL DoCOW = FALSE;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, BaseAddress);
|
||||||
|
Segment = MemoryArea->Data.SectionData.Segment;
|
||||||
|
|
||||||
|
if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
|
||||||
|
(NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE))
|
||||||
|
{
|
||||||
|
DoCOW = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OldProtect != NewProtect)
|
||||||
|
{
|
||||||
|
for (i = 0; i < (RegionSize / PAGESIZE); i++)
|
||||||
|
{
|
||||||
|
PVOID Address = BaseAddress + (i * PAGESIZE);
|
||||||
|
ULONG Protect = NewProtect;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we doing COW for this segment then check if the page is
|
||||||
|
* already private.
|
||||||
|
*/
|
||||||
|
if (DoCOW && MmIsPagePresent(AddressSpace->Process, Address))
|
||||||
|
{
|
||||||
|
LARGE_INTEGER Offset;
|
||||||
|
ULONG Entry;
|
||||||
|
LARGE_INTEGER PhysicalAddress;
|
||||||
|
|
||||||
|
Offset.QuadPart =
|
||||||
|
(ULONG)(Address - (ULONG)MemoryArea->BaseAddress) +
|
||||||
|
MemoryArea->Data.SectionData.ViewOffset;
|
||||||
|
Entry = MmGetPageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
|
PhysicalAddress =
|
||||||
|
MmGetPhysicalAddressForProcess(AddressSpace->Process, Address);
|
||||||
|
|
||||||
|
Protect = PAGE_READONLY;
|
||||||
|
if ((Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
||||||
|
IS_SWAP_FROM_SSE(Entry) ||
|
||||||
|
(LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart))
|
||||||
|
{
|
||||||
|
Protect = NewProtect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MmIsPagePresent(AddressSpace->Process, Address))
|
||||||
|
{
|
||||||
|
MmSetPageProtect(AddressSpace->Process, BaseAddress,
|
||||||
|
Protect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG Length,
|
||||||
|
ULONG Protect,
|
||||||
|
PULONG OldProtect)
|
||||||
|
{
|
||||||
|
PMM_REGION Region;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Length = min(Length, MemoryArea->Length);
|
||||||
|
Region = MmFindRegion(MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.SectionData.RegionListHead,
|
||||||
|
BaseAddress, NULL);
|
||||||
|
*OldProtect = Region->Protect;
|
||||||
|
Status = MmAlterRegion(AddressSpace, MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.SectionData.RegionListHead,
|
||||||
|
BaseAddress, Length, Region->Type, Protect,
|
||||||
|
MmAlterViewAttributes);
|
||||||
|
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
MmQuerySectionView(PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PMEMORY_BASIC_INFORMATION Info,
|
||||||
|
PULONG ResultLength)
|
||||||
|
{
|
||||||
|
PMM_REGION Region;
|
||||||
|
PVOID RegionBaseAddress;
|
||||||
|
|
||||||
|
Region = MmFindRegion(MemoryArea->BaseAddress,
|
||||||
|
&MemoryArea->Data.SectionData.RegionListHead,
|
||||||
|
Address, &RegionBaseAddress);
|
||||||
|
Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
|
||||||
|
Info->AllocationBase = MemoryArea->BaseAddress;
|
||||||
|
Info->AllocationProtect = MemoryArea->Attributes;
|
||||||
|
Info->RegionSize = MemoryArea->Length;
|
||||||
|
Info->State = MEM_COMMIT;
|
||||||
|
Info->Protect = Region->Protect;
|
||||||
|
if (MemoryArea->Data.SectionData.Section->Flags & MM_IMAGE_SECTION)
|
||||||
|
{
|
||||||
|
Info->Type = MEM_IMAGE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info->Type = MEM_MAPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
MmpDeleteSection(PVOID ObjectBody)
|
MmpDeleteSection(PVOID ObjectBody)
|
||||||
{
|
{
|
||||||
|
@ -2187,6 +2315,7 @@ MmCreateImageSection(PHANDLE SectionHandle,
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
|
ULONG Characteristics;
|
||||||
|
|
||||||
Size = sizeof(MM_IMAGE_SECTION_OBJECT) +
|
Size = sizeof(MM_IMAGE_SECTION_OBJECT) +
|
||||||
(sizeof(MM_SECTION_SEGMENT) * NrSegments);
|
(sizeof(MM_SECTION_SEGMENT) * NrSegments);
|
||||||
|
@ -2226,27 +2355,27 @@ MmCreateImageSection(PHANDLE SectionHandle,
|
||||||
/*
|
/*
|
||||||
* Set up the protection and write copy variables.
|
* Set up the protection and write copy variables.
|
||||||
*/
|
*/
|
||||||
if ((ImageSections[i-1].Characteristics & IMAGE_SECTION_CHAR_READABLE) ||
|
Characteristics = ImageSections[i - 1].Characteristics;
|
||||||
(ImageSections[i-1].Characteristics & IMAGE_SECTION_CHAR_WRITABLE) ||
|
if ((Characteristics & IMAGE_SECTION_CHAR_READABLE) ||
|
||||||
(ImageSections[i-1].Characteristics & IMAGE_SECTION_CHAR_EXECUTABLE))
|
(Characteristics & IMAGE_SECTION_CHAR_WRITABLE) ||
|
||||||
|
(Characteristics & IMAGE_SECTION_CHAR_EXECUTABLE))
|
||||||
{
|
{
|
||||||
SectionSegments[i].Protection =
|
SectionSegments[i].Protection =
|
||||||
SectionCharacteristicsToProtect[ImageSections[i-1].Characteristics >> 28];
|
SectionCharacteristicsToProtect[Characteristics >> 28];
|
||||||
SectionSegments[i].WriteCopy =
|
SectionSegments[i].WriteCopy =
|
||||||
!(ImageSections[i - 1].Characteristics & IMAGE_SECTION_CHAR_SHARED);
|
!(Characteristics & IMAGE_SECTION_CHAR_SHARED);
|
||||||
}
|
}
|
||||||
else if (ImageSections[i-1].Characteristics & IMAGE_SECTION_CHAR_CODE)
|
else if (Characteristics & IMAGE_SECTION_CHAR_CODE)
|
||||||
{
|
{
|
||||||
SectionSegments[i].Protection = PAGE_EXECUTE_READ;
|
SectionSegments[i].Protection = PAGE_EXECUTE_READ;
|
||||||
SectionSegments[i].WriteCopy = TRUE;
|
SectionSegments[i].WriteCopy = TRUE;
|
||||||
}
|
}
|
||||||
else if (ImageSections[i-1].Characteristics &
|
else if (Characteristics & IMAGE_SECTION_CHAR_DATA)
|
||||||
IMAGE_SECTION_CHAR_DATA)
|
|
||||||
{
|
{
|
||||||
SectionSegments[i].Protection = PAGE_READWRITE;
|
SectionSegments[i].Protection = PAGE_READWRITE;
|
||||||
SectionSegments[i].WriteCopy = TRUE;
|
SectionSegments[i].WriteCopy = TRUE;
|
||||||
}
|
}
|
||||||
else if (ImageSections[i-1].Characteristics & IMAGE_SECTION_CHAR_BSS)
|
else if (Characteristics & IMAGE_SECTION_CHAR_BSS)
|
||||||
{
|
{
|
||||||
SectionSegments[i].Protection = PAGE_READWRITE;
|
SectionSegments[i].Protection = PAGE_READWRITE;
|
||||||
SectionSegments[i].WriteCopy = TRUE;
|
SectionSegments[i].WriteCopy = TRUE;
|
||||||
|
@ -2260,15 +2389,15 @@ MmCreateImageSection(PHANDLE SectionHandle,
|
||||||
/*
|
/*
|
||||||
* Set up the attributes.
|
* Set up the attributes.
|
||||||
*/
|
*/
|
||||||
if (ImageSections[i-1].Characteristics & IMAGE_SECTION_CHAR_CODE)
|
if (Characteristics & IMAGE_SECTION_CHAR_CODE)
|
||||||
{
|
{
|
||||||
SectionSegments[i].Attributes = 0;
|
SectionSegments[i].Attributes = 0;
|
||||||
}
|
}
|
||||||
else if (ImageSections[i-1].Characteristics & IMAGE_SECTION_CHAR_DATA)
|
else if (Characteristics & IMAGE_SECTION_CHAR_DATA)
|
||||||
{
|
{
|
||||||
SectionSegments[i].Attributes = 0;
|
SectionSegments[i].Attributes = 0;
|
||||||
}
|
}
|
||||||
else if (ImageSections[i-1].Characteristics & IMAGE_SECTION_CHAR_BSS)
|
else if (Characteristics & IMAGE_SECTION_CHAR_BSS)
|
||||||
{
|
{
|
||||||
SectionSegments[i].Attributes = MM_SECTION_SEGMENT_BSS;
|
SectionSegments[i].Attributes = MM_SECTION_SEGMENT_BSS;
|
||||||
}
|
}
|
||||||
|
@ -2409,14 +2538,9 @@ MmMapViewOfSegment(PEPROCESS Process,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
if (Protect == PAGE_NOACCESS || Protect == PAGE_GUARD)
|
|
||||||
{
|
|
||||||
DPRINT1("Mapping inaccessible region between 0x%.8X and 0x%.8X\n",
|
|
||||||
(*BaseAddress), (*BaseAddress) + ViewSize);
|
|
||||||
}
|
|
||||||
Status = MmCreateMemoryArea(Process,
|
Status = MmCreateMemoryArea(Process,
|
||||||
&Process->AddressSpace,
|
&Process->AddressSpace,
|
||||||
MEMORY_AREA_SECTION_VIEW_COMMIT,
|
MEMORY_AREA_SECTION_VIEW,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
ViewSize,
|
ViewSize,
|
||||||
Protect,
|
Protect,
|
||||||
|
@ -2442,6 +2566,8 @@ MmMapViewOfSegment(PEPROCESS Process,
|
||||||
MArea->Data.SectionData.Section = Section;
|
MArea->Data.SectionData.Section = Section;
|
||||||
MArea->Data.SectionData.ViewOffset = ViewOffset;
|
MArea->Data.SectionData.ViewOffset = ViewOffset;
|
||||||
MArea->Data.SectionData.WriteCopyView = FALSE;
|
MArea->Data.SectionData.WriteCopyView = FALSE;
|
||||||
|
MmInitialiseRegion(&MArea->Data.SectionData.RegionListHead,
|
||||||
|
ViewSize, 0, Protect);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -2612,6 +2738,8 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
||||||
PSECTION_OBJECT Section;
|
PSECTION_OBJECT Section;
|
||||||
PMM_SECTION_SEGMENT Segment;
|
PMM_SECTION_SEGMENT Segment;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PMM_REGION CurrentRegion;
|
||||||
|
|
||||||
AddressSpace = &Process->AddressSpace;
|
AddressSpace = &Process->AddressSpace;
|
||||||
|
|
||||||
|
@ -2632,6 +2760,16 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
||||||
KeAcquireSpinLock(&Section->ViewListLock, &oldIrql);
|
KeAcquireSpinLock(&Section->ViewListLock, &oldIrql);
|
||||||
RemoveEntryList(&MemoryArea->Data.SectionData.ViewListEntry);
|
RemoveEntryList(&MemoryArea->Data.SectionData.ViewListEntry);
|
||||||
KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
|
KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
|
||||||
|
|
||||||
|
CurrentEntry = MemoryArea->Data.SectionData.RegionListHead.Flink;
|
||||||
|
while (CurrentEntry != &MemoryArea->Data.SectionData.RegionListHead)
|
||||||
|
{
|
||||||
|
CurrentRegion =
|
||||||
|
CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry);
|
||||||
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
ExFreePool(CurrentRegion);
|
||||||
|
}
|
||||||
|
|
||||||
if (MemoryArea->Data.SectionData.Section->Flags & SO_PHYSICAL_MEMORY)
|
if (MemoryArea->Data.SectionData.Section->Flags & SO_PHYSICAL_MEMORY)
|
||||||
{
|
{
|
||||||
Status = MmFreeMemoryArea(&Process->AddressSpace,
|
Status = MmFreeMemoryArea(&Process->AddressSpace,
|
||||||
|
@ -3030,7 +3168,6 @@ MmMapViewOfSection(IN PVOID SectionObject,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN STDCALL
|
BOOLEAN STDCALL
|
||||||
MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
IN PLARGE_INTEGER NewFileSize)
|
IN PLARGE_INTEGER NewFileSize)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -62,6 +62,19 @@ extern DWORD CDECL SEHFilterRoutine(VOID);
|
||||||
extern VOID CDECL SEHHandlerRoutine(VOID);
|
extern VOID CDECL SEHHandlerRoutine(VOID);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DWORD CDECL SEHFilterRoutine(VOID)
|
||||||
|
{
|
||||||
|
DbgPrint("Within filter routine.\n");
|
||||||
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
|
//return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID CDECL SEHHandlerRoutine(VOID)
|
||||||
|
{
|
||||||
|
DbgPrint("Within exception handler.\n");
|
||||||
|
DbgPrint("System halted.\n");
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
EXCEPTION_DISPOSITION
|
||||||
CDECL
|
CDECL
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
|
|
||||||
this file added to test commit mailer
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue