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