2018-08-13 05:42:57 +00:00
|
|
|
|
/*
|
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
|
* FILE: ntoskrnl/mm/shutdown.c
|
|
|
|
|
* PURPOSE: Memory Manager Shutdown
|
|
|
|
|
* PROGRAMMERS:
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
|
#define NDEBUG
|
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
|
|
#define MODULE_INVOLVED_IN_ARM3
|
|
|
|
|
#include "ARM3/miarm.h"
|
|
|
|
|
|
|
|
|
|
/* PRIVATE FUNCTIONS *********************************************************/
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
|
MiShutdownSystem(VOID)
|
|
|
|
|
{
|
2018-08-13 05:52:05 +00:00
|
|
|
|
ULONG i;
|
2021-01-27 09:29:07 +00:00
|
|
|
|
PFN_NUMBER Page;
|
|
|
|
|
BOOLEAN Dirty;
|
|
|
|
|
|
2021-02-10 10:06:44 +00:00
|
|
|
|
/* Loop through all the paging files */
|
|
|
|
|
for (i = 0; i < MmNumberOfPagingFiles; i++)
|
|
|
|
|
{
|
|
|
|
|
/* Free page file name */
|
|
|
|
|
ASSERT(MmPagingFile[i]->PageFileName.Buffer != NULL);
|
|
|
|
|
ExFreePoolWithTag(MmPagingFile[i]->PageFileName.Buffer, TAG_MM);
|
|
|
|
|
MmPagingFile[i]->PageFileName.Buffer = NULL;
|
|
|
|
|
|
|
|
|
|
/* And close them */
|
|
|
|
|
ZwClose(MmPagingFile[i]->FileHandle);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-27 09:29:07 +00:00
|
|
|
|
/* Loop through all the pages owned by the legacy Mm and page them out, if needed. */
|
2021-02-10 10:06:44 +00:00
|
|
|
|
/* We do it as long as there are dirty pages, since flushing can cause the FS to dirtify new ones. */
|
2021-01-27 09:29:07 +00:00
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
Dirty = FALSE;
|
|
|
|
|
|
|
|
|
|
Page = MmGetLRUFirstUserPage();
|
|
|
|
|
while (Page)
|
|
|
|
|
{
|
|
|
|
|
LARGE_INTEGER SegmentOffset;
|
|
|
|
|
PMM_SECTION_SEGMENT Segment = MmGetSectionAssociation(Page, &SegmentOffset);
|
|
|
|
|
|
|
|
|
|
if (Segment)
|
|
|
|
|
{
|
|
|
|
|
if ((*Segment->Flags) & MM_DATAFILE_SEGMENT)
|
|
|
|
|
{
|
|
|
|
|
MmLockSectionSegment(Segment);
|
|
|
|
|
|
|
|
|
|
ULONG_PTR Entry = MmGetPageEntrySectionSegment(Segment, &SegmentOffset);
|
|
|
|
|
|
|
|
|
|
if (!IS_SWAP_FROM_SSE(Entry) && IS_DIRTY_SSE(Entry))
|
|
|
|
|
{
|
|
|
|
|
Dirty = TRUE;
|
|
|
|
|
MmCheckDirtySegment(Segment, &SegmentOffset, FALSE, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MmUnlockSectionSegment(Segment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MmDereferenceSegment(Segment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Page = MmGetLRUNextUserPage(Page, FALSE);
|
|
|
|
|
}
|
|
|
|
|
} while (Dirty);
|
2018-08-13 05:42:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
|
MmShutdownSystem(IN ULONG Phase)
|
|
|
|
|
{
|
|
|
|
|
if (Phase == 0)
|
|
|
|
|
{
|
|
|
|
|
MiShutdownSystem();
|
|
|
|
|
}
|
2018-08-13 06:23:44 +00:00
|
|
|
|
else if (Phase == 1)
|
|
|
|
|
{
|
|
|
|
|
ULONG i;
|
|
|
|
|
|
|
|
|
|
/* Loop through all the paging files */
|
|
|
|
|
for (i = 0; i < MmNumberOfPagingFiles; i++)
|
|
|
|
|
{
|
|
|
|
|
/* And dereference them */
|
|
|
|
|
ObDereferenceObject(MmPagingFile[i]->FileObject);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-08-13 05:42:57 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2018-08-13 06:23:44 +00:00
|
|
|
|
ASSERT(Phase == 2);
|
|
|
|
|
|
2018-08-13 05:42:57 +00:00
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
}
|