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