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