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 BOOLEAN 1504 NTAPI 1505 MmArePagesResident( 1506 _In_ PEPROCESS Process, 1507 _In_ PVOID BaseAddress, 1508 _In_ ULONG Length); 1509 1510 NTSTATUS 1511 NTAPI 1512 MmMakePagesDirty( 1513 _In_ PEPROCESS Process, 1514 _In_ PVOID Address, 1515 _In_ ULONG Length); 1516 1517 NTSTATUS 1518 NTAPI 1519 MmFlushSegment( 1520 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1521 _In_opt_ PLARGE_INTEGER Offset, 1522 _In_ ULONG Length, 1523 _Out_opt_ PIO_STATUS_BLOCK Iosb); 1524 1525 NTSTATUS 1526 NTAPI 1527 MmMakeDataSectionResident( 1528 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1529 _In_ LONGLONG Offset, 1530 _In_ ULONG Length, 1531 _In_ PLARGE_INTEGER ValidDataLength); 1532 1533 BOOLEAN 1534 NTAPI 1535 MmPurgeSegment( 1536 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, 1537 _In_opt_ PLARGE_INTEGER Offset, 1538 _In_ ULONG Length); 1539 1540 BOOLEAN 1541 NTAPI 1542 MmCheckDirtySegment( 1543 PMM_SECTION_SEGMENT Segment, 1544 PLARGE_INTEGER Offset, 1545 BOOLEAN ForceDirty, 1546 BOOLEAN PageOut); 1547 1548 BOOLEAN 1549 NTAPI 1550 MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea, 1551 PMM_SECTION_SEGMENT Segment, 1552 PLARGE_INTEGER Offset, 1553 BOOLEAN Dirty, 1554 BOOLEAN PageOut, 1555 ULONG_PTR *InEntry); 1556 1557 _When_(OldIrql == MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL)) 1558 _When_(OldIrql == MM_NOIRQL, _Requires_lock_not_held_(MmPfnLock)) 1559 _When_(OldIrql != MM_NOIRQL, _Requires_lock_held_(MmPfnLock)) 1560 _When_(OldIrql != MM_NOIRQL, _Releases_lock_(MmPfnLock)) 1561 _When_(OldIrql != MM_NOIRQL, _IRQL_requires_(DISPATCH_LEVEL)) 1562 VOID 1563 NTAPI 1564 MmDereferenceSegmentWithLock( 1565 _In_ PMM_SECTION_SEGMENT Segment, 1566 _In_ _When_(OldIrql != MM_NOIRQL, _IRQL_restores_) KIRQL OldIrql); 1567 1568 _IRQL_requires_max_(DISPATCH_LEVEL) 1569 _Requires_lock_not_held_(MmPfnLock) 1570 FORCEINLINE 1571 VOID 1572 MmDereferenceSegment(PMM_SECTION_SEGMENT Segment) 1573 { 1574 MmDereferenceSegmentWithLock(Segment, MM_NOIRQL); 1575 } 1576 1577 NTSTATUS 1578 NTAPI 1579 MmExtendSection( 1580 _In_ PVOID Section, 1581 _Inout_ PLARGE_INTEGER NewSize); 1582 1583 /* sptab.c *******************************************************************/ 1584 1585 NTSTATUS 1586 NTAPI 1587 _MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, 1588 PLARGE_INTEGER Offset, 1589 ULONG_PTR Entry, 1590 const char *file, 1591 int line); 1592 1593 ULONG_PTR 1594 NTAPI 1595 _MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, 1596 PLARGE_INTEGER Offset, 1597 const char *file, 1598 int line); 1599 1600 #define MmSetPageEntrySectionSegment(S,O,E) _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__) 1601 1602 #define MmGetPageEntrySectionSegment(S,O) _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__) 1603 1604 /* sysldr.c ******************************************************************/ 1605 1606 CODE_SEG("INIT") 1607 VOID 1608 NTAPI 1609 MiReloadBootLoadedDrivers( 1610 IN PLOADER_PARAMETER_BLOCK LoaderBlock 1611 ); 1612 1613 CODE_SEG("INIT") 1614 BOOLEAN 1615 NTAPI 1616 MiInitializeLoadedModuleList( 1617 IN PLOADER_PARAMETER_BLOCK LoaderBlock 1618 ); 1619 1620 BOOLEAN 1621 NTAPI 1622 MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask); 1623 1624 VOID 1625 NTAPI 1626 MmMakeKernelResourceSectionWritable(VOID); 1627 1628 NTSTATUS 1629 NTAPI 1630 MmLoadSystemImage( 1631 IN PUNICODE_STRING FileName, 1632 IN PUNICODE_STRING NamePrefix OPTIONAL, 1633 IN PUNICODE_STRING LoadedName OPTIONAL, 1634 IN ULONG Flags, 1635 OUT PVOID *ModuleObject, 1636 OUT PVOID *ImageBaseAddress 1637 ); 1638 1639 NTSTATUS 1640 NTAPI 1641 MmUnloadSystemImage( 1642 IN PVOID ImageHandle 1643 ); 1644 1645 NTSTATUS 1646 NTAPI 1647 MmCheckSystemImage( 1648 IN HANDLE ImageHandle, 1649 IN BOOLEAN PurgeSection 1650 ); 1651 1652 NTSTATUS 1653 NTAPI 1654 MmCallDllInitialize( 1655 _In_ PLDR_DATA_TABLE_ENTRY LdrEntry, 1656 _In_ PLIST_ENTRY ModuleListHead); 1657 1658 VOID 1659 NTAPI 1660 MmFreeDriverInitialization( 1661 IN PLDR_DATA_TABLE_ENTRY LdrEntry); 1662 1663 /* ReactOS-only, used by psmgr.c PspLookupSystemDllEntryPoint() as well */ 1664 NTSTATUS 1665 NTAPI 1666 RtlpFindExportedRoutineByName( 1667 _In_ PVOID ImageBase, 1668 _In_ PCSTR ExportName, 1669 _Out_ PVOID* Function, 1670 _Out_opt_ PBOOLEAN IsForwarder, 1671 _In_ NTSTATUS NotFoundStatus); 1672 1673 /* Exported from NT 10.0 onward. We keep it internal. */ 1674 PVOID 1675 NTAPI 1676 RtlFindExportedRoutineByName( 1677 _In_ PVOID ImageBase, 1678 _In_ PCSTR ExportName); 1679 1680 /* procsup.c *****************************************************************/ 1681 1682 NTSTATUS 1683 NTAPI 1684 MmGrowKernelStack( 1685 IN PVOID StackPointer 1686 ); 1687 1688 1689 FORCEINLINE 1690 VOID 1691 MmLockAddressSpace(PMMSUPPORT AddressSpace) 1692 { 1693 ASSERT(!PsGetCurrentThread()->OwnsProcessWorkingSetExclusive); 1694 ASSERT(!PsGetCurrentThread()->OwnsProcessWorkingSetShared); 1695 ASSERT(!PsGetCurrentThread()->OwnsSystemWorkingSetExclusive); 1696 ASSERT(!PsGetCurrentThread()->OwnsSystemWorkingSetShared); 1697 ASSERT(!PsGetCurrentThread()->OwnsSessionWorkingSetExclusive); 1698 ASSERT(!PsGetCurrentThread()->OwnsSessionWorkingSetShared); 1699 KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 1700 } 1701 1702 FORCEINLINE 1703 VOID 1704 MmUnlockAddressSpace(PMMSUPPORT AddressSpace) 1705 { 1706 KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 1707 } 1708 1709 FORCEINLINE 1710 PEPROCESS 1711 MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace) 1712 { 1713 if (AddressSpace == MmKernelAddressSpace) return NULL; 1714 return CONTAINING_RECORD(AddressSpace, EPROCESS, Vm); 1715 } 1716 1717 FORCEINLINE 1718 PMMSUPPORT 1719 MmGetCurrentAddressSpace(VOID) 1720 { 1721 return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm; 1722 } 1723 1724 FORCEINLINE 1725 PMMSUPPORT 1726 MmGetKernelAddressSpace(VOID) 1727 { 1728 return MmKernelAddressSpace; 1729 } 1730 1731 1732 /* expool.c ******************************************************************/ 1733 1734 VOID 1735 NTAPI 1736 ExpCheckPoolAllocation( 1737 PVOID P, 1738 POOL_TYPE PoolType, 1739 ULONG Tag); 1740 1741 VOID 1742 NTAPI 1743 ExReturnPoolQuota( 1744 IN PVOID P); 1745 1746 1747 /* mmsup.c *****************************************************************/ 1748 1749 NTSTATUS 1750 NTAPI 1751 MmAdjustWorkingSetSize( 1752 IN SIZE_T WorkingSetMinimumInBytes, 1753 IN SIZE_T WorkingSetMaximumInBytes, 1754 IN ULONG SystemCache, 1755 IN BOOLEAN IncreaseOkay); 1756 1757 1758 /* session.c *****************************************************************/ 1759 1760 _IRQL_requires_max_(APC_LEVEL) 1761 NTSTATUS 1762 NTAPI 1763 MmAttachSession( 1764 _Inout_ PVOID SessionEntry, 1765 _Out_ PKAPC_STATE ApcState); 1766 1767 _IRQL_requires_max_(APC_LEVEL) 1768 VOID 1769 NTAPI 1770 MmDetachSession( 1771 _Inout_ PVOID SessionEntry, 1772 _Out_ PKAPC_STATE ApcState); 1773 1774 VOID 1775 NTAPI 1776 MmQuitNextSession( 1777 _Inout_ PVOID SessionEntry); 1778 1779 PVOID 1780 NTAPI 1781 MmGetSessionById( 1782 _In_ ULONG SessionId); 1783 1784 _IRQL_requires_max_(APC_LEVEL) 1785 VOID 1786 NTAPI 1787 MmSetSessionLocaleId( 1788 _In_ LCID LocaleId); 1789 1790 /* shutdown.c *****************************************************************/ 1791 1792 VOID 1793 MmShutdownSystem(IN ULONG Phase); 1794 1795 /* virtual.c *****************************************************************/ 1796 1797 NTSTATUS 1798 NTAPI 1799 MmCopyVirtualMemory(IN PEPROCESS SourceProcess, 1800 IN PVOID SourceAddress, 1801 IN PEPROCESS TargetProcess, 1802 OUT PVOID TargetAddress, 1803 IN SIZE_T BufferSize, 1804 IN KPROCESSOR_MODE PreviousMode, 1805 OUT PSIZE_T ReturnSize); 1806 1807 /* wslist.cpp ****************************************************************/ 1808 _Requires_exclusive_lock_held_(WorkingSet->WorkingSetMutex) 1809 VOID 1810 NTAPI 1811 MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet); 1812 1813 #ifdef __cplusplus 1814 } // extern "C" 1815 1816 namespace ntoskrnl 1817 { 1818 using MiPfnLockGuard = const KiQueuedSpinLockGuard<LockQueuePfnLock>; 1819 } // namespace ntoskrnl 1820 1821 #endif 1822