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 *****************************************************************/ 870 871 CODE_SEG("INIT") 872 VOID 873 NTAPI 874 MmInitializeMemoryConsumer( 875 ULONG Consumer, 876 NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed) 877 ); 878 879 CODE_SEG("INIT") 880 VOID 881 NTAPI 882 MmInitializeBalancer( 883 ULONG NrAvailablePages, 884 ULONG NrSystemPages 885 ); 886 887 NTSTATUS 888 NTAPI 889 MmReleasePageMemoryConsumer( 890 ULONG Consumer, 891 PFN_NUMBER Page 892 ); 893 894 NTSTATUS 895 NTAPI 896 MmRequestPageMemoryConsumer( 897 ULONG Consumer, 898 BOOLEAN MyWait, 899 PPFN_NUMBER AllocatedPage 900 ); 901 902 CODE_SEG("INIT") 903 VOID 904 NTAPI 905 MiInitBalancerThread(VOID); 906 907 VOID 908 NTAPI 909 MmRebalanceMemoryConsumers(VOID); 910 911 /* rmap.c **************************************************************/ 912 #define RMAP_SEGMENT_MASK ~((ULONG_PTR)0xff) 913 #define RMAP_IS_SEGMENT(x) (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK) 914 915 VOID 916 NTAPI 917 MmSetRmapListHeadPage( 918 PFN_NUMBER Page, 919 struct _MM_RMAP_ENTRY* ListHead 920 ); 921 922 struct _MM_RMAP_ENTRY* 923 NTAPI 924 MmGetRmapListHeadPage(PFN_NUMBER Page); 925 926 VOID 927 NTAPI 928 MmInsertRmap( 929 PFN_NUMBER Page, 930 struct _EPROCESS *Process, 931 PVOID Address 932 ); 933 934 VOID 935 NTAPI 936 MmDeleteAllRmaps( 937 PFN_NUMBER Page, 938 PVOID Context, 939 VOID (*DeleteMapping)(PVOID Context, struct _EPROCESS *Process, PVOID Address) 940 ); 941 942 VOID 943 NTAPI 944 MmDeleteRmap( 945 PFN_NUMBER Page, 946 struct _EPROCESS *Process, 947 PVOID Address 948 ); 949 950 CODE_SEG("INIT") 951 VOID 952 NTAPI 953 MmInitializeRmapList(VOID); 954 955 NTSTATUS 956 NTAPI 957 MmPageOutPhysicalAddress(PFN_NUMBER Page); 958 959 PMM_SECTION_SEGMENT 960 NTAPI 961 MmGetSectionAssociation(PFN_NUMBER Page, 962 PLARGE_INTEGER Offset); 963 964 /* freelist.c **********************************************************/ 965 _IRQL_raises_(DISPATCH_LEVEL) 966 _IRQL_requires_max_(DISPATCH_LEVEL) 967 _Requires_lock_not_held_(MmPfnLock) 968 _Acquires_lock_(MmPfnLock) 969 _IRQL_saves_ 970 FORCEINLINE 971 KIRQL 972 MiAcquirePfnLock(VOID) 973 { 974 return KeAcquireQueuedSpinLock(LockQueuePfnLock); 975 } 976 977 _Requires_lock_held_(MmPfnLock) 978 _Releases_lock_(MmPfnLock) 979 _IRQL_requires_(DISPATCH_LEVEL) 980 FORCEINLINE 981 VOID 982 MiReleasePfnLock( 983 _In_ _IRQL_restores_ KIRQL OldIrql) 984 { 985 KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); 986 } 987 988 _IRQL_requires_min_(DISPATCH_LEVEL) 989 _Requires_lock_not_held_(MmPfnLock) 990 _Acquires_lock_(MmPfnLock) 991 FORCEINLINE 992 VOID 993 MiAcquirePfnLockAtDpcLevel(VOID) 994 { 995 PKSPIN_LOCK_QUEUE LockQueue; 996 997 ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); 998 LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock]; 999 KeAcquireQueuedSpinLockAtDpcLevel(LockQueue); 1000 } 1001 1002 _Requires_lock_held_(MmPfnLock) 1003 _Releases_lock_(MmPfnLock) 1004 _IRQL_requires_min_(DISPATCH_LEVEL) 1005 FORCEINLINE 1006 VOID 1007 MiReleasePfnLockFromDpcLevel(VOID) 1008 { 1009 PKSPIN_LOCK_QUEUE LockQueue; 1010 1011 LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock]; 1012 KeReleaseQueuedSpinLockFromDpcLevel(LockQueue); 1013 ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); 1014 } 1015 1016 #define MI_ASSERT_PFN_LOCK_HELD() NT_ASSERT((KeGetCurrentIrql() >= DISPATCH_LEVEL) && (MmPfnLock != 0)) 1017 1018 FORCEINLINE 1019 PMMPFN 1020 MiGetPfnEntry(IN PFN_NUMBER Pfn) 1021 { 1022 PMMPFN Page; 1023 extern RTL_BITMAP MiPfnBitMap; 1024 1025 /* Make sure the PFN number is valid */ 1026 if (Pfn > MmHighestPhysicalPage) return NULL; 1027 1028 /* Make sure this page actually has a PFN entry */ 1029 if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, (ULONG)Pfn))) return NULL; 1030 1031 /* Get the entry */ 1032 Page = &MmPfnDatabase[Pfn]; 1033 1034 /* Return it */ 1035 return Page; 1036 }; 1037 1038 FORCEINLINE 1039 PFN_NUMBER 1040 MiGetPfnEntryIndex(IN PMMPFN Pfn1) 1041 { 1042 // 1043 // This will return the Page Frame Number (PFN) from the MMPFN 1044 // 1045 return Pfn1 - MmPfnDatabase; 1046 } 1047 1048 PFN_NUMBER 1049 NTAPI 1050 MmGetLRUNextUserPage(PFN_NUMBER PreviousPage, BOOLEAN MoveToLast); 1051 1052 PFN_NUMBER 1053 NTAPI 1054 MmGetLRUFirstUserPage(VOID); 1055 1056 VOID 1057 NTAPI 1058 MmDumpArmPfnDatabase( 1059 IN BOOLEAN StatusOnly 1060 ); 1061 1062 VOID 1063 NTAPI 1064 MmZeroPageThread( 1065 VOID 1066 ); 1067 1068 /* hypermap.c *****************************************************************/ 1069 PVOID 1070 NTAPI 1071 MiMapPageInHyperSpace(IN PEPROCESS Process, 1072 IN PFN_NUMBER Page, 1073 IN PKIRQL OldIrql); 1074 1075 VOID 1076 NTAPI 1077 MiUnmapPageInHyperSpace(IN PEPROCESS Process, 1078 IN PVOID Address, 1079 IN KIRQL OldIrql); 1080 1081 PVOID 1082 NTAPI 1083 MiMapPagesInZeroSpace(IN PMMPFN Pfn1, 1084 IN PFN_NUMBER NumberOfPages); 1085 1086 VOID 1087 NTAPI 1088 MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, 1089 IN PFN_NUMBER NumberOfPages); 1090 1091 /* i386/page.c *********************************************************/ 1092 1093 NTSTATUS 1094 NTAPI 1095 MmCreateVirtualMapping( 1096 struct _EPROCESS* Process, 1097 PVOID Address, 1098 ULONG flProtect, 1099 PFN_NUMBER Page 1100 ); 1101 1102 NTSTATUS 1103 NTAPI 1104 MmCreateVirtualMappingUnsafe( 1105 struct _EPROCESS* Process, 1106 PVOID Address, 1107 ULONG flProtect, 1108 PFN_NUMBER Page 1109 ); 1110 1111 ULONG 1112 NTAPI 1113 MmGetPageProtect( 1114 struct _EPROCESS* Process, 1115 PVOID Address); 1116 1117 VOID 1118 NTAPI 1119 MmSetPageProtect( 1120 struct _EPROCESS* Process, 1121 PVOID Address, 1122 ULONG flProtect 1123 ); 1124 1125 BOOLEAN 1126 NTAPI 1127 MmIsPagePresent( 1128 struct _EPROCESS* Process, 1129 PVOID Address 1130 ); 1131 1132 BOOLEAN 1133 NTAPI 1134 MmIsDisabledPage( 1135 struct _EPROCESS* Process, 1136 PVOID Address 1137 ); 1138 1139 CODE_SEG("INIT") 1140 VOID 1141 NTAPI 1142 MmInitGlobalKernelPageDirectory(VOID); 1143 1144 VOID 1145 NTAPI 1146 MmDeletePageFileMapping( 1147 struct _EPROCESS *Process, 1148 PVOID Address, 1149 SWAPENTRY* SwapEntry 1150 ); 1151 1152 NTSTATUS 1153 NTAPI 1154 MmCreatePageFileMapping( 1155 struct _EPROCESS *Process, 1156 PVOID Address, 1157 SWAPENTRY SwapEntry 1158 ); 1159 1160 VOID 1161 NTAPI 1162 MmGetPageFileMapping( 1163 PEPROCESS Process, 1164 PVOID Address, 1165 SWAPENTRY *SwapEntry); 1166 1167 BOOLEAN 1168 NTAPI 1169 MmIsPageSwapEntry( 1170 struct _EPROCESS *Process, 1171 PVOID Address 1172 ); 1173 1174 PFN_NUMBER 1175 NTAPI 1176 MmAllocPage( 1177 ULONG Consumer 1178 ); 1179 1180 VOID 1181 NTAPI 1182 MmDereferencePage(PFN_NUMBER Page); 1183 1184 VOID 1185 NTAPI 1186 MmReferencePage(PFN_NUMBER Page); 1187 1188 ULONG 1189 NTAPI 1190 MmGetReferenceCountPage(PFN_NUMBER Page); 1191 1192 BOOLEAN 1193 NTAPI 1194 MmIsPageInUse(PFN_NUMBER Page); 1195 1196 VOID 1197 NTAPI 1198 MmSetSavedSwapEntryPage( 1199 PFN_NUMBER Page, 1200 SWAPENTRY SavedSwapEntry); 1201 1202 SWAPENTRY 1203 NTAPI 1204 MmGetSavedSwapEntryPage(PFN_NUMBER Page); 1205 1206 VOID 1207 NTAPI 1208 MmSetCleanPage( 1209 struct _EPROCESS *Process, 1210 PVOID Address 1211 ); 1212 1213 VOID 1214 NTAPI 1215 MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN Bit); 1216 #define MmSetCleanPage(__P, __A) MmSetDirtyBit(__P, __A, FALSE) 1217 #define MmSetDirtyPage(__P, __A) MmSetDirtyBit(__P, __A, TRUE) 1218 1219 VOID 1220 NTAPI 1221 MmDeletePageTable( 1222 struct _EPROCESS *Process, 1223 PVOID Address 1224 ); 1225 1226 PFN_NUMBER 1227 NTAPI 1228 MmGetPfnForProcess( 1229 struct _EPROCESS *Process, 1230 PVOID Address 1231 ); 1232 1233 BOOLEAN 1234 NTAPI 1235 MmCreateProcessAddressSpace( 1236 IN ULONG MinWs, 1237 IN PEPROCESS Dest, 1238 IN PULONG_PTR DirectoryTableBase 1239 ); 1240 1241 CODE_SEG("INIT") 1242 NTSTATUS 1243 NTAPI 1244 MmInitializeHandBuiltProcess( 1245 IN PEPROCESS Process, 1246 IN PULONG_PTR DirectoryTableBase 1247 ); 1248 1249 CODE_SEG("INIT") 1250 NTSTATUS 1251 NTAPI 1252 MmInitializeHandBuiltProcess2( 1253 IN PEPROCESS Process 1254 ); 1255 1256 NTSTATUS 1257 NTAPI 1258 MmSetExecuteOptions(IN ULONG ExecuteOptions); 1259 1260 NTSTATUS 1261 NTAPI 1262 MmGetExecuteOptions(IN PULONG ExecuteOptions); 1263 1264 VOID 1265 NTAPI 1266 MmDeleteVirtualMapping( 1267 struct _EPROCESS *Process, 1268 PVOID Address, 1269 BOOLEAN* WasDirty, 1270 PPFN_NUMBER Page 1271 ); 1272 1273 /* arch/procsup.c ************************************************************/ 1274 1275 BOOLEAN 1276 MiArchCreateProcessAddressSpace( 1277 _In_ PEPROCESS Process, 1278 _In_ PULONG_PTR DirectoryTableBase); 1279 1280 /* wset.c ********************************************************************/ 1281 1282 NTSTATUS 1283 MmTrimUserMemory( 1284 ULONG Target, 1285 ULONG Priority, 1286 PULONG NrFreedPages 1287 ); 1288 1289 /* region.c ************************************************************/ 1290 1291 NTSTATUS 1292 NTAPI 1293 MmAlterRegion( 1294 PMMSUPPORT AddressSpace, 1295 PVOID BaseAddress, 1296 PLIST_ENTRY RegionListHead, 1297 PVOID StartAddress, 1298 SIZE_T Length, 1299 ULONG NewType, 1300 ULONG NewProtect, 1301 PMM_ALTER_REGION_FUNC AlterFunc 1302 ); 1303 1304 VOID 1305 NTAPI 1306 MmInitializeRegion( 1307 PLIST_ENTRY RegionListHead, 1308 SIZE_T Length, 1309 ULONG Type, 1310 ULONG Protect 1311 ); 1312 1313 PMM_REGION 1314 NTAPI 1315 MmFindRegion( 1316 PVOID BaseAddress, 1317 PLIST_ENTRY RegionListHead, 1318 PVOID Address, 1319 PVOID* RegionBaseAddress 1320 ); 1321 1322 /* section.c *****************************************************************/ 1323 1324 #define PFN_FROM_SSE(E) ((PFN_NUMBER)((E) >> PAGE_SHIFT)) 1325 #define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001) 1326 #define MM_IS_WAIT_PTE(E) \ 1327 (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY) 1328 #define MAKE_PFN_SSE(P) ((ULONG_PTR)((P) << PAGE_SHIFT)) 1329 #define SWAPENTRY_FROM_SSE(E) ((E) >> 1) 1330 #define MAKE_SWAP_SSE(S) (((ULONG_PTR)(S) << 1) | 0x1) 1331 #define DIRTY_SSE(E) ((E) | 2) 1332 #define CLEAN_SSE(E) ((E) & ~2) 1333 #define IS_DIRTY_SSE(E) ((E) & 2) 1334 #define WRITE_SSE(E) ((E) | 4) 1335 #define IS_WRITE_SSE(E) ((E) & 4) 1336 #ifdef _WIN64 1337 #define PAGE_FROM_SSE(E) ((E) & 0xFFFFFFF000ULL) 1338 #else 1339 #define PAGE_FROM_SSE(E) ((E) & 0xFFFFF000) 1340 #endif 1341 #define SHARE_COUNT_FROM_SSE(E) (((E) & 0x00000FFC) >> 3) 1342 #define MAX_SHARE_COUNT 0x1FF 1343 #define MAKE_SSE(P, C) ((ULONG_PTR)((P) | ((C) << 3))) 1344 #define BUMPREF_SSE(E) (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) + 1) << 3) | ((E) & 0x7)) 1345 #define DECREF_SSE(E) (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) - 1) << 3) | ((E) & 0x7)) 1346 1347 VOID 1348 NTAPI 1349 _MmLockSectionSegment(PMM_SECTION_SEGMENT Segment, 1350 const char *file, 1351 int line); 1352 1353 #define MmLockSectionSegment(x) _MmLockSectionSegment(x,__FILE__,__LINE__) 1354 1355 VOID 1356 NTAPI 1357 _MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment, 1358 const char *file, 1359 int line); 1360 1361 #define MmUnlockSectionSegment(x) _MmUnlockSectionSegment(x,__FILE__,__LINE__) 1362 1363 VOID 1364 NTAPI 1365 MmGetImageInformation( 1366 OUT PSECTION_IMAGE_INFORMATION ImageInformation 1367 ); 1368 1369 PFILE_OBJECT 1370 NTAPI 1371 MmGetFileObjectForSection( 1372 IN PVOID Section 1373 ); 1374 NTSTATUS 1375 NTAPI 1376 MmGetFileNameForAddress( 1377 IN PVOID Address, 1378 OUT PUNICODE_STRING ModuleName 1379 ); 1380 1381 NTSTATUS 1382 NTAPI 1383 MmGetFileNameForSection( 1384 IN PVOID Section, 1385 OUT POBJECT_NAME_INFORMATION *ModuleName 1386 ); 1387 1388 NTSTATUS 1389 NTAPI 1390 MmQuerySectionView( 1391 PMEMORY_AREA MemoryArea, 1392 PVOID Address, 1393 PMEMORY_BASIC_INFORMATION Info, 1394 PSIZE_T ResultLength 1395 ); 1396 1397 NTSTATUS 1398 NTAPI 1399 MmProtectSectionView( 1400 PMMSUPPORT AddressSpace, 1401 PMEMORY_AREA MemoryArea, 1402 PVOID BaseAddress, 1403 SIZE_T Length, 1404 ULONG Protect, 1405 PULONG OldProtect 1406 ); 1407 1408 CODE_SEG("INIT") 1409 NTSTATUS 1410 NTAPI 1411 MmInitSectionImplementation(VOID); 1412 1413 NTSTATUS 1414 NTAPI 1415 MmNotPresentFaultSectionView( 1416 PMMSUPPORT AddressSpace, 1417 MEMORY_AREA* MemoryArea, 1418 PVOID Address, 1419 BOOLEAN Locked 1420 ); 1421 1422 NTSTATUS 1423 NTAPI 1424 MmPageOutSectionView( 1425 PMMSUPPORT AddressSpace, 1426 PMEMORY_AREA MemoryArea, 1427 PVOID Address, 1428 ULONG_PTR Entry 1429 ); 1430 1431 CODE_SEG("INIT") 1432 NTSTATUS 1433 NTAPI 1434 MmCreatePhysicalMemorySection(VOID); 1435 1436 NTSTATUS 1437 NTAPI 1438 MmAccessFaultSectionView( 1439 PMMSUPPORT AddressSpace, 1440 MEMORY_AREA* MemoryArea, 1441 PVOID Address, 1442 BOOLEAN Locked 1443 ); 1444 1445 VOID 1446 NTAPI 1447 MmFreeSectionSegments(PFILE_OBJECT FileObject); 1448 1449 /* Exported from NT 6.2 Onward. We keep it internal. */ 1450 NTSTATUS 1451 NTAPI 1452 MmMapViewInSystemSpaceEx ( 1453 _In_ PVOID Section, 1454 _Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase, 1455 _Inout_ PSIZE_T ViewSize, 1456 _Inout_ PLARGE_INTEGER SectionOffset, 1457 _In_ ULONG_PTR Flags 1458 ); 1459 1460 BOOLEAN 1461 NTAPI 1462 MmArePagesResident( 1463 _In_ PEPROCESS Process, 1464 _In_ PVOID BaseAddress, 1465 _In_ ULONG Length); 1466 1467 NTSTATUS 1468 NTAPI 1469 MmMakePagesDirty( 1470 _In_ PEPROCESS Process, 1471 _In_ PVOID Address, 1472 _In_ ULONG Length); 1473 1474 NTSTATUS 1475 NTAPI 1476 MmFlushSegment( 1477 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1478 _In_opt_ PLARGE_INTEGER Offset, 1479 _In_ ULONG Length, 1480 _Out_opt_ PIO_STATUS_BLOCK Iosb); 1481 1482 NTSTATUS 1483 NTAPI 1484 MmMakeDataSectionResident( 1485 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1486 _In_ LONGLONG Offset, 1487 _In_ ULONG Length, 1488 _In_ PLARGE_INTEGER ValidDataLength); 1489 1490 BOOLEAN 1491 NTAPI 1492 MmPurgeSegment( 1493 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1494 _In_opt_ PLARGE_INTEGER Offset, 1495 _In_ ULONG Length); 1496 1497 BOOLEAN 1498 NTAPI 1499 MmCheckDirtySegment( 1500 PMM_SECTION_SEGMENT Segment, 1501 PLARGE_INTEGER Offset, 1502 BOOLEAN ForceDirty, 1503 BOOLEAN PageOut); 1504 1505 BOOLEAN 1506 NTAPI 1507 MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea, 1508 PMM_SECTION_SEGMENT Segment, 1509 PLARGE_INTEGER Offset, 1510 BOOLEAN Dirty, 1511 BOOLEAN PageOut, 1512 ULONG_PTR *InEntry); 1513 1514 _When_(OldIrql == MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL)) 1515 _When_(OldIrql == MM_NOIRQL, _Requires_lock_not_held_(MmPfnLock)) 1516 _When_(OldIrql != MM_NOIRQL, _Requires_lock_held_(MmPfnLock)) 1517 _When_(OldIrql != MM_NOIRQL, _Releases_lock_(MmPfnLock)) 1518 _When_(OldIrql != MM_NOIRQL, _IRQL_requires_(DISPATCH_LEVEL)) 1519 VOID 1520 NTAPI 1521 MmDereferenceSegmentWithLock( 1522 _In_ PMM_SECTION_SEGMENT Segment, 1523 _In_ _When_(OldIrql != MM_NOIRQL, _IRQL_restores_) KIRQL OldIrql); 1524 1525 _IRQL_requires_max_(DISPATCH_LEVEL) 1526 _Requires_lock_not_held_(MmPfnLock) 1527 FORCEINLINE 1528 VOID 1529 MmDereferenceSegment(PMM_SECTION_SEGMENT Segment) 1530 { 1531 MmDereferenceSegmentWithLock(Segment, MM_NOIRQL); 1532 } 1533 1534 NTSTATUS 1535 NTAPI 1536 MmExtendSection( 1537 _In_ PVOID Section, 1538 _Inout_ PLARGE_INTEGER NewSize); 1539 1540 /* sptab.c *******************************************************************/ 1541 1542 NTSTATUS 1543 NTAPI 1544 _MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, 1545 PLARGE_INTEGER Offset, 1546 ULONG_PTR Entry, 1547 const char *file, 1548 int line); 1549 1550 ULONG_PTR 1551 NTAPI 1552 _MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, 1553 PLARGE_INTEGER Offset, 1554 const char *file, 1555 int line); 1556 1557 #define MmSetPageEntrySectionSegment(S,O,E) _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__) 1558 1559 #define MmGetPageEntrySectionSegment(S,O) _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__) 1560 1561 /* sysldr.c ******************************************************************/ 1562 1563 CODE_SEG("INIT") 1564 VOID 1565 NTAPI 1566 MiReloadBootLoadedDrivers( 1567 IN PLOADER_PARAMETER_BLOCK LoaderBlock 1568 ); 1569 1570 CODE_SEG("INIT") 1571 BOOLEAN 1572 NTAPI 1573 MiInitializeLoadedModuleList( 1574 IN PLOADER_PARAMETER_BLOCK LoaderBlock 1575 ); 1576 1577 BOOLEAN 1578 NTAPI 1579 MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask); 1580 1581 VOID 1582 NTAPI 1583 MmMakeKernelResourceSectionWritable(VOID); 1584 1585 NTSTATUS 1586 NTAPI 1587 MmLoadSystemImage( 1588 IN PUNICODE_STRING FileName, 1589 IN PUNICODE_STRING NamePrefix OPTIONAL, 1590 IN PUNICODE_STRING LoadedName OPTIONAL, 1591 IN ULONG Flags, 1592 OUT PVOID *ModuleObject, 1593 OUT PVOID *ImageBaseAddress 1594 ); 1595 1596 NTSTATUS 1597 NTAPI 1598 MmUnloadSystemImage( 1599 IN PVOID ImageHandle 1600 ); 1601 1602 NTSTATUS 1603 NTAPI 1604 MmCheckSystemImage( 1605 IN HANDLE ImageHandle, 1606 IN BOOLEAN PurgeSection 1607 ); 1608 1609 NTSTATUS 1610 NTAPI 1611 MmCallDllInitialize( 1612 IN PLDR_DATA_TABLE_ENTRY LdrEntry, 1613 IN PLIST_ENTRY ListHead 1614 ); 1615 1616 VOID 1617 NTAPI 1618 MmFreeDriverInitialization( 1619 IN PLDR_DATA_TABLE_ENTRY LdrEntry); 1620 1621 /* procsup.c *****************************************************************/ 1622 1623 NTSTATUS 1624 NTAPI 1625 MmGrowKernelStack( 1626 IN PVOID StackPointer 1627 ); 1628 1629 1630 FORCEINLINE 1631 VOID 1632 MmLockAddressSpace(PMMSUPPORT AddressSpace) 1633 { 1634 KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 1635 } 1636 1637 FORCEINLINE 1638 VOID 1639 MmUnlockAddressSpace(PMMSUPPORT AddressSpace) 1640 { 1641 KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 1642 } 1643 1644 FORCEINLINE 1645 PEPROCESS 1646 MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace) 1647 { 1648 if (AddressSpace == MmKernelAddressSpace) return NULL; 1649 return CONTAINING_RECORD(AddressSpace, EPROCESS, Vm); 1650 } 1651 1652 FORCEINLINE 1653 PMMSUPPORT 1654 MmGetCurrentAddressSpace(VOID) 1655 { 1656 return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm; 1657 } 1658 1659 FORCEINLINE 1660 PMMSUPPORT 1661 MmGetKernelAddressSpace(VOID) 1662 { 1663 return MmKernelAddressSpace; 1664 } 1665 1666 1667 /* expool.c ******************************************************************/ 1668 1669 VOID 1670 NTAPI 1671 ExpCheckPoolAllocation( 1672 PVOID P, 1673 POOL_TYPE PoolType, 1674 ULONG Tag); 1675 1676 VOID 1677 NTAPI 1678 ExReturnPoolQuota( 1679 IN PVOID P); 1680 1681 1682 /* mmsup.c *****************************************************************/ 1683 1684 NTSTATUS 1685 NTAPI 1686 MmAdjustWorkingSetSize( 1687 IN SIZE_T WorkingSetMinimumInBytes, 1688 IN SIZE_T WorkingSetMaximumInBytes, 1689 IN ULONG SystemCache, 1690 IN BOOLEAN IncreaseOkay); 1691 1692 1693 /* session.c *****************************************************************/ 1694 1695 _IRQL_requires_max_(APC_LEVEL) 1696 NTSTATUS 1697 NTAPI 1698 MmAttachSession( 1699 _Inout_ PVOID SessionEntry, 1700 _Out_ PKAPC_STATE ApcState); 1701 1702 _IRQL_requires_max_(APC_LEVEL) 1703 VOID 1704 NTAPI 1705 MmDetachSession( 1706 _Inout_ PVOID SessionEntry, 1707 _Out_ PKAPC_STATE ApcState); 1708 1709 VOID 1710 NTAPI 1711 MmQuitNextSession( 1712 _Inout_ PVOID SessionEntry); 1713 1714 PVOID 1715 NTAPI 1716 MmGetSessionById( 1717 _In_ ULONG SessionId); 1718 1719 _IRQL_requires_max_(APC_LEVEL) 1720 VOID 1721 NTAPI 1722 MmSetSessionLocaleId( 1723 _In_ LCID LocaleId); 1724 1725 /* shutdown.c *****************************************************************/ 1726 1727 VOID 1728 MmShutdownSystem(IN ULONG Phase); 1729 1730 /* virtual.c *****************************************************************/ 1731 1732 NTSTATUS 1733 NTAPI 1734 MmCopyVirtualMemory(IN PEPROCESS SourceProcess, 1735 IN PVOID SourceAddress, 1736 IN PEPROCESS TargetProcess, 1737 OUT PVOID TargetAddress, 1738 IN SIZE_T BufferSize, 1739 IN KPROCESSOR_MODE PreviousMode, 1740 OUT PSIZE_T ReturnSize); 1741 1742 /* wslist.cpp ****************************************************************/ 1743 _Requires_exclusive_lock_held_(WorkingSet->WorkingSetMutex) 1744 VOID 1745 NTAPI 1746 MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet); 1747 1748 #ifdef __cplusplus 1749 } // extern "C" 1750 1751 namespace ntoskrnl 1752 { 1753 using MiPfnLockGuard = const KiQueuedSpinLockGuard<LockQueuePfnLock>; 1754 } // namespace ntoskrnl 1755 1756 #endif 1757