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