mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
- Remove deprecated/old/buggy/unused code.
- Make MxGetNextPage return the lowest free physical page, not the highest. - This way we fragment the address space less. - Also makes calculation of "forgotten" pages when we build the PFN database earlier. - Remove MmAllocEarlyPage and use MxGetNextPage instead. svn path=/trunk/; revision=42175
This commit is contained in:
@@ -1162,13 +1162,7 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
|
||||
|
||||
/* FIXME: Support Triage Dump */
|
||||
|
||||
/* Write the crash dump */
|
||||
MmDumpToPagingFile(KiBugCheckData[4],
|
||||
KiBugCheckData[0],
|
||||
KiBugCheckData[1],
|
||||
KiBugCheckData[2],
|
||||
KiBugCheckData[3],
|
||||
TrapFrame);
|
||||
/* FIXME: Write the crash dump */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -250,9 +250,10 @@ MxGetNextPage(IN PFN_NUMBER PageCount)
|
||||
}
|
||||
|
||||
//
|
||||
// Use our highest usable free pages
|
||||
// Use our lowest usable free pages
|
||||
//
|
||||
Pfn = MxFreeDescriptor->BasePage + MxFreeDescriptor->PageCount - PageCount;
|
||||
Pfn = MxFreeDescriptor->BasePage;
|
||||
MxFreeDescriptor->BasePage += PageCount;
|
||||
MxFreeDescriptor->PageCount -= PageCount;
|
||||
return Pfn;
|
||||
}
|
||||
|
||||
@@ -135,110 +135,6 @@ MmRemoveLRUUserPage(PFN_TYPE Page)
|
||||
RemoveEntryList(&MiGetPfnEntry(Page)->ListEntry);
|
||||
}
|
||||
|
||||
PFN_TYPE
|
||||
NTAPI
|
||||
MmGetContinuousPages(ULONG NumberOfBytes,
|
||||
PHYSICAL_ADDRESS LowestAcceptableAddress,
|
||||
PHYSICAL_ADDRESS HighestAcceptableAddress,
|
||||
PHYSICAL_ADDRESS BoundaryAddressMultiple,
|
||||
BOOLEAN ZeroPages)
|
||||
{
|
||||
ULONG NrPages;
|
||||
ULONG i, j;
|
||||
ULONG start;
|
||||
ULONG last;
|
||||
ULONG length;
|
||||
ULONG boundary;
|
||||
KIRQL oldIrql;
|
||||
|
||||
NrPages = PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE;
|
||||
|
||||
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||
|
||||
last = min(HighestAcceptableAddress.LowPart / PAGE_SIZE, MmHighestPhysicalPage - 1);
|
||||
boundary = BoundaryAddressMultiple.LowPart / PAGE_SIZE;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
start = -1;
|
||||
length = 0;
|
||||
/* First try to allocate the pages above the 16MB area. This may fail
|
||||
* because there are not enough continuous pages or we cannot allocate
|
||||
* pages above the 16MB area because the caller has specify an upper limit.
|
||||
* The second try uses the specified lower limit.
|
||||
*/
|
||||
for (i = j == 0 ? 0x100000 / PAGE_SIZE : LowestAcceptableAddress.LowPart / PAGE_SIZE; i <= last; )
|
||||
{
|
||||
if (MiGetPfnEntry(i)->Flags.Type == MM_PHYSICAL_PAGE_FREE)
|
||||
{
|
||||
if (start == (ULONG)-1)
|
||||
{
|
||||
start = i;
|
||||
length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
length++;
|
||||
if (boundary)
|
||||
{
|
||||
if (start / boundary != i / boundary)
|
||||
{
|
||||
start = i;
|
||||
length = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (length == NrPages)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
start = (ULONG)-1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (start != (ULONG)-1 && length == NrPages)
|
||||
{
|
||||
for (i = start; i < (start + length); i++)
|
||||
{
|
||||
PPHYSICAL_PAGE Page;
|
||||
Page = MiGetPfnEntry(i);
|
||||
RemoveEntryList(&Page->ListEntry);
|
||||
if (MmPfnDatabase[i].Flags.Zero == 0)
|
||||
{
|
||||
UnzeroedPageCount--;
|
||||
}
|
||||
MmStats.NrFreePages--;
|
||||
MmStats.NrSystemPages++;
|
||||
Page->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
||||
Page->Flags.Consumer = MC_NPPOOL;
|
||||
Page->ReferenceCount = 1;
|
||||
Page->LockCount = 0;
|
||||
Page->MapCount = 0;
|
||||
Page->SavedSwapEntry = 0;
|
||||
}
|
||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||
for (i = start; i < (start + length); i++)
|
||||
{
|
||||
if (MiGetPfnEntry(i)->Flags.Zero == 0)
|
||||
{
|
||||
if (ZeroPages) MiZeroPage(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
MiGetPfnEntry(i)->Flags.Zero = 0;
|
||||
}
|
||||
}
|
||||
return start;
|
||||
}
|
||||
}
|
||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PFN_NUMBER
|
||||
NTAPI
|
||||
MiFindContiguousPages(IN PFN_NUMBER LowestPfn,
|
||||
@@ -706,20 +602,6 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
|
||||
return Mdl;
|
||||
}
|
||||
|
||||
PFN_TYPE
|
||||
NTAPI
|
||||
MmAllocEarlyPage(VOID)
|
||||
{
|
||||
PFN_TYPE Pfn;
|
||||
|
||||
/* Use one of our highest usable pages */
|
||||
Pfn = MxFreeDescriptor->BasePage + MxFreeDescriptor->PageCount - 1;
|
||||
MxFreeDescriptor->PageCount--;
|
||||
|
||||
/* Return it */
|
||||
return Pfn;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmDumpPfnDatabase(VOID)
|
||||
@@ -820,6 +702,10 @@ MmDumpPfnDatabase(VOID)
|
||||
KeLowerIrql(OldIrql);
|
||||
}
|
||||
|
||||
PFN_NUMBER
|
||||
NTAPI
|
||||
MxGetNextPage(IN PFN_NUMBER PageCount);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmInitializePageList(VOID)
|
||||
@@ -845,7 +731,7 @@ MmInitializePageList(VOID)
|
||||
if (!MmIsPagePresent(NULL, Address))
|
||||
{
|
||||
/* Use one of our highest usable pages */
|
||||
Pfn = MmAllocEarlyPage();
|
||||
Pfn = MxGetNextPage(1);
|
||||
|
||||
/* Set the PFN */
|
||||
Status = MmCreateVirtualMappingForKernel(Address,
|
||||
@@ -934,9 +820,7 @@ MmInitializePageList(VOID)
|
||||
}
|
||||
|
||||
/* Finally handle the pages describing the PFN database themselves */
|
||||
for (i = (MxFreeDescriptor->BasePage + MxFreeDescriptor->PageCount);
|
||||
i < (MxOldFreeDescriptor.BasePage + MxOldFreeDescriptor.PageCount);
|
||||
i++)
|
||||
for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++)
|
||||
{
|
||||
/* Ensure this page was not added previously */
|
||||
ASSERT(MmPfnDatabase[i].Flags.Type == 0);
|
||||
@@ -945,9 +829,8 @@ MmInitializePageList(VOID)
|
||||
MmPfnDatabase[i] = UsedPage;
|
||||
MmStats.NrSystemPages++;
|
||||
}
|
||||
|
||||
|
||||
KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE);
|
||||
|
||||
DPRINT("Pages: %x %x\n", MmStats.NrFreePages, MmStats.NrSystemPages);
|
||||
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
|
||||
MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
|
||||
@@ -1290,11 +1173,7 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry)
|
||||
/* Check if this allocation is for the PFN DB itself */
|
||||
if (MmStats.NrTotalPages == 0)
|
||||
{
|
||||
/* Allocate an early page -- we'll account for it later */
|
||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||
PfnOffset = MmAllocEarlyPage();
|
||||
if (Consumer != MC_SYSTEM) MiZeroPage(PfnOffset);
|
||||
return PfnOffset;
|
||||
MxGetNextPage(1);
|
||||
}
|
||||
|
||||
DPRINT1("MmAllocPage(): Out of memory\n");
|
||||
@@ -1355,154 +1234,6 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry)
|
||||
return PfnOffset;
|
||||
}
|
||||
|
||||
LONG
|
||||
NTAPI
|
||||
MmAllocPagesSpecifyRange(ULONG Consumer,
|
||||
PHYSICAL_ADDRESS LowestAddress,
|
||||
PHYSICAL_ADDRESS HighestAddress,
|
||||
ULONG NumberOfPages,
|
||||
PPFN_TYPE Pages)
|
||||
{
|
||||
PPHYSICAL_PAGE PageDescriptor;
|
||||
KIRQL oldIrql;
|
||||
PFN_TYPE LowestPage, HighestPage;
|
||||
PFN_TYPE pfn;
|
||||
ULONG NumberOfPagesFound = 0;
|
||||
ULONG i;
|
||||
|
||||
DPRINT("MmAllocPagesSpecifyRange()\n"
|
||||
" LowestAddress = 0x%08x%08x\n"
|
||||
" HighestAddress = 0x%08x%08x\n"
|
||||
" NumberOfPages = %d\n",
|
||||
LowestAddress.u.HighPart, LowestAddress.u.LowPart,
|
||||
HighestAddress.u.HighPart, HighestAddress.u.LowPart,
|
||||
NumberOfPages);
|
||||
|
||||
if (NumberOfPages == 0)
|
||||
return 0;
|
||||
|
||||
LowestPage = LowestAddress.LowPart / PAGE_SIZE;
|
||||
HighestPage = HighestAddress.LowPart / PAGE_SIZE;
|
||||
if ((HighestAddress.u.LowPart % PAGE_SIZE) != 0)
|
||||
HighestPage++;
|
||||
|
||||
if (LowestPage >= MmHighestPhysicalPage)
|
||||
{
|
||||
DPRINT1("MmAllocPagesSpecifyRange(): Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
if (HighestPage > MmHighestPhysicalPage)
|
||||
HighestPage = MmHighestPhysicalPage;
|
||||
|
||||
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||
if (LowestPage == 0 && HighestPage == MmHighestPhysicalPage)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
while (NumberOfPagesFound < NumberOfPages)
|
||||
{
|
||||
if (!IsListEmpty(&FreeZeroedPageListHead))
|
||||
{
|
||||
ListEntry = RemoveTailList(&FreeZeroedPageListHead);
|
||||
}
|
||||
else if (!IsListEmpty(&FreeUnzeroedPageListHead))
|
||||
{
|
||||
ListEntry = RemoveTailList(&FreeUnzeroedPageListHead);
|
||||
UnzeroedPageCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NumberOfPagesFound == 0)
|
||||
{
|
||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||
DPRINT1("MmAllocPagesSpecifyRange(): Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
|
||||
|
||||
ASSERT(PageDescriptor->Flags.Type == MM_PHYSICAL_PAGE_FREE);
|
||||
ASSERT(PageDescriptor->MapCount == 0);
|
||||
ASSERT(PageDescriptor->ReferenceCount == 0);
|
||||
|
||||
/* Allocate the page */
|
||||
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
||||
PageDescriptor->Flags.Consumer = Consumer;
|
||||
PageDescriptor->ReferenceCount = 1;
|
||||
PageDescriptor->LockCount = 0;
|
||||
PageDescriptor->MapCount = 0;
|
||||
PageDescriptor->SavedSwapEntry = 0; /* FIXME: Do we need swap entries? */
|
||||
|
||||
MmStats.NrSystemPages++;
|
||||
MmStats.NrFreePages--;
|
||||
|
||||
/* Remember the page */
|
||||
pfn = PageDescriptor - MmPfnDatabase;
|
||||
Pages[NumberOfPagesFound++] = pfn;
|
||||
if(Consumer == MC_USER) MmInsertLRULastUserPage(pfn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INT LookForZeroedPages;
|
||||
for (LookForZeroedPages = 1; LookForZeroedPages >= 0; LookForZeroedPages--)
|
||||
{
|
||||
for (pfn = LowestPage; pfn < HighestPage; pfn++)
|
||||
{
|
||||
PageDescriptor = MmPfnDatabase + pfn;
|
||||
|
||||
if (PageDescriptor->Flags.Type != MM_PHYSICAL_PAGE_FREE)
|
||||
continue;
|
||||
if (PageDescriptor->Flags.Zero != LookForZeroedPages)
|
||||
continue;
|
||||
|
||||
ASSERT(PageDescriptor->MapCount == 0);
|
||||
ASSERT(PageDescriptor->ReferenceCount == 0);
|
||||
|
||||
/* Allocate the page */
|
||||
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
||||
PageDescriptor->Flags.Consumer = Consumer;
|
||||
PageDescriptor->ReferenceCount = 1;
|
||||
PageDescriptor->LockCount = 0;
|
||||
PageDescriptor->MapCount = 0;
|
||||
PageDescriptor->SavedSwapEntry = 0; /* FIXME: Do we need swap entries? */
|
||||
|
||||
if (!PageDescriptor->Flags.Zero)
|
||||
UnzeroedPageCount--;
|
||||
MmStats.NrSystemPages++;
|
||||
MmStats.NrFreePages--;
|
||||
|
||||
/* Remember the page */
|
||||
Pages[NumberOfPagesFound++] = pfn;
|
||||
if (NumberOfPagesFound == NumberOfPages)
|
||||
break;
|
||||
}
|
||||
if (NumberOfPagesFound == NumberOfPages)
|
||||
break;
|
||||
}
|
||||
}
|
||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||
|
||||
/* Zero unzero-ed pages */
|
||||
for (i = 0; i < NumberOfPagesFound; i++)
|
||||
{
|
||||
pfn = Pages[i];
|
||||
if (MiGetPfnEntry(pfn)->Flags.Zero == 0)
|
||||
{
|
||||
MiZeroPage(pfn);
|
||||
}
|
||||
else
|
||||
{
|
||||
MiGetPfnEntry(pfn)->Flags.Zero = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return NumberOfPagesFound;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmZeroPageThreadMain(PVOID Ignored)
|
||||
|
||||
@@ -105,15 +105,6 @@ static ULONG MiReservedSwapPages;
|
||||
*/
|
||||
#define MM_PAGEFILE_COMMIT_GRACE (256)
|
||||
|
||||
static PVOID MmCoreDumpPageFrame = NULL;
|
||||
static ULONG MmCoreDumpSize;
|
||||
static DUMP_POINTERS MmCoreDumpPointers;
|
||||
static PMM_CORE_DUMP_FUNCTIONS MmCoreDumpFunctions;
|
||||
static ULONG MmCoreDumpPageFile = 0xFFFFFFFF;
|
||||
static ROS_QUERY_LCN_MAPPING MmCoreDumpLcnMapping;
|
||||
|
||||
ULONG MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
|
||||
|
||||
/*
|
||||
* Translate between a swap entry and a file and offset pair.
|
||||
*/
|
||||
@@ -360,22 +351,6 @@ MmInitPagingFile(VOID)
|
||||
PagingFileList[i] = NULL;
|
||||
}
|
||||
MiPagingFileCount = 0;
|
||||
|
||||
/*
|
||||
* Initialize the crash dump support.
|
||||
*/
|
||||
if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE)
|
||||
{
|
||||
MmCoreDumpPageFrame = MmAllocateSection(PAGE_SIZE, NULL);
|
||||
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
||||
{
|
||||
MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
MmCoreDumpSize = 1024 * 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
@@ -538,263 +513,6 @@ MmAllocRetrievelDescriptorList(ULONG Pairs)
|
||||
return RetDescList;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
MmDumpToPagingFile(ULONG BugCode,
|
||||
ULONG BugCodeParameter1,
|
||||
ULONG BugCodeParameter2,
|
||||
ULONG BugCodeParameter3,
|
||||
ULONG BugCodeParameter4,
|
||||
PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
PMM_CORE_DUMP_HEADER Headers;
|
||||
NTSTATUS Status;
|
||||
UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
|
||||
PMDL Mdl = (PMDL)MdlBase;
|
||||
PETHREAD Thread = PsGetCurrentThread();
|
||||
ULONG_PTR StackSize;
|
||||
PULONG MdlMap;
|
||||
LONGLONG NextOffset = 0;
|
||||
ULONG i;
|
||||
PRETRIEVAL_POINTERS_BUFFER RetrievalPointers;
|
||||
LARGE_INTEGER DiskOffset;
|
||||
|
||||
if (MmCoreDumpPageFile == 0xFFFFFFFF)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
DbgPrint("\nMM: Dumping core: ");
|
||||
|
||||
/* Prepare the dump headers. */
|
||||
Headers = (PMM_CORE_DUMP_HEADER)MmCoreDumpPageFrame;
|
||||
Headers->Magic = MM_CORE_DUMP_HEADER_MAGIC;
|
||||
Headers->Version = MM_CORE_DUMP_HEADER_VERSION;
|
||||
Headers->Type = MmCoreDumpType;
|
||||
if (TrapFrame != NULL)
|
||||
{
|
||||
#ifdef _M_IX86
|
||||
if (!(TrapFrame->EFlags & (1 << 17)))
|
||||
{
|
||||
memcpy(&Headers->TrapFrame, TrapFrame,
|
||||
sizeof(KTRAP_FRAME) - (4 * sizeof(ULONG)));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memcpy(&Headers->TrapFrame, TrapFrame, sizeof(KTRAP_FRAME));
|
||||
}
|
||||
}
|
||||
Headers->BugCheckCode = BugCode;
|
||||
Headers->BugCheckParameters[0] = BugCodeParameter1;
|
||||
Headers->BugCheckParameters[1] = BugCodeParameter2;
|
||||
Headers->BugCheckParameters[2] = BugCodeParameter3;
|
||||
Headers->BugCheckParameters[3] = BugCodeParameter4;
|
||||
Headers->FaultingStackBase = (PVOID)Thread->Tcb.StackLimit;
|
||||
Headers->FaultingStackSize =
|
||||
StackSize = (ULONG_PTR)Thread->Tcb.StackBase - (ULONG_PTR)Thread->Tcb.StackLimit;
|
||||
Headers->PhysicalMemorySize = MmStats.NrTotalPages * PAGE_SIZE;
|
||||
|
||||
/* Initialize the dump device. */
|
||||
Status = MmCoreDumpFunctions->DumpInit();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MM: Failed to initialize core dump device.\n");
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Initialize the MDL. */
|
||||
MmInitializeMdl(Mdl, MmCoreDumpPageFrame, PAGE_SIZE);
|
||||
Mdl->MdlFlags = MDL_PAGES_LOCKED|MDL_IO_PAGE_READ|MDL_SOURCE_IS_NONPAGED_POOL;
|
||||
MdlMap = (PULONG)(Mdl + 1);
|
||||
|
||||
|
||||
/* Initialize the retrieval offsets. */
|
||||
RetrievalPointers = PagingFileList[MmCoreDumpPageFile]->RetrievalPointers;
|
||||
|
||||
/* Dump the header. */
|
||||
MdlMap[0] = (ULONG)(MmGetPhysicalAddress(MmCoreDumpPageFrame).QuadPart >> PAGE_SHIFT);
|
||||
#if defined(__GNUC__)
|
||||
|
||||
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, (LARGE_INTEGER)0LL);
|
||||
#else
|
||||
|
||||
{
|
||||
const LARGE_INTEGER dummy =
|
||||
{
|
||||
0
|
||||
};
|
||||
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, dummy);
|
||||
}
|
||||
#endif
|
||||
DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart;
|
||||
Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MM: Failed to write core dump header\n.");
|
||||
return(Status);
|
||||
}
|
||||
NextOffset += PAGE_SIZE;
|
||||
;
|
||||
DbgPrint("00");
|
||||
|
||||
|
||||
/* Write out the contents of physical memory. */
|
||||
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
||||
{
|
||||
for (i = 0; i < MmStats.NrTotalPages; i++)
|
||||
{
|
||||
MdlMap[0] = i;
|
||||
MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
|
||||
PAGE_READWRITE,
|
||||
MdlMap,
|
||||
1);
|
||||
#if defined(__GNUC__)
|
||||
|
||||
DiskOffset = MmGetOffsetPageFile(RetrievalPointers,
|
||||
(LARGE_INTEGER)NextOffset);
|
||||
#else
|
||||
|
||||
{
|
||||
LARGE_INTEGER dummy;
|
||||
dummy.QuadPart = NextOffset;
|
||||
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, dummy);
|
||||
}
|
||||
#endif
|
||||
DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart;
|
||||
Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl);
|
||||
MmRawDeleteVirtualMapping(MmCoreDumpPageFrame);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MM: Failed to write page to core dump.\n");
|
||||
return(Status);
|
||||
}
|
||||
if ((i % ((1024*1024) / PAGE_SIZE)) == 0)
|
||||
{
|
||||
DbgPrint("\b\b%.2d", i / ((1024*1024)/PAGE_SIZE));
|
||||
}
|
||||
NextOffset += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
DbgPrint("\n");
|
||||
MmCoreDumpFunctions->DumpFinish();
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum)
|
||||
{
|
||||
PFILE_OBJECT PageFile;
|
||||
PDEVICE_OBJECT PageFileDevice;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
UNICODE_STRING DiskDumpName = RTL_CONSTANT_STRING(L"DiskDump");
|
||||
ANSI_STRING ProcName;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
PLDR_DATA_TABLE_ENTRY ModuleObject = NULL;
|
||||
PVOID BaseAddress;
|
||||
|
||||
Status = ZwFsControlFile(PageFileHandle,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&Iosb,
|
||||
FSCTL_ROS_QUERY_LCN_MAPPING,
|
||||
NULL,
|
||||
0,
|
||||
&MmCoreDumpLcnMapping,
|
||||
sizeof(ROS_QUERY_LCN_MAPPING));
|
||||
if (!NT_SUCCESS(Status) ||
|
||||
Iosb.Information != sizeof(ROS_QUERY_LCN_MAPPING))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Get the underlying storage device. */
|
||||
Status =
|
||||
ObReferenceObjectByHandle(PageFileHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
NULL,
|
||||
KernelMode,
|
||||
(PVOID*)&PageFile,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
PageFileDevice = PageFile->Vpb->RealDevice;
|
||||
|
||||
/* Get the dump pointers. */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_GET_DUMP_POINTERS,
|
||||
PageFileDevice,
|
||||
NULL,
|
||||
0,
|
||||
&MmCoreDumpPointers,
|
||||
sizeof(MmCoreDumpPointers),
|
||||
FALSE,
|
||||
&Event,
|
||||
&Iosb);
|
||||
if(Irp == NULL)
|
||||
{
|
||||
ObDereferenceObject(PageFile);
|
||||
return(STATUS_NO_MEMORY);// tMk - is this correct return code ???
|
||||
}
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->FileObject = PageFile;
|
||||
StackPtr->DeviceObject = PageFileDevice;
|
||||
StackPtr->Parameters.DeviceIoControl.InputBufferLength = 0;
|
||||
StackPtr->Parameters.DeviceIoControl.OutputBufferLength = sizeof(MmCoreDumpPointers);
|
||||
|
||||
Status = IoCallDriver(PageFileDevice,Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
}
|
||||
if (Status != STATUS_SUCCESS ||
|
||||
Iosb.Information != sizeof(MmCoreDumpPointers))
|
||||
{
|
||||
ObDereferenceObject(PageFile);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Load the diskdump driver. */
|
||||
Status = MmLoadSystemImage(&DiskDumpName, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
|
||||
if (ModuleObject == NULL)
|
||||
{
|
||||
return(STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
}
|
||||
RtlInitAnsiString(&ProcName, "DiskDumpFunctions");
|
||||
MmCoreDumpFunctions = MiFindExportedRoutineByName(BaseAddress,
|
||||
&ProcName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(PageFile);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Prepare for disk dumping. */
|
||||
Status = MmCoreDumpFunctions->DumpPrepare(PageFileDevice,
|
||||
&MmCoreDumpPointers);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(PageFile);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
MmCoreDumpPageFile = PageFileNum;
|
||||
ObDereferenceObject(PageFile);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||
IN PLARGE_INTEGER InitialSize,
|
||||
@@ -1135,13 +853,6 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||
MiPagingFileCount++;
|
||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||
|
||||
/* Check whether this pagefile can be a crash dump target. */
|
||||
if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE &&
|
||||
PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize &&
|
||||
MmCoreDumpPageFile == 0xFFFFFFFF)
|
||||
{
|
||||
MmInitializeCrashDump(FileHandle, i);
|
||||
}
|
||||
ZwClose(FileHandle);
|
||||
|
||||
MmSwapSpaceMessage = FALSE;
|
||||
|
||||
Reference in New Issue
Block a user