mirror of
https://github.com/reactos/reactos.git
synced 2025-06-15 23:08:30 +00:00
Use ULONG_PTR instead of ULONG when doing pointer arithmetics.
Use ULONG_PTR for physical adresses and PVOID for virtual addresses. Added several consistency checks in the memory memory manager. svn path=/trunk/; revision=2946
This commit is contained in:
parent
5e4527aff7
commit
c804ca06be
39 changed files with 3165 additions and 1119 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: section.c,v 1.13 2001/02/17 17:42:46 ekohl Exp $
|
/* $Id: section.c,v 1.14 2002/05/13 18:10:38 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -157,6 +157,8 @@ MapViewOfFileEx(HANDLE hFileMappingObject,
|
||||||
BaseAddress = lpBaseAddress;
|
BaseAddress = lpBaseAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewSize = (ULONG) dwNumberOfBytesToMap;
|
||||||
|
|
||||||
Status = ZwMapViewOfSection(hFileMappingObject,
|
Status = ZwMapViewOfSection(hFileMappingObject,
|
||||||
NtCurrentProcess(),
|
NtCurrentProcess(),
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
|
|
|
@ -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: view.c,v 1.38 2002/05/05 14:57:42 chorns Exp $
|
/* $Id: view.c,v 1.39 2002/05/13 18:10:38 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -284,7 +284,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
|
||||||
ExReleaseFastMutex(&ViewLock);
|
ExReleaseFastMutex(&ViewLock);
|
||||||
for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++)
|
for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++)
|
||||||
{
|
{
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page);
|
Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -295,7 +295,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
current->BaseAddress + (i * PAGESIZE),
|
current->BaseAddress + (i * PAGESIZE),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)Page,
|
Page,
|
||||||
TRUE);
|
TRUE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -452,14 +452,22 @@ CcRosRequestCacheSegment(PBCB Bcb,
|
||||||
CacheSeg));
|
CacheSeg));
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC VOID
|
VOID
|
||||||
CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
CcFreeCachePage(IN BOOLEAN Before,
|
||||||
ULONG PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
IN PVOID Context,
|
||||||
|
IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN SWAPENTRY SwapEntry,
|
||||||
|
IN BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
if (!Before)
|
||||||
if (PhysAddr != 0)
|
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_CACHE, (PVOID)PhysAddr);
|
assert(SwapEntry == 0);
|
||||||
|
if (PhysicalAddress != 0)
|
||||||
|
{
|
||||||
|
MmReleasePageMemoryConsumer(MC_CACHE, PhysicalAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey,
|
||||||
|
|
||||||
if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
|
if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
|
||||||
{
|
{
|
||||||
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(PagedPool,
|
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool,
|
||||||
(ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD));
|
(ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD));
|
||||||
|
|
||||||
if (ParentKey->NumberOfSubKeys > 0)
|
if (ParentKey->NumberOfSubKeys > 0)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: work.c,v 1.11 2001/08/26 17:26:23 ekohl Exp $
|
/* $Id: work.c,v 1.12 2002/05/13 18:10:39 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -99,8 +99,8 @@ ExWorkerThreadEntryPoint(PVOID context)
|
||||||
static VOID ExInitializeWorkQueue(PWORK_QUEUE WorkQueue,
|
static VOID ExInitializeWorkQueue(PWORK_QUEUE WorkQueue,
|
||||||
KPRIORITY Priority)
|
KPRIORITY Priority)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PETHREAD Thread;
|
|
||||||
|
|
||||||
InitializeListHead(&WorkQueue->Head);
|
InitializeListHead(&WorkQueue->Head);
|
||||||
KeInitializeSpinLock(&WorkQueue->Lock);
|
KeInitializeSpinLock(&WorkQueue->Lock);
|
||||||
|
@ -116,15 +116,13 @@ static VOID ExInitializeWorkQueue(PWORK_QUEUE WorkQueue,
|
||||||
NULL,
|
NULL,
|
||||||
ExWorkerThreadEntryPoint,
|
ExWorkerThreadEntryPoint,
|
||||||
WorkQueue);
|
WorkQueue);
|
||||||
ObReferenceObjectByHandle(WorkQueue->Thread[i],
|
Status = PiSetPriorityThread(WorkQueue->Thread[i], Priority);
|
||||||
THREAD_ALL_ACCESS,
|
|
||||||
PsThreadType,
|
if (!NT_SUCCESS(Status))
|
||||||
KernelMode,
|
{
|
||||||
(PVOID*)&Thread,
|
DPRINT1("PiSetThreadPriority() failed with status 0x%.08x\n", Status);
|
||||||
NULL);
|
KeBugCheck(0);
|
||||||
KeSetPriorityThread(&Thread->Tcb,
|
}
|
||||||
Priority);
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,5 +15,4 @@
|
||||||
#define InternalNotificationTimer (InternalBaseType + 10)
|
#define InternalNotificationTimer (InternalBaseType + 10)
|
||||||
#define InternalSynchronizationTimer (InternalBaseType + 11)
|
#define InternalSynchronizationTimer (InternalBaseType + 11)
|
||||||
#define InternalQueueType (InternalBaseType + 12)
|
#define InternalQueueType (InternalBaseType + 12)
|
||||||
|
#define InternalTypeMaximum InternalQueueType
|
||||||
|
|
||||||
|
|
|
@ -222,6 +222,15 @@ KeBugCheckWithTf(ULONG BugCheckCode,
|
||||||
VOID
|
VOID
|
||||||
KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2);
|
KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KiValidateDispatcherObject(IN PDISPATCHER_HEADER Object);
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
#define VALIDATE_DISPATCHER_OBJECT(Object) KiValidateDispatcherObject(Object);
|
||||||
|
#else /* !DBG */
|
||||||
|
#define VALIDATE_DISPATCHER_OBJECT(Object)
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
#endif /* not __ASM__ */
|
#endif /* not __ASM__ */
|
||||||
|
|
||||||
#define MAXIMUM_PROCESSORS 32
|
#define MAXIMUM_PROCESSORS 32
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#ifndef __INCLUDE_INTERNAL_MM_H
|
#ifndef __INCLUDE_INTERNAL_MM_H
|
||||||
#define __INCLUDE_INTERNAL_MM_H
|
#define __INCLUDE_INTERNAL_MM_H
|
||||||
|
|
||||||
|
#include <roscfg.h>
|
||||||
#include <internal/ntoskrnl.h>
|
#include <internal/ntoskrnl.h>
|
||||||
#include <internal/arch/mm.h>
|
#include <internal/arch/mm.h>
|
||||||
|
|
||||||
|
@ -14,7 +15,8 @@ struct _EPROCESS;
|
||||||
|
|
||||||
struct _MM_RMAP_ENTRY;
|
struct _MM_RMAP_ENTRY;
|
||||||
struct _MM_PAGEOP;
|
struct _MM_PAGEOP;
|
||||||
typedef ULONG SWAPENTRY;
|
typedef ULONG SWAPENTRY, *PSWAPENTRY;
|
||||||
|
|
||||||
|
|
||||||
#define MEMORY_AREA_INVALID (0)
|
#define MEMORY_AREA_INVALID (0)
|
||||||
#define MEMORY_AREA_SECTION_VIEW_COMMIT (1)
|
#define MEMORY_AREA_SECTION_VIEW_COMMIT (1)
|
||||||
|
@ -58,7 +60,7 @@ typedef ULONG SWAPENTRY;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG Entry[NR_SECTION_PAGE_ENTRIES];
|
ULONG_PTR Entry[NR_SECTION_PAGE_ENTRIES];
|
||||||
} SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
|
} SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -117,14 +119,19 @@ typedef struct
|
||||||
BOOLEAN Executable;
|
BOOLEAN Executable;
|
||||||
} SECTION_OBJECT, *PSECTION_OBJECT;
|
} SECTION_OBJECT, *PSECTION_OBJECT;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
|
typedef struct _MEMORY_AREA
|
||||||
{
|
{
|
||||||
|
#ifdef DBG
|
||||||
|
ULONG Magic;
|
||||||
|
#endif /* DBG */
|
||||||
ULONG Type;
|
ULONG Type;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
ULONG LockCount;
|
ULONG LockCount;
|
||||||
|
ULONG ReferenceCount;
|
||||||
struct _EPROCESS* Process;
|
struct _EPROCESS* Process;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -143,46 +150,287 @@ typedef struct
|
||||||
} Data;
|
} Data;
|
||||||
} MEMORY_AREA, *PMEMORY_AREA;
|
} MEMORY_AREA, *PMEMORY_AREA;
|
||||||
|
|
||||||
|
|
||||||
|
#define MM_PAGEOP_PAGEIN (1)
|
||||||
|
#define MM_PAGEOP_PAGEOUT (2)
|
||||||
|
#define MM_PAGEOP_PAGESYNCH (3)
|
||||||
|
#define MM_PAGEOP_ACCESSFAULT (4)
|
||||||
|
#define MM_PAGEOP_MINIMUM MM_PAGEOP_PAGEIN
|
||||||
|
#define MM_PAGEOP_MAXIMUM MM_PAGEOP_ACCESSFAULT
|
||||||
|
|
||||||
|
typedef struct _MM_PAGEOP
|
||||||
|
{
|
||||||
|
#ifdef DBG
|
||||||
|
/* Magic ID */
|
||||||
|
ULONG Magic;
|
||||||
|
#endif /* DBG */
|
||||||
|
/* Type of operation. */
|
||||||
|
ULONG OpType;
|
||||||
|
/* Number of threads interested in this operation. */
|
||||||
|
ULONG ReferenceCount;
|
||||||
|
/* Event that will be set when the operation is completed. */
|
||||||
|
KEVENT CompletionEvent;
|
||||||
|
/* Status of the operation once it is completed. */
|
||||||
|
NTSTATUS Status;
|
||||||
|
/* TRUE if the operation was abandoned. */
|
||||||
|
BOOLEAN Abandoned;
|
||||||
|
/* The memory area to be affected by the operation. */
|
||||||
|
PMEMORY_AREA MArea;
|
||||||
|
ULONG Hash;
|
||||||
|
struct _MM_PAGEOP* Next;
|
||||||
|
struct _ETHREAD* Thread;
|
||||||
|
/*
|
||||||
|
* These fields are used to identify the operation if it is against a
|
||||||
|
* virtual memory area.
|
||||||
|
*/
|
||||||
|
ULONG Pid;
|
||||||
|
PVOID Address;
|
||||||
|
/*
|
||||||
|
* These fields are used to identify the operation if it is against a
|
||||||
|
* section mapping.
|
||||||
|
*/
|
||||||
|
PMM_SECTION_SEGMENT Segment;
|
||||||
|
ULONG Offset;
|
||||||
|
} MM_PAGEOP, *PMM_PAGEOP;
|
||||||
|
|
||||||
|
|
||||||
|
#define PAGE_STATE_VALID (0)
|
||||||
|
#define PAGE_STATE_PROTOTYPE (1)
|
||||||
|
#define PAGE_STATE_DEMAND_ZERO (2)
|
||||||
|
#define PAGE_STATE_TRANSITION (3)
|
||||||
|
|
||||||
|
#define MM_PTYPE(x) (x)
|
||||||
|
|
||||||
|
#define PAGE_LIST_FREE_ZEROED (0)
|
||||||
|
#define PAGE_LIST_FREE_UNZEROED (1)
|
||||||
|
#define PAGE_LIST_BIOS (2)
|
||||||
|
#define PAGE_LIST_STANDBY (3)
|
||||||
|
#define PAGE_LIST_MODIFIED (4)
|
||||||
|
#define PAGE_LIST_MODIFIED_NO_WRITE (5)
|
||||||
|
#define PAGE_LIST_MPW (6)
|
||||||
|
|
||||||
|
/* PHYSICAL_PAGE.Flags */
|
||||||
|
#define MM_PHYSICAL_PAGE_FREE (0x1)
|
||||||
|
#define MM_PHYSICAL_PAGE_USED (0x2)
|
||||||
|
#define MM_PHYSICAL_PAGE_BIOS (0x3)
|
||||||
|
#define MM_PHYSICAL_PAGE_STANDBY (0x4)
|
||||||
|
#define MM_PHYSICAL_PAGE_MODIFIED (0x5)
|
||||||
|
#define MM_PHYSICAL_PAGE_MPW (0x6)
|
||||||
|
|
||||||
|
typedef VOID (*PRMAP_DELETE_CALLBACK)(IN PVOID Context,
|
||||||
|
IN PEPROCESS Process,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
|
/* FIXME: Unionize this structure */
|
||||||
|
typedef struct _PHYSICAL_PAGE
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
ULONG ReferenceCount;
|
||||||
|
SWAPENTRY SavedSwapEntry;
|
||||||
|
ULONG LockCount;
|
||||||
|
ULONG MapCount;
|
||||||
|
struct _MM_RMAP_ENTRY* RmapListHead;
|
||||||
|
PRMAP_DELETE_CALLBACK RmapDelete;
|
||||||
|
PVOID RmapDeleteContext;
|
||||||
|
PMM_PAGEOP PageOp;
|
||||||
|
} PHYSICAL_PAGE, *PPHYSICAL_PAGE;
|
||||||
|
|
||||||
|
|
||||||
|
extern PPHYSICAL_PAGE MmPageArray;
|
||||||
|
|
||||||
|
#define MiPageFromDescriptor(pp)((((ULONG_PTR)(pp) - (ULONG_PTR) MmPageArray) / sizeof(PHYSICAL_PAGE)) * PAGESIZE)
|
||||||
|
|
||||||
typedef struct _MADDRESS_SPACE
|
typedef struct _MADDRESS_SPACE
|
||||||
{
|
{
|
||||||
|
#ifdef DBG
|
||||||
|
ULONG Magic;
|
||||||
|
#endif /* DBG */
|
||||||
LIST_ENTRY MAreaListHead;
|
LIST_ENTRY MAreaListHead;
|
||||||
KMUTEX Lock;
|
KMUTEX Lock;
|
||||||
|
ULONG ReferenceCount;
|
||||||
ULONG LowestAddress;
|
ULONG LowestAddress;
|
||||||
struct _EPROCESS* Process;
|
struct _EPROCESS* Process;
|
||||||
PUSHORT PageTableRefCountTable;
|
PUSHORT PageTableRefCountTable;
|
||||||
ULONG PageTableRefCountTableSize;
|
ULONG PageTableRefCountTableSize;
|
||||||
} MADDRESS_SPACE, *PMADDRESS_SPACE;
|
} MADDRESS_SPACE, *PMADDRESS_SPACE;
|
||||||
|
|
||||||
|
|
||||||
|
#define MmIsCopyOnWriteMemoryArea(MemoryArea) \
|
||||||
|
( \
|
||||||
|
((MemoryArea)->Data.SectionData.Segment->WriteCopy \
|
||||||
|
|| (MemoryArea)->Data.SectionData.WriteCopyView) \
|
||||||
|
&& ((MemoryArea)->Attributes == PAGE_READWRITE \
|
||||||
|
|| (MemoryArea)->Attributes == PAGE_EXECUTE_READWRITE) \
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
extern ULONG MiMaximumModifiedPageListSize;
|
||||||
|
extern ULONG MiModifiedPageListSize;
|
||||||
|
extern ULONG MiMaximumStandbyPageListSize;
|
||||||
|
extern ULONG MiStandbyPageListSize;
|
||||||
|
|
||||||
/* FUNCTIONS */
|
/* FUNCTIONS */
|
||||||
|
|
||||||
VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
|
#ifdef DBG
|
||||||
VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
|
|
||||||
VOID MmInitializeKernelAddressSpace(VOID);
|
VOID
|
||||||
PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID);
|
DbgMmDumpProtection(IN ULONG Value);
|
||||||
PMADDRESS_SPACE MmGetKernelAddressSpace(VOID);
|
|
||||||
NTSTATUS MmInitializeAddressSpace(struct _EPROCESS* Process,
|
VOID
|
||||||
PMADDRESS_SPACE AddressSpace);
|
MiDumpPTE(IN ULONG Value);
|
||||||
NTSTATUS MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace);
|
|
||||||
PVOID STDCALL MmAllocateSection (IN ULONG Length);
|
VOID
|
||||||
NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
|
MiDumpProcessPTE(IN PEPROCESS Process,
|
||||||
PMADDRESS_SPACE AddressSpace,
|
IN PVOID Address);
|
||||||
ULONG Type,
|
|
||||||
PVOID* BaseAddress,
|
#endif /* DBG */
|
||||||
ULONG Length,
|
|
||||||
ULONG Attributes,
|
VOID
|
||||||
MEMORY_AREA** Result,
|
MiAcquirePageListLock(IN ULONG PageList,
|
||||||
BOOL FixedAddress);
|
OUT PLIST_ENTRY * ListHead);
|
||||||
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
|
|
||||||
PVOID Address);
|
VOID
|
||||||
NTSTATUS MmInitMemoryAreas(VOID);
|
MiReleasePageListLock();
|
||||||
VOID ExInitNonPagedPool(ULONG BaseAddress);
|
|
||||||
NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
VOID
|
||||||
PVOID BaseAddress,
|
MiReclaimPage(IN ULONG_PTR PhysicalAddress,
|
||||||
ULONG Length,
|
IN BOOLEAN Dirty);
|
||||||
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
|
|
||||||
PVOID Address, ULONG PhysAddr, SWAPENTRY SwapEntry,
|
VOID
|
||||||
BOOLEAN Dirty),
|
MmInitMpwThreads();
|
||||||
PVOID FreePageContext);
|
|
||||||
|
VOID
|
||||||
|
MiShutdownMpwThreads();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSignalModifiedPageWriter();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSignalMappedPageWriter();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmInitializeBalanceSetManager();
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MiGetLockCountPage(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiDisableAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN PBOOLEAN Modified);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiEnableAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN BOOLEAN Modified);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiGetDirtyAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN PBOOLEAN Dirty);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiGetPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN ULONG PageState,
|
||||||
|
OUT PBOOLEAN Result);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiClearPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN ULONG PageState);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSetPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN ULONG PageState);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSetDirtyAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN BOOLEAN Dirty);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MiPageState(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG PageState);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiClearPageState(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG PageState);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSetPageState(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG PageState);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmInitializeKernelAddressSpace(VOID);
|
||||||
|
|
||||||
|
PMADDRESS_SPACE
|
||||||
|
MmGetCurrentAddressSpace();
|
||||||
|
|
||||||
|
PMADDRESS_SPACE
|
||||||
|
MmGetKernelAddressSpace();
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmInitializeAddressSpace(IN PEPROCESS Process,
|
||||||
|
IN PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmDestroyAddressSpace(IN PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmReferenceAddressSpace(IN PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmDereferenceAddressSpace(IN PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmApplyMemoryAreaProtection(IN PMEMORY_AREA MemoryArea);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmFlushSection(IN PSECTION_OBJECT SectionObject,
|
||||||
|
IN PLARGE_INTEGER FileOffset OPTIONAL,
|
||||||
|
IN ULONG Length,
|
||||||
|
OUT PIO_STATUS_BLOCK IoStatus OPTIONAL);
|
||||||
|
|
||||||
|
PVOID STDCALL
|
||||||
|
MmAllocateSection(IN ULONG Length);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmCreateMemoryArea(IN PEPROCESS Process,
|
||||||
|
IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN ULONG Type,
|
||||||
|
IN OUT PVOID* BaseAddress,
|
||||||
|
IN ULONG Length,
|
||||||
|
IN ULONG Attributes,
|
||||||
|
OUT PMEMORY_AREA* Result,
|
||||||
|
IN BOOLEAN FixedAddress);
|
||||||
|
|
||||||
|
PMEMORY_AREA
|
||||||
|
MmOpenMemoryAreaByAddress(IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmCloseMemoryArea(IN PMEMORY_AREA MemoryArea);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmInitMemoryAreas();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ExInitNonPagedPool(IN PVOID BaseAddress);
|
||||||
|
|
||||||
|
typedef VOID (*PFREE_MEMORY_AREA_PAGE_CALLBACK)(IN BOOLEAN Before,
|
||||||
|
IN PVOID Context,
|
||||||
|
IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN SWAPENTRY SwapEntry,
|
||||||
|
IN BOOLEAN Dirty);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmFreeMemoryArea(IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN PVOID BaseAddress,
|
||||||
|
IN ULONG Length,
|
||||||
|
IN PFREE_MEMORY_AREA_PAGE_CALLBACK FreePage,
|
||||||
|
IN PVOID FreePageContext);
|
||||||
|
|
||||||
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
|
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
|
||||||
NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
|
NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
|
||||||
NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
|
NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
|
||||||
|
@ -204,10 +452,12 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
||||||
PADDRESS_RANGE BIOSMemoryMap,
|
PADDRESS_RANGE BIOSMemoryMap,
|
||||||
ULONG AddressRangeCount);
|
ULONG AddressRangeCount);
|
||||||
|
|
||||||
PVOID
|
ULONG_PTR
|
||||||
MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry);
|
MmAllocPage(IN ULONG Consumer,
|
||||||
VOID MmDereferencePage(PVOID PhysicalAddress);
|
IN SWAPENTRY SavedSwapEntry);
|
||||||
VOID MmReferencePage(PVOID PhysicalAddress);
|
|
||||||
|
VOID MmDereferencePage(IN ULONG_PTR PhysicalAddress);
|
||||||
|
VOID MmReferencePage(IN ULONG_PTR PhysicalAddress);
|
||||||
VOID MmDeletePageTable(struct _EPROCESS* Process,
|
VOID MmDeletePageTable(struct _EPROCESS* Process,
|
||||||
PVOID Address);
|
PVOID Address);
|
||||||
NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
|
NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
|
||||||
|
@ -217,21 +467,33 @@ NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
|
||||||
VOID
|
VOID
|
||||||
MmDeleteVirtualMapping(struct _EPROCESS* Process,
|
MmDeleteVirtualMapping(struct _EPROCESS* Process,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
BOOL FreePage,
|
BOOLEAN FreePage,
|
||||||
BOOL* WasDirty,
|
PBOOLEAN WasDirty,
|
||||||
ULONG* PhysicalPage);
|
PULONG PhysicalPage);
|
||||||
|
|
||||||
#define MM_PAGE_CLEAN (0)
|
#define MM_PAGE_CLEAN (0)
|
||||||
#define MM_PAGE_DIRTY (1)
|
#define MM_PAGE_DIRTY (1)
|
||||||
|
|
||||||
VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages);
|
VOID
|
||||||
PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
|
MmBuildMdlFromPages(IN PMDL Mdl,
|
||||||
VOID MiShutdownMemoryManager(VOID);
|
IN PULONG_PTR Pages);
|
||||||
ULONG MmGetPhysicalAddressForProcess(struct _EPROCESS* Process,
|
|
||||||
PVOID Address);
|
PVOID
|
||||||
|
MmGetMdlPageAddress(IN PMDL Mdl,
|
||||||
|
IN PVOID Offset);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiShutdownMemoryManager(VOID);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MmGetPhysicalAddressForProcess(IN struct _EPROCESS* Process,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress);
|
MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress);
|
||||||
VOID MmInitPagingFile(VOID);
|
|
||||||
|
VOID
|
||||||
|
MmInitPagingFile(VOID);
|
||||||
|
|
||||||
/* FIXME: it should be in ddk/mmfuncs.h */
|
/* FIXME: it should be in ddk/mmfuncs.h */
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -276,13 +538,14 @@ VOID MmClearWaitPage(PVOID Page);
|
||||||
VOID MmSetWaitPage(PVOID Page);
|
VOID MmSetWaitPage(PVOID Page);
|
||||||
BOOLEAN MmIsPageDirty(struct _EPROCESS* Process, PVOID Address);
|
BOOLEAN MmIsPageDirty(struct _EPROCESS* Process, PVOID Address);
|
||||||
BOOLEAN MmIsPageTablePresent(PVOID PAddress);
|
BOOLEAN MmIsPageTablePresent(PVOID PAddress);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
MmFlushVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MemoryArea,
|
PMEMORY_AREA MemoryArea,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
struct _MM_PAGEOP* PageOp);
|
struct _MM_PAGEOP* PageOp);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
MmFlushSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MemoryArea,
|
PMEMORY_AREA MemoryArea,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
struct _MM_PAGEOP* PageOp);
|
struct _MM_PAGEOP* PageOp);
|
||||||
|
@ -290,14 +553,44 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
ULONG Length);
|
ULONG Length);
|
||||||
|
|
||||||
VOID ExUnmapPage(PVOID Addr);
|
VOID
|
||||||
PVOID ExAllocatePage(VOID);
|
ExUnmapPage(IN PVOID Addr);
|
||||||
|
|
||||||
VOID MmInitPagingFile(VOID);
|
PVOID
|
||||||
BOOLEAN MmReserveSwapPages(ULONG Nr);
|
ExAllocatePage(VOID);
|
||||||
VOID MmDereserveSwapPages(ULONG Nr);
|
|
||||||
SWAPENTRY MmAllocSwapPage(VOID);
|
VOID
|
||||||
VOID MmFreeSwapPage(SWAPENTRY Entry);
|
MmInitPagingFile(VOID);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MmReserveSwapPages(IN ULONG Nr);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmDereserveSwapPages(IN ULONG Nr);
|
||||||
|
|
||||||
|
SWAPENTRY
|
||||||
|
MmAllocSwapPage(VOID);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmFreeSwapPage(IN SWAPENTRY Entry);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidateSwapEntry(IN SWAPENTRY Entry);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidatePageOp(IN PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidatePhysicalAddress(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidateAddressSpace(IN PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidateMemoryArea(IN PMEMORY_AREA MemoryArea);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidateRmapList(struct _MM_RMAP_ENTRY* RmapList);
|
||||||
|
|
||||||
VOID MmInit1(ULONG FirstKernelPhysAddress,
|
VOID MmInit1(ULONG FirstKernelPhysAddress,
|
||||||
ULONG LastKernelPhysAddress,
|
ULONG LastKernelPhysAddress,
|
||||||
|
@ -327,107 +620,197 @@ typedef struct
|
||||||
|
|
||||||
extern MM_STATS MmStats;
|
extern MM_STATS MmStats;
|
||||||
|
|
||||||
|
extern BOOLEAN MiInitialized;
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
#define VALIDATE_PHYSICAL_ADDRESS(PhysicalAddress) MiValidatePhysicalAddress((ULONG_PTR)PhysicalAddress)
|
||||||
|
#define VALIDATE_SWAP_ENTRY(Entry) MiValidateSwapEntry(Entry)
|
||||||
|
#define VALIDATE_PAGEOP(PageOp) MiValidatePageOp(PageOp)
|
||||||
|
#define VALIDATE_ADDRESS_SPACE(AddressSpace) MiValidateAddressSpace(AddressSpace)
|
||||||
|
#define VALIDATE_MEMORY_AREA(MemoryArea) MiValidateMemoryArea(MemoryArea)
|
||||||
|
#define VALIDATE_RMAP_LIST(RmapList) MiValidateRmapList(RmapList)
|
||||||
|
#else /* !DBG */
|
||||||
|
#define VALIDATE_PHYSICAL_ADDRESS(PhysicalAddress)
|
||||||
|
#define VALIDATE_SWAP_ENTRY(Entry)
|
||||||
|
#define VALIDATE_PAGEOP(PageOp)
|
||||||
|
#define VALIDATE_ADDRESS_SPACE(AddressSpace)
|
||||||
|
#define VALIDATE_MEMORY_AREA(MemoryArea)
|
||||||
|
#define VALIDATE_RMAP_LIST(RmapList)
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiLockAddressSpace(IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN LPSTR FileName,
|
||||||
|
IN ULONG LineNumber);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiUnlockAddressSpace(IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN LPSTR FileName,
|
||||||
|
IN ULONG LineNumber);
|
||||||
|
|
||||||
|
/* Use macros for easier debugging */
|
||||||
|
#define MmLockAddressSpace(AddressSpace) MiLockAddressSpace(AddressSpace, __FILE__, __LINE__)
|
||||||
|
#define MmUnlockAddressSpace(AddressSpace) MiUnlockAddressSpace(AddressSpace, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#else /* !DBG */
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiLockAddressSpace(IN PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiUnlockAddressSpace(IN PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
#define MmLockAddressSpace MiLockAddressSpace
|
||||||
|
#define MmUnlockAddressSpace MiUnlockAddressSpace
|
||||||
|
|
||||||
|
#endif /* !DBG */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiReferenceMemoryArea(IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN LPSTR FileName,
|
||||||
|
IN ULONG LineNumber);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiDereferenceMemoryArea(IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN LPSTR FileName,
|
||||||
|
IN ULONG LineNumber);
|
||||||
|
|
||||||
|
/* Use macros for easier debugging */
|
||||||
|
#define MmReferenceMemoryArea(MemoryArea) MiReferenceMemoryArea(MemoryArea, __FILE__, __LINE__)
|
||||||
|
#define MmDereferenceMemoryArea(MemoryArea) MiDereferenceMemoryArea(MemoryArea, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#else /* !DBG */
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiReferenceMemoryArea(IN PMEMORY_AREA MemoryArea);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiDereferenceMemoryArea(IN PMEMORY_AREA MemoryArea);
|
||||||
|
|
||||||
|
#define MmReferenceMemoryArea MiReferenceMemoryArea
|
||||||
|
#define MmDereferenceMemoryArea MiDereferenceMemoryArea
|
||||||
|
|
||||||
|
#endif /* !DBG */
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MArea,
|
PMEMORY_AREA MArea,
|
||||||
PVOID Address);
|
PVOID Address);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MArea,
|
PMEMORY_AREA MArea,
|
||||||
PVOID Address);
|
PVOID Address);
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
|
MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
|
MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
|
MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
|
||||||
VOID
|
|
||||||
MmSetFlagsPage(PVOID PhysicalAddress, ULONG Flags);
|
|
||||||
ULONG
|
|
||||||
MmGetFlagsPage(PVOID PhysicalAddress);
|
|
||||||
VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress,
|
|
||||||
SWAPENTRY SavedSwapEntry);
|
|
||||||
SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
|
|
||||||
VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
|
|
||||||
VOID MmLockPage(PVOID PhysicalPage);
|
|
||||||
VOID MmUnlockPage(PVOID PhysicalPage);
|
|
||||||
|
|
||||||
NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG Count);
|
|
||||||
NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
|
|
||||||
NTSTATUS
|
|
||||||
MmCreatePhysicalMemorySection(VOID);
|
|
||||||
PVOID
|
|
||||||
MmGetContinuousPages(ULONG NumberOfBytes,
|
|
||||||
PHYSICAL_ADDRESS HighestAcceptableAddress,
|
|
||||||
ULONG Alignment);
|
|
||||||
|
|
||||||
#define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|
||||||
MEMORY_AREA* MemoryArea,
|
|
||||||
PVOID Address,
|
|
||||||
BOOLEAN Locked);
|
|
||||||
ULONG
|
|
||||||
MmGetPageProtect(struct _EPROCESS* Process, PVOID Address);
|
|
||||||
PVOID
|
|
||||||
ExAllocatePageWithPhysPage(ULONG PhysPage);
|
|
||||||
ULONG
|
|
||||||
MmGetReferenceCountPage(PVOID PhysicalAddress);
|
|
||||||
BOOLEAN
|
|
||||||
MmIsUsablePage(PVOID PhysicalAddress);
|
|
||||||
|
|
||||||
#define MM_PAGEOP_PAGEIN (1)
|
|
||||||
#define MM_PAGEOP_PAGEOUT (2)
|
|
||||||
#define MM_PAGEOP_PAGESYNCH (3)
|
|
||||||
#define MM_PAGEOP_ACCESSFAULT (4)
|
|
||||||
|
|
||||||
typedef struct _MM_PAGEOP
|
|
||||||
{
|
|
||||||
/* Type of operation. */
|
|
||||||
ULONG OpType;
|
|
||||||
/* Number of threads interested in this operation. */
|
|
||||||
ULONG ReferenceCount;
|
|
||||||
/* Event that will be set when the operation is completed. */
|
|
||||||
KEVENT CompletionEvent;
|
|
||||||
/* Status of the operation once it is completed. */
|
|
||||||
NTSTATUS Status;
|
|
||||||
/* TRUE if the operation was abandoned. */
|
|
||||||
BOOLEAN Abandoned;
|
|
||||||
/* The memory area to be affected by the operation. */
|
|
||||||
PMEMORY_AREA MArea;
|
|
||||||
ULONG Hash;
|
|
||||||
struct _MM_PAGEOP* Next;
|
|
||||||
struct _ETHREAD* Thread;
|
|
||||||
/*
|
|
||||||
* These fields are used to identify the operation if it is against a
|
|
||||||
* virtual memory area.
|
|
||||||
*/
|
|
||||||
ULONG Pid;
|
|
||||||
PVOID Address;
|
|
||||||
/*
|
|
||||||
* These fields are used to identify the operation if it is against a
|
|
||||||
* section mapping.
|
|
||||||
*/
|
|
||||||
PMM_SECTION_SEGMENT Segment;
|
|
||||||
ULONG Offset;
|
|
||||||
} MM_PAGEOP, *PMM_PAGEOP;
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmReleasePageOp(PMM_PAGEOP PageOp);
|
MmSetFlagsPage(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN ULONG Flags);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MmGetFlagsPage(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmSetSavedSwapEntryPage(IN ULONG_PTR PhysicalAddress,
|
||||||
|
SWAPENTRY SavedSwapEntry);
|
||||||
|
|
||||||
|
SWAPENTRY
|
||||||
|
MmGetSavedSwapEntryPage(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmSetSavedPageOp(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
PMM_PAGEOP
|
PMM_PAGEOP
|
||||||
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
MmGetSavedPageOp(IN ULONG_PTR PhysicalAddress);
|
||||||
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType);
|
|
||||||
|
VOID
|
||||||
|
MmSetCleanPage(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmLockPage(IN ULONG_PTR PhysicalPage);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmUnlockPage(IN ULONG_PTR PhysicalPage);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG Count);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmCreatePhysicalMemorySection(VOID);
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
|
PHYSICAL_ADDRESS HighestAcceptableAddress,
|
||||||
|
ULONG Alignment);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmAccessFaultSectionView(IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN MEMORY_AREA* IN MemoryArea,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN BOOLEAN Locked);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MmGetPageProtect(IN struct _EPROCESS* Process,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
ExAllocatePageWithPhysPage(IN ULONG_PTR Page);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MmGetReferenceCountPage(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MmIsUsablePage(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmReleasePageOp(IN PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
|
PMM_PAGEOP
|
||||||
|
MmGetPageOp(IN PMEMORY_AREA MArea,
|
||||||
|
IN ULONG Pid,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN PMM_SECTION_SEGMENT Segment,
|
||||||
|
IN ULONG Offset,
|
||||||
|
IN ULONG OpType);
|
||||||
|
|
||||||
|
PMM_PAGEOP
|
||||||
|
MmGotPageOp(IN PMEMORY_AREA MArea,
|
||||||
|
IN ULONG Pid,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN PMM_SECTION_SEGMENT Segment,
|
||||||
|
IN ULONG Offset);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
|
MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmMarkPageMapped(PVOID PhysicalAddress);
|
MmMarkPageMapped(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmMarkPageUnmapped(PVOID PhysicalAddress);
|
MmMarkPageUnmapped(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmFreeSectionSegments(PFILE_OBJECT FileObject);
|
MmFreeSectionSegments(PFILE_OBJECT FileObject);
|
||||||
|
|
||||||
|
@ -439,14 +822,15 @@ typedef struct _MM_IMAGE_SECTION_OBJECT
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
|
MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress);
|
MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MiZeroPage(ULONG PhysPage);
|
MiZeroPage(IN ULONG_PTR Page);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
|
MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
|
||||||
SWAPENTRY
|
|
||||||
MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
|
|
||||||
|
|
||||||
#define STATUS_MM_RESTART_OPERATION (0xD0000001)
|
#define STATUS_MM_RESTART_OPERATION (0xD0000001)
|
||||||
|
|
||||||
|
@ -463,10 +847,22 @@ MmInitializeMemoryConsumer(ULONG Consumer,
|
||||||
PULONG NrFreed));
|
PULONG NrFreed));
|
||||||
VOID
|
VOID
|
||||||
MmInitializeBalancer(ULONG NrAvailablePages);
|
MmInitializeBalancer(ULONG NrAvailablePages);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmReleasePageMemoryConsumer(ULONG Consumer, PVOID Page);
|
MmReleasePageMemoryConsumer(IN ULONG Consumer,
|
||||||
|
IN ULONG_PTR Page);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPage);
|
MiFreePageMemoryConsumer(IN ULONG Consumer,
|
||||||
|
IN ULONG_PTR Page);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmRequestPageMemoryConsumer(IN ULONG Consumer,
|
||||||
|
IN BOOLEAN CanWait,
|
||||||
|
OUT PULONG_PTR pPage);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSatisfyAllocationRequest();
|
||||||
|
|
||||||
#define MC_CACHE (0)
|
#define MC_CACHE (0)
|
||||||
#define MC_USER (1)
|
#define MC_USER (1)
|
||||||
|
@ -475,39 +871,109 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
|
||||||
#define MC_MAXIMUM (4)
|
#define MC_MAXIMUM (4)
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmSetRmapListHeadPage(PVOID PhysicalAddress, struct _MM_RMAP_ENTRY* ListHead);
|
MiTransitionAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN BOOLEAN Reference,
|
||||||
|
OUT PBOOLEAN Modified);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MiAbortTransition(IN ULONG_PTR Address);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MiFinishTransition(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN BOOLEAN Dirty);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmSetRmapListHeadPage(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN struct _MM_RMAP_ENTRY* ListHead);
|
||||||
|
|
||||||
struct _MM_RMAP_ENTRY*
|
struct _MM_RMAP_ENTRY*
|
||||||
MmGetRmapListHeadPage(PVOID PhysicalAddress);
|
MmGetRmapListHeadPage(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmInsertRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address);
|
MmSetRmapCallback(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN PRMAP_DELETE_CALLBACK RmapDelete,
|
||||||
|
IN PVOID RmapDeleteContext);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeleteAllRmaps(PVOID PhysicalAddress, PVOID Context,
|
MmGetRmapCallback(IN ULONG_PTR PhysicalAddress,
|
||||||
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, PVOID Address));
|
IN PRMAP_DELETE_CALLBACK *RmapDelete,
|
||||||
|
IN PVOID *RmapDeleteContext);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmPageOutPhysicalAddress(ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeleteRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address);
|
MmInsertRmap(ULONG_PTR PhysicalAddress, PEPROCESS Process, PVOID Address);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmDeleteAllRmaps(ULONG_PTR PhysicalAddress, PVOID Context,
|
||||||
|
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
|
||||||
|
PVOID Address));
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmDeleteRmap(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN PEPROCESS Process,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmInitializeRmapList(VOID);
|
MmInitializeRmapList(VOID);
|
||||||
PVOID
|
|
||||||
MmGetLRUNextUserPage(PVOID PreviousPhysicalAddress);
|
ULONG_PTR
|
||||||
PVOID
|
MmGetLRUNextUserPage(IN ULONG_PTR PreviousPhysicalAddress);
|
||||||
|
|
||||||
|
ULONG_PTR
|
||||||
MmGetLRUFirstUserPage(VOID);
|
MmGetLRUFirstUserPage(VOID);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmPageOutPhysicalAddress(PVOID PhysicalAddress);
|
MmPrepareFlushPhysicalAddress(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmFlushPhysicalAddress(IN ULONG_PTR PhysicalAddress);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages);
|
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG* PhysicalAddr);
|
MmDisableVirtualMapping(IN PEPROCESS Process,
|
||||||
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address);
|
IN PVOID Address,
|
||||||
|
OUT PBOOLEAN WasDirty,
|
||||||
|
OUT PULONG_PTR PhysicalAddr);
|
||||||
|
|
||||||
|
VOID MmEnableVirtualMapping(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry);
|
MmDeletePageFileMapping(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address,
|
||||||
|
OUT PSWAPENTRY SwapEntry);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmCreatePageFileMapping(PEPROCESS Process,
|
MmCreatePageFileMapping(IN PEPROCESS Process,
|
||||||
PVOID Address,
|
IN PVOID Address,
|
||||||
SWAPENTRY SwapEntry);
|
IN SWAPENTRY SwapEntry);
|
||||||
BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address);
|
|
||||||
|
BOOLEAN
|
||||||
|
MmIsPageSwapEntry(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmTransferOwnershipPage(PVOID PhysicalAddress, ULONG NewConsumer);
|
MmTransferOwnershipPage(IN ULONG_PTR PhysicalAddress,
|
||||||
VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address);
|
IN ULONG NewConsumer);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmSetDirtyPage(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
MEMORY_AREA* MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,10 +7,17 @@
|
||||||
|
|
||||||
#ifndef __ASM__
|
#ifndef __ASM__
|
||||||
|
|
||||||
|
#include <roscfg.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
#define SET_MAGIC(x, magic)(x)->Magic = (magic);
|
||||||
|
#else /* !DBG */
|
||||||
|
#define SET_MAGIC(x, magic)
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use these to place a function in a specific section of the executable
|
* Use these to place a function in a specific section of the executable
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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: ps.h,v 1.31 2002/02/15 14:44:13 ekohl Exp $
|
/* $Id: ps.h,v 1.32 2002/05/13 18:10:39 chorns Exp $
|
||||||
*
|
*
|
||||||
* FILE: ntoskrnl/ke/kthread.c
|
* FILE: ntoskrnl/ke/kthread.c
|
||||||
* PURPOSE: Process manager definitions
|
* PURPOSE: Process manager definitions
|
||||||
|
@ -585,6 +585,10 @@ PiTimeoutThread(struct _KDPC *dpc,
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
PsDispatchThread(ULONG NewThreadStatus);
|
PsDispatchThread(ULONG NewThreadStatus);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PiSetPriorityThread(IN HANDLE ThreadHandle,
|
||||||
|
IN KPRIORITY Priority);
|
||||||
|
|
||||||
#endif /* ASSEMBLER */
|
#endif /* ASSEMBLER */
|
||||||
|
|
||||||
#endif /* __INCLUDE_INTERNAL_PS_H */
|
#endif /* __INCLUDE_INTERNAL_PS_H */
|
||||||
|
|
|
@ -87,6 +87,7 @@
|
||||||
#include <internal/kd.h>
|
#include <internal/kd.h>
|
||||||
#include <internal/ke.h>
|
#include <internal/ke.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
|
#include <internal/module.h>
|
||||||
#include <internal/ldr.h>
|
#include <internal/ldr.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
@ -100,8 +101,10 @@ extern LIST_ENTRY PiThreadListHead;
|
||||||
/* at least NUMREGBYTES*2 are needed for register packets */
|
/* at least NUMREGBYTES*2 are needed for register packets */
|
||||||
#define BUFMAX 1000
|
#define BUFMAX 1000
|
||||||
|
|
||||||
static BOOLEAN GspInitialized; /* boolean flag. TRUE means we've been initialized */
|
static BOOLEAN GspInitialized;
|
||||||
|
#if 0
|
||||||
static PKINTERRUPT GspInterrupt;
|
static PKINTERRUPT GspInterrupt;
|
||||||
|
#endif
|
||||||
|
|
||||||
static BOOLEAN GspRemoteDebug;
|
static BOOLEAN GspRemoteDebug;
|
||||||
|
|
||||||
|
@ -1237,10 +1240,12 @@ extern ULONG KdpPortIrq;
|
||||||
VOID
|
VOID
|
||||||
KdGdbStubInit(ULONG Phase)
|
KdGdbStubInit(ULONG Phase)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
KAFFINITY Affinity;
|
KAFFINITY Affinity;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG MappedIrq;
|
ULONG MappedIrq;
|
||||||
KIRQL Dirql;
|
KIRQL Dirql;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (Phase == 0)
|
if (Phase == 0)
|
||||||
{
|
{
|
||||||
|
@ -1250,9 +1255,12 @@ KdGdbStubInit(ULONG Phase)
|
||||||
GspRunThread = PsGetCurrentThread();
|
GspRunThread = PsGetCurrentThread();
|
||||||
GspDbgThread = PsGetCurrentThread();
|
GspDbgThread = PsGetCurrentThread();
|
||||||
GspEnumThread = NULL;
|
GspEnumThread = NULL;
|
||||||
|
|
||||||
|
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
|
||||||
}
|
}
|
||||||
else if (Phase == 1)
|
else if (Phase == 1)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
/* Hook an interrupt handler to allow the debugger to break into
|
/* Hook an interrupt handler to allow the debugger to break into
|
||||||
the system */
|
the system */
|
||||||
MappedIrq = HalGetInterruptVector (Internal,
|
MappedIrq = HalGetInterruptVector (Internal,
|
||||||
|
@ -1283,30 +1291,58 @@ KdGdbStubInit(ULONG Phase)
|
||||||
KdPortEnableInterrupts();
|
KdPortEnableInterrupts();
|
||||||
|
|
||||||
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
|
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function will generate a breakpoint exception. It is used at the
|
|
||||||
beginning of a program to sync up with a debugger and can be used
|
|
||||||
otherwise as a quick means to stop program execution and "break" into
|
|
||||||
the debugger. */
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdGdbDebugPrint (LPSTR Message)
|
KdGdbDebugPrint(LPSTR Message)
|
||||||
{
|
{
|
||||||
/* This can be quite annoying! */
|
|
||||||
#if 0
|
#if 0
|
||||||
|
/* This can be quite annoying! */
|
||||||
if (GspInitialized)
|
if (GspInitialized)
|
||||||
{
|
{
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
|
||||||
GspOutBuffer[0] = 'O';
|
GspOutBuffer[0] = 'O';
|
||||||
GspOutBuffer[1] = '\0';
|
GspOutBuffer[1] = '\0';
|
||||||
strcat (&GspOutBuffer[0], Message);
|
strcat (&GspOutBuffer[0], Message);
|
||||||
Length = strlen (Message);
|
Length = strlen (Message);
|
||||||
GspOutBuffer[2 + Length] = '\n';
|
GspOutBuffer[2 + Length] = '\n';
|
||||||
GspOutBuffer[3 + Length] = '\0';
|
GspOutBuffer[3 + Length] = '\0';
|
||||||
GspPutPacketNoWait (&GspOutBuffer[0]);
|
GspPutPacketNoWait (&GspOutBuffer[0]);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
HalDisplayString(Message);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern LIST_ENTRY ModuleListHead;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KdGdbListModules()
|
||||||
|
{
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PMODULE_OBJECT Current;
|
||||||
|
ULONG ModuleCount;
|
||||||
|
|
||||||
|
DPRINT1("\n");
|
||||||
|
|
||||||
|
ModuleCount = 0;
|
||||||
|
|
||||||
|
CurrentEntry = ModuleListHead.Flink;
|
||||||
|
while (CurrentEntry != (&ModuleListHead))
|
||||||
|
{
|
||||||
|
Current = CONTAINING_RECORD (CurrentEntry, MODULE_OBJECT, ListEntry);
|
||||||
|
|
||||||
|
DbgPrint ("Module %S Base 0x%.08x Length 0x%.08x\n",
|
||||||
|
Current->BaseName.Buffer, Current->Base, Current->Length);
|
||||||
|
|
||||||
|
ModuleCount++;
|
||||||
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbgPrint ("%d modules listed\n", ModuleCount);
|
||||||
|
}
|
||||||
|
|
|
@ -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: bug.c,v 1.21 2002/05/02 23:45:32 dwelch Exp $
|
/* $Id: bug.c,v 1.22 2002/05/13 18:10:39 chorns Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/bug.c
|
* FILE: ntoskrnl/ke/bug.c
|
||||||
|
@ -103,9 +103,10 @@ KeBugCheckEx(ULONG BugCheckCode,
|
||||||
{
|
{
|
||||||
PRTL_MESSAGE_RESOURCE_ENTRY Message;
|
PRTL_MESSAGE_RESOURCE_ENTRY Message;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||||||
|
|
||||||
/* PJS: disable interrupts first, then do the rest */
|
|
||||||
__asm__("cli\n\t");
|
|
||||||
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
|
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
|
||||||
BugCheckCode,
|
BugCheckCode,
|
||||||
BugCheckParameter1,
|
BugCheckParameter1,
|
||||||
|
@ -133,12 +134,19 @@ KeBugCheckEx(ULONG BugCheckCode,
|
||||||
if (InBugCheck == 1)
|
if (InBugCheck == 1)
|
||||||
{
|
{
|
||||||
DbgPrint("Recursive bug check halting now\n");
|
DbgPrint("Recursive bug check halting now\n");
|
||||||
|
|
||||||
|
if (KdDebuggerEnabled)
|
||||||
|
{
|
||||||
|
DbgBreakPoint();
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
__asm__("hlt\n\t");
|
__asm__("hlt\n\t");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InBugCheck = 1;
|
InBugCheck = 1;
|
||||||
|
|
||||||
if (PsGetCurrentProcess() != NULL)
|
if (PsGetCurrentProcess() != NULL)
|
||||||
{
|
{
|
||||||
DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
|
DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
|
||||||
|
@ -150,12 +158,10 @@ KeBugCheckEx(ULONG BugCheckCode,
|
||||||
PsGetCurrentThread(),
|
PsGetCurrentThread(),
|
||||||
PsGetCurrentThread()->Cid.UniqueThread);
|
PsGetCurrentThread()->Cid.UniqueThread);
|
||||||
}
|
}
|
||||||
// PsDumpThreads();
|
|
||||||
KeDumpStackFrames((PULONG)__builtin_frame_address(0));
|
KeDumpStackFrames((PULONG)__builtin_frame_address(0));
|
||||||
|
|
||||||
if (KdDebuggerEnabled)
|
if (KdDebuggerEnabled)
|
||||||
{
|
{
|
||||||
__asm__("sti\n\t");
|
|
||||||
DbgBreakPoint();
|
DbgBreakPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -544,6 +544,10 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
*/
|
*/
|
||||||
if (ExceptionNr == 14)
|
if (ExceptionNr == 14)
|
||||||
{
|
{
|
||||||
|
#ifdef DBG
|
||||||
|
KIRQL SavedIrql = KeGetCurrentIrql();
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
__asm__("sti\n\t");
|
__asm__("sti\n\t");
|
||||||
Status = MmPageFault(Tf->Cs&0xffff,
|
Status = MmPageFault(Tf->Cs&0xffff,
|
||||||
&Tf->Eip,
|
&Tf->Eip,
|
||||||
|
@ -552,6 +556,9 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
Tf->ErrorCode);
|
Tf->ErrorCode);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
assertmsg((KeGetCurrentIrql() == SavedIrql),
|
||||||
|
("Page fault handler changed IRQL (Before %d After %d). Forgot to release a spin lock?\n",
|
||||||
|
SavedIrql, KeGetCurrentIrql()));
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
ULONG KiPcrInitDone = 0;
|
ULONG KiPcrInitDone = 0;
|
||||||
static ULONG PcrsAllocated = 0;
|
static ULONG PcrsAllocated = 0;
|
||||||
static PVOID PcrPages[MAXIMUM_PROCESSORS];
|
static ULONG_PTR PcrPages[MAXIMUM_PROCESSORS];
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ KeApplicationProcessorInit(VOID)
|
||||||
KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGESIZE));
|
KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGESIZE));
|
||||||
MmCreateVirtualMappingForKernel((PVOID)KPCR,
|
MmCreateVirtualMappingForKernel((PVOID)KPCR,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)PcrPages[Offset]);
|
PcrPages[Offset]);
|
||||||
memset(KPCR, 0, PAGESIZE);
|
memset(KPCR, 0, PAGESIZE);
|
||||||
KPCR->ProcessorNumber = Offset;
|
KPCR->ProcessorNumber = Offset;
|
||||||
KPCR->Self = KPCR;
|
KPCR->Self = KPCR;
|
||||||
|
|
|
@ -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: kthread.c,v 1.23 2002/05/07 22:34:17 hbirr Exp $
|
/* $Id: kthread.c,v 1.24 2002/05/13 18:10:39 chorns Exp $
|
||||||
*
|
*
|
||||||
* FILE: ntoskrnl/ke/kthread.c
|
* FILE: ntoskrnl/ke/kthread.c
|
||||||
* PURPOSE: Microkernel thread support
|
* PURPOSE: Microkernel thread support
|
||||||
|
@ -44,13 +44,21 @@
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
KeFreeStackPage(IN BOOLEAN Before,
|
||||||
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
IN PVOID Context,
|
||||||
|
IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN SWAPENTRY SwapEntry,
|
||||||
|
IN BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
if (!Before)
|
||||||
if (PhysAddr != 0)
|
|
||||||
{
|
{
|
||||||
MmDereferencePage((PVOID)PhysAddr);
|
assert(SwapEntry == 0);
|
||||||
|
if (PhysicalAddress != 0)
|
||||||
|
{
|
||||||
|
MmDereferencePage(PhysicalAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +117,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
MEMORY_AREA_KERNEL_STACK,
|
MEMORY_AREA_KERNEL_STACK,
|
||||||
&KernelStack,
|
&KernelStack,
|
||||||
MM_STACK_SIZE,
|
MM_STACK_SIZE,
|
||||||
0,
|
PAGE_EXECUTE_READWRITE,
|
||||||
&StackArea,
|
&StackArea,
|
||||||
FALSE);
|
FALSE);
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||||
|
@ -121,7 +129,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
}
|
}
|
||||||
for (i = 0; i < (MM_STACK_SIZE / PAGESIZE); i++)
|
for (i = 0; i < (MM_STACK_SIZE / PAGESIZE); i++)
|
||||||
{
|
{
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -129,8 +137,8 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
}
|
}
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
KernelStack + (i * PAGESIZE),
|
KernelStack + (i * PAGESIZE),
|
||||||
PAGE_EXECUTE_READWRITE,
|
StackArea->Attributes,
|
||||||
(ULONG)Page,
|
Page,
|
||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
Thread->InitialStack = KernelStack + MM_STACK_SIZE;
|
Thread->InitialStack = KernelStack + MM_STACK_SIZE;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: timer.c,v 1.48 2002/04/26 13:11:28 ekohl Exp $
|
/* $Id: timer.c,v 1.49 2002/05/13 18:10:39 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -138,7 +138,7 @@ KeDelayExecutionThread (KPROCESSOR_MODE WaitMode,
|
||||||
KeSetTimer(&Thread->Timer, *Interval, NULL);
|
KeSetTimer(&Thread->Timer, *Interval, NULL);
|
||||||
return (KeWaitForSingleObject(&Thread->Timer,
|
return (KeWaitForSingleObject(&Thread->Timer,
|
||||||
Executive,
|
Executive,
|
||||||
UserMode,
|
WaitMode,
|
||||||
Alertable,
|
Alertable,
|
||||||
NULL));
|
NULL));
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,127 @@ static PKTHREAD Owner = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KiValidateDispatcherObject(IN PDISPATCHER_HEADER Object)
|
||||||
|
{
|
||||||
|
if ((Object->Type < InternalBaseType)
|
||||||
|
|| (Object->Type > InternalTypeMaximum))
|
||||||
|
{
|
||||||
|
assertmsg(FALSE, ("Bad dispatcher object type %d\n", Object->Type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PKTHREAD
|
||||||
|
KiGetDispatcherObjectOwner(IN PDISPATCHER_HEADER Header)
|
||||||
|
{
|
||||||
|
switch (Header->Type)
|
||||||
|
{
|
||||||
|
case InternalMutexType:
|
||||||
|
{
|
||||||
|
PKMUTEX Mutex = (PKMUTEX)Header;
|
||||||
|
return Mutex->OwnerThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* No owner */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID KiDeadlockDetectionMutualResource(IN PDISPATCHER_HEADER CurrentObject,
|
||||||
|
IN PKTHREAD CurrentThread,
|
||||||
|
IN PKTHREAD OwnerThread)
|
||||||
|
/*
|
||||||
|
* PURPOSE: Perform deadlock detection.
|
||||||
|
* At this point, OwnerThread owns CurrentObject and CurrentThread
|
||||||
|
* is waiting on CurrentObject
|
||||||
|
* Deadlock happens if OwnerThread is waiting on a resource that
|
||||||
|
* InitialThread owns.
|
||||||
|
* NOTE: Called with the dispatcher database locked
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDISPATCHER_HEADER Object;
|
||||||
|
PKWAIT_BLOCK WaitBlock;
|
||||||
|
PKTHREAD Thread;
|
||||||
|
|
||||||
|
DPRINT("KiDeadlockDetectionMutualResource("
|
||||||
|
"CurrentObject 0x%.08x, CurrentThread 0x%.08x OwnerThread 0x%.08x)\n",
|
||||||
|
CurrentObject, CurrentThread, OwnerThread);
|
||||||
|
|
||||||
|
/* Go through all dispather objects that OwnerThread is waiting on */
|
||||||
|
for (WaitBlock = OwnerThread->WaitBlockList;
|
||||||
|
WaitBlock;
|
||||||
|
WaitBlock = WaitBlock->NextWaitBlock)
|
||||||
|
{
|
||||||
|
Object = WaitBlock->Object;
|
||||||
|
|
||||||
|
/* If OwnerThread is waiting on a resource that CurrentThread has
|
||||||
|
* acquired then we have a deadlock */
|
||||||
|
Thread = KiGetDispatcherObjectOwner(Object);
|
||||||
|
if ((Thread != NULL) && (Thread == CurrentThread))
|
||||||
|
{
|
||||||
|
DbgPrint("Deadlock detected!\n");
|
||||||
|
DbgPrint("Thread 0x%.08x is waiting on Object 0x%.08x of type %d "
|
||||||
|
" which is owned by Thread 0x%.08x\n",
|
||||||
|
Thread, CurrentObject, CurrentObject->Type, OwnerThread);
|
||||||
|
DbgPrint("Thread 0x%.08x is waiting on Object 0x%.08x of type %d "
|
||||||
|
" which is owned by Thread 0x%.08x\n",
|
||||||
|
OwnerThread, Object, Object->Type, Thread);
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID KiDeadlockDetection(IN PDISPATCHER_HEADER Header)
|
||||||
|
/*
|
||||||
|
* PURPOSE: Perform deadlock detection
|
||||||
|
* NOTE: Called with the dispatcher database locked
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PKWAIT_BLOCK WaitBlock;
|
||||||
|
PKWAIT_BLOCK Current;
|
||||||
|
PKTHREAD OwnerThread;
|
||||||
|
PKTHREAD Thread;
|
||||||
|
|
||||||
|
DPRINT("KiDeadlockDetection(Header %x)\n", Header);
|
||||||
|
if (IsListEmpty(&(Header->WaitListHead)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CurrentEntry = Header->WaitListHead.Flink;
|
||||||
|
Current = CONTAINING_RECORD(CurrentEntry, KWAIT_BLOCK, WaitListEntry);
|
||||||
|
|
||||||
|
/* Go through all threads waiting on this dispatcher object */
|
||||||
|
for (WaitBlock = Current->Thread->WaitBlockList;
|
||||||
|
WaitBlock;
|
||||||
|
WaitBlock = WaitBlock->NextWaitBlock)
|
||||||
|
{
|
||||||
|
Thread = WaitBlock->Thread;
|
||||||
|
|
||||||
|
DPRINT("KiDeadlockDetection: WaitBlock->Thread %x waiting on WaitBlock->Object %x\n",
|
||||||
|
WaitBlock->Thread, WaitBlock->Object);
|
||||||
|
|
||||||
|
/* If another thread is currently owning this dispatcher object,
|
||||||
|
see if we have a deadlock */
|
||||||
|
OwnerThread = KiGetDispatcherObjectOwner(Current->Object);
|
||||||
|
DPRINT("KiDeadlockDetection: OwnerThread %x\n", OwnerThread);
|
||||||
|
if ((OwnerThread != NULL) && (OwnerThread != Thread))
|
||||||
|
{
|
||||||
|
KiDeadlockDetectionMutualResource(Current->Object,
|
||||||
|
Current->Thread,
|
||||||
|
OwnerThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
|
||||||
VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
|
VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
|
||||||
ULONG Type,
|
ULONG Type,
|
||||||
ULONG Size,
|
ULONG Size,
|
||||||
|
@ -136,6 +257,7 @@ static VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr,
|
||||||
DPRINT1("Thread == NULL!\n");
|
DPRINT1("Thread == NULL!\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Abandoned != NULL)
|
if (Abandoned != NULL)
|
||||||
*Abandoned = Mutex->Abandoned;
|
*Abandoned = Mutex->Abandoned;
|
||||||
if (Thread != NULL)
|
if (Thread != NULL)
|
||||||
|
@ -433,6 +555,10 @@ KeWaitForSingleObject(PVOID Object,
|
||||||
KIRQL WaitIrql;
|
KIRQL WaitIrql;
|
||||||
BOOLEAN Abandoned;
|
BOOLEAN Abandoned;
|
||||||
|
|
||||||
|
assert_irql(DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
VALIDATE_DISPATCHER_OBJECT(Object);
|
||||||
|
|
||||||
CurrentThread = KeGetCurrentThread();
|
CurrentThread = KeGetCurrentThread();
|
||||||
WaitIrql = KeGetCurrentIrql();
|
WaitIrql = KeGetCurrentIrql();
|
||||||
|
|
||||||
|
@ -489,9 +615,22 @@ KeWaitForSingleObject(PVOID Object,
|
||||||
return(STATUS_TIMEOUT);
|
return(STATUS_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifdef DBG
|
||||||
* Set up for a wait
|
|
||||||
*/
|
if (hdr->Type == InternalMutexType)
|
||||||
|
{
|
||||||
|
PKMUTEX Mutex;
|
||||||
|
|
||||||
|
Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header);
|
||||||
|
assertmsg(Mutex->OwnerThread != CurrentThread,
|
||||||
|
("Recursive locking of mutex (0x%.08x)\n", Mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up for a wait
|
||||||
|
*/
|
||||||
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
|
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
|
||||||
/* Append wait block to the KTHREAD wait block list */
|
/* Append wait block to the KTHREAD wait block list */
|
||||||
CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0];
|
CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0];
|
||||||
|
@ -517,6 +656,16 @@ KeWaitForSingleObject(PVOID Object,
|
||||||
{
|
{
|
||||||
CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
|
CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
/*
|
||||||
|
* Do deadlock detection in checked version
|
||||||
|
* NOTE: This must be done after the the dispatcher object is put on
|
||||||
|
* the wait block list.
|
||||||
|
*/
|
||||||
|
KiDeadlockDetection(Object);
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
PsBlockThread(&Status, (UCHAR)Alertable, WaitMode, TRUE, WaitIrql);
|
PsBlockThread(&Status, (UCHAR)Alertable, WaitMode, TRUE, WaitIrql);
|
||||||
} while (Status == STATUS_KERNEL_APC);
|
} while (Status == STATUS_KERNEL_APC);
|
||||||
|
|
||||||
|
@ -552,6 +701,8 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
|
DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
|
||||||
"PsGetCurrentThread() %x\n",Count,Object,PsGetCurrentThread());
|
"PsGetCurrentThread() %x\n",Count,Object,PsGetCurrentThread());
|
||||||
|
|
||||||
|
assert_irql(APC_LEVEL);
|
||||||
|
|
||||||
CountSignaled = 0;
|
CountSignaled = 0;
|
||||||
CurrentThread = KeGetCurrentThread();
|
CurrentThread = KeGetCurrentThread();
|
||||||
WaitIrql = KeGetCurrentIrql();
|
WaitIrql = KeGetCurrentIrql();
|
||||||
|
@ -610,6 +761,8 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
{
|
{
|
||||||
hdr = (DISPATCHER_HEADER *)Object[i];
|
hdr = (DISPATCHER_HEADER *)Object[i];
|
||||||
|
|
||||||
|
VALIDATE_DISPATCHER_OBJECT(hdr);
|
||||||
|
|
||||||
if (KiIsObjectSignalled(hdr, CurrentThread, &Abandoned))
|
if (KiIsObjectSignalled(hdr, CurrentThread, &Abandoned))
|
||||||
{
|
{
|
||||||
CountSignaled++;
|
CountSignaled++;
|
||||||
|
@ -655,7 +808,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
for (i = 0; i < Count; i++)
|
for (i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
hdr = (DISPATCHER_HEADER *)Object[i];
|
hdr = (DISPATCHER_HEADER *)Object[i];
|
||||||
|
assertmsg(hdr != NULL, ("Waiting on uninitialized object\n"));
|
||||||
blk->Object = Object[i];
|
blk->Object = Object[i];
|
||||||
blk->Thread = CurrentThread;
|
blk->Thread = CurrentThread;
|
||||||
blk->WaitKey = STATUS_WAIT_0 + i;
|
blk->WaitKey = STATUS_WAIT_0 + i;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: aspace.c,v 1.8 2001/12/31 01:53:45 dwelch Exp $
|
/* $Id: aspace.c,v 1.9 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <roscfg.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <internal/mm.h>
|
#include <internal/mm.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
|
@ -18,33 +19,115 @@
|
||||||
|
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* Define to track address space locking/unlocking */
|
||||||
|
//#define TRACK_ADDRESS_SPACE_LOCK
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
STATIC MADDRESS_SPACE KernelAddressSpace;
|
STATIC MADDRESS_SPACE KernelAddressSpace;
|
||||||
|
|
||||||
|
#define TAG_ASPC TAG('A', 'S', 'P', 'C')
|
||||||
#define TAG_PTRC TAG('P', 'T', 'R', 'C')
|
#define TAG_PTRC TAG('P', 'T', 'R', 'C')
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
VOID
|
VOID
|
||||||
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace)
|
MiValidateAddressSpace(IN PMADDRESS_SPACE AddressSpace)
|
||||||
{
|
{
|
||||||
|
assertmsg(AddressSpace != NULL,
|
||||||
|
("No address space can exist at 0x%.08x\n", AddressSpace));
|
||||||
|
|
||||||
|
assertmsg(AddressSpace->Magic == TAG_ASPC,
|
||||||
|
("Bad magic (0x%.08x) for address space (0x%.08x). It should be 0x%.08x\n",
|
||||||
|
AddressSpace->Magic, AddressSpace, TAG_ASPC));
|
||||||
|
|
||||||
|
assertmsg(AddressSpace->ReferenceCount > 0,
|
||||||
|
("No outstanding references on address space (0x%.08x)\n", AddressSpace));
|
||||||
|
}
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiLockAddressSpace(IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN LPSTR FileName,
|
||||||
|
IN ULONG LineNumber)
|
||||||
|
{
|
||||||
|
VALIDATE_ADDRESS_SPACE(AddressSpace);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't bother with locking if we are the first thread.
|
||||||
|
*/
|
||||||
|
if (KeGetCurrentThread() == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TRACK_ADDRESS_SPACE_LOCK
|
||||||
|
DbgPrint("(0x%.08x)(%s:%d) Locking address space 0x%.08x\n",
|
||||||
|
KeGetCurrentThread(), FileName, LineNumber, AddressSpace);
|
||||||
|
#endif /* TRACK_ADDRESS_SPACE_LOCK */
|
||||||
|
|
||||||
|
(VOID)KeWaitForMutexObject(&AddressSpace->Lock,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
#ifdef TRACK_ADDRESS_SPACE_LOCK
|
||||||
|
DbgPrint("(0x%.08x)(%s:%d) Locked address space 0x%.08x\n",
|
||||||
|
KeGetCurrentThread(), FileName, LineNumber, AddressSpace);
|
||||||
|
#endif /* TRACK_ADDRESS_SPACE_LOCK */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiUnlockAddressSpace(IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN LPSTR FileName,
|
||||||
|
IN ULONG LineNumber)
|
||||||
|
{
|
||||||
|
VALIDATE_ADDRESS_SPACE(AddressSpace);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't bother with locking if we are the first thread.
|
* Don't bother locking if we are the first thread.
|
||||||
*/
|
*/
|
||||||
if (KeGetCurrentThread() == NULL)
|
if (KeGetCurrentThread() == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(VOID)KeWaitForMutexObject(&AddressSpace->Lock,
|
KeReleaseMutex(&AddressSpace->Lock, FALSE);
|
||||||
0,
|
|
||||||
KernelMode,
|
#ifdef TRACK_ADDRESS_SPACE_LOCK
|
||||||
FALSE,
|
DbgPrint("(0x%.08x)(%s:%d) Unlocked address space 0x%.08x\n",
|
||||||
NULL);
|
KeGetCurrentThread(), FileName, LineNumber, AddressSpace);
|
||||||
|
#endif /* TRACK_ADDRESS_SPACE_LOCK */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* !DBG */
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace)
|
MiLockAddressSpace(IN PMADDRESS_SPACE AddressSpace)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Don't bother with locking if we are the first thread.
|
||||||
|
*/
|
||||||
|
if (KeGetCurrentThread() == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(VOID)KeWaitForMutexObject(&AddressSpace->Lock,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiUnlockAddressSpace(IN PMADDRESS_SPACE AddressSpace)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Don't bother locking if we are the first thread.
|
* Don't bother locking if we are the first thread.
|
||||||
|
@ -56,26 +139,37 @@ MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace)
|
||||||
KeReleaseMutex(&AddressSpace->Lock, FALSE);
|
KeReleaseMutex(&AddressSpace->Lock, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !DBG */
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmInitializeKernelAddressSpace(VOID)
|
MmInitializeKernelAddressSpace()
|
||||||
{
|
{
|
||||||
MmInitializeAddressSpace(NULL, &KernelAddressSpace);
|
MmInitializeAddressSpace(NULL, &KernelAddressSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID)
|
|
||||||
|
PMADDRESS_SPACE
|
||||||
|
MmGetCurrentAddressSpace()
|
||||||
{
|
{
|
||||||
return(&PsGetCurrentProcess()->AddressSpace);
|
return(&PsGetCurrentProcess()->AddressSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
PMADDRESS_SPACE MmGetKernelAddressSpace(VOID)
|
|
||||||
|
PMADDRESS_SPACE
|
||||||
|
MmGetKernelAddressSpace()
|
||||||
{
|
{
|
||||||
return(&KernelAddressSpace);
|
return(&KernelAddressSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmInitializeAddressSpace(PEPROCESS Process,
|
MmInitializeAddressSpace(IN PEPROCESS Process,
|
||||||
PMADDRESS_SPACE AddressSpace)
|
IN PMADDRESS_SPACE AddressSpace)
|
||||||
{
|
{
|
||||||
|
SET_MAGIC(AddressSpace, TAG_ASPC)
|
||||||
|
|
||||||
|
AddressSpace->ReferenceCount = 1;
|
||||||
InitializeListHead(&AddressSpace->MAreaListHead);
|
InitializeListHead(&AddressSpace->MAreaListHead);
|
||||||
KeInitializeMutex(&AddressSpace->Lock, 1);
|
KeInitializeMutex(&AddressSpace->Lock, 1);
|
||||||
if (Process != NULL)
|
if (Process != NULL)
|
||||||
|
@ -102,12 +196,38 @@ MmInitializeAddressSpace(PEPROCESS Process,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace)
|
MmDestroyAddressSpace(IN PMADDRESS_SPACE AddressSpace)
|
||||||
{
|
{
|
||||||
|
VALIDATE_ADDRESS_SPACE(AddressSpace);
|
||||||
|
|
||||||
|
AddressSpace->ReferenceCount--;
|
||||||
|
|
||||||
|
assertmsg(AddressSpace->ReferenceCount == 0,
|
||||||
|
("There are %d outstanding references on address space (0x%.08x)\n",
|
||||||
|
AddressSpace->ReferenceCount, AddressSpace));
|
||||||
|
|
||||||
if (AddressSpace->PageTableRefCountTable != NULL)
|
if (AddressSpace->PageTableRefCountTable != NULL)
|
||||||
{
|
{
|
||||||
ExFreePool(AddressSpace->PageTableRefCountTable);
|
ExFreePool(AddressSpace->PageTableRefCountTable);
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmReferenceAddressSpace(IN PMADDRESS_SPACE AddressSpace)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&AddressSpace->ReferenceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmDereferenceAddressSpace(IN PMADDRESS_SPACE AddressSpace)
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&AddressSpace->ReferenceCount);
|
||||||
|
|
||||||
|
assertmsg(AddressSpace->ReferenceCount > 0,
|
||||||
|
("No outstanding references on address space (0x%.08x)\n", AddressSpace));
|
||||||
|
}
|
||||||
|
|
|
@ -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: balance.c,v 1.6 2002/02/28 17:44:48 hbirr Exp $
|
/* $Id: balance.c,v 1.7 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -47,7 +47,7 @@ typedef struct _MM_MEMORY_CONSUMER
|
||||||
|
|
||||||
typedef struct _MM_ALLOCATION_REQUEST
|
typedef struct _MM_ALLOCATION_REQUEST
|
||||||
{
|
{
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
} MM_ALLOCATION_REQUEST, *PMM_ALLOCATION_REQUEST;
|
} MM_ALLOCATION_REQUEST, *PMM_ALLOCATION_REQUEST;
|
||||||
|
@ -93,13 +93,13 @@ MmInitializeMemoryConsumer(ULONG Consumer,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmReleasePageMemoryConsumer(ULONG Consumer, PVOID Page)
|
MmReleasePageMemoryConsumer(ULONG Consumer, ULONG_PTR Page)
|
||||||
{
|
{
|
||||||
PMM_ALLOCATION_REQUEST Request;
|
PMM_ALLOCATION_REQUEST Request;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
if (Page == NULL)
|
if (Page == 0)
|
||||||
{
|
{
|
||||||
DPRINT1("Tried to release page zero.\n");
|
DPRINT1("Tried to release page zero.\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
|
@ -173,11 +173,11 @@ MiRebalanceMemoryConsumers(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPage)
|
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PULONG_PTR AllocatedPage)
|
||||||
{
|
{
|
||||||
ULONG OldUsed;
|
ULONG OldUsed;
|
||||||
ULONG OldAvailable;
|
ULONG OldAvailable;
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -211,7 +211,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert an allocation request. */
|
/* Insert an allocation request. */
|
||||||
Request.Page = NULL;
|
Request.Page = 0;
|
||||||
KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
|
||||||
InterlockedIncrement(&MiPagesRequired);
|
InterlockedIncrement(&MiPagesRequired);
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
|
||||||
{
|
{
|
||||||
Page = MmAllocPage(Consumer, 0);
|
Page = MmAllocPage(Consumer, 0);
|
||||||
KeReleaseSpinLock(&AllocationListLock, oldIrql);
|
KeReleaseSpinLock(&AllocationListLock, oldIrql);
|
||||||
if (Page == NULL)
|
if (Page == 0)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
Page = Request.Page;
|
Page = Request.Page;
|
||||||
if (Page == NULL)
|
if (Page == 0)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
|
||||||
* Actually allocate the page.
|
* Actually allocate the page.
|
||||||
*/
|
*/
|
||||||
Page = MmAllocPage(Consumer, 0);
|
Page = MmAllocPage(Consumer, 0);
|
||||||
if (Page == NULL)
|
if (Page == 0)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: cont.c,v 1.17 2002/01/01 00:21:55 dwelch Exp $
|
/* $Id: cont.c,v 1.18 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -19,14 +19,22 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID STATIC
|
VOID
|
||||||
MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
MmFreeContinuousPage(IN BOOLEAN Before,
|
||||||
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
IN PVOID Context,
|
||||||
|
IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN SWAPENTRY SwapEntry,
|
||||||
|
IN BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
if (!Before)
|
||||||
if (PhysAddr != 0)
|
|
||||||
{
|
{
|
||||||
MmDereferencePage((PVOID)PhysAddr);
|
assert(SwapEntry == 0);
|
||||||
|
if (PhysicalAddress != 0)
|
||||||
|
{
|
||||||
|
MmDereferencePage(PhysicalAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,13 +51,13 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
|
||||||
|
|
||||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||||
Status = MmCreateMemoryArea(NULL,
|
Status = MmCreateMemoryArea(NULL,
|
||||||
MmGetKernelAddressSpace(),
|
MmGetKernelAddressSpace(),
|
||||||
MEMORY_AREA_CONTINUOUS_MEMORY,
|
MEMORY_AREA_CONTINUOUS_MEMORY,
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
NumberOfBytes,
|
NumberOfBytes,
|
||||||
0,
|
0,
|
||||||
&MArea,
|
&MArea,
|
||||||
FALSE);
|
FALSE);
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -141,11 +149,11 @@ MmAllocateContiguousMemory (IN ULONG NumberOfBytes,
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
MmFreeContiguousMemory(IN PVOID BaseAddress)
|
MmFreeContiguousMemory(IN PVOID BaseAddress)
|
||||||
{
|
{
|
||||||
MmFreeMemoryArea(MmGetKernelAddressSpace(),
|
MmFreeMemoryArea(MmGetKernelAddressSpace(),
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
0,
|
0,
|
||||||
MmFreeContinuousPage,
|
MmFreeContinuousPage,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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.34 2002/01/08 00:49:01 dwelch Exp $
|
/* $Id: page.c,v 1.35 2002/05/13 18:10:41 chorns Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/i386/page.c
|
* FILE: ntoskrnl/mm/i386/page.c
|
||||||
|
@ -39,30 +39,141 @@
|
||||||
|
|
||||||
/* GLOBALS *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
#define PA_BIT_PRESENT (0)
|
/* See pagefile.c for the layout of a swap entry PTE */
|
||||||
#define PA_BIT_READWRITE (1)
|
#define PA_BIT_PRESENT (0)
|
||||||
#define PA_BIT_USER (2)
|
#define PA_BIT_READWRITE (1)
|
||||||
#define PA_BIT_WT (3)
|
#define PA_BIT_USER (2)
|
||||||
#define PA_BIT_CD (4)
|
#define PA_BIT_WT (3)
|
||||||
#define PA_BIT_ACCESSED (5)
|
#define PA_BIT_CD (4)
|
||||||
#define PA_BIT_DIRTY (6)
|
#define PA_BIT_ACCESSED (5)
|
||||||
|
#define PA_BIT_DIRTY (6)
|
||||||
|
#define PA_BIT_PROTOTYPE (7)
|
||||||
|
#define PA_BIT_TRANSITION (8)
|
||||||
|
#define PA_BIT_DEMAND_ZERO (9)
|
||||||
|
|
||||||
#define PA_PRESENT (1 << PA_BIT_PRESENT)
|
#define PA_PRESENT (1 << PA_BIT_PRESENT)
|
||||||
#define PA_READWRITE (1 << PA_BIT_READWRITE)
|
#define PA_READWRITE (1 << PA_BIT_READWRITE)
|
||||||
#define PA_USER (1 << PA_BIT_USER)
|
#define PA_USER (1 << PA_BIT_USER)
|
||||||
#define PA_DIRTY (1 << PA_BIT_DIRTY)
|
#define PA_DIRTY (1 << PA_BIT_DIRTY)
|
||||||
#define PA_WT (1 << PA_BIT_WT)
|
#define PA_WT (1 << PA_BIT_WT)
|
||||||
#define PA_CD (1 << PA_BIT_CD)
|
#define PA_CD (1 << PA_BIT_CD)
|
||||||
#define PA_ACCESSED (1 << PA_BIT_ACCESSED)
|
#define PA_ACCESSED (1 << PA_BIT_ACCESSED)
|
||||||
#define PA_DIRTY (1 << PA_BIT_DIRTY)
|
#define PA_DIRTY (1 << PA_BIT_DIRTY)
|
||||||
|
#define PA_PROTOTYPE (1 << PA_BIT_PROTOTYPE)
|
||||||
|
#define PA_TRANSITION (1 << PA_BIT_TRANSITION)
|
||||||
|
#define PA_DEMAND_ZERO (1 << PA_BIT_DEMAND_ZERO)
|
||||||
|
|
||||||
|
#define GET_SWAPENTRY_FROM_PTE(pte)((pte) & 0x1ffffffe) >> 1
|
||||||
|
#define SET_SWAPENTRY_IN_PTE(pte, entry)((pte) = ((entry << 1) & 0x1ffffffe))
|
||||||
|
#define IS_SWAPENTRY_PTE(pte)((!(Pte & PA_PRESENT)) && ((pte) & 0x1ffffffe))
|
||||||
|
|
||||||
#define PAGETABLE_MAP (0xf0000000)
|
#define PAGETABLE_MAP (0xf0000000)
|
||||||
#define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024)))
|
#define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024)))
|
||||||
|
|
||||||
ULONG MmGlobalKernelPageDirectory[1024] = {0, };
|
ULONG MmGlobalKernelPageDirectory[1024] = {0, };
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
PVOID MiBreakPointAddressLow = (PVOID)0x0;
|
||||||
|
PVOID MiBreakPointAddressHigh = (PVOID)0x0;
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiDumpPTE(IN ULONG Value)
|
||||||
|
{
|
||||||
|
if (Value & PA_PRESENT)
|
||||||
|
DbgPrint("Valid\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Invalid\n");
|
||||||
|
|
||||||
|
if (Value & PA_READWRITE)
|
||||||
|
DbgPrint("Read/Write\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Read only\n");
|
||||||
|
|
||||||
|
if (Value & PA_USER)
|
||||||
|
DbgPrint("User access\n");
|
||||||
|
else
|
||||||
|
DbgPrint("System access\n");
|
||||||
|
|
||||||
|
if (Value & PA_WT)
|
||||||
|
DbgPrint("Write through\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Not write through\n");
|
||||||
|
|
||||||
|
if (Value & PA_CD)
|
||||||
|
DbgPrint("No cache\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Cache\n");
|
||||||
|
|
||||||
|
if (Value & PA_ACCESSED)
|
||||||
|
DbgPrint("Accessed\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Not accessed\n");
|
||||||
|
|
||||||
|
if (Value & PA_DIRTY)
|
||||||
|
DbgPrint("Dirty\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Clean\n");
|
||||||
|
|
||||||
|
if (Value & PA_PROTOTYPE)
|
||||||
|
DbgPrint("Prototype\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Not prototype\n");
|
||||||
|
|
||||||
|
if (Value & PA_TRANSITION)
|
||||||
|
DbgPrint("Transition\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Not transition\n");
|
||||||
|
|
||||||
|
if (Value & PA_DEMAND_ZERO)
|
||||||
|
DbgPrint("Demand zero\n");
|
||||||
|
else
|
||||||
|
DbgPrint("Not demand zero\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call from a debugger to have the OS break into the
|
||||||
|
* debugger when a PTE in this range is changed
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
DbgMmSetBreakPointAddressRange(IN PVOID LowAddress,
|
||||||
|
IN PVOID HighAddress)
|
||||||
|
{
|
||||||
|
MiBreakPointAddressLow = LowAddress;
|
||||||
|
MiBreakPointAddressHigh = HighAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Single page version of DbgSetBreakPointAddressRange()
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
DbgMmSetBreakPointAddress(IN PVOID Address)
|
||||||
|
{
|
||||||
|
MiBreakPointAddressLow = Address;
|
||||||
|
MiBreakPointAddressHigh = Address;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidatePhysicalAddress(IN ULONG_PTR PhysicalAddress)
|
||||||
|
{
|
||||||
|
if (!MiInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
assertmsg((PhysicalAddress / PAGESIZE) < MmStats.NrTotalPages,
|
||||||
|
("Bad physical address 0x%.08x\n", PhysicalAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
PULONG
|
PULONG
|
||||||
MmGetPageDirectory(VOID)
|
MmGetPageDirectory(VOID)
|
||||||
{
|
{
|
||||||
|
@ -72,6 +183,7 @@ MmGetPageDirectory(VOID)
|
||||||
return((PULONG)page_dir);
|
return((PULONG)page_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ULONG
|
static ULONG
|
||||||
ProtectToPTE(ULONG flProtect)
|
ProtectToPTE(ULONG flProtect)
|
||||||
{
|
{
|
||||||
|
@ -122,7 +234,7 @@ NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process)
|
||||||
{
|
{
|
||||||
DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process);
|
DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process);
|
||||||
|
|
||||||
MmDereferencePage(Process->Pcb.DirectoryTableBase[0]);
|
MmDereferencePage((ULONG_PTR) Process->Pcb.DirectoryTableBase[0]);
|
||||||
Process->Pcb.DirectoryTableBase[0] = NULL;
|
Process->Pcb.DirectoryTableBase[0] = NULL;
|
||||||
|
|
||||||
DPRINT("Finished Mmi386ReleaseMmInfo()\n");
|
DPRINT("Finished Mmi386ReleaseMmInfo()\n");
|
||||||
|
@ -145,6 +257,9 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
PhysPageDirectory = (PULONG)(MmGetPhysicalAddress(PageDirectory)).u.LowPart;
|
PhysPageDirectory = (PULONG)(MmGetPhysicalAddress(PageDirectory)).u.LowPart;
|
||||||
|
|
||||||
|
VALIDATE_PHYSICAL_ADDRESS(PhysPageDirectory);
|
||||||
|
|
||||||
KProcess->DirectoryTableBase[0] = PhysPageDirectory;
|
KProcess->DirectoryTableBase[0] = PhysPageDirectory;
|
||||||
CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
|
CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
|
||||||
|
|
||||||
|
@ -176,7 +291,7 @@ VOID MmDeletePageTable(PEPROCESS Process, PVOID Address)
|
||||||
KeAttachProcess(Process);
|
KeAttachProcess(Process);
|
||||||
}
|
}
|
||||||
*(ADDR_TO_PDE(Address)) = 0;
|
*(ADDR_TO_PDE(Address)) = 0;
|
||||||
if (Address >= (PVOID)KERNEL_BASE)
|
if (Address >= (PVOID) KERNEL_BASE)
|
||||||
{
|
{
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
|
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
|
||||||
}
|
}
|
||||||
|
@ -192,13 +307,13 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
PULONG PageTable;
|
PULONG PageTable;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG npage;
|
ULONG_PTR npage;
|
||||||
|
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
KeAttachProcess(Process);
|
KeAttachProcess(Process);
|
||||||
}
|
}
|
||||||
PageTable = (PULONG)PAGE_ROUND_DOWN((PVOID)ADDR_TO_PTE(Address));
|
PageTable = (PULONG) PAGE_ROUND_DOWN((PVOID) ADDR_TO_PTE(Address));
|
||||||
for (i = 0; i < 1024; i++)
|
for (i = 0; i < 1024; i++)
|
||||||
{
|
{
|
||||||
if (PageTable[i] != 0)
|
if (PageTable[i] != 0)
|
||||||
|
@ -210,11 +325,11 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
npage = *(ADDR_TO_PDE(Address));
|
npage = *(ADDR_TO_PDE(Address));
|
||||||
*(ADDR_TO_PDE(Address)) = 0;
|
*(ADDR_TO_PDE(Address)) = 0;
|
||||||
if (Address >= (PVOID)KERNEL_BASE)
|
if (Address >= (PVOID) KERNEL_BASE)
|
||||||
{
|
{
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
|
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
|
||||||
}
|
}
|
||||||
MmDereferencePage((PVOID)PAGE_MASK(npage));
|
MmDereferencePage((ULONG_PTR) PAGE_MASK(npage));
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
|
@ -228,8 +343,8 @@ NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PULONG Pde;
|
PULONG Pde;
|
||||||
ULONG Address = (ULONG)PAddress;
|
ULONG_PTR Address = (ULONG)PAddress;
|
||||||
ULONG npage;
|
ULONG_PTR npage;
|
||||||
|
|
||||||
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
||||||
|
|
||||||
|
@ -245,18 +360,21 @@ NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, (PVOID*)&npage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(npage));
|
||||||
|
|
||||||
(*Pde) = npage | 0x7;
|
(*Pde) = npage | 0x7;
|
||||||
if (Address >= KERNEL_BASE)
|
if (Address >= KERNEL_BASE)
|
||||||
{
|
{
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] =
|
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] =
|
||||||
*Pde;
|
*Pde;
|
||||||
}
|
}
|
||||||
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
|
memset((PVOID) PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +408,7 @@ ULONG MmGetPageEntry1(PVOID PAddress)
|
||||||
PULONG page_dir;
|
PULONG page_dir;
|
||||||
ULONG Address = (ULONG)PAddress;
|
ULONG Address = (ULONG)PAddress;
|
||||||
|
|
||||||
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
DPRINT("MmGetPageEntry1(Address %x)\n", Address);
|
||||||
|
|
||||||
page_dir = ADDR_TO_PDE(Address);
|
page_dir = ADDR_TO_PDE(Address);
|
||||||
if ((*page_dir) == 0 &&
|
if ((*page_dir) == 0 &&
|
||||||
|
@ -327,30 +445,31 @@ ULONG MmGetPageEntryForProcess1(PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ULONG MmGetPhysicalAddressForProcess(PEPROCESS Process,
|
ULONG
|
||||||
PVOID Address)
|
MmGetPhysicalAddressForProcess(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address)
|
||||||
{
|
{
|
||||||
ULONG PageEntry;
|
ULONG PageEntry;
|
||||||
|
|
||||||
PageEntry = MmGetPageEntryForProcess(Process, Address);
|
PageEntry = MmGetPageEntryForProcess(Process, Address);
|
||||||
|
|
||||||
if (!(PageEntry & PA_PRESENT))
|
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(PageEntry));
|
||||||
{
|
|
||||||
return(0);
|
return(PAGE_MASK(PageEntry));
|
||||||
}
|
|
||||||
return(PAGE_MASK(PageEntry));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG* PhysicalAddr)
|
MmDisableVirtualMapping(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address,
|
||||||
|
OUT PBOOLEAN WasDirty,
|
||||||
|
OUT PULONG_PTR PhysicalAddr)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Delete a virtual mapping
|
* FUNCTION: Disable a virtual mapping
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG Pte;
|
ULONG Pte;
|
||||||
PULONG Pde;
|
PULONG Pde;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
BOOLEAN WasValid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are setting a page in another process we need to be in its
|
* If we are setting a page in another process we need to be in its
|
||||||
|
@ -374,20 +493,16 @@ MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG*
|
||||||
}
|
}
|
||||||
if ((*Pde) == 0)
|
if ((*Pde) == 0)
|
||||||
{
|
{
|
||||||
|
DPRINT1("PDE for address 0x%.08x does not exist\n", Address);
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Atomically set the entry to zero and get the old value.
|
* Reset the present bit
|
||||||
*/
|
*/
|
||||||
Pte = *ADDR_TO_PTE(Address);
|
Pte = *ADDR_TO_PTE(Address);
|
||||||
*ADDR_TO_PTE(Address) = Pte & (~PA_PRESENT);
|
*ADDR_TO_PTE(Address) = Pte & (~PA_PRESENT);
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
WasValid = (PAGE_MASK(Pte) != 0);
|
|
||||||
if (!WasValid)
|
|
||||||
{
|
|
||||||
KeBugCheck(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If necessary go back to the original context
|
* If necessary go back to the original context
|
||||||
|
@ -406,13 +521,18 @@ MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG*
|
||||||
}
|
}
|
||||||
if (PhysicalAddr != NULL)
|
if (PhysicalAddr != NULL)
|
||||||
{
|
{
|
||||||
*PhysicalAddr = PAGE_MASK(Pte);
|
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(Pte));
|
||||||
|
|
||||||
|
*PhysicalAddr = PAGE_MASK(Pte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
MmDeleteVirtualMapping(PEPROCESS Process,
|
||||||
BOOL* WasDirty, ULONG* PhysicalAddr)
|
PVOID Address,
|
||||||
|
BOOLEAN FreePage,
|
||||||
|
PBOOLEAN WasDirty,
|
||||||
|
PULONG PhysicalAddr)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Delete a virtual mapping
|
* FUNCTION: Delete a virtual mapping
|
||||||
*/
|
*/
|
||||||
|
@ -467,11 +587,11 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
||||||
WasValid = (PAGE_MASK(Pte) != 0);
|
WasValid = (PAGE_MASK(Pte) != 0);
|
||||||
if (WasValid)
|
if (WasValid)
|
||||||
{
|
{
|
||||||
MmMarkPageUnmapped((PVOID)PAGE_MASK(Pte));
|
MmMarkPageUnmapped((ULONG_PTR) PAGE_MASK(Pte));
|
||||||
}
|
}
|
||||||
if (FreePage && WasValid)
|
if (FreePage && WasValid)
|
||||||
{
|
{
|
||||||
MmDereferencePage((PVOID)PAGE_MASK(Pte));
|
MmDereferencePage((ULONG_PTR) PAGE_MASK(Pte));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -516,13 +636,16 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
||||||
}
|
}
|
||||||
if (PhysicalAddr != NULL)
|
if (PhysicalAddr != NULL)
|
||||||
{
|
{
|
||||||
|
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(Pte));
|
||||||
|
|
||||||
*PhysicalAddr = PAGE_MASK(Pte);
|
*PhysicalAddr = PAGE_MASK(Pte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
MmDeletePageFileMapping(IN PEPROCESS Process,
|
||||||
SWAPENTRY* SwapEntry)
|
IN PVOID Address,
|
||||||
|
OUT PSWAPENTRY SwapEntry)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Delete a virtual mapping
|
* FUNCTION: Delete a virtual mapping
|
||||||
*/
|
*/
|
||||||
|
@ -530,7 +653,6 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
||||||
ULONG Pte;
|
ULONG Pte;
|
||||||
PULONG Pde;
|
PULONG Pde;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
BOOLEAN WasValid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are setting a page in another process we need to be in its
|
* If we are setting a page in another process we need to be in its
|
||||||
|
@ -571,7 +693,7 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
||||||
/*
|
/*
|
||||||
* Decrement the reference count for this page table.
|
* Decrement the reference count for this page table.
|
||||||
*/
|
*/
|
||||||
if (Process != NULL && WasValid &&
|
if (Process != NULL &&
|
||||||
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
ADDR_TO_PAGE_TABLE(Address) < 768)
|
ADDR_TO_PAGE_TABLE(Address) < 768)
|
||||||
{
|
{
|
||||||
|
@ -597,7 +719,7 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
||||||
/*
|
/*
|
||||||
* Return some information to the caller
|
* Return some information to the caller
|
||||||
*/
|
*/
|
||||||
*SwapEntry = Pte >> 1;
|
*SwapEntry = GET_SWAPENTRY_FROM_PTE(Pte);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -635,8 +757,8 @@ BOOLEAN MmIsPageTablePresent(PVOID PAddress)
|
||||||
NTSTATUS MmCreatePageTable(PVOID PAddress)
|
NTSTATUS MmCreatePageTable(PVOID PAddress)
|
||||||
{
|
{
|
||||||
PULONG page_dir;
|
PULONG page_dir;
|
||||||
ULONG Address = (ULONG)PAddress;
|
ULONG_PTR Address = (ULONG)PAddress;
|
||||||
ULONG npage;
|
ULONG_PTR npage;
|
||||||
|
|
||||||
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
||||||
|
|
||||||
|
@ -651,13 +773,16 @@ NTSTATUS MmCreatePageTable(PVOID PAddress)
|
||||||
if ((*page_dir) == 0)
|
if ((*page_dir) == 0)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, (PVOID*)&npage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(npage));
|
||||||
|
|
||||||
(*page_dir) = npage | 0x7;
|
(*page_dir) = npage | 0x7;
|
||||||
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
|
memset((PVOID) PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -670,8 +795,8 @@ PULONG MmGetPageEntry(PVOID PAddress)
|
||||||
{
|
{
|
||||||
PULONG page_tlb;
|
PULONG page_tlb;
|
||||||
PULONG page_dir;
|
PULONG page_dir;
|
||||||
ULONG Address = (ULONG)PAddress;
|
ULONG_PTR Address = (ULONG)PAddress;
|
||||||
ULONG npage;
|
ULONG_PTR npage;
|
||||||
|
|
||||||
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
||||||
|
|
||||||
|
@ -686,13 +811,14 @@ PULONG MmGetPageEntry(PVOID PAddress)
|
||||||
if ((*page_dir) == 0)
|
if ((*page_dir) == 0)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, (PVOID*)&npage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
(*page_dir) = npage | 0x7;
|
(*page_dir) = npage | 0x7;
|
||||||
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
|
memset((PVOID) PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
page_tlb = ADDR_TO_PTE(Address);
|
page_tlb = ADDR_TO_PTE(Address);
|
||||||
|
@ -700,11 +826,14 @@ PULONG MmGetPageEntry(PVOID PAddress)
|
||||||
return(page_tlb);
|
return(page_tlb);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN MmIsPageDirty(PEPROCESS Process, PVOID Address)
|
|
||||||
|
BOOLEAN
|
||||||
|
MmIsPageDirty(PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
return((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY);
|
return((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address)
|
MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
|
@ -731,7 +860,10 @@ MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address)
|
||||||
return(Accessed);
|
return(Accessed);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmSetCleanPage(PEPROCESS Process, PVOID Address)
|
|
||||||
|
VOID
|
||||||
|
MmSetCleanPage(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address)
|
||||||
{
|
{
|
||||||
PULONG PageEntry;
|
PULONG PageEntry;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
@ -749,7 +881,143 @@ VOID MmSetCleanPage(PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address)
|
|
||||||
|
BOOLEAN
|
||||||
|
MiPageState(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG PageState)
|
||||||
|
{
|
||||||
|
PULONG PageEntry;
|
||||||
|
BOOLEAN Value;
|
||||||
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeAttachProcess(Process);
|
||||||
|
}
|
||||||
|
|
||||||
|
PageEntry = MmGetPageEntry(Address);
|
||||||
|
|
||||||
|
switch (PageState)
|
||||||
|
{
|
||||||
|
case PAGE_STATE_VALID:
|
||||||
|
Value = ((*PageEntry) & PA_PRESENT) != 0;
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_PROTOTYPE:
|
||||||
|
Value = ((*PageEntry) & PA_PROTOTYPE) != 0;
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_TRANSITION:
|
||||||
|
Value = ((*PageEntry) & PA_TRANSITION) != 0;
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_DEMAND_ZERO:
|
||||||
|
Value = ((*PageEntry) & PA_DEMAND_ZERO) != 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DPRINT1("Unknown page state 0x%.08x\n", PageState);
|
||||||
|
KeBugCheck(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiClearPageState(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG PageState)
|
||||||
|
{
|
||||||
|
PULONG PageEntry;
|
||||||
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeAttachProcess(Process);
|
||||||
|
}
|
||||||
|
PageEntry = MmGetPageEntry(Address);
|
||||||
|
|
||||||
|
switch (PageState)
|
||||||
|
{
|
||||||
|
case PAGE_STATE_VALID:
|
||||||
|
(*PageEntry) = (*PageEntry) & (~PA_PRESENT);
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_PROTOTYPE:
|
||||||
|
(*PageEntry) = (*PageEntry) & (~PA_PROTOTYPE);
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_TRANSITION:
|
||||||
|
assertmsg(!((*PageEntry) & PA_PRESENT), ("Page 0x%.08x in transition is present\n", Address));
|
||||||
|
(*PageEntry) = (*PageEntry) & (~PA_TRANSITION);
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_DEMAND_ZERO:
|
||||||
|
assertmsg(!((*PageEntry) & PA_PRESENT), ("Demand zero page 0x%.08x is present\n", Address));
|
||||||
|
(*PageEntry) = (*PageEntry) & (~PA_DEMAND_ZERO);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DPRINT1("Unknown page state 0x%.08x\n", PageState);
|
||||||
|
KeBugCheck(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLUSH_TLB;
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSetPageState(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG PageState)
|
||||||
|
{
|
||||||
|
PULONG PageEntry;
|
||||||
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeAttachProcess(Process);
|
||||||
|
}
|
||||||
|
PageEntry = MmGetPageEntry(Address);
|
||||||
|
|
||||||
|
switch (PageState)
|
||||||
|
{
|
||||||
|
case PAGE_STATE_VALID:
|
||||||
|
(*PageEntry) = (*PageEntry) | PA_PRESENT;
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_PROTOTYPE:
|
||||||
|
(*PageEntry) = (*PageEntry) | PA_PROTOTYPE;
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_TRANSITION:
|
||||||
|
assertmsg(!((*PageEntry) & PA_PRESENT), ("Page 0x%.08x in transition is present\n", Address));
|
||||||
|
(*PageEntry) = (*PageEntry) | PA_TRANSITION;
|
||||||
|
break;
|
||||||
|
case PAGE_STATE_DEMAND_ZERO:
|
||||||
|
assertmsg(!((*PageEntry) & PA_PRESENT), ("Demand zero page 0x%.08x is present\n", Address));
|
||||||
|
(*PageEntry) = (*PageEntry) | PA_DEMAND_ZERO;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DPRINT1("Unknown page state 0x%.08x\n", PageState);
|
||||||
|
KeBugCheck(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLUSH_TLB;
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmSetDirtyPage(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address)
|
||||||
{
|
{
|
||||||
PULONG PageEntry;
|
PULONG PageEntry;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
@ -767,7 +1035,10 @@ VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
|
|
||||||
|
VOID
|
||||||
|
MmEnableVirtualMapping(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address)
|
||||||
{
|
{
|
||||||
PULONG PageEntry;
|
PULONG PageEntry;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
@ -785,16 +1056,19 @@ VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
|
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
|
BOOLEAN
|
||||||
|
MmIsPageSwapEntry(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address)
|
||||||
{
|
{
|
||||||
ULONG Pte;
|
ULONG Pte;
|
||||||
Pte = MmGetPageEntryForProcess1(Process, Address);
|
Pte = MmGetPageEntryForProcess1(Process, Address);
|
||||||
return((!(Pte & PA_PRESENT)) && Pte != 0);
|
return(IS_SWAPENTRY_PTE(Pte));
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -817,12 +1091,12 @@ MmCreateVirtualMappingForKernel(PVOID Address,
|
||||||
CurrentProcess = NULL;
|
CurrentProcess = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Process == NULL && Address < (PVOID)KERNEL_BASE)
|
if (Process == NULL && Address < (PVOID) KERNEL_BASE)
|
||||||
{
|
{
|
||||||
DPRINT1("No process\n");
|
DPRINT1("No process\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
if (Process != NULL && Address >= (PVOID)KERNEL_BASE)
|
if (Process != NULL && Address >= (PVOID) KERNEL_BASE)
|
||||||
{
|
{
|
||||||
DPRINT1("Setting kernel address with process context\n");
|
DPRINT1("Setting kernel address with process context\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
|
@ -849,7 +1123,7 @@ MmCreateVirtualMappingForKernel(PVOID Address,
|
||||||
}
|
}
|
||||||
if (PAGE_MASK((*Pte)) != 0)
|
if (PAGE_MASK((*Pte)) != 0)
|
||||||
{
|
{
|
||||||
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte)));
|
MmMarkPageUnmapped((ULONG_PTR) PAGE_MASK((*Pte)));
|
||||||
}
|
}
|
||||||
*Pte = PhysicalAddress | Attributes;
|
*Pte = PhysicalAddress | Attributes;
|
||||||
if (Process != NULL &&
|
if (Process != NULL &&
|
||||||
|
@ -872,9 +1146,9 @@ MmCreateVirtualMappingForKernel(PVOID Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmCreatePageFileMapping(PEPROCESS Process,
|
MmCreatePageFileMapping(IN PEPROCESS Process,
|
||||||
PVOID Address,
|
IN PVOID Address,
|
||||||
SWAPENTRY SwapEntry)
|
IN SWAPENTRY SwapEntry)
|
||||||
{
|
{
|
||||||
PEPROCESS CurrentProcess;
|
PEPROCESS CurrentProcess;
|
||||||
PULONG Pte;
|
PULONG Pte;
|
||||||
|
@ -889,12 +1163,12 @@ MmCreatePageFileMapping(PEPROCESS Process,
|
||||||
CurrentProcess = NULL;
|
CurrentProcess = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Process == NULL && Address < (PVOID)KERNEL_BASE)
|
if (Process == NULL && Address < (PVOID) KERNEL_BASE)
|
||||||
{
|
{
|
||||||
DPRINT1("No process\n");
|
DPRINT1("No process\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
if (Process != NULL && Address >= (PVOID)KERNEL_BASE)
|
if (Process != NULL && Address >= (PVOID) KERNEL_BASE)
|
||||||
{
|
{
|
||||||
DPRINT1("Setting kernel address with process context\n");
|
DPRINT1("Setting kernel address with process context\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
|
@ -920,9 +1194,9 @@ MmCreatePageFileMapping(PEPROCESS Process,
|
||||||
}
|
}
|
||||||
if (PAGE_MASK((*Pte)) != 0)
|
if (PAGE_MASK((*Pte)) != 0)
|
||||||
{
|
{
|
||||||
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte)));
|
MmMarkPageUnmapped((ULONG_PTR) PAGE_MASK((*Pte)));
|
||||||
}
|
}
|
||||||
*Pte = SwapEntry << 1;
|
SET_SWAPENTRY_IN_PTE(*Pte, SwapEntry);
|
||||||
if (Process != NULL &&
|
if (Process != NULL &&
|
||||||
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
ADDR_TO_PAGE_TABLE(Address) < 768)
|
ADDR_TO_PAGE_TABLE(Address) < 768)
|
||||||
|
@ -962,17 +1236,17 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
||||||
CurrentProcess = NULL;
|
CurrentProcess = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Process == NULL && Address < (PVOID)KERNEL_BASE)
|
if (Process == NULL && Address < (PVOID) KERNEL_BASE)
|
||||||
{
|
{
|
||||||
DPRINT1("No process\n");
|
DPRINT1("No process\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
if (Process != NULL && Address >= (PVOID)KERNEL_BASE)
|
if (Process != NULL && Address >= (PVOID) KERNEL_BASE)
|
||||||
{
|
{
|
||||||
DPRINT1("Setting kernel address with process context\n");
|
DPRINT1("Setting kernel address with process context\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
MmMarkPageMapped((PVOID)PhysicalAddress);
|
MmMarkPageMapped(PhysicalAddress);
|
||||||
|
|
||||||
Attributes = ProtectToPTE(flProtect);
|
Attributes = ProtectToPTE(flProtect);
|
||||||
if (!(Attributes & PA_PRESENT) && PhysicalAddress != 0)
|
if (!(Attributes & PA_PRESENT) && PhysicalAddress != 0)
|
||||||
|
@ -1003,8 +1277,24 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
||||||
}
|
}
|
||||||
if (PAGE_MASK((*Pte)) != 0)
|
if (PAGE_MASK((*Pte)) != 0)
|
||||||
{
|
{
|
||||||
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte)));
|
MmMarkPageUnmapped((ULONG_PTR) PAGE_MASK((*Pte)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
if ((MiBreakPointAddressLow != NULL) && (MiBreakPointAddressHigh != NULL) &&
|
||||||
|
((PAGE_ROUND_DOWN(Address) >= PAGE_ROUND_DOWN(MiBreakPointAddressLow))
|
||||||
|
&& (PAGE_ROUND_DOWN(Address) < PAGE_ROUND_UP(MiBreakPointAddressHigh))))
|
||||||
|
{
|
||||||
|
DbgPrint("Changing PTE of virtual address 0x%.08x from PTE 0x%.08x\n", Address, *Pte);
|
||||||
|
MiDumpPTE(*Pte);
|
||||||
|
DbgPrint("To 0x%.08x\n", PhysicalAddress | Attributes);
|
||||||
|
MiDumpPTE(PhysicalAddress | Attributes);
|
||||||
|
//assert(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
*Pte = PhysicalAddress | Attributes;
|
*Pte = PhysicalAddress | Attributes;
|
||||||
if (Process != NULL &&
|
if (Process != NULL &&
|
||||||
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
|
@ -1032,7 +1322,7 @@ MmCreateVirtualMapping(PEPROCESS Process,
|
||||||
ULONG PhysicalAddress,
|
ULONG PhysicalAddress,
|
||||||
BOOLEAN MayWait)
|
BOOLEAN MayWait)
|
||||||
{
|
{
|
||||||
if (!MmIsUsablePage((PVOID)PhysicalAddress))
|
if (!MmIsUsablePage(PhysicalAddress))
|
||||||
{
|
{
|
||||||
DPRINT1("Page at address %x not usable\n", PhysicalAddress);
|
DPRINT1("Page at address %x not usable\n", PhysicalAddress);
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
|
@ -1079,14 +1369,15 @@ 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();
|
||||||
}
|
}
|
||||||
|
@ -1106,6 +1397,8 @@ MmGetPhysicalAddress(PVOID vaddr)
|
||||||
Pte = *MmGetPageEntry(vaddr);
|
Pte = *MmGetPageEntry(vaddr);
|
||||||
if (Pte & PA_PRESENT)
|
if (Pte & PA_PRESENT)
|
||||||
{
|
{
|
||||||
|
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(Pte));
|
||||||
|
|
||||||
p.QuadPart = PAGE_MASK(Pte);
|
p.QuadPart = PAGE_MASK(Pte);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1116,5 +1409,19 @@ MmGetPhysicalAddress(PVOID vaddr)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiDumpProcessPTE(IN PEPROCESS Process,
|
||||||
|
IN PVOID Address)
|
||||||
|
{
|
||||||
|
ULONG Value;
|
||||||
|
|
||||||
|
Value = MmGetPageEntryForProcess1(Process, Address);
|
||||||
|
|
||||||
|
MiDumpPTE(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: kmap.c,v 1.14 2002/01/01 00:21:56 dwelch Exp $
|
/* $Id: kmap.c,v 1.15 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -50,28 +50,29 @@ ExUnmapPage(PVOID Addr)
|
||||||
PVOID
|
PVOID
|
||||||
ExAllocatePage(VOID)
|
ExAllocatePage(VOID)
|
||||||
{
|
{
|
||||||
ULONG PhysPage;
|
ULONG_PTR Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, (PVOID*)&PhysPage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ExAllocatePageWithPhysPage(PhysPage));
|
return(ExAllocatePageWithPhysPage(Page));
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MiZeroPage(ULONG PhysPage)
|
MiZeroPage(IN ULONG_PTR Page)
|
||||||
{
|
{
|
||||||
PVOID TempAddress;
|
PVOID TempAddress;
|
||||||
|
|
||||||
TempAddress = ExAllocatePageWithPhysPage(PhysPage);
|
TempAddress = ExAllocatePageWithPhysPage(Page);
|
||||||
if (TempAddress == NULL)
|
if (TempAddress == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_NO_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(TempAddress, 0, PAGESIZE);
|
memset(TempAddress, 0, PAGESIZE);
|
||||||
ExUnmapPage(TempAddress);
|
ExUnmapPage(TempAddress);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -93,10 +94,10 @@ MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
ExAllocatePageWithPhysPage(ULONG PhysPage)
|
ExAllocatePageWithPhysPage(IN ULONG_PTR Page)
|
||||||
{
|
{
|
||||||
KIRQL oldlvl;
|
KIRQL oldlvl;
|
||||||
ULONG addr;
|
PVOID addr;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -107,11 +108,11 @@ ExAllocatePageWithPhysPage(ULONG PhysPage)
|
||||||
{
|
{
|
||||||
DPRINT("i %x\n",i);
|
DPRINT("i %x\n",i);
|
||||||
AllocMap[i / 32] |= (1 << (i % 32));
|
AllocMap[i / 32] |= (1 << (i % 32));
|
||||||
addr = (ULONG)(NonPagedPoolBase + (i*PAGESIZE));
|
addr = (PVOID) (NonPagedPoolBase + (i*PAGESIZE));
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)addr,
|
addr,
|
||||||
PAGE_READWRITE | PAGE_SYSTEM,
|
PAGE_READWRITE | PAGE_SYSTEM,
|
||||||
PhysPage,
|
Page,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -119,7 +120,7 @@ ExAllocatePageWithPhysPage(ULONG PhysPage)
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&AllocMapLock, oldlvl);
|
KeReleaseSpinLock(&AllocMapLock, oldlvl);
|
||||||
return((PVOID)addr);
|
return(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&AllocMapLock, oldlvl);
|
KeReleaseSpinLock(&AllocMapLock, oldlvl);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* ReactOS kernel
|
* ReactOS kernel
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
* Copyright (C) 1998-2002 ReactOS Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <roscfg.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <internal/mm.h>
|
#include <internal/mm.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
|
@ -39,6 +40,13 @@
|
||||||
|
|
||||||
#define TAG_MAREA TAG('M', 'A', 'R', 'E')
|
#define TAG_MAREA TAG('M', 'A', 'R', 'E')
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
PVOID MiMemoryAreaBugCheckAddress = (PVOID) NULL;
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
/* Define to track memory area references */
|
||||||
|
//#define TRACK_MEMORY_AREA_REFERENCES
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead)
|
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead)
|
||||||
|
@ -61,8 +69,94 @@ VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead)
|
||||||
DbgPrint("Finished MmDumpMemoryAreas()\n");
|
DbgPrint("Finished MmDumpMemoryAreas()\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
|
#ifdef DBG
|
||||||
PVOID Address)
|
|
||||||
|
VOID
|
||||||
|
MiValidateMemoryAreaPTEs(IN PMEMORY_AREA MemoryArea)
|
||||||
|
{
|
||||||
|
ULONG PteProtect;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
if (!MiInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i <= (MemoryArea->Length / PAGESIZE); i++)
|
||||||
|
{
|
||||||
|
if (MmIsPagePresent(MemoryArea->Process, MemoryArea->BaseAddress + (i * PAGESIZE)))
|
||||||
|
{
|
||||||
|
PteProtect = MmGetPageProtect(MemoryArea->Process, MemoryArea->BaseAddress + (i * PAGESIZE));
|
||||||
|
if (PteProtect != MemoryArea->Attributes)
|
||||||
|
{
|
||||||
|
if (MmIsCopyOnWriteMemoryArea(MemoryArea))
|
||||||
|
{
|
||||||
|
if ((PteProtect != PAGE_READONLY) && (PteProtect != PAGE_EXECUTE_READ))
|
||||||
|
{
|
||||||
|
DPRINT1("COW memory area attributes 0x%.08x\n", MemoryArea->Attributes);
|
||||||
|
DbgMmDumpProtection(MemoryArea->Attributes);
|
||||||
|
DPRINT1("PTE attributes 0x%.08x\n", PteProtect);
|
||||||
|
DbgMmDumpProtection(PteProtect);
|
||||||
|
assertmsg(FALSE, ("PTE attributes and memory area protection are different. Area 0x%.08x\n",
|
||||||
|
MemoryArea->BaseAddress));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Memory area attributes 0x%.08x\n", MemoryArea->Attributes);
|
||||||
|
DbgMmDumpProtection(MemoryArea->Attributes);
|
||||||
|
DPRINT1("PTE attributes 0x%.08x\n", PteProtect);
|
||||||
|
DbgMmDumpProtection(PteProtect);
|
||||||
|
assertmsg(FALSE, ("PTE attributes and memory area protection are different. Area 0x%.08x\n",
|
||||||
|
MemoryArea->BaseAddress));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidateMemoryArea(IN PMEMORY_AREA MemoryArea)
|
||||||
|
{
|
||||||
|
assertmsg(MemoryArea != NULL,
|
||||||
|
("No memory area can exist at 0x%.08x\n", MemoryArea));
|
||||||
|
|
||||||
|
assertmsg(MemoryArea->Magic == TAG_MAREA,
|
||||||
|
("Bad magic (0x%.08x) for memory area (0x%.08x). It should be 0x%.08x\n",
|
||||||
|
MemoryArea->Magic, MemoryArea, TAG_MAREA));
|
||||||
|
|
||||||
|
/* FIXME: Can cause page faults and deadlock on the address space lock */
|
||||||
|
//MiValidateMemoryAreaPTEs(MemoryArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmApplyMemoryAreaProtection(IN PMEMORY_AREA MemoryArea)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
if (!MiInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i <= (MemoryArea->Length / PAGESIZE); i++)
|
||||||
|
{
|
||||||
|
if (MmIsPagePresent(MemoryArea->Process, MemoryArea->BaseAddress + (i * PAGESIZE)))
|
||||||
|
{
|
||||||
|
MmSetPageProtect(MemoryArea->Process,
|
||||||
|
MemoryArea->BaseAddress + (i * PAGESIZE),
|
||||||
|
MemoryArea->Attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: If the memory area is found, then it is referenced. The caller must
|
||||||
|
* call MmCloseMemoryArea() after use.
|
||||||
|
*/
|
||||||
|
PMEMORY_AREA
|
||||||
|
MmOpenMemoryAreaByAddress(IN PMADDRESS_SPACE AddressSpace,
|
||||||
|
IN PVOID Address)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
MEMORY_AREA* current;
|
MEMORY_AREA* current;
|
||||||
|
@ -102,6 +196,7 @@ MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
|
||||||
(current->BaseAddress + current->Length) > Address)
|
(current->BaseAddress + current->Length) > Address)
|
||||||
{
|
{
|
||||||
DPRINT("%s() = %x\n",__FUNCTION__,current);
|
DPRINT("%s() = %x\n",__FUNCTION__,current);
|
||||||
|
MmReferenceMemoryArea(current);
|
||||||
return(current);
|
return(current);
|
||||||
}
|
}
|
||||||
if (current->BaseAddress > Address)
|
if (current->BaseAddress > Address)
|
||||||
|
@ -116,6 +211,10 @@ MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: If the memory area is found, then it is referenced. The caller must
|
||||||
|
* call MmCloseMemoryArea() after use.
|
||||||
|
*/
|
||||||
MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
ULONG Length)
|
ULONG Length)
|
||||||
|
@ -140,6 +239,7 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
|
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
|
||||||
current);
|
current);
|
||||||
|
MmReferenceMemoryArea(current);
|
||||||
return(current);
|
return(current);
|
||||||
}
|
}
|
||||||
Extent = (ULONG)current->BaseAddress + current->Length;
|
Extent = (ULONG)current->BaseAddress + current->Length;
|
||||||
|
@ -148,6 +248,7 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
|
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
|
||||||
current);
|
current);
|
||||||
|
MmReferenceMemoryArea(current);
|
||||||
return(current);
|
return(current);
|
||||||
}
|
}
|
||||||
if (current->BaseAddress <= Address &&
|
if (current->BaseAddress <= Address &&
|
||||||
|
@ -155,6 +256,7 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
|
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
|
||||||
current);
|
current);
|
||||||
|
MmReferenceMemoryArea(current);
|
||||||
return(current);
|
return(current);
|
||||||
}
|
}
|
||||||
if (current->BaseAddress >= (Address+Length))
|
if (current->BaseAddress >= (Address+Length))
|
||||||
|
@ -168,6 +270,14 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmCloseMemoryArea(IN PMEMORY_AREA MemoryArea)
|
||||||
|
{
|
||||||
|
MmDereferenceMemoryArea(MemoryArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
|
static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
MEMORY_AREA* marea)
|
MEMORY_AREA* marea)
|
||||||
{
|
{
|
||||||
|
@ -290,50 +400,75 @@ NTSTATUS MmInitMemoryAreas(VOID)
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOTE: The address space lock must be held when called */
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
MmFreeMemoryArea(IN PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID BaseAddress,
|
IN PVOID BaseAddress,
|
||||||
ULONG Length,
|
IN ULONG Length,
|
||||||
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
IN PFREE_MEMORY_AREA_PAGE_CALLBACK FreePage,
|
||||||
ULONG PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty),
|
IN PVOID FreePageContext)
|
||||||
PVOID FreePageContext)
|
|
||||||
{
|
{
|
||||||
MEMORY_AREA* MemoryArea;
|
MEMORY_AREA* MemoryArea;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
DPRINT("MmFreeMemoryArea(AddressSpace %x, BaseAddress %x, Length %x,"
|
DPRINT("MmFreeMemoryArea(AddressSpace %x, BaseAddress %x, Length %x, "
|
||||||
"FreePageContext %d)\n",AddressSpace,BaseAddress,Length,FreePageContext);
|
"FreePageContext %d)\n",AddressSpace,BaseAddress,Length,FreePageContext);
|
||||||
|
|
||||||
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
|
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, BaseAddress);
|
||||||
BaseAddress);
|
if (MemoryArea == NULL)
|
||||||
if (MemoryArea == NULL)
|
{
|
||||||
{
|
assertmsg(FALSE, ("Freeing non-existant memory area at 0x%.08x\n", BaseAddress));
|
||||||
KeBugCheck(0);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
}
|
||||||
}
|
|
||||||
|
MmCloseMemoryArea(MemoryArea);
|
||||||
|
InterlockedDecrement(&MemoryArea->ReferenceCount);
|
||||||
|
#if 0
|
||||||
|
assertmsg(MemoryArea->ReferenceCount == 0,
|
||||||
|
("Memory area at address 0x%.08x has %d outstanding references\n",
|
||||||
|
BaseAddress, MemoryArea->ReferenceCount));
|
||||||
|
#endif
|
||||||
for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGESIZE); i++)
|
for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGESIZE); i++)
|
||||||
{
|
{
|
||||||
ULONG PhysAddr = 0;
|
ULONG_PTR PhysicalPage = 0;
|
||||||
BOOL Dirty;
|
BOOLEAN Dirty = FALSE;
|
||||||
SWAPENTRY SwapEntry = 0;
|
SWAPENTRY SwapEntry = 0;
|
||||||
|
PVOID VirtualPage = NULL;
|
||||||
|
|
||||||
if (MmIsPageSwapEntry(AddressSpace->Process,
|
VirtualPage = MemoryArea->BaseAddress + (i * PAGESIZE);
|
||||||
MemoryArea->BaseAddress + (i * PAGESIZE)))
|
|
||||||
|
#ifdef DBG
|
||||||
|
if ((MiMemoryAreaBugCheckAddress != NULL)
|
||||||
|
&& ((MiMemoryAreaBugCheckAddress >= VirtualPage)
|
||||||
|
&& MiMemoryAreaBugCheckAddress < VirtualPage + PAGESIZE))
|
||||||
|
{
|
||||||
|
assertmsg(FALSE, ("VirtualPage 0x%.08x MiMemoryAreaBugCheckAddress 0x%.08x \n",
|
||||||
|
VirtualPage));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (FreePage != NULL)
|
||||||
|
{
|
||||||
|
FreePage(TRUE, FreePageContext, MemoryArea,
|
||||||
|
VirtualPage, 0, 0, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MmIsPageSwapEntry(AddressSpace->Process, VirtualPage))
|
||||||
{
|
{
|
||||||
MmDeletePageFileMapping(AddressSpace->Process,
|
MmDeletePageFileMapping(AddressSpace->Process,
|
||||||
MemoryArea->BaseAddress + (i * PAGESIZE),
|
VirtualPage,
|
||||||
&SwapEntry);
|
&SwapEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmDeleteVirtualMapping(AddressSpace->Process,
|
MmDeleteVirtualMapping(AddressSpace->Process,
|
||||||
MemoryArea->BaseAddress + (i*PAGESIZE),
|
VirtualPage,
|
||||||
FALSE, &Dirty, &PhysAddr);
|
FALSE, &Dirty, &PhysicalPage);
|
||||||
}
|
}
|
||||||
if (FreePage != NULL)
|
if (FreePage != NULL)
|
||||||
{
|
{
|
||||||
FreePage(FreePageContext, MemoryArea,
|
FreePage(FALSE, FreePageContext, MemoryArea,
|
||||||
MemoryArea->BaseAddress + (i * PAGESIZE), PhysAddr, SwapEntry, Dirty);
|
VirtualPage, PhysicalPage, SwapEntry, Dirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +499,7 @@ PMEMORY_AREA MmSplitMemoryArea(PEPROCESS Process,
|
||||||
Result->Length = Length;
|
Result->Length = Length;
|
||||||
Result->Attributes = NewAttributes;
|
Result->Attributes = NewAttributes;
|
||||||
Result->LockCount = 0;
|
Result->LockCount = 0;
|
||||||
|
Result->ReferenceCount = 1;
|
||||||
Result->Process = Process;
|
Result->Process = Process;
|
||||||
|
|
||||||
if (BaseAddress == OriginalMemoryArea->BaseAddress)
|
if (BaseAddress == OriginalMemoryArea->BaseAddress)
|
||||||
|
@ -394,14 +530,15 @@ PMEMORY_AREA MmSplitMemoryArea(PEPROCESS Process,
|
||||||
return(Split);
|
return(Split);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
|
NTSTATUS
|
||||||
PMADDRESS_SPACE AddressSpace,
|
MmCreateMemoryArea(IN PEPROCESS Process,
|
||||||
ULONG Type,
|
IN PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID* BaseAddress,
|
IN ULONG Type,
|
||||||
ULONG Length,
|
IN OUT PVOID* BaseAddress,
|
||||||
ULONG Attributes,
|
IN ULONG Length,
|
||||||
MEMORY_AREA** Result,
|
IN ULONG Attributes,
|
||||||
BOOL FixedAddress)
|
OUT PMEMORY_AREA* Result,
|
||||||
|
IN BOOLEAN FixedAddress)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Create a memory area
|
* FUNCTION: Create a memory area
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
@ -411,10 +548,13 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
|
||||||
* Length = Length to allocate
|
* Length = Length to allocate
|
||||||
* Attributes = Protection attributes for the memory area
|
* Attributes = Protection attributes for the memory area
|
||||||
* Result = Receives a pointer to the memory area on exit
|
* Result = Receives a pointer to the memory area on exit
|
||||||
|
* FixedAddress = Wether the memory area must be based at BaseAddress or not
|
||||||
* RETURNS: Status
|
* RETURNS: Status
|
||||||
* NOTES: Lock the address space before calling this function
|
* NOTES: Lock the address space before calling this function
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
PMEMORY_AREA MemoryArea;
|
||||||
|
|
||||||
DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x,"
|
DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x,"
|
||||||
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
|
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
|
||||||
Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
|
Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
|
||||||
|
@ -433,27 +573,90 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress));
|
(*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress));
|
||||||
if (MmOpenMemoryAreaByRegion(AddressSpace,
|
MemoryArea = MmOpenMemoryAreaByRegion(AddressSpace, *BaseAddress, Length);
|
||||||
*BaseAddress,
|
if (MemoryArea)
|
||||||
Length)!=NULL)
|
|
||||||
{
|
{
|
||||||
|
MmCloseMemoryArea(MemoryArea);
|
||||||
DPRINT("Memory area already occupied\n");
|
DPRINT("Memory area already occupied\n");
|
||||||
return(STATUS_CONFLICTING_ADDRESSES);
|
return(STATUS_CONFLICTING_ADDRESSES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("MmCreateMemoryArea(*BaseAddress %x)\n", *BaseAddress);
|
||||||
|
|
||||||
*Result = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA),
|
*Result = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA),
|
||||||
TAG_MAREA);
|
TAG_MAREA);
|
||||||
RtlZeroMemory(*Result,sizeof(MEMORY_AREA));
|
RtlZeroMemory(*Result,sizeof(MEMORY_AREA));
|
||||||
|
SET_MAGIC(*Result, TAG_MAREA)
|
||||||
(*Result)->Type = Type;
|
(*Result)->Type = Type;
|
||||||
(*Result)->BaseAddress = *BaseAddress;
|
(*Result)->BaseAddress = *BaseAddress;
|
||||||
(*Result)->Length = Length;
|
(*Result)->Length = Length;
|
||||||
(*Result)->Attributes = Attributes;
|
(*Result)->Attributes = Attributes;
|
||||||
(*Result)->LockCount = 0;
|
(*Result)->LockCount = 0;
|
||||||
|
(*Result)->ReferenceCount = 1;
|
||||||
(*Result)->Process = Process;
|
(*Result)->Process = Process;
|
||||||
|
|
||||||
|
MmApplyMemoryAreaProtection(*Result);
|
||||||
|
|
||||||
MmInsertMemoryArea(AddressSpace, *Result);
|
MmInsertMemoryArea(AddressSpace, *Result);
|
||||||
|
|
||||||
DPRINT("MmCreateMemoryArea() succeeded\n");
|
DPRINT("MmCreateMemoryArea() succeeded\n");
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiReferenceMemoryArea(IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN LPSTR FileName,
|
||||||
|
IN ULONG LineNumber)
|
||||||
|
{
|
||||||
|
VALIDATE_MEMORY_AREA(MemoryArea);
|
||||||
|
|
||||||
|
InterlockedIncrement(&MemoryArea->ReferenceCount);
|
||||||
|
|
||||||
|
#ifdef TRACK_MEMORY_AREA_REFERENCES
|
||||||
|
DbgPrint("(0x%.08x)(%s:%d) Referencing memory area 0x%.08x (New ref.count %d)\n",
|
||||||
|
KeGetCurrentThread(), FileName, LineNumber,
|
||||||
|
MemoryArea->BaseAddress,
|
||||||
|
MemoryArea->ReferenceCount);
|
||||||
|
#endif /* TRACK_MEMORY_AREA_REFERENCES */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiDereferenceMemoryArea(IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN LPSTR FileName,
|
||||||
|
IN ULONG LineNumber)
|
||||||
|
{
|
||||||
|
VALIDATE_MEMORY_AREA(MemoryArea);
|
||||||
|
|
||||||
|
InterlockedDecrement(&MemoryArea->ReferenceCount);
|
||||||
|
|
||||||
|
#ifdef TRACK_MEMORY_AREA_REFERENCES
|
||||||
|
DbgPrint("(0x%.08x)(%s:%d) Dereferencing memory area 0x%.08x (New ref.count %d)\n",
|
||||||
|
KeGetCurrentThread(), FileName, LineNumber,
|
||||||
|
MemoryArea->BaseAddress,
|
||||||
|
MemoryArea->ReferenceCount);
|
||||||
|
#endif /* TRACK_MEMORY_AREA_REFERENCES */
|
||||||
|
|
||||||
|
assertmsg(MemoryArea->ReferenceCount > 0,
|
||||||
|
("No outstanding references on memory area (0x%.08x)\n", MemoryArea));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !DBG */
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiReferenceMemoryArea(IN PMEMORY_AREA MemoryArea)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&MemoryArea->ReferenceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiDereferenceMemoryArea(IN PMEMORY_AREA MemoryArea)
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&MemoryArea->ReferenceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !DBG */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mdl.c,v 1.37 2002/05/07 22:35:02 hbirr Exp $
|
/* $Id: mdl.c,v 1.38 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -28,11 +28,11 @@
|
||||||
PVOID
|
PVOID
|
||||||
MmGetMdlPageAddress(PMDL Mdl, PVOID Offset)
|
MmGetMdlPageAddress(PMDL Mdl, PVOID Offset)
|
||||||
{
|
{
|
||||||
PULONG MdlPages;
|
PULONG_PTR MdlPages;
|
||||||
|
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
MdlPages = (PULONG_PTR)(Mdl + 1);
|
||||||
|
|
||||||
return((PVOID)MdlPages[((ULONG)Offset) / PAGESIZE]);
|
return((PVOID) MdlPages[((ULONG_PTR) Offset) / PAGESIZE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
|
@ -46,8 +46,8 @@ MmUnlockPages(PMDL Mdl)
|
||||||
* MDL is updated
|
* MDL is updated
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
PULONG_PTR MdlPages;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PULONG MdlPages;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: I don't know whether this right, but it looks sensible
|
* FIXME: I don't know whether this right, but it looks sensible
|
||||||
|
@ -66,11 +66,11 @@ MmUnlockPages(PMDL Mdl)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
MdlPages = (PULONG_PTR) (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++)
|
||||||
{
|
{
|
||||||
MmUnlockPage((PVOID)MdlPages[i]);
|
MmUnlockPage(MdlPages[i]);
|
||||||
MmDereferencePage((PVOID)MdlPages[i]);
|
MmDereferencePage(MdlPages[i]);
|
||||||
}
|
}
|
||||||
Mdl->MdlFlags = Mdl->MdlFlags & (~MDL_PAGES_LOCKED);
|
Mdl->MdlFlags = Mdl->MdlFlags & (~MDL_PAGES_LOCKED);
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
{
|
{
|
||||||
PVOID Base;
|
PVOID Base;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PULONG MdlPages;
|
PULONG_PTR MdlPages;
|
||||||
MEMORY_AREA* Result;
|
MEMORY_AREA* Result;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -103,18 +103,18 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
|
|
||||||
Base = NULL;
|
Base = NULL;
|
||||||
Status = MmCreateMemoryArea(NULL,
|
Status = MmCreateMemoryArea(NULL,
|
||||||
MmGetKernelAddressSpace(),
|
MmGetKernelAddressSpace(),
|
||||||
MEMORY_AREA_MDL_MAPPING,
|
MEMORY_AREA_MDL_MAPPING,
|
||||||
&Base,
|
&Base,
|
||||||
Mdl->ByteCount + Mdl->ByteOffset,
|
Mdl->ByteCount + Mdl->ByteOffset,
|
||||||
0,
|
PAGE_READWRITE,
|
||||||
&Result,
|
&Result,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
return(STATUS_SUCCESS);
|
return(NULL);
|
||||||
}
|
}
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||||
|
|
||||||
|
@ -122,8 +122,8 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
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++)
|
||||||
{
|
{
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)((ULONG)Base+(i*PAGESIZE)),
|
(PVOID)((ULONG_PTR) Base+(i*PAGESIZE)),
|
||||||
PAGE_READWRITE,
|
Result->Attributes,
|
||||||
MdlPages[i],
|
MdlPages[i],
|
||||||
TRUE);
|
TRUE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -171,15 +171,16 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmBuildMdlFromPages(PMDL Mdl, PULONG Pages)
|
MmBuildMdlFromPages(IN PMDL Mdl,
|
||||||
|
IN PULONG_PTR Pages)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PULONG MdlPages;
|
PULONG_PTR MdlPages;
|
||||||
|
|
||||||
Mdl->MdlFlags = Mdl->MdlFlags |
|
Mdl->MdlFlags = Mdl->MdlFlags |
|
||||||
(MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
|
(MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
|
||||||
|
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
MdlPages = (PULONG_PTR) (Mdl + 1);
|
||||||
|
|
||||||
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++)
|
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++)
|
||||||
{
|
{
|
||||||
|
@ -251,15 +252,15 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
||||||
{
|
{
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
MmUnlockPage((PVOID)MdlPages[j]);
|
MmUnlockPage((ULONG_PTR) MdlPages[j]);
|
||||||
MmDereferencePage((PVOID)MdlPages[j]);
|
MmDereferencePage((ULONG_PTR) MdlPages[j]);
|
||||||
}
|
}
|
||||||
ExRaiseStatus(Status);
|
ExRaiseStatus(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
if ((Operation == IoWriteAccess || Operation == IoModifyAccess) &&
|
if ((Operation == IoWriteAccess || Operation == IoModifyAccess) &&
|
||||||
(!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE)))
|
(!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE)))
|
||||||
|
@ -269,14 +270,14 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
||||||
{
|
{
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
MmUnlockPage((PVOID)MdlPages[j]);
|
MmUnlockPage((ULONG_PTR) MdlPages[j]);
|
||||||
MmDereferencePage((PVOID)MdlPages[j]);
|
MmDereferencePage((ULONG_PTR) MdlPages[j]);
|
||||||
}
|
}
|
||||||
ExRaiseStatus(Status);
|
ExRaiseStatus(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MdlPages[i] = MmGetPhysicalAddressForProcess(NULL, Address);
|
MdlPages[i] = MmGetPhysicalAddressForProcess(NULL, Address);
|
||||||
MmReferencePage((PVOID)MdlPages[i]);
|
MmReferencePage((ULONG_PTR) MdlPages[i]);
|
||||||
}
|
}
|
||||||
MmUnlockAddressSpace(&Mdl->Process->AddressSpace);
|
MmUnlockAddressSpace(&Mdl->Process->AddressSpace);
|
||||||
if (Mdl->Process != CurrentProcess)
|
if (Mdl->Process != CurrentProcess)
|
||||||
|
@ -370,12 +371,3 @@ MmMapMemoryDumpMdl (PVOID Unknown0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* 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: mm.c,v 1.54 2002/01/23 23:39:26 chorns Exp $
|
/* $Id: mm.c,v 1.55 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -48,6 +48,45 @@ extern PVOID MmSharedDataPagePhysicalAddress;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DbgMmDumpProtection(IN ULONG Value)
|
||||||
|
{
|
||||||
|
if (Value & PAGE_NOACCESS)
|
||||||
|
DbgPrint("No access\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_GUARD)
|
||||||
|
DbgPrint("Guard\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_READWRITE)
|
||||||
|
DbgPrint("Read/Write\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_EXECUTE_READWRITE)
|
||||||
|
DbgPrint("Execute/Read/Write\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_READONLY)
|
||||||
|
DbgPrint("Read only\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_EXECUTE)
|
||||||
|
DbgPrint("Execute\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_EXECUTE_READ)
|
||||||
|
DbgPrint("Execute/Read\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_SYSTEM)
|
||||||
|
DbgPrint("System\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_NOCACHE)
|
||||||
|
DbgPrint("No cache\n");
|
||||||
|
|
||||||
|
if (Value & PAGE_WRITETHROUGH)
|
||||||
|
DbgPrint("No cache\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -245,7 +284,7 @@ NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode,
|
||||||
NTSTATUS MmCommitPagedPoolAddress(PVOID Address)
|
NTSTATUS MmCommitPagedPoolAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PVOID AllocatedPage;
|
ULONG_PTR AllocatedPage;
|
||||||
Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage);
|
Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mminit.c,v 1.31 2002/04/26 13:11:55 ekohl Exp $
|
/* $Id: mminit.c,v 1.32 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -25,11 +25,6 @@
|
||||||
|
|
||||||
/* GLOBALS *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
/*
|
|
||||||
* Size of extended memory (kb) (fixed for now)
|
|
||||||
*/
|
|
||||||
#define EXTENDED_MEMORY_SIZE (3*1024*1024)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compiler defined symbols
|
* Compiler defined symbols
|
||||||
*/
|
*/
|
||||||
|
@ -48,7 +43,9 @@ static MEMORY_AREA* kernel_pool_desc = NULL;
|
||||||
static MEMORY_AREA* kernel_shared_data_desc = NULL;
|
static MEMORY_AREA* kernel_shared_data_desc = NULL;
|
||||||
static MEMORY_AREA* MiPagedPoolDescriptor = NULL;
|
static MEMORY_AREA* MiPagedPoolDescriptor = NULL;
|
||||||
|
|
||||||
PVOID MmSharedDataPagePhysicalAddress = NULL;
|
ULONG_PTR MmSharedDataPagePhysicalAddress = 0;
|
||||||
|
|
||||||
|
BOOLEAN MiInitialized = FALSE;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
@ -62,18 +59,14 @@ MM_SYSTEM_SIZE STDCALL MmQuerySystemSize(VOID)
|
||||||
return(MmSystemSize);
|
return(MmSystemSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MiShutdownMemoryManager(VOID)
|
VOID
|
||||||
|
MiShutdownMemoryManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmInitVirtualMemory(ULONG LastKernelAddress,
|
VOID
|
||||||
ULONG KernelLength)
|
MmInitVirtualMemory(IN ULONG LastKernelAddress,
|
||||||
/*
|
IN ULONG KernelLength)
|
||||||
* FUNCTION: Intialize the memory areas list
|
|
||||||
* ARGUMENTS:
|
|
||||||
* bp = Pointer to the boot parameters
|
|
||||||
* kernel_len = Length of the kernel
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
@ -86,7 +79,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
|
||||||
LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
|
LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
|
||||||
|
|
||||||
MmInitMemoryAreas();
|
MmInitMemoryAreas();
|
||||||
ExInitNonPagedPool(LastKernelAddress + PAGESIZE);
|
ExInitNonPagedPool((PVOID) (LastKernelAddress + PAGESIZE));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the system area descriptor list
|
* Setup the system area descriptor list
|
||||||
|
@ -183,7 +176,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)KI_USER_SHARED_DATA,
|
(PVOID)KI_USER_SHARED_DATA,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)MmSharedDataPagePhysicalAddress,
|
MmSharedDataPagePhysicalAddress,
|
||||||
TRUE);
|
TRUE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -198,6 +191,9 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
|
||||||
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
|
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called at DISPATCH_LEVEL
|
||||||
|
*/
|
||||||
VOID MmInit1(ULONG FirstKrnlPhysAddr,
|
VOID MmInit1(ULONG FirstKrnlPhysAddr,
|
||||||
ULONG LastKrnlPhysAddr,
|
ULONG LastKrnlPhysAddr,
|
||||||
ULONG LastKernelAddress,
|
ULONG LastKernelAddress,
|
||||||
|
@ -293,6 +289,7 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
|
||||||
#ifdef BIOS_MEM_FIX
|
#ifdef BIOS_MEM_FIX
|
||||||
MmStats.NrTotalPages += 16;
|
MmStats.NrTotalPages += 16;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGESIZE) / 1024);
|
DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGESIZE) / 1024);
|
||||||
|
|
||||||
LastKernelAddress = (ULONG)MmInitializePageList(
|
LastKernelAddress = (ULONG)MmInitializePageList(
|
||||||
|
@ -338,20 +335,28 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
|
||||||
* Intialize memory areas
|
* Intialize memory areas
|
||||||
*/
|
*/
|
||||||
MmInitVirtualMemory(LastKernelAddress, kernel_len);
|
MmInitVirtualMemory(LastKernelAddress, kernel_len);
|
||||||
|
|
||||||
|
MiInitialized = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called at DISPATCH_LEVEL
|
||||||
|
*/
|
||||||
VOID MmInit2(VOID)
|
VOID MmInit2(VOID)
|
||||||
{
|
{
|
||||||
MmInitSectionImplementation();
|
MmInitSectionImplementation();
|
||||||
MmInitPagingFile();
|
MmInitPagingFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called at PASSIVE_LEVEL
|
||||||
|
*/
|
||||||
VOID MmInit3(VOID)
|
VOID MmInit3(VOID)
|
||||||
{
|
{
|
||||||
MmInitPagerThread();
|
MmCreatePhysicalMemorySection();
|
||||||
MmCreatePhysicalMemorySection();
|
MmInitializeRmapList();
|
||||||
MmInitializeRmapList();
|
MmInitPagerThread();
|
||||||
|
|
||||||
/* FIXME: Read parameters from memory */
|
/* FIXME: Read parameters from memory */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: ncache.c,v 1.15 2002/01/01 00:21:56 dwelch Exp $
|
/* $Id: ncache.c,v 1.16 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -73,7 +73,7 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
|
||||||
PAGE_WRITETHROUGH;
|
PAGE_WRITETHROUGH;
|
||||||
for (i = 0; i <= (NumberOfBytes / PAGESIZE); i++)
|
for (i = 0; i <= (NumberOfBytes / PAGESIZE); i++)
|
||||||
{
|
{
|
||||||
PVOID NPage;
|
ULONG_PTR NPage;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage);
|
||||||
MmCreateVirtualMapping (NULL,
|
MmCreateVirtualMapping (NULL,
|
||||||
|
@ -85,14 +85,22 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
|
||||||
return ((PVOID)Result);
|
return ((PVOID)Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STATIC
|
VOID
|
||||||
MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
MmFreeNonCachedPage(IN BOOLEAN Before,
|
||||||
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
IN PVOID Context,
|
||||||
|
IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN SWAPENTRY SwapEntry,
|
||||||
|
IN BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
if (!Before)
|
||||||
if (PhysAddr != 0)
|
|
||||||
{
|
{
|
||||||
MmDereferencePage((PVOID)PhysAddr);
|
assert(SwapEntry == 0);
|
||||||
|
if (PhysicalAddress != 0)
|
||||||
|
{
|
||||||
|
MmDereferencePage(PhysicalAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: npool.c,v 1.55 2002/01/01 05:09:50 dwelch Exp $
|
/* $Id: npool.c,v 1.56 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -78,7 +78,7 @@ ExFreeWholePageBlock(PVOID Addr);
|
||||||
/*
|
/*
|
||||||
* Memory managment initalized symbol for the base of the pool
|
* Memory managment initalized symbol for the base of the pool
|
||||||
*/
|
*/
|
||||||
static unsigned int kernel_pool_base = 0;
|
static PVOID kernel_pool_base = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Head of the list of free blocks
|
* Head of the list of free blocks
|
||||||
|
@ -222,7 +222,7 @@ MiAddToTagHashTable(BLOCK_HDR* block)
|
||||||
#endif /* TAG_STATISTICS_TRACKING */
|
#endif /* TAG_STATISTICS_TRACKING */
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ExInitNonPagedPool(ULONG BaseAddress)
|
ExInitNonPagedPool(IN PVOID BaseAddress)
|
||||||
{
|
{
|
||||||
kernel_pool_base = BaseAddress;
|
kernel_pool_base = BaseAddress;
|
||||||
KeInitializeSpinLock(&MmNpoolLock);
|
KeInitializeSpinLock(&MmNpoolLock);
|
||||||
|
@ -390,13 +390,13 @@ static void validate_free_list(void)
|
||||||
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
|
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base_addr < (kernel_pool_base) ||
|
if (base_addr < (ULONG_PTR) (kernel_pool_base) ||
|
||||||
(base_addr+current->Size) > (kernel_pool_base)+NONPAGED_POOL_SIZE)
|
(base_addr+current->Size) > (ULONG_PTR) (kernel_pool_base)+NONPAGED_POOL_SIZE)
|
||||||
{
|
{
|
||||||
DbgPrint("Block %x found outside pool area\n",current);
|
DbgPrint("Block %x found outside pool area\n",current);
|
||||||
DbgPrint("Size %d\n",current->Size);
|
DbgPrint("Size %d\n",current->Size);
|
||||||
DbgPrint("Limits are %x %x\n",kernel_pool_base,
|
DbgPrint("Limits are %x %x\n", kernel_pool_base,
|
||||||
kernel_pool_base+NONPAGED_POOL_SIZE);
|
(ULONG_PTR) kernel_pool_base + NONPAGED_POOL_SIZE);
|
||||||
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
|
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
|
||||||
}
|
}
|
||||||
blocks_seen++;
|
blocks_seen++;
|
||||||
|
@ -442,9 +442,9 @@ static void validate_used_list(void)
|
||||||
current);
|
current);
|
||||||
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
|
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
|
||||||
}
|
}
|
||||||
if (base_addr < (kernel_pool_base) ||
|
if (base_addr < (ULONG_PTR) (kernel_pool_base) ||
|
||||||
(base_addr+current->Size) >
|
(base_addr+current->Size) >
|
||||||
(kernel_pool_base)+NONPAGED_POOL_SIZE)
|
(ULONG_PTR) (kernel_pool_base) + NONPAGED_POOL_SIZE)
|
||||||
{
|
{
|
||||||
DbgPrint("Block %x found outside pool area\n",current);
|
DbgPrint("Block %x found outside pool area\n",current);
|
||||||
for(;;);
|
for(;;);
|
||||||
|
@ -567,8 +567,8 @@ free_pages(BLOCK_HDR* blk)
|
||||||
ULONG end;
|
ULONG end;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
start = (ULONG)blk;
|
start = (ULONG_PTR) blk;
|
||||||
end = (ULONG)blk + sizeof(BLOCK_HDR) + blk->Size;
|
end = (ULONG_PTR) blk + sizeof(BLOCK_HDR) + blk->Size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the block doesn't contain a whole page then there is nothing to do
|
* If the block doesn't contain a whole page then there is nothing to do
|
||||||
|
@ -699,14 +699,15 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
start = (ULONG)MiAllocNonPagedPoolRegion(nr_pages);
|
start = (ULONG_PTR) MiAllocNonPagedPoolRegion(nr_pages);
|
||||||
|
|
||||||
DPRINT("growing heap for block size %d, ",size);
|
DPRINT("growing heap for block size %d, ",size);
|
||||||
DPRINT("start %x\n",start);
|
DPRINT("start %x\n",start);
|
||||||
|
|
||||||
for (i=0;i<nr_pages;i++)
|
for (i=0;i<nr_pages;i++)
|
||||||
{
|
{
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
|
|
||||||
/* FIXME: Check whether we can really wait here. */
|
/* FIXME: Check whether we can really wait here. */
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -717,7 +718,7 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)(start + (i*PAGESIZE)),
|
(PVOID)(start + (i*PAGESIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
(ULONG)Page,
|
Page,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -853,9 +854,9 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("freeing block %x\n",blk);
|
DPRINT("freeing block %x\n",block);
|
||||||
|
|
||||||
POOL_TRACE("ExFreePool(block %x), size %d, caller %x\n",block,blk->size,
|
POOL_TRACE("ExFreePool(block %x), size %d, caller %x\n",block,block->size,
|
||||||
((PULONG)&block)[-1]);
|
((PULONG)&block)[-1]);
|
||||||
|
|
||||||
KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
|
KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
|
||||||
|
@ -1007,7 +1008,7 @@ PVOID STDCALL
|
||||||
ExAllocateWholePageBlock(ULONG UserSize)
|
ExAllocateWholePageBlock(ULONG UserSize)
|
||||||
{
|
{
|
||||||
PVOID Address;
|
PVOID Address;
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
ULONG NrPages;
|
ULONG NrPages;
|
||||||
|
@ -1020,19 +1021,19 @@ ExAllocateWholePageBlock(ULONG UserSize)
|
||||||
for (i = 0; i < NrPages; i++)
|
for (i = 0; i < NrPages; i++)
|
||||||
{
|
{
|
||||||
Page = MmAllocPage(MC_NPPOOL, 0);
|
Page = MmAllocPage(MC_NPPOOL, 0);
|
||||||
if (Page == NULL)
|
if (Page == 0)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
MmCreateVirtualMapping(NULL,
|
MmCreateVirtualMapping(NULL,
|
||||||
Address + (i * PAGESIZE),
|
Address + (i * PAGESIZE),
|
||||||
PAGE_READWRITE | PAGE_SYSTEM,
|
PAGE_READWRITE | PAGE_SYSTEM,
|
||||||
(ULONG)Page,
|
Page,
|
||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
*((PULONG)((ULONG)Address + (NrPages * PAGESIZE) - Size)) = NrPages;
|
*((PULONG)((ULONG_PTR) Address + (NrPages * PAGESIZE) - Size)) = NrPages;
|
||||||
return((PVOID)((ULONG)Address + (NrPages * PAGESIZE) - UserSize));
|
return((PVOID)((ULONG_PTR) Address + (NrPages * PAGESIZE) - UserSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
|
@ -1040,14 +1041,14 @@ ExFreeWholePageBlock(PVOID Addr)
|
||||||
{
|
{
|
||||||
ULONG NrPages;
|
ULONG NrPages;
|
||||||
|
|
||||||
if ((ULONG)Addr < kernel_pool_base ||
|
if ((ULONG_PTR)Addr < (ULONG_PTR) kernel_pool_base ||
|
||||||
(ULONG)Addr >= (kernel_pool_base + NONPAGED_POOL_SIZE))
|
(ULONG_PTR)Addr >= ((ULONG_PTR) kernel_pool_base + NONPAGED_POOL_SIZE))
|
||||||
{
|
{
|
||||||
DbgPrint("Block %x found outside pool area\n", Addr);
|
DbgPrint("Block %x found outside pool area\n", Addr);
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
NrPages = *(PULONG)((ULONG)Addr - sizeof(ULONG));
|
NrPages = *(PULONG)((ULONG_PTR) Addr - sizeof(ULONG));
|
||||||
MiFreeNonPagedPoolRegion((PVOID)PAGE_ROUND_DOWN((ULONG)Addr), NrPages, TRUE);
|
MiFreeNonPagedPoolRegion((PVOID)PAGE_ROUND_DOWN((ULONG_PTR) Addr), NrPages, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WHOLE_PAGE_ALLOCATIONS */
|
#endif /* WHOLE_PAGE_ALLOCATIONS */
|
||||||
|
|
|
@ -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: pagefile.c,v 1.18 2002/03/18 16:15:08 ekohl Exp $
|
/* $Id: pagefile.c,v 1.19 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/pagefile.c
|
* FILE: ntoskrnl/mm/pagefile.c
|
||||||
|
@ -98,12 +98,40 @@ static BYTE MmCoreDumpHeader[PAGESIZE];
|
||||||
/*
|
/*
|
||||||
* Translate between a swap entry and a file and offset pair.
|
* Translate between a swap entry and a file and offset pair.
|
||||||
*/
|
*/
|
||||||
#define FILE_FROM_ENTRY(i) ((i) >> 24)
|
#define PTE_SWAP_FILE_MASK 0x0f000000
|
||||||
|
#define PTE_SWAP_FILE_BIT 24
|
||||||
|
#define FILE_FROM_ENTRY(i) (((i) & PTE_SWAP_FILE_MASK) >> PTE_SWAP_FILE_BIT)
|
||||||
#define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1)
|
#define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1)
|
||||||
#define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << 24) | ((j) + 1))
|
#define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << PTE_SWAP_FILE_BIT) | ((j) + 1))
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidateSwapEntry(SWAPENTRY Entry)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
ULONG off;
|
||||||
|
|
||||||
|
if (Entry != 0)
|
||||||
|
{
|
||||||
|
DPRINT("MiValidateSwapEntry(SwapEntry 0x%.08x)\n", Entry);
|
||||||
|
|
||||||
|
i = FILE_FROM_ENTRY(Entry);
|
||||||
|
|
||||||
|
assertmsg(i < MAX_PAGING_FILES,
|
||||||
|
("Bad SwapEntry (0x%.08x). Wrong paging file number (%d, 0x%.08x)\n", Entry, i, off));
|
||||||
|
|
||||||
|
off = OFFSET_FROM_ENTRY(Entry);
|
||||||
|
|
||||||
|
assertmsg(off / 32 <= PagingFileList[i]->AllocMapSize,
|
||||||
|
("Bad SwapEntry (0x%.08x). Wrong paging file offset (%d, 0x%.08x)\n", Entry, i, off));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
||||||
{
|
{
|
||||||
ULONG i, offset;
|
ULONG i, offset;
|
||||||
|
@ -134,6 +162,12 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
||||||
|
|
||||||
file_offset.QuadPart = offset * 4096;
|
file_offset.QuadPart = offset * 4096;
|
||||||
|
|
||||||
|
if (file_offset.QuadPart > PagingFileList[i]->MaximumSize.QuadPart)
|
||||||
|
{
|
||||||
|
DPRINT1("Bad swap file offset 0x%.08x\n", file_offset.u.LowPart);
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
Status = IoPageWrite(PagingFileList[i]->FileObject,
|
Status = IoPageWrite(PagingFileList[i]->FileObject,
|
||||||
Mdl,
|
Mdl,
|
||||||
&file_offset,
|
&file_offset,
|
||||||
|
@ -149,6 +183,10 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("MmReadFromSwapPage(SwapEntry 0x%.08x)\n", SwapEntry);
|
||||||
|
|
||||||
|
VALIDATE_SWAP_ENTRY(SwapEntry);
|
||||||
|
|
||||||
if (SwapEntry == 0)
|
if (SwapEntry == 0)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
|
@ -172,11 +210,18 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
||||||
|
|
||||||
file_offset.QuadPart = offset * 4096;
|
file_offset.QuadPart = offset * 4096;
|
||||||
|
|
||||||
|
if (file_offset.QuadPart > PagingFileList[i]->MaximumSize.QuadPart)
|
||||||
|
{
|
||||||
|
DPRINT1("Bad swap file offset 0x%.08x\n", file_offset.u.LowPart);
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
Status = IoPageRead(PagingFileList[i]->FileObject,
|
Status = IoPageRead(PagingFileList[i]->FileObject,
|
||||||
Mdl,
|
Mdl,
|
||||||
&file_offset,
|
&file_offset,
|
||||||
&Iosb,
|
&Iosb,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
DPRINT("MmReadFromSwapPage() Status 0x%.8X\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +313,15 @@ MmFreeSwapPage(SWAPENTRY Entry)
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
i = FILE_FROM_ENTRY(Entry);
|
i = FILE_FROM_ENTRY(Entry);
|
||||||
|
|
||||||
|
assertmsg(i < MAX_PAGING_FILES,
|
||||||
|
("Bad SwapEntry (0x%.08x). Wrong paging file number (%d, 0x%.08x)\n", Entry, i, off));
|
||||||
|
|
||||||
off = OFFSET_FROM_ENTRY(Entry);
|
off = OFFSET_FROM_ENTRY(Entry);
|
||||||
|
|
||||||
|
assertmsg(off / 32 <= PagingFileList[i]->AllocMapSize,
|
||||||
|
("Bad SwapEntry (0x%.08x). Wrong paging file offset (%d, 0x%.08x)\n", Entry, i, off));
|
||||||
|
|
||||||
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
||||||
if (PagingFileList[i] == NULL)
|
if (PagingFileList[i] == NULL)
|
||||||
{
|
{
|
||||||
|
@ -278,7 +330,6 @@ MmFreeSwapPage(SWAPENTRY Entry)
|
||||||
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
|
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
|
||||||
|
|
||||||
PagingFileList[i]->AllocMap[off / 32] &= (~(1 << (off % 32)));
|
PagingFileList[i]->AllocMap[off / 32] &= (~(1 << (off % 32)));
|
||||||
|
|
||||||
PagingFileList[i]->FreePages++;
|
PagingFileList[i]->FreePages++;
|
||||||
PagingFileList[i]->UsedPages--;
|
PagingFileList[i]->UsedPages--;
|
||||||
|
|
||||||
|
@ -410,6 +461,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
SL_OPEN_PAGING_FILE);
|
SL_OPEN_PAGING_FILE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("Failed to open swap file (Status 0x%.08x)\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,6 +478,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("Failed to write to swap file (Status 0x%.08x)\n", Status);
|
||||||
NtClose(FileHandle);
|
NtClose(FileHandle);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
@ -439,6 +492,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("Failed to reference swap file (Status 0x%.08x)\n", Status);
|
||||||
NtClose(FileHandle);
|
NtClose(FileHandle);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
@ -484,15 +538,10 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
MiPagingFileCount++;
|
MiPagingFileCount++;
|
||||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||||
|
|
||||||
|
DPRINT("Successfully opened swap file\n");
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: pageop.c,v 1.7 2002/02/18 18:41:23 hbirr Exp $
|
/* $Id: pageop.c,v 1.8 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -29,8 +29,27 @@ PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE] = {NULL, } ;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmReleasePageOp(PMM_PAGEOP PageOp)
|
MiValidatePageOp(IN PMM_PAGEOP PageOp)
|
||||||
|
{
|
||||||
|
if (PageOp != NULL)
|
||||||
|
{
|
||||||
|
DPRINT("MiValidatePageOp(PageOp 0x%.08x)\n", PageOp);
|
||||||
|
|
||||||
|
assertmsg(PageOp->Magic == TAG_MM_PAGEOP,
|
||||||
|
("Bad PageOp (0x%.08x). Wrong magic (0x%.08x)\n", PageOp->Magic));
|
||||||
|
|
||||||
|
assertmsg((PageOp->OpType >= MM_PAGEOP_MINIMUM) && (PageOp->OpType <= MM_PAGEOP_MAXIMUM),
|
||||||
|
("Bad PageOp (0x%.08x). Wrong type (%d)\n", PageOp->OpType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmReleasePageOp(IN PMM_PAGEOP PageOp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Release a reference to a page operation descriptor
|
* FUNCTION: Release a reference to a page operation descriptor
|
||||||
*/
|
*/
|
||||||
|
@ -38,6 +57,9 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PMM_PAGEOP PrevPageOp;
|
PMM_PAGEOP PrevPageOp;
|
||||||
|
|
||||||
|
assert(PageOp);
|
||||||
|
VALIDATE_PAGEOP(PageOp);
|
||||||
|
|
||||||
KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
|
KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
|
||||||
PageOp->ReferenceCount--;
|
PageOp->ReferenceCount--;
|
||||||
if (PageOp->ReferenceCount > 0)
|
if (PageOp->ReferenceCount > 0)
|
||||||
|
@ -65,24 +87,31 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
|
||||||
PrevPageOp = PrevPageOp->Next;
|
PrevPageOp = PrevPageOp->Next;
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
|
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
|
||||||
|
CPRINT("PageOp (0x%.08x) not found\n", PageOp);
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PMM_PAGEOP
|
PMM_PAGEOP
|
||||||
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
MmGetPageOp(IN PMEMORY_AREA MArea,
|
||||||
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType)
|
IN ULONG Pid,
|
||||||
/*
|
IN PVOID Address,
|
||||||
* FUNCTION: Get a page operation descriptor corresponding to
|
IN PMM_SECTION_SEGMENT Segment,
|
||||||
* the memory area and either the segment, offset pair or the
|
IN ULONG Offset,
|
||||||
* pid, address pair.
|
IN ULONG OpType)
|
||||||
*/
|
/*
|
||||||
|
* FUNCTION: Get a page operation descriptor corresponding to
|
||||||
|
* the memory area and either the segment, offset pair or the
|
||||||
|
* pid, address pair. Create a new pageop if one does not exist.
|
||||||
|
* FIXME: Make Offset 64-bit
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
ULONG Hash;
|
ULONG Hash;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PMM_PAGEOP PageOp;
|
PMM_PAGEOP PageOp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calcuate the hash value for pageop structure
|
* Calculate the hash value for pageop structure
|
||||||
*/
|
*/
|
||||||
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
||||||
{
|
{
|
||||||
|
@ -90,6 +119,9 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
assertmsg(((ULONG_PTR)Address % PAGESIZE) == 0,
|
||||||
|
("Address must be page aligned (0x%.08x)\n", Address));
|
||||||
|
|
||||||
Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGESIZE));
|
Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGESIZE));
|
||||||
}
|
}
|
||||||
Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
|
Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
|
||||||
|
@ -127,6 +159,8 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
*/
|
*/
|
||||||
if (PageOp != NULL)
|
if (PageOp != NULL)
|
||||||
{
|
{
|
||||||
|
VALIDATE_PAGEOP(PageOp);
|
||||||
|
|
||||||
PageOp->ReferenceCount++;
|
PageOp->ReferenceCount++;
|
||||||
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
|
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
|
||||||
return(PageOp);
|
return(PageOp);
|
||||||
|
@ -143,6 +177,8 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SET_MAGIC(PageOp, TAG_MM_PAGEOP);
|
||||||
|
|
||||||
if (MArea->Type != MEMORY_AREA_SECTION_VIEW_COMMIT)
|
if (MArea->Type != MEMORY_AREA_SECTION_VIEW_COMMIT)
|
||||||
{
|
{
|
||||||
PageOp->Pid = Pid;
|
PageOp->Pid = Pid;
|
||||||
|
@ -163,14 +199,90 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
|
KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
|
||||||
MmPageOpHashTable[Hash] = PageOp;
|
MmPageOpHashTable[Hash] = PageOp;
|
||||||
|
|
||||||
|
VALIDATE_PAGEOP(PageOp);
|
||||||
|
|
||||||
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
|
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
|
||||||
return(PageOp);
|
return(PageOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PMM_PAGEOP
|
||||||
|
MmGotPageOp(IN PMEMORY_AREA MArea,
|
||||||
|
IN ULONG Pid,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN PMM_SECTION_SEGMENT Segment,
|
||||||
|
IN ULONG Offset)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Get a page operation descriptor corresponding to
|
||||||
|
* the memory area and either the segment, offset pair or the
|
||||||
|
* pid, address pair. Returns NULL if a pageop does not exist.
|
||||||
|
* FIXME: Make Offset 64-bit
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG Hash;
|
||||||
|
KIRQL oldIrql;
|
||||||
|
PMM_PAGEOP PageOp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the hash value for pageop structure
|
||||||
|
*/
|
||||||
|
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
||||||
|
{
|
||||||
|
Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assertmsg(((ULONG_PTR)Address % PAGESIZE) == 0,
|
||||||
|
("Address must be page aligned (0x%.08x)\n", Address));
|
||||||
|
|
||||||
|
Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGESIZE));
|
||||||
|
}
|
||||||
|
Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for an existing pageop structure
|
||||||
|
*/
|
||||||
|
PageOp = MmPageOpHashTable[Hash];
|
||||||
|
while (PageOp != NULL)
|
||||||
|
{
|
||||||
|
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
|
||||||
|
{
|
||||||
|
if (PageOp->Segment == Segment &&
|
||||||
|
PageOp->Offset == Offset)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (PageOp->Pid == Pid &&
|
||||||
|
PageOp->Address == Address)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageOp = PageOp->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we found an existing pageop then increment the reference count
|
||||||
|
* and return it.
|
||||||
|
*/
|
||||||
|
if (PageOp != NULL)
|
||||||
|
{
|
||||||
|
VALIDATE_PAGEOP(PageOp);
|
||||||
|
|
||||||
|
PageOp->ReferenceCount++;
|
||||||
|
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
|
||||||
|
return(PageOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Otherwise return NULL.
|
||||||
|
*/
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: ppool.c,v 1.7 2002/02/14 00:07:23 hbirr Exp $
|
/* $Id: ppool.c,v 1.8 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -75,6 +75,8 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
|
||||||
PMM_PPOOL_FREE_BLOCK_HEADER BestPreviousBlock;
|
PMM_PPOOL_FREE_BLOCK_HEADER BestPreviousBlock;
|
||||||
PVOID BlockAddress;
|
PVOID BlockAddress;
|
||||||
|
|
||||||
|
assert_irql(APC_LEVEL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't bother allocating anything for a zero-byte block.
|
* Don't bother allocating anything for a zero-byte block.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,13 +16,14 @@
|
||||||
* 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.3 2002/01/08 00:49:00 dwelch Exp $
|
/* $Id: rmap.c,v 1.4 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/rmap.c
|
* FILE: ntoskrnl/mm/rmap.c
|
||||||
* PURPOSE: kernel memory managment functions
|
* PURPOSE: kernel memory managment functions
|
||||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||||
|
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* Created 27/12/01
|
* Created 27/12/01
|
||||||
*/
|
*/
|
||||||
|
@ -43,22 +44,61 @@ typedef struct _MM_RMAP_ENTRY
|
||||||
struct _MM_RMAP_ENTRY* Next;
|
struct _MM_RMAP_ENTRY* Next;
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
PVOID Address;
|
PVOID Address;
|
||||||
|
ULONG ReferenceCount;
|
||||||
} MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
|
} MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
static FAST_MUTEX RmapListLock;
|
static FAST_MUTEX MiRmapListLock;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiValidateRmapList(struct _MM_RMAP_ENTRY* RmapList)
|
||||||
|
{
|
||||||
|
if (RmapList != NULL)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY CurrentEntry = RmapList;
|
||||||
|
|
||||||
|
while (CurrentEntry != NULL)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY Entry = RmapList;
|
||||||
|
ULONG Count = 0;
|
||||||
|
|
||||||
|
assertmsg(RmapList->ReferenceCount >= 0, ("Bad reference count %d for rmap entry\n",
|
||||||
|
RmapList->ReferenceCount));
|
||||||
|
|
||||||
|
while (Entry != NULL)
|
||||||
|
{
|
||||||
|
if (Entry->Process == CurrentEntry->Process)
|
||||||
|
{
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
Entry = Entry->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertmsg(Count == 1, ("%d rmap entries for process 0x%.08x\n",
|
||||||
|
Count, CurrentEntry->Process));
|
||||||
|
|
||||||
|
CurrentEntry = CurrentEntry->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBG */
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmInitializeRmapList(VOID)
|
MmInitializeRmapList(VOID)
|
||||||
{
|
{
|
||||||
ExInitializeFastMutex(&RmapListLock);
|
ExInitializeFastMutex(&MiRmapListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmPageOutPhysicalAddress(PVOID PhysicalAddress)
|
MmPageOutPhysicalAddress(ULONG_PTR PhysicalAddress)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY entry;
|
PMM_RMAP_ENTRY entry;
|
||||||
PMEMORY_AREA MemoryArea;
|
PMEMORY_AREA MemoryArea;
|
||||||
|
@ -69,11 +109,11 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
entry = MmGetRmapListHeadPage(PhysicalAddress);
|
entry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
{
|
{
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
Process = entry->Process;
|
Process = entry->Process;
|
||||||
|
@ -107,7 +147,7 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
|
||||||
{
|
{
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
MmUnlockAddressSpace(&Process->AddressSpace);
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +155,7 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
|
||||||
* Release locks now we have a page op.
|
* Release locks now we have a page op.
|
||||||
*/
|
*/
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
MmUnlockAddressSpace(&Process->AddressSpace);
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the actual page out work.
|
* Do the actual page out work.
|
||||||
|
@ -131,7 +171,7 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
|
||||||
{
|
{
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
MmUnlockAddressSpace(&Process->AddressSpace);
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +179,7 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
|
||||||
* Release locks now we have a page op.
|
* Release locks now we have a page op.
|
||||||
*/
|
*/
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
MmUnlockAddressSpace(&Process->AddressSpace);
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the actual page out work.
|
* Do the actual page out work.
|
||||||
|
@ -154,48 +194,324 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmInsertRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address)
|
MmReferenceRmap(IN PMM_RMAP_ENTRY RmapEntry)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY current_entry;
|
InterlockedIncrement(&RmapEntry->ReferenceCount);
|
||||||
PMM_RMAP_ENTRY new_entry;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmDereferenceRmap(IN PMM_RMAP_ENTRY RmapEntry)
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&RmapEntry->ReferenceCount);
|
||||||
|
|
||||||
|
assertmsg(RmapEntry->ReferenceCount > 0, ("Bad reference count (%d) for "
|
||||||
|
"Process (0x%.08x) Addresss (0x%.08x)\n",
|
||||||
|
RmapEntry->ReferenceCount, RmapEntry->Process, RmapEntry->Address));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiDisableAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN PBOOLEAN Modified)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY CurrentEntry;
|
||||||
|
PMM_RMAP_ENTRY NextEntry;
|
||||||
|
BOOLEAN WasDirty;
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
|
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
|
|
||||||
|
assertmsg(CurrentEntry != NULL, ("MiDisableAllRmaps: No rmaps.\n"))
|
||||||
|
|
||||||
|
*Modified = FALSE;
|
||||||
|
while (CurrentEntry != NULL)
|
||||||
|
{
|
||||||
|
NextEntry = CurrentEntry->Next;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
MmDisableVirtualMapping(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address,
|
||||||
|
&WasDirty,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (WasDirty)
|
||||||
|
{
|
||||||
|
*Modified = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiEnableAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN BOOLEAN Modified)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY CurrentEntry;
|
||||||
|
PMM_RMAP_ENTRY NextEntry;
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
|
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
|
|
||||||
|
assertmsg(CurrentEntry != NULL, ("MiEnableAllRmaps: No rmaps.\n"))
|
||||||
|
|
||||||
|
while (CurrentEntry != NULL)
|
||||||
|
{
|
||||||
|
NextEntry = CurrentEntry->Next;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
MmEnableVirtualMapping(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address);
|
||||||
|
|
||||||
|
if (Modified)
|
||||||
|
{
|
||||||
|
MmSetDirtyPage(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiGetDirtyAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
OUT PBOOLEAN Dirty)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY CurrentEntry;
|
||||||
|
PMM_RMAP_ENTRY NextEntry;
|
||||||
|
BOOLEAN WasDirty;
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
|
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
|
|
||||||
|
assertmsg(CurrentEntry != NULL, ("MiGetDirtyAllRmaps: No rmaps.\n"))
|
||||||
|
|
||||||
|
*Dirty = FALSE;
|
||||||
|
while (CurrentEntry != NULL)
|
||||||
|
{
|
||||||
|
NextEntry = CurrentEntry->Next;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
WasDirty = MmIsPageDirty(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address);
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
if (WasDirty)
|
||||||
|
{
|
||||||
|
*Dirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSetDirtyAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN BOOLEAN Dirty)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY CurrentEntry;
|
||||||
|
PMM_RMAP_ENTRY NextEntry;
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
|
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
|
|
||||||
|
assertmsg(CurrentEntry != NULL, ("MiSetDirtyAllRmaps: No rmaps.\n"))
|
||||||
|
|
||||||
|
while (CurrentEntry != NULL)
|
||||||
|
{
|
||||||
|
NextEntry = CurrentEntry->Next;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
if (Dirty)
|
||||||
|
{
|
||||||
|
MmSetDirtyPage(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MmSetCleanPage(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiGetPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN ULONG PageState,
|
||||||
|
OUT PBOOLEAN Result)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY CurrentEntry;
|
||||||
|
PMM_RMAP_ENTRY NextEntry;
|
||||||
|
ULONG State;
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
|
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
|
|
||||||
|
assertmsg(CurrentEntry != NULL, ("MiGetPageStateAllRmaps: No rmaps.\n"))
|
||||||
|
|
||||||
|
*Result = FALSE;
|
||||||
|
while (CurrentEntry != NULL)
|
||||||
|
{
|
||||||
|
NextEntry = CurrentEntry->Next;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
State = MiPageState(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address,
|
||||||
|
PageState);
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
if (State)
|
||||||
|
{
|
||||||
|
*Result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiClearPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN ULONG PageState)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY CurrentEntry;
|
||||||
|
PMM_RMAP_ENTRY NextEntry;
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
|
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
|
|
||||||
|
assertmsg(CurrentEntry != NULL, ("MiClearPageStateAllRmaps: No rmaps.\n"))
|
||||||
|
|
||||||
|
while (CurrentEntry != NULL)
|
||||||
|
{
|
||||||
|
NextEntry = CurrentEntry->Next;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
MiClearPageState(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address,
|
||||||
|
PageState);
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiSetPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN ULONG PageState)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY CurrentEntry;
|
||||||
|
PMM_RMAP_ENTRY NextEntry;
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
|
|
||||||
|
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
|
|
||||||
|
assertmsg(CurrentEntry != NULL, ("MiSetPageStateAllRmaps: No rmaps.\n"))
|
||||||
|
|
||||||
|
while (CurrentEntry != NULL)
|
||||||
|
{
|
||||||
|
NextEntry = CurrentEntry->Next;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
MiSetPageState(CurrentEntry->Process,
|
||||||
|
CurrentEntry->Address,
|
||||||
|
PageState);
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
|
||||||
|
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmInsertRmap(ULONG_PTR PhysicalAddress, PEPROCESS Process, PVOID Address)
|
||||||
|
{
|
||||||
|
PMM_RMAP_ENTRY Current;
|
||||||
|
PMM_RMAP_ENTRY New;
|
||||||
|
|
||||||
Address = (PVOID)PAGE_ROUND_DOWN(Address);
|
Address = (PVOID)PAGE_ROUND_DOWN(Address);
|
||||||
|
|
||||||
new_entry = ExAllocatePool(NonPagedPool, sizeof(MM_RMAP_ENTRY));
|
New = ExAllocatePool(NonPagedPool, sizeof(MM_RMAP_ENTRY));
|
||||||
if (new_entry == NULL)
|
assert(New);
|
||||||
{
|
New->ReferenceCount = 1;
|
||||||
KeBugCheck(0);
|
New->Address = Address;
|
||||||
}
|
New->Process = Process;
|
||||||
new_entry->Address = Address;
|
|
||||||
new_entry->Process = Process;
|
|
||||||
|
|
||||||
if (MmGetPhysicalAddressForProcess(Process, Address) !=
|
if (MmGetPhysicalAddressForProcess(Process, Address) !=
|
||||||
(ULONG)PhysicalAddress)
|
(ULONG_PTR)PhysicalAddress)
|
||||||
{
|
{
|
||||||
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
|
DPRINT("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
|
||||||
"address 0x%.8X\n", Process->UniqueProcessId, Address,
|
"address 0x%.8X\n", Process->UniqueProcessId, Address,
|
||||||
MmGetPhysicalAddressForProcess(Process, Address),
|
MmGetPhysicalAddressForProcess(Process, Address),
|
||||||
PhysicalAddress)
|
PhysicalAddress)
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
Current = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
new_entry->Next = current_entry;
|
New->Next = Current;
|
||||||
MmSetRmapListHeadPage(PhysicalAddress, new_entry);
|
MmSetRmapListHeadPage(PhysicalAddress, New);
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
MmSetRmapCallback(PhysicalAddress, NULL, NULL);
|
||||||
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeleteAllRmaps(PVOID PhysicalAddress, PVOID Context,
|
MmDeleteAllRmaps(ULONG_PTR PhysicalAddress, PVOID Context,
|
||||||
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
|
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
|
||||||
PVOID Address))
|
PVOID Address))
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY current_entry;
|
PMM_RMAP_ENTRY current_entry;
|
||||||
PMM_RMAP_ENTRY previous_entry;
|
PMM_RMAP_ENTRY previous_entry;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
if (current_entry == NULL)
|
if (current_entry == NULL)
|
||||||
{
|
{
|
||||||
|
@ -214,38 +530,47 @@ MmDeleteAllRmaps(PVOID PhysicalAddress, PVOID Context,
|
||||||
ExFreePool(previous_entry);
|
ExFreePool(previous_entry);
|
||||||
}
|
}
|
||||||
MmSetRmapListHeadPage(PhysicalAddress, NULL);
|
MmSetRmapListHeadPage(PhysicalAddress, NULL);
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeleteRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address)
|
MmDeleteRmap(IN ULONG_PTR PhysicalAddress,
|
||||||
|
IN PEPROCESS Process,
|
||||||
|
IN PVOID Address)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY current_entry, previous_entry;
|
PMM_RMAP_ENTRY Current;
|
||||||
|
PMM_RMAP_ENTRY Previous;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&MiRmapListLock);
|
||||||
previous_entry = NULL;
|
Previous = NULL;
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
Current = MmGetRmapListHeadPage(PhysicalAddress);
|
||||||
while (current_entry != NULL)
|
while (Current != NULL)
|
||||||
{
|
{
|
||||||
if (current_entry->Process == Process &&
|
if (Current->Process == Process && Current->Address == Address)
|
||||||
current_entry->Address == Address)
|
{
|
||||||
{
|
Current->ReferenceCount--;
|
||||||
if (previous_entry == NULL)
|
assertmsg(Current->ReferenceCount == 0, ("Rmap has outstanding references (%d) for Page (0x%.08x) "
|
||||||
{
|
"Process (0x%.08x) Addresss (0x%.08x)\n",
|
||||||
MmSetRmapListHeadPage(PhysicalAddress, current_entry->Next);
|
Current->ReferenceCount, PhysicalAddress, Process, Address));
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
|
||||||
ExFreePool(current_entry);
|
if (Previous == NULL)
|
||||||
}
|
{
|
||||||
else
|
MmSetRmapListHeadPage(PhysicalAddress, Current->Next);
|
||||||
{
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
previous_entry->Next = current_entry->Next;
|
ExFreePool(Current);
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
}
|
||||||
ExFreePool(current_entry);
|
else
|
||||||
}
|
{
|
||||||
return;
|
Previous->Next = Current->Next;
|
||||||
}
|
ExReleaseFastMutex(&MiRmapListLock);
|
||||||
previous_entry = current_entry;
|
ExFreePool(Current);
|
||||||
current_entry = current_entry->Next;
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Previous = Current;
|
||||||
|
Current = Current->Next;
|
||||||
}
|
}
|
||||||
KeBugCheck(0);
|
assertmsg(FALSE, ("No rmap entry for Page (0x%.08x) Process (0x%.08x) Addresss (0x%.08x)\n",
|
||||||
|
PhysicalAddress, Process, Address));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.80 2002/05/07 22:53:05 hbirr Exp $
|
/* $Id: section.c,v 1.81 2002/05/13 18:10:40 chorns Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/section.c
|
* FILE: ntoskrnl/mm/section.c
|
||||||
|
@ -306,7 +306,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MiReadPage(PMEMORY_AREA MemoryArea,
|
MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
PLARGE_INTEGER Offset,
|
PLARGE_INTEGER Offset,
|
||||||
PVOID* Page)
|
PULONG_PTR Page)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Read a page for a section backed memory area.
|
* FUNCTION: Read a page for a section backed memory area.
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
|
@ -381,7 +381,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
*/
|
*/
|
||||||
Addr = MmGetPhysicalAddress(BaseAddress +
|
Addr = MmGetPhysicalAddress(BaseAddress +
|
||||||
Offset->QuadPart - BaseOffset);
|
Offset->QuadPart - BaseOffset);
|
||||||
(*Page) = (PVOID)(ULONG)Addr.QuadPart;
|
(*Page) = (ULONG_PTR)Addr.QuadPart;
|
||||||
MmReferencePage((*Page));
|
MmReferencePage((*Page));
|
||||||
|
|
||||||
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, TRUE);
|
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, TRUE);
|
||||||
|
@ -423,7 +423,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
BOOLEAN Locked)
|
BOOLEAN Locked)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG PAddress;
|
ULONG PAddress;
|
||||||
PSECTION_OBJECT Section;
|
PSECTION_OBJECT Section;
|
||||||
|
@ -442,7 +442,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -534,7 +534,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
return(STATUS_MM_RESTART_OPERATION);
|
return(STATUS_MM_RESTART_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page = (PVOID)(PAGE_FROM_SSE(Entry));
|
Page = (ULONG_PTR)(PAGE_FROM_SSE(Entry));
|
||||||
MmReferencePage(Page);
|
MmReferencePage(Page);
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset.u.LowPart);
|
MmSharePageEntrySectionSegment(Segment, Offset.u.LowPart);
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
|
@ -627,7 +627,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -655,7 +655,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -696,7 +696,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address));
|
(PVOID)PAGE_ROUND_DOWN(Address));
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -827,7 +827,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -910,7 +910,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -927,14 +927,14 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* take another reference to the page
|
* take another reference to the page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Page = (PVOID)PAGE_FROM_SSE(Entry);
|
Page = (ULONG_PTR)PAGE_FROM_SSE(Entry);
|
||||||
MmReferencePage(Page);
|
MmReferencePage(Page);
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
|
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
Attributes,
|
Attributes,
|
||||||
(ULONG)Page,
|
Page,
|
||||||
FALSE);
|
FALSE);
|
||||||
MmInsertRmap(Page, PsGetCurrentProcess(),
|
MmInsertRmap(Page, PsGetCurrentProcess(),
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address));
|
(PVOID)PAGE_ROUND_DOWN(Address));
|
||||||
|
@ -945,7 +945,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -964,8 +964,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
PMM_SECTION_SEGMENT Segment;
|
PMM_SECTION_SEGMENT Segment;
|
||||||
PSECTION_OBJECT Section;
|
PSECTION_OBJECT Section;
|
||||||
ULONG OldPage;
|
ULONG_PTR OldPage;
|
||||||
PVOID NewPage;
|
ULONG_PTR NewPage;
|
||||||
PVOID NewAddress;
|
PVOID NewAddress;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG PAddress;
|
ULONG PAddress;
|
||||||
|
@ -1106,16 +1106,16 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unshare the old page.
|
* Unshare the old page.
|
||||||
*/
|
*/
|
||||||
MmUnsharePageEntrySectionSegment(Section, Segment, Offset.QuadPart, FALSE);
|
MmUnsharePageEntrySectionSegment(Section, Segment, Offset.QuadPart, FALSE);
|
||||||
MmDeleteRmap((PVOID)OldPage, PsGetCurrentProcess(),
|
MmDeleteRmap(OldPage, PsGetCurrentProcess(),
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address));
|
(PVOID)PAGE_ROUND_DOWN(Address));
|
||||||
MmDereferencePage((PVOID)OldPage);
|
MmDereferencePage(OldPage);
|
||||||
|
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -1127,15 +1127,15 @@ VOID
|
||||||
MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
|
MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
|
MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
|
||||||
BOOL WasDirty;
|
BOOLEAN WasDirty;
|
||||||
PVOID PhysicalAddress;
|
ULONG_PTR PhysicalAddress;
|
||||||
|
|
||||||
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
|
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
|
||||||
MmDeleteVirtualMapping(Process,
|
MmDeleteVirtualMapping(Process,
|
||||||
Address,
|
Address,
|
||||||
FALSE,
|
FALSE,
|
||||||
&WasDirty,
|
&WasDirty,
|
||||||
(PULONG)&PhysicalAddress);
|
(PULONG_PTR)&PhysicalAddress);
|
||||||
if (WasDirty)
|
if (WasDirty)
|
||||||
{
|
{
|
||||||
PageOutContext->WasDirty = TRUE;
|
PageOutContext->WasDirty = TRUE;
|
||||||
|
@ -1159,7 +1159,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
PSECTION_OBJECT Section;
|
PSECTION_OBJECT Section;
|
||||||
PMM_SECTION_SEGMENT Segment;
|
PMM_SECTION_SEGMENT Segment;
|
||||||
PVOID PhysicalAddress;
|
ULONG_PTR PhysicalAddress;
|
||||||
MM_SECTION_PAGEOUT_CONTEXT Context;
|
MM_SECTION_PAGEOUT_CONTEXT Context;
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
@ -1221,7 +1221,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
PhysicalAddress =
|
PhysicalAddress =
|
||||||
(PVOID)MmGetPhysicalAddressForProcess(AddressSpace->Process,
|
MmGetPhysicalAddressForProcess(AddressSpace->Process,
|
||||||
Address);
|
Address);
|
||||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
||||||
|
|
||||||
|
@ -1234,7 +1234,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Context.WasDirty = FALSE;
|
Context.WasDirty = FALSE;
|
||||||
if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
||||||
IS_SWAP_FROM_SSE(Entry) ||
|
IS_SWAP_FROM_SSE(Entry) ||
|
||||||
(PVOID)(PAGE_FROM_SSE(Entry)) != PhysicalAddress)
|
(ULONG_PTR)(PAGE_FROM_SSE(Entry)) != PhysicalAddress)
|
||||||
{
|
{
|
||||||
Context.Private = Private = TRUE;
|
Context.Private = Private = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1361,7 +1361,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
if (DirectMapped && !Private)
|
if (DirectMapped && !Private)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
assert(SwapEntry == 0);
|
||||||
MmDereferencePage((PVOID)PhysicalAddress);
|
MmDereferencePage(PhysicalAddress);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
|
@ -1371,7 +1371,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* If necessary, allocate an entry in the paging file for this page
|
* If necessary, allocate an entry in the paging file for this page
|
||||||
*/
|
*/
|
||||||
SwapEntry = MmGetSavedSwapEntryPage((PVOID)PhysicalAddress);
|
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
||||||
if (SwapEntry == 0)
|
if (SwapEntry == 0)
|
||||||
{
|
{
|
||||||
SwapEntry = MmAllocSwapPage();
|
SwapEntry = MmAllocSwapPage();
|
||||||
|
@ -2557,13 +2557,21 @@ NtMapViewOfSection(HANDLE SectionHandle,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STATIC
|
VOID
|
||||||
MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
MmFreeSectionPage (IN BOOLEAN Before,
|
||||||
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
IN PVOID Context,
|
||||||
|
IN PMEMORY_AREA MemoryArea,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN ULONG_PTR PhysAddr,
|
||||||
|
IN SWAPENTRY SwapEntry,
|
||||||
|
IN BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
PMEMORY_AREA MArea;
|
PMEMORY_AREA MArea;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
|
|
||||||
|
if (Before)
|
||||||
|
return;
|
||||||
|
|
||||||
MArea = (PMEMORY_AREA)Context;
|
MArea = (PMEMORY_AREA)Context;
|
||||||
|
|
||||||
if (SwapEntry != 0)
|
if (SwapEntry != 0)
|
||||||
|
@ -2589,8 +2597,8 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG P
|
||||||
/*
|
/*
|
||||||
* Just dereference private pages
|
* Just dereference private pages
|
||||||
*/
|
*/
|
||||||
MmDeleteRmap((PVOID)PhysAddr, MArea->Process, Address);
|
MmDeleteRmap(PhysAddr, MArea->Process, Address);
|
||||||
MmDereferencePage((PVOID)PhysAddr);
|
MmDereferencePage(PhysAddr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2598,8 +2606,8 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG P
|
||||||
MArea->Data.SectionData.Segment,
|
MArea->Data.SectionData.Segment,
|
||||||
Offset,
|
Offset,
|
||||||
Dirty);
|
Dirty);
|
||||||
MmDeleteRmap((PVOID)PhysAddr, MArea->Process, Address);
|
MmDeleteRmap(PhysAddr, MArea->Process, Address);
|
||||||
MmDereferencePage((PVOID)PhysAddr);
|
MmDereferencePage(PhysAddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2856,7 +2864,7 @@ 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++)
|
||||||
{
|
{
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
|
@ -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: slab.c,v 1.2 2002/01/03 22:52:29 dwelch Exp $
|
/* $Id: slab.c,v 1.3 2002/05/13 18:10:41 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -103,7 +103,7 @@ PSLAB_CACHE_PAGE
|
||||||
ExGrowSlabCache(PSLAB_CACHE Slab)
|
ExGrowSlabCache(PSLAB_CACHE Slab)
|
||||||
{
|
{
|
||||||
PSLAB_CACHE_PAGE SlabPage;
|
PSLAB_CACHE_PAGE SlabPage;
|
||||||
PVOID PhysicalPage;
|
ULONG_PTR PhysicalPage;
|
||||||
PVOID Page;
|
PVOID Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -116,7 +116,7 @@ ExGrowSlabCache(PSLAB_CACHE Slab)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page = ExAllocatePageWithPhysPage((ULONG)PhysicalPage);
|
Page = ExAllocatePageWithPhysPage(PhysicalPage);
|
||||||
if (Page == NULL)
|
if (Page == NULL)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
|
||||||
|
@ -299,22 +299,22 @@ ExDestroySlabCache(PSLAB_CACHE Slab)
|
||||||
while (current_entry != &Slab->PageListHead)
|
while (current_entry != &Slab->PageListHead)
|
||||||
{
|
{
|
||||||
PVOID Base;
|
PVOID Base;
|
||||||
PVOID PhysicalPage;
|
ULONG_PTR PhysicalPage;
|
||||||
|
|
||||||
current = CONTAINING_RECORD(current_entry,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
SLAB_CACHE_PAGE,
|
SLAB_CACHE_PAGE,
|
||||||
PageListEntry);
|
PageListEntry);
|
||||||
Base = (PVOID)current + sizeof(SLAB_CACHE_PAGE) - PAGESIZE;
|
Base = (PVOID)(current + sizeof(SLAB_CACHE_PAGE) - PAGESIZE);
|
||||||
if (Slab->Destructor != NULL)
|
if (Slab->Destructor != NULL)
|
||||||
{
|
{
|
||||||
for (i = 0; i < Slab->ObjectsPerPage; i++)
|
for (i = 0; i < Slab->ObjectsPerPage; i++)
|
||||||
{
|
{
|
||||||
Object = Base + (i * Slab->ObjectSize) +
|
Object = (PVOID)(Base + (i * Slab->ObjectSize) +
|
||||||
sizeof(SLAB_CACHE_BUFCTL);
|
sizeof(SLAB_CACHE_BUFCTL));
|
||||||
Slab->Destructor(Object, Slab->BaseSize);
|
Slab->Destructor(Object, Slab->BaseSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PhysicalPage = (PVOID)MmGetPhysicalAddressForProcess(NULL, Base);
|
PhysicalPage = MmGetPhysicalAddressForProcess(NULL, Base);
|
||||||
ExUnmapPage(Base);
|
ExUnmapPage(Base);
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: virtual.c,v 1.56 2002/05/07 22:36:46 hbirr Exp $
|
/* $Id: virtual.c,v 1.57 2002/05/13 18:10:41 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -101,8 +101,8 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
PMM_PAGEOP PageOp)
|
PMM_PAGEOP PageOp)
|
||||||
{
|
{
|
||||||
PVOID PhysicalAddress;
|
ULONG_PTR PhysicalAddress;
|
||||||
BOOL WasDirty;
|
BOOLEAN WasDirty;
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
@ -136,7 +136,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
* Otherwise this is read-write data
|
* Otherwise this is read-write data
|
||||||
*/
|
*/
|
||||||
MmDisableVirtualMapping(MemoryArea->Process, Address,
|
MmDisableVirtualMapping(MemoryArea->Process, Address,
|
||||||
&WasDirty, (PULONG)&PhysicalAddress);
|
&WasDirty, (PULONG_PTR)&PhysicalAddress);
|
||||||
if (PhysicalAddress == 0)
|
if (PhysicalAddress == 0)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
|
@ -160,7 +160,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* If necessary, allocate an entry in the paging file for this page
|
* If necessary, allocate an entry in the paging file for this page
|
||||||
*/
|
*/
|
||||||
SwapEntry = MmGetSavedSwapEntryPage((PVOID)PhysicalAddress);
|
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
||||||
if (SwapEntry == 0)
|
if (SwapEntry == 0)
|
||||||
{
|
{
|
||||||
SwapEntry = MmAllocSwapPage();
|
SwapEntry = MmAllocSwapPage();
|
||||||
|
@ -221,7 +221,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
* NOTES: This function is called with the address space lock held.
|
* NOTES: This function is called with the address space lock held.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PMM_SEGMENT Segment;
|
PMM_SEGMENT Segment;
|
||||||
PVOID CurrentAddress;
|
PVOID CurrentAddress;
|
||||||
|
@ -236,7 +236,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -384,7 +384,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -434,9 +434,9 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
FALSE, NULL, NULL);
|
FALSE, NULL, NULL);
|
||||||
if (PhysicalAddr.u.LowPart != 0)
|
if (PhysicalAddr.u.LowPart != 0)
|
||||||
{
|
{
|
||||||
MmDeleteRmap((PVOID)PhysicalAddr.u.LowPart, AddressSpace->Process,
|
MmDeleteRmap((ULONG_PTR)PhysicalAddr.u.LowPart, AddressSpace->Process,
|
||||||
BaseAddress + (i * PAGESIZE));
|
BaseAddress + (i * PAGESIZE));
|
||||||
MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart));
|
MmDereferencePage((ULONG_PTR)(PhysicalAddr.u.LowPart));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1048,21 +1048,24 @@ NtFlushVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
VOID
|
||||||
VOID STATIC
|
MmFreeVirtualMemoryPage (IN BOOLEAN Before,
|
||||||
MmFreeVirtualMemoryPage(PVOID Context,
|
IN PVOID Context,
|
||||||
MEMORY_AREA* MemoryArea,
|
IN PMEMORY_AREA MemoryArea,
|
||||||
PVOID Address,
|
IN PVOID Address,
|
||||||
ULONG PhysicalAddr,
|
IN ULONG_PTR PhysicalAddress,
|
||||||
SWAPENTRY SwapEntry,
|
IN SWAPENTRY SwapEntry,
|
||||||
BOOLEAN Dirty)
|
IN BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
PEPROCESS Process = (PEPROCESS)Context;
|
PEPROCESS Process = (PEPROCESS)Context;
|
||||||
|
|
||||||
if (PhysicalAddr != 0)
|
if (Before)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (PhysicalAddress != 0)
|
||||||
{
|
{
|
||||||
MmDeleteRmap((PVOID)PhysicalAddr, Process, Address);
|
MmDeleteRmap(PhysicalAddress, Process, Address);
|
||||||
MmDereferencePage((PVOID)PhysicalAddr);
|
MmDereferencePage(PhysicalAddress);
|
||||||
}
|
}
|
||||||
else if (SwapEntry != 0)
|
else if (SwapEntry != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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: wset.c,v 1.11 2001/12/31 01:53:45 dwelch Exp $
|
/* $Id: wset.c,v 1.12 2002/05/13 18:10:41 chorns Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/wset.c
|
* FILE: ntoskrnl/mm/wset.c
|
||||||
|
@ -41,14 +41,14 @@
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
|
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
|
||||||
{
|
{
|
||||||
PVOID CurrentPhysicalAddress;
|
ULONG_PTR CurrentPhysicalAddress;
|
||||||
PVOID NextPhysicalAddress;
|
ULONG_PTR NextPhysicalAddress;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
(*NrFreedPages) = 0;
|
(*NrFreedPages) = 0;
|
||||||
|
|
||||||
CurrentPhysicalAddress = MmGetLRUFirstUserPage();
|
CurrentPhysicalAddress = MmGetLRUFirstUserPage();
|
||||||
while (CurrentPhysicalAddress != NULL && Target > 0)
|
while (CurrentPhysicalAddress != 0 && Target > 0)
|
||||||
{
|
{
|
||||||
NextPhysicalAddress = MmGetLRUNextUserPage(CurrentPhysicalAddress);
|
NextPhysicalAddress = MmGetLRUNextUserPage(CurrentPhysicalAddress);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: object.c,v 1.47 2002/05/07 22:39:26 hbirr Exp $
|
/* $Id: object.c,v 1.48 2002/05/13 18:10:41 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -143,7 +143,7 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
|
||||||
Path = ObjectAttributes->ObjectName->Buffer;
|
Path = ObjectAttributes->ObjectName->Buffer;
|
||||||
|
|
||||||
if (Path[0] == 0)
|
if ((Path == NULL) && (Path[0] == 0))
|
||||||
{
|
{
|
||||||
*ReturnedObject = CurrentObject;
|
*ReturnedObject = CurrentObject;
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -155,16 +155,8 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Path)
|
|
||||||
{
|
|
||||||
RtlCreateUnicodeString (&PathString, Path);
|
RtlCreateUnicodeString (&PathString, Path);
|
||||||
current = PathString.Buffer;
|
current = PathString.Buffer;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RtlInitUnicodeString (&PathString, NULL);
|
|
||||||
current = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
RootObject = CurrentObject;
|
RootObject = CurrentObject;
|
||||||
|
|
||||||
|
@ -244,15 +236,18 @@ ObCreateObject(OUT PHANDLE Handle,
|
||||||
|
|
||||||
DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n",
|
DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n",
|
||||||
Handle, ObjectAttributes, Type);
|
Handle, ObjectAttributes, Type);
|
||||||
|
|
||||||
if (ObjectAttributes != NULL &&
|
if (ObjectAttributes != NULL &&
|
||||||
ObjectAttributes->ObjectName != NULL)
|
ObjectAttributes->ObjectName != NULL &&
|
||||||
|
ObjectAttributes->ObjectName->Buffer != NULL)
|
||||||
{
|
{
|
||||||
DPRINT("ObjectAttributes->ObjectName->Buffer %S\n",
|
DPRINT("ObjectAttributes->ObjectName->Buffer %S\n",
|
||||||
ObjectAttributes->ObjectName->Buffer);
|
ObjectAttributes->ObjectName->Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectAttributes != NULL &&
|
if (ObjectAttributes != NULL &&
|
||||||
ObjectAttributes->ObjectName != NULL)
|
ObjectAttributes->ObjectName != NULL &&
|
||||||
|
ObjectAttributes->ObjectName->Buffer != NULL)
|
||||||
{
|
{
|
||||||
Status = ObFindObject(ObjectAttributes,
|
Status = ObFindObject(ObjectAttributes,
|
||||||
&Parent,
|
&Parent,
|
||||||
|
@ -268,7 +263,6 @@ ObCreateObject(OUT PHANDLE Handle,
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&RemainingPath, NULL);
|
RtlInitUnicodeString(&RemainingPath, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlMapGenericMask(&DesiredAccess,
|
RtlMapGenericMask(&DesiredAccess,
|
||||||
Type->Mapping);
|
Type->Mapping);
|
||||||
|
|
||||||
|
@ -304,6 +298,7 @@ ObCreateObject(OUT PHANDLE Handle,
|
||||||
Parent,
|
Parent,
|
||||||
RemainingPath.Buffer,
|
RemainingPath.Buffer,
|
||||||
ObjectAttributes);
|
ObjectAttributes);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (ObjectAttached == TRUE)
|
if (ObjectAttached == TRUE)
|
||||||
|
@ -320,6 +315,7 @@ ObCreateObject(OUT PHANDLE Handle,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString( &RemainingPath );
|
RtlFreeUnicodeString( &RemainingPath );
|
||||||
|
|
||||||
*Object = HEADER_TO_BODY(Header);
|
*Object = HEADER_TO_BODY(Header);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: thread.c,v 1.90 2002/03/08 17:04:03 hbirr Exp $
|
/* $Id: thread.c,v 1.91 2002/05/13 18:10:41 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -57,6 +57,30 @@ static GENERIC_MAPPING PiThreadMapping = {THREAD_READ,
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PiSetPriorityThread(IN HANDLE ThreadHandle,
|
||||||
|
IN KPRIORITY Priority)
|
||||||
|
{
|
||||||
|
PETHREAD Thread;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
PsThreadType,
|
||||||
|
KernelMode,
|
||||||
|
(PVOID*) &Thread,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeSetPriorityThread(&Thread->Tcb, Priority);
|
||||||
|
ObReferenceObject(Thread);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
PKTHREAD STDCALL KeGetCurrentThread(VOID)
|
PKTHREAD STDCALL KeGetCurrentThread(VOID)
|
||||||
{
|
{
|
||||||
return(KeGetCurrentKPCR()->CurrentThread);
|
return(KeGetCurrentKPCR()->CurrentThread);
|
||||||
|
@ -142,23 +166,6 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem)
|
||||||
|
|
||||||
static PETHREAD PsScanThreadList (KPRIORITY Priority, ULONG Affinity)
|
static PETHREAD PsScanThreadList (KPRIORITY Priority, ULONG Affinity)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
PLIST_ENTRY current_entry;
|
|
||||||
PETHREAD current;
|
|
||||||
|
|
||||||
current_entry = RemoveHeadList(&PriorityListHead[Priority]);
|
|
||||||
if (current_entry != &PriorityListHead[Priority])
|
|
||||||
{
|
|
||||||
current = CONTAINING_RECORD(current_entry, ETHREAD,
|
|
||||||
Tcb.QueueListEntry);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(current);
|
|
||||||
#else
|
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PETHREAD current;
|
PETHREAD current;
|
||||||
|
|
||||||
|
@ -179,7 +186,6 @@ static PETHREAD PsScanThreadList (KPRIORITY Priority, ULONG Affinity)
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
return(NULL);
|
return(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -594,7 +600,7 @@ PsAllocateCallbackStack(ULONG StackSize)
|
||||||
}
|
}
|
||||||
for (i = 0; i < (StackSize / PAGESIZE); i++)
|
for (i = 0; i < (StackSize / PAGESIZE); i++)
|
||||||
{
|
{
|
||||||
PVOID Page;
|
ULONG_PTR Page;
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -603,7 +609,7 @@ PsAllocateCallbackStack(ULONG StackSize)
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
KernelStack + (i * PAGESIZE),
|
KernelStack + (i * PAGESIZE),
|
||||||
PAGE_EXECUTE_READWRITE,
|
PAGE_EXECUTE_READWRITE,
|
||||||
(ULONG)Page,
|
Page,
|
||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
return(KernelStack);
|
return(KernelStack);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mem.c,v 1.11 2001/03/16 10:58:47 dwelch Exp $
|
/* $Id: mem.c,v 1.12 2002/05/13 18:10:41 chorns Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -24,6 +24,8 @@ MmCopyToCaller(PVOID Dest, PVOID Src, ULONG NumberOfBytes)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
//assertmsg(KeGetCurrentIrql() < DISPATCH_LEVEL, ("MmCopyToCaller() called at >= DISPATCH_LEVEL\n"));
|
||||||
|
|
||||||
if (ExGetPreviousMode() == UserMode)
|
if (ExGetPreviousMode() == UserMode)
|
||||||
{
|
{
|
||||||
if ((ULONG)Dest >= KERNEL_BASE)
|
if ((ULONG)Dest >= KERNEL_BASE)
|
||||||
|
@ -45,6 +47,8 @@ MmCopyFromCaller(PVOID Dest, PVOID Src, ULONG NumberOfBytes)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
//assertmsg(KeGetCurrentIrql() < DISPATCH_LEVEL, ("MmCopyFromCaller() called at >= DISPATCH_LEVEL\n"));
|
||||||
|
|
||||||
if (ExGetPreviousMode() == UserMode)
|
if (ExGetPreviousMode() == UserMode)
|
||||||
{
|
{
|
||||||
if ((ULONG)Src >= KERNEL_BASE)
|
if ((ULONG)Src >= KERNEL_BASE)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue