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