xref: /reactos/ntoskrnl/mm/shutdown.c (revision 73fd52a1)
1 /*
2  * PROJECT:         ReactOS Kernel
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            ntoskrnl/mm/shutdown.c
5  * PURPOSE:         Memory Manager Shutdown
6  * PROGRAMMERS:
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define MODULE_INVOLVED_IN_ARM3
16 #include "ARM3/miarm.h"
17 
18 /* PRIVATE FUNCTIONS *********************************************************/
19 
20 VOID
MiShutdownSystem(VOID)21 MiShutdownSystem(VOID)
22 {
23     ULONG i;
24     PFN_NUMBER Page;
25     BOOLEAN Dirty;
26 
27     /* Loop through all the paging files */
28     for (i = 0; i < MmNumberOfPagingFiles; i++)
29     {
30         /* Free page file name */
31         ASSERT(MmPagingFile[i]->PageFileName.Buffer != NULL);
32         ExFreePoolWithTag(MmPagingFile[i]->PageFileName.Buffer, TAG_MM);
33         MmPagingFile[i]->PageFileName.Buffer = NULL;
34 
35         /* And close them */
36         ZwClose(MmPagingFile[i]->FileHandle);
37     }
38 
39     /* Loop through all the pages owned by the legacy Mm and page them out, if needed. */
40     /* We do it as long as there are dirty pages, since flushing can cause the FS to dirtify new ones. */
41     do
42     {
43         Dirty = FALSE;
44 
45         Page = MmGetLRUFirstUserPage();
46         while (Page)
47         {
48             LARGE_INTEGER SegmentOffset;
49             PMM_SECTION_SEGMENT Segment = MmGetSectionAssociation(Page, &SegmentOffset);
50 
51             if (Segment)
52             {
53                 if ((*Segment->Flags) & MM_DATAFILE_SEGMENT)
54                 {
55                     MmLockSectionSegment(Segment);
56 
57                     ULONG_PTR Entry = MmGetPageEntrySectionSegment(Segment, &SegmentOffset);
58 
59                     if (!IS_SWAP_FROM_SSE(Entry) && IS_DIRTY_SSE(Entry))
60                     {
61                         Dirty = TRUE;
62                         MmCheckDirtySegment(Segment, &SegmentOffset, FALSE, TRUE);
63                     }
64 
65                     MmUnlockSectionSegment(Segment);
66                 }
67 
68                 MmDereferenceSegment(Segment);
69             }
70 
71             Page = MmGetLRUNextUserPage(Page, FALSE);
72         }
73     } while (Dirty);
74 }
75 
76 VOID
MmShutdownSystem(IN ULONG Phase)77 MmShutdownSystem(IN ULONG Phase)
78 {
79     if (Phase == 0)
80     {
81         MiShutdownSystem();
82     }
83     else if (Phase == 1)
84     {
85         ULONG i;
86 
87         /* Loop through all the paging files */
88         for (i = 0; i < MmNumberOfPagingFiles; i++)
89         {
90             /* And dereference them */
91             ObDereferenceObject(MmPagingFile[i]->FileObject);
92         }
93     }
94     else
95     {
96         ASSERT(Phase == 2);
97 
98         UNIMPLEMENTED;
99     }
100 }
101