xref: /reactos/ntoskrnl/include/internal/mm.h (revision 84344399)
1 #pragma once
2 
3 #include <internal/arch/mm.h>
4 
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8 
9 /* TYPES *********************************************************************/
10 
11 struct _EPROCESS;
12 
13 extern PMMSUPPORT MmKernelAddressSpace;
14 extern PFN_COUNT MiFreeSwapPages;
15 extern PFN_COUNT MiUsedSwapPages;
16 extern PFN_COUNT MmNumberOfPhysicalPages;
17 extern UCHAR MmDisablePagingExecutive;
18 extern PFN_NUMBER MmLowestPhysicalPage;
19 extern PFN_NUMBER MmHighestPhysicalPage;
20 extern PFN_NUMBER MmAvailablePages;
21 extern PFN_NUMBER MmResidentAvailablePages;
22 extern ULONG MmThrottleTop;
23 extern ULONG MmThrottleBottom;
24 
25 extern LIST_ENTRY MmLoadedUserImageList;
26 
27 extern KMUTANT MmSystemLoadLock;
28 
29 extern ULONG MmNumberOfPagingFiles;
30 
31 extern SIZE_T MmTotalNonPagedPoolQuota;
32 extern SIZE_T MmTotalPagedPoolQuota;
33 
34 extern PVOID MmUnloadedDrivers;
35 extern PVOID MmLastUnloadedDrivers;
36 extern PVOID MmTriageActionTaken;
37 extern PVOID KernelVerifier;
38 extern MM_DRIVER_VERIFIER_DATA MmVerifierData;
39 
40 extern SIZE_T MmTotalCommitLimit;
41 extern SIZE_T MmTotalCommittedPages;
42 extern SIZE_T MmSharedCommit;
43 extern SIZE_T MmDriverCommit;
44 extern SIZE_T MmProcessCommit;
45 extern SIZE_T MmPagedPoolCommit;
46 extern SIZE_T MmPeakCommitment;
47 extern SIZE_T MmtotalCommitLimitMaximum;
48 
49 extern PVOID MiDebugMapping; // internal
50 extern PMMPTE MmDebugPte; // internal
51 
52 extern KSPIN_LOCK MmPfnLock;
53 
54 struct _KTRAP_FRAME;
55 struct _EPROCESS;
56 struct _MM_RMAP_ENTRY;
57 typedef ULONG_PTR SWAPENTRY;
58 
59 //
60 // Pool Quota values
61 //
62 #define MI_QUOTA_NON_PAGED_NEEDED_PAGES             64
63 #define MI_NON_PAGED_QUOTA_MIN_RESIDENT_PAGES       200
64 #define MI_CHARGE_PAGED_POOL_QUOTA                  0x80000
65 #define MI_CHARGE_NON_PAGED_POOL_QUOTA              0x10000
66 
67 //
68 // Special IRQL value (found in assertions)
69 //
70 #define MM_NOIRQL ((KIRQL)0xFFFFFFFF)
71 
72 //
73 // MmDbgCopyMemory Flags
74 //
75 #define MMDBG_COPY_WRITE            0x00000001
76 #define MMDBG_COPY_PHYSICAL         0x00000002
77 #define MMDBG_COPY_UNSAFE           0x00000004
78 #define MMDBG_COPY_CACHED           0x00000008
79 #define MMDBG_COPY_UNCACHED         0x00000010
80 #define MMDBG_COPY_WRITE_COMBINED   0x00000020
81 
82 //
83 // Maximum chunk size per copy
84 //
85 #define MMDBG_COPY_MAX_SIZE         0x8
86 
87 #if defined(_X86_) // intenal for marea.c
88 #define MI_STATIC_MEMORY_AREAS              (14)
89 #else
90 #define MI_STATIC_MEMORY_AREAS              (13)
91 #endif
92 
93 #define MEMORY_AREA_SECTION_VIEW            (1)
94 #ifdef NEWCC
95 #define MEMORY_AREA_CACHE                   (2)
96 #endif
97 #define MEMORY_AREA_OWNED_BY_ARM3           (15)
98 #define MEMORY_AREA_STATIC                  (0x80000000)
99 
100 /* Although Microsoft says this isn't hardcoded anymore,
101    they won't be able to change it. Stuff depends on it */
102 #define MM_VIRTMEM_GRANULARITY              (64 * 1024)
103 
104 #define STATUS_MM_RESTART_OPERATION         ((NTSTATUS)0xD0000001)
105 
106 /*
107  * Additional flags for protection attributes
108  */
109 #define PAGE_WRITETHROUGH                   (1024)
110 #define PAGE_SYSTEM                         (2048)
111 
112 #define SEC_PHYSICALMEMORY                  (0x80000000)
113 
114 #define MC_USER                             (0)
115 #define MC_SYSTEM                           (1)
116 #define MC_MAXIMUM                          (2)
117 
118 #define PAGED_POOL_MASK                     1
119 #define MUST_SUCCEED_POOL_MASK              2
120 #define CACHE_ALIGNED_POOL_MASK             4
121 #define QUOTA_POOL_MASK                     8
122 #define SESSION_POOL_MASK                   32
123 #define VERIFIER_POOL_MASK                  64
124 
125 #define MAX_PAGING_FILES                    (16)
126 
127 // FIXME: use ALIGN_UP_BY
128 #define MM_ROUND_UP(x,s)                    \
129     ((PVOID)(((ULONG_PTR)(x)+(s)-1) & ~((ULONG_PTR)(s)-1)))
130 
131 #define MM_ROUND_DOWN(x,s)                  \
132     ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1)))
133 
134 #define PAGE_FLAGS_VALID_FOR_SECTION \
135     (PAGE_READONLY | \
136      PAGE_READWRITE | \
137      PAGE_WRITECOPY | \
138      PAGE_EXECUTE | \
139      PAGE_EXECUTE_READ | \
140      PAGE_EXECUTE_READWRITE | \
141      PAGE_EXECUTE_WRITECOPY | \
142      PAGE_NOACCESS | \
143      PAGE_NOCACHE)
144 
145 #define PAGE_IS_READABLE                    \
146     (PAGE_READONLY | \
147     PAGE_READWRITE | \
148     PAGE_WRITECOPY | \
149     PAGE_EXECUTE_READ | \
150     PAGE_EXECUTE_READWRITE | \
151     PAGE_EXECUTE_WRITECOPY)
152 
153 #define PAGE_IS_WRITABLE                    \
154     (PAGE_READWRITE | \
155     PAGE_WRITECOPY | \
156     PAGE_EXECUTE_READWRITE | \
157     PAGE_EXECUTE_WRITECOPY)
158 
159 #define PAGE_IS_EXECUTABLE                  \
160     (PAGE_EXECUTE | \
161     PAGE_EXECUTE_READ | \
162     PAGE_EXECUTE_READWRITE | \
163     PAGE_EXECUTE_WRITECOPY)
164 
165 #define PAGE_IS_WRITECOPY                   \
166     (PAGE_WRITECOPY | \
167     PAGE_EXECUTE_WRITECOPY)
168 
169 //
170 // Wait entry for marking pages that are being serviced
171 //
172 #ifdef _M_IX86
173 #define MM_WAIT_ENTRY            0x7ffffc00
174 #elif defined(_M_AMD64)
175 #define MM_WAIT_ENTRY            0x7FFFFFFFFFFFFC00ULL
176 #else
177 #error Unsupported architecture!
178 #endif
179 
180 #ifdef _M_AMD64
181 #define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand) \
182     InterlockedCompareExchange64((PLONG64)(PointerPte), Exchange, Comperand)
183 
184 #define InterlockedExchangePte(PointerPte, Value) \
185     InterlockedExchange64((PLONG64)(PointerPte), Value)
186 #else
187 #define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand) \
188     InterlockedCompareExchange((PLONG)(PointerPte), Exchange, Comperand)
189 
190 #define InterlockedExchangePte(PointerPte, Value) \
191     InterlockedExchange((PLONG)(PointerPte), Value)
192 #endif
193 
194 typedef struct _MM_SECTION_SEGMENT
195 {
196     LONG64 RefCount;
197     PFILE_OBJECT FileObject;
198 
199     FAST_MUTEX Lock;		/* lock which protects the page directory */
200     LARGE_INTEGER RawLength;		/* length of the segment which is part of the mapped file */
201     LARGE_INTEGER Length;			/* absolute length of the segment */
202     PLONG64 ReferenceCount;
203 	ULONG SectionCount;
204     ULONG Protection;
205     PULONG Flags;
206     BOOLEAN WriteCopy;
207 	BOOLEAN Locked;
208 
209 	struct
210 	{
211 		ULONGLONG FileOffset;		/* start offset into the file for image sections */
212 		ULONG_PTR VirtualAddress;	/* start offset into the address range for image sections */
213 		ULONG Characteristics;
214 	} Image;
215 
216 	ULONG SegFlags;
217 
218     ULONGLONG LastPage;
219 
220 	RTL_GENERIC_TABLE PageTable;
221 } MM_SECTION_SEGMENT, *PMM_SECTION_SEGMENT;
222 
223 typedef struct _MM_IMAGE_SECTION_OBJECT
224 {
225     LONG64 RefCount;
226     PFILE_OBJECT FileObject;
227     ULONG SectionCount;
228     LONG MapCount;
229     ULONG SegFlags;
230 
231     SECTION_IMAGE_INFORMATION ImageInformation;
232     PVOID BasedAddress;
233     ULONG NrSegments;
234     PMM_SECTION_SEGMENT Segments;
235 } MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
236 
237 #define MM_PHYSICALMEMORY_SEGMENT           (0x1)
238 #define MM_DATAFILE_SEGMENT                 (0x2)
239 #define MM_SEGMENT_INDELETE                 (0x4)
240 #define MM_SEGMENT_INCREATE                 (0x8)
241 #define MM_IMAGE_SECTION_FLUSH_DELETE       (0x10)
242 
243 
244 #define MA_GetStartingAddress(_MemoryArea) ((_MemoryArea)->VadNode.StartingVpn << PAGE_SHIFT)
245 #define MA_GetEndingAddress(_MemoryArea) (((_MemoryArea)->VadNode.EndingVpn + 1) << PAGE_SHIFT)
246 
247 typedef struct _MEMORY_AREA
248 {
249     MMVAD VadNode;
250 
251     ULONG Type;
252     ULONG Flags;
253     BOOLEAN DeleteInProgress;
254     ULONG Magic;
255     PVOID Vad;
256 
257     struct
258     {
259         LONGLONG ViewOffset;
260         PMM_SECTION_SEGMENT Segment;
261         LIST_ENTRY RegionListHead;
262     } SectionData;
263 } MEMORY_AREA, *PMEMORY_AREA;
264 
265 typedef struct _MM_RMAP_ENTRY
266 {
267    struct _MM_RMAP_ENTRY* Next;
268    PEPROCESS Process;
269    PVOID Address;
270 #if DBG
271    PVOID Caller;
272 #endif
273 }
274 MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
275 
276 #if MI_TRACE_PFNS
277 extern ULONG MI_PFN_CURRENT_USAGE;
278 extern CHAR MI_PFN_CURRENT_PROCESS_NAME[16];
279 #define MI_SET_USAGE(x)     MI_PFN_CURRENT_USAGE = x
280 #define MI_SET_PROCESS2(x)  memcpy(MI_PFN_CURRENT_PROCESS_NAME, x, min(sizeof(x), sizeof(MI_PFN_CURRENT_PROCESS_NAME)))
281 FORCEINLINE
282 void
283 MI_SET_PROCESS(PEPROCESS Process)
284 {
285     if (!Process)
286         MI_SET_PROCESS2("Kernel");
287     else if (Process == (PEPROCESS)1)
288         MI_SET_PROCESS2("Hydra");
289     else
290         MI_SET_PROCESS2(Process->ImageFileName);
291 }
292 
293 FORCEINLINE
294 void
295 MI_SET_PROCESS_USTR(PUNICODE_STRING ustr)
296 {
297     PWSTR pos, strEnd;
298     ULONG i;
299 
300     if (!ustr->Buffer || ustr->Length == 0)
301     {
302         MI_PFN_CURRENT_PROCESS_NAME[0] = 0;
303         return;
304     }
305 
306     pos = strEnd = &ustr->Buffer[ustr->Length / sizeof(WCHAR)];
307     while ((*pos != L'\\') && (pos >  ustr->Buffer))
308         pos--;
309 
310     if (*pos == L'\\')
311         pos++;
312 
313     for (i = 0; i < sizeof(MI_PFN_CURRENT_PROCESS_NAME) && pos <= strEnd; i++, pos++)
314         MI_PFN_CURRENT_PROCESS_NAME[i] = (CHAR)*pos;
315 }
316 #else
317 #define MI_SET_USAGE(x)
318 #define MI_SET_PROCESS(x)
319 #define MI_SET_PROCESS2(x)
320 #endif
321 
322 typedef enum _MI_PFN_USAGES
323 {
324     MI_USAGE_NOT_SET = 0,
325     MI_USAGE_PAGED_POOL,
326     MI_USAGE_NONPAGED_POOL,
327     MI_USAGE_NONPAGED_POOL_EXPANSION,
328     MI_USAGE_KERNEL_STACK,
329     MI_USAGE_KERNEL_STACK_EXPANSION,
330     MI_USAGE_SYSTEM_PTE,
331     MI_USAGE_VAD,
332     MI_USAGE_PEB_TEB,
333     MI_USAGE_SECTION,
334     MI_USAGE_PAGE_TABLE,
335     MI_USAGE_PAGE_DIRECTORY,
336     MI_USAGE_LEGACY_PAGE_DIRECTORY,
337     MI_USAGE_DRIVER_PAGE,
338     MI_USAGE_CONTINOUS_ALLOCATION,
339     MI_USAGE_MDL,
340     MI_USAGE_DEMAND_ZERO,
341     MI_USAGE_ZERO_LOOP,
342     MI_USAGE_CACHE,
343     MI_USAGE_PFN_DATABASE,
344     MI_USAGE_BOOT_DRIVER,
345     MI_USAGE_INIT_MEMORY,
346     MI_USAGE_PAGE_FILE,
347     MI_USAGE_COW,
348     MI_USAGE_WSLE,
349     MI_USAGE_FREE_PAGE
350 } MI_PFN_USAGES;
351 
352 //
353 // These two mappings are actually used by Windows itself, based on the ASSERTS
354 //
355 #define StartOfAllocation ReadInProgress
356 #define EndOfAllocation WriteInProgress
357 
358 typedef struct _MMPFNENTRY
359 {
360     USHORT Modified:1;
361     USHORT ReadInProgress:1;                 // StartOfAllocation
362     USHORT WriteInProgress:1;                // EndOfAllocation
363     USHORT PrototypePte:1;
364     USHORT PageColor:4;
365     USHORT PageLocation:3;
366     USHORT RemovalRequested:1;
367     USHORT CacheAttribute:2;
368     USHORT Rom:1;
369     USHORT ParityError:1;
370 } MMPFNENTRY;
371 
372 // Mm internal
373 typedef struct _MMPFN
374 {
375     union
376     {
377         PFN_NUMBER Flink;
378         ULONG WsIndex;
379         PKEVENT Event;
380         NTSTATUS ReadStatus;
381         SINGLE_LIST_ENTRY NextStackPfn;
382 
383         // HACK for ROSPFN
384         SWAPENTRY SwapEntry;
385     } u1;
386     PMMPTE PteAddress;
387     union
388     {
389         PFN_NUMBER Blink;
390         ULONG_PTR ShareCount;
391     } u2;
392     union
393     {
394         struct
395         {
396             USHORT ReferenceCount;
397             MMPFNENTRY e1;
398         };
399         struct
400         {
401             USHORT ReferenceCount;
402             USHORT ShortFlags;
403         } e2;
404     } u3;
405     union
406     {
407         MMPTE OriginalPte;
408         LONG AweReferenceCount;
409 
410         // HACK for ROSPFN
411         PMM_RMAP_ENTRY RmapListHead;
412     };
413     union
414     {
415         ULONG_PTR EntireFrame;
416         struct
417         {
418             ULONG_PTR PteFrame:25;
419             ULONG_PTR InPageError:1;
420             ULONG_PTR VerifierAllocation:1;
421             ULONG_PTR AweAllocation:1;
422             ULONG_PTR Priority:3;
423             ULONG_PTR MustBeCached:1;
424         };
425     } u4;
426 #if MI_TRACE_PFNS
427     MI_PFN_USAGES PfnUsage;
428     CHAR ProcessName[16];
429 #define MI_SET_PFN_PROCESS_NAME(pfn, x) memcpy(pfn->ProcessName, x, min(sizeof(x), sizeof(pfn->ProcessName)))
430     PVOID CallSite;
431 #endif
432 
433     // HACK until WS lists are supported
434     MMWSLE Wsle;
435     struct _MMPFN* NextLRU;
436     struct _MMPFN* PreviousLRU;
437 } MMPFN, *PMMPFN;
438 
439 extern PMMPFN MmPfnDatabase;
440 
441 typedef struct _MMPFNLIST
442 {
443     PFN_NUMBER Total;
444     MMLISTS ListName;
445     PFN_NUMBER Flink;
446     PFN_NUMBER Blink;
447 } MMPFNLIST, *PMMPFNLIST;
448 
449 extern MMPFNLIST MmZeroedPageListHead;
450 extern MMPFNLIST MmFreePageListHead;
451 extern MMPFNLIST MmStandbyPageListHead;
452 extern MMPFNLIST MmModifiedPageListHead;
453 extern MMPFNLIST MmModifiedNoWritePageListHead;
454 
455 typedef struct _MM_MEMORY_CONSUMER
456 {
457     ULONG PagesUsed;
458     ULONG PagesTarget;
459     NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed);
460 } MM_MEMORY_CONSUMER, *PMM_MEMORY_CONSUMER;
461 
462 typedef struct _MM_REGION
463 {
464     ULONG Type;
465     ULONG Protect;
466     SIZE_T Length;
467     LIST_ENTRY RegionListEntry;
468 } MM_REGION, *PMM_REGION;
469 
470 // Mm internal
471 /* Entry describing free pool memory */
472 typedef struct _MMFREE_POOL_ENTRY
473 {
474     LIST_ENTRY List;
475     PFN_COUNT Size;
476     ULONG Signature;
477     struct _MMFREE_POOL_ENTRY *Owner;
478 } MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
479 
480 /* Signature of a freed block */
481 #define MM_FREE_POOL_SIGNATURE 'ARM3'
482 
483 /* Paged pool information */
484 typedef struct _MM_PAGED_POOL_INFO
485 {
486     PRTL_BITMAP PagedPoolAllocationMap;
487     PRTL_BITMAP EndOfPagedPoolBitmap;
488     PMMPTE FirstPteForPagedPool;
489     PMMPTE LastPteForPagedPool;
490     PMMPDE NextPdeForPagedPoolExpansion;
491     ULONG PagedPoolHint;
492     SIZE_T PagedPoolCommit;
493     SIZE_T AllocatedPagedPool;
494 } MM_PAGED_POOL_INFO, *PMM_PAGED_POOL_INFO;
495 
496 extern MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
497 
498 /* Page file information */
499 typedef struct _MMPAGING_FILE
500 {
501     PFN_NUMBER Size;
502     PFN_NUMBER MaximumSize;
503     PFN_NUMBER MinimumSize;
504     PFN_NUMBER FreeSpace;
505     PFN_NUMBER CurrentUsage;
506     PFILE_OBJECT FileObject;
507     UNICODE_STRING PageFileName;
508     PRTL_BITMAP Bitmap;
509     HANDLE FileHandle;
510 }
511 MMPAGING_FILE, *PMMPAGING_FILE;
512 
513 extern PMMPAGING_FILE MmPagingFile[MAX_PAGING_FILES];
514 
515 typedef VOID
516 (*PMM_ALTER_REGION_FUNC)(
517     PMMSUPPORT AddressSpace,
518     PVOID BaseAddress,
519     SIZE_T Length,
520     ULONG OldType,
521     ULONG OldProtect,
522     ULONG NewType,
523     ULONG NewProtect
524 );
525 
526 typedef VOID
527 (*PMM_FREE_PAGE_FUNC)(
528     PVOID Context,
529     PMEMORY_AREA MemoryArea,
530     PVOID Address,
531     PFN_NUMBER Page,
532     SWAPENTRY SwapEntry,
533     BOOLEAN Dirty
534 );
535 
536 //
537 // Mm copy support for Kd
538 //
539 NTSTATUS
540 NTAPI
541 MmDbgCopyMemory(
542     IN ULONG64 Address,
543     IN PVOID Buffer,
544     IN ULONG Size,
545     IN ULONG Flags
546 );
547 
548 //
549 // Determines if a given address is a session address
550 //
551 BOOLEAN
552 NTAPI
553 MmIsSessionAddress(
554     IN PVOID Address
555 );
556 
557 ULONG
558 NTAPI
559 MmGetSessionId(
560     IN PEPROCESS Process
561 );
562 
563 ULONG
564 NTAPI
565 MmGetSessionIdEx(
566     IN PEPROCESS Process
567 );
568 
569 /* marea.c *******************************************************************/
570 
571 NTSTATUS
572 NTAPI
573 MmCreateMemoryArea(
574     PMMSUPPORT AddressSpace,
575     ULONG Type,
576     PVOID *BaseAddress,
577     SIZE_T Length,
578     ULONG Protection,
579     PMEMORY_AREA *Result,
580     ULONG AllocationFlags,
581     ULONG AllocationGranularity
582 );
583 
584 PMEMORY_AREA
585 NTAPI
586 MmLocateMemoryAreaByAddress(
587     PMMSUPPORT AddressSpace,
588     PVOID Address
589 );
590 
591 NTSTATUS
592 NTAPI
593 MmFreeMemoryArea(
594     PMMSUPPORT AddressSpace,
595     PMEMORY_AREA MemoryArea,
596     PMM_FREE_PAGE_FUNC FreePage,
597     PVOID FreePageContext
598 );
599 
600 VOID
601 NTAPI
602 MiRosCleanupMemoryArea(
603     PEPROCESS Process,
604     PMMVAD Vad);
605 
606 PMEMORY_AREA
607 NTAPI
608 MmLocateMemoryAreaByRegion(
609     PMMSUPPORT AddressSpace,
610     PVOID Address,
611     SIZE_T Length
612 );
613 
614 PVOID
615 NTAPI
616 MmFindGap(
617     PMMSUPPORT AddressSpace,
618     SIZE_T Length,
619     ULONG_PTR Granularity,
620     BOOLEAN TopDown
621 );
622 
623 VOID
624 NTAPI
625 MiRosCheckMemoryAreas(
626    PMMSUPPORT AddressSpace);
627 
628 VOID
629 NTAPI
630 MiCheckAllProcessMemoryAreas(VOID);
631 
632 /* npool.c *******************************************************************/
633 
634 CODE_SEG("INIT")
635 VOID
636 NTAPI
637 MiInitializeNonPagedPool(VOID);
638 
639 PVOID
640 NTAPI
641 MiAllocatePoolPages(
642     IN POOL_TYPE PoolType,
643     IN SIZE_T SizeInBytes
644 );
645 
646 POOL_TYPE
647 NTAPI
648 MmDeterminePoolType(
649     IN PVOID VirtualAddress
650 );
651 
652 ULONG
653 NTAPI
654 MiFreePoolPages(
655     IN PVOID StartingAddress
656 );
657 
658 /* pool.c *******************************************************************/
659 
660 _Requires_lock_held_(PspQuotaLock)
661 BOOLEAN
662 NTAPI
663 MmRaisePoolQuota(
664     _In_ POOL_TYPE PoolType,
665     _In_ SIZE_T CurrentMaxQuota,
666     _Out_ PSIZE_T NewMaxQuota
667 );
668 
669 _Requires_lock_held_(PspQuotaLock)
670 VOID
671 NTAPI
672 MmReturnPoolQuota(
673     _In_ POOL_TYPE PoolType,
674     _In_ SIZE_T QuotaToReturn
675 );
676 
677 /* mdl.c *********************************************************************/
678 
679 VOID
680 NTAPI
681 MmBuildMdlFromPages(
682     PMDL Mdl,
683     PPFN_NUMBER Pages
684 );
685 
686 /* mminit.c ******************************************************************/
687 
688 VOID
689 NTAPI
690 MmInit1(
691     VOID
692 );
693 
694 CODE_SEG("INIT")
695 BOOLEAN
696 NTAPI
697 MmInitSystem(IN ULONG Phase,
698              IN PLOADER_PARAMETER_BLOCK LoaderBlock);
699 
700 
701 /* pagefile.c ****************************************************************/
702 
703 SWAPENTRY
704 NTAPI
705 MmAllocSwapPage(VOID);
706 
707 VOID
708 NTAPI
709 MmFreeSwapPage(SWAPENTRY Entry);
710 
711 CODE_SEG("INIT")
712 VOID
713 NTAPI
714 MmInitPagingFile(VOID);
715 
716 BOOLEAN
717 NTAPI
718 MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject);
719 
720 NTSTATUS
721 NTAPI
722 MmReadFromSwapPage(
723     SWAPENTRY SwapEntry,
724     PFN_NUMBER Page
725 );
726 
727 NTSTATUS
728 NTAPI
729 MmWriteToSwapPage(
730     SWAPENTRY SwapEntry,
731     PFN_NUMBER Page
732 );
733 
734 VOID
735 NTAPI
736 MmShowOutOfSpaceMessagePagingFile(VOID);
737 
738 NTSTATUS
739 NTAPI
740 MiReadPageFile(
741     _In_ PFN_NUMBER Page,
742     _In_ ULONG PageFileIndex,
743     _In_ ULONG_PTR PageFileOffset);
744 
745 /* process.c ****************************************************************/
746 
747 NTSTATUS
748 NTAPI
749 MmInitializeProcessAddressSpace(
750     IN PEPROCESS Process,
751     IN PEPROCESS Clone OPTIONAL,
752     IN PVOID Section OPTIONAL,
753     IN OUT PULONG Flags,
754     IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL
755 );
756 
757 NTSTATUS
758 NTAPI
759 MmCreatePeb(
760     IN PEPROCESS Process,
761     IN PINITIAL_PEB InitialPeb,
762     OUT PPEB *BasePeb
763 );
764 
765 NTSTATUS
766 NTAPI
767 MmCreateTeb(
768     IN PEPROCESS Process,
769     IN PCLIENT_ID ClientId,
770     IN PINITIAL_TEB InitialTeb,
771     OUT PTEB* BaseTeb
772 );
773 
774 VOID
775 NTAPI
776 MmDeleteTeb(
777     struct _EPROCESS *Process,
778     PTEB Teb
779 );
780 
781 VOID
782 NTAPI
783 MmCleanProcessAddressSpace(IN PEPROCESS Process);
784 
785 VOID
786 NTAPI
787 MmDeleteProcessAddressSpace(IN PEPROCESS Process);
788 
789 ULONG
790 NTAPI
791 MmGetSessionLocaleId(VOID);
792 
793 NTSTATUS
794 NTAPI
795 MmSetMemoryPriorityProcess(
796     IN PEPROCESS Process,
797     IN UCHAR MemoryPriority
798 );
799 
800 /* i386/pfault.c *************************************************************/
801 
802 NTSTATUS
803 NTAPI
804 MmPageFault(
805     ULONG Cs,
806     PULONG Eip,
807     PULONG Eax,
808     ULONG Cr2,
809     ULONG ErrorCode
810 );
811 
812 /* special.c *****************************************************************/
813 
814 VOID
815 NTAPI
816 MiInitializeSpecialPool(VOID);
817 
818 BOOLEAN
819 NTAPI
820 MmUseSpecialPool(
821     IN SIZE_T NumberOfBytes,
822     IN ULONG Tag);
823 
824 BOOLEAN
825 NTAPI
826 MmIsSpecialPoolAddress(
827     IN PVOID P);
828 
829 BOOLEAN
830 NTAPI
831 MmIsSpecialPoolAddressFree(
832     IN PVOID P);
833 
834 PVOID
835 NTAPI
836 MmAllocateSpecialPool(
837     IN SIZE_T NumberOfBytes,
838     IN ULONG Tag,
839     IN POOL_TYPE PoolType,
840     IN ULONG SpecialType);
841 
842 VOID
843 NTAPI
844 MmFreeSpecialPool(
845     IN PVOID P);
846 
847 /* mm.c **********************************************************************/
848 
849 NTSTATUS
850 NTAPI
851 MmAccessFault(
852     IN ULONG FaultCode,
853     IN PVOID Address,
854     IN KPROCESSOR_MODE Mode,
855     IN PVOID TrapInformation
856 );
857 
858 /* process.c *****************************************************************/
859 
860 PVOID
861 NTAPI
862 MmCreateKernelStack(BOOLEAN GuiStack, UCHAR Node);
863 
864 VOID
865 NTAPI
866 MmDeleteKernelStack(PVOID Stack,
867                     BOOLEAN GuiStack);
868 
869 /* balance.c / pagefile.c******************************************************/
870 
871 FORCEINLINE VOID UpdateTotalCommittedPages(LONG Delta)
872 {
873     /*
874      * Add up all the used "Committed" memory + pagefile.
875      * Not sure this is right. 8^\
876      * MmTotalCommittedPages should be adjusted consistently with
877      * other counters at different places.
878      *
879        MmTotalCommittedPages = MiMemoryConsumers[MC_SYSTEM].PagesUsed +
880                                MiMemoryConsumers[MC_USER].PagesUsed +
881                                MiUsedSwapPages;
882      */
883 
884     /* Update Commitment */
885     SIZE_T TotalCommittedPages = InterlockedExchangeAddSizeT(&MmTotalCommittedPages, Delta) + Delta;
886 
887     /* Update Peak = max(Peak, Total) in a lockless way */
888     SIZE_T PeakCommitment = MmPeakCommitment;
889     while (TotalCommittedPages > PeakCommitment &&
890            InterlockedCompareExchangeSizeT(&MmPeakCommitment, TotalCommittedPages, PeakCommitment) != PeakCommitment)
891     {
892         PeakCommitment = MmPeakCommitment;
893     }
894 }
895 
896 /* balance.c *****************************************************************/
897 
898 CODE_SEG("INIT")
899 VOID
900 NTAPI
901 MmInitializeMemoryConsumer(
902     ULONG Consumer,
903     NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed)
904 );
905 
906 CODE_SEG("INIT")
907 VOID
908 NTAPI
909 MmInitializeBalancer(
910     ULONG NrAvailablePages,
911     ULONG NrSystemPages
912 );
913 
914 NTSTATUS
915 NTAPI
916 MmReleasePageMemoryConsumer(
917     ULONG Consumer,
918     PFN_NUMBER Page
919 );
920 
921 NTSTATUS
922 NTAPI
923 MmRequestPageMemoryConsumer(
924     ULONG Consumer,
925     BOOLEAN MyWait,
926     PPFN_NUMBER AllocatedPage
927 );
928 
929 CODE_SEG("INIT")
930 VOID
931 NTAPI
932 MiInitBalancerThread(VOID);
933 
934 VOID
935 NTAPI
936 MmRebalanceMemoryConsumers(VOID);
937 
938 /* rmap.c **************************************************************/
939 #define RMAP_SEGMENT_MASK ~((ULONG_PTR)0xff)
940 #define RMAP_IS_SEGMENT(x) (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK)
941 
942 VOID
943 NTAPI
944 MmSetRmapListHeadPage(
945     PFN_NUMBER Page,
946     struct _MM_RMAP_ENTRY* ListHead
947 );
948 
949 struct _MM_RMAP_ENTRY*
950 NTAPI
951 MmGetRmapListHeadPage(PFN_NUMBER Page);
952 
953 VOID
954 NTAPI
955 MmInsertRmap(
956     PFN_NUMBER Page,
957     struct _EPROCESS *Process,
958     PVOID Address
959 );
960 
961 VOID
962 NTAPI
963 MmDeleteAllRmaps(
964     PFN_NUMBER Page,
965     PVOID Context,
966     VOID (*DeleteMapping)(PVOID Context, struct _EPROCESS *Process, PVOID Address)
967 );
968 
969 VOID
970 NTAPI
971 MmDeleteRmap(
972     PFN_NUMBER Page,
973     struct _EPROCESS *Process,
974     PVOID Address
975 );
976 
977 CODE_SEG("INIT")
978 VOID
979 NTAPI
980 MmInitializeRmapList(VOID);
981 
982 NTSTATUS
983 NTAPI
984 MmPageOutPhysicalAddress(PFN_NUMBER Page);
985 
986 PMM_SECTION_SEGMENT
987 NTAPI
988 MmGetSectionAssociation(PFN_NUMBER Page,
989                         PLARGE_INTEGER Offset);
990 
991 /* freelist.c **********************************************************/
992 _IRQL_raises_(DISPATCH_LEVEL)
993 _IRQL_requires_max_(DISPATCH_LEVEL)
994 _Requires_lock_not_held_(MmPfnLock)
995 _Acquires_lock_(MmPfnLock)
996 _IRQL_saves_
997 FORCEINLINE
998 KIRQL
999 MiAcquirePfnLock(VOID)
1000 {
1001     return KeAcquireQueuedSpinLock(LockQueuePfnLock);
1002 }
1003 
1004 _Requires_lock_held_(MmPfnLock)
1005 _Releases_lock_(MmPfnLock)
1006 _IRQL_requires_(DISPATCH_LEVEL)
1007 FORCEINLINE
1008 VOID
1009 MiReleasePfnLock(
1010     _In_ _IRQL_restores_ KIRQL OldIrql)
1011 {
1012     KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
1013 }
1014 
1015 _IRQL_requires_min_(DISPATCH_LEVEL)
1016 _Requires_lock_not_held_(MmPfnLock)
1017 _Acquires_lock_(MmPfnLock)
1018 FORCEINLINE
1019 VOID
1020 MiAcquirePfnLockAtDpcLevel(VOID)
1021 {
1022     PKSPIN_LOCK_QUEUE LockQueue;
1023 
1024     ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
1025     LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock];
1026     KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
1027 }
1028 
1029 _Requires_lock_held_(MmPfnLock)
1030 _Releases_lock_(MmPfnLock)
1031 _IRQL_requires_min_(DISPATCH_LEVEL)
1032 FORCEINLINE
1033 VOID
1034 MiReleasePfnLockFromDpcLevel(VOID)
1035 {
1036     PKSPIN_LOCK_QUEUE LockQueue;
1037 
1038     LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock];
1039     KeReleaseQueuedSpinLockFromDpcLevel(LockQueue);
1040     ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
1041 }
1042 
1043 #define MI_ASSERT_PFN_LOCK_HELD() NT_ASSERT((KeGetCurrentIrql() >= DISPATCH_LEVEL) && (MmPfnLock != 0))
1044 
1045 FORCEINLINE
1046 PMMPFN
1047 MiGetPfnEntry(IN PFN_NUMBER Pfn)
1048 {
1049     PMMPFN Page;
1050     extern RTL_BITMAP MiPfnBitMap;
1051 
1052     /* Make sure the PFN number is valid */
1053     if (Pfn > MmHighestPhysicalPage) return NULL;
1054 
1055     /* Make sure this page actually has a PFN entry */
1056     if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, (ULONG)Pfn))) return NULL;
1057 
1058     /* Get the entry */
1059     Page = &MmPfnDatabase[Pfn];
1060 
1061     /* Return it */
1062     return Page;
1063 };
1064 
1065 FORCEINLINE
1066 PFN_NUMBER
1067 MiGetPfnEntryIndex(IN PMMPFN Pfn1)
1068 {
1069     //
1070     // This will return the Page Frame Number (PFN) from the MMPFN
1071     //
1072     return Pfn1 - MmPfnDatabase;
1073 }
1074 
1075 PFN_NUMBER
1076 NTAPI
1077 MmGetLRUNextUserPage(PFN_NUMBER PreviousPage, BOOLEAN MoveToLast);
1078 
1079 PFN_NUMBER
1080 NTAPI
1081 MmGetLRUFirstUserPage(VOID);
1082 
1083 VOID
1084 NTAPI
1085 MmDumpArmPfnDatabase(
1086    IN BOOLEAN StatusOnly
1087 );
1088 
1089 VOID
1090 NTAPI
1091 MmZeroPageThread(
1092     VOID
1093 );
1094 
1095 /* hypermap.c *****************************************************************/
1096 PVOID
1097 NTAPI
1098 MiMapPageInHyperSpace(IN PEPROCESS Process,
1099                       IN PFN_NUMBER Page,
1100                       IN PKIRQL OldIrql);
1101 
1102 VOID
1103 NTAPI
1104 MiUnmapPageInHyperSpace(IN PEPROCESS Process,
1105                         IN PVOID Address,
1106                         IN KIRQL OldIrql);
1107 
1108 PVOID
1109 NTAPI
1110 MiMapPagesInZeroSpace(IN PMMPFN Pfn1,
1111                       IN PFN_NUMBER NumberOfPages);
1112 
1113 VOID
1114 NTAPI
1115 MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress,
1116                         IN PFN_NUMBER NumberOfPages);
1117 
1118 /* i386/page.c *********************************************************/
1119 
1120 NTSTATUS
1121 NTAPI
1122 MmCreateVirtualMapping(
1123     struct _EPROCESS* Process,
1124     PVOID Address,
1125     ULONG flProtect,
1126     PFN_NUMBER Page
1127 );
1128 
1129 NTSTATUS
1130 NTAPI
1131 MmCreateVirtualMappingUnsafe(
1132     struct _EPROCESS* Process,
1133     PVOID Address,
1134     ULONG flProtect,
1135     PFN_NUMBER Page
1136 );
1137 
1138 NTSTATUS
1139 NTAPI
1140 MmCreatePhysicalMapping(
1141     _Inout_opt_ PEPROCESS Process,
1142     _In_ PVOID Address,
1143     _In_ ULONG flProtect,
1144     _In_ PFN_NUMBER Page);
1145 
1146 ULONG
1147 NTAPI
1148 MmGetPageProtect(
1149     struct _EPROCESS* Process,
1150     PVOID Address);
1151 
1152 VOID
1153 NTAPI
1154 MmSetPageProtect(
1155     struct _EPROCESS* Process,
1156     PVOID Address,
1157     ULONG flProtect
1158 );
1159 
1160 BOOLEAN
1161 NTAPI
1162 MmIsPagePresent(
1163     struct _EPROCESS* Process,
1164     PVOID Address
1165 );
1166 
1167 BOOLEAN
1168 NTAPI
1169 MmIsDisabledPage(
1170     struct _EPROCESS* Process,
1171     PVOID Address
1172 );
1173 
1174 CODE_SEG("INIT")
1175 VOID
1176 NTAPI
1177 MmInitGlobalKernelPageDirectory(VOID);
1178 
1179 VOID
1180 NTAPI
1181 MmDeletePageFileMapping(
1182     struct _EPROCESS *Process,
1183     PVOID Address,
1184     SWAPENTRY* SwapEntry
1185 );
1186 
1187 NTSTATUS
1188 NTAPI
1189 MmCreatePageFileMapping(
1190     struct _EPROCESS *Process,
1191     PVOID Address,
1192     SWAPENTRY SwapEntry
1193 );
1194 
1195 VOID
1196 NTAPI
1197 MmGetPageFileMapping(
1198     PEPROCESS Process,
1199     PVOID Address,
1200     SWAPENTRY *SwapEntry);
1201 
1202 BOOLEAN
1203 NTAPI
1204 MmIsPageSwapEntry(
1205     struct _EPROCESS *Process,
1206     PVOID Address
1207 );
1208 
1209 PFN_NUMBER
1210 NTAPI
1211 MmAllocPage(
1212     ULONG Consumer
1213 );
1214 
1215 VOID
1216 NTAPI
1217 MmDereferencePage(PFN_NUMBER Page);
1218 
1219 VOID
1220 NTAPI
1221 MmReferencePage(PFN_NUMBER Page);
1222 
1223 ULONG
1224 NTAPI
1225 MmGetReferenceCountPage(PFN_NUMBER Page);
1226 
1227 BOOLEAN
1228 NTAPI
1229 MmIsPageInUse(PFN_NUMBER Page);
1230 
1231 VOID
1232 NTAPI
1233 MmSetSavedSwapEntryPage(
1234     PFN_NUMBER Page,
1235     SWAPENTRY SavedSwapEntry);
1236 
1237 SWAPENTRY
1238 NTAPI
1239 MmGetSavedSwapEntryPage(PFN_NUMBER Page);
1240 
1241 VOID
1242 NTAPI
1243 MmSetCleanPage(
1244     struct _EPROCESS *Process,
1245     PVOID Address
1246 );
1247 
1248 VOID
1249 NTAPI
1250 MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN Bit);
1251 #define MmSetCleanPage(__P, __A) MmSetDirtyBit(__P, __A, FALSE)
1252 #define MmSetDirtyPage(__P, __A) MmSetDirtyBit(__P, __A, TRUE)
1253 
1254 VOID
1255 NTAPI
1256 MmDeletePageTable(
1257     struct _EPROCESS *Process,
1258     PVOID Address
1259 );
1260 
1261 PFN_NUMBER
1262 NTAPI
1263 MmGetPfnForProcess(
1264     struct _EPROCESS *Process,
1265     PVOID Address
1266 );
1267 
1268 BOOLEAN
1269 NTAPI
1270 MmCreateProcessAddressSpace(
1271     IN ULONG MinWs,
1272     IN PEPROCESS Dest,
1273     IN PULONG_PTR DirectoryTableBase
1274 );
1275 
1276 CODE_SEG("INIT")
1277 NTSTATUS
1278 NTAPI
1279 MmInitializeHandBuiltProcess(
1280     IN PEPROCESS Process,
1281     IN PULONG_PTR DirectoryTableBase
1282 );
1283 
1284 CODE_SEG("INIT")
1285 NTSTATUS
1286 NTAPI
1287 MmInitializeHandBuiltProcess2(
1288     IN PEPROCESS Process
1289 );
1290 
1291 NTSTATUS
1292 NTAPI
1293 MmSetExecuteOptions(IN ULONG ExecuteOptions);
1294 
1295 NTSTATUS
1296 NTAPI
1297 MmGetExecuteOptions(IN PULONG ExecuteOptions);
1298 
1299 _Success_(return)
1300 BOOLEAN
1301 MmDeleteVirtualMapping(
1302     _Inout_opt_ PEPROCESS Process,
1303     _In_ PVOID Address,
1304     _Out_opt_ BOOLEAN* WasDirty,
1305     _Out_opt_ PPFN_NUMBER Page
1306 );
1307 
1308 _Success_(return)
1309 BOOLEAN
1310 MmDeletePhysicalMapping(
1311     _Inout_opt_ PEPROCESS Process,
1312     _In_ PVOID Address,
1313     _Out_opt_ BOOLEAN * WasDirty,
1314     _Out_opt_ PPFN_NUMBER Page
1315 );
1316 
1317 /* arch/procsup.c ************************************************************/
1318 
1319 BOOLEAN
1320 MiArchCreateProcessAddressSpace(
1321     _In_ PEPROCESS Process,
1322     _In_ PULONG_PTR DirectoryTableBase);
1323 
1324 /* wset.c ********************************************************************/
1325 
1326 NTSTATUS
1327 MmTrimUserMemory(
1328     ULONG Target,
1329     ULONG Priority,
1330     PULONG NrFreedPages
1331 );
1332 
1333 /* region.c ************************************************************/
1334 
1335 NTSTATUS
1336 NTAPI
1337 MmAlterRegion(
1338     PMMSUPPORT AddressSpace,
1339     PVOID BaseAddress,
1340     PLIST_ENTRY RegionListHead,
1341     PVOID StartAddress,
1342     SIZE_T Length,
1343     ULONG NewType,
1344     ULONG NewProtect,
1345     PMM_ALTER_REGION_FUNC AlterFunc
1346 );
1347 
1348 VOID
1349 NTAPI
1350 MmInitializeRegion(
1351     PLIST_ENTRY RegionListHead,
1352     SIZE_T Length,
1353     ULONG Type,
1354     ULONG Protect
1355 );
1356 
1357 PMM_REGION
1358 NTAPI
1359 MmFindRegion(
1360     PVOID BaseAddress,
1361     PLIST_ENTRY RegionListHead,
1362     PVOID Address,
1363     PVOID* RegionBaseAddress
1364 );
1365 
1366 /* section.c *****************************************************************/
1367 
1368 #define PFN_FROM_SSE(E)          ((PFN_NUMBER)((E) >> PAGE_SHIFT))
1369 #define IS_SWAP_FROM_SSE(E)      ((E) & 0x00000001)
1370 #define MM_IS_WAIT_PTE(E)        \
1371     (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY)
1372 #define MAKE_PFN_SSE(P)          ((ULONG_PTR)((P) << PAGE_SHIFT))
1373 #define SWAPENTRY_FROM_SSE(E)    ((E) >> 1)
1374 #define MAKE_SWAP_SSE(S)         (((ULONG_PTR)(S) << 1) | 0x1)
1375 #define DIRTY_SSE(E)             ((E) | 2)
1376 #define CLEAN_SSE(E)             ((E) & ~2)
1377 #define IS_DIRTY_SSE(E)          ((E) & 2)
1378 #define WRITE_SSE(E)             ((E) | 4)
1379 #define IS_WRITE_SSE(E)          ((E) & 4)
1380 #ifdef _WIN64
1381 #define PAGE_FROM_SSE(E)         ((E) & 0xFFFFFFF000ULL)
1382 #else
1383 #define PAGE_FROM_SSE(E)         ((E) & 0xFFFFF000)
1384 #endif
1385 #define SHARE_COUNT_FROM_SSE(E)  (((E) & 0x00000FFC) >> 3)
1386 #define MAX_SHARE_COUNT          0x1FF
1387 #define MAKE_SSE(P, C)           ((ULONG_PTR)((P) | ((C) << 3)))
1388 #define BUMPREF_SSE(E)           (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) + 1) << 3) | ((E) & 0x7))
1389 #define DECREF_SSE(E)            (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) - 1) << 3) | ((E) & 0x7))
1390 
1391 VOID
1392 NTAPI
1393 _MmLockSectionSegment(PMM_SECTION_SEGMENT Segment,
1394                       const char *file,
1395                       int line);
1396 
1397 #define MmLockSectionSegment(x) _MmLockSectionSegment(x,__FILE__,__LINE__)
1398 
1399 VOID
1400 NTAPI
1401 _MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment,
1402                         const char *file,
1403                         int line);
1404 
1405 #define MmUnlockSectionSegment(x) _MmUnlockSectionSegment(x,__FILE__,__LINE__)
1406 
1407 VOID
1408 NTAPI
1409 MmGetImageInformation(
1410     OUT PSECTION_IMAGE_INFORMATION ImageInformation
1411 );
1412 
1413 PFILE_OBJECT
1414 NTAPI
1415 MmGetFileObjectForSection(
1416     IN PVOID Section
1417 );
1418 NTSTATUS
1419 NTAPI
1420 MmGetFileNameForAddress(
1421     IN PVOID Address,
1422     OUT PUNICODE_STRING ModuleName
1423 );
1424 
1425 NTSTATUS
1426 NTAPI
1427 MmGetFileNameForSection(
1428     IN PVOID Section,
1429     OUT POBJECT_NAME_INFORMATION *ModuleName
1430 );
1431 
1432 NTSTATUS
1433 NTAPI
1434 MmQuerySectionView(
1435     PMEMORY_AREA MemoryArea,
1436     PVOID Address,
1437     PMEMORY_BASIC_INFORMATION Info,
1438     PSIZE_T ResultLength
1439 );
1440 
1441 NTSTATUS
1442 NTAPI
1443 MmProtectSectionView(
1444     PMMSUPPORT AddressSpace,
1445     PMEMORY_AREA MemoryArea,
1446     PVOID BaseAddress,
1447     SIZE_T Length,
1448     ULONG Protect,
1449     PULONG OldProtect
1450 );
1451 
1452 CODE_SEG("INIT")
1453 NTSTATUS
1454 NTAPI
1455 MmInitSectionImplementation(VOID);
1456 
1457 NTSTATUS
1458 NTAPI
1459 MmNotPresentFaultSectionView(
1460     PMMSUPPORT AddressSpace,
1461     MEMORY_AREA* MemoryArea,
1462     PVOID Address,
1463     BOOLEAN Locked
1464 );
1465 
1466 NTSTATUS
1467 NTAPI
1468 MmPageOutSectionView(
1469     PMMSUPPORT AddressSpace,
1470     PMEMORY_AREA MemoryArea,
1471     PVOID Address,
1472     ULONG_PTR Entry
1473 );
1474 
1475 CODE_SEG("INIT")
1476 NTSTATUS
1477 NTAPI
1478 MmCreatePhysicalMemorySection(VOID);
1479 
1480 NTSTATUS
1481 NTAPI
1482 MmAccessFaultSectionView(
1483     PMMSUPPORT AddressSpace,
1484     MEMORY_AREA* MemoryArea,
1485     PVOID Address,
1486     BOOLEAN Locked
1487 );
1488 
1489 VOID
1490 NTAPI
1491 MmFreeSectionSegments(PFILE_OBJECT FileObject);
1492 
1493 /* Exported from NT 6.2 onward. We keep it internal. */
1494 NTSTATUS
1495 NTAPI
1496 MmMapViewInSystemSpaceEx(
1497     _In_ PVOID Section,
1498     _Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase,
1499     _Inout_ PSIZE_T ViewSize,
1500     _Inout_ PLARGE_INTEGER SectionOffset,
1501     _In_ ULONG_PTR Flags);
1502 
1503 BOOLEAN
1504 NTAPI
1505 MmArePagesResident(
1506     _In_ PEPROCESS Process,
1507     _In_ PVOID BaseAddress,
1508     _In_ ULONG Length);
1509 
1510 NTSTATUS
1511 NTAPI
1512 MmMakePagesDirty(
1513     _In_ PEPROCESS Process,
1514     _In_ PVOID Address,
1515     _In_ ULONG Length);
1516 
1517 NTSTATUS
1518 NTAPI
1519 MmFlushSegment(
1520     _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer,
1521     _In_opt_ PLARGE_INTEGER Offset,
1522     _In_ ULONG Length,
1523     _Out_opt_ PIO_STATUS_BLOCK Iosb);
1524 
1525 NTSTATUS
1526 NTAPI
1527 MmMakeDataSectionResident(
1528     _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer,
1529     _In_ LONGLONG Offset,
1530     _In_ ULONG Length,
1531     _In_ PLARGE_INTEGER ValidDataLength);
1532 
1533 BOOLEAN
1534 NTAPI
1535 MmPurgeSegment(
1536     _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer,
1537     _In_opt_ PLARGE_INTEGER Offset,
1538     _In_ ULONG Length);
1539 
1540 BOOLEAN
1541 NTAPI
1542 MmCheckDirtySegment(
1543     PMM_SECTION_SEGMENT Segment,
1544     PLARGE_INTEGER Offset,
1545     BOOLEAN ForceDirty,
1546     BOOLEAN PageOut);
1547 
1548 BOOLEAN
1549 NTAPI
1550 MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea,
1551                                  PMM_SECTION_SEGMENT Segment,
1552                                  PLARGE_INTEGER Offset,
1553                                  BOOLEAN Dirty,
1554                                  BOOLEAN PageOut,
1555                                  ULONG_PTR *InEntry);
1556 
1557 _When_(OldIrql == MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL))
1558 _When_(OldIrql == MM_NOIRQL, _Requires_lock_not_held_(MmPfnLock))
1559 _When_(OldIrql != MM_NOIRQL, _Requires_lock_held_(MmPfnLock))
1560 _When_(OldIrql != MM_NOIRQL, _Releases_lock_(MmPfnLock))
1561 _When_(OldIrql != MM_NOIRQL, _IRQL_requires_(DISPATCH_LEVEL))
1562 VOID
1563 NTAPI
1564 MmDereferenceSegmentWithLock(
1565     _In_ PMM_SECTION_SEGMENT Segment,
1566     _In_ _When_(OldIrql != MM_NOIRQL, _IRQL_restores_) KIRQL OldIrql);
1567 
1568 _IRQL_requires_max_(DISPATCH_LEVEL)
1569 _Requires_lock_not_held_(MmPfnLock)
1570 FORCEINLINE
1571 VOID
1572 MmDereferenceSegment(PMM_SECTION_SEGMENT Segment)
1573 {
1574     MmDereferenceSegmentWithLock(Segment, MM_NOIRQL);
1575 }
1576 
1577 NTSTATUS
1578 NTAPI
1579 MmExtendSection(
1580     _In_ PVOID Section,
1581     _Inout_ PLARGE_INTEGER NewSize);
1582 
1583 /* sptab.c *******************************************************************/
1584 
1585 NTSTATUS
1586 NTAPI
1587 _MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
1588                               PLARGE_INTEGER Offset,
1589                               ULONG_PTR Entry,
1590                               const char *file,
1591                               int line);
1592 
1593 ULONG_PTR
1594 NTAPI
1595 _MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
1596                               PLARGE_INTEGER Offset,
1597                               const char *file,
1598                               int line);
1599 
1600 #define MmSetPageEntrySectionSegment(S,O,E) _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__)
1601 
1602 #define MmGetPageEntrySectionSegment(S,O) _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__)
1603 
1604 /* sysldr.c ******************************************************************/
1605 
1606 CODE_SEG("INIT")
1607 VOID
1608 NTAPI
1609 MiReloadBootLoadedDrivers(
1610     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1611 );
1612 
1613 CODE_SEG("INIT")
1614 BOOLEAN
1615 NTAPI
1616 MiInitializeLoadedModuleList(
1617     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1618 );
1619 
1620 BOOLEAN
1621 NTAPI
1622 MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask);
1623 
1624 VOID
1625 NTAPI
1626 MmMakeKernelResourceSectionWritable(VOID);
1627 
1628 NTSTATUS
1629 NTAPI
1630 MmLoadSystemImage(
1631     IN PUNICODE_STRING FileName,
1632     IN PUNICODE_STRING NamePrefix OPTIONAL,
1633     IN PUNICODE_STRING LoadedName OPTIONAL,
1634     IN ULONG Flags,
1635     OUT PVOID *ModuleObject,
1636     OUT PVOID *ImageBaseAddress
1637 );
1638 
1639 NTSTATUS
1640 NTAPI
1641 MmUnloadSystemImage(
1642     IN PVOID ImageHandle
1643 );
1644 
1645 NTSTATUS
1646 NTAPI
1647 MmCheckSystemImage(
1648     IN HANDLE ImageHandle,
1649     IN BOOLEAN PurgeSection
1650 );
1651 
1652 NTSTATUS
1653 NTAPI
1654 MmCallDllInitialize(
1655     _In_ PLDR_DATA_TABLE_ENTRY LdrEntry,
1656     _In_ PLIST_ENTRY ModuleListHead);
1657 
1658 VOID
1659 NTAPI
1660 MmFreeDriverInitialization(
1661     IN PLDR_DATA_TABLE_ENTRY LdrEntry);
1662 
1663 /* ReactOS-only, used by psmgr.c PspLookupSystemDllEntryPoint() as well */
1664 NTSTATUS
1665 NTAPI
1666 RtlpFindExportedRoutineByName(
1667     _In_ PVOID ImageBase,
1668     _In_ PCSTR ExportName,
1669     _Out_ PVOID* Function,
1670     _Out_opt_ PBOOLEAN IsForwarder,
1671     _In_ NTSTATUS NotFoundStatus);
1672 
1673 /* Exported from NT 10.0 onward. We keep it internal. */
1674 PVOID
1675 NTAPI
1676 RtlFindExportedRoutineByName(
1677     _In_ PVOID ImageBase,
1678     _In_ PCSTR ExportName);
1679 
1680 /* procsup.c *****************************************************************/
1681 
1682 NTSTATUS
1683 NTAPI
1684 MmGrowKernelStack(
1685     IN PVOID StackPointer
1686 );
1687 
1688 
1689 FORCEINLINE
1690 VOID
1691 MmLockAddressSpace(PMMSUPPORT AddressSpace)
1692 {
1693     ASSERT(!PsGetCurrentThread()->OwnsProcessWorkingSetExclusive);
1694     ASSERT(!PsGetCurrentThread()->OwnsProcessWorkingSetShared);
1695     ASSERT(!PsGetCurrentThread()->OwnsSystemWorkingSetExclusive);
1696     ASSERT(!PsGetCurrentThread()->OwnsSystemWorkingSetShared);
1697     ASSERT(!PsGetCurrentThread()->OwnsSessionWorkingSetExclusive);
1698     ASSERT(!PsGetCurrentThread()->OwnsSessionWorkingSetShared);
1699     KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock);
1700 }
1701 
1702 FORCEINLINE
1703 VOID
1704 MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
1705 {
1706     KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock);
1707 }
1708 
1709 FORCEINLINE
1710 PEPROCESS
1711 MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
1712 {
1713     if (AddressSpace == MmKernelAddressSpace) return NULL;
1714     return CONTAINING_RECORD(AddressSpace, EPROCESS, Vm);
1715 }
1716 
1717 FORCEINLINE
1718 PMMSUPPORT
1719 MmGetCurrentAddressSpace(VOID)
1720 {
1721     return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm;
1722 }
1723 
1724 FORCEINLINE
1725 PMMSUPPORT
1726 MmGetKernelAddressSpace(VOID)
1727 {
1728     return MmKernelAddressSpace;
1729 }
1730 
1731 
1732 /* expool.c ******************************************************************/
1733 
1734 VOID
1735 NTAPI
1736 ExpCheckPoolAllocation(
1737     PVOID P,
1738     POOL_TYPE PoolType,
1739     ULONG Tag);
1740 
1741 VOID
1742 NTAPI
1743 ExReturnPoolQuota(
1744     IN PVOID P);
1745 
1746 
1747 /* mmsup.c *****************************************************************/
1748 
1749 NTSTATUS
1750 NTAPI
1751 MmAdjustWorkingSetSize(
1752     IN SIZE_T WorkingSetMinimumInBytes,
1753     IN SIZE_T WorkingSetMaximumInBytes,
1754     IN ULONG SystemCache,
1755     IN BOOLEAN IncreaseOkay);
1756 
1757 
1758 /* session.c *****************************************************************/
1759 
1760 _IRQL_requires_max_(APC_LEVEL)
1761 NTSTATUS
1762 NTAPI
1763 MmAttachSession(
1764     _Inout_ PVOID SessionEntry,
1765     _Out_ PKAPC_STATE ApcState);
1766 
1767 _IRQL_requires_max_(APC_LEVEL)
1768 VOID
1769 NTAPI
1770 MmDetachSession(
1771     _Inout_ PVOID SessionEntry,
1772     _Out_ PKAPC_STATE ApcState);
1773 
1774 VOID
1775 NTAPI
1776 MmQuitNextSession(
1777     _Inout_ PVOID SessionEntry);
1778 
1779 PVOID
1780 NTAPI
1781 MmGetSessionById(
1782     _In_ ULONG SessionId);
1783 
1784 _IRQL_requires_max_(APC_LEVEL)
1785 VOID
1786 NTAPI
1787 MmSetSessionLocaleId(
1788     _In_ LCID LocaleId);
1789 
1790 /* shutdown.c *****************************************************************/
1791 
1792 VOID
1793 MmShutdownSystem(IN ULONG Phase);
1794 
1795 /* virtual.c *****************************************************************/
1796 
1797 NTSTATUS
1798 NTAPI
1799 MmCopyVirtualMemory(IN PEPROCESS SourceProcess,
1800                     IN PVOID SourceAddress,
1801                     IN PEPROCESS TargetProcess,
1802                     OUT PVOID TargetAddress,
1803                     IN SIZE_T BufferSize,
1804                     IN KPROCESSOR_MODE PreviousMode,
1805                     OUT PSIZE_T ReturnSize);
1806 
1807 /* wslist.cpp ****************************************************************/
1808 _Requires_exclusive_lock_held_(WorkingSet->WorkingSetMutex)
1809 VOID
1810 NTAPI
1811 MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet);
1812 
1813 #ifdef __cplusplus
1814 } // extern "C"
1815 
1816 namespace ntoskrnl
1817 {
1818 using MiPfnLockGuard = const KiQueuedSpinLockGuard<LockQueuePfnLock>;
1819 } // namespace ntoskrnl
1820 
1821 #endif
1822