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 INIT_FUNCTION 563 VOID 564 NTAPI 565 MiInitializeNonPagedPool(VOID); 566 567 PVOID 568 NTAPI 569 MiAllocatePoolPages( 570 IN POOL_TYPE PoolType, 571 IN SIZE_T SizeInBytes 572 ); 573 574 POOL_TYPE 575 NTAPI 576 MmDeterminePoolType( 577 IN PVOID VirtualAddress 578 ); 579 580 ULONG 581 NTAPI 582 MiFreePoolPages( 583 IN PVOID StartingAddress 584 ); 585 586 /* pool.c *******************************************************************/ 587 588 BOOLEAN 589 NTAPI 590 MiRaisePoolQuota( 591 IN POOL_TYPE PoolType, 592 IN ULONG CurrentMaxQuota, 593 OUT PULONG NewMaxQuota 594 ); 595 596 /* mdl.c *********************************************************************/ 597 598 VOID 599 NTAPI 600 MmBuildMdlFromPages( 601 PMDL Mdl, 602 PPFN_NUMBER Pages 603 ); 604 605 /* mminit.c ******************************************************************/ 606 607 VOID 608 NTAPI 609 MmInit1( 610 VOID 611 ); 612 613 INIT_FUNCTION 614 BOOLEAN 615 NTAPI 616 MmInitSystem(IN ULONG Phase, 617 IN PLOADER_PARAMETER_BLOCK LoaderBlock); 618 619 620 /* pagefile.c ****************************************************************/ 621 622 SWAPENTRY 623 NTAPI 624 MmAllocSwapPage(VOID); 625 626 VOID 627 NTAPI 628 MmFreeSwapPage(SWAPENTRY Entry); 629 630 INIT_FUNCTION 631 VOID 632 NTAPI 633 MmInitPagingFile(VOID); 634 635 BOOLEAN 636 NTAPI 637 MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject); 638 639 NTSTATUS 640 NTAPI 641 MmReadFromSwapPage( 642 SWAPENTRY SwapEntry, 643 PFN_NUMBER Page 644 ); 645 646 NTSTATUS 647 NTAPI 648 MmWriteToSwapPage( 649 SWAPENTRY SwapEntry, 650 PFN_NUMBER Page 651 ); 652 653 VOID 654 NTAPI 655 MmShowOutOfSpaceMessagePagingFile(VOID); 656 657 NTSTATUS 658 NTAPI 659 MiReadPageFile( 660 _In_ PFN_NUMBER Page, 661 _In_ ULONG PageFileIndex, 662 _In_ ULONG_PTR PageFileOffset); 663 664 /* process.c ****************************************************************/ 665 666 NTSTATUS 667 NTAPI 668 MmInitializeProcessAddressSpace( 669 IN PEPROCESS Process, 670 IN PEPROCESS Clone OPTIONAL, 671 IN PVOID Section OPTIONAL, 672 IN OUT PULONG Flags, 673 IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL 674 ); 675 676 NTSTATUS 677 NTAPI 678 MmCreatePeb( 679 IN PEPROCESS Process, 680 IN PINITIAL_PEB InitialPeb, 681 OUT PPEB *BasePeb 682 ); 683 684 NTSTATUS 685 NTAPI 686 MmCreateTeb( 687 IN PEPROCESS Process, 688 IN PCLIENT_ID ClientId, 689 IN PINITIAL_TEB InitialTeb, 690 OUT PTEB* BaseTeb 691 ); 692 693 VOID 694 NTAPI 695 MmDeleteTeb( 696 struct _EPROCESS *Process, 697 PTEB Teb 698 ); 699 700 VOID 701 NTAPI 702 MmCleanProcessAddressSpace(IN PEPROCESS Process); 703 704 NTSTATUS 705 NTAPI 706 MmDeleteProcessAddressSpace(IN PEPROCESS Process); 707 708 ULONG 709 NTAPI 710 MmGetSessionLocaleId(VOID); 711 712 NTSTATUS 713 NTAPI 714 MmSetMemoryPriorityProcess( 715 IN PEPROCESS Process, 716 IN UCHAR MemoryPriority 717 ); 718 719 /* i386/pfault.c *************************************************************/ 720 721 NTSTATUS 722 NTAPI 723 MmPageFault( 724 ULONG Cs, 725 PULONG Eip, 726 PULONG Eax, 727 ULONG Cr2, 728 ULONG ErrorCode 729 ); 730 731 /* special.c *****************************************************************/ 732 733 VOID 734 NTAPI 735 MiInitializeSpecialPool(VOID); 736 737 BOOLEAN 738 NTAPI 739 MmUseSpecialPool( 740 IN SIZE_T NumberOfBytes, 741 IN ULONG Tag); 742 743 BOOLEAN 744 NTAPI 745 MmIsSpecialPoolAddress( 746 IN PVOID P); 747 748 BOOLEAN 749 NTAPI 750 MmIsSpecialPoolAddressFree( 751 IN PVOID P); 752 753 PVOID 754 NTAPI 755 MmAllocateSpecialPool( 756 IN SIZE_T NumberOfBytes, 757 IN ULONG Tag, 758 IN POOL_TYPE PoolType, 759 IN ULONG SpecialType); 760 761 VOID 762 NTAPI 763 MmFreeSpecialPool( 764 IN PVOID P); 765 766 /* mm.c **********************************************************************/ 767 768 NTSTATUS 769 NTAPI 770 MmAccessFault( 771 IN ULONG FaultCode, 772 IN PVOID Address, 773 IN KPROCESSOR_MODE Mode, 774 IN PVOID TrapInformation 775 ); 776 777 /* kmap.c ********************************************************************/ 778 779 NTSTATUS 780 NTAPI 781 MiCopyFromUserPage( 782 PFN_NUMBER DestPage, 783 const VOID *SrcAddress 784 ); 785 786 /* process.c *****************************************************************/ 787 788 PVOID 789 NTAPI 790 MmCreateKernelStack(BOOLEAN GuiStack, UCHAR Node); 791 792 VOID 793 NTAPI 794 MmDeleteKernelStack(PVOID Stack, 795 BOOLEAN GuiStack); 796 797 /* balance.c *****************************************************************/ 798 799 INIT_FUNCTION 800 VOID 801 NTAPI 802 MmInitializeMemoryConsumer( 803 ULONG Consumer, 804 NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed) 805 ); 806 807 INIT_FUNCTION 808 VOID 809 NTAPI 810 MmInitializeBalancer( 811 ULONG NrAvailablePages, 812 ULONG NrSystemPages 813 ); 814 815 NTSTATUS 816 NTAPI 817 MmReleasePageMemoryConsumer( 818 ULONG Consumer, 819 PFN_NUMBER Page 820 ); 821 822 NTSTATUS 823 NTAPI 824 MmRequestPageMemoryConsumer( 825 ULONG Consumer, 826 BOOLEAN MyWait, 827 PPFN_NUMBER AllocatedPage 828 ); 829 830 INIT_FUNCTION 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 INIT_FUNCTION 877 VOID 878 NTAPI 879 MmInitializeRmapList(VOID); 880 881 VOID 882 NTAPI 883 MmSetCleanAllRmaps(PFN_NUMBER Page); 884 885 VOID 886 NTAPI 887 MmSetDirtyAllRmaps(PFN_NUMBER Page); 888 889 BOOLEAN 890 NTAPI 891 MmIsDirtyPageRmap(PFN_NUMBER Page); 892 893 NTSTATUS 894 NTAPI 895 MmPageOutPhysicalAddress(PFN_NUMBER Page); 896 897 /* freelist.c **********************************************************/ 898 899 FORCEINLINE 900 KIRQL 901 MiAcquirePfnLock(VOID) 902 { 903 return KeAcquireQueuedSpinLock(LockQueuePfnLock); 904 } 905 906 FORCEINLINE 907 VOID 908 MiReleasePfnLock( 909 _In_ KIRQL OldIrql) 910 { 911 KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); 912 } 913 914 FORCEINLINE 915 VOID 916 MiAcquirePfnLockAtDpcLevel(VOID) 917 { 918 PKSPIN_LOCK_QUEUE LockQueue; 919 920 ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); 921 LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock]; 922 KeAcquireQueuedSpinLockAtDpcLevel(LockQueue); 923 } 924 925 FORCEINLINE 926 VOID 927 MiReleasePfnLockFromDpcLevel(VOID) 928 { 929 PKSPIN_LOCK_QUEUE LockQueue; 930 931 LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock]; 932 KeReleaseQueuedSpinLockFromDpcLevel(LockQueue); 933 ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); 934 } 935 936 #define MI_ASSERT_PFN_LOCK_HELD() ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL) 937 938 FORCEINLINE 939 PMMPFN 940 MiGetPfnEntry(IN PFN_NUMBER Pfn) 941 { 942 PMMPFN Page; 943 extern RTL_BITMAP MiPfnBitMap; 944 945 /* Make sure the PFN number is valid */ 946 if (Pfn > MmHighestPhysicalPage) return NULL; 947 948 /* Make sure this page actually has a PFN entry */ 949 if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, (ULONG)Pfn))) return NULL; 950 951 /* Get the entry */ 952 Page = &MmPfnDatabase[Pfn]; 953 954 /* Return it */ 955 return Page; 956 }; 957 958 FORCEINLINE 959 PFN_NUMBER 960 MiGetPfnEntryIndex(IN PMMPFN Pfn1) 961 { 962 // 963 // This will return the Page Frame Number (PFN) from the MMPFN 964 // 965 return Pfn1 - MmPfnDatabase; 966 } 967 968 PFN_NUMBER 969 NTAPI 970 MmGetLRUNextUserPage(PFN_NUMBER PreviousPage); 971 972 PFN_NUMBER 973 NTAPI 974 MmGetLRUFirstUserPage(VOID); 975 976 VOID 977 NTAPI 978 MmInsertLRULastUserPage(PFN_NUMBER Page); 979 980 VOID 981 NTAPI 982 MmRemoveLRUUserPage(PFN_NUMBER Page); 983 984 VOID 985 NTAPI 986 MmDumpArmPfnDatabase( 987 IN BOOLEAN StatusOnly 988 ); 989 990 VOID 991 NTAPI 992 MmZeroPageThread( 993 VOID 994 ); 995 996 /* hypermap.c *****************************************************************/ 997 998 extern PEPROCESS HyperProcess; 999 extern KIRQL HyperIrql; 1000 1001 PVOID 1002 NTAPI 1003 MiMapPageInHyperSpace(IN PEPROCESS Process, 1004 IN PFN_NUMBER Page, 1005 IN PKIRQL OldIrql); 1006 1007 VOID 1008 NTAPI 1009 MiUnmapPageInHyperSpace(IN PEPROCESS Process, 1010 IN PVOID Address, 1011 IN KIRQL OldIrql); 1012 1013 PVOID 1014 NTAPI 1015 MiMapPagesInZeroSpace(IN PMMPFN Pfn1, 1016 IN PFN_NUMBER NumberOfPages); 1017 1018 VOID 1019 NTAPI 1020 MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, 1021 IN PFN_NUMBER NumberOfPages); 1022 1023 // 1024 // ReactOS Compatibility Layer 1025 // 1026 FORCEINLINE 1027 PVOID 1028 MmCreateHyperspaceMapping(IN PFN_NUMBER Page) 1029 { 1030 HyperProcess = (PEPROCESS)KeGetCurrentThread()->ApcState.Process; 1031 return MiMapPageInHyperSpace(HyperProcess, Page, &HyperIrql); 1032 } 1033 1034 #define MmDeleteHyperspaceMapping(x) MiUnmapPageInHyperSpace(HyperProcess, x, HyperIrql); 1035 1036 /* i386/page.c *********************************************************/ 1037 1038 NTSTATUS 1039 NTAPI 1040 MmCreateVirtualMapping( 1041 struct _EPROCESS* Process, 1042 PVOID Address, 1043 ULONG flProtect, 1044 PPFN_NUMBER Pages, 1045 ULONG PageCount 1046 ); 1047 1048 NTSTATUS 1049 NTAPI 1050 MmCreateVirtualMappingUnsafe( 1051 struct _EPROCESS* Process, 1052 PVOID Address, 1053 ULONG flProtect, 1054 PPFN_NUMBER Pages, 1055 ULONG PageCount 1056 ); 1057 1058 ULONG 1059 NTAPI 1060 MmGetPageProtect( 1061 struct _EPROCESS* Process, 1062 PVOID Address); 1063 1064 VOID 1065 NTAPI 1066 MmSetPageProtect( 1067 struct _EPROCESS* Process, 1068 PVOID Address, 1069 ULONG flProtect 1070 ); 1071 1072 BOOLEAN 1073 NTAPI 1074 MmIsPagePresent( 1075 struct _EPROCESS* Process, 1076 PVOID Address 1077 ); 1078 1079 BOOLEAN 1080 NTAPI 1081 MmIsDisabledPage( 1082 struct _EPROCESS* Process, 1083 PVOID Address 1084 ); 1085 1086 INIT_FUNCTION 1087 VOID 1088 NTAPI 1089 MmInitGlobalKernelPageDirectory(VOID); 1090 1091 VOID 1092 NTAPI 1093 MmGetPageFileMapping( 1094 struct _EPROCESS *Process, 1095 PVOID Address, 1096 SWAPENTRY* SwapEntry); 1097 1098 VOID 1099 NTAPI 1100 MmDeletePageFileMapping( 1101 struct _EPROCESS *Process, 1102 PVOID Address, 1103 SWAPENTRY* SwapEntry 1104 ); 1105 1106 NTSTATUS 1107 NTAPI 1108 MmCreatePageFileMapping( 1109 struct _EPROCESS *Process, 1110 PVOID Address, 1111 SWAPENTRY SwapEntry 1112 ); 1113 1114 BOOLEAN 1115 NTAPI 1116 MmIsPageSwapEntry( 1117 struct _EPROCESS *Process, 1118 PVOID Address 1119 ); 1120 1121 VOID 1122 NTAPI 1123 MmSetDirtyPage( 1124 struct _EPROCESS *Process, 1125 PVOID Address 1126 ); 1127 1128 PFN_NUMBER 1129 NTAPI 1130 MmAllocPage( 1131 ULONG Consumer 1132 ); 1133 1134 VOID 1135 NTAPI 1136 MmDereferencePage(PFN_NUMBER Page); 1137 1138 VOID 1139 NTAPI 1140 MmReferencePage(PFN_NUMBER Page); 1141 1142 ULONG 1143 NTAPI 1144 MmGetReferenceCountPage(PFN_NUMBER Page); 1145 1146 BOOLEAN 1147 NTAPI 1148 MmIsPageInUse(PFN_NUMBER Page); 1149 1150 VOID 1151 NTAPI 1152 MmSetSavedSwapEntryPage( 1153 PFN_NUMBER Page, 1154 SWAPENTRY SavedSwapEntry); 1155 1156 SWAPENTRY 1157 NTAPI 1158 MmGetSavedSwapEntryPage(PFN_NUMBER Page); 1159 1160 VOID 1161 NTAPI 1162 MmSetCleanPage( 1163 struct _EPROCESS *Process, 1164 PVOID Address 1165 ); 1166 1167 VOID 1168 NTAPI 1169 MmDeletePageTable( 1170 struct _EPROCESS *Process, 1171 PVOID Address 1172 ); 1173 1174 PFN_NUMBER 1175 NTAPI 1176 MmGetPfnForProcess( 1177 struct _EPROCESS *Process, 1178 PVOID Address 1179 ); 1180 1181 BOOLEAN 1182 NTAPI 1183 MmCreateProcessAddressSpace( 1184 IN ULONG MinWs, 1185 IN PEPROCESS Dest, 1186 IN PULONG_PTR DirectoryTableBase 1187 ); 1188 1189 INIT_FUNCTION 1190 NTSTATUS 1191 NTAPI 1192 MmInitializeHandBuiltProcess( 1193 IN PEPROCESS Process, 1194 IN PULONG_PTR DirectoryTableBase 1195 ); 1196 1197 INIT_FUNCTION 1198 NTSTATUS 1199 NTAPI 1200 MmInitializeHandBuiltProcess2( 1201 IN PEPROCESS Process 1202 ); 1203 1204 NTSTATUS 1205 NTAPI 1206 MmSetExecuteOptions(IN ULONG ExecuteOptions); 1207 1208 NTSTATUS 1209 NTAPI 1210 MmGetExecuteOptions(IN PULONG ExecuteOptions); 1211 1212 VOID 1213 NTAPI 1214 MmDeleteVirtualMapping( 1215 struct _EPROCESS *Process, 1216 PVOID Address, 1217 BOOLEAN* WasDirty, 1218 PPFN_NUMBER Page 1219 ); 1220 1221 BOOLEAN 1222 NTAPI 1223 MmIsDirtyPage( 1224 struct _EPROCESS *Process, 1225 PVOID Address 1226 ); 1227 1228 /* wset.c ********************************************************************/ 1229 1230 NTSTATUS 1231 MmTrimUserMemory( 1232 ULONG Target, 1233 ULONG Priority, 1234 PULONG NrFreedPages 1235 ); 1236 1237 /* region.c ************************************************************/ 1238 1239 NTSTATUS 1240 NTAPI 1241 MmAlterRegion( 1242 PMMSUPPORT AddressSpace, 1243 PVOID BaseAddress, 1244 PLIST_ENTRY RegionListHead, 1245 PVOID StartAddress, 1246 SIZE_T Length, 1247 ULONG NewType, 1248 ULONG NewProtect, 1249 PMM_ALTER_REGION_FUNC AlterFunc 1250 ); 1251 1252 VOID 1253 NTAPI 1254 MmInitializeRegion( 1255 PLIST_ENTRY RegionListHead, 1256 SIZE_T Length, 1257 ULONG Type, 1258 ULONG Protect 1259 ); 1260 1261 PMM_REGION 1262 NTAPI 1263 MmFindRegion( 1264 PVOID BaseAddress, 1265 PLIST_ENTRY RegionListHead, 1266 PVOID Address, 1267 PVOID* RegionBaseAddress 1268 ); 1269 1270 /* section.c *****************************************************************/ 1271 1272 VOID 1273 NTAPI 1274 MmGetImageInformation( 1275 OUT PSECTION_IMAGE_INFORMATION ImageInformation 1276 ); 1277 1278 PFILE_OBJECT 1279 NTAPI 1280 MmGetFileObjectForSection( 1281 IN PVOID Section 1282 ); 1283 NTSTATUS 1284 NTAPI 1285 MmGetFileNameForAddress( 1286 IN PVOID Address, 1287 OUT PUNICODE_STRING ModuleName 1288 ); 1289 1290 NTSTATUS 1291 NTAPI 1292 MmGetFileNameForSection( 1293 IN PVOID Section, 1294 OUT POBJECT_NAME_INFORMATION *ModuleName 1295 ); 1296 1297 NTSTATUS 1298 NTAPI 1299 MmQuerySectionView( 1300 PMEMORY_AREA MemoryArea, 1301 PVOID Address, 1302 PMEMORY_BASIC_INFORMATION Info, 1303 PSIZE_T ResultLength 1304 ); 1305 1306 NTSTATUS 1307 NTAPI 1308 MmProtectSectionView( 1309 PMMSUPPORT AddressSpace, 1310 PMEMORY_AREA MemoryArea, 1311 PVOID BaseAddress, 1312 SIZE_T Length, 1313 ULONG Protect, 1314 PULONG OldProtect 1315 ); 1316 1317 INIT_FUNCTION 1318 NTSTATUS 1319 NTAPI 1320 MmInitSectionImplementation(VOID); 1321 1322 NTSTATUS 1323 NTAPI 1324 MmNotPresentFaultSectionView( 1325 PMMSUPPORT AddressSpace, 1326 MEMORY_AREA* MemoryArea, 1327 PVOID Address, 1328 BOOLEAN Locked 1329 ); 1330 1331 NTSTATUS 1332 NTAPI 1333 MmPageOutSectionView( 1334 PMMSUPPORT AddressSpace, 1335 PMEMORY_AREA MemoryArea, 1336 PVOID Address, 1337 ULONG_PTR Entry 1338 ); 1339 1340 INIT_FUNCTION 1341 NTSTATUS 1342 NTAPI 1343 MmCreatePhysicalMemorySection(VOID); 1344 1345 NTSTATUS 1346 NTAPI 1347 MmAccessFaultSectionView( 1348 PMMSUPPORT AddressSpace, 1349 MEMORY_AREA* MemoryArea, 1350 PVOID Address 1351 ); 1352 1353 VOID 1354 NTAPI 1355 MmFreeSectionSegments(PFILE_OBJECT FileObject); 1356 1357 /* sysldr.c ******************************************************************/ 1358 1359 INIT_FUNCTION 1360 VOID 1361 NTAPI 1362 MiReloadBootLoadedDrivers( 1363 IN PLOADER_PARAMETER_BLOCK LoaderBlock 1364 ); 1365 1366 INIT_FUNCTION 1367 BOOLEAN 1368 NTAPI 1369 MiInitializeLoadedModuleList( 1370 IN PLOADER_PARAMETER_BLOCK LoaderBlock 1371 ); 1372 1373 BOOLEAN 1374 NTAPI 1375 MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask); 1376 1377 VOID 1378 NTAPI 1379 MmMakeKernelResourceSectionWritable(VOID); 1380 1381 NTSTATUS 1382 NTAPI 1383 MmLoadSystemImage( 1384 IN PUNICODE_STRING FileName, 1385 IN PUNICODE_STRING NamePrefix OPTIONAL, 1386 IN PUNICODE_STRING LoadedName OPTIONAL, 1387 IN ULONG Flags, 1388 OUT PVOID *ModuleObject, 1389 OUT PVOID *ImageBaseAddress 1390 ); 1391 1392 NTSTATUS 1393 NTAPI 1394 MmUnloadSystemImage( 1395 IN PVOID ImageHandle 1396 ); 1397 1398 NTSTATUS 1399 NTAPI 1400 MmCheckSystemImage( 1401 IN HANDLE ImageHandle, 1402 IN BOOLEAN PurgeSection 1403 ); 1404 1405 NTSTATUS 1406 NTAPI 1407 MmCallDllInitialize( 1408 IN PLDR_DATA_TABLE_ENTRY LdrEntry, 1409 IN PLIST_ENTRY ListHead 1410 ); 1411 1412 1413 /* procsup.c *****************************************************************/ 1414 1415 NTSTATUS 1416 NTAPI 1417 MmGrowKernelStack( 1418 IN PVOID StackPointer 1419 ); 1420 1421 1422 FORCEINLINE 1423 VOID 1424 MmLockAddressSpace(PMMSUPPORT AddressSpace) 1425 { 1426 KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 1427 } 1428 1429 FORCEINLINE 1430 VOID 1431 MmUnlockAddressSpace(PMMSUPPORT AddressSpace) 1432 { 1433 KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 1434 } 1435 1436 FORCEINLINE 1437 PEPROCESS 1438 MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace) 1439 { 1440 if (AddressSpace == MmKernelAddressSpace) return NULL; 1441 return CONTAINING_RECORD(AddressSpace, EPROCESS, Vm); 1442 } 1443 1444 FORCEINLINE 1445 PMMSUPPORT 1446 MmGetCurrentAddressSpace(VOID) 1447 { 1448 return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm; 1449 } 1450 1451 FORCEINLINE 1452 PMMSUPPORT 1453 MmGetKernelAddressSpace(VOID) 1454 { 1455 return MmKernelAddressSpace; 1456 } 1457 1458 1459 /* expool.c ******************************************************************/ 1460 1461 VOID 1462 NTAPI 1463 ExpCheckPoolAllocation( 1464 PVOID P, 1465 POOL_TYPE PoolType, 1466 ULONG Tag); 1467 1468 VOID 1469 NTAPI 1470 ExReturnPoolQuota( 1471 IN PVOID P); 1472 1473 1474 /* mmsup.c *****************************************************************/ 1475 1476 NTSTATUS 1477 NTAPI 1478 MmAdjustWorkingSetSize( 1479 IN SIZE_T WorkingSetMinimumInBytes, 1480 IN SIZE_T WorkingSetMaximumInBytes, 1481 IN ULONG SystemCache, 1482 IN BOOLEAN IncreaseOkay); 1483 1484 1485 /* session.c *****************************************************************/ 1486 1487 _IRQL_requires_max_(APC_LEVEL) 1488 NTSTATUS 1489 NTAPI 1490 MmAttachSession( 1491 _Inout_ PVOID SessionEntry, 1492 _Out_ PKAPC_STATE ApcState); 1493 1494 _IRQL_requires_max_(APC_LEVEL) 1495 VOID 1496 NTAPI 1497 MmDetachSession( 1498 _Inout_ PVOID SessionEntry, 1499 _Out_ PKAPC_STATE ApcState); 1500 1501 VOID 1502 NTAPI 1503 MmQuitNextSession( 1504 _Inout_ PVOID SessionEntry); 1505 1506 PVOID 1507 NTAPI 1508 MmGetSessionById( 1509 _In_ ULONG SessionId); 1510 1511 _IRQL_requires_max_(APC_LEVEL) 1512 VOID 1513 NTAPI 1514 MmSetSessionLocaleId( 1515 _In_ LCID LocaleId); 1516 1517 /* shutdown.c *****************************************************************/ 1518 1519 VOID 1520 MmShutdownSystem(IN ULONG Phase); 1521 1522 /* virtual.c *****************************************************************/ 1523 1524 NTSTATUS 1525 NTAPI 1526 MmCopyVirtualMemory(IN PEPROCESS SourceProcess, 1527 IN PVOID SourceAddress, 1528 IN PEPROCESS TargetProcess, 1529 OUT PVOID TargetAddress, 1530 IN SIZE_T BufferSize, 1531 IN KPROCESSOR_MODE PreviousMode, 1532 OUT PSIZE_T ReturnSize); 1533 1534