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