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 inline 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 ULONG 1139 NTAPI 1140 MmGetPageProtect( 1141 struct _EPROCESS* Process, 1142 PVOID Address); 1143 1144 VOID 1145 NTAPI 1146 MmSetPageProtect( 1147 struct _EPROCESS* Process, 1148 PVOID Address, 1149 ULONG flProtect 1150 ); 1151 1152 BOOLEAN 1153 NTAPI 1154 MmIsPagePresent( 1155 struct _EPROCESS* Process, 1156 PVOID Address 1157 ); 1158 1159 BOOLEAN 1160 NTAPI 1161 MmIsDisabledPage( 1162 struct _EPROCESS* Process, 1163 PVOID Address 1164 ); 1165 1166 CODE_SEG("INIT") 1167 VOID 1168 NTAPI 1169 MmInitGlobalKernelPageDirectory(VOID); 1170 1171 VOID 1172 NTAPI 1173 MmDeletePageFileMapping( 1174 struct _EPROCESS *Process, 1175 PVOID Address, 1176 SWAPENTRY* SwapEntry 1177 ); 1178 1179 NTSTATUS 1180 NTAPI 1181 MmCreatePageFileMapping( 1182 struct _EPROCESS *Process, 1183 PVOID Address, 1184 SWAPENTRY SwapEntry 1185 ); 1186 1187 VOID 1188 NTAPI 1189 MmGetPageFileMapping( 1190 PEPROCESS Process, 1191 PVOID Address, 1192 SWAPENTRY *SwapEntry); 1193 1194 BOOLEAN 1195 NTAPI 1196 MmIsPageSwapEntry( 1197 struct _EPROCESS *Process, 1198 PVOID Address 1199 ); 1200 1201 PFN_NUMBER 1202 NTAPI 1203 MmAllocPage( 1204 ULONG Consumer 1205 ); 1206 1207 VOID 1208 NTAPI 1209 MmDereferencePage(PFN_NUMBER Page); 1210 1211 VOID 1212 NTAPI 1213 MmReferencePage(PFN_NUMBER Page); 1214 1215 ULONG 1216 NTAPI 1217 MmGetReferenceCountPage(PFN_NUMBER Page); 1218 1219 BOOLEAN 1220 NTAPI 1221 MmIsPageInUse(PFN_NUMBER Page); 1222 1223 VOID 1224 NTAPI 1225 MmSetSavedSwapEntryPage( 1226 PFN_NUMBER Page, 1227 SWAPENTRY SavedSwapEntry); 1228 1229 SWAPENTRY 1230 NTAPI 1231 MmGetSavedSwapEntryPage(PFN_NUMBER Page); 1232 1233 VOID 1234 NTAPI 1235 MmSetCleanPage( 1236 struct _EPROCESS *Process, 1237 PVOID Address 1238 ); 1239 1240 VOID 1241 NTAPI 1242 MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN Bit); 1243 #define MmSetCleanPage(__P, __A) MmSetDirtyBit(__P, __A, FALSE) 1244 #define MmSetDirtyPage(__P, __A) MmSetDirtyBit(__P, __A, TRUE) 1245 1246 VOID 1247 NTAPI 1248 MmDeletePageTable( 1249 struct _EPROCESS *Process, 1250 PVOID Address 1251 ); 1252 1253 PFN_NUMBER 1254 NTAPI 1255 MmGetPfnForProcess( 1256 struct _EPROCESS *Process, 1257 PVOID Address 1258 ); 1259 1260 BOOLEAN 1261 NTAPI 1262 MmCreateProcessAddressSpace( 1263 IN ULONG MinWs, 1264 IN PEPROCESS Dest, 1265 IN PULONG_PTR DirectoryTableBase 1266 ); 1267 1268 CODE_SEG("INIT") 1269 NTSTATUS 1270 NTAPI 1271 MmInitializeHandBuiltProcess( 1272 IN PEPROCESS Process, 1273 IN PULONG_PTR DirectoryTableBase 1274 ); 1275 1276 CODE_SEG("INIT") 1277 NTSTATUS 1278 NTAPI 1279 MmInitializeHandBuiltProcess2( 1280 IN PEPROCESS Process 1281 ); 1282 1283 NTSTATUS 1284 NTAPI 1285 MmSetExecuteOptions(IN ULONG ExecuteOptions); 1286 1287 NTSTATUS 1288 NTAPI 1289 MmGetExecuteOptions(IN PULONG ExecuteOptions); 1290 1291 VOID 1292 NTAPI 1293 MmDeleteVirtualMapping( 1294 struct _EPROCESS *Process, 1295 PVOID Address, 1296 BOOLEAN* WasDirty, 1297 PPFN_NUMBER Page 1298 ); 1299 1300 /* arch/procsup.c ************************************************************/ 1301 1302 BOOLEAN 1303 MiArchCreateProcessAddressSpace( 1304 _In_ PEPROCESS Process, 1305 _In_ PULONG_PTR DirectoryTableBase); 1306 1307 /* wset.c ********************************************************************/ 1308 1309 NTSTATUS 1310 MmTrimUserMemory( 1311 ULONG Target, 1312 ULONG Priority, 1313 PULONG NrFreedPages 1314 ); 1315 1316 /* region.c ************************************************************/ 1317 1318 NTSTATUS 1319 NTAPI 1320 MmAlterRegion( 1321 PMMSUPPORT AddressSpace, 1322 PVOID BaseAddress, 1323 PLIST_ENTRY RegionListHead, 1324 PVOID StartAddress, 1325 SIZE_T Length, 1326 ULONG NewType, 1327 ULONG NewProtect, 1328 PMM_ALTER_REGION_FUNC AlterFunc 1329 ); 1330 1331 VOID 1332 NTAPI 1333 MmInitializeRegion( 1334 PLIST_ENTRY RegionListHead, 1335 SIZE_T Length, 1336 ULONG Type, 1337 ULONG Protect 1338 ); 1339 1340 PMM_REGION 1341 NTAPI 1342 MmFindRegion( 1343 PVOID BaseAddress, 1344 PLIST_ENTRY RegionListHead, 1345 PVOID Address, 1346 PVOID* RegionBaseAddress 1347 ); 1348 1349 /* section.c *****************************************************************/ 1350 1351 #define PFN_FROM_SSE(E) ((PFN_NUMBER)((E) >> PAGE_SHIFT)) 1352 #define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001) 1353 #define MM_IS_WAIT_PTE(E) \ 1354 (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY) 1355 #define MAKE_PFN_SSE(P) ((ULONG_PTR)((P) << PAGE_SHIFT)) 1356 #define SWAPENTRY_FROM_SSE(E) ((E) >> 1) 1357 #define MAKE_SWAP_SSE(S) (((ULONG_PTR)(S) << 1) | 0x1) 1358 #define DIRTY_SSE(E) ((E) | 2) 1359 #define CLEAN_SSE(E) ((E) & ~2) 1360 #define IS_DIRTY_SSE(E) ((E) & 2) 1361 #define WRITE_SSE(E) ((E) | 4) 1362 #define IS_WRITE_SSE(E) ((E) & 4) 1363 #ifdef _WIN64 1364 #define PAGE_FROM_SSE(E) ((E) & 0xFFFFFFF000ULL) 1365 #else 1366 #define PAGE_FROM_SSE(E) ((E) & 0xFFFFF000) 1367 #endif 1368 #define SHARE_COUNT_FROM_SSE(E) (((E) & 0x00000FFC) >> 3) 1369 #define MAX_SHARE_COUNT 0x1FF 1370 #define MAKE_SSE(P, C) ((ULONG_PTR)((P) | ((C) << 3))) 1371 #define BUMPREF_SSE(E) (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) + 1) << 3) | ((E) & 0x7)) 1372 #define DECREF_SSE(E) (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) - 1) << 3) | ((E) & 0x7)) 1373 1374 VOID 1375 NTAPI 1376 _MmLockSectionSegment(PMM_SECTION_SEGMENT Segment, 1377 const char *file, 1378 int line); 1379 1380 #define MmLockSectionSegment(x) _MmLockSectionSegment(x,__FILE__,__LINE__) 1381 1382 VOID 1383 NTAPI 1384 _MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment, 1385 const char *file, 1386 int line); 1387 1388 #define MmUnlockSectionSegment(x) _MmUnlockSectionSegment(x,__FILE__,__LINE__) 1389 1390 VOID 1391 NTAPI 1392 MmGetImageInformation( 1393 OUT PSECTION_IMAGE_INFORMATION ImageInformation 1394 ); 1395 1396 PFILE_OBJECT 1397 NTAPI 1398 MmGetFileObjectForSection( 1399 IN PVOID Section 1400 ); 1401 NTSTATUS 1402 NTAPI 1403 MmGetFileNameForAddress( 1404 IN PVOID Address, 1405 OUT PUNICODE_STRING ModuleName 1406 ); 1407 1408 NTSTATUS 1409 NTAPI 1410 MmGetFileNameForSection( 1411 IN PVOID Section, 1412 OUT POBJECT_NAME_INFORMATION *ModuleName 1413 ); 1414 1415 NTSTATUS 1416 NTAPI 1417 MmQuerySectionView( 1418 PMEMORY_AREA MemoryArea, 1419 PVOID Address, 1420 PMEMORY_BASIC_INFORMATION Info, 1421 PSIZE_T ResultLength 1422 ); 1423 1424 NTSTATUS 1425 NTAPI 1426 MmProtectSectionView( 1427 PMMSUPPORT AddressSpace, 1428 PMEMORY_AREA MemoryArea, 1429 PVOID BaseAddress, 1430 SIZE_T Length, 1431 ULONG Protect, 1432 PULONG OldProtect 1433 ); 1434 1435 CODE_SEG("INIT") 1436 NTSTATUS 1437 NTAPI 1438 MmInitSectionImplementation(VOID); 1439 1440 NTSTATUS 1441 NTAPI 1442 MmNotPresentFaultSectionView( 1443 PMMSUPPORT AddressSpace, 1444 MEMORY_AREA* MemoryArea, 1445 PVOID Address, 1446 BOOLEAN Locked 1447 ); 1448 1449 NTSTATUS 1450 NTAPI 1451 MmPageOutSectionView( 1452 PMMSUPPORT AddressSpace, 1453 PMEMORY_AREA MemoryArea, 1454 PVOID Address, 1455 ULONG_PTR Entry 1456 ); 1457 1458 CODE_SEG("INIT") 1459 NTSTATUS 1460 NTAPI 1461 MmCreatePhysicalMemorySection(VOID); 1462 1463 NTSTATUS 1464 NTAPI 1465 MmAccessFaultSectionView( 1466 PMMSUPPORT AddressSpace, 1467 MEMORY_AREA* MemoryArea, 1468 PVOID Address, 1469 BOOLEAN Locked 1470 ); 1471 1472 VOID 1473 NTAPI 1474 MmFreeSectionSegments(PFILE_OBJECT FileObject); 1475 1476 /* Exported from NT 6.2 Onward. We keep it internal. */ 1477 NTSTATUS 1478 NTAPI 1479 MmMapViewInSystemSpaceEx ( 1480 _In_ PVOID Section, 1481 _Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase, 1482 _Inout_ PSIZE_T ViewSize, 1483 _Inout_ PLARGE_INTEGER SectionOffset, 1484 _In_ ULONG_PTR Flags 1485 ); 1486 1487 BOOLEAN 1488 NTAPI 1489 MmArePagesResident( 1490 _In_ PEPROCESS Process, 1491 _In_ PVOID BaseAddress, 1492 _In_ ULONG Length); 1493 1494 NTSTATUS 1495 NTAPI 1496 MmMakePagesDirty( 1497 _In_ PEPROCESS Process, 1498 _In_ PVOID Address, 1499 _In_ ULONG Length); 1500 1501 NTSTATUS 1502 NTAPI 1503 MmFlushSegment( 1504 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1505 _In_opt_ PLARGE_INTEGER Offset, 1506 _In_ ULONG Length, 1507 _Out_opt_ PIO_STATUS_BLOCK Iosb); 1508 1509 NTSTATUS 1510 NTAPI 1511 MmMakeDataSectionResident( 1512 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1513 _In_ LONGLONG Offset, 1514 _In_ ULONG Length, 1515 _In_ PLARGE_INTEGER ValidDataLength); 1516 1517 BOOLEAN 1518 NTAPI 1519 MmPurgeSegment( 1520 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1521 _In_opt_ PLARGE_INTEGER Offset, 1522 _In_ ULONG Length); 1523 1524 BOOLEAN 1525 NTAPI 1526 MmCheckDirtySegment( 1527 PMM_SECTION_SEGMENT Segment, 1528 PLARGE_INTEGER Offset, 1529 BOOLEAN ForceDirty, 1530 BOOLEAN PageOut); 1531 1532 BOOLEAN 1533 NTAPI 1534 MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea, 1535 PMM_SECTION_SEGMENT Segment, 1536 PLARGE_INTEGER Offset, 1537 BOOLEAN Dirty, 1538 BOOLEAN PageOut, 1539 ULONG_PTR *InEntry); 1540 1541 _When_(OldIrql == MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL)) 1542 _When_(OldIrql == MM_NOIRQL, _Requires_lock_not_held_(MmPfnLock)) 1543 _When_(OldIrql != MM_NOIRQL, _Requires_lock_held_(MmPfnLock)) 1544 _When_(OldIrql != MM_NOIRQL, _Releases_lock_(MmPfnLock)) 1545 _When_(OldIrql != MM_NOIRQL, _IRQL_requires_(DISPATCH_LEVEL)) 1546 VOID 1547 NTAPI 1548 MmDereferenceSegmentWithLock( 1549 _In_ PMM_SECTION_SEGMENT Segment, 1550 _In_ _When_(OldIrql != MM_NOIRQL, _IRQL_restores_) KIRQL OldIrql); 1551 1552 _IRQL_requires_max_(DISPATCH_LEVEL) 1553 _Requires_lock_not_held_(MmPfnLock) 1554 FORCEINLINE 1555 VOID 1556 MmDereferenceSegment(PMM_SECTION_SEGMENT Segment) 1557 { 1558 MmDereferenceSegmentWithLock(Segment, MM_NOIRQL); 1559 } 1560 1561 NTSTATUS 1562 NTAPI 1563 MmExtendSection( 1564 _In_ PVOID Section, 1565 _Inout_ PLARGE_INTEGER NewSize); 1566 1567 /* sptab.c *******************************************************************/ 1568 1569 NTSTATUS 1570 NTAPI 1571 _MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, 1572 PLARGE_INTEGER Offset, 1573 ULONG_PTR Entry, 1574 const char *file, 1575 int line); 1576 1577 ULONG_PTR 1578 NTAPI 1579 _MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, 1580 PLARGE_INTEGER Offset, 1581 const char *file, 1582 int line); 1583 1584 #define MmSetPageEntrySectionSegment(S,O,E) _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__) 1585 1586 #define MmGetPageEntrySectionSegment(S,O) _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__) 1587 1588 /* sysldr.c ******************************************************************/ 1589 1590 CODE_SEG("INIT") 1591 VOID 1592 NTAPI 1593 MiReloadBootLoadedDrivers( 1594 IN PLOADER_PARAMETER_BLOCK LoaderBlock 1595 ); 1596 1597 CODE_SEG("INIT") 1598 BOOLEAN 1599 NTAPI 1600 MiInitializeLoadedModuleList( 1601 IN PLOADER_PARAMETER_BLOCK LoaderBlock 1602 ); 1603 1604 BOOLEAN 1605 NTAPI 1606 MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask); 1607 1608 VOID 1609 NTAPI 1610 MmMakeKernelResourceSectionWritable(VOID); 1611 1612 NTSTATUS 1613 NTAPI 1614 MmLoadSystemImage( 1615 IN PUNICODE_STRING FileName, 1616 IN PUNICODE_STRING NamePrefix OPTIONAL, 1617 IN PUNICODE_STRING LoadedName OPTIONAL, 1618 IN ULONG Flags, 1619 OUT PVOID *ModuleObject, 1620 OUT PVOID *ImageBaseAddress 1621 ); 1622 1623 NTSTATUS 1624 NTAPI 1625 MmUnloadSystemImage( 1626 IN PVOID ImageHandle 1627 ); 1628 1629 NTSTATUS 1630 NTAPI 1631 MmCheckSystemImage( 1632 IN HANDLE ImageHandle, 1633 IN BOOLEAN PurgeSection 1634 ); 1635 1636 NTSTATUS 1637 NTAPI 1638 MmCallDllInitialize( 1639 IN PLDR_DATA_TABLE_ENTRY LdrEntry, 1640 IN PLIST_ENTRY ListHead 1641 ); 1642 1643 VOID 1644 NTAPI 1645 MmFreeDriverInitialization( 1646 IN PLDR_DATA_TABLE_ENTRY LdrEntry); 1647 1648 /* procsup.c *****************************************************************/ 1649 1650 NTSTATUS 1651 NTAPI 1652 MmGrowKernelStack( 1653 IN PVOID StackPointer 1654 ); 1655 1656 1657 FORCEINLINE 1658 VOID 1659 MmLockAddressSpace(PMMSUPPORT AddressSpace) 1660 { 1661 KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 1662 } 1663 1664 FORCEINLINE 1665 VOID 1666 MmUnlockAddressSpace(PMMSUPPORT AddressSpace) 1667 { 1668 KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 1669 } 1670 1671 FORCEINLINE 1672 PEPROCESS 1673 MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace) 1674 { 1675 if (AddressSpace == MmKernelAddressSpace) return NULL; 1676 return CONTAINING_RECORD(AddressSpace, EPROCESS, Vm); 1677 } 1678 1679 FORCEINLINE 1680 PMMSUPPORT 1681 MmGetCurrentAddressSpace(VOID) 1682 { 1683 return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm; 1684 } 1685 1686 FORCEINLINE 1687 PMMSUPPORT 1688 MmGetKernelAddressSpace(VOID) 1689 { 1690 return MmKernelAddressSpace; 1691 } 1692 1693 1694 /* expool.c ******************************************************************/ 1695 1696 VOID 1697 NTAPI 1698 ExpCheckPoolAllocation( 1699 PVOID P, 1700 POOL_TYPE PoolType, 1701 ULONG Tag); 1702 1703 VOID 1704 NTAPI 1705 ExReturnPoolQuota( 1706 IN PVOID P); 1707 1708 1709 /* mmsup.c *****************************************************************/ 1710 1711 NTSTATUS 1712 NTAPI 1713 MmAdjustWorkingSetSize( 1714 IN SIZE_T WorkingSetMinimumInBytes, 1715 IN SIZE_T WorkingSetMaximumInBytes, 1716 IN ULONG SystemCache, 1717 IN BOOLEAN IncreaseOkay); 1718 1719 1720 /* session.c *****************************************************************/ 1721 1722 _IRQL_requires_max_(APC_LEVEL) 1723 NTSTATUS 1724 NTAPI 1725 MmAttachSession( 1726 _Inout_ PVOID SessionEntry, 1727 _Out_ PKAPC_STATE ApcState); 1728 1729 _IRQL_requires_max_(APC_LEVEL) 1730 VOID 1731 NTAPI 1732 MmDetachSession( 1733 _Inout_ PVOID SessionEntry, 1734 _Out_ PKAPC_STATE ApcState); 1735 1736 VOID 1737 NTAPI 1738 MmQuitNextSession( 1739 _Inout_ PVOID SessionEntry); 1740 1741 PVOID 1742 NTAPI 1743 MmGetSessionById( 1744 _In_ ULONG SessionId); 1745 1746 _IRQL_requires_max_(APC_LEVEL) 1747 VOID 1748 NTAPI 1749 MmSetSessionLocaleId( 1750 _In_ LCID LocaleId); 1751 1752 /* shutdown.c *****************************************************************/ 1753 1754 VOID 1755 MmShutdownSystem(IN ULONG Phase); 1756 1757 /* virtual.c *****************************************************************/ 1758 1759 NTSTATUS 1760 NTAPI 1761 MmCopyVirtualMemory(IN PEPROCESS SourceProcess, 1762 IN PVOID SourceAddress, 1763 IN PEPROCESS TargetProcess, 1764 OUT PVOID TargetAddress, 1765 IN SIZE_T BufferSize, 1766 IN KPROCESSOR_MODE PreviousMode, 1767 OUT PSIZE_T ReturnSize); 1768 1769 /* wslist.cpp ****************************************************************/ 1770 _Requires_exclusive_lock_held_(WorkingSet->WorkingSetMutex) 1771 VOID 1772 NTAPI 1773 MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet); 1774 1775 #ifdef __cplusplus 1776 } // extern "C" 1777 1778 namespace ntoskrnl 1779 { 1780 using MiPfnLockGuard = const KiQueuedSpinLockGuard<LockQueuePfnLock>; 1781 } // namespace ntoskrnl 1782 1783 #endif 1784