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