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