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