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