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