Mm: Fix page protection flags checks.
[reactos.git] / reactos / ntoskrnl / include / internal / mm.h
1 #ifndef __INCLUDE_INTERNAL_MM_H
2 #define __INCLUDE_INTERNAL_MM_H
3
4 #include <internal/arch/mm.h>
5
6 /* TYPES *********************************************************************/
7
8 struct _EPROCESS;
9
10 extern ULONG MiFreeSwapPages;
11 extern ULONG MiUsedSwapPages;
12 extern ULONG MmPagedPoolSize;
13 extern ULONG MmTotalPagedPoolQuota;
14 extern ULONG MmTotalNonPagedPoolQuota;
15 extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
16 extern ULONG MmNumberOfPhysicalPages;
17
18 extern PVOID MmPagedPoolBase;
19 extern ULONG MmPagedPoolSize;
20
21 extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
22 extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg;
23 extern ULONG MmHighestPhysicalPage;
24 extern PVOID MmPfnDatabase;
25
26 struct _KTRAP_FRAME;
27 struct _EPROCESS;
28 struct _MM_RMAP_ENTRY;
29 struct _MM_PAGEOP;
30 typedef ULONG SWAPENTRY;
31 typedef ULONG PFN_TYPE, *PPFN_TYPE;
32
33 #define MEMORY_AREA_INVALID (0)
34 #define MEMORY_AREA_SECTION_VIEW (1)
35 #define MEMORY_AREA_CONTINUOUS_MEMORY (2)
36 #define MEMORY_AREA_NO_CACHE (3)
37 #define MEMORY_AREA_IO_MAPPING (4)
38 #define MEMORY_AREA_SYSTEM (5)
39 #define MEMORY_AREA_MDL_MAPPING (7)
40 #define MEMORY_AREA_VIRTUAL_MEMORY (8)
41 #define MEMORY_AREA_CACHE_SEGMENT (9)
42 #define MEMORY_AREA_SHARED_DATA (10)
43 #define MEMORY_AREA_KERNEL_STACK (11)
44 #define MEMORY_AREA_PAGED_POOL (12)
45 #define MEMORY_AREA_NO_ACCESS (13)
46 #define MEMORY_AREA_PEB_OR_TEB (14)
47
48 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
49
50 #define MM_CORE_DUMP_TYPE_NONE (0x0)
51 #define MM_CORE_DUMP_TYPE_MINIMAL (0x1)
52 #define MM_CORE_DUMP_TYPE_FULL (0x2)
53
54 #define MM_PAGEOP_PAGEIN (1)
55 #define MM_PAGEOP_PAGEOUT (2)
56 #define MM_PAGEOP_PAGESYNCH (3)
57 #define MM_PAGEOP_ACCESSFAULT (4)
58
59 /* Number of list heads to use */
60 #define MI_FREE_POOL_LISTS 4
61
62 /* Signature of free pool blocks */
63 #define MM_FREE_POOL_TAG TAG('F', 'r', 'p', 'l')
64
65 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
66 ((x) / (4*1024*1024))
67
68 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
69 ((((x)) % (4*1024*1024)) / (4*1024))
70
71 #define NR_SECTION_PAGE_TABLES 1024
72 #define NR_SECTION_PAGE_ENTRIES 1024
73
74 #define TEB_BASE 0x7FFDE000
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_PPOOL (2)
96 #define MC_NPPOOL (3)
97 #define MC_MAXIMUM (4)
98
99 #define PAGED_POOL_MASK 1
100 #define MUST_SUCCEED_POOL_MASK 2
101 #define CACHE_ALIGNED_POOL_MASK 4
102 #define QUOTA_POOL_MASK 8
103 #define SESSION_POOL_MASK 32
104 #define VERIFIER_POOL_MASK 64
105
106 #define MM_PAGED_POOL_SIZE (100*1024*1024)
107 #define MM_NONPAGED_POOL_SIZE (100*1024*1024)
108
109 /*
110 * Paged and non-paged pools are 8-byte aligned
111 */
112 #define MM_POOL_ALIGNMENT 8
113
114 /*
115 * Maximum size of the kmalloc area (this is totally arbitary)
116 */
117 #define MM_KERNEL_MAP_SIZE (16*1024*1024)
118 #define MM_KERNEL_MAP_BASE (0xf0c00000)
119
120 /*
121 * FIXME - different architectures have different cache line sizes...
122 */
123 #define MM_CACHE_LINE_SIZE 32
124
125 #define MM_ROUND_UP(x,s) \
126 ((PVOID)(((ULONG_PTR)(x)+(s)-1) & ~((ULONG_PTR)(s)-1)))
127
128 #define MM_ROUND_DOWN(x,s) \
129 ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1)))
130
131 #define PAGE_FLAGS_VALID_FROM_USER_MODE \
132 (PAGE_READONLY | \
133 PAGE_READWRITE | \
134 PAGE_WRITECOPY | \
135 PAGE_EXECUTE | \
136 PAGE_EXECUTE_READ | \
137 PAGE_EXECUTE_READWRITE | \
138 PAGE_EXECUTE_WRITECOPY | \
139 PAGE_GUARD | \
140 PAGE_NOACCESS | \
141 PAGE_NOCACHE)
142
143 #define PAGE_FLAGS_VALID_FOR_SECTION \
144 (PAGE_READONLY | \
145 PAGE_READWRITE | \
146 PAGE_WRITECOPY | \
147 PAGE_EXECUTE | \
148 PAGE_EXECUTE_READ | \
149 PAGE_EXECUTE_READWRITE | \
150 PAGE_EXECUTE_WRITECOPY | \
151 PAGE_NOACCESS)
152
153 #define PAGE_IS_READABLE \
154 (PAGE_READONLY | \
155 PAGE_READWRITE | \
156 PAGE_WRITECOPY | \
157 PAGE_EXECUTE_READ | \
158 PAGE_EXECUTE_READWRITE | \
159 PAGE_EXECUTE_WRITECOPY)
160
161 #define PAGE_IS_WRITABLE \
162 (PAGE_READWRITE | \
163 PAGE_WRITECOPY | \
164 PAGE_EXECUTE_READWRITE | \
165 PAGE_EXECUTE_WRITECOPY)
166
167 #define PAGE_IS_EXECUTABLE \
168 (PAGE_EXECUTE | \
169 PAGE_EXECUTE_READ | \
170 PAGE_EXECUTE_READWRITE | \
171 PAGE_EXECUTE_WRITECOPY)
172
173 #define PAGE_IS_WRITECOPY \
174 (PAGE_WRITECOPY | \
175 PAGE_EXECUTE_WRITECOPY)
176
177
178 #define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand) \
179 InterlockedCompareExchange((PLONG)(PointerPte), Exchange, Comperand)
180
181 #define InterlockedExchangePte(PointerPte, Value) \
182 InterlockedExchange((PLONG)(PointerPte), Value)
183
184 typedef struct
185 {
186 ULONG Entry[NR_SECTION_PAGE_ENTRIES];
187 } SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
188
189 typedef struct
190 {
191 PSECTION_PAGE_TABLE PageTables[NR_SECTION_PAGE_TABLES];
192 } SECTION_PAGE_DIRECTORY, *PSECTION_PAGE_DIRECTORY;
193
194 typedef struct _MM_SECTION_SEGMENT
195 {
196 LONG FileOffset; /* start offset into the file for image sections */
197 ULONG_PTR VirtualAddress; /* dtart offset into the address range for image sections */
198 ULONG RawLength; /* length of the segment which is part of the mapped file */
199 ULONG Length; /* absolute length of the segment */
200 ULONG Protection;
201 FAST_MUTEX Lock; /* lock which protects the page directory */
202 ULONG ReferenceCount;
203 SECTION_PAGE_DIRECTORY PageDirectory;
204 ULONG Flags;
205 ULONG Characteristics;
206 BOOLEAN WriteCopy;
207 } MM_SECTION_SEGMENT, *PMM_SECTION_SEGMENT;
208
209 typedef struct _MM_IMAGE_SECTION_OBJECT
210 {
211 ULONG_PTR ImageBase;
212 ULONG_PTR StackReserve;
213 ULONG_PTR StackCommit;
214 ULONG_PTR EntryPoint;
215 USHORT Subsystem;
216 USHORT ImageCharacteristics;
217 USHORT MinorSubsystemVersion;
218 USHORT MajorSubsystemVersion;
219 USHORT Machine;
220 BOOLEAN Executable;
221 ULONG NrSegments;
222 ULONG ImageSize;
223 PMM_SECTION_SEGMENT Segments;
224 } MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
225
226 typedef struct _ROS_SECTION_OBJECT
227 {
228 CSHORT Type;
229 CSHORT Size;
230 LARGE_INTEGER MaximumSize;
231 ULONG SectionPageProtection;
232 ULONG AllocationAttributes;
233 PFILE_OBJECT FileObject;
234 union
235 {
236 PMM_IMAGE_SECTION_OBJECT ImageSection;
237 PMM_SECTION_SEGMENT Segment;
238 };
239 } ROS_SECTION_OBJECT, *PROS_SECTION_OBJECT;
240
241 typedef struct _MEMORY_AREA
242 {
243 PVOID StartingAddress;
244 PVOID EndingAddress;
245 struct _MEMORY_AREA *Parent;
246 struct _MEMORY_AREA *LeftChild;
247 struct _MEMORY_AREA *RightChild;
248 ULONG Type;
249 ULONG Protect;
250 ULONG Flags;
251 BOOLEAN DeleteInProgress;
252 ULONG PageOpCount;
253 union
254 {
255 struct
256 {
257 ROS_SECTION_OBJECT* Section;
258 ULONG ViewOffset;
259 PMM_SECTION_SEGMENT Segment;
260 BOOLEAN WriteCopyView;
261 LIST_ENTRY RegionListHead;
262 } SectionData;
263 struct
264 {
265 LIST_ENTRY RegionListHead;
266 } VirtualMemoryData;
267 } Data;
268 } MEMORY_AREA, *PMEMORY_AREA;
269
270 typedef struct
271 {
272 ULONG NrTotalPages;
273 ULONG NrSystemPages;
274 ULONG NrUserPages;
275 ULONG NrFreePages;
276 ULONG NrDirtyPages;
277 ULONG NrLockedPages;
278 ULONG PagingRequestsInLastMinute;
279 ULONG PagingRequestsInLastFiveMinutes;
280 ULONG PagingRequestsInLastFifteenMinutes;
281 } MM_STATS;
282
283 typedef struct _PHYSICAL_PAGE
284 {
285 union
286 {
287 struct
288 {
289 ULONG Type: 2;
290 ULONG Consumer: 3;
291 ULONG Zero: 1;
292 ULONG StartOfAllocation: 1;
293 ULONG EndOfAllocation: 1;
294 }
295 Flags;
296 ULONG AllFlags;
297 };
298
299 LIST_ENTRY ListEntry;
300 ULONG ReferenceCount;
301 SWAPENTRY SavedSwapEntry;
302 ULONG LockCount;
303 ULONG MapCount;
304 struct _MM_RMAP_ENTRY* RmapListHead;
305 }
306 PHYSICAL_PAGE, *PPHYSICAL_PAGE;
307
308 extern MM_STATS MmStats;
309
310 typedef struct _MM_PAGEOP
311 {
312 /* Type of operation. */
313 ULONG OpType;
314 /* Number of threads interested in this operation. */
315 ULONG ReferenceCount;
316 /* Event that will be set when the operation is completed. */
317 KEVENT CompletionEvent;
318 /* Status of the operation once it is completed. */
319 NTSTATUS Status;
320 /* TRUE if the operation was abandoned. */
321 BOOLEAN Abandoned;
322 /* The memory area to be affected by the operation. */
323 PMEMORY_AREA MArea;
324 ULONG Hash;
325 struct _MM_PAGEOP* Next;
326 struct _ETHREAD* Thread;
327 /*
328 * These fields are used to identify the operation if it is against a
329 * virtual memory area.
330 */
331 HANDLE Pid;
332 PVOID Address;
333 /*
334 * These fields are used to identify the operation if it is against a
335 * section mapping.
336 */
337 PMM_SECTION_SEGMENT Segment;
338 ULONG Offset;
339 } MM_PAGEOP, *PMM_PAGEOP;
340
341 typedef struct _MM_MEMORY_CONSUMER
342 {
343 ULONG PagesUsed;
344 ULONG PagesTarget;
345 NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed);
346 } MM_MEMORY_CONSUMER, *PMM_MEMORY_CONSUMER;
347
348 typedef struct _MM_REGION
349 {
350 ULONG Type;
351 ULONG Protect;
352 ULONG Length;
353 LIST_ENTRY RegionListEntry;
354 } MM_REGION, *PMM_REGION;
355
356 /* Entry describing free pool memory */
357 typedef struct _MMFREE_POOL_ENTRY
358 {
359 LIST_ENTRY List;
360 PFN_NUMBER Size;
361 ULONG Signature;
362 struct _MMFREE_POOL_ENTRY *Owner;
363 } MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
364
365 /* Paged pool information */
366 typedef struct _MM_PAGED_POOL_INFO
367 {
368 PRTL_BITMAP PagedPoolAllocationMap;
369 PRTL_BITMAP EndOfPagedPoolBitmap;
370 PMMPTE FirstPteForPagedPool;
371 PMMPTE LastPteForPagedPool;
372 PMMPTE NextPdeForPagedPoolExpansion;
373 ULONG PagedPoolHint;
374 SIZE_T PagedPoolCommit;
375 SIZE_T AllocatedPagedPool;
376 } MM_PAGED_POOL_INFO, *PMM_PAGED_POOL_INFO;
377
378 extern MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
379
380 typedef VOID
381 (*PMM_ALTER_REGION_FUNC)(
382 PMM_AVL_TABLE AddressSpace,
383 PVOID BaseAddress,
384 ULONG Length,
385 ULONG OldType,
386 ULONG OldProtect,
387 ULONG NewType,
388 ULONG NewProtect
389 );
390
391 typedef VOID
392 (*PMM_FREE_PAGE_FUNC)(
393 PVOID Context,
394 PMEMORY_AREA MemoryArea,
395 PVOID Address,
396 PFN_TYPE Page,
397 SWAPENTRY SwapEntry,
398 BOOLEAN Dirty
399 );
400
401 /* marea.c *******************************************************************/
402
403 NTSTATUS
404 NTAPI
405 MmCreateMemoryArea(
406 PMM_AVL_TABLE AddressSpace,
407 ULONG Type,
408 PVOID *BaseAddress,
409 ULONG_PTR Length,
410 ULONG Protection,
411 PMEMORY_AREA *Result,
412 BOOLEAN FixedAddress,
413 ULONG AllocationFlags,
414 PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL
415 );
416
417 PMEMORY_AREA
418 NTAPI
419 MmLocateMemoryAreaByAddress(
420 PMM_AVL_TABLE AddressSpace,
421 PVOID Address
422 );
423
424 ULONG_PTR
425 NTAPI
426 MmFindGapAtAddress(
427 PMM_AVL_TABLE AddressSpace,
428 PVOID Address
429 );
430
431 NTSTATUS
432 NTAPI
433 MmFreeMemoryArea(
434 PMM_AVL_TABLE AddressSpace,
435 PMEMORY_AREA MemoryArea,
436 PMM_FREE_PAGE_FUNC FreePage,
437 PVOID FreePageContext
438 );
439
440 NTSTATUS
441 NTAPI
442 MmFreeMemoryAreaByPtr(
443 PMM_AVL_TABLE AddressSpace,
444 PVOID BaseAddress,
445 PMM_FREE_PAGE_FUNC FreePage,
446 PVOID FreePageContext
447 );
448
449 VOID
450 NTAPI
451 MmDumpMemoryAreas(PMM_AVL_TABLE AddressSpace);
452
453 PMEMORY_AREA
454 NTAPI
455 MmLocateMemoryAreaByRegion(
456 PMM_AVL_TABLE AddressSpace,
457 PVOID Address,
458 ULONG_PTR Length
459 );
460
461 PVOID
462 NTAPI
463 MmFindGap(
464 PMM_AVL_TABLE AddressSpace,
465 ULONG_PTR Length,
466 ULONG_PTR Granularity,
467 BOOLEAN TopDown
468 );
469
470 VOID
471 NTAPI
472 MmReleaseMemoryAreaIfDecommitted(
473 struct _EPROCESS *Process,
474 PMM_AVL_TABLE AddressSpace,
475 PVOID BaseAddress
476 );
477
478 VOID
479 NTAPI
480 MmMapMemoryArea(PVOID BaseAddress,
481 ULONG Length,
482 ULONG Consumer,
483 ULONG Protection);
484
485 /* npool.c *******************************************************************/
486
487 VOID
488 NTAPI
489 MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
490
491 VOID
492 NTAPI
493 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
494
495 VOID
496 NTAPI
497 MiInitializeNonPagedPool(VOID);
498
499 PVOID
500 NTAPI
501 MiAllocatePoolPages(
502 IN POOL_TYPE PoolType,
503 IN SIZE_T SizeInBytes
504 );
505
506 POOL_TYPE
507 NTAPI
508 MmDeterminePoolType(
509 IN PVOID VirtualAddress
510 );
511
512 ULONG
513 NTAPI
514 MiFreePoolPages(
515 IN PVOID StartingAddress
516 );
517
518 PVOID
519 NTAPI
520 MmGetMdlPageAddress(
521 PMDL Mdl,
522 PVOID Offset
523 );
524
525 /* pool.c *******************************************************************/
526
527 PVOID
528 NTAPI
529 ExAllocateNonPagedPoolWithTag(
530 POOL_TYPE type,
531 ULONG size,
532 ULONG Tag,
533 PVOID Caller
534 );
535
536 PVOID
537 NTAPI
538 ExAllocatePagedPoolWithTag(
539 POOL_TYPE Type,
540 ULONG size,
541 ULONG Tag
542 );
543
544 VOID
545 NTAPI
546 ExFreeNonPagedPool(PVOID block);
547
548 VOID
549 NTAPI
550 ExFreePagedPool(IN PVOID Block);
551
552 VOID
553 NTAPI
554 MmInitializePagedPool(VOID);
555
556 PVOID
557 NTAPI
558 MiAllocateSpecialPool(
559 IN POOL_TYPE PoolType,
560 IN SIZE_T NumberOfBytes,
561 IN ULONG Tag,
562 IN ULONG Underrun
563 );
564
565 BOOLEAN
566 NTAPI
567 MiRaisePoolQuota(
568 IN POOL_TYPE PoolType,
569 IN ULONG CurrentMaxQuota,
570 OUT PULONG NewMaxQuota
571 );
572
573 /* mdl.c *********************************************************************/
574
575 VOID
576 NTAPI
577 MmBuildMdlFromPages(
578 PMDL Mdl,
579 PULONG Pages
580 );
581
582 /* mminit.c ******************************************************************/
583
584 VOID
585 NTAPI
586 MiShutdownMemoryManager(VOID);
587
588 VOID
589 NTAPI
590 MmInit1(
591 VOID
592 );
593
594 BOOLEAN
595 NTAPI
596 MmInitSystem(IN ULONG Phase,
597 IN PLOADER_PARAMETER_BLOCK LoaderBlock);
598
599 VOID
600 NTAPI
601 MiFreeInitMemory(VOID);
602
603 VOID
604 NTAPI
605 MmInitializeMdlImplementation(VOID);
606
607 /* pagefile.c ****************************************************************/
608
609 SWAPENTRY
610 NTAPI
611 MmAllocSwapPage(VOID);
612
613 VOID
614 NTAPI
615 MmDereserveSwapPages(ULONG Nr);
616
617 VOID
618 NTAPI
619 MmFreeSwapPage(SWAPENTRY Entry);
620
621 VOID
622 NTAPI
623 MmInitPagingFile(VOID);
624
625 NTSTATUS
626 NTAPI
627 MmReadFromSwapPage(
628 SWAPENTRY SwapEntry,
629 PFN_TYPE Page
630 );
631
632 BOOLEAN
633 NTAPI
634 MmReserveSwapPages(ULONG Nr);
635
636 NTSTATUS
637 NTAPI
638 MmWriteToSwapPage(
639 SWAPENTRY SwapEntry,
640 PFN_TYPE Page
641 );
642
643 NTSTATUS
644 NTAPI
645 MmDumpToPagingFile(
646 ULONG BugCode,
647 ULONG BugCodeParameter1,
648 ULONG BugCodeParameter2,
649 ULONG BugCodeParameter3,
650 ULONG BugCodeParameter4,
651 struct _KTRAP_FRAME* TrapFrame
652 );
653
654 BOOLEAN
655 NTAPI
656 MmIsAvailableSwapPage(VOID);
657
658 VOID
659 NTAPI
660 MmShowOutOfSpaceMessagePagingFile(VOID);
661
662 /* process.c ****************************************************************/
663
664 NTSTATUS
665 NTAPI
666 MmInitializeProcessAddressSpace(
667 IN PEPROCESS Process,
668 IN PEPROCESS Clone OPTIONAL,
669 IN PVOID Section OPTIONAL,
670 IN OUT PULONG Flags,
671 IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL
672 );
673
674 NTSTATUS
675 NTAPI
676 MmCreatePeb(struct _EPROCESS *Process);
677
678 PTEB
679 NTAPI
680 MmCreateTeb(
681 struct _EPROCESS *Process,
682 PCLIENT_ID ClientId,
683 PINITIAL_TEB InitialTeb
684 );
685
686 VOID
687 NTAPI
688 MmDeleteTeb(
689 struct _EPROCESS *Process,
690 PTEB Teb
691 );
692
693 VOID
694 NTAPI
695 MmCleanProcessAddressSpace(IN PEPROCESS Process);
696
697 NTSTATUS
698 NTAPI
699 MmDeleteProcessAddressSpace(IN PEPROCESS Process);
700
701 ULONG
702 NTAPI
703 MmGetSessionLocaleId(VOID);
704
705 NTSTATUS
706 NTAPI
707 MmSetMemoryPriorityProcess(
708 IN PEPROCESS Process,
709 IN UCHAR MemoryPriority
710 );
711
712 /* i386/pfault.c *************************************************************/
713
714 NTSTATUS
715 NTAPI
716 MmPageFault(
717 ULONG Cs,
718 PULONG Eip,
719 PULONG Eax,
720 ULONG Cr2,
721 ULONG ErrorCode
722 );
723
724 /* mm.c **********************************************************************/
725
726 NTSTATUS
727 NTAPI
728 MmAccessFault(
729 IN BOOLEAN StoreInstruction,
730 IN PVOID Address,
731 IN KPROCESSOR_MODE Mode,
732 IN PVOID TrapInformation
733 );
734
735 /* anonmem.c *****************************************************************/
736
737 NTSTATUS
738 NTAPI
739 MmNotPresentFaultVirtualMemory(
740 PMM_AVL_TABLE AddressSpace,
741 MEMORY_AREA* MemoryArea,
742 PVOID Address,
743 BOOLEAN Locked
744 );
745
746 NTSTATUS
747 NTAPI
748 MmPageOutVirtualMemory(
749 PMM_AVL_TABLE AddressSpace,
750 PMEMORY_AREA MemoryArea,
751 PVOID Address,
752 struct _MM_PAGEOP* PageOp
753 );
754
755 NTSTATUS
756 NTAPI
757 MmQueryAnonMem(
758 PMEMORY_AREA MemoryArea,
759 PVOID Address,
760 PMEMORY_BASIC_INFORMATION Info,
761 PULONG ResultLength
762 );
763
764 VOID
765 NTAPI
766 MmFreeVirtualMemory(
767 struct _EPROCESS* Process,
768 PMEMORY_AREA MemoryArea
769 );
770
771 NTSTATUS
772 NTAPI
773 MmProtectAnonMem(
774 PMM_AVL_TABLE AddressSpace,
775 PMEMORY_AREA MemoryArea,
776 PVOID BaseAddress,
777 ULONG Length,
778 ULONG Protect,
779 PULONG OldProtect
780 );
781
782 NTSTATUS
783 NTAPI
784 MmWritePageVirtualMemory(
785 PMM_AVL_TABLE AddressSpace,
786 PMEMORY_AREA MArea,
787 PVOID Address,
788 PMM_PAGEOP PageOp
789 );
790
791 /* kmap.c ********************************************************************/
792
793 PVOID
794 NTAPI
795 ExAllocatePage(VOID);
796
797 VOID
798 NTAPI
799 ExUnmapPage(PVOID Addr);
800
801 PVOID
802 NTAPI
803 ExAllocatePageWithPhysPage(PFN_TYPE Page);
804
805 NTSTATUS
806 NTAPI
807 MiCopyFromUserPage(
808 PFN_TYPE Page,
809 PVOID SourceAddress
810 );
811
812 NTSTATUS
813 NTAPI
814 MiZeroPage(PFN_TYPE Page);
815
816 /* memsafe.s *****************************************************************/
817
818 PVOID
819 FASTCALL
820 MmSafeReadPtr(PVOID Source);
821
822 /* pageop.c ******************************************************************/
823
824 VOID
825 NTAPI
826 MmReleasePageOp(PMM_PAGEOP PageOp);
827
828 PMM_PAGEOP
829 NTAPI
830 MmGetPageOp(
831 PMEMORY_AREA MArea,
832 HANDLE Pid,
833 PVOID Address,
834 PMM_SECTION_SEGMENT Segment,
835 ULONG Offset,
836 ULONG OpType,
837 BOOLEAN First
838 );
839
840 PMM_PAGEOP
841 NTAPI
842 MmCheckForPageOp(
843 PMEMORY_AREA MArea,
844 HANDLE Pid,
845 PVOID Address,
846 PMM_SECTION_SEGMENT Segment,
847 ULONG Offset
848 );
849
850 VOID
851 NTAPI
852 MmInitializePageOp(VOID);
853
854 /* process.c *****************************************************************/
855
856 PVOID
857 NTAPI
858 MmCreateKernelStack(BOOLEAN GuiStack, UCHAR Node);
859
860 VOID
861 NTAPI
862 MmDeleteKernelStack(PVOID Stack,
863 BOOLEAN GuiStack);
864
865 /* balace.c ******************************************************************/
866
867 VOID
868 NTAPI
869 MmInitializeMemoryConsumer(
870 ULONG Consumer,
871 NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed)
872 );
873
874 VOID
875 NTAPI
876 MmInitializeBalancer(
877 ULONG NrAvailablePages,
878 ULONG NrSystemPages
879 );
880
881 NTSTATUS
882 NTAPI
883 MmReleasePageMemoryConsumer(
884 ULONG Consumer,
885 PFN_TYPE Page
886 );
887
888 NTSTATUS
889 NTAPI
890 MmRequestPageMemoryConsumer(
891 ULONG Consumer,
892 BOOLEAN MyWait,
893 PPFN_TYPE AllocatedPage
894 );
895
896 VOID
897 NTAPI
898 MiInitBalancerThread(VOID);
899
900 VOID
901 NTAPI
902 MmRebalanceMemoryConsumers(VOID);
903
904 /* rmap.c **************************************************************/
905
906 VOID
907 NTAPI
908 MmSetRmapListHeadPage(
909 PFN_TYPE Page,
910 struct _MM_RMAP_ENTRY* ListHead
911 );
912
913 struct _MM_RMAP_ENTRY*
914 NTAPI
915 MmGetRmapListHeadPage(PFN_TYPE Page);
916
917 VOID
918 NTAPI
919 MmInsertRmap(
920 PFN_TYPE Page,
921 struct _EPROCESS *Process,
922 PVOID Address
923 );
924
925 VOID
926 NTAPI
927 MmDeleteAllRmaps(
928 PFN_TYPE Page,
929 PVOID Context,
930 VOID (*DeleteMapping)(PVOID Context, struct _EPROCESS *Process, PVOID Address)
931 );
932
933 VOID
934 NTAPI
935 MmDeleteRmap(
936 PFN_TYPE Page,
937 struct _EPROCESS *Process,
938 PVOID Address
939 );
940
941 VOID
942 NTAPI
943 MmInitializeRmapList(VOID);
944
945 VOID
946 NTAPI
947 MmSetCleanAllRmaps(PFN_TYPE Page);
948
949 VOID
950 NTAPI
951 MmSetDirtyAllRmaps(PFN_TYPE Page);
952
953 BOOLEAN
954 NTAPI
955 MmIsDirtyPageRmap(PFN_TYPE Page);
956
957 NTSTATUS
958 NTAPI
959 MmWritePagePhysicalAddress(PFN_TYPE Page);
960
961 NTSTATUS
962 NTAPI
963 MmPageOutPhysicalAddress(PFN_TYPE Page);
964
965 /* freelist.c **********************************************************/
966
967 #define ASSERT_PFN(x) ASSERT((x)->Flags.Type != 0)
968
969 FORCEINLINE
970 PPHYSICAL_PAGE
971 MiGetPfnEntry(IN PFN_TYPE Pfn)
972 {
973 PPHYSICAL_PAGE Page;
974 extern PPHYSICAL_PAGE MmPageArray;
975 extern ULONG MmPageArraySize;
976
977 /* Mark MmPageArraySize as unreferenced, otherwise it will appear as an unused variable on a Release build */
978 UNREFERENCED_PARAMETER(MmPageArraySize);
979
980 /* Make sure the PFN number is valid */
981 ASSERT(Pfn <= MmPageArraySize);
982
983 /* Get the entry */
984 Page = &MmPageArray[Pfn];
985
986 /* Make sure it's valid */
987 ASSERT_PFN(Page);
988
989 /* Return it */
990 return Page;
991 };
992
993 PFN_TYPE
994 NTAPI
995 MmGetLRUNextUserPage(PFN_TYPE PreviousPage);
996
997 PFN_TYPE
998 NTAPI
999 MmGetLRUFirstUserPage(VOID);
1000
1001 VOID
1002 NTAPI
1003 MmInsertLRULastUserPage(PFN_TYPE Page);
1004
1005 VOID
1006 NTAPI
1007 MmRemoveLRUUserPage(PFN_TYPE Page);
1008
1009 VOID
1010 NTAPI
1011 MmLockPage(PFN_TYPE Page);
1012
1013 VOID
1014 NTAPI
1015 MmLockPageUnsafe(PFN_TYPE Page);
1016
1017 VOID
1018 NTAPI
1019 MmUnlockPage(PFN_TYPE Page);
1020
1021 ULONG
1022 NTAPI
1023 MmGetLockCountPage(PFN_TYPE Page);
1024
1025 static
1026 __inline
1027 KIRQL
1028 NTAPI
1029 MmAcquirePageListLock()
1030 {
1031 return KeAcquireQueuedSpinLock(LockQueuePfnLock);
1032 }
1033
1034 FORCEINLINE
1035 VOID
1036 NTAPI
1037 MmReleasePageListLock(KIRQL oldIrql)
1038 {
1039 KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
1040 }
1041
1042 VOID
1043 NTAPI
1044 MmInitializePageList(
1045 VOID
1046 );
1047
1048 PFN_TYPE
1049 NTAPI
1050 MmGetContinuousPages(
1051 ULONG NumberOfBytes,
1052 PHYSICAL_ADDRESS LowestAcceptableAddress,
1053 PHYSICAL_ADDRESS HighestAcceptableAddress,
1054 PHYSICAL_ADDRESS BoundaryAddressMultiple
1055 );
1056
1057 NTSTATUS
1058 NTAPI
1059 MmZeroPageThreadMain(
1060 PVOID Context
1061 );
1062
1063 /* i386/page.c *********************************************************/
1064
1065 PVOID
1066 NTAPI
1067 MmCreateHyperspaceMapping(PFN_TYPE Page);
1068
1069 PFN_TYPE
1070 NTAPI
1071 MmDeleteHyperspaceMapping(PVOID Address);
1072
1073 NTSTATUS
1074 NTAPI
1075 MmCreateVirtualMappingForKernel(
1076 PVOID Address,
1077 ULONG flProtect,
1078 PPFN_TYPE Pages,
1079 ULONG PageCount
1080 );
1081
1082 NTSTATUS
1083 NTAPI
1084 MmCommitPagedPoolAddress(
1085 PVOID Address,
1086 BOOLEAN Locked
1087 );
1088
1089 NTSTATUS
1090 NTAPI
1091 MmCreateVirtualMapping(
1092 struct _EPROCESS* Process,
1093 PVOID Address,
1094 ULONG flProtect,
1095 PPFN_TYPE Pages,
1096 ULONG PageCount
1097 );
1098
1099 NTSTATUS
1100 NTAPI
1101 MmCreateVirtualMappingUnsafe(
1102 struct _EPROCESS* Process,
1103 PVOID Address,
1104 ULONG flProtect,
1105 PPFN_TYPE Pages,
1106 ULONG PageCount
1107 );
1108
1109 ULONG
1110 NTAPI
1111 MmGetPageProtect(
1112 struct _EPROCESS* Process,
1113 PVOID Address);
1114
1115 VOID
1116 NTAPI
1117 MmSetPageProtect(
1118 struct _EPROCESS* Process,
1119 PVOID Address,
1120 ULONG flProtect
1121 );
1122
1123 BOOLEAN
1124 NTAPI
1125 MmIsPagePresent(
1126 struct _EPROCESS* Process,
1127 PVOID Address
1128 );
1129
1130 VOID
1131 NTAPI
1132 MmInitGlobalKernelPageDirectory(VOID);
1133
1134 VOID
1135 NTAPI
1136 MmDisableVirtualMapping(
1137 struct _EPROCESS *Process,
1138 PVOID Address,
1139 BOOLEAN* WasDirty,
1140 PPFN_TYPE Page
1141 );
1142
1143 VOID
1144 NTAPI
1145 MmEnableVirtualMapping(
1146 struct _EPROCESS *Process,
1147 PVOID Address
1148 );
1149
1150 VOID
1151 NTAPI
1152 MmRawDeleteVirtualMapping(PVOID Address);
1153
1154 VOID
1155 NTAPI
1156 MmDeletePageFileMapping(
1157 struct _EPROCESS *Process,
1158 PVOID Address,
1159 SWAPENTRY* SwapEntry
1160 );
1161
1162 NTSTATUS
1163 NTAPI
1164 MmCreatePageFileMapping(
1165 struct _EPROCESS *Process,
1166 PVOID Address,
1167 SWAPENTRY SwapEntry
1168 );
1169
1170 BOOLEAN
1171 NTAPI
1172 MmIsPageSwapEntry(
1173 struct _EPROCESS *Process,
1174 PVOID Address
1175 );
1176
1177 VOID
1178 NTAPI
1179 MmTransferOwnershipPage(
1180 PFN_TYPE Page,
1181 ULONG NewConsumer
1182 );
1183
1184 VOID
1185 NTAPI
1186 MmSetDirtyPage(
1187 struct _EPROCESS *Process,
1188 PVOID Address
1189 );
1190
1191 PFN_TYPE
1192 NTAPI
1193 MmAllocPage(
1194 ULONG Consumer,
1195 SWAPENTRY SavedSwapEntry
1196 );
1197
1198 LONG
1199 NTAPI
1200 MmAllocPagesSpecifyRange(
1201 ULONG Consumer,
1202 PHYSICAL_ADDRESS LowestAddress,
1203 PHYSICAL_ADDRESS HighestAddress,
1204 ULONG NumberOfPages,
1205 PPFN_TYPE Pages
1206 );
1207
1208 VOID
1209 NTAPI
1210 MmDereferencePage(PFN_TYPE Page);
1211
1212 VOID
1213 NTAPI
1214 MmReferencePage(PFN_TYPE Page);
1215
1216 VOID
1217 NTAPI
1218 MmReferencePageUnsafe(PFN_TYPE Page);
1219
1220 ULONG
1221 NTAPI
1222 MmGetReferenceCountPage(PFN_TYPE Page);
1223
1224 BOOLEAN
1225 NTAPI
1226 MmIsPageInUse(PFN_TYPE Page);
1227
1228 VOID
1229 NTAPI
1230 MmSetFlagsPage(
1231 PFN_TYPE Page,
1232 ULONG Flags);
1233
1234 ULONG
1235 NTAPI
1236 MmGetFlagsPage(PFN_TYPE Page);
1237
1238 VOID
1239 NTAPI
1240 MmSetSavedSwapEntryPage(
1241 PFN_TYPE Page,
1242 SWAPENTRY SavedSwapEntry);
1243
1244 SWAPENTRY
1245 NTAPI
1246 MmGetSavedSwapEntryPage(PFN_TYPE Page);
1247
1248 VOID
1249 NTAPI
1250 MmSetCleanPage(
1251 struct _EPROCESS *Process,
1252 PVOID Address
1253 );
1254
1255 NTSTATUS
1256 NTAPI
1257 MmCreatePageTable(PVOID PAddress);
1258
1259 VOID
1260 NTAPI
1261 MmDeletePageTable(
1262 struct _EPROCESS *Process,
1263 PVOID Address
1264 );
1265
1266 PFN_TYPE
1267 NTAPI
1268 MmGetPfnForProcess(
1269 struct _EPROCESS *Process,
1270 PVOID Address
1271 );
1272
1273 BOOLEAN
1274 NTAPI
1275 MmCreateProcessAddressSpace(
1276 IN ULONG MinWs,
1277 IN PEPROCESS Dest,
1278 IN PULONG DirectoryTableBase
1279 );
1280
1281 NTSTATUS
1282 NTAPI
1283 MmInitializeHandBuiltProcess(
1284 IN PEPROCESS Process,
1285 IN PULONG DirectoryTableBase
1286 );
1287
1288
1289 NTSTATUS
1290 NTAPI
1291 MmInitializeHandBuiltProcess2(
1292 IN PEPROCESS Process
1293 );
1294
1295 NTSTATUS
1296 NTAPI
1297 MmReleaseMmInfo(struct _EPROCESS *Process);
1298
1299 NTSTATUS
1300 NTAPI
1301 Mmi386ReleaseMmInfo(struct _EPROCESS *Process);
1302
1303 VOID
1304 NTAPI
1305 MmDeleteVirtualMapping(
1306 struct _EPROCESS *Process,
1307 PVOID Address,
1308 BOOLEAN FreePage,
1309 BOOLEAN* WasDirty,
1310 PPFN_TYPE Page
1311 );
1312
1313 BOOLEAN
1314 NTAPI
1315 MmIsDirtyPage(
1316 struct _EPROCESS *Process,
1317 PVOID Address
1318 );
1319
1320 VOID
1321 NTAPI
1322 MmMarkPageMapped(PFN_TYPE Page);
1323
1324 VOID
1325 NTAPI
1326 MmMarkPageUnmapped(PFN_TYPE Page);
1327
1328 VOID
1329 NTAPI
1330 MmUpdatePageDir(
1331 struct _EPROCESS *Process,
1332 PVOID Address,
1333 ULONG Size
1334 );
1335
1336 VOID
1337 NTAPI
1338 MiInitPageDirectoryMap(VOID);
1339
1340 ULONG
1341 NTAPI
1342 MiGetUserPageDirectoryCount(VOID);
1343
1344 /* wset.c ********************************************************************/
1345
1346 NTSTATUS
1347 MmTrimUserMemory(
1348 ULONG Target,
1349 ULONG Priority,
1350 PULONG NrFreedPages
1351 );
1352
1353 /* region.c ************************************************************/
1354
1355 NTSTATUS
1356 NTAPI
1357 MmAlterRegion(
1358 PMM_AVL_TABLE AddressSpace,
1359 PVOID BaseAddress,
1360 PLIST_ENTRY RegionListHead,
1361 PVOID StartAddress,
1362 ULONG Length,
1363 ULONG NewType,
1364 ULONG NewProtect,
1365 PMM_ALTER_REGION_FUNC AlterFunc
1366 );
1367
1368 VOID
1369 NTAPI
1370 MmInitializeRegion(
1371 PLIST_ENTRY RegionListHead,
1372 SIZE_T Length,
1373 ULONG Type,
1374 ULONG Protect
1375 );
1376
1377 PMM_REGION
1378 NTAPI
1379 MmFindRegion(
1380 PVOID BaseAddress,
1381 PLIST_ENTRY RegionListHead,
1382 PVOID Address,
1383 PVOID* RegionBaseAddress
1384 );
1385
1386 /* section.c *****************************************************************/
1387
1388 PFILE_OBJECT
1389 NTAPI
1390 MmGetFileObjectForSection(
1391 IN PROS_SECTION_OBJECT Section
1392 );
1393 NTSTATUS
1394 NTAPI
1395 MmGetFileNameForAddress(
1396 IN PVOID Address,
1397 OUT PUNICODE_STRING ModuleName
1398 );
1399
1400 NTSTATUS
1401 NTAPI
1402 MmGetFileNameForSection(
1403 IN PROS_SECTION_OBJECT Section,
1404 OUT POBJECT_NAME_INFORMATION *ModuleName
1405 );
1406
1407 PVOID
1408 NTAPI
1409 MmAllocateSection(
1410 IN ULONG Length,
1411 PVOID BaseAddress
1412 );
1413
1414 NTSTATUS
1415 NTAPI
1416 MmQuerySectionView(
1417 PMEMORY_AREA MemoryArea,
1418 PVOID Address,
1419 PMEMORY_BASIC_INFORMATION Info,
1420 PULONG ResultLength
1421 );
1422
1423 NTSTATUS
1424 NTAPI
1425 MmProtectSectionView(
1426 PMM_AVL_TABLE AddressSpace,
1427 PMEMORY_AREA MemoryArea,
1428 PVOID BaseAddress,
1429 ULONG Length,
1430 ULONG Protect,
1431 PULONG OldProtect
1432 );
1433
1434 NTSTATUS
1435 NTAPI
1436 MmWritePageSectionView(
1437 PMM_AVL_TABLE AddressSpace,
1438 PMEMORY_AREA MArea,
1439 PVOID Address,
1440 PMM_PAGEOP PageOp
1441 );
1442
1443 NTSTATUS
1444 NTAPI
1445 MmInitSectionImplementation(VOID);
1446
1447 NTSTATUS
1448 NTAPI
1449 MmNotPresentFaultSectionView(
1450 PMM_AVL_TABLE AddressSpace,
1451 MEMORY_AREA* MemoryArea,
1452 PVOID Address,
1453 BOOLEAN Locked
1454 );
1455
1456 NTSTATUS
1457 NTAPI
1458 MmPageOutSectionView(
1459 PMM_AVL_TABLE AddressSpace,
1460 PMEMORY_AREA MemoryArea,
1461 PVOID Address,
1462 struct _MM_PAGEOP *PageOp
1463 );
1464
1465 NTSTATUS
1466 NTAPI
1467 MmCreatePhysicalMemorySection(VOID);
1468
1469 NTSTATUS
1470 NTAPI
1471 MmAccessFaultSectionView(
1472 PMM_AVL_TABLE AddressSpace,
1473 MEMORY_AREA* MemoryArea,
1474 PVOID Address,
1475 BOOLEAN Locked
1476 );
1477
1478 VOID
1479 NTAPI
1480 MmFreeSectionSegments(PFILE_OBJECT FileObject);
1481
1482 /* mpw.c *********************************************************************/
1483
1484 NTSTATUS
1485 NTAPI
1486 MmInitMpwThread(VOID);
1487
1488 NTSTATUS
1489 NTAPI
1490 MmInitBsmThread(VOID);
1491
1492 /* pager.c *******************************************************************/
1493
1494 BOOLEAN
1495 NTAPI
1496 MiIsPagerThread(VOID);
1497
1498 VOID
1499 NTAPI
1500 MiStartPagerThread(VOID);
1501
1502 VOID
1503 NTAPI
1504 MiStopPagerThread(VOID);
1505
1506 NTSTATUS
1507 FASTCALL
1508 MiQueryVirtualMemory(
1509 IN HANDLE ProcessHandle,
1510 IN PVOID Address,
1511 IN MEMORY_INFORMATION_CLASS VirtualMemoryInformationClass,
1512 OUT PVOID VirtualMemoryInformation,
1513 IN ULONG Length,
1514 OUT PULONG ResultLength
1515 );
1516
1517 /* sysldr.c ******************************************************************/
1518
1519 VOID
1520 NTAPI
1521 MiReloadBootLoadedDrivers(
1522 IN PLOADER_PARAMETER_BLOCK LoaderBlock
1523 );
1524
1525 BOOLEAN
1526 NTAPI
1527 MiInitializeLoadedModuleList(
1528 IN PLOADER_PARAMETER_BLOCK LoaderBlock
1529 );
1530
1531 NTSTATUS
1532 NTAPI
1533 MmLoadSystemImage(
1534 IN PUNICODE_STRING FileName,
1535 IN PUNICODE_STRING NamePrefix OPTIONAL,
1536 IN PUNICODE_STRING LoadedName OPTIONAL,
1537 IN ULONG Flags,
1538 OUT PVOID *ModuleObject,
1539 OUT PVOID *ImageBaseAddress
1540 );
1541
1542 NTSTATUS
1543 NTAPI
1544 MmUnloadSystemImage(
1545 IN PVOID ImageHandle
1546 );
1547
1548 NTSTATUS
1549 NTAPI
1550 MmCheckSystemImage(
1551 IN HANDLE ImageHandle,
1552 IN BOOLEAN PurgeSection
1553 );
1554
1555 NTSTATUS
1556 NTAPI
1557 MmCallDllInitialize(
1558 IN PLDR_DATA_TABLE_ENTRY LdrEntry,
1559 IN PLIST_ENTRY ListHead
1560 );
1561
1562 /* ReactOS Mm Hacks */
1563 VOID
1564 FASTCALL
1565 MiSyncForProcessAttach(
1566 IN PKTHREAD NextThread,
1567 IN PEPROCESS Process
1568 );
1569
1570 VOID
1571 FASTCALL
1572 MiSyncForContextSwitch(
1573 IN PKTHREAD Thread
1574 );
1575
1576 extern PMM_AVL_TABLE MmKernelAddressSpace;
1577
1578 FORCEINLINE
1579 VOID
1580 MmLockAddressSpace(PMM_AVL_TABLE AddressSpace)
1581 {
1582 KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, VadRoot)->AddressCreationLock);
1583 }
1584
1585 FORCEINLINE
1586 VOID
1587 MmUnlockAddressSpace(PMM_AVL_TABLE AddressSpace)
1588 {
1589 KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, VadRoot)->AddressCreationLock);
1590 }
1591
1592 FORCEINLINE
1593 PEPROCESS
1594 MmGetAddressSpaceOwner(IN PMM_AVL_TABLE AddressSpace)
1595 {
1596 if (AddressSpace == MmKernelAddressSpace) return NULL;
1597 return CONTAINING_RECORD(AddressSpace, EPROCESS, VadRoot);
1598 }
1599
1600 FORCEINLINE
1601 PMM_AVL_TABLE
1602 MmGetCurrentAddressSpace(VOID)
1603 {
1604 return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->VadRoot;
1605 }
1606
1607 FORCEINLINE
1608 PMM_AVL_TABLE
1609 MmGetKernelAddressSpace(VOID)
1610 {
1611 return MmKernelAddressSpace;
1612 }
1613
1614 #endif