mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Add 'simple' implementation of MmDbgCopyMemory to read/write virtual memory in a somewhat safe way (still no support for physical memory). Properly implement KdpCopyMemoryChunks as a wrapper around MmDbgCopyMemory and make most of the remaining unsafe copies use it instead of RtlCopyMemory. This fixes most of the remaining crashes during KD debugging as WinDbg/KD relies on the kernel support to handle bad addresses.
- Stub out the remaining missing global variables for the debugger data block -- fixes some cases of WinDbg failures and gives it a chance to handle errors instead of failing on a NULL read. Several of these variables are for functionality we don't yet implement, so I tried to put them where they are "least wrong". Everything besides the MmLoadedUserImageList variable is left unitialized -- KD should mostly be able to handle this properly. - Define correctly sized KDDEBUGGER_DATA64 for our kernel (needs to be done in a better way). svn path=/trunk/; revision=43863
This commit is contained in:
parent
c4d8068980
commit
82bd7858d1
21 changed files with 417 additions and 121 deletions
|
@ -285,7 +285,11 @@ typedef struct _KDDEBUGGER_DATA64
|
||||||
USHORT Gdt64R3CmTeb;
|
USHORT Gdt64R3CmTeb;
|
||||||
GCC_ULONG64 IopNumTriageDumpDataBlocks;
|
GCC_ULONG64 IopNumTriageDumpDataBlocks;
|
||||||
GCC_ULONG64 IopTriageDumpDataBlocks;
|
GCC_ULONG64 IopTriageDumpDataBlocks;
|
||||||
|
#if 0 // Longhorn/Vista and later
|
||||||
GCC_ULONG64 VfCrashDataBlock;
|
GCC_ULONG64 VfCrashDataBlock;
|
||||||
|
GCC_ULONG64 MmBadPagesDetected;
|
||||||
|
GCC_ULONG64 MmZeroedPageSingleBitErrorsDetected;
|
||||||
|
#endif
|
||||||
} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
|
} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1057,6 +1057,8 @@ extern GENERIC_MAPPING IopFileMapping;
|
||||||
extern POBJECT_TYPE _IoFileObjectType;
|
extern POBJECT_TYPE _IoFileObjectType;
|
||||||
extern HAL_DISPATCH _HalDispatchTable;
|
extern HAL_DISPATCH _HalDispatchTable;
|
||||||
extern LIST_ENTRY IopErrorLogListHead;
|
extern LIST_ENTRY IopErrorLogListHead;
|
||||||
|
extern ULONG IopNumTriageDumpDataBlocks;
|
||||||
|
extern PVOID IopTriageDumpDataBlocks[64];
|
||||||
|
|
||||||
//
|
//
|
||||||
// Inlined Functions
|
// Inlined Functions
|
||||||
|
|
|
@ -296,6 +296,20 @@ KdpSuspendAllBreakPoints(
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Safe memory read & write Support
|
||||||
|
//
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
KdpCopyMemoryChunks(
|
||||||
|
IN ULONG64 Address,
|
||||||
|
IN PVOID Buffer,
|
||||||
|
IN ULONG TotalSize,
|
||||||
|
IN ULONG ChunkSize,
|
||||||
|
IN ULONG Flags,
|
||||||
|
OUT PULONG ActualSize OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Architecture dependent support routines
|
// Architecture dependent support routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -18,6 +18,7 @@ extern UCHAR MmDisablePagingExecutive;
|
||||||
extern ULONG MmLowestPhysicalPage;
|
extern ULONG MmLowestPhysicalPage;
|
||||||
extern ULONG MmHighestPhysicalPage;
|
extern ULONG MmHighestPhysicalPage;
|
||||||
extern ULONG MmAvailablePages;
|
extern ULONG MmAvailablePages;
|
||||||
|
extern ULONG MmResidentAvailablePages;
|
||||||
|
|
||||||
extern PVOID MmPagedPoolBase;
|
extern PVOID MmPagedPoolBase;
|
||||||
extern ULONG MmPagedPoolSize;
|
extern ULONG MmPagedPoolSize;
|
||||||
|
@ -25,6 +26,25 @@ extern ULONG MmPagedPoolSize;
|
||||||
extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
|
extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
|
||||||
extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg;
|
extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg;
|
||||||
|
|
||||||
|
extern LIST_ENTRY MmLoadedUserImageList;
|
||||||
|
|
||||||
|
extern ULONG MmNumberOfPagingFiles;
|
||||||
|
|
||||||
|
extern PVOID MmUnloadedDrivers;
|
||||||
|
extern PVOID MmLastUnloadedDrivers;
|
||||||
|
extern PVOID MmTriageActionTaken;
|
||||||
|
extern PVOID KernelVerifier;
|
||||||
|
extern MM_DRIVER_VERIFIER_DATA MmVerifierData;
|
||||||
|
|
||||||
|
extern SIZE_T MmTotalCommitLimit;
|
||||||
|
extern SIZE_T MmTotalCommittedPages;
|
||||||
|
extern SIZE_T MmSharedCommit;
|
||||||
|
extern SIZE_T MmDriverCommit;
|
||||||
|
extern SIZE_T MmProcessCommit;
|
||||||
|
extern SIZE_T MmPagedPoolCommit;
|
||||||
|
extern SIZE_T MmPeakCommitment;
|
||||||
|
extern SIZE_T MmtotalCommitLimitMaximum;
|
||||||
|
|
||||||
struct _KTRAP_FRAME;
|
struct _KTRAP_FRAME;
|
||||||
struct _EPROCESS;
|
struct _EPROCESS;
|
||||||
struct _MM_RMAP_ENTRY;
|
struct _MM_RMAP_ENTRY;
|
||||||
|
@ -33,7 +53,7 @@ typedef ULONG SWAPENTRY;
|
||||||
typedef ULONG PFN_TYPE, *PPFN_TYPE;
|
typedef ULONG PFN_TYPE, *PPFN_TYPE;
|
||||||
|
|
||||||
//
|
//
|
||||||
//MmDbgCopyMemory Flags
|
// MmDbgCopyMemory Flags
|
||||||
//
|
//
|
||||||
#define MMDBG_COPY_WRITE 0x00000001
|
#define MMDBG_COPY_WRITE 0x00000001
|
||||||
#define MMDBG_COPY_PHYSICAL 0x00000002
|
#define MMDBG_COPY_PHYSICAL 0x00000002
|
||||||
|
@ -369,6 +389,20 @@ typedef struct _MMPFN
|
||||||
|
|
||||||
extern PMMPFN MmPfnDatabase;
|
extern PMMPFN MmPfnDatabase;
|
||||||
|
|
||||||
|
typedef struct _MMPFNLIST
|
||||||
|
{
|
||||||
|
PFN_NUMBER Total;
|
||||||
|
MMLISTS ListName;
|
||||||
|
PFN_NUMBER Flink;
|
||||||
|
PFN_NUMBER Blink;
|
||||||
|
} MMPFNLIST, *PMMPFNLIST;
|
||||||
|
|
||||||
|
extern MMPFNLIST MmZeroedPageListHead;
|
||||||
|
extern MMPFNLIST MmFreePageListHead;
|
||||||
|
extern MMPFNLIST MmStandbyPageListHead;
|
||||||
|
extern MMPFNLIST MmModifiedPageListHead;
|
||||||
|
extern MMPFNLIST MmModifiedNoWritePageListHead;
|
||||||
|
|
||||||
typedef struct _MM_PAGEOP
|
typedef struct _MM_PAGEOP
|
||||||
{
|
{
|
||||||
/* Type of operation. */
|
/* Type of operation. */
|
||||||
|
|
|
@ -39,6 +39,8 @@ LARGE_INTEGER IoWriteTransferCount = {{0, 0}};
|
||||||
ULONG IoOtherOperationCount = 0;
|
ULONG IoOtherOperationCount = 0;
|
||||||
LARGE_INTEGER IoOtherTransferCount = {{0, 0}};
|
LARGE_INTEGER IoOtherTransferCount = {{0, 0}};
|
||||||
KSPIN_LOCK IoStatisticsLock = 0;
|
KSPIN_LOCK IoStatisticsLock = 0;
|
||||||
|
ULONG IopNumTriageDumpDataBlocks;
|
||||||
|
PVOID IopTriageDumpDataBlocks[64];
|
||||||
|
|
||||||
GENERIC_MAPPING IopFileMapping = {
|
GENERIC_MAPPING IopFileMapping = {
|
||||||
FILE_GENERIC_READ,
|
FILE_GENERIC_READ,
|
||||||
|
|
|
@ -160,7 +160,7 @@ KdpSysReadBusData(IN ULONG BusDataType,
|
||||||
Length);
|
Length);
|
||||||
|
|
||||||
/* Return status */
|
/* Return status */
|
||||||
return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -182,7 +182,7 @@ KdpSysWriteBusData(IN ULONG BusDataType,
|
||||||
Length);
|
Length);
|
||||||
|
|
||||||
/* Return status */
|
/* Return status */
|
||||||
return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -209,12 +209,13 @@ KdpSysReadControlSpace(IN ULONG Processor,
|
||||||
(ULONG_PTR)&KiProcessorBlock[Processor]->
|
(ULONG_PTR)&KiProcessorBlock[Processor]->
|
||||||
ProcessorState);
|
ProcessorState);
|
||||||
|
|
||||||
/* Copy the memory */
|
/* Read the control state safely */
|
||||||
RtlCopyMemory(Buffer, ControlStart, Length);
|
return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
|
||||||
|
ControlStart,
|
||||||
/* Finish up */
|
Length,
|
||||||
*ActualLength = Length;
|
0,
|
||||||
return STATUS_SUCCESS;
|
MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
|
||||||
|
ActualLength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -243,12 +244,13 @@ KdpSysWriteControlSpace(IN ULONG Processor,
|
||||||
(ULONG_PTR)&KiProcessorBlock[Processor]->
|
(ULONG_PTR)&KiProcessorBlock[Processor]->
|
||||||
ProcessorState);
|
ProcessorState);
|
||||||
|
|
||||||
/* Copy the memory */
|
/* Write the control state safely */
|
||||||
RtlCopyMemory(ControlStart, Buffer, Length);
|
return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
|
||||||
|
ControlStart,
|
||||||
/* Finish up */
|
Length,
|
||||||
*ActualLength = Length;
|
0,
|
||||||
return STATUS_SUCCESS;
|
MMDBG_COPY_UNSAFE,
|
||||||
|
ActualLength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,65 +24,72 @@ KdpCopyMemoryChunks(IN ULONG64 Address,
|
||||||
IN ULONG Flags,
|
IN ULONG Flags,
|
||||||
OUT PULONG ActualSize OPTIONAL)
|
OUT PULONG ActualSize OPTIONAL)
|
||||||
{
|
{
|
||||||
ULONG Length;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG RemainingLength, CopyChunk;
|
||||||
|
|
||||||
/* Check if this is physical or virtual copy */
|
/* Check if we didn't get a chunk size or if it is too big */
|
||||||
if (Flags & MMDBG_COPY_PHYSICAL)
|
if (ChunkSize == 0)
|
||||||
{
|
{
|
||||||
/* Fail physical memory read/write for now */
|
/* Default to 4 byte chunks */
|
||||||
if (Flags & MMDBG_COPY_WRITE)
|
ChunkSize = 4;
|
||||||
{
|
|
||||||
KdpDprintf("KdpCopyMemoryChunks: Failing write for Physical Address 0x%I64x Length: %x\n",
|
|
||||||
Address,
|
|
||||||
TotalSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
KdpDprintf("KdpCopyMemoryChunks: Failing read for Physical Address 0x%I64x Length: %x\n",
|
|
||||||
Address,
|
|
||||||
TotalSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return an error */
|
|
||||||
Length = 0;
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
}
|
||||||
else
|
else if (ChunkSize > MMDBG_COPY_MAX_SIZE)
|
||||||
{
|
{
|
||||||
/* Protect against NULL */
|
/* Normalize to maximum size */
|
||||||
if (!Address)
|
ChunkSize = MMDBG_COPY_MAX_SIZE;
|
||||||
{
|
|
||||||
if (ActualSize) *ActualSize = 0;
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this is read or write */
|
|
||||||
if (Flags & MMDBG_COPY_WRITE)
|
|
||||||
{
|
|
||||||
/* Do the write */
|
|
||||||
RtlCopyMemory((PVOID)(ULONG_PTR)Address,
|
|
||||||
Buffer,
|
|
||||||
TotalSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Do the read */
|
|
||||||
RtlCopyMemory(Buffer,
|
|
||||||
(PVOID)(ULONG_PTR)Address,
|
|
||||||
TotalSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set size and status */
|
|
||||||
Length = TotalSize;
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the actual length if requested */
|
/* Copy the whole range in page aligned chunks */
|
||||||
if (ActualSize) *ActualSize = Length;
|
RemainingLength = TotalSize;
|
||||||
|
CopyChunk = 1;
|
||||||
|
while (RemainingLength > 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Determine the best chunk size for this round.
|
||||||
|
* The ideal size is page aligned, isn't larger than the
|
||||||
|
* the remaining length and respects the chunk limit.
|
||||||
|
*/
|
||||||
|
while (((CopyChunk * 2) <= RemainingLength) &&
|
||||||
|
(CopyChunk < ChunkSize) &&
|
||||||
|
((Address & ((CopyChunk * 2) - 1)) == 0))
|
||||||
|
{
|
||||||
|
/* Increase it */
|
||||||
|
CopyChunk = CopyChunk * 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return status */
|
/*
|
||||||
return Status;
|
* The chunk size can be larger than the remaining size if this isn't
|
||||||
|
* the first round, so check if we need to shrink it back
|
||||||
|
*/
|
||||||
|
while (CopyChunk > RemainingLength)
|
||||||
|
{
|
||||||
|
/* Shrink it */
|
||||||
|
CopyChunk /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the copy */
|
||||||
|
Status = MmDbgCopyMemory(Address,
|
||||||
|
Buffer,
|
||||||
|
CopyChunk,
|
||||||
|
Flags);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Copy failed, break out */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update pointers and length for the next run */
|
||||||
|
Address = Address + CopyChunk;
|
||||||
|
Buffer = (PVOID)((ULONG_PTR)Buffer + CopyChunk);
|
||||||
|
RemainingLength = RemainingLength - CopyChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the size we managed to copy
|
||||||
|
* and return success if we could copy the whole range
|
||||||
|
*/
|
||||||
|
if (ActualSize) *ActualSize = TotalSize - RemainingLength;
|
||||||
|
return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -269,7 +276,7 @@ KdpSetCommonState(IN ULONG NewState,
|
||||||
IN PCONTEXT Context,
|
IN PCONTEXT Context,
|
||||||
IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange)
|
IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange)
|
||||||
{
|
{
|
||||||
USHORT InstructionCount;
|
ULONG InstructionCount;
|
||||||
BOOLEAN HadBreakpoints;
|
BOOLEAN HadBreakpoints;
|
||||||
|
|
||||||
/* Setup common stuff available for all CPU architectures */
|
/* Setup common stuff available for all CPU architectures */
|
||||||
|
@ -285,10 +292,12 @@ KdpSetCommonState(IN ULONG NewState,
|
||||||
sizeof(DBGKD_ANY_CONTROL_REPORT));
|
sizeof(DBGKD_ANY_CONTROL_REPORT));
|
||||||
|
|
||||||
/* Now copy the instruction stream and set the count */
|
/* Now copy the instruction stream and set the count */
|
||||||
RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
|
KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
|
||||||
(PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
|
&WaitStateChange->ControlReport.InstructionStream[0],
|
||||||
DBGKD_MAXSTREAM);
|
DBGKD_MAXSTREAM,
|
||||||
InstructionCount = DBGKD_MAXSTREAM;
|
0,
|
||||||
|
MMDBG_COPY_UNSAFE,
|
||||||
|
&InstructionCount);
|
||||||
WaitStateChange->ControlReport.InstructionCount = InstructionCount;
|
WaitStateChange->ControlReport.InstructionCount = InstructionCount;
|
||||||
|
|
||||||
/* Clear all the breakpoints in this region */
|
/* Clear all the breakpoints in this region */
|
||||||
|
@ -299,9 +308,12 @@ KdpSetCommonState(IN ULONG NewState,
|
||||||
if (HadBreakpoints)
|
if (HadBreakpoints)
|
||||||
{
|
{
|
||||||
/* Copy the instruction stream again, this time without breakpoints */
|
/* Copy the instruction stream again, this time without breakpoints */
|
||||||
RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
|
KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
|
||||||
(PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
|
&WaitStateChange->ControlReport.InstructionStream[0],
|
||||||
WaitStateChange->ControlReport.InstructionCount);
|
InstructionCount,
|
||||||
|
0,
|
||||||
|
MMDBG_COPY_UNSAFE,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1297,6 +1309,7 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
|
||||||
PSTRING ExtraData;
|
PSTRING ExtraData;
|
||||||
STRING Data, Header;
|
STRING Data, Header;
|
||||||
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
|
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
|
||||||
|
ULONG PathNameLength;
|
||||||
KCONTINUE_STATUS Status;
|
KCONTINUE_STATUS Status;
|
||||||
|
|
||||||
/* Start wait loop */
|
/* Start wait loop */
|
||||||
|
@ -1317,14 +1330,27 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
|
||||||
WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
|
WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
|
||||||
WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
|
WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
|
||||||
|
|
||||||
/* Check if we have a symbol name */
|
/* Check if we have a path name */
|
||||||
if (PathName)
|
if (PathName)
|
||||||
{
|
{
|
||||||
/* Setup the information */
|
/* Copy it to the path buffer */
|
||||||
WaitStateChange.u.LoadSymbols.PathNameLength = PathName->Length;
|
KdpCopyMemoryChunks((ULONG_PTR)PathName->Buffer,
|
||||||
RtlCopyMemory(KdpPathBuffer, PathName->Buffer, PathName->Length);
|
KdpPathBuffer,
|
||||||
|
PathName->Length,
|
||||||
|
0,
|
||||||
|
MMDBG_COPY_UNSAFE,
|
||||||
|
&PathNameLength);
|
||||||
|
|
||||||
|
/* Null terminate */
|
||||||
|
KdpPathBuffer[PathNameLength] = ANSI_NULL;
|
||||||
|
PathNameLength++;
|
||||||
|
|
||||||
|
/* Set the path length */
|
||||||
|
WaitStateChange.u.LoadSymbols.PathNameLength = PathNameLength;
|
||||||
|
|
||||||
|
/* Set up the data */
|
||||||
Data.Buffer = KdpPathBuffer;
|
Data.Buffer = KdpPathBuffer;
|
||||||
Data.Length = WaitStateChange.u.LoadSymbols.PathNameLength;
|
Data.Length = PathNameLength;
|
||||||
ExtraData = &Data;
|
ExtraData = &Data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -21,6 +21,7 @@ KdpAddBreakpoint(IN PVOID Address)
|
||||||
{
|
{
|
||||||
KD_BREAKPOINT_TYPE Content;
|
KD_BREAKPOINT_TYPE Content;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Loop current breakpoints */
|
/* Loop current breakpoints */
|
||||||
for (i = 0; i < KD_BREAKPOINT_MAX; i++)
|
for (i = 0; i < KD_BREAKPOINT_MAX; i++)
|
||||||
|
@ -51,15 +52,39 @@ KdpAddBreakpoint(IN PVOID Address)
|
||||||
if (i == KD_BREAKPOINT_MAX) return 0;
|
if (i == KD_BREAKPOINT_MAX) return 0;
|
||||||
|
|
||||||
/* Save the old instruction */
|
/* Save the old instruction */
|
||||||
RtlCopyMemory(&Content, Address, KD_BREAKPOINT_SIZE);
|
Status = KdpCopyMemoryChunks((ULONG_PTR)Address,
|
||||||
|
&Content,
|
||||||
|
KD_BREAKPOINT_SIZE,
|
||||||
|
0,
|
||||||
|
MMDBG_COPY_UNSAFE,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* TODO: Set it as a owed breakpoint */
|
||||||
|
KdpDprintf("Failed to set breakpoint at address 0x%p\n", Address);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write the entry */
|
/* Write the entry */
|
||||||
KdpBreakpointTable[i].Address = Address;
|
KdpBreakpointTable[i].Address = Address;
|
||||||
KdpBreakpointTable[i].Content = Content;
|
KdpBreakpointTable[i].Content = Content;
|
||||||
KdpBreakpointTable[i].Flags = KdpBreakpointActive;
|
KdpBreakpointTable[i].Flags = KdpBreakpointActive;
|
||||||
|
|
||||||
/* Write the breakpoint and return the handle */
|
/* Write the breakpoint */
|
||||||
RtlCopyMemory(Address, &KdpBreakpointInstruction, KD_BREAKPOINT_SIZE);
|
Status = KdpCopyMemoryChunks((ULONG_PTR)Address,
|
||||||
|
&KdpBreakpointInstruction,
|
||||||
|
KD_BREAKPOINT_SIZE,
|
||||||
|
0,
|
||||||
|
MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* This should never happen */
|
||||||
|
KdpDprintf("Unable to write breakpoint to address 0x%p\n", Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the breakpoint handle */
|
||||||
return i + 1;
|
return i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +92,8 @@ BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdpLowWriteContent(IN ULONG BpIndex)
|
KdpLowWriteContent(IN ULONG BpIndex)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Make sure that the breakpoint is actually active */
|
/* Make sure that the breakpoint is actually active */
|
||||||
if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending)
|
if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending)
|
||||||
{
|
{
|
||||||
|
@ -83,9 +110,20 @@ KdpLowWriteContent(IN ULONG BpIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have an active breakpoint with an instruction to bring back. Do it. */
|
/* We have an active breakpoint with an instruction to bring back. Do it. */
|
||||||
RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,
|
Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
|
||||||
&KdpBreakpointTable[BpIndex].Content,
|
Address,
|
||||||
KD_BREAKPOINT_SIZE);
|
&KdpBreakpointTable[BpIndex].Content,
|
||||||
|
KD_BREAKPOINT_SIZE,
|
||||||
|
0,
|
||||||
|
MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* TODO: Set it as a owed breakpoint */
|
||||||
|
KdpDprintf("Failed to delete breakpoint at address 0x%p\n",
|
||||||
|
KdpBreakpointTable[BpIndex].Address);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Everything went fine, return */
|
/* Everything went fine, return */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -95,6 +133,8 @@ BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdpLowRestoreBreakpoint(IN ULONG BpIndex)
|
KdpLowRestoreBreakpoint(IN ULONG BpIndex)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Were we not able to remove it earlier? */
|
/* Were we not able to remove it earlier? */
|
||||||
if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)
|
if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)
|
||||||
{
|
{
|
||||||
|
@ -111,9 +151,20 @@ KdpLowRestoreBreakpoint(IN ULONG BpIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ok, we actually have to overwrite the instruction now */
|
/* Ok, we actually have to overwrite the instruction now */
|
||||||
RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,
|
Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
|
||||||
&KdpBreakpointInstruction,
|
Address,
|
||||||
KD_BREAKPOINT_SIZE);
|
&KdpBreakpointInstruction,
|
||||||
|
KD_BREAKPOINT_SIZE,
|
||||||
|
0,
|
||||||
|
MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME: Set it as a owed breakpoint */
|
||||||
|
KdpDprintf("Failed to restore breakpoint at address 0x%p\n",
|
||||||
|
KdpBreakpointTable[BpIndex].Address);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear any possible previous pending flag and return success */
|
/* Clear any possible previous pending flag and return success */
|
||||||
KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;
|
KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;
|
||||||
|
|
|
@ -391,22 +391,22 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
|
||||||
{(ULONG_PTR)&PsActiveProcessHead},
|
{(ULONG_PTR)&PsActiveProcessHead},
|
||||||
{(ULONG_PTR)&PspCidTable},
|
{(ULONG_PTR)&PspCidTable},
|
||||||
{(ULONG_PTR)&ExpSystemResourcesList},
|
{(ULONG_PTR)&ExpSystemResourcesList},
|
||||||
{0}, // ExpPagedPoolDescriptor
|
{(ULONG_PTR)ExpPagedPoolDescriptor},
|
||||||
{0}, // ExpNumberOfPagedPools
|
{(ULONG_PTR)&ExpNumberOfPagedPools},
|
||||||
{(ULONG_PTR)&KeTimeIncrement},
|
{(ULONG_PTR)&KeTimeIncrement},
|
||||||
{(ULONG_PTR)&KeBugcheckCallbackListHead},
|
{(ULONG_PTR)&KeBugcheckCallbackListHead},
|
||||||
{(ULONG_PTR)KiBugCheckData},
|
{(ULONG_PTR)KiBugCheckData},
|
||||||
{(ULONG_PTR)&IopErrorLogListHead},
|
{(ULONG_PTR)&IopErrorLogListHead},
|
||||||
{(ULONG_PTR)&ObpRootDirectoryObject},
|
{(ULONG_PTR)&ObpRootDirectoryObject},
|
||||||
{(ULONG_PTR)&ObpTypeObjectType},
|
{(ULONG_PTR)&ObpTypeObjectType},
|
||||||
{0}, // MmSystemCacheStart
|
{(ULONG_PTR)&MmSystemCacheStart},
|
||||||
{0}, // MmSystemCacheEnd
|
{(ULONG_PTR)&MmSystemCacheEnd},
|
||||||
{0}, // MmSystemCacheWs
|
{(ULONG_PTR)&MmSystemCacheWs},
|
||||||
{(ULONG_PTR)&MmPfnDatabase},
|
{(ULONG_PTR)&MmPfnDatabase},
|
||||||
{(ULONG_PTR)MmSystemPtesStart},
|
{(ULONG_PTR)MmSystemPtesStart},
|
||||||
{(ULONG_PTR)MmSystemPtesEnd},
|
{(ULONG_PTR)MmSystemPtesEnd},
|
||||||
{0}, // MmSubsectionBase
|
{(ULONG_PTR)&MmSubsectionBase},
|
||||||
{0}, // MmNumberOfPagingFiles
|
{(ULONG_PTR)&MmNumberOfPagingFiles},
|
||||||
{(ULONG_PTR)&MmLowestPhysicalPage},
|
{(ULONG_PTR)&MmLowestPhysicalPage},
|
||||||
{(ULONG_PTR)&MmHighestPhysicalPage},
|
{(ULONG_PTR)&MmHighestPhysicalPage},
|
||||||
{(ULONG_PTR)&MmNumberOfPhysicalPages},
|
{(ULONG_PTR)&MmNumberOfPhysicalPages},
|
||||||
|
@ -419,21 +419,21 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
|
||||||
{(ULONG_PTR)&MmPagedPoolInfo},
|
{(ULONG_PTR)&MmPagedPoolInfo},
|
||||||
PAGE_SIZE,
|
PAGE_SIZE,
|
||||||
{(ULONG_PTR)&MmSizeOfPagedPoolInBytes},
|
{(ULONG_PTR)&MmSizeOfPagedPoolInBytes},
|
||||||
{0}, // MmTotalCommitLimit
|
{(ULONG_PTR)&MmTotalCommitLimit},
|
||||||
{0}, // MmTotalCommittedPages
|
{(ULONG_PTR)&MmTotalCommittedPages},
|
||||||
{0}, // MmSharedCommit
|
{(ULONG_PTR)&MmSharedCommit},
|
||||||
{0}, // MmDriverCommit
|
{(ULONG_PTR)&MmDriverCommit},
|
||||||
{0}, // MmProcessCommit
|
{(ULONG_PTR)&MmProcessCommit},
|
||||||
{0}, // MmPagedPoolCommit
|
{(ULONG_PTR)&MmPagedPoolCommit},
|
||||||
{0},
|
{0},
|
||||||
{0}, // MmZeroedPageListHead
|
{(ULONG_PTR)&MmZeroedPageListHead},
|
||||||
{0}, // MmFreePageListHead
|
{(ULONG_PTR)&MmFreePageListHead},
|
||||||
{0}, // MmStandbyPageListHead
|
{(ULONG_PTR)&MmStandbyPageListHead},
|
||||||
{0}, // MmModifiedPageListHead
|
{(ULONG_PTR)&MmModifiedPageListHead},
|
||||||
{0}, // MmModifiedNoWritePageListHead
|
{(ULONG_PTR)&MmModifiedNoWritePageListHead},
|
||||||
{0}, // MmAvailablePages
|
{(ULONG_PTR)&MmAvailablePages},
|
||||||
{0}, // MmResidentAvailablePages
|
{(ULONG_PTR)&MmResidentAvailablePages},
|
||||||
{0}, // PoolTrackTable
|
{(ULONG_PTR)&PoolTrackTable},
|
||||||
{(ULONG_PTR)&NonPagedPoolDescriptor},
|
{(ULONG_PTR)&NonPagedPoolDescriptor},
|
||||||
{(ULONG_PTR)&MmHighestUserAddress},
|
{(ULONG_PTR)&MmHighestUserAddress},
|
||||||
{(ULONG_PTR)&MmSystemRangeStart},
|
{(ULONG_PTR)&MmSystemRangeStart},
|
||||||
|
@ -442,19 +442,19 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
|
||||||
{(ULONG_PTR)KdPrintDefaultCircularBuffer + 1},
|
{(ULONG_PTR)KdPrintDefaultCircularBuffer + 1},
|
||||||
{(ULONG_PTR)&KdPrintWritePointer},
|
{(ULONG_PTR)&KdPrintWritePointer},
|
||||||
{(ULONG_PTR)&KdPrintRolloverCount},
|
{(ULONG_PTR)&KdPrintRolloverCount},
|
||||||
{0}, // MmLoadedUserImageList
|
{(ULONG_PTR)&MmLoadedUserImageList},
|
||||||
{(ULONG_PTR)&NtBuildLab},
|
{(ULONG_PTR)&NtBuildLab},
|
||||||
{0},
|
{0},
|
||||||
{(ULONG_PTR)KiProcessorBlock},
|
{(ULONG_PTR)KiProcessorBlock},
|
||||||
{0}, // MmUnloadedDrivers
|
{(ULONG_PTR)&MmUnloadedDrivers},
|
||||||
{0}, // MmLastUnloadedDrivers
|
{(ULONG_PTR)&MmLastUnloadedDrivers},
|
||||||
{0}, // MmTriageActionTaken
|
{(ULONG_PTR)&MmTriageActionTaken},
|
||||||
{0}, // MmSpecialPoolTag
|
{(ULONG_PTR)&MmSpecialPoolTag},
|
||||||
{0}, // KernelVerifier
|
{(ULONG_PTR)&KernelVerifier},
|
||||||
{0}, // MmVerifierData
|
{(ULONG_PTR)&MmVerifierData},
|
||||||
{0}, // MmAllocatedNonPagedPool
|
{(ULONG_PTR)&MmAllocatedNonPagedPool},
|
||||||
{0}, // MmPeakCommitment
|
{(ULONG_PTR)&MmPeakCommitment},
|
||||||
{0}, // MmtotalCommitLimitMaximum
|
{(ULONG_PTR)&MmtotalCommitLimitMaximum},
|
||||||
{(ULONG_PTR)&CmNtCSDVersion},
|
{(ULONG_PTR)&CmNtCSDVersion},
|
||||||
{(ULONG_PTR)&MmPhysicalMemoryBlock},
|
{(ULONG_PTR)&MmPhysicalMemoryBlock},
|
||||||
{(ULONG_PTR)&MmSessionBase},
|
{(ULONG_PTR)&MmSessionBase},
|
||||||
|
@ -539,6 +539,6 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
#endif
|
#endif
|
||||||
{0}, // IopNumTriageDumpDataBlocks
|
{(ULONG_PTR)&IopNumTriageDumpDataBlocks},
|
||||||
{0}, // IopTriageDumpDataBlocks
|
{(ULONG_PTR)IopTriageDumpDataBlocks},
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,6 +54,9 @@ ULONG MmBootImageSize;
|
||||||
ULONG MmUserProbeAddress;
|
ULONG MmUserProbeAddress;
|
||||||
PVOID MmHighestUserAddress;
|
PVOID MmHighestUserAddress;
|
||||||
PVOID MmSystemRangeStart;
|
PVOID MmSystemRangeStart;
|
||||||
|
PVOID MmSystemCacheStart;
|
||||||
|
PVOID MmSystemCacheEnd;
|
||||||
|
MMSUPPORT MmSystemCacheWs;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,11 @@
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
ULONG ExpNumberOfPagedPools;
|
||||||
POOL_DESCRIPTOR NonPagedPoolDescriptor;
|
POOL_DESCRIPTOR NonPagedPoolDescriptor;
|
||||||
|
PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
|
||||||
PPOOL_DESCRIPTOR PoolVector[2];
|
PPOOL_DESCRIPTOR PoolVector[2];
|
||||||
|
PVOID PoolTrackTable;
|
||||||
PKGUARDED_MUTEX ExpPagedPoolMutex;
|
PKGUARDED_MUTEX ExpPagedPoolMutex;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
|
@ -217,6 +217,12 @@ ULONG MmUserProbeAddress;
|
||||||
PVOID MmHighestUserAddress;
|
PVOID MmHighestUserAddress;
|
||||||
PVOID MmSystemRangeStart;
|
PVOID MmSystemRangeStart;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PVOID MmSystemCacheStart;
|
||||||
|
PVOID MmSystemCacheEnd;
|
||||||
|
MMSUPPORT MmSystemCacheWs;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -87,7 +87,10 @@ typedef struct _POOL_HEADER
|
||||||
C_ASSERT(sizeof(POOL_HEADER) == 8);
|
C_ASSERT(sizeof(POOL_HEADER) == 8);
|
||||||
C_ASSERT(sizeof(POOL_HEADER) == sizeof(LIST_ENTRY));
|
C_ASSERT(sizeof(POOL_HEADER) == sizeof(LIST_ENTRY));
|
||||||
|
|
||||||
|
extern ULONG ExpNumberOfPagedPools;
|
||||||
extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
|
extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
|
||||||
|
extern PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
|
||||||
|
extern PVOID PoolTrackTable;
|
||||||
|
|
||||||
//
|
//
|
||||||
// END FIXFIX
|
// END FIXFIX
|
||||||
|
@ -156,6 +159,12 @@ extern PVOID MmSessionBase;
|
||||||
extern PVOID MiSessionSpaceEnd;
|
extern PVOID MiSessionSpaceEnd;
|
||||||
extern ULONG MmSizeOfPagedPoolInBytes;
|
extern ULONG MmSizeOfPagedPoolInBytes;
|
||||||
extern PMMPTE MmSystemPagePtes;
|
extern PMMPTE MmSystemPagePtes;
|
||||||
|
extern PVOID MmSystemCacheStart;
|
||||||
|
extern PVOID MmSystemCacheEnd;
|
||||||
|
extern MMSUPPORT MmSystemCacheWs;
|
||||||
|
extern SIZE_T MmAllocatedNonPagedPool;
|
||||||
|
extern ULONG_PTR MmSubsectionBase;
|
||||||
|
extern ULONG MmSpecialPoolTag;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -24,6 +24,8 @@ PVOID MmNonPagedPoolEnd0;
|
||||||
PFN_NUMBER MiStartOfInitialPoolFrame, MiEndOfInitialPoolFrame;
|
PFN_NUMBER MiStartOfInitialPoolFrame, MiEndOfInitialPoolFrame;
|
||||||
KGUARDED_MUTEX MmPagedPoolMutex;
|
KGUARDED_MUTEX MmPagedPoolMutex;
|
||||||
MM_PAGED_POOL_INFO MmPagedPoolInfo;
|
MM_PAGED_POOL_INFO MmPagedPoolInfo;
|
||||||
|
SIZE_T MmAllocatedNonPagedPool;
|
||||||
|
ULONG MmSpecialPoolTag;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,22 @@
|
||||||
PPHYSICAL_PAGE MmPfnDatabase;
|
PPHYSICAL_PAGE MmPfnDatabase;
|
||||||
|
|
||||||
ULONG MmAvailablePages;
|
ULONG MmAvailablePages;
|
||||||
|
ULONG MmResidentAvailablePages;
|
||||||
|
|
||||||
|
SIZE_T MmTotalCommitLimit;
|
||||||
|
SIZE_T MmTotalCommittedPages;
|
||||||
|
SIZE_T MmSharedCommit;
|
||||||
|
SIZE_T MmDriverCommit;
|
||||||
|
SIZE_T MmProcessCommit;
|
||||||
|
SIZE_T MmPagedPoolCommit;
|
||||||
|
SIZE_T MmPeakCommitment;
|
||||||
|
SIZE_T MmtotalCommitLimitMaximum;
|
||||||
|
|
||||||
|
MMPFNLIST MmZeroedPageListHead;
|
||||||
|
MMPFNLIST MmFreePageListHead;
|
||||||
|
MMPFNLIST MmStandbyPageListHead;
|
||||||
|
MMPFNLIST MmModifiedPageListHead;
|
||||||
|
MMPFNLIST MmModifiedNoWritePageListHead;
|
||||||
|
|
||||||
/* List of pages allocated to the MC_USER Consumer */
|
/* List of pages allocated to the MC_USER Consumer */
|
||||||
static LIST_ENTRY UserPageListHead;
|
static LIST_ENTRY UserPageListHead;
|
||||||
|
|
108
reactos/ntoskrnl/mm/mmdbg.c
Normal file
108
reactos/ntoskrnl/mm/mmdbg.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: ntoskrnl/mm/mmdbg.c
|
||||||
|
* PURPOSE: Memory Manager support routines for the Kernel Debugger
|
||||||
|
* PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmDbgCopyMemory(IN ULONG64 Address,
|
||||||
|
IN PVOID Buffer,
|
||||||
|
IN ULONG Size,
|
||||||
|
IN ULONG Flags)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* For now, this must be a "unsafe" copy */
|
||||||
|
ASSERT(Flags & MMDBG_COPY_UNSAFE);
|
||||||
|
|
||||||
|
/* We only handle 1, 2, 4 and 8 byte requests */
|
||||||
|
if ((Size != 1) &&
|
||||||
|
(Size != 2) &&
|
||||||
|
(Size != 4) &&
|
||||||
|
(Size != MMDBG_COPY_MAX_SIZE))
|
||||||
|
{
|
||||||
|
/* Invalid size, fail */
|
||||||
|
return STATUS_INVALID_PARAMETER_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The copy must be aligned too */
|
||||||
|
if ((Address & (Size - 1)) != 0)
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
return STATUS_INVALID_PARAMETER_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No physical memory support yet */
|
||||||
|
if (Flags & MMDBG_COPY_PHYSICAL)
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
KdpDprintf("MmDbgCopyMemory: Failing %s for Physical Address 0x%I64x\n",
|
||||||
|
Flags & MMDBG_COPY_WRITE ? "write" : "read",
|
||||||
|
Address);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simple check for invalid address */
|
||||||
|
if ((MiAddressToPde((ULONG_PTR)Address)->u.Hard.Valid == 0) ||
|
||||||
|
(MiAddressToPte((ULONG_PTR)Address)->u.Hard.Valid == 0))
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Address 0x%p\n",
|
||||||
|
Flags & MMDBG_COPY_WRITE ? "write" : "read",
|
||||||
|
(PVOID)(ULONG_PTR)Address);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we are going to write to it then make sure it is writeable too */
|
||||||
|
if ((Flags & MMDBG_COPY_WRITE) &&
|
||||||
|
(!MI_IS_PAGE_WRITEABLE(MiAddressToPte((ULONG_PTR)Address))))
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
KdpDprintf("MmDbgCopyMemory: Failing write for Address 0x%p\n",
|
||||||
|
(PVOID)(ULONG_PTR)Address);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use SEH to try to catch anything else somewhat cleanly */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
/* Check if this is read or write */
|
||||||
|
if (Flags & MMDBG_COPY_WRITE)
|
||||||
|
{
|
||||||
|
/* Do the write */
|
||||||
|
RtlCopyMemory((PVOID)(ULONG_PTR)Address,
|
||||||
|
Buffer,
|
||||||
|
Size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Do the read */
|
||||||
|
RtlCopyMemory(Buffer,
|
||||||
|
(PVOID)(ULONG_PTR)Address,
|
||||||
|
Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy succeeded */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
|
@ -424,6 +424,9 @@ MmInitSystem(IN ULONG Phase,
|
||||||
/* Initialize working sets */
|
/* Initialize working sets */
|
||||||
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
|
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
|
||||||
|
|
||||||
|
/* Initialize the user mode image list */
|
||||||
|
InitializeListHead(&MmLoadedUserImageList);
|
||||||
|
|
||||||
/* Initialize the Loader Lock */
|
/* Initialize the Loader Lock */
|
||||||
KeInitializeMutant(&MmSystemLoadLock, FALSE);
|
KeInitializeMutant(&MmSystemLoadLock, FALSE);
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ static KSPIN_LOCK PagingFileListLock;
|
||||||
|
|
||||||
/* Number of paging files */
|
/* Number of paging files */
|
||||||
static ULONG MiPagingFileCount;
|
static ULONG MiPagingFileCount;
|
||||||
|
ULONG MmNumberOfPagingFiles;
|
||||||
|
|
||||||
/* Number of pages that are available for swapping */
|
/* Number of pages that are available for swapping */
|
||||||
ULONG MiFreeSwapPages;
|
ULONG MiFreeSwapPages;
|
||||||
|
|
|
@ -71,6 +71,8 @@ MM_SECTION_PAGEOUT_CONTEXT;
|
||||||
|
|
||||||
POBJECT_TYPE MmSectionObjectType = NULL;
|
POBJECT_TYPE MmSectionObjectType = NULL;
|
||||||
|
|
||||||
|
ULONG_PTR MmSubsectionBase;
|
||||||
|
|
||||||
static GENERIC_MAPPING MmpSectionMapping = {
|
static GENERIC_MAPPING MmpSectionMapping = {
|
||||||
STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY,
|
STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY,
|
||||||
STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE,
|
STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE,
|
||||||
|
|
|
@ -28,11 +28,18 @@ sprintf_nt(IN PCHAR Buffer,
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
LIST_ENTRY PsLoadedModuleList;
|
LIST_ENTRY PsLoadedModuleList;
|
||||||
|
LIST_ENTRY MmLoadedUserImageList;
|
||||||
KSPIN_LOCK PsLoadedModuleSpinLock;
|
KSPIN_LOCK PsLoadedModuleSpinLock;
|
||||||
ULONG_PTR PsNtosImageBase;
|
ULONG_PTR PsNtosImageBase;
|
||||||
KMUTANT MmSystemLoadLock;
|
KMUTANT MmSystemLoadLock;
|
||||||
extern ULONG NtGlobalFlag;
|
extern ULONG NtGlobalFlag;
|
||||||
|
|
||||||
|
PVOID MmUnloadedDrivers;
|
||||||
|
PVOID MmLastUnloadedDrivers;
|
||||||
|
PVOID MmTriageActionTaken;
|
||||||
|
PVOID KernelVerifier;
|
||||||
|
MM_DRIVER_VERIFIER_DATA MmVerifierData;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
|
|
|
@ -405,6 +405,7 @@
|
||||||
<file>dbgpool.c</file>
|
<file>dbgpool.c</file>
|
||||||
<file>freelist.c</file>
|
<file>freelist.c</file>
|
||||||
<file>marea.c</file>
|
<file>marea.c</file>
|
||||||
|
<file>mmdbg.c</file>
|
||||||
<file>mmfault.c</file>
|
<file>mmfault.c</file>
|
||||||
<file>mminit.c</file>
|
<file>mminit.c</file>
|
||||||
<file>mpw.c</file>
|
<file>mpw.c</file>
|
||||||
|
|
Loading…
Reference in a new issue