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