Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

mapview.c File Reference

#include "mi.h"

Go to the source code of this file.

Classes

struct  _NTSYM

Defines

#define X256MEG   (256*1024*1024)
#define ROUND_TO_PAGES64(Size)   (((UINT64)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))

Typedefs

typedef _NTSYM NTSYM
typedef _NTSYMPNTSYM

Functions

VOID MiSetPageModified (IN PVOID Address)
NTSTATUS MiMapViewOfImageSection (IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *CapturedBase, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T CapturedViewSize, IN PSECTION Section, IN SECTION_INHERIT InheritDisposition, IN ULONG_PTR ZeroBits, IN SIZE_T ImageCommitment, OUT PBOOLEAN ReleasedWsMutex)
NTSTATUS MiMapViewOfDataSection (IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *CapturedBase, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T CapturedViewSize, IN PSECTION Section, IN SECTION_INHERIT InheritDisposition, IN ULONG ProtectionMask, IN SIZE_T CommitSize, IN ULONG_PTR ZeroBits, IN ULONG AllocationType, OUT PBOOLEAN ReleasedWsMutex)
VOID MiRemoveMappedPtes (IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT WorkingSetInfo)
NTSTATUS MiMapViewInSystemSpace (IN PVOID Section, IN PMMSESSION Session, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
NTSTATUS MiUnmapViewInSystemSpace (IN PMMSESSION Session, IN PVOID MappedBase)
BOOLEAN MiFillSystemPageDirectory (PVOID Base, SIZE_T NumberOfBytes)
VOID VadTreeWalk (PMMVAD Start)
ULONG CacheImageSymbols (IN PVOID ImageBase)
PVOID MiInsertInSystemSpace (IN PMMSESSION Session, IN ULONG SizeIn64k, IN PCONTROL_AREA ControlArea)
ULONG MiRemoveFromSystemSpace (IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
NTSTATUS NtMapViewOfSection (IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
NTSTATUS MmMapViewOfSection (IN PVOID SectionToMap, IN PEPROCESS Process, IN OUT PVOID *CapturedBase, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset, IN OUT PSIZE_T CapturedViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
NTSTATUS MiMapViewOfPhysicalSection (IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *CapturedBase, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T CapturedViewSize, IN ULONG ProtectionMask, IN ULONG_PTR ZeroBits, IN ULONG AllocationType, IN BOOLEAN WriteCombined, OUT PBOOLEAN ReleasedWsMutex)
NTSTATUS MiMapViewOfImageSection (IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *CapturedBase, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T CapturedViewSize, IN PSECTION Section, IN SECTION_INHERIT InheritDisposition, IN ULONG_PTR ZeroBits, IN SIZE_T ImageCommitment, IN OUT PBOOLEAN ReleasedWsMutex)
 _ALPHA_

NTSTATUS MiMapViewOfDataSection (IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *CapturedBase, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T CapturedViewSize, IN PSECTION Section, IN SECTION_INHERIT InheritDisposition, IN ULONG ProtectionMask, IN SIZE_T CommitSize, IN ULONG_PTR ZeroBits, IN ULONG AllocationType, IN PBOOLEAN ReleasedWsMutex)
LOGICAL MiCheckPurgeAndUpMapCount (IN PCONTROL_AREA ControlArea)
NTSYSAPI NTSTATUS NTAPI NtAreMappedFilesTheSame (IN PVOID File1MappedAsAnImage, IN PVOID File2MappedAsFile)
NTSTATUS MmMapViewInSystemSpace (IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
NTSTATUS MmMapViewInSessionSpace (IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
NTSTATUS MmUnmapViewInSystemSpace (IN PVOID MappedBase)
NTSTATUS MmUnmapViewInSessionSpace (IN PVOID MappedBase)
BOOLEAN MiInitializeSystemSpaceMap (PVOID InputSession OPTIONAL)
VOID MiFreeSessionSpaceMap (VOID)
HANDLE MmSecureVirtualMemory (IN PVOID Address, IN SIZE_T Size, IN ULONG ProbeMode)
VOID MmUnsecureVirtualMemory (IN HANDLE SecureHandle)

Variables

ULONG MMPPTE_NAME = 'tPmM'
ULONG MMDB = 'bDmM'
ULONG MMVADKEY
LIST_ENTRY MmLoadedUserImageList
MMSESSION MmSession


Define Documentation

#define ROUND_TO_PAGES64 Size   )     (((UINT64)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
 

Definition at line 42 of file mapview.c.

Referenced by MiMapViewOfDataSection().

#define X256MEG   (256*1024*1024)
 

Definition at line 36 of file mapview.c.


Typedef Documentation

typedef struct _NTSYM NTSYM
 

typedef struct _NTSYM * PNTSYM
 


Function Documentation

ULONG CacheImageSymbols IN PVOID  ImageBase  ) 
 

Definition at line 2930 of file mapview.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, PAGED_CODE, RtlImageDirectoryEntryToData(), and TRUE.

02933 { 02934 PIMAGE_DEBUG_DIRECTORY DebugDirectory; 02935 ULONG DebugSize; 02936 02937 PAGED_CODE(); 02938 02939 try { 02940 DebugDirectory = (PIMAGE_DEBUG_DIRECTORY) 02941 RtlImageDirectoryEntryToData( ImageBase, 02942 TRUE, 02943 IMAGE_DIRECTORY_ENTRY_DEBUG, 02944 &DebugSize 02945 ); 02946 if (!DebugDirectory) { 02947 return FALSE; 02948 } 02949 02950 // 02951 // If using remote KD, ImageBase is what it wants to see. 02952 // 02953 02954 } except (EXCEPTION_EXECUTE_HANDLER) { 02955 return FALSE; 02956 } 02957 02958 return TRUE; 02959 }

LOGICAL MiCheckPurgeAndUpMapCount IN PCONTROL_AREA  ControlArea  ) 
 

Definition at line 2809 of file mapview.c.

References ASSERT, _EVENT_COUNTER::Event, FALSE, KeEnterCriticalRegion, KeLeaveCriticalRegion, KernelMode, KeWaitForSingleObject(), LOCK_PFN, MiFreeEventCounter(), MiGetEventCounter(), NULL, _EVENT_COUNTER::RefCount, TRUE, UNLOCK_PFN, UNLOCK_PFN_AND_THEN_WAIT, and WrVirtualMemory.

Referenced by MiMapViewInSystemSpace(), MiMapViewOfDataSection(), MiMapViewOfImageSection(), and MiShareSessionImage().

02815 : 02816 02817 This routine synchronizes with any on going purge operations 02818 on the same segment (identified via the control area). If 02819 another purge operation is occurring, the function blocks until 02820 it is completed. 02821 02822 When this function returns the MappedView and the NumberOfUserReferences 02823 count for the control area will be incremented thereby referencing 02824 the control area. 02825 02826 Arguments: 02827 02828 ControlArea - Supplies the control area for the segment to be purged. 02829 02830 Return Value: 02831 02832 TRUE if the synchronization was successful. 02833 FALSE if the synchronization did not occur due to low resources, etc. 02834 02835 Environment: 02836 02837 Kernel Mode. 02838 02839 --*/ 02840 02841 { 02842 KIRQL OldIrql; 02843 PEVENT_COUNTER PurgedEvent; 02844 PEVENT_COUNTER WaitEvent; 02845 ULONG OldRef; 02846 02847 PurgedEvent = NULL; 02848 OldRef = 1; 02849 02850 LOCK_PFN (OldIrql); 02851 02852 while (ControlArea->u.Flags.BeingPurged != 0) { 02853 02854 // 02855 // A purge operation is in progress. 02856 // 02857 02858 if (PurgedEvent == NULL) { 02859 02860 // 02861 // Release the locks and allocate pool for the event. 02862 // 02863 02864 PurgedEvent = MiGetEventCounter (); 02865 if (PurgedEvent == NULL) { 02866 UNLOCK_PFN (OldIrql); 02867 return FALSE; 02868 } 02869 02870 continue; 02871 } 02872 02873 if (ControlArea->WaitingForDeletion == NULL) { 02874 ControlArea->WaitingForDeletion = PurgedEvent; 02875 WaitEvent = PurgedEvent; 02876 PurgedEvent = NULL; 02877 } else { 02878 WaitEvent = ControlArea->WaitingForDeletion; 02879 WaitEvent->RefCount += 1; 02880 } 02881 02882 // 02883 // Release the pfn lock and wait for the event. 02884 // 02885 02886 KeEnterCriticalRegion(); 02887 UNLOCK_PFN_AND_THEN_WAIT(OldIrql); 02888 02889 KeWaitForSingleObject(&WaitEvent->Event, 02890 WrVirtualMemory, 02891 KernelMode, 02892 FALSE, 02893 (PLARGE_INTEGER)NULL); 02894 LOCK_PFN (OldIrql); 02895 KeLeaveCriticalRegion(); 02896 MiFreeEventCounter (WaitEvent, FALSE); 02897 } 02898 02899 // 02900 // Indicate another file is mapped for the segment. 02901 // 02902 02903 ControlArea->NumberOfMappedViews += 1; 02904 ControlArea->NumberOfUserReferences += 1; 02905 ControlArea->u.Flags.HadUserReference = 1; 02906 ASSERT (ControlArea->NumberOfSectionReferences != 0); 02907 02908 if (PurgedEvent != NULL) { 02909 MiFreeEventCounter (PurgedEvent, TRUE); 02910 } 02911 UNLOCK_PFN (OldIrql); 02912 02913 return TRUE; 02914 }

BOOLEAN MiFillSystemPageDirectory PVOID  Base,
SIZE_T  NumberOfBytes
 

Definition at line 3484 of file mapview.c.

References LOCK_PFN, MI_GET_PAGE_COLOR_FROM_PTE, MI_WRITE_VALID_PTE, MiChargeCommitmentCantExpand(), MiEnsureAvailablePageOrWait(), MiFillMemoryPte, MiGetPdeAddress, MiGetVirtualAddressMappedByPte, MiInitializePfn(), MiInitializePfnForOtherProcess(), MiRemoveAnyPage(), MM_DBG_COMMIT_FILL_SYSTEM_DIRECTORY, MM_TRACK_COMMIT, MM_ZERO_KERNEL_PTE, MmSystemPageDirectory, MmSystemPagePtes, NULL, PAGE_SIZE, PAGED_CODE, PDE_PER_PAGE, TRUE, _MMPTE::u, UNLOCK_PFN, and ValidKernelPde.

Referenced by MiMapViewInSystemSpace().

03491 : 03492 03493 This routine allocates page tables and fills the system page directory 03494 entries for the specified virtual address range. 03495 03496 Arguments: 03497 03498 Base - Supplies the virtual address of the view. 03499 03500 NumberOfBytes - Supplies the number of bytes the view spans. 03501 03502 Return Value: 03503 03504 TRUE on success, FALSE on failure. 03505 03506 Environment: 03507 03508 Kernel Mode, IRQL of dispatch level. 03509 03510 --*/ 03511 03512 { 03513 PMMPTE FirstPde; 03514 PMMPTE LastPde; 03515 PMMPTE FirstSystemPde; 03516 MMPTE TempPte; 03517 PFN_NUMBER PageFrameIndex; 03518 KIRQL OldIrql; 03519 ULONG i; 03520 03521 PAGED_CODE(); 03522 03523 // 03524 // CODE IS ALREADY LOCKED BY CALLER. 03525 // 03526 03527 FirstPde = MiGetPdeAddress (Base); 03528 LastPde = MiGetPdeAddress ((PVOID)(((PCHAR)Base) + NumberOfBytes - 1)); 03529 03530 #if defined (_WIN64) 03531 FirstSystemPde = FirstPde; 03532 #else 03533 #if !defined (_X86PAE_) 03534 FirstSystemPde = &MmSystemPagePtes[((ULONG_PTR)FirstPde & 03535 ((PDE_PER_PAGE * sizeof(MMPTE)) - 1)) / sizeof(MMPTE) ]; 03536 #else 03537 FirstSystemPde = &MmSystemPagePtes[((ULONG_PTR)FirstPde & 03538 (PD_PER_SYSTEM * (PDE_PER_PAGE * sizeof(MMPTE)) - 1)) / sizeof(MMPTE) ]; 03539 #endif 03540 #endif 03541 03542 do { 03543 if (FirstSystemPde->u.Hard.Valid == 0) { 03544 03545 // 03546 // No page table page exists, get a page and map it in. 03547 // 03548 03549 TempPte = ValidKernelPde; 03550 03551 LOCK_PFN (OldIrql); 03552 03553 if (((volatile MMPTE *)FirstSystemPde)->u.Hard.Valid == 0) { 03554 03555 if (MiEnsureAvailablePageOrWait (NULL, FirstPde)) { 03556 03557 // 03558 // PFN_LOCK was dropped, redo this loop as another process 03559 // could have made this PDE valid. 03560 // 03561 03562 UNLOCK_PFN (OldIrql); 03563 continue; 03564 } 03565 03566 MiChargeCommitmentCantExpand (1, TRUE); 03567 MM_TRACK_COMMIT (MM_DBG_COMMIT_FILL_SYSTEM_DIRECTORY, 1); 03568 PageFrameIndex = MiRemoveAnyPage ( 03569 MI_GET_PAGE_COLOR_FROM_PTE (FirstSystemPde)); 03570 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 03571 MI_WRITE_VALID_PTE (FirstSystemPde, TempPte); 03572 MI_WRITE_VALID_PTE (FirstPde, TempPte); 03573 03574 #if defined (_WIN64) 03575 MiInitializePfn (PageFrameIndex, 03576 FirstPde, 03577 1); 03578 #else 03579 03580 #if !defined (_X86PAE_) 03581 MiInitializePfnForOtherProcess (PageFrameIndex, 03582 FirstPde, 03583 MmSystemPageDirectory); 03584 #else 03585 i = (FirstPde - MiGetPdeAddress(0)) / PDE_PER_PAGE; 03586 MiInitializePfnForOtherProcess (PageFrameIndex, 03587 FirstPde, 03588 MmSystemPageDirectory[i]); 03589 #endif 03590 03591 #endif 03592 03593 MiFillMemoryPte (MiGetVirtualAddressMappedByPte (FirstPde), 03594 PAGE_SIZE, 03595 MM_ZERO_KERNEL_PTE); 03596 } 03597 UNLOCK_PFN (OldIrql); 03598 } 03599 03600 FirstSystemPde += 1; 03601 FirstPde += 1; 03602 } while (FirstPde <= LastPde ); 03603 03604 return TRUE; 03605 }

VOID MiFreeSessionSpaceMap VOID   ) 
 

Definition at line 4071 of file mapview.c.

References _MMVIEW::ControlArea, DbgPrint, _MMVIEW::Entry, ExFreePool(), Index, KeBugCheckEx(), LOCK_SYSTEM_VIEW_SPACE, MiRemoveBitMap, MiUnmapViewInSystemSpace(), MmSessionSpace, NULL, PAGED_CODE, _MM_SESSION_SPACE::Session, _MM_SESSION_SPACE::SessionId, _MMSESSION::SystemSpaceBitMap, _MMSESSION::SystemSpaceHashEntries, _MMSESSION::SystemSpaceHashSize, _MMSESSION::SystemSpaceViewTable, and UNLOCK_SYSTEM_VIEW_SPACE.

Referenced by MiDereferenceSession(), and MiSessionCreateInternal().

04077 : 04078 04079 This routine frees the tables used for mapping session views. 04080 04081 Arguments: 04082 04083 None. 04084 04085 Return Value: 04086 04087 None. 04088 04089 Environment: 04090 04091 Kernel Mode. The caller must be in the correct session context. 04092 04093 --*/ 04094 04095 { 04096 PMMSESSION Session; 04097 04098 PAGED_CODE(); 04099 04100 Session = &MmSessionSpace->Session; 04101 04102 // 04103 // Check for leaks of objects in the view table. 04104 // 04105 04106 LOCK_SYSTEM_VIEW_SPACE (Session); 04107 04108 if (Session->SystemSpaceViewTable && Session->SystemSpaceHashEntries) { 04109 04110 KeBugCheckEx (SESSION_HAS_VALID_VIEWS_ON_EXIT, 04111 (ULONG_PTR)MmSessionSpace->SessionId, 04112 Session->SystemSpaceHashEntries, 04113 (ULONG_PTR)&Session->SystemSpaceViewTable[0], 04114 Session->SystemSpaceHashSize); 04115 04116 #if 0 04117 ULONG Index; 04118 04119 for (Index = 0; Index < Session->SystemSpaceHashSize; Index += 1) { 04120 04121 PMMVIEW Table; 04122 PVOID Base; 04123 04124 Table = &Session->SystemSpaceViewTable[Index]; 04125 04126 if (Table->Entry) { 04127 04128 #if DBG 04129 DbgPrint ("MM: MiFreeSessionSpaceMap: view entry %d leak: ControlArea %p, Addr %p, Size %d\n", 04130 Index, 04131 Table->ControlArea, 04132 Table->Entry & ~0xFFFF, 04133 Table->Entry & 0x0000FFFF 04134 ); 04135 #endif 04136 04137 Base = (PVOID)(Table->Entry & ~0xFFFF); 04138 04139 // 04140 // MiUnmapViewInSystemSpace locks the ViewLock. 04141 // 04142 04143 UNLOCK_SYSTEM_VIEW_SPACE(Session); 04144 04145 MiUnmapViewInSystemSpace (Session, Base); 04146 04147 LOCK_SYSTEM_VIEW_SPACE (Session); 04148 04149 // 04150 // The view table may have been deleted while we let go of 04151 // the lock. 04152 // 04153 04154 if (Session->SystemSpaceViewTable == NULL) { 04155 break; 04156 } 04157 } 04158 } 04159 #endif 04160 04161 } 04162 04163 UNLOCK_SYSTEM_VIEW_SPACE (Session); 04164 04165 if (Session->SystemSpaceViewTable) { 04166 ExFreePool (Session->SystemSpaceViewTable); 04167 Session->SystemSpaceViewTable = NULL; 04168 } 04169 04170 if (Session->SystemSpaceBitMap) { 04171 MiRemoveBitMap (&Session->SystemSpaceBitMap); 04172 } 04173 }

BOOLEAN MiInitializeSystemSpaceMap PVOID InputSession  OPTIONAL  ) 
 

Definition at line 3967 of file mapview.c.

References ASSERT, ExAllocatePoolWithTag, ExInitializeFastMutex, FALSE, MI_SESSION_VIEW_SIZE, MI_SESSION_VIEW_START, MiCreateBitMap, MiHydra, MiRemoveBitMap, MiSystemViewStart, MM_BUMP_SESSION_FAILURES, MM_SESSION_FAILURE_NO_NONPAGED_POOL, MM_SESSION_FAILURE_NO_SESSION_PAGED_POOL, MM_SYSTEM_VIEW_SIZE, MM_SYSTEM_VIEW_SIZE_IF_HYDRA, MmSession, NonPagedPool, NULL, PAGE_SIZE, PagedPool, RtlClearAllBits(), Size, _MMSESSION::SystemSpaceBitMap, _MMSESSION::SystemSpaceHashEntries, _MMSESSION::SystemSpaceHashKey, _MMSESSION::SystemSpaceHashSize, _MMSESSION::SystemSpaceViewLock, _MMSESSION::SystemSpaceViewLockPointer, _MMSESSION::SystemSpaceViewStart, _MMSESSION::SystemSpaceViewTable, TRUE, and X64K.

03973 : 03974 03975 This routine initializes the tables for mapping views into system space. 03976 Views are kept in a multiple of 64k bytes in a growable hashed table. 03977 03978 Arguments: 03979 03980 NULL if this is the initial system session (non-Hydra), a valid session 03981 pointer (the pointer must be in global space, not session space) for 03982 Hydra session initialization. 03983 03984 Return Value: 03985 03986 TRUE on success, FALSE on failure. 03987 03988 Environment: 03989 03990 Kernel Mode, initialization. 03991 03992 --*/ 03993 03994 { 03995 ULONG AllocSize; 03996 ULONG Size; 03997 PCHAR ViewStart; 03998 PMMSESSION Session; 03999 04000 if (ARGUMENT_PRESENT (InputSession)) { 04001 Session = (PMMSESSION)InputSession; 04002 ViewStart = (PCHAR)MI_SESSION_VIEW_START; 04003 Size = MI_SESSION_VIEW_SIZE; 04004 } 04005 else { 04006 Session = &MmSession; 04007 ViewStart = (PCHAR)MiSystemViewStart; 04008 if (MiHydra == TRUE) { 04009 Size = MM_SYSTEM_VIEW_SIZE_IF_HYDRA; 04010 } 04011 else { 04012 Size = MM_SYSTEM_VIEW_SIZE; 04013 } 04014 } 04015 04016 // 04017 // We are passed a system global address for the address of the session. 04018 // Save a global pointer to the mutex below because multiple sessions will 04019 // generally give us a session-space (not a global space) pointer to the 04020 // MMSESSION in subsequent calls. We need the global pointer for the mutex 04021 // field for the kernel primitives to work properly. 04022 // 04023 04024 Session->SystemSpaceViewLockPointer = &Session->SystemSpaceViewLock; 04025 ExInitializeFastMutex(Session->SystemSpaceViewLockPointer); 04026 04027 // 04028 // If the kernel image has not been biased to allow for 3gb of user space, 04029 // then the system space view starts at the defined place. Otherwise, it 04030 // starts 16mb above the kernel image. 04031 // 04032 04033 Session->SystemSpaceViewStart = ViewStart; 04034 04035 MiCreateBitMap (&Session->SystemSpaceBitMap, Size / X64K, NonPagedPool); 04036 if (Session->SystemSpaceBitMap == NULL) { 04037 MM_BUMP_SESSION_FAILURES (MM_SESSION_FAILURE_NO_NONPAGED_POOL); 04038 return FALSE; 04039 } 04040 04041 RtlClearAllBits (Session->SystemSpaceBitMap); 04042 04043 // 04044 // Build the view table. 04045 // 04046 04047 Session->SystemSpaceHashSize = 31; 04048 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1; 04049 Session->SystemSpaceHashEntries = 0; 04050 04051 AllocSize = sizeof(MMVIEW) * Session->SystemSpaceHashSize; 04052 ASSERT (AllocSize < PAGE_SIZE); 04053 04054 Session->SystemSpaceViewTable = ExAllocatePoolWithTag (PagedPool, 04055 AllocSize, 04056 ' mM'); 04057 04058 if (Session->SystemSpaceViewTable == NULL) { 04059 MM_BUMP_SESSION_FAILURES (MM_SESSION_FAILURE_NO_SESSION_PAGED_POOL); 04060 MiRemoveBitMap (&Session->SystemSpaceBitMap); 04061 return FALSE; 04062 } 04063 04064 RtlZeroMemory (Session->SystemSpaceViewTable, AllocSize); 04065 04066 return TRUE; 04067 }

PVOID MiInsertInSystemSpace IN PMMSESSION  Session,
IN ULONG  SizeIn64k,
IN PCONTROL_AREA  ControlArea
 

Definition at line 3757 of file mapview.c.

References ASSERT, _MMVIEW::Entry, ExAllocatePoolWithTag, ExFreePool(), LOCK_SYSTEM_VIEW_SPACE, MI_64K_ALIGN, MMVIEW, NULL, PAGE_SIZE, PAGED_CODE, PagedPool, PMMVIEW, RtlFindClearBitsAndSet(), UNLOCK_SYSTEM_VIEW_SPACE, and X64K.

Referenced by MiMapViewInSystemSpace().

03765 : 03766 03767 This routine creates a view in system space for the specified control 03768 area (file mapping). 03769 03770 Arguments: 03771 03772 SizeIn64k - Supplies the size of the view to be created. 03773 03774 ControlArea - Supplies a pointer to the control area for this view. 03775 03776 Return Value: 03777 03778 Base address where the view was mapped, NULL if the view could not be 03779 mapped. 03780 03781 Environment: 03782 03783 Kernel Mode. 03784 03785 --*/ 03786 03787 { 03788 03789 PVOID Base; 03790 ULONG_PTR Entry; 03791 ULONG Hash; 03792 ULONG i; 03793 ULONG AllocSize; 03794 PMMVIEW OldTable; 03795 ULONG StartBit; 03796 ULONG NewHashSize; 03797 03798 PAGED_CODE(); 03799 03800 // 03801 // CODE IS ALREADY LOCKED BY CALLER. 03802 // 03803 03804 LOCK_SYSTEM_VIEW_SPACE (Session); 03805 03806 if (Session->SystemSpaceHashEntries + 8 > Session->SystemSpaceHashSize) { 03807 03808 // 03809 // Less than 8 free slots, reallocate and rehash. 03810 // 03811 03812 NewHashSize = Session->SystemSpaceHashSize << 1; 03813 03814 AllocSize = sizeof(MMVIEW) * NewHashSize; 03815 ASSERT (AllocSize < PAGE_SIZE); 03816 03817 OldTable = Session->SystemSpaceViewTable; 03818 03819 Session->SystemSpaceViewTable = ExAllocatePoolWithTag (PagedPool, 03820 AllocSize, 03821 ' mM'); 03822 03823 if (Session->SystemSpaceViewTable == NULL) { 03824 Session->SystemSpaceViewTable = OldTable; 03825 } 03826 else { 03827 RtlZeroMemory (Session->SystemSpaceViewTable, AllocSize); 03828 03829 Session->SystemSpaceHashSize = NewHashSize; 03830 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1; 03831 03832 for (i = 0; i < (Session->SystemSpaceHashSize / 2); i += 1) { 03833 if (OldTable[i].Entry != 0) { 03834 Hash = (ULONG) ((OldTable[i].Entry >> 16) % Session->SystemSpaceHashKey); 03835 03836 while (Session->SystemSpaceViewTable[Hash].Entry != 0) { 03837 Hash += 1; 03838 if (Hash >= Session->SystemSpaceHashSize) { 03839 Hash = 0; 03840 } 03841 } 03842 Session->SystemSpaceViewTable[Hash] = OldTable[i]; 03843 } 03844 } 03845 ExFreePool (OldTable); 03846 } 03847 } 03848 03849 if (Session->SystemSpaceHashEntries == Session->SystemSpaceHashSize) { 03850 03851 // 03852 // There are no free hash slots to place a new entry into even 03853 // though there may still be unused virtual address space. 03854 // 03855 03856 UNLOCK_SYSTEM_VIEW_SPACE (Session); 03857 return NULL; 03858 } 03859 03860 StartBit = RtlFindClearBitsAndSet (Session->SystemSpaceBitMap, 03861 SizeIn64k, 03862 0); 03863 03864 if (StartBit == 0xFFFFFFFF) { 03865 UNLOCK_SYSTEM_VIEW_SPACE (Session); 03866 return NULL; 03867 } 03868 03869 Base = (PVOID)((PCHAR)Session->SystemSpaceViewStart + (StartBit * X64K)); 03870 03871 Entry = (ULONG_PTR) MI_64K_ALIGN(Base) + SizeIn64k; 03872 03873 Hash = (ULONG) ((Entry >> 16) % Session->SystemSpaceHashKey); 03874 03875 while (Session->SystemSpaceViewTable[Hash].Entry != 0) { 03876 Hash += 1; 03877 if (Hash >= Session->SystemSpaceHashSize) { 03878 Hash = 0; 03879 } 03880 } 03881 03882 Session->SystemSpaceHashEntries += 1; 03883 03884 Session->SystemSpaceViewTable[Hash].Entry = Entry; 03885 Session->SystemSpaceViewTable[Hash].ControlArea = ControlArea; 03886 03887 UNLOCK_SYSTEM_VIEW_SPACE (Session); 03888 return Base; 03889 }

NTSTATUS MiMapViewInSystemSpace IN PVOID  Section,
IN PMMSESSION  Session,
OUT PVOID *  MappedBase,
IN OUT PSIZE_T  ViewSize
 

Definition at line 3268 of file mapview.c.

References ASSERT, BYTES_TO_PAGES, _SEGMENT::ControlArea, ExPageLockHandle, FALSE, LOCK_PFN, LOCK_SESSION_SPACE_WS, LOCK_SYSTEM_VIEW_SPACE, MiAddMappedPtes(), MiCheckControlArea(), MiCheckPurgeAndUpMapCount(), MiFillSystemPageDirectory(), MiGetPteAddress, MiInsertInSystemSpace(), MiRemoveFromSystemSpace(), MiSessionCommitPageTables(), MmLockPagableSectionByHandle(), MmSession, MmUnlockPagableImageSection(), NT_SUCCESS, NULL, _CONTROL_AREA::NumberOfMappedViews, _CONTROL_AREA::NumberOfUserReferences, PAGED_CODE, PSECTION, RtlClearBits(), _CONTROL_AREA::Segment, TRUE, _CONTROL_AREA::u, UNLOCK_PFN, UNLOCK_SESSION_SPACE_WS, UNLOCK_SYSTEM_VIEW_SPACE, and X64K.

Referenced by MmMapViewInSessionSpace(), and MmMapViewInSystemSpace().

03277 : 03278 03279 This routine maps the specified section into the system's address space. 03280 03281 Arguments: 03282 03283 Section - Supplies a pointer to the section to map. 03284 03285 Session - Supplies the session data structure for this view. 03286 03287 *MappedBase - Returns the address where the section was mapped. 03288 03289 ViewSize - Supplies the size of the view to map. If this 03290 is specified as zero, the whole section is mapped. 03291 Returns the actual size mapped. 03292 03293 Protect - Supplies the protection for the view. Must be 03294 either PAGE_READWRITE or PAGE_READONLY. 03295 03296 Return Value: 03297 03298 Status of the map view operation. 03299 03300 Environment: 03301 03302 Kernel Mode, IRQL of APC_LEVEL or below. 03303 03304 --*/ 03305 03306 { 03307 PVOID Base; 03308 KIRQL OldIrql; 03309 PSUBSECTION Subsection; 03310 PCONTROL_AREA ControlArea; 03311 PCONTROL_AREA NewControlArea; 03312 ULONG StartBit; 03313 ULONG SizeIn64k; 03314 ULONG NewSizeIn64k; 03315 PMMPTE BasePte; 03316 ULONG NumberOfPtes; 03317 ULONG NumberOfBytes; 03318 BOOLEAN status; 03319 KIRQL WsIrql; 03320 03321 PAGED_CODE(); 03322 03323 // 03324 // Check to see if a purge operation is in progress and if so, wait 03325 // for the purge to complete. In addition, up the count of mapped 03326 // views for this control area. 03327 // 03328 03329 ControlArea = ((PSECTION)Section)->Segment->ControlArea; 03330 03331 if (ControlArea->u.Flags.GlobalOnlyPerSession == 0) { 03332 Subsection = (PSUBSECTION)(ControlArea + 1); 03333 } 03334 else { 03335 Subsection = (PSUBSECTION)((PLARGE_CONTROL_AREA)ControlArea + 1); 03336 } 03337 03338 MmLockPagableSectionByHandle(ExPageLockHandle); 03339 03340 if (MiCheckPurgeAndUpMapCount (ControlArea) == FALSE) { 03341 MmUnlockPagableImageSection(ExPageLockHandle); 03342 return STATUS_INSUFFICIENT_RESOURCES; 03343 } 03344 03345 if (*ViewSize == 0) { 03346 03347 *ViewSize = ((PSECTION)Section)->SizeOfSection.LowPart; 03348 03349 } else if (*ViewSize > ((PSECTION)Section)->SizeOfSection.LowPart) { 03350 03351 // 03352 // Section offset or view size past size of section. 03353 // 03354 03355 LOCK_PFN (OldIrql); 03356 ControlArea->NumberOfMappedViews -= 1; 03357 ControlArea->NumberOfUserReferences -= 1; 03358 03359 // 03360 // Check to see if the control area (segment) should be deleted. 03361 // This routine releases the PFN lock. 03362 // 03363 03364 MiCheckControlArea (ControlArea, NULL, OldIrql); 03365 03366 MmUnlockPagableImageSection(ExPageLockHandle); 03367 return STATUS_INVALID_VIEW_SIZE; 03368 } 03369 03370 // 03371 // Calculate the first prototype PTE field in the Vad. 03372 // 03373 03374 SizeIn64k = (ULONG)((*ViewSize / X64K) + ((*ViewSize & (X64K - 1)) != 0)); 03375 03376 Base = MiInsertInSystemSpace (Session, SizeIn64k, ControlArea); 03377 03378 if (Base == NULL) { 03379 LOCK_PFN (OldIrql); 03380 ControlArea->NumberOfMappedViews -= 1; 03381 ControlArea->NumberOfUserReferences -= 1; 03382 03383 // 03384 // Check to see if the control area (segment) should be deleted. 03385 // This routine releases the PFN lock. 03386 // 03387 03388 MiCheckControlArea (ControlArea, NULL, OldIrql); 03389 03390 MmUnlockPagableImageSection(ExPageLockHandle); 03391 return STATUS_NO_MEMORY; 03392 } 03393 03394 NumberOfBytes = SizeIn64k * X64K; 03395 03396 if (Session == &MmSession) { 03397 status = MiFillSystemPageDirectory (Base, NumberOfBytes); 03398 } 03399 else { 03400 LOCK_SESSION_SPACE_WS (WsIrql); 03401 if (NT_SUCCESS(MiSessionCommitPageTables (Base, 03402 (PVOID)((ULONG_PTR)Base + NumberOfBytes - 1)))) { 03403 status = TRUE; 03404 } 03405 else { 03406 status = FALSE; 03407 } 03408 } 03409 03410 if (status == FALSE) { 03411 if (Session != &MmSession) { 03412 UNLOCK_SESSION_SPACE_WS (WsIrql); 03413 } 03414 03415 LOCK_PFN (OldIrql); 03416 ControlArea->NumberOfMappedViews -= 1; 03417 ControlArea->NumberOfUserReferences -= 1; 03418 03419 // 03420 // Check to see if the control area (segment) should be deleted. 03421 // This routine releases the PFN lock. 03422 // 03423 03424 MiCheckControlArea (ControlArea, NULL, OldIrql); 03425 03426 StartBit = (ULONG) (((ULONG_PTR)Base - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16); 03427 03428 LOCK_SYSTEM_VIEW_SPACE (Session); 03429 03430 NewSizeIn64k = MiRemoveFromSystemSpace (Session, Base, &NewControlArea); 03431 03432 ASSERT (ControlArea == NewControlArea); 03433 ASSERT (SizeIn64k == NewSizeIn64k); 03434 03435 RtlClearBits (Session->SystemSpaceBitMap, StartBit, SizeIn64k); 03436 03437 UNLOCK_SYSTEM_VIEW_SPACE (Session); 03438 03439 MmUnlockPagableImageSection(ExPageLockHandle); 03440 return STATUS_NO_MEMORY; 03441 } 03442 03443 // 03444 // Setup PTEs to point to prototype PTEs. 03445 // 03446 03447 if (((PSECTION)Section)->u.Flags.Image) { 03448 03449 #if DBG 03450 // 03451 // The only reason this ASSERT isn't done for Hydra is because 03452 // the session space working set lock is currently held so faults 03453 // are not allowed. 03454 // 03455 03456 if (Session == &MmSession) { 03457 ASSERT (((PSECTION)Section)->Segment->ControlArea == ControlArea); 03458 } 03459 #endif 03460 03461 LOCK_PFN (OldIrql); 03462 ControlArea->u.Flags.ImageMappedInSystemSpace = 1; 03463 UNLOCK_PFN (OldIrql); 03464 } 03465 03466 BasePte = MiGetPteAddress (Base); 03467 NumberOfPtes = BYTES_TO_PAGES (*ViewSize); 03468 03469 MiAddMappedPtes (BasePte, 03470 NumberOfPtes, 03471 ControlArea); 03472 03473 if (Session != &MmSession) { 03474 UNLOCK_SESSION_SPACE_WS (WsIrql); 03475 } 03476 03477 *MappedBase = Base; 03478 03479 MmUnlockPagableImageSection(ExPageLockHandle); 03480 return STATUS_SUCCESS; 03481 }

NTSTATUS MiMapViewOfDataSection IN PCONTROL_AREA  ControlArea,
IN PEPROCESS  Process,
IN PVOID *  CapturedBase,
IN PLARGE_INTEGER  SectionOffset,
IN PSIZE_T  CapturedViewSize,
IN PSECTION  Section,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG  ProtectionMask,
IN SIZE_T  CommitSize,
IN ULONG_PTR  ZeroBits,
IN ULONG  AllocationType,
IN PBOOLEAN  ReleasedWsMutex
 

Definition at line 2256 of file mapview.c.

References ASSERT, BYTES_TO_PAGES, _MMEXTEND_INFO::CommittedSize, _MMVAD::ControlArea, _MMVAD::EndingVpn, ExAcquireFastMutexUnsafe(), ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExRaiseStatus(), ExReleaseFastMutexUnsafe(), FALSE, _MMVAD::FirstPrototypePte, L, _MMVAD::LastContiguousPte, LOCK_PFN, LOCK_WS_UNSAFE, MI_ALIGN_TO_SIZE, MI_IS_PTE_PROTECTION_COPY_WRITE, MI_VA_TO_VPN, MI_WRITE_INVALID_PTE, MiChargeCommitment(), MiCheckControlArea(), MiCheckForConflictingVad, MiCheckPurgeAndUpMapCount(), MiFindEmptyAddressRange(), MiFindEmptyAddressRangeDown, MiInsertVad(), MiProtectMapFileFor4kPage(), MiReturnCommitment(), MM_DBG_COMMIT_MAPVIEW_DATA, MM_DBG_COMMIT_RETURN_MAPVIEW_DATA, MM_HIGHEST_VAD_ADDRESS, MM_TRACK_COMMIT, MM_USER_ADDRESS_RANGE_LIMIT, MMEXTEND_INFO, MmSectionBasedMutex, MmSectionCommitMutex, MmSharedCommit, MMVAD, MMVADKEY, _SUBSECTION::NextSubsection, NonPagedPool, NULL, PAGE_4K, PAGE_SHIFT, PAGE_SIZE, _SUBSECTION::PtesInSubsection, _MMEXTEND_INFO::ReferenceCount, ROUND_TO_PAGES64, _MMVAD::StartingVpn, _SUBSECTION::SubsectionBase, TRUE, _MMVAD::u, _MMPTE::u, _MMVAD::u2, _MMVAD::u4, UNLOCK_WS_UNSAFE, _SUBSECTION::UnusedPtes, and X64K.

Referenced by MmMapViewOfSection().

02273 : 02274 02275 This routine maps the specified physical section into the 02276 specified process's address space. 02277 02278 Arguments: 02279 02280 see MmMapViewOfSection above... 02281 02282 ControlArea - Supplies the control area for the section. 02283 02284 Process - Supplies the process pointer which is receiving the section. 02285 02286 ProtectionMask - Supplies the initial page protection-mask. 02287 02288 ReleasedWsMutex - Supplies FALSE. If the working set mutex is 02289 not held when returning this must be set to TRUE 02290 so the caller will not release the unheld mutex. 02291 02292 Note if this routine acquires the working set mutex 02293 it is always done unsafely as the address space mutex 02294 must be held on entry regardless. 02295 02296 Return Value: 02297 02298 Status of the map view operation. 02299 02300 Environment: 02301 02302 Kernel Mode, address creation mutex held. 02303 02304 --*/ 02305 02306 { 02307 PMMVAD Vad; 02308 PVOID StartingAddress; 02309 PVOID EndingAddress; 02310 BOOLEAN Attached; 02311 KIRQL OldIrql; 02312 PSUBSECTION Subsection; 02313 ULONG PteOffset; 02314 PMMPTE PointerPte; 02315 PMMPTE LastPte; 02316 MMPTE TempPte; 02317 ULONG_PTR Alignment; 02318 SIZE_T QuotaCharge; 02319 BOOLEAN ChargedQuota; 02320 PMMPTE TheFirstPrototypePte; 02321 PVOID CapturedStartingVa; 02322 ULONG CapturedCopyOnWrite; 02323 #if defined(_MIALT4K_) 02324 SIZE_T ViewSizeFor4k; 02325 #endif 02326 02327 Attached = FALSE; 02328 QuotaCharge = 0; 02329 ChargedQuota = FALSE; 02330 02331 if ((AllocationType & MEM_RESERVE) && 02332 (ControlArea->FilePointer == NULL)) { 02333 *ReleasedWsMutex = TRUE; 02334 return STATUS_INVALID_PARAMETER_9; 02335 } 02336 02337 // 02338 // Check to see if there is a purge operation ongoing for 02339 // this segment. 02340 // 02341 02342 if ((AllocationType & MEM_DOS_LIM) != 0) { 02343 if ((*CapturedBase == NULL) || 02344 (AllocationType & MEM_RESERVE)) { 02345 02346 // 02347 // If MEM_DOS_LIM is specified, the address to map the 02348 // view MUST be specified as well. 02349 // 02350 02351 *ReleasedWsMutex = TRUE; 02352 return STATUS_INVALID_PARAMETER_3; 02353 } 02354 Alignment = PAGE_SIZE; 02355 } else { 02356 Alignment = X64K; 02357 } 02358 02359 // 02360 // Check to see if a purge operation is in progress and if so, wait 02361 // for the purge to complete. In addition, up the count of mapped 02362 // views for this control area. 02363 // 02364 02365 if (MiCheckPurgeAndUpMapCount (ControlArea) == FALSE) { 02366 *ReleasedWsMutex = TRUE; 02367 return STATUS_INSUFFICIENT_RESOURCES; 02368 } 02369 02370 if (*CapturedViewSize == 0) { 02371 02372 SectionOffset->LowPart = SectionOffset->LowPart & ~((ULONG)Alignment - 1); 02373 *CapturedViewSize = (ULONG_PTR)(Section->SizeOfSection.QuadPart - 02374 SectionOffset->QuadPart); 02375 } else { 02376 *CapturedViewSize += SectionOffset->LowPart & (Alignment - 1); 02377 SectionOffset->LowPart = SectionOffset->LowPart & ~((ULONG)Alignment - 1); 02378 } 02379 02380 if ((LONG_PTR)*CapturedViewSize <= 0) { 02381 02382 // 02383 // Section offset or view size past size of section. 02384 // 02385 02386 LOCK_PFN (OldIrql); 02387 ControlArea->NumberOfMappedViews -= 1; 02388 ControlArea->NumberOfUserReferences -= 1; 02389 02390 // 02391 // Check to see if the control area (segment) should be deleted. 02392 // This routine releases the PFN lock. 02393 // 02394 02395 MiCheckControlArea (ControlArea, NULL, OldIrql); 02396 02397 *ReleasedWsMutex = TRUE; 02398 return STATUS_INVALID_VIEW_SIZE; 02399 } 02400 02401 // 02402 // Calculate the first prototype PTE field in the Vad. 02403 // 02404 02405 ASSERT (ControlArea->u.Flags.GlobalOnlyPerSession == 0); 02406 02407 Subsection = (PSUBSECTION)(ControlArea + 1); 02408 02409 SectionOffset->LowPart = SectionOffset->LowPart & ~((ULONG)Alignment - 1); 02410 PteOffset = (ULONG)(SectionOffset->QuadPart >> PAGE_SHIFT); 02411 02412 // 02413 // Make sure the PTEs are not in the extended part of the 02414 // segment. 02415 // 02416 02417 if (PteOffset >= ControlArea->Segment->TotalNumberOfPtes) { 02418 LOCK_PFN (OldIrql); 02419 ControlArea->NumberOfMappedViews -= 1; 02420 ControlArea->NumberOfUserReferences -= 1; 02421 02422 // 02423 // Check to see if the control area (segment) should be deleted. 02424 // This routine releases the PFN lock. 02425 // 02426 02427 MiCheckControlArea (ControlArea, NULL, OldIrql); 02428 02429 *ReleasedWsMutex = TRUE; 02430 return STATUS_INVALID_VIEW_SIZE; 02431 } 02432 02433 while (PteOffset >= Subsection->PtesInSubsection) { 02434 PteOffset -= Subsection->PtesInSubsection; 02435 Subsection = Subsection->NextSubsection; 02436 ASSERT (Subsection != NULL); 02437 } 02438 02439 TheFirstPrototypePte = &Subsection->SubsectionBase[PteOffset]; 02440 02441 // 02442 // Calculate the quota for the specified pages. 02443 // 02444 02445 if ((ControlArea->FilePointer == NULL) && 02446 (CommitSize != 0) && 02447 (ControlArea->Segment->NumberOfCommittedPages < 02448 ControlArea->Segment->TotalNumberOfPtes)) { 02449 02450 02451 ExAcquireFastMutexUnsafe (&MmSectionCommitMutex); 02452 02453 PointerPte = TheFirstPrototypePte; 02454 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize); 02455 02456 while (PointerPte < LastPte) { 02457 if (PointerPte->u.Long == 0) { 02458 QuotaCharge += 1; 02459 } 02460 PointerPte += 1; 02461 } 02462 ExReleaseFastMutexUnsafe (&MmSectionCommitMutex); 02463 } 02464 02465 CapturedStartingVa = (PVOID)Section->Address.StartingVpn; 02466 CapturedCopyOnWrite = Section->u.Flags.CopyOnWrite; 02467 LOCK_WS_UNSAFE (Process); 02468 02469 if ((*CapturedBase == NULL) && (CapturedStartingVa == NULL)) { 02470 02471 // 02472 // The section is not based, find an empty range. 02473 // This could raise an exception. 02474 02475 try { 02476 02477 // 02478 // Find a starting address on a 64k boundary. 02479 // 02480 02481 if ( AllocationType & MEM_TOP_DOWN ) { 02482 StartingAddress = MiFindEmptyAddressRangeDown ( 02483 *CapturedViewSize, 02484 (PVOID)((PCHAR)MM_HIGHEST_VAD_ADDRESS + 1), 02485 Alignment 02486 ); 02487 } else { 02488 StartingAddress = MiFindEmptyAddressRange (*CapturedViewSize, 02489 Alignment, 02490 (ULONG)ZeroBits); 02491 } 02492 02493 } except (EXCEPTION_EXECUTE_HANDLER) { 02494 02495 LOCK_PFN (OldIrql); 02496 ControlArea->NumberOfMappedViews -= 1; 02497 ControlArea->NumberOfUserReferences -= 1; 02498 02499 // 02500 // Check to see if the control area (segment) should be deleted. 02501 // This routine releases the PFN lock. 02502 // 02503 02504 MiCheckControlArea (ControlArea, Process, OldIrql); 02505 02506 return GetExceptionCode(); 02507 } 02508 02509 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 02510 *CapturedViewSize - 1L) | (PAGE_SIZE - 1L)); 02511 02512 if (ZeroBits > 0) { 02513 if (EndingAddress > (PVOID)((ULONG_PTR)MM_USER_ADDRESS_RANGE_LIMIT >> ZeroBits)) { 02514 LOCK_PFN (OldIrql); 02515 ControlArea->NumberOfMappedViews -= 1; 02516 ControlArea->NumberOfUserReferences -= 1; 02517 02518 // 02519 // Check to see if the control area (segment) should be deleted. 02520 // This routine releases the PFN lock. 02521 // 02522 02523 MiCheckControlArea (ControlArea, Process, OldIrql); 02524 02525 return STATUS_NO_MEMORY; 02526 } 02527 } 02528 02529 } else { 02530 02531 if (*CapturedBase == NULL) { 02532 02533 // 02534 // The section is based. 02535 // 02536 02537 StartingAddress = (PVOID)((PCHAR)CapturedStartingVa + 02538 SectionOffset->LowPart); 02539 } else { 02540 02541 StartingAddress = MI_ALIGN_TO_SIZE (*CapturedBase, Alignment); 02542 02543 } 02544 02545 // 02546 // Check to make sure the specified base address to ending address 02547 // is currently unused. 02548 // 02549 02550 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 02551 *CapturedViewSize - 1L) | (PAGE_SIZE - 1L)); 02552 02553 Vad = MiCheckForConflictingVad (StartingAddress, EndingAddress); 02554 if (Vad != (PMMVAD)NULL) { 02555 #if DBG 02556 MiDumpConflictingVad (StartingAddress, EndingAddress, Vad); 02557 #endif 02558 02559 LOCK_PFN (OldIrql); 02560 ControlArea->NumberOfMappedViews -= 1; 02561 ControlArea->NumberOfUserReferences -= 1; 02562 02563 // 02564 // Check to see if the control area (segment) should be deleted. 02565 // This routine releases the PFN lock. 02566 // 02567 02568 MiCheckControlArea (ControlArea, Process, OldIrql); 02569 02570 return STATUS_CONFLICTING_ADDRESSES; 02571 } 02572 } 02573 02574 // 02575 // An unoccupied address range has been found, build the virtual 02576 // address descriptor to describe this range. 02577 // 02578 02579 try { 02580 02581 Vad = ExAllocatePoolWithTag (NonPagedPool, 02582 sizeof(MMVAD), 02583 MMVADKEY); 02584 if (Vad == NULL) { 02585 ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES); 02586 } 02587 RtlZeroMemory (Vad, sizeof(MMVAD)); 02588 02589 Vad->StartingVpn = MI_VA_TO_VPN (StartingAddress); 02590 Vad->EndingVpn = MI_VA_TO_VPN (EndingAddress); 02591 Vad->FirstPrototypePte = TheFirstPrototypePte; 02592 02593 // 02594 // Set the protection in the PTE template field of the VAD. 02595 // 02596 02597 Vad->ControlArea = ControlArea; 02598 02599 Vad->u2.VadFlags2.Inherit = (InheritDisposition == ViewShare); 02600 Vad->u.VadFlags.Protection = ProtectionMask; 02601 Vad->u2.VadFlags2.CopyOnWrite = CapturedCopyOnWrite; 02602 02603 // 02604 // Note that for MEM_DOS_LIM significance is lost here, but those 02605 // files are not mapped MEM_RESERVE. 02606 // 02607 02608 Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16); 02609 02610 if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange)) { 02611 Vad->u.VadFlags.NoChange = 1; 02612 Vad->u2.VadFlags2.SecNoChange = 1; 02613 } 02614 if (AllocationType & MEM_RESERVE) { 02615 PMMEXTEND_INFO ExtendInfo; 02616 02617 ExAcquireFastMutexUnsafe (&MmSectionBasedMutex); 02618 ExtendInfo = ControlArea->Segment->ExtendInfo; 02619 if (ExtendInfo) { 02620 ExtendInfo->ReferenceCount += 1; 02621 if (ExtendInfo->CommittedSize < (UINT64)Section->SizeOfSection.QuadPart) { 02622 ExtendInfo->CommittedSize = (UINT64)Section->SizeOfSection.QuadPart; 02623 } 02624 } else { 02625 02626 ExtendInfo = ExAllocatePoolWithTag (NonPagedPool, 02627 sizeof(MMEXTEND_INFO), 02628 'xCmM'); 02629 if (ExtendInfo == NULL) { 02630 ExReleaseFastMutexUnsafe (&MmSectionBasedMutex); 02631 ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES); 02632 } 02633 ExtendInfo->ReferenceCount = 1; 02634 ExtendInfo->CommittedSize = ControlArea->Segment->SizeOfSegment; 02635 if (ExtendInfo->CommittedSize < (UINT64)Section->SizeOfSection.QuadPart) { 02636 ExtendInfo->CommittedSize = (UINT64)Section->SizeOfSection.QuadPart; 02637 } 02638 ControlArea->Segment->ExtendInfo = ExtendInfo; 02639 } 02640 ExReleaseFastMutexUnsafe (&MmSectionBasedMutex); 02641 Vad->u2.VadFlags2.ExtendableFile = 1; 02642 ASSERT (Vad->u4.ExtendedInfo == NULL); 02643 Vad->u4.ExtendedInfo = ExtendInfo; 02644 } 02645 02646 // 02647 // If the page protection is write-copy or execute-write-copy 02648 // charge for each page in the view as it may become private. 02649 // 02650 02651 if (MI_IS_PTE_PROTECTION_COPY_WRITE(ProtectionMask)) { 02652 Vad->u.VadFlags.CommitCharge = (BYTES_TO_PAGES ((PCHAR) EndingAddress - 02653 (PCHAR) StartingAddress)); 02654 } 02655 02656 // 02657 // If this is a page file backed section, charge the process's page 02658 // file quota as if all the pages have been committed. This solves 02659 // the problem when other processes commit all the pages and leave 02660 // only one process around who may not have been charged the proper 02661 // quota. This is solved by charging everyone the maximum quota. 02662 // 02663 // 02664 // commented out for commitment charging. 02665 // 02666 02667 #if 0 02668 if (ControlArea->FilePointer == NULL) { 02669 02670 // 02671 // This is a page file backed section. Charge for all the pages. 02672 // 02673 02674 Vad->CommitCharge += (BYTES_TO_PAGES ((PCHAR)EndingAddress - 02675 (PCHAR)StartingAddress)); 02676 } 02677 #endif 02678 02679 02680 PteOffset += (ULONG)(Vad->EndingVpn - Vad->StartingVpn); 02681 02682 if (PteOffset < Subsection->PtesInSubsection ) { 02683 Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset]; 02684 02685 } else { 02686 Vad->LastContiguousPte = &Subsection->SubsectionBase[ 02687 (Subsection->PtesInSubsection - 1) + 02688 Subsection->UnusedPtes]; 02689 } 02690 02691 if (QuotaCharge != 0) { 02692 if (MiChargeCommitment (QuotaCharge, Process) == FALSE) { 02693 ExRaiseStatus (STATUS_COMMITMENT_LIMIT); 02694 } 02695 ChargedQuota = TRUE; 02696 MM_TRACK_COMMIT (MM_DBG_COMMIT_MAPVIEW_DATA, QuotaCharge); 02697 } 02698 02699 ASSERT (Vad->FirstPrototypePte <= Vad->LastContiguousPte); 02700 MiInsertVad (Vad); 02701 02702 } except (EXCEPTION_EXECUTE_HANDLER) { 02703 02704 LOCK_PFN (OldIrql); 02705 ControlArea->NumberOfMappedViews -= 1; 02706 ControlArea->NumberOfUserReferences -= 1; 02707 02708 // 02709 // Check to see if the control area (segment) should be deleted. 02710 // This routine releases the PFN lock. 02711 // 02712 02713 MiCheckControlArea (ControlArea, Process, OldIrql); 02714 02715 if (Vad != (PMMVAD)NULL) { 02716 02717 // 02718 // The pool allocation succeeded, but the quota charge 02719 // in InsertVad failed, deallocate the pool and return 02720 // an error. 02721 // 02722 02723 ExFreePool (Vad); 02724 if (ChargedQuota) { 02725 MiReturnCommitment (QuotaCharge); 02726 MM_TRACK_COMMIT (MM_DBG_COMMIT_RETURN_MAPVIEW_DATA, QuotaCharge); 02727 } 02728 return GetExceptionCode(); 02729 } 02730 return STATUS_INSUFFICIENT_RESOURCES; 02731 } 02732 02733 *ReleasedWsMutex = TRUE; 02734 02735 #if DBG 02736 if (!(AllocationType & MEM_RESERVE)) { 02737 ASSERT(((ULONG_PTR)EndingAddress - (ULONG_PTR)StartingAddress) <= 02738 ROUND_TO_PAGES64(Section->Segment->SizeOfSegment)); 02739 } 02740 #endif //DBG 02741 02742 UNLOCK_WS_UNSAFE (Process); 02743 02744 // 02745 // If a commit size was specified, make sure those pages are committed. 02746 // 02747 02748 if (QuotaCharge != 0) { 02749 02750 ExAcquireFastMutexUnsafe (&MmSectionCommitMutex); 02751 02752 PointerPte = Vad->FirstPrototypePte; 02753 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize); 02754 TempPte = ControlArea->Segment->SegmentPteTemplate; 02755 02756 while (PointerPte < LastPte) { 02757 02758 if (PointerPte->u.Long == 0) { 02759 02760 MI_WRITE_INVALID_PTE (PointerPte, TempPte); 02761 } 02762 PointerPte += 1; 02763 } 02764 02765 ControlArea->Segment->NumberOfCommittedPages += QuotaCharge; 02766 02767 ASSERT (ControlArea->Segment->NumberOfCommittedPages <= 02768 ControlArea->Segment->TotalNumberOfPtes); 02769 MmSharedCommit += QuotaCharge; 02770 02771 ExReleaseFastMutexUnsafe (&MmSectionCommitMutex); 02772 } 02773 02774 #if defined(_MIALT4K_) 02775 02776 if (Process->Wow64Process != NULL) { 02777 02778 02779 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 02780 *CapturedViewSize - 1L) | (PAGE_4K - 1L)); 02781 02782 ViewSizeFor4k = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1L; 02783 02784 MiProtectMapFileFor4kPage (StartingAddress, 02785 ViewSizeFor4k, 02786 ProtectionMask, 02787 Vad->FirstPrototypePte, 02788 Process); 02789 } 02790 #endif 02791 02792 // 02793 // Update the current virtual size in the process header. 02794 // 02795 02796 *CapturedViewSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1L; 02797 Process->VirtualSize += *CapturedViewSize; 02798 02799 if (Process->VirtualSize > Process->PeakVirtualSize) { 02800 Process->PeakVirtualSize = Process->VirtualSize; 02801 } 02802 02803 *CapturedBase = StartingAddress; 02804 02805 return STATUS_SUCCESS; 02806 }

NTSTATUS MiMapViewOfDataSection IN PCONTROL_AREA  ControlArea,
IN PEPROCESS  Process,
IN PVOID *  CapturedBase,
IN PLARGE_INTEGER  SectionOffset,
IN PSIZE_T  CapturedViewSize,
IN PSECTION  Section,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG  ProtectionMask,
IN SIZE_T  CommitSize,
IN ULONG_PTR  ZeroBits,
IN ULONG  AllocationType,
OUT PBOOLEAN  ReleasedWsMutex
 

NTSTATUS MiMapViewOfImageSection IN PCONTROL_AREA  ControlArea,
IN PEPROCESS  Process,
IN PVOID *  CapturedBase,
IN PLARGE_INTEGER  SectionOffset,
IN PSIZE_T  CapturedViewSize,
IN PSECTION  Section,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG_PTR  ZeroBits,
IN SIZE_T  ImageCommitment,
IN OUT PBOOLEAN  ReleasedWsMutex
 

_ALPHA_

_WIN64

Definition at line 1567 of file mapview.c.

References ASSERT, CacheImageSymbols(), _MMVAD::ControlArea, DbgPrint, _MMVAD::EndingVpn, ExAcquireResourceExclusive, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExRaiseStatus(), ExReleaseResource, FALSE, FileName, _MMVAD::FirstPrototypePte, IMAGE_ADDRESSING_MODE_32BIT, _IMAGE_INFO::ImageAddressingMode, _IMAGE_INFO::ImageBase, _IMAGE_INFO::ImageSectionNumber, _IMAGE_INFO::ImageSelector, _IMAGE_INFO::ImageSize, KeEnterCriticalRegion, KeLeaveCriticalRegion, KernelMode, L, _MMVAD::LastContiguousPte, LOCK_PFN, LOCK_WS_UNSAFE, MI_64K_ALIGN, MI_VA_TO_VPN, MI_VPN_TO_VA, MiCheckControlArea(), MiCheckForConflictingVad, MiCheckPurgeAndUpMapCount(), MiFindEmptyAddressRange(), MiInsertVad(), MiProtectImageFileFor4kPage(), MiSetPageModified(), MM_ALLOCATION_FILLS_VAD, MM_DBG_WALK_VAD_TREE, MM_EXECUTE_WRITECOPY, MM_HIGHEST_VAD_ADDRESS, MMDB, MmHighestUserAddress, MmLoadedUserImageList, MMVAD, MMVADKEY, MmVirtualBias, NonPagedPool, NT_SUCCESS, NtGlobalFlag, NTSTATUS(), NULL, PAGE_SHIFT, PAGE_SIZE, _IMAGE_INFO::Properties, PsCallImageNotifyRoutines(), PsImageNotifyEnabled, PsInitialSystemProcess, PsLoadedModuleResource, RtlFreeAnsiString(), RtlImageNtHeader(), RtlUnicodeStringToAnsiString(), _MMVAD::StartingVpn, Status, _SUBSECTION::SubsectionBase, TRUE, _MMPTE::u, _MMVAD::u, _MMVAD::u2, UNLOCK_PFN, UNLOCK_WS_UNSAFE, USHORT, VadTreeWalk(), and X64K.

Referenced by MmMapViewOfSection().

01582 : 01583 01584 This routine maps the specified Image section into the 01585 specified process's address space. 01586 01587 Arguments: 01588 01589 see MmMapViewOfSection above... 01590 01591 ControlArea - Supplies the control area for the section. 01592 01593 Process - Supplies the process pointer which is receiving the section. 01594 01595 ReleasedWsMutex - Supplies FALSE. If the working set mutex is 01596 not held when returning this must be set to TRUE 01597 so the caller will not release the unheld mutex. 01598 01599 Note if this routine acquires the working set mutex 01600 it is always done unsafely as the address space mutex 01601 must be held on entry regardless. 01602 01603 Return Value: 01604 01605 Status of the map view operation. 01606 01607 Environment: 01608 01609 Kernel Mode, address creation mutex held. 01610 01611 --*/ 01612 01613 { 01614 PMMVAD Vad; 01615 PVOID StartingAddress; 01616 PVOID EndingAddress; 01617 BOOLEAN Attached; 01618 KIRQL OldIrql; 01619 PSUBSECTION Subsection; 01620 ULONG PteOffset; 01621 NTSTATUS ReturnedStatus; 01622 PMMPTE ProtoPte; 01623 PVOID BasedAddress; 01624 SIZE_T NeededViewSize; 01625 #if defined(_ALPHA_) 01626 ULONG_PTR Starting2gb; 01627 ULONG_PTR Ending2gb; 01628 ULONG_PTR BoundaryMask; 01629 LOGICAL AlignmentOk; 01630 #endif 01631 #if defined(_MIALT4K_) 01632 PMMPTE PointerAltPte; 01633 PMMPTE ProtoAltPte; 01634 MMPTE TempAltPte; 01635 PIMAGE_NT_HEADERS NtHeaders; 01636 ULONG ImageAlignment; 01637 #endif 01638 01639 Attached = FALSE; 01640 01641 // 01642 // Image file. 01643 // 01644 // Locate the first subsection (text) and create a virtual 01645 // address descriptor to map the entire image here. 01646 // 01647 01648 if (ControlArea->u.Flags.GlobalOnlyPerSession == 0) { 01649 Subsection = (PSUBSECTION)(ControlArea + 1); 01650 } 01651 else { 01652 Subsection = (PSUBSECTION)((PLARGE_CONTROL_AREA)ControlArea + 1); 01653 } 01654 01655 if (ControlArea->u.Flags.ImageMappedInSystemSpace) { 01656 01657 if (KeGetPreviousMode() != KernelMode) { 01658 01659 // 01660 // Mapping in system space as a driver, hence copy on write does 01661 // not work. Don't allow user processes to map the image. 01662 // 01663 01664 *ReleasedWsMutex = TRUE; 01665 return STATUS_CONFLICTING_ADDRESSES; 01666 } 01667 } 01668 01669 // 01670 // Check to see if a purge operation is in progress and if so, wait 01671 // for the purge to complete. In addition, up the count of mapped 01672 // views for this control area. 01673 // 01674 01675 if (MiCheckPurgeAndUpMapCount (ControlArea) == FALSE) { 01676 *ReleasedWsMutex = TRUE; 01677 return STATUS_INSUFFICIENT_RESOURCES; 01678 } 01679 01680 // 01681 // Capture the based address to the stack, to prevent page faults. 01682 // 01683 01684 BasedAddress = ControlArea->Segment->BasedAddress; 01685 01686 if (*CapturedViewSize == 0) { 01687 *CapturedViewSize = 01688 (ULONG_PTR)(Section->SizeOfSection.QuadPart - SectionOffset->QuadPart); 01689 } 01690 01691 LOCK_WS_UNSAFE (Process); 01692 01693 ReturnedStatus = STATUS_SUCCESS; 01694 01695 // 01696 // Determine if a specific base was specified. 01697 // 01698 01699 if (*CapturedBase != NULL) { 01700 01701 // 01702 // Captured base is not NULL. 01703 // 01704 // Check to make sure the specified address range is currently unused 01705 // and within the user address space. 01706 // 01707 01708 Vad = (PMMVAD)1; 01709 StartingAddress = MI_64K_ALIGN(*CapturedBase); 01710 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 01711 *CapturedViewSize - 1) | (PAGE_SIZE - 1)); 01712 01713 if ((StartingAddress <= MM_HIGHEST_VAD_ADDRESS) && 01714 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) - 01715 (ULONG_PTR)StartingAddress >= *CapturedViewSize) && 01716 01717 (EndingAddress <= MM_HIGHEST_VAD_ADDRESS)) { 01718 01719 Vad = MiCheckForConflictingVad (StartingAddress, EndingAddress); 01720 } 01721 01722 if (Vad != NULL) { 01723 #if DBG 01724 if (Vad != (PMMVAD)1) { 01725 MiDumpConflictingVad (StartingAddress, EndingAddress, Vad); 01726 } 01727 #endif 01728 01729 LOCK_PFN (OldIrql); 01730 ControlArea->NumberOfMappedViews -= 1; 01731 ControlArea->NumberOfUserReferences -= 1; 01732 01733 // 01734 // Check to see if the control area (segment) should be deleted. 01735 // This routine releases the PFN lock. 01736 // 01737 01738 MiCheckControlArea (ControlArea, Process, OldIrql); 01739 return STATUS_CONFLICTING_ADDRESSES; 01740 } 01741 01742 // 01743 // A conflicting VAD was not found and the specified address range is 01744 // within the user address space. If the image will not reside at its 01745 // base address, then set a special return status. 01746 // 01747 01748 if (((ULONG_PTR)StartingAddress + 01749 (ULONG_PTR)MI_64K_ALIGN(SectionOffset->LowPart)) != (ULONG_PTR)BasedAddress) { 01750 ReturnedStatus = STATUS_IMAGE_NOT_AT_BASE; 01751 } 01752 01753 } else { 01754 01755 // 01756 // Captured base is NULL. 01757 // 01758 // If the captured view size is greater than the largest size that 01759 // can fit in the user address space, then it is not possible to map 01760 // the image. 01761 // 01762 01763 if ((PVOID)*CapturedViewSize > MM_HIGHEST_VAD_ADDRESS) { 01764 LOCK_PFN (OldIrql); 01765 ControlArea->NumberOfMappedViews -= 1; 01766 ControlArea->NumberOfUserReferences -= 1; 01767 01768 // 01769 // Check to see if the control area (segment) should be deleted. 01770 // This routine releases the PFN lock. 01771 // 01772 01773 MiCheckControlArea (ControlArea, Process, OldIrql); 01774 return STATUS_NO_MEMORY; 01775 } 01776 01777 // 01778 // Check to make sure the specified address range is currently unused 01779 // and within the user address space. 01780 // 01781 01782 StartingAddress = (PVOID)((ULONG_PTR)BasedAddress + 01783 (ULONG_PTR)MI_64K_ALIGN(SectionOffset->LowPart)); 01784 01785 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 01786 *CapturedViewSize - 1) | (PAGE_SIZE - 1)); 01787 01788 Vad = (PMMVAD)1; 01789 NeededViewSize = *CapturedViewSize; 01790 01791 #if defined(_ALPHA_) 01792 01793 #if defined(_AXP64_) 01794 #define BOUNDARY ((LONG_PTR)_2gb) 01795 #else 01796 #define BOUNDARY ((ULONG_PTR)_2gb) 01797 #endif 01798 01799 // 01800 // Alpha images cannot span 2GB boundaries with the current compiler 01801 // generated branch instructions. If a spanning image is detected, it 01802 // must be relocated. 01803 // 01804 01805 BoundaryMask = (ULONG_PTR)~(BOUNDARY-1); 01806 01807 Starting2gb = (ULONG_PTR)StartingAddress & BoundaryMask; 01808 Ending2gb = (ULONG_PTR)EndingAddress & BoundaryMask; 01809 01810 AlignmentOk = TRUE; 01811 01812 if (Starting2gb != Ending2gb) { 01813 AlignmentOk = FALSE; 01814 if (Starting2gb + 1 == Ending2gb) { 01815 if (((ULONG_PTR)EndingAddress & (BOUNDARY-1)) == 0) { 01816 AlignmentOk = TRUE; 01817 } 01818 } 01819 } 01820 01821 if (AlignmentOk == FALSE) { 01822 01823 // 01824 // Find twice the required size so that it can be placed correctly. 01825 // 01826 01827 NeededViewSize = *CapturedViewSize * 2 + X64K; 01828 } 01829 else 01830 #endif 01831 01832 if ((StartingAddress >= MM_LOWEST_USER_ADDRESS) && 01833 (StartingAddress <= MM_HIGHEST_VAD_ADDRESS) && 01834 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) - 01835 (ULONG_PTR)StartingAddress >= *CapturedViewSize) && 01836 01837 (EndingAddress <= MM_HIGHEST_VAD_ADDRESS)) { 01838 01839 Vad = MiCheckForConflictingVad (StartingAddress, EndingAddress); 01840 } 01841 01842 // 01843 // If the VAD address is not NULL, then a conflict was discovered. 01844 // Attempt to select another address range in which to map the image. 01845 // 01846 01847 if (Vad != (PMMVAD)NULL) { 01848 01849 // 01850 // The image could not be mapped at its natural base address 01851 // try to find another place to map it. 01852 // 01853 #if DBG 01854 if (Vad != (PMMVAD)1) { 01855 MiDumpConflictingVad (StartingAddress, EndingAddress, Vad); 01856 } 01857 #endif 01858 01859 // 01860 // If the system has been biased to an alternate base address to 01861 // allow 3gb of user address space, then make sure the high order 01862 // address bit is zero. 01863 // 01864 01865 #if defined(_X86_) 01866 01867 if ((MmVirtualBias != 0) && 01868 (ZeroBits == 0)) { 01869 ZeroBits = 1; 01870 } 01871 #endif 01872 01873 ReturnedStatus = STATUS_IMAGE_NOT_AT_BASE; 01874 try { 01875 01876 // 01877 // Find a starting address on a 64k boundary. 01878 // 01879 01880 StartingAddress = MiFindEmptyAddressRange (NeededViewSize, 01881 X64K, 01882 (ULONG)ZeroBits); 01883 01884 01885 } except (EXCEPTION_EXECUTE_HANDLER) { 01886 LOCK_PFN (OldIrql); 01887 ControlArea->NumberOfMappedViews -= 1; 01888 ControlArea->NumberOfUserReferences -= 1; 01889 01890 // 01891 // Check to see if the control area (segment) should be deleted. 01892 // This routine releases the PFN lock. 01893 // 01894 01895 MiCheckControlArea (ControlArea, Process, OldIrql); 01896 01897 return GetExceptionCode(); 01898 } 01899 01900 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 01901 *CapturedViewSize - 1) | (PAGE_SIZE - 1)); 01902 01903 #if defined(_ALPHA_) 01904 01905 if (AlignmentOk == FALSE) { 01906 Starting2gb = (ULONG_PTR)StartingAddress & ~(BOUNDARY-1); 01907 Ending2gb = (ULONG_PTR)EndingAddress & ~(BOUNDARY-1); 01908 01909 if (Starting2gb != Ending2gb) { 01910 01911 // 01912 // Not in the same 2gb. Up the start to a 2gb boundary. 01913 // 01914 01915 StartingAddress = (PVOID)Ending2gb; 01916 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 01917 *CapturedViewSize - 1) | (PAGE_SIZE - 1)); 01918 } 01919 } 01920 #endif 01921 01922 } 01923 } 01924 01925 // 01926 // Allocate and initialize a VAD for the specified address range. 01927 // 01928 01929 Vad = ExAllocatePoolWithTag (NonPagedPool, sizeof(MMVAD), MMVADKEY); 01930 try { 01931 if (Vad == NULL) { 01932 ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES); 01933 } 01934 01935 RtlZeroMemory (Vad, sizeof(MMVAD)); 01936 Vad->StartingVpn = MI_VA_TO_VPN (StartingAddress); 01937 Vad->EndingVpn = MI_VA_TO_VPN (EndingAddress); 01938 Vad->u2.VadFlags2.Inherit = (InheritDisposition == ViewShare); 01939 Vad->u.VadFlags.ImageMap = 1; 01940 01941 // 01942 // Set the protection in the VAD as EXECUTE_WRITE_COPY. 01943 // 01944 01945 Vad->u.VadFlags.Protection = MM_EXECUTE_WRITECOPY; 01946 Vad->ControlArea = ControlArea; 01947 01948 // 01949 // Set the first prototype PTE field in the Vad. 01950 // 01951 01952 SectionOffset->LowPart = SectionOffset->LowPart & ~(X64K - 1); 01953 PteOffset = (ULONG)(SectionOffset->QuadPart >> PAGE_SHIFT); 01954 01955 Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset]; 01956 Vad->LastContiguousPte = MM_ALLOCATION_FILLS_VAD; 01957 01958 // 01959 // NOTE: the full commitment is charged even if a partial map of an 01960 // image is being done. This saves from having to run through the 01961 // entire image (via prototype PTEs) and calculate the charge on 01962 // a per page basis for the partial map. 01963 // 01964 01965 Vad->u.VadFlags.CommitCharge = (SIZE_T)ImageCommitment; // ****** temp 01966 01967 ASSERT (Vad->FirstPrototypePte <= Vad->LastContiguousPte); 01968 01969 MiInsertVad (Vad); 01970 01971 } except (EXCEPTION_EXECUTE_HANDLER) { 01972 LOCK_PFN (OldIrql); 01973 ControlArea->NumberOfMappedViews -= 1; 01974 ControlArea->NumberOfUserReferences -= 1; 01975 01976 // 01977 // Check to see if the control area (segment) should be deleted. 01978 // This routine releases the PFN lock. 01979 // 01980 01981 MiCheckControlArea (ControlArea, Process, OldIrql); 01982 01983 if (Vad != (PMMVAD)NULL) { 01984 01985 // 01986 // The pool allocation succeeded, but the quota charge 01987 // in InsertVad failed, deallocate the pool and return 01988 // an error. 01989 // 01990 01991 ExFreePool (Vad); 01992 return GetExceptionCode(); 01993 } 01994 01995 return STATUS_INSUFFICIENT_RESOURCES; 01996 } 01997 01998 *CapturedViewSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1L; 01999 *CapturedBase = StartingAddress; 02000 02001 #if DBG 02002 if (MmDebug & MM_DBG_WALK_VAD_TREE) { 02003 DbgPrint("mapped image section vads\n"); 02004 VadTreeWalk(Process->VadRoot); 02005 } 02006 #endif 02007 02008 // 02009 // Update the current virtual size in the process header. 02010 // 02011 02012 Process->VirtualSize += *CapturedViewSize; 02013 02014 if (Process->VirtualSize > Process->PeakVirtualSize) { 02015 Process->PeakVirtualSize = Process->VirtualSize; 02016 } 02017 02018 if (ControlArea->u.Flags.FloppyMedia) { 02019 02020 *ReleasedWsMutex = TRUE; 02021 UNLOCK_WS_UNSAFE (Process); 02022 02023 // 02024 // The image resides on a floppy disk, in-page all 02025 // pages from the floppy and mark them as modified so 02026 // they migrate to the paging file rather than reread 02027 // them from the floppy disk which may have been removed. 02028 // 02029 02030 ProtoPte = Vad->FirstPrototypePte; 02031 02032 // 02033 // This could get an in-page error from the floppy. 02034 // 02035 02036 while (StartingAddress < EndingAddress) { 02037 02038 // 02039 // If the prototype PTE is valid, transition or 02040 // in prototype PTE format, bring the page into 02041 // memory and set the modified bit. 02042 // 02043 02044 if ((ProtoPte->u.Hard.Valid == 1) || 02045 (ProtoPte->u.Soft.Prototype == 1) || 02046 (ProtoPte->u.Soft.Transition == 1)) { 02047 02048 try { 02049 02050 MiSetPageModified (StartingAddress); 02051 02052 } except (EXCEPTION_EXECUTE_HANDLER) { 02053 02054 // 02055 // An in page error must have occurred touching the image, 02056 // ignore the error and continue to the next page. 02057 // 02058 02059 NOTHING; 02060 } 02061 } 02062 ProtoPte += 1; 02063 StartingAddress = (PVOID)((PCHAR)StartingAddress + PAGE_SIZE); 02064 } 02065 } 02066 02067 if (!*ReleasedWsMutex) { 02068 *ReleasedWsMutex = TRUE; 02069 UNLOCK_WS_UNSAFE (Process); 02070 } 02071 02072 if (NT_SUCCESS(ReturnedStatus)) { 02073 02074 02075 // 02076 // Check to see if this image is for the architecture of the current 02077 // machine. 02078 // 02079 02080 if (ControlArea->Segment->ImageInformation->ImageContainsCode && 02081 ((ControlArea->Segment->ImageInformation->Machine < 02082 USER_SHARED_DATA->ImageNumberLow) || 02083 (ControlArea->Segment->ImageInformation->Machine > 02084 USER_SHARED_DATA->ImageNumberHigh) 02085 ) 02086 ) { 02087 #if defined (_WIN64) 02088 02089 // 02090 // If this is a wow64 process, allow i386 images 02091 // 02092 02093 if (!Process->Wow64Process || 02094 ControlArea->Segment->ImageInformation->Machine != IMAGE_FILE_MACHINE_I386) { 02095 return STATUS_IMAGE_MACHINE_TYPE_MISMATCH; 02096 } 02097 #else 02098 return STATUS_IMAGE_MACHINE_TYPE_MISMATCH; 02099 #endif 02100 } 02101 02102 StartingAddress = MI_VPN_TO_VA (Vad->StartingVpn); 02103 02104 if (PsImageNotifyEnabled) { 02105 02106 IMAGE_INFO ImageInfo; 02107 02108 if ( (StartingAddress < MmHighestUserAddress) && 02109 Process->UniqueProcessId && 02110 Process != PsInitialSystemProcess ) { 02111 02112 ImageInfo.Properties = 0; 02113 ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT; 02114 ImageInfo.ImageBase = StartingAddress; 02115 ImageInfo.ImageSize = *CapturedViewSize; 02116 ImageInfo.ImageSelector = 0; 02117 ImageInfo.ImageSectionNumber = 0; 02118 PsCallImageNotifyRoutines( 02119 (PUNICODE_STRING) &ControlArea->FilePointer->FileName, 02120 Process->UniqueProcessId, 02121 &ImageInfo 02122 ); 02123 } 02124 } 02125 02126 if ((NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD) && 02127 (ControlArea->u.Flags.Image) && 02128 (ReturnedStatus != STATUS_IMAGE_NOT_AT_BASE)) { 02129 if (ControlArea->u.Flags.DebugSymbolsLoaded == 0) { 02130 if (CacheImageSymbols (StartingAddress)) { 02131 02132 // 02133 // TEMP TEMP TEMP rip out when debugger converted 02134 // 02135 02136 PUNICODE_STRING FileName; 02137 ANSI_STRING AnsiName; 02138 NTSTATUS Status; 02139 02140 LOCK_PFN (OldIrql); 02141 ControlArea->u.Flags.DebugSymbolsLoaded = 1; 02142 UNLOCK_PFN (OldIrql); 02143 02144 FileName = (PUNICODE_STRING)&ControlArea->FilePointer->FileName; 02145 if (FileName->Length != 0 && (NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD)) { 02146 PLIST_ENTRY Head, Next; 02147 PLDR_DATA_TABLE_ENTRY Entry; 02148 02149 KeEnterCriticalRegion(); 02150 ExAcquireResourceExclusive (&PsLoadedModuleResource, TRUE); 02151 Head = &MmLoadedUserImageList; 02152 Next = Head->Flink; 02153 while (Next != Head) { 02154 Entry = CONTAINING_RECORD( Next, 02155 LDR_DATA_TABLE_ENTRY, 02156 InLoadOrderLinks 02157 ); 02158 if (Entry->DllBase == StartingAddress) { 02159 Entry->LoadCount += 1; 02160 break; 02161 } 02162 Next = Next->Flink; 02163 } 02164 02165 if (Next == Head) { 02166 Entry = ExAllocatePoolWithTag( NonPagedPool, 02167 sizeof( *Entry ) + 02168 FileName->Length + 02169 sizeof( UNICODE_NULL ), 02170 MMDB 02171 ); 02172 if (Entry != NULL) { 02173 PIMAGE_NT_HEADERS NtHeaders; 02174 02175 RtlZeroMemory (Entry, sizeof(*Entry)); 02176 02177 try { 02178 NtHeaders = RtlImageNtHeader (StartingAddress); 02179 if (NtHeaders != NULL) { 02180 #if defined(_WIN64) 02181 if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { 02182 Entry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; 02183 Entry->CheckSum = NtHeaders->OptionalHeader.CheckSum; 02184 } 02185 else { 02186 PIMAGE_NT_HEADERS32 NtHeaders32 = (PIMAGE_NT_HEADERS32)NtHeaders; 02187 02188 Entry->SizeOfImage = NtHeaders32->OptionalHeader.SizeOfImage; 02189 Entry->CheckSum = NtHeaders32->OptionalHeader.CheckSum; 02190 } 02191 #else 02192 Entry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; 02193 Entry->CheckSum = NtHeaders->OptionalHeader.CheckSum; 02194 #endif 02195 } 02196 } except (EXCEPTION_EXECUTE_HANDLER) { 02197 NOTHING; 02198 } 02199 02200 Entry->DllBase = StartingAddress; 02201 Entry->FullDllName.Buffer = (PWSTR)(Entry+1); 02202 Entry->FullDllName.Length = FileName->Length; 02203 Entry->FullDllName.MaximumLength = (USHORT) 02204 (Entry->FullDllName.Length + sizeof( UNICODE_NULL )); 02205 RtlMoveMemory( Entry->FullDllName.Buffer, 02206 FileName->Buffer, 02207 FileName->Length 02208 ); 02209 Entry->FullDllName.Buffer[ Entry->FullDllName.Length / sizeof( WCHAR )] = UNICODE_NULL; 02210 Entry->LoadCount = 1; 02211 InsertTailList( &MmLoadedUserImageList, 02212 &Entry->InLoadOrderLinks 02213 ); 02214 InitializeListHead( &Entry->InInitializationOrderLinks ); 02215 InitializeListHead( &Entry->InMemoryOrderLinks ); 02216 } 02217 } 02218 02219 ExReleaseResource (&PsLoadedModuleResource); 02220 KeLeaveCriticalRegion(); 02221 } 02222 02223 Status = RtlUnicodeStringToAnsiString( &AnsiName, 02224 FileName, 02225 TRUE ); 02226 02227 if (NT_SUCCESS( Status)) { 02228 DbgLoadImageSymbols( &AnsiName, 02229 StartingAddress, 02230 (ULONG_PTR)Process 02231 ); 02232 RtlFreeAnsiString( &AnsiName ); 02233 } 02234 } 02235 } 02236 } 02237 } 02238 02239 #if defined(_MIALT4K_) 02240 02241 if (Process->Wow64Process != NULL) { 02242 02243 MiProtectImageFileFor4kPage(StartingAddress, 02244 *CapturedViewSize, 02245 Vad->FirstPrototypePte, 02246 Process); 02247 } 02248 02249 #endif 02250 02251 return ReturnedStatus; 02252 02253 }

NTSTATUS MiMapViewOfImageSection IN PCONTROL_AREA  ControlArea,
IN PEPROCESS  Process,
IN PVOID *  CapturedBase,
IN PLARGE_INTEGER  SectionOffset,
IN PSIZE_T  CapturedViewSize,
IN PSECTION  Section,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG_PTR  ZeroBits,
IN SIZE_T  ImageCommitment,
OUT PBOOLEAN  ReleasedWsMutex
 

NTSTATUS MiMapViewOfPhysicalSection IN PCONTROL_AREA  ControlArea,
IN PEPROCESS  Process,
IN PVOID *  CapturedBase,
IN PLARGE_INTEGER  SectionOffset,
IN PSIZE_T  CapturedViewSize,
IN ULONG  ProtectionMask,
IN ULONG_PTR  ZeroBits,
IN ULONG  AllocationType,
IN BOOLEAN  WriteCombined,
OUT PBOOLEAN  ReleasedWsMutex
 

Definition at line 1028 of file mapview.c.

References AggregatePages(), ASSERT, CONSISTENCY_LOCK_PFN, CONSISTENCY_UNLOCK_PFN, _MMVAD::ControlArea, DbgPrint, _MMVAD::EndingVpn, _MI_PHYSICAL_VIEW::EndVa, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExRaiseStatus(), FALSE, _MMVAD::FirstPrototypePte, KeFlushEntireTb(), KeInvalidateAllCaches(), L, _MMVAD::LastContiguousPte, _MI_PHYSICAL_VIEW::ListEntry, LOCK_AWE, LOCK_PFN, LOCK_PFN2, LOCK_WS_UNSAFE, MaximumAlignment(), MI_64K_ALIGN, MI_CONVERT_PHYSICAL_BUS_TO_PFN, MI_GET_USED_PTES_FROM_HANDLE, MI_GET_USED_PTES_HANDLE, MI_INCREMENT_USED_PTES_BY_HANDLE, MI_IS_CACHING_DISABLED, MI_MAKE_VALID_PTE, MI_PFN_ELEMENT, MI_PHYSICAL_VIEW_KEY, MI_SET_PTE_DIRTY, MI_SET_PTE_WRITE_COMBINE, MI_VA_TO_VPN, MI_WRITE_VALID_PTE, MiCheckForConflictingVad, MiFindEmptyAddressRange(), MiGetPdeAddress, MiGetPpeAddress, MiGetPteAddress, MiGetSubsectionAddressForPte, MiGetVirtualAddressMappedByPte, MiInsertVad(), MiIsPteOnPdeBoundary, MiIsPteOnPpeBoundary, MiMakePdeExistAndMakeValid(), MiMakePpeExistAndMakeValid, MiProtoAddressForPte, MiSweepCacheMachineDependent(), MiWriteCombiningPtes, MM_USER_ADDRESS_RANGE_LIMIT, MM_VA_MAPPED_BY_PDE, MM_VIEW_UNMAP, MmPageSizeInfo, MMPPTE_NAME, MMVAD, MMVADKEY, MmWriteCombined, NonPagedPool, NULL, PAGE_SHIFT, PAGE_SIZE, _SUBSECTION::StartingSector, _MMVAD::StartingVpn, _MI_PHYSICAL_VIEW::StartVa, TRUE, _SUBSECTION::u, _MMPTE::u, _MMVAD::u, _MMPFN::u2, _MMVAD::u2, _MMVAD::u4, UNLOCK_AWE, UNLOCK_PFN, UNLOCK_PFN2, UNLOCK_WS_UNSAFE, _MI_PHYSICAL_VIEW::Vad, X64K, and ZeroPte.

Referenced by MmMapViewOfSection().

01043 : 01044 01045 This routine maps the specified physical section into the 01046 specified process's address space. 01047 01048 Arguments: 01049 01050 see MmMapViewOfSection above... 01051 01052 ControlArea - Supplies the control area for the section. 01053 01054 Process - Supplies the process pointer which is receiving the section. 01055 01056 ProtectionMask - Supplies the initial page protection-mask. 01057 01058 ReleasedWsMutex - Supplies FALSE. If the working set mutex is 01059 not held when returning this must be set to TRUE 01060 so the caller will not release the unheld mutex. 01061 01062 Note if this routine acquires the working set mutex 01063 it is always done unsafely as the address space mutex 01064 must be held on entry regardless. 01065 01066 Return Value: 01067 01068 Status of the map view operation. 01069 01070 Environment: 01071 01072 Kernel Mode, address creation mutex held. 01073 01074 --*/ 01075 01076 { 01077 PMMVAD Vad; 01078 PVOID StartingAddress; 01079 PVOID EndingAddress; 01080 KIRQL OldIrql; 01081 KIRQL OldIrql2; 01082 PMMPTE PointerPpe; 01083 PMMPTE PointerPde; 01084 PMMPTE PointerPte; 01085 PMMPTE LastPte; 01086 MMPTE TempPte; 01087 PMMPFN Pfn2; 01088 SIZE_T PhysicalViewSize; 01089 ULONG_PTR Alignment; 01090 PVOID UsedPageTableHandle; 01091 PVOID UsedPageDirectoryHandle; 01092 PMI_PHYSICAL_VIEW PhysicalView; 01093 #ifdef LARGE_PAGES 01094 ULONG size; 01095 PMMPTE protoPte; 01096 ULONG pageSize; 01097 PSUBSECTION Subsection; 01098 ULONG EmPageSize; 01099 #endif //LARGE_PAGES 01100 01101 // 01102 // Physical memory section. 01103 // 01104 01105 // 01106 // If running on an R4000 and MEM_LARGE_PAGES is specified, 01107 // set up the PTEs as a series of pointers to the same 01108 // prototype PTE. This prototype PTE will reference a subsection 01109 // that indicates large pages should be used. 01110 // 01111 // The R4000 supports pages of 4k, 16k, 64k, etc (powers of 4). 01112 // Since the TB supports 2 entries, sizes of 8k, 32k etc can 01113 // be mapped by 2 LargePages in a single TB entry. These 2 entries 01114 // are maintained in the subsection structure pointed to by the 01115 // prototype PTE. 01116 // 01117 01118 if (AllocationType & MEM_RESERVE) { 01119 *ReleasedWsMutex = TRUE; 01120 return STATUS_INVALID_PARAMETER_9; 01121 } 01122 Alignment = X64K; 01123 LOCK_WS_UNSAFE (Process); 01124 01125 #ifdef LARGE_PAGES 01126 if (AllocationType & MEM_LARGE_PAGES) { 01127 01128 // 01129 // Determine the page size and the required alignment. 01130 // 01131 01132 if ((SectionOffset->LowPart & (X64K - 1)) != 0) { 01133 return STATUS_INVALID_PARAMETER_9; 01134 } 01135 01136 size = (*CapturedViewSize - 1) >> (PAGE_SHIFT + 1); 01137 pageSize = PAGE_SIZE; 01138 01139 while (size != 0) { 01140 size = size >> 2; 01141 pageSize = pageSize << 2; 01142 } 01143 01144 Alignment = pageSize << 1; 01145 if (Alignment < MM_VA_MAPPED_BY_PDE) { 01146 Alignment = MM_VA_MAPPED_BY_PDE; 01147 } 01148 01149 #if defined(_IA64_) 01150 01151 // 01152 // Convert pageSize to the EM page-size field format. 01153 // 01154 01155 EmPageSize = 0; 01156 size = pageSize - 1 ; 01157 01158 while (size) { 01159 size = size >> 1; 01160 EmPageSize += 1; 01161 } 01162 01163 if (*CapturedViewSize > pageSize) { 01164 01165 if (MmPageSizeInfo & (pageSize << 1)) { 01166 01167 // 01168 // if larger page size is supported in the implementation 01169 // 01170 01171 pageSize = pageSize << 1; 01172 EmPageSize += 1; 01173 01174 } 01175 else { 01176 01177 EmPageSize = EmPageSize | pageSize; 01178 01179 } 01180 } 01181 01182 pageSize = EmPageSize; 01183 #endif 01184 01185 } 01186 #endif //LARGE_PAGES 01187 01188 if (*CapturedBase == NULL) { 01189 01190 // 01191 // Attempt to locate address space. This could raise an 01192 // exception. 01193 // 01194 01195 try { 01196 01197 // 01198 // Find a starting address on a 64k boundary. 01199 // 01200 #ifdef i386 01201 ASSERT (SectionOffset->HighPart == 0); 01202 #endif 01203 01204 #ifdef LARGE_PAGES 01205 if (AllocationType & MEM_LARGE_PAGES) { 01206 PhysicalViewSize = Alignment; 01207 } else { 01208 #endif //LARGE_PAGES 01209 01210 PhysicalViewSize = *CapturedViewSize + 01211 (SectionOffset->LowPart & (X64K - 1)); 01212 #ifdef LARGE_PAGES 01213 } 01214 #endif //LARGE_PAGES 01215 01216 StartingAddress = MiFindEmptyAddressRange (PhysicalViewSize, 01217 Alignment, 01218 (ULONG)ZeroBits); 01219 01220 } except (EXCEPTION_EXECUTE_HANDLER) { 01221 01222 return GetExceptionCode(); 01223 } 01224 01225 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 01226 PhysicalViewSize - 1L) | (PAGE_SIZE - 1L)); 01227 StartingAddress = (PVOID)((ULONG_PTR)StartingAddress + 01228 (SectionOffset->LowPart & (X64K - 1))); 01229 01230 if (ZeroBits > 0) { 01231 if (EndingAddress > (PVOID)((ULONG_PTR)MM_USER_ADDRESS_RANGE_LIMIT >> ZeroBits)) { 01232 return STATUS_NO_MEMORY; 01233 } 01234 } 01235 01236 } else { 01237 01238 // 01239 // Check to make sure the specified base address to ending address 01240 // is currently unused. 01241 // 01242 01243 StartingAddress = (PVOID)((ULONG_PTR)MI_64K_ALIGN(*CapturedBase) + 01244 (SectionOffset->LowPart & (X64K - 1))); 01245 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress + 01246 *CapturedViewSize - 1L) | (PAGE_SIZE - 1L)); 01247 01248 #ifdef LARGE_PAGES 01249 if (AllocationType & MEM_LARGE_PAGES) { 01250 if (((ULONG_PTR)StartingAddress & (Alignment - 1)) != 0) { 01251 return STATUS_CONFLICTING_ADDRESSES; 01252 } 01253 EndingAddress = (PVOID)((PCHAR)StartingAddress + Alignment); 01254 } 01255 #endif //LARGE_PAGES 01256 01257 Vad = MiCheckForConflictingVad (StartingAddress, EndingAddress); 01258 01259 if (Vad != (PMMVAD)NULL) { 01260 #if DBG 01261 MiDumpConflictingVad (StartingAddress, EndingAddress, Vad); 01262 #endif 01263 01264 return STATUS_CONFLICTING_ADDRESSES; 01265 } 01266 } 01267 01268 // 01269 // An unoccupied address range has been found, build the virtual 01270 // address descriptor to describe this range. 01271 // 01272 01273 #ifdef LARGE_PAGES 01274 if (AllocationType & MEM_LARGE_PAGES) { 01275 // 01276 // Allocate a subsection and 4 prototype PTEs to hold 01277 // the information for the large pages. 01278 // 01279 01280 Subsection = ExAllocatePoolWithTag (NonPagedPool, 01281 sizeof(SUBSECTION) + (4 * sizeof(MMPTE)), 01282 MMPPTE_NAME); 01283 if (Subsection == NULL) { 01284 return STATUS_INSUFFICIENT_RESOURCES; 01285 } 01286 } 01287 #endif //LARGE_PAGES 01288 01289 // 01290 // Establish an exception handler and attempt to allocate 01291 // the pool and charge quota. Note that the InsertVad routine 01292 // will also charge quota which could raise an exception. 01293 // 01294 01295 try { 01296 01297 PhysicalView = (PMI_PHYSICAL_VIEW)ExAllocatePoolWithTag (NonPagedPool, 01298 sizeof(MI_PHYSICAL_VIEW), 01299 MI_PHYSICAL_VIEW_KEY); 01300 if (PhysicalView == NULL) { 01301 ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES); 01302 } 01303 01304 Vad = (PMMVAD)ExAllocatePoolWithTag (NonPagedPool, 01305 sizeof(MMVAD), 01306 MMVADKEY); 01307 if (Vad == NULL) { 01308 ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES); 01309 } 01310 01311 PhysicalView->Vad = Vad; 01312 PhysicalView->StartVa = StartingAddress; 01313 PhysicalView->EndVa = EndingAddress; 01314 01315 RtlZeroMemory (Vad, sizeof(MMVAD)); 01316 Vad->StartingVpn = MI_VA_TO_VPN (StartingAddress); 01317 Vad->EndingVpn = MI_VA_TO_VPN (EndingAddress); 01318 Vad->ControlArea = ControlArea; 01319 Vad->u2.VadFlags2.Inherit = MM_VIEW_UNMAP; 01320 Vad->u.VadFlags.PhysicalMapping = 1; 01321 Vad->u.VadFlags.Protection = ProtectionMask; 01322 01323 // 01324 // Set the last contiguous PTE field in the Vad to the page frame 01325 // number of the starting physical page. 01326 // 01327 01328 Vad->LastContiguousPte = (PMMPTE)(ULONG)( 01329 SectionOffset->QuadPart >> PAGE_SHIFT); 01330 #ifdef LARGE_PAGES 01331 if (AllocationType & MEM_LARGE_PAGES) { 01332 Vad->u.VadFlags.LargePages = 1; 01333 Vad->FirstPrototypePte = (PMMPTE)Subsection; 01334 } else { 01335 #endif //LARGE_PAGES 01336 // Vad->u.VadFlags.LargePages = 0; 01337 Vad->FirstPrototypePte = Vad->LastContiguousPte; 01338 #ifdef LARGE_PAGES 01339 } 01340 #endif //LARGE_PAGES 01341 01342 // 01343 // Insert the VAD. This could get an exception. 01344 // 01345 01346 ASSERT (Vad->FirstPrototypePte <= Vad->LastContiguousPte); 01347 MiInsertVad (Vad); 01348 01349 } except (EXCEPTION_EXECUTE_HANDLER) { 01350 01351 if (PhysicalView != NULL) { 01352 ExFreePool (PhysicalView); 01353 } 01354 01355 if (Vad != (PMMVAD)NULL) { 01356 01357 // 01358 // The pool allocation succeeded, but the quota charge 01359 // in InsertVad failed, deallocate the pool and return 01360 // an error. 01361 // 01362 01363 ExFreePool (Vad); 01364 #ifdef LARGE_PAGES 01365 if (AllocationType & MEM_LARGE_PAGES) { 01366 ExFreePool (Subsection); 01367 } 01368 #endif //LARGE_PAGES 01369 return GetExceptionCode(); 01370 } 01371 return STATUS_INSUFFICIENT_RESOURCES; 01372 } 01373 01374 // 01375 // Increment the count of the number of views for the 01376 // section object. This requires the PFN lock to be held. 01377 // 01378 01379 LOCK_AWE (Process, OldIrql); 01380 LOCK_PFN2 (OldIrql2); 01381 01382 InsertHeadList (&Process->PhysicalVadList, &PhysicalView->ListEntry); 01383 01384 ControlArea->NumberOfMappedViews += 1; 01385 ControlArea->NumberOfUserReferences += 1; 01386 01387 ASSERT (ControlArea->NumberOfSectionReferences != 0); 01388 01389 UNLOCK_PFN2 (OldIrql2); 01390 UNLOCK_AWE (Process, OldIrql); 01391 01392 // 01393 // Build the PTEs in the address space. 01394 // 01395 01396 PointerPpe = MiGetPpeAddress (StartingAddress); 01397 PointerPde = MiGetPdeAddress (StartingAddress); 01398 PointerPte = MiGetPteAddress (StartingAddress); 01399 LastPte = MiGetPteAddress (EndingAddress); 01400 01401 MI_MAKE_VALID_PTE (TempPte, 01402 (ULONG_PTR)Vad->LastContiguousPte, 01403 ProtectionMask, 01404 PointerPte); 01405 01406 if (WriteCombined == TRUE) { 01407 MI_SET_PTE_WRITE_COMBINE (TempPte); 01408 } 01409 01410 if (TempPte.u.Hard.Write) { 01411 MI_SET_PTE_DIRTY (TempPte); 01412 } 01413 01414 #if defined(_IA64_) 01415 if (MI_IS_CACHING_DISABLED(&TempPte) || (WriteCombined == TRUE)) { 01416 KeFlushEntireTb(FALSE, TRUE); 01417 } 01418 #endif 01419 01420 #ifdef LARGE_PAGES 01421 if (AllocationType & MEM_LARGE_PAGES) { 01422 Subsection->StartingSector = pageSize; 01423 Subsection->EndingSector = (ULONG_PTR)StartingAddress; 01424 Subsection->u.LongFlags = 0; 01425 Subsection->u.SubsectionFlags.LargePages = 1; 01426 protoPte = (PMMPTE)(Subsection + 1); 01427 01428 // 01429 // Build the first 2 PTEs as entries for the TLB to 01430 // map the specified physical address. 01431 // 01432 01433 *protoPte = TempPte; 01434 protoPte += 1; 01435 01436 if (*CapturedViewSize > pageSize) { 01437 *protoPte = TempPte; 01438 protoPte->u.Hard.PageFrameNumber += (pageSize >> PAGE_SHIFT); 01439 } else { 01440 *protoPte = ZeroPte; 01441 } 01442 protoPte += 1; 01443 01444 // 01445 // Build the first prototype PTE as a paging file format PTE 01446 // referring to the subsection. 01447 // 01448 01449 protoPte->u.Long = MiGetSubsectionAddressForPte (Subsection); 01450 protoPte->u.Soft.Prototype = 1; 01451 protoPte->u.Soft.Protection = ProtectionMask; 01452 01453 // 01454 // Set the PTE up for all the user's PTE entries, proto pte 01455 // format pointing to the 3rd prototype PTE. 01456 // 01457 01458 TempPte.u.Long = MiProtoAddressForPte (protoPte); 01459 } 01460 01461 if (!(AllocationType & MEM_LARGE_PAGES)) { 01462 #endif //LARGE_PAGES 01463 01464 #if defined (_WIN64) 01465 MiMakePpeExistAndMakeValid (PointerPpe, Process, FALSE); 01466 if (PointerPde->u.Long == 0) { 01467 UsedPageDirectoryHandle = MI_GET_USED_PTES_HANDLE (PointerPte); 01468 MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageDirectoryHandle); 01469 } 01470 #endif 01471 01472 MiMakePdeExistAndMakeValid (PointerPde, Process, FALSE); 01473 01474 Pfn2 = MI_PFN_ELEMENT (PointerPde->u.Hard.PageFrameNumber); 01475 01476 UsedPageTableHandle = MI_GET_USED_PTES_HANDLE (StartingAddress); 01477 01478 while (PointerPte <= LastPte) { 01479 01480 if (MiIsPteOnPdeBoundary (PointerPte)) { 01481 01482 PointerPde = MiGetPteAddress (PointerPte); 01483 01484 if (MiIsPteOnPpeBoundary (PointerPte)) { 01485 PointerPpe = MiGetPteAddress (PointerPde); 01486 MiMakePpeExistAndMakeValid (PointerPpe, Process, FALSE); 01487 } 01488 01489 #if defined (_WIN64) 01490 if (PointerPde->u.Long == 0) { 01491 UsedPageDirectoryHandle = MI_GET_USED_PTES_HANDLE (PointerPte); 01492 MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageDirectoryHandle); 01493 } 01494 #endif 01495 01496 MiMakePdeExistAndMakeValid (PointerPde, Process, FALSE); 01497 Pfn2 = MI_PFN_ELEMENT (PointerPde->u.Hard.PageFrameNumber); 01498 UsedPageTableHandle = MI_GET_USED_PTES_HANDLE (MiGetVirtualAddressMappedByPte (PointerPte)); 01499 } 01500 01501 ASSERT (PointerPte->u.Long == 0); 01502 01503 MI_WRITE_VALID_PTE (PointerPte, TempPte); 01504 01505 CONSISTENCY_LOCK_PFN (OldIrql); 01506 01507 Pfn2->u2.ShareCount += 1; 01508 01509 CONSISTENCY_UNLOCK_PFN (OldIrql); 01510 01511 // 01512 // Increment the count of non-zero page table entries for this 01513 // page table and the number of private pages for the process. 01514 // 01515 01516 MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageTableHandle); 01517 01518 PointerPte += 1; 01519 TempPte.u.Hard.PageFrameNumber += 1; 01520 } 01521 #ifdef LARGE_PAGES 01522 } 01523 #endif //LARGE_PAGES 01524 01525 #if defined(i386) 01526 // 01527 // If write combined was specified then flush all caches and TBs. 01528 // 01529 01530 if (WriteCombined == TRUE && MiWriteCombiningPtes == TRUE) { 01531 KeFlushEntireTb (FALSE, TRUE); 01532 KeInvalidateAllCaches (TRUE); 01533 } 01534 #endif 01535 01536 #if defined(_IA64_) 01537 if (MI_IS_CACHING_DISABLED(&TempPte) || (WriteCombined == TRUE)) { 01538 MiSweepCacheMachineDependent(StartingAddress, 01539 (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1L, 01540 MmWriteCombined); 01541 } 01542 #endif 01543 01544 UNLOCK_WS_UNSAFE (Process); 01545 *ReleasedWsMutex = TRUE; 01546 01547 // 01548 // Update the current virtual size in the process header. 01549 // 01550 01551 *CapturedViewSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1L; 01552 Process->VirtualSize += *CapturedViewSize; 01553 01554 if (Process->VirtualSize > Process->PeakVirtualSize) { 01555 Process->PeakVirtualSize = Process->VirtualSize; 01556 } 01557 01558 *CapturedBase = StartingAddress; 01559 01560 return STATUS_SUCCESS; 01561 }

ULONG MiRemoveFromSystemSpace IN PMMSESSION  Session,
IN PVOID  Base,
OUT PCONTROL_AREA ControlArea
 

Definition at line 3893 of file mapview.c.

References KeBugCheckEx(), MiHydra, PAGED_CODE, and Size.

Referenced by MiMapViewInSystemSpace(), and MiUnmapViewInSystemSpace().

03901 : 03902 03903 This routine looks up the specified view in the system space hash 03904 table and unmaps the view from system space and the table. 03905 03906 Arguments: 03907 03908 Session - Supplies the session data structure for this view. 03909 03910 Base - Supplies the base address for the view. If this address is 03911 NOT found in the hash table, the system bugchecks. 03912 03913 ControlArea - Returns the control area corresponding to the base 03914 address. 03915 03916 Return Value: 03917 03918 Size of the view divided by 64k. 03919 03920 Environment: 03921 03922 Kernel Mode, system view hash table locked. 03923 03924 --*/ 03925 03926 { 03927 ULONG_PTR Base16; 03928 ULONG Hash; 03929 ULONG Size; 03930 ULONG count; 03931 03932 PAGED_CODE(); 03933 03934 count = 0; 03935 03936 // 03937 // CODE IS ALREADY LOCKED BY CALLER. 03938 // 03939 03940 Base16 = (ULONG_PTR)Base >> 16; 03941 Hash = (ULONG)(Base16 % Session->SystemSpaceHashKey); 03942 03943 while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Base16) { 03944 Hash += 1; 03945 if (Hash >= Session->SystemSpaceHashSize) { 03946 Hash = 0; 03947 count += 1; 03948 if (count == 2) { 03949 KeBugCheckEx (DRIVER_UNMAPPING_INVALID_VIEW, 03950 (ULONG_PTR)Base, 03951 MiHydra, 03952 0, 03953 0); 03954 } 03955 } 03956 } 03957 03958 Session->SystemSpaceHashEntries -= 1; 03959 Size = (ULONG) (Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF); 03960 Session->SystemSpaceViewTable[Hash].Entry = 0; 03961 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea; 03962 return Size; 03963 }

VOID MiRemoveMappedPtes IN PVOID  BaseAddress,
IN ULONG  NumberOfPtes,
IN PCONTROL_AREA  ControlArea,
IN PMMSUPPORT  WorkingSetInfo
 

Referenced by MiUnmapViewInSystemSpace().

VOID MiSetPageModified IN PVOID  Address  ) 
 

Definition at line 3060 of file mapview.c.

References FALSE, KeFlushSingleTb(), LOCK_PFN, MI_IS_PTE_DIRTY, MI_PFN_ELEMENT, MI_SET_PTE_CLEAN, MiGetPdeAddress, MiGetPpeAddress, MiGetPteAddress, MiReleasePageFileSpace(), _MMPFN::OriginalPte, TRUE, _MMPTE::u, _MMPFN::u3, UNLOCK_PFN, and VOID().

Referenced by MiMapViewOfImageSection().

03066 : 03067 03068 This routine sets the modified bit in the PFN database for the 03069 pages that correspond to the specified address range. 03070 03071 Note that the dirty bit in the PTE is cleared by this operation. 03072 03073 Arguments: 03074 03075 Address - Supplies the address of the start of the range. This 03076 range must reside within the system cache. 03077 03078 Return Value: 03079 03080 None. 03081 03082 Environment: 03083 03084 Kernel mode. APC_LEVEL and below for pagable addresses, 03085 DISPATCH_LEVEL and below for non-pagable addresses. 03086 03087 --*/ 03088 03089 { 03090 volatile PMMPTE PointerPpe; 03091 volatile PMMPTE PointerPde; 03092 volatile PMMPTE PointerPte; 03093 PMMPFN Pfn1; 03094 MMPTE PteContents; 03095 KIRQL OldIrql; 03096 03097 // 03098 // Loop on the copy on write case until the page is only 03099 // writable. 03100 // 03101 03102 PointerPte = MiGetPteAddress (Address); 03103 PointerPde = MiGetPdeAddress (Address); 03104 PointerPpe = MiGetPpeAddress (Address); 03105 03106 *(volatile CCHAR *)Address; 03107 03108 LOCK_PFN (OldIrql); 03109 03110 #if defined (_WIN64) 03111 while ((PointerPpe->u.Hard.Valid == 0) || 03112 (PointerPde->u.Hard.Valid == 0) || 03113 (PointerPte->u.Hard.Valid == 0)) 03114 #else 03115 while ((PointerPde->u.Hard.Valid == 0) || 03116 (PointerPte->u.Hard.Valid == 0)) 03117 #endif 03118 { 03119 03120 // 03121 // Page is no longer valid. 03122 // 03123 03124 UNLOCK_PFN (OldIrql); 03125 *(volatile CCHAR *)Address; 03126 LOCK_PFN (OldIrql); 03127 } 03128 03129 PteContents = *PointerPte; 03130 03131 Pfn1 = MI_PFN_ELEMENT (PteContents.u.Hard.PageFrameNumber); 03132 Pfn1->u3.e1.Modified = 1; 03133 03134 if ((Pfn1->OriginalPte.u.Soft.Prototype == 0) && 03135 (Pfn1->u3.e1.WriteInProgress == 0)) { 03136 MiReleasePageFileSpace (Pfn1->OriginalPte); 03137 Pfn1->OriginalPte.u.Soft.PageFileHigh = 0; 03138 } 03139 03140 #ifdef NT_UP 03141 if (MI_IS_PTE_DIRTY (PteContents)) { 03142 #endif //NT_UP 03143 MI_SET_PTE_CLEAN (PteContents); 03144 03145 // 03146 // Clear the dirty bit in the PTE so new writes can be tracked. 03147 // 03148 03149 (VOID)KeFlushSingleTb (Address, 03150 FALSE, 03151 TRUE, 03152 (PHARDWARE_PTE)PointerPte, 03153 PteContents.u.Flush); 03154 #ifdef NT_UP 03155 } 03156 #endif //NT_UP 03157 03158 UNLOCK_PFN (OldIrql); 03159 return; 03160 }

NTSTATUS MiUnmapViewInSystemSpace IN PMMSESSION  Session,
IN PVOID  MappedBase
 

Definition at line 3683 of file mapview.c.

References ExPageLockHandle, LOCK_SESSION_SPACE_WS, LOCK_SYSTEM_VIEW_SPACE, MiRemoveFromSystemSpace(), MiRemoveMappedPtes(), MmLockPagableSectionByHandle(), MmSession, MmSessionSpace, MmSystemCacheWs, MmUnlockPagableImageSection(), PAGE_SHIFT, PAGED_CODE, RtlClearBits(), Size, UNLOCK_SESSION_SPACE_WS, UNLOCK_SYSTEM_VIEW_SPACE, _MM_SESSION_SPACE::Vm, and X64K.

Referenced by MiFreeSessionSpaceMap(), MmUnmapViewInSessionSpace(), and MmUnmapViewInSystemSpace().

03690 : 03691 03692 This routine unmaps the specified section from the system's address space. 03693 03694 Arguments: 03695 03696 Session - Supplies the session data structure for this view. 03697 03698 MappedBase - Supplies the address of the view to unmap. 03699 03700 Return Value: 03701 03702 Status of the map view operation. 03703 03704 Environment: 03705 03706 Kernel Mode, IRQL of dispatch level. 03707 03708 --*/ 03709 03710 { 03711 ULONG StartBit; 03712 ULONG Size; 03713 PCONTROL_AREA ControlArea; 03714 PMMSUPPORT Ws; 03715 KIRQL WsIrql; 03716 03717 PAGED_CODE(); 03718 03719 MmLockPagableSectionByHandle(ExPageLockHandle); 03720 StartBit = (ULONG) (((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16); 03721 03722 LOCK_SYSTEM_VIEW_SPACE (Session); 03723 03724 Size = MiRemoveFromSystemSpace (Session, MappedBase, &ControlArea); 03725 03726 RtlClearBits (Session->SystemSpaceBitMap, StartBit, Size); 03727 03728 // 03729 // Zero PTEs. 03730 // 03731 03732 Size = Size * (X64K >> PAGE_SHIFT); 03733 03734 if (Session == &MmSession) { 03735 Ws = &MmSystemCacheWs; 03736 } 03737 else { 03738 Ws = &MmSessionSpace->Vm; 03739 LOCK_SESSION_SPACE_WS(WsIrql); 03740 } 03741 03742 MiRemoveMappedPtes (MappedBase, Size, ControlArea, Ws); 03743 03744 if (Session != &MmSession) { 03745 UNLOCK_SESSION_SPACE_WS(WsIrql); 03746 } 03747 03748 UNLOCK_SYSTEM_VIEW_SPACE (Session); 03749 03750 MmUnlockPagableImageSection(ExPageLockHandle); 03751 03752 return STATUS_SUCCESS; 03753 }

NTSTATUS MmMapViewInSessionSpace IN PVOID  Section,
OUT PVOID *  MappedBase,
IN OUT PSIZE_T  ViewSize
 

Definition at line 3211 of file mapview.c.

References ASSERT, MiHydra, MiMapViewInSystemSpace(), MmIsAddressValid(), MmSession, MmSessionSpace, PAGED_CODE, PsGetCurrentProcess, _MM_SESSION_SPACE::Session, and TRUE.

03219 : 03220 03221 This routine maps the specified section into the current process's 03222 session address space. 03223 03224 Arguments: 03225 03226 Section - Supplies a pointer to the section to map. 03227 03228 *MappedBase - Returns the address where the section was mapped. 03229 03230 ViewSize - Supplies the size of the view to map. If this 03231 is specified as zero, the whole section is mapped. 03232 Returns the actual size mapped. 03233 03234 Return Value: 03235 03236 Status of the map view operation. 03237 03238 Environment: 03239 03240 Kernel Mode, IRQL of dispatch level. 03241 03242 --*/ 03243 03244 { 03245 PMMSESSION Session; 03246 03247 PAGED_CODE(); 03248 03249 if (MiHydra == TRUE) { 03250 if (PsGetCurrentProcess()->Vm.u.Flags.ProcessInSession == 0) { 03251 return STATUS_NOT_MAPPED_VIEW; 03252 } 03253 ASSERT (MmIsAddressValid(MmSessionSpace) == TRUE); 03254 Session = &MmSessionSpace->Session; 03255 } 03256 else { 03257 Session = &MmSession; 03258 } 03259 03260 return MiMapViewInSystemSpace (Section, 03261 Session, 03262 MappedBase, 03263 ViewSize); 03264 }

NTSTATUS MmMapViewInSystemSpace IN PVOID  Section,
OUT PVOID *  MappedBase,
IN OUT PSIZE_T  ViewSize
 

Definition at line 3164 of file mapview.c.

References MiMapViewInSystemSpace(), MmSession, and PAGED_CODE.

Referenced by MiLoadSystemImage(), and NtMapViewOfSection().

03172 : 03173 03174 This routine maps the specified section into the system's address space. 03175 03176 Arguments: 03177 03178 Section - Supplies a pointer to the section to map. 03179 03180 *MappedBase - Returns the address where the section was mapped. 03181 03182 ViewSize - Supplies the size of the view to map. If this 03183 is specified as zero, the whole section is mapped. 03184 Returns the actual size mapped. 03185 03186 Return Value: 03187 03188 Status of the map view operation. 03189 03190 Environment: 03191 03192 Kernel Mode, IRQL of dispatch level. 03193 03194 --*/ 03195 03196 { 03197 PMMSESSION Session; 03198 03199 PAGED_CODE(); 03200 03201 Session = &MmSession; 03202 03203 return MiMapViewInSystemSpace (Section, 03204 Session, 03205 MappedBase, 03206 ViewSize); 03207 }

NTSTATUS MmMapViewOfSection IN PVOID  SectionToMap,
IN PEPROCESS  Process,
IN OUT PVOID *  CapturedBase,
IN ULONG_PTR  ZeroBits,
IN SIZE_T  CommitSize,
IN OUT PLARGE_INTEGER  SectionOffset,
IN OUT PSIZE_T  CapturedViewSize,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG  AllocationType,
IN ULONG  Protect
 

Definition at line 753 of file mapview.c.

References _SEGMENT::ControlArea, EXCEPTION_EXECUTE_HANDLER, ExPageLockHandle, FALSE, _SEGMENT::ImageCommitment, KeAttachProcess(), KeDetachProcess(), LOCK_ADDRESS_SPACE, MiMakeProtectionMask(), MiMapViewOfDataSection(), MiMapViewOfImageSection(), MiMapViewOfPhysicalSection(), MmLockPagableSectionByHandle(), MmUnlockPagableImageSection(), NTSTATUS(), PAGED_CODE, PSECTION, PsGetCurrentProcess, _CONTROL_AREA::Segment, TRUE, _CONTROL_AREA::u, UNLOCK_ADDRESS_SPACE, and UNLOCK_WS_AND_ADDRESS_SPACE.

Referenced by CommitReadOnlyMemory(), InitMapSharedSection(), MapDesktop(), MiGetWritablePagesInSection(), MiLoadImageSection(), MmCreatePeb(), MmInitializeProcessAddressSpace(), NtAcceptConnectPort(), NtMapViewOfSection(), NtMapViewOfSuperSection(), NtSecureConnectPort(), PspMapSystemDll(), and UserCreateHeap().

00768 : 00769 00770 This function maps a view in the specified subject process to 00771 the section object. 00772 00773 This function is a kernel mode interface to allow LPC to map 00774 a section given the section pointer to map. 00775 00776 This routine assumes all arguments have been probed and captured. 00777 00778 ******************************************************************** 00779 ******************************************************************** 00780 ******************************************************************** 00781 00782 NOTE: 00783 00784 CapturedViewSize, SectionOffset, and CapturedBase must be 00785 captured in non-paged system space (i.e., kernel stack). 00786 00787 ******************************************************************** 00788 ******************************************************************** 00789 ******************************************************************** 00790 00791 Arguments: 00792 00793 SectionToMap - Supplies a pointer to the section object. 00794 00795 Process - Supplies a pointer to the process object. 00796 00797 BaseAddress - Supplies a pointer to a variable that will receive 00798 the base address of the view. If the initial value 00799 of this argument is not null, then the view will 00800 be allocated starting at the specified virtual 00801 address rounded down to the next 64kb address 00802 boundary. If the initial value of this argument is 00803 null, then the operating system will determine 00804 where to allocate the view using the information 00805 specified by the ZeroBits argument value and the 00806 section allocation attributes (i.e. based and 00807 tiled). 00808 00809 ZeroBits - Supplies the number of high order address bits that 00810 must be zero in the base address of the section 00811 view. The value of this argument must be less than 00812 21 and is only used when the operating system 00813 determines where to allocate the view (i.e. when 00814 BaseAddress is null). 00815 00816 CommitSize - Supplies the size of the initially committed region 00817 of the view in bytes. This value is rounded up to 00818 the next host page size boundary. 00819 00820 SectionOffset - Supplies the offset from the beginning of the 00821 section to the view in bytes. This value is 00822 rounded down to the next host page size boundary. 00823 00824 ViewSize - Supplies a pointer to a variable that will receive 00825 the actual size in bytes of the view. If the value 00826 of this argument is zero, then a view of the 00827 section will be mapped starting at the specified 00828 section offset and continuing to the end of the 00829 section. Otherwise the initial value of this 00830 argument specifies the size of the view in bytes 00831 and is rounded up to the next host page size 00832 boundary. 00833 00834 InheritDisposition - Supplies a value that specifies how the 00835 view is to be shared by a child process created 00836 with a create process operation. 00837 00838 AllocationType - Supplies the type of allocation. 00839 00840 Protect - Supplies the protection desired for the region of 00841 initially committed pages. 00842 00843 Return Value: 00844 00845 Returns the status 00846 00847 TBS 00848 00849 00850 --*/ 00851 { 00852 BOOLEAN Attached; 00853 PSECTION Section; 00854 PCONTROL_AREA ControlArea; 00855 ULONG ProtectionMask; 00856 NTSTATUS status; 00857 BOOLEAN ReleasedWsMutex; 00858 BOOLEAN WriteCombined; 00859 SIZE_T ImageCommitment; 00860 00861 PAGED_CODE(); 00862 00863 Attached = FALSE; 00864 ReleasedWsMutex = TRUE; 00865 00866 Section = (PSECTION)SectionToMap; 00867 00868 // 00869 // Check to make sure the section is not smaller than the view size. 00870 // 00871 00872 if ((LONGLONG)*CapturedViewSize > Section->SizeOfSection.QuadPart) { 00873 if ((AllocationType & MEM_RESERVE) == 0) { 00874 return STATUS_INVALID_VIEW_SIZE; 00875 } 00876 } 00877 00878 if (AllocationType & MEM_RESERVE) { 00879 if (((Section->InitialPageProtection & PAGE_READWRITE) | 00880 (Section->InitialPageProtection & PAGE_EXECUTE_READWRITE)) == 0) { 00881 00882 return STATUS_SECTION_PROTECTION; 00883 } 00884 } 00885 00886 if (Section->u.Flags.NoCache) { 00887 Protect |= PAGE_NOCACHE; 00888 } 00889 00890 // 00891 // Note that write combining is only relevant to physical memory sections 00892 // because they are never trimmed - the write combining bits in a PTE entry 00893 // are not preserved across trims. 00894 // 00895 00896 if (Protect & PAGE_WRITECOMBINE) { 00897 Protect &= ~PAGE_WRITECOMBINE; 00898 WriteCombined = TRUE; 00899 } 00900 else { 00901 WriteCombined = FALSE; 00902 } 00903 00904 // 00905 // Check the protection field. This could raise an exception. 00906 // 00907 00908 try { 00909 ProtectionMask = MiMakeProtectionMask (Protect); 00910 } except (EXCEPTION_EXECUTE_HANDLER) { 00911 return GetExceptionCode(); 00912 } 00913 00914 ControlArea = Section->Segment->ControlArea; 00915 ImageCommitment = Section->Segment->ImageCommitment; 00916 00917 // 00918 // If the specified process is not the current process, attach 00919 // to the specified process. 00920 // 00921 00922 if (PsGetCurrentProcess() != Process) { 00923 KeAttachProcess (&Process->Pcb); 00924 Attached = TRUE; 00925 } 00926 00927 // 00928 // Get the address creation mutex to block multiple threads 00929 // creating or deleting address space at the same time. 00930 // 00931 00932 LOCK_ADDRESS_SPACE (Process); 00933 00934 // 00935 // Make sure the address space was not deleted, if so, return an error. 00936 // 00937 00938 if (Process->AddressSpaceDeleted != 0) { 00939 status = STATUS_PROCESS_IS_TERMINATING; 00940 goto ErrorReturn; 00941 } 00942 00943 // 00944 // Map the view base on the type. 00945 // 00946 00947 ReleasedWsMutex = FALSE; 00948 00949 if (ControlArea->u.Flags.PhysicalMemory) { 00950 00951 MmLockPagableSectionByHandle(ExPageLockHandle); 00952 status = MiMapViewOfPhysicalSection (ControlArea, 00953 Process, 00954 CapturedBase, 00955 SectionOffset, 00956 CapturedViewSize, 00957 ProtectionMask, 00958 ZeroBits, 00959 AllocationType, 00960 WriteCombined, 00961 &ReleasedWsMutex); 00962 MmUnlockPagableImageSection(ExPageLockHandle); 00963 00964 } else if (ControlArea->u.Flags.Image) { 00965 if (AllocationType & MEM_RESERVE) { 00966 status = STATUS_INVALID_PARAMETER_9; 00967 } 00968 else if (WriteCombined == TRUE) { 00969 status = STATUS_INVALID_PARAMETER_10; 00970 } else { 00971 00972 status = MiMapViewOfImageSection (ControlArea, 00973 Process, 00974 CapturedBase, 00975 SectionOffset, 00976 CapturedViewSize, 00977 Section, 00978 InheritDisposition, 00979 ZeroBits, 00980 ImageCommitment, 00981 &ReleasedWsMutex); 00982 } 00983 00984 } else { 00985 00986 // 00987 // Not an image section, therefore it is a data section. 00988 // 00989 00990 if (WriteCombined == TRUE) { 00991 status = STATUS_INVALID_PARAMETER_10; 00992 } 00993 else { 00994 status = MiMapViewOfDataSection (ControlArea, 00995 Process, 00996 CapturedBase, 00997 SectionOffset, 00998 CapturedViewSize, 00999 Section, 01000 InheritDisposition, 01001 ProtectionMask, 01002 CommitSize, 01003 ZeroBits, 01004 AllocationType, 01005 &ReleasedWsMutex 01006 ); 01007 } 01008 } 01009 01010 ErrorReturn: 01011 if (!ReleasedWsMutex) { 01012 UNLOCK_WS_AND_ADDRESS_SPACE (Process); 01013 } 01014 else { 01015 UNLOCK_ADDRESS_SPACE (Process); 01016 } 01017 01018 if (Attached) { 01019 KeDetachProcess(); 01020 } 01021 01022 return status; 01023 }

HANDLE MmSecureVirtualMemory IN PVOID  Address,
IN SIZE_T  Size,
IN ULONG  ProbeMode
 

Definition at line 4177 of file mapview.c.

References ASSERT, CHAR, _MMVAD::EndingVpn, _MMSECURE_ENTRY::EndVpn, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, Handle, _MMVAD::LeftChild, _MMSECURE_ENTRY::List, LOCK_ADDRESS_SPACE, LOCK_WS_UNSAFE, MI_VA_TO_VPN, MiDoesPdeExistAndMakeValid(), MiDoesPpeExistAndMakeValid, MiGetPdeAddress, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MiInsertConflictInList(), MiIsPteOnPdeBoundary, MiLocateAddress(), MiPhysicalViewAdjuster(), MiRemoveConflictFromList(), MM_EXECUTE_READWRITE, MM_EXECUTE_WRITECOPY, MM_NOACCESS, MM_READWRITE, MMSECURE_ENTRY, MMVAD, MMVADKEY, NonPagedPool, NULL, PAGE_SIZE, PAGED_CODE, _MMVAD::Parent, PMMSECURE_ENTRY, ProbeForWrite(), PsGetCurrentProcess, _MMVAD::RightChild, Size, _MMVAD::StartingVpn, _MMSECURE_ENTRY::StartVpn, _MMPTE::u, _MMVAD::u, _MMSECURE_ENTRY::u2, _MMVAD::u2, _MMVAD::u3, UNLOCK_ADDRESS_SPACE, UNLOCK_WS_UNSAFE, _EPROCESS::VadFreeHint, _EPROCESS::VadHint, and _EPROCESS::VadRoot.

04185 : 04186 04187 This routine probes the requested address range and protects 04188 the specified address range from having its protection made 04189 more restricted and being deleted. 04190 04191 MmUnsecureVirtualMemory is used to allow the range to return 04192 to a normal state. 04193 04194 Arguments: 04195 04196 Address - Supplies the base address to probe and secure. 04197 04198 Size - Supplies the size of the range to secure. 04199 04200 ProbeMode - Supplies one of PAGE_READONLY or PAGE_READWRITE. 04201 04202 Return Value: 04203 04204 Returns a handle to be used to unsecure the range. 04205 If the range could not be locked because of protection 04206 problems or noncommitted memory, the value (HANDLE)0 04207 is returned. 04208 04209 Environment: 04210 04211 Kernel Mode. 04212 04213 --*/ 04214 04215 { 04216 ULONG_PTR EndAddress; 04217 PVOID StartAddress; 04218 CHAR Temp; 04219 ULONG Probe; 04220 HANDLE Handle; 04221 PMMVAD Vad; 04222 PMMVAD NewVad; 04223 PMMSECURE_ENTRY Secure; 04224 PEPROCESS Process; 04225 PMMPTE PointerPpe; 04226 PMMPTE PointerPde; 04227 PMMPTE PointerPte; 04228 PMMPTE LastPte; 04229 MMLOCK_CONFLICT Conflict; 04230 ULONG Waited; 04231 04232 PAGED_CODE(); 04233 04234 if ((ULONG_PTR)Address + Size > (ULONG_PTR)MM_HIGHEST_USER_ADDRESS || (ULONG_PTR)Address + Size <= (ULONG_PTR)Address) { 04235 return (HANDLE)0; 04236 } 04237 04238 Handle = (HANDLE)0; 04239 04240 Probe = (ProbeMode == PAGE_READONLY); 04241 04242 Process = PsGetCurrentProcess(); 04243 StartAddress = Address; 04244 04245 LOCK_ADDRESS_SPACE (Process); 04246 04247 // 04248 // Check for a private committed VAD first instead of probing to avoid all 04249 // the page faults and zeroing. If we find one, then we run the PTEs 04250 // instead. 04251 // 04252 04253 if (Size >= 64 * 1024) { 04254 EndAddress = (ULONG_PTR)StartAddress + Size - 1; 04255 Vad = MiLocateAddress (StartAddress); 04256 04257 if (Vad == NULL) { 04258 goto Return1; 04259 } 04260 04261 if (Vad->u.VadFlags.UserPhysicalPages == 1) { 04262 goto Return1; 04263 } 04264 04265 if (Vad->u.VadFlags.MemCommit == 0) { 04266 goto LongWay; 04267 } 04268 04269 if (Vad->u.VadFlags.PrivateMemory == 0) { 04270 goto LongWay; 04271 } 04272 04273 if (Vad->u.VadFlags.PhysicalMapping == 1) { 04274 goto LongWay; 04275 } 04276 04277 ASSERT (Vad->u.VadFlags.Protection); 04278 04279 if ((MI_VA_TO_VPN (StartAddress) < Vad->StartingVpn) || 04280 (MI_VA_TO_VPN (EndAddress) > Vad->EndingVpn)) { 04281 goto Return1; 04282 } 04283 04284 if (Vad->u.VadFlags.Protection == MM_NOACCESS) { 04285 goto LongWay; 04286 } 04287 04288 if (ProbeMode == PAGE_READONLY) { 04289 if (Vad->u.VadFlags.Protection > MM_EXECUTE_WRITECOPY) { 04290 goto LongWay; 04291 } 04292 } 04293 else { 04294 if (Vad->u.VadFlags.Protection != MM_READWRITE && 04295 Vad->u.VadFlags.Protection != MM_EXECUTE_READWRITE) { 04296 goto LongWay; 04297 } 04298 } 04299 04300 // 04301 // Check individual page permissions. 04302 // 04303 04304 PointerPde = MiGetPdeAddress (StartAddress); 04305 PointerPpe = MiGetPteAddress (PointerPde); 04306 PointerPte = MiGetPteAddress (StartAddress); 04307 LastPte = MiGetPteAddress (EndAddress); 04308 04309 LOCK_WS_UNSAFE (Process); 04310 04311 do { 04312 04313 while (MiDoesPpeExistAndMakeValid (PointerPpe, 04314 Process, 04315 FALSE, 04316 &Waited) == FALSE) { 04317 // 04318 // Page directory parent entry is empty, go to the next one. 04319 // 04320 04321 PointerPpe += 1; 04322 PointerPde = MiGetVirtualAddressMappedByPte (PointerPpe); 04323 PointerPte = MiGetVirtualAddressMappedByPte (PointerPde); 04324 if (PointerPte > LastPte) { 04325 UNLOCK_WS_UNSAFE (Process); 04326 goto EditVad; 04327 } 04328 } 04329 04330 Waited = 0; 04331 04332 while (MiDoesPdeExistAndMakeValid (PointerPde, 04333 Process, 04334 FALSE, 04335 &Waited) == FALSE) { 04336 // 04337 // This page directory entry is empty, go to the next one. 04338 // 04339 04340 PointerPde += 1; 04341 PointerPpe = MiGetPteAddress (PointerPde); 04342 PointerPte = MiGetVirtualAddressMappedByPte (PointerPde); 04343 if (PointerPte > LastPte) { 04344 UNLOCK_WS_UNSAFE (Process); 04345 goto EditVad; 04346 } 04347 #if defined (_WIN64) 04348 if (MiIsPteOnPdeBoundary (PointerPde)) { 04349 Waited = 1; 04350 break; 04351 } 04352 #endif 04353 } 04354 04355 } while (Waited != 0); 04356 04357 while (PointerPte <= LastPte) { 04358 04359 if (MiIsPteOnPdeBoundary (PointerPte)) { 04360 04361 PointerPde = MiGetPteAddress (PointerPte); 04362 PointerPpe = MiGetPteAddress (PointerPde); 04363 04364 do { 04365 04366 while (MiDoesPpeExistAndMakeValid (PointerPpe, 04367 Process, 04368 FALSE, 04369 &Waited) == FALSE) { 04370 // 04371 // Page directory parent entry is empty, go to the next one. 04372 // 04373 04374 PointerPpe += 1; 04375 PointerPde = MiGetVirtualAddressMappedByPte (PointerPpe); 04376 PointerPte = MiGetVirtualAddressMappedByPte (PointerPde); 04377 04378 if (PointerPte > LastPte) { 04379 UNLOCK_WS_UNSAFE (Process); 04380 goto EditVad; 04381 } 04382 } 04383 04384 Waited = 0; 04385 04386 while (MiDoesPdeExistAndMakeValid (PointerPde, 04387 Process, 04388 FALSE, 04389 &Waited) == FALSE) { 04390 // 04391 // This page directory entry is empty, go to the next one. 04392 // 04393 04394 PointerPde += 1; 04395 PointerPpe = MiGetPteAddress (PointerPde); 04396 PointerPte = MiGetVirtualAddressMappedByPte (PointerPde); 04397 if (PointerPte > LastPte) { 04398 UNLOCK_WS_UNSAFE (Process); 04399 goto EditVad; 04400 } 04401 #if defined (_WIN64) 04402 if (MiIsPteOnPdeBoundary (PointerPde)) { 04403 Waited = 1; 04404 break; 04405 } 04406 #endif 04407 } 04408 04409 } while (Waited != 0); 04410 } 04411 if (PointerPte->u.Long) { 04412 UNLOCK_WS_UNSAFE (Process); 04413 goto LongWay; 04414 } 04415 PointerPte += 1; 04416 } 04417 UNLOCK_WS_UNSAFE (Process); 04418 } 04419 else { 04420 LongWay: 04421 04422 MiInsertConflictInList (&Conflict); 04423 04424 try { 04425 04426 if (ProbeMode == PAGE_READONLY) { 04427 04428 EndAddress = (ULONG_PTR)Address + Size - 1; 04429 EndAddress = (EndAddress & ~(PAGE_SIZE - 1)) + PAGE_SIZE; 04430 04431 do { 04432 Temp = *(volatile CHAR *)Address; 04433 Address = (PVOID)(((ULONG_PTR)Address & ~(PAGE_SIZE - 1)) + PAGE_SIZE); 04434 } while ((ULONG_PTR)Address != EndAddress); 04435 } else { 04436 ProbeForWrite (Address, (ULONG)Size, 1); // ****** temp ****** 04437 } 04438 04439 } except (EXCEPTION_EXECUTE_HANDLER) { 04440 MiRemoveConflictFromList (&Conflict); 04441 goto Return1; 04442 } 04443 04444 MiRemoveConflictFromList (&Conflict); 04445 04446 // 04447 // Locate VAD and add in secure descriptor. 04448 // 04449 04450 EndAddress = (ULONG_PTR)StartAddress + Size - 1; 04451 Vad = MiLocateAddress (StartAddress); 04452 04453 if (Vad == NULL) { 04454 goto Return1; 04455 } 04456 04457 if (Vad->u.VadFlags.UserPhysicalPages == 1) { 04458 goto Return1; 04459 } 04460 04461 if ((MI_VA_TO_VPN (StartAddress) < Vad->StartingVpn) || 04462 (MI_VA_TO_VPN (EndAddress) > Vad->EndingVpn)) { 04463 04464 // 04465 // Not within the section virtual address descriptor, 04466 // return an error. 04467 // 04468 04469 goto Return1; 04470 } 04471 } 04472 04473 EditVad: 04474 04475 // 04476 // If this is a short VAD, it needs to be reallocated as a large 04477 // VAD. 04478 // 04479 04480 if ((Vad->u.VadFlags.PrivateMemory) && (!Vad->u.VadFlags.NoChange)) { 04481 04482 NewVad = ExAllocatePoolWithTag (NonPagedPool, 04483 sizeof(MMVAD), 04484 MMVADKEY); 04485 if (NewVad == NULL) { 04486 goto Return1; 04487 } 04488 04489 RtlZeroMemory (NewVad, sizeof(MMVAD)); 04490 RtlCopyMemory (NewVad, Vad, sizeof(MMVAD_SHORT)); 04491 NewVad->u.VadFlags.NoChange = 1; 04492 NewVad->u2.VadFlags2.OneSecured = 1; 04493 NewVad->u2.VadFlags2.StoredInVad = 1; 04494 NewVad->u2.VadFlags2.ReadOnly = Probe; 04495 NewVad->u3.Secured.StartVpn = (ULONG_PTR)StartAddress; 04496 NewVad->u3.Secured.EndVpn = EndAddress; 04497 04498 // 04499 // Replace the current VAD with this expanded VAD. 04500 // 04501 04502 LOCK_WS_UNSAFE (Process); 04503 if (Vad->Parent) { 04504 if (Vad->Parent->RightChild == Vad) { 04505 Vad->Parent->RightChild = NewVad; 04506 } else { 04507 ASSERT (Vad->Parent->LeftChild == Vad); 04508 Vad->Parent->LeftChild = NewVad; 04509 } 04510 } else { 04511 Process->VadRoot = NewVad; 04512 } 04513 if (Vad->LeftChild) { 04514 Vad->LeftChild->Parent = NewVad; 04515 } 04516 if (Vad->RightChild) { 04517 Vad->RightChild->Parent = NewVad; 04518 } 04519 if (Process->VadHint == Vad) { 04520 Process->VadHint = NewVad; 04521 } 04522 if (Process->VadFreeHint == Vad) { 04523 Process->VadFreeHint = NewVad; 04524 } 04525 04526 if ((Vad->u.VadFlags.PhysicalMapping == 1) || 04527 (Vad->u.VadFlags.WriteWatch == 1)) { 04528 04529 MiPhysicalViewAdjuster (Process, Vad, NewVad); 04530 } 04531 04532 UNLOCK_WS_UNSAFE (Process); 04533 ExFreePool (Vad); 04534 Handle = (HANDLE)&NewVad->u2.LongFlags2; 04535 goto Return1; 04536 } 04537 04538 // 04539 // This is already a large VAD, add the secure entry. 04540 // 04541 04542 if (Vad->u2.VadFlags2.OneSecured) { 04543 04544 // 04545 // This VAD already is secured. Move the info out of the 04546 // block into pool. 04547 // 04548 04549 Secure = ExAllocatePoolWithTag (NonPagedPool, 04550 sizeof (MMSECURE_ENTRY), 04551 'eSmM'); 04552 if (Secure == NULL) { 04553 goto Return1; 04554 } 04555 04556 ASSERT (Vad->u.VadFlags.NoChange == 1); 04557 Vad->u2.VadFlags2.OneSecured = 0; 04558 Vad->u2.VadFlags2.MultipleSecured = 1; 04559 Secure->u2.LongFlags2 = (ULONG) Vad->u.LongFlags; 04560 Secure->u2.VadFlags2.StoredInVad = 0; 04561 Secure->StartVpn = Vad->u3.Secured.StartVpn; 04562 Secure->EndVpn = Vad->u3.Secured.EndVpn; 04563 04564 InitializeListHead (&Vad->u3.List); 04565 InsertTailList (&Vad->u3.List, 04566 &Secure->List); 04567 } 04568 04569 if (Vad->u2.VadFlags2.MultipleSecured) { 04570 04571 // 04572 // This VAD already has a secured element in its list, allocate and 04573 // add in the new secured element. 04574 // 04575 04576 Secure = ExAllocatePoolWithTag (NonPagedPool, 04577 sizeof (MMSECURE_ENTRY), 04578 'eSmM'); 04579 if (Secure == NULL) { 04580 goto Return1; 04581 } 04582 04583 Secure->u2.LongFlags2 = 0; 04584 Secure->u2.VadFlags2.ReadOnly = Probe; 04585 Secure->StartVpn = (ULONG_PTR)StartAddress; 04586 Secure->EndVpn = EndAddress; 04587 04588 InsertTailList (&Vad->u3.List, 04589 &Secure->List); 04590 Handle = (HANDLE)Secure; 04591 04592 } else { 04593 04594 // 04595 // This list does not have a secure element. Put it in the VAD. 04596 // 04597 04598 Vad->u.VadFlags.NoChange = 1; 04599 Vad->u2.VadFlags2.OneSecured = 1; 04600 Vad->u2.VadFlags2.StoredInVad = 1; 04601 Vad->u2.VadFlags2.ReadOnly = Probe; 04602 Vad->u3.Secured.StartVpn = (ULONG_PTR)StartAddress; 04603 Vad->u3.Secured.EndVpn = EndAddress; 04604 Handle = (HANDLE)&Vad->u2.LongFlags2; 04605 } 04606 04607 Return1: 04608 UNLOCK_ADDRESS_SPACE (Process); 04609 return Handle; 04610 }

NTSTATUS MmUnmapViewInSessionSpace IN PVOID  MappedBase  ) 
 

Definition at line 3639 of file mapview.c.

References ASSERT, MiHydra, MiUnmapViewInSystemSpace(), MmIsAddressValid(), MmSession, MmSessionSpace, PAGED_CODE, PsGetCurrentProcess, _MM_SESSION_SPACE::Session, and TRUE.

03645 : 03646 03647 This routine unmaps the specified section from the system's address space. 03648 03649 Arguments: 03650 03651 MappedBase - Supplies the address of the view to unmap. 03652 03653 Return Value: 03654 03655 Status of the map view operation. 03656 03657 Environment: 03658 03659 Kernel Mode, IRQL of dispatch level. 03660 03661 --*/ 03662 03663 { 03664 PMMSESSION Session; 03665 03666 PAGED_CODE(); 03667 03668 if (MiHydra == TRUE) { 03669 if (PsGetCurrentProcess()->Vm.u.Flags.ProcessInSession == 0) { 03670 return STATUS_NOT_MAPPED_VIEW; 03671 } 03672 ASSERT (MmIsAddressValid(MmSessionSpace) == TRUE); 03673 Session = &MmSessionSpace->Session; 03674 } 03675 else { 03676 Session = &MmSession; 03677 } 03678 03679 return MiUnmapViewInSystemSpace (Session, MappedBase); 03680 }

NTSTATUS MmUnmapViewInSystemSpace IN PVOID  MappedBase  ) 
 

Definition at line 3608 of file mapview.c.

References MiUnmapViewInSystemSpace(), MmSession, and PAGED_CODE.

Referenced by NtMapViewOfSection().

03614 : 03615 03616 This routine unmaps the specified section from the system's address space. 03617 03618 Arguments: 03619 03620 MappedBase - Supplies the address of the view to unmap. 03621 03622 Return Value: 03623 03624 Status of the map view operation. 03625 03626 Environment: 03627 03628 Kernel Mode, IRQL of dispatch level. 03629 03630 --*/ 03631 03632 { 03633 PAGED_CODE(); 03634 03635 return MiUnmapViewInSystemSpace (&MmSession, MappedBase); 03636 }

VOID MmUnsecureVirtualMemory IN HANDLE  SecureHandle  ) 
 

Definition at line 4614 of file mapview.c.

References ASSERT, ExFreePool(), _MMSECURE_ENTRY::List, List, LOCK_ADDRESS_SPACE, _MMSECURE_ENTRY::LongFlags2, MiLocateAddress(), PAGED_CODE, PsGetCurrentProcess, _MMSECURE_ENTRY::StartVpn, _MMVAD::u, _MMVAD::u2, _MMSECURE_ENTRY::u2, _MMVAD::u3, and UNLOCK_ADDRESS_SPACE.

04620 : 04621 04622 This routine unsecures memory previous secured via a call to 04623 MmSecureVirtualMemory. 04624 04625 Arguments: 04626 04627 SecureHandle - Supplies the handle returned in MmSecureVirtualMemory. 04628 04629 Return Value: 04630 04631 None. 04632 04633 Environment: 04634 04635 Kernel Mode. 04636 04637 --*/ 04638 04639 { 04640 PMMSECURE_ENTRY Secure; 04641 PEPROCESS Process; 04642 PMMVAD Vad; 04643 04644 PAGED_CODE(); 04645 04646 Secure = (PMMSECURE_ENTRY)SecureHandle; 04647 Process = PsGetCurrentProcess (); 04648 LOCK_ADDRESS_SPACE (Process); 04649 04650 if (Secure->u2.VadFlags2.StoredInVad) { 04651 Vad = CONTAINING_RECORD( Secure, 04652 MMVAD, 04653 u2.LongFlags2); 04654 } else { 04655 Vad = MiLocateAddress ((PVOID)Secure->StartVpn); 04656 } 04657 04658 ASSERT (Vad); 04659 ASSERT (Vad->u.VadFlags.NoChange == 1); 04660 04661 if (Vad->u2.VadFlags2.OneSecured) { 04662 ASSERT (Secure == (PMMSECURE_ENTRY)&Vad->u2.LongFlags2); 04663 Vad->u2.VadFlags2.OneSecured = 0; 04664 ASSERT (Vad->u2.VadFlags2.MultipleSecured == 0); 04665 if (Vad->u2.VadFlags2.SecNoChange == 0) { 04666 04667 // 04668 // No more secure entries in this list, remove the state. 04669 // 04670 04671 Vad->u.VadFlags.NoChange = 0; 04672 } 04673 } else { 04674 ASSERT (Vad->u2.VadFlags2.MultipleSecured == 1); 04675 04676 if (Secure == (PMMSECURE_ENTRY)&Vad->u2.LongFlags2) { 04677 04678 // 04679 // This was a single block that got converted into a list. 04680 // Reset the entry. 04681 // 04682 04683 Secure = CONTAINING_RECORD (Vad->u3.List.Flink, 04684 MMSECURE_ENTRY, 04685 List); 04686 } 04687 RemoveEntryList (&Secure->List); 04688 ExFreePool (Secure); 04689 if (IsListEmpty (&Vad->u3.List)) { 04690 04691 // 04692 // No more secure entries, reset the state. 04693 // 04694 04695 Vad->u2.VadFlags2.MultipleSecured = 0; 04696 04697 if ((Vad->u2.VadFlags2.SecNoChange == 0) && 04698 (Vad->u.VadFlags.PrivateMemory == 0)) { 04699 04700 // 04701 // No more secure entries in this list, remove the state 04702 // if and only if this VAD is not private. If this VAD 04703 // is private, removing the state NoChange flag indicates 04704 // that this is a short VAD which it no longer is. 04705 // 04706 04707 Vad->u.VadFlags.NoChange = 0; 04708 } 04709 } 04710 } 04711 04712 UNLOCK_ADDRESS_SPACE (Process); 04713 return; 04714 } }

NTSYSAPI NTSTATUS NTAPI NtAreMappedFilesTheSame IN PVOID  File1MappedAsAnImage,
IN PVOID  File2MappedAsFile
 

Definition at line 2965 of file mapview.c.

References _MMVAD::ControlArea, _CONTROL_AREA::FilePointer, _SECTION_OBJECT_POINTERS::ImageSectionObject, LOCK_ADDRESS_SPACE, MiLocateAddress(), NTSTATUS(), NULL, PsGetCurrentProcess, _FILE_OBJECT::SectionObjectPointer, Status, _MMVAD::u, and UNLOCK_ADDRESS_SPACE.

Referenced by LdrpCheckForLoadedDll().

02972 : 02973 02974 This routine compares the two files mapped at the specified 02975 addresses to see if they are both the same file. 02976 02977 Arguments: 02978 02979 File1MappedAsAnImage - Supplies an address within the first file which 02980 is mapped as an image file. 02981 02982 File2MappedAsFile - Supplies an address within the second file which 02983 is mapped as either an image file or a data file. 02984 02985 Return Value: 02986 02987 02988 STATUS_SUCCESS is returned if the two files are the same. 02989 02990 STATUS_NOT_SAME_DEVICE is returned if the files are different. 02991 02992 Other status values can be returned if the addresses are not mapped as 02993 files, etc. 02994 02995 Environment: 02996 02997 User mode callable system service. 02998 02999 --*/ 03000 03001 { 03002 PMMVAD FoundVad1; 03003 PMMVAD FoundVad2; 03004 NTSTATUS Status; 03005 03006 LOCK_ADDRESS_SPACE (PsGetCurrentProcess()); 03007 FoundVad1 = MiLocateAddress (File1MappedAsAnImage); 03008 FoundVad2 = MiLocateAddress (File2MappedAsFile); 03009 03010 if ((FoundVad1 == NULL) || 03011 (FoundVad2 == NULL)) { 03012 03013 // 03014 // No virtual address is allocated at the specified base address, 03015 // return an error. 03016 // 03017 03018 Status = STATUS_INVALID_ADDRESS; 03019 goto ErrorReturn; 03020 } 03021 03022 // 03023 // Check file names. 03024 // 03025 03026 if ((FoundVad1->u.VadFlags.PrivateMemory == 1) || 03027 (FoundVad2->u.VadFlags.PrivateMemory == 1)) { 03028 Status = STATUS_CONFLICTING_ADDRESSES; 03029 goto ErrorReturn; 03030 } 03031 03032 if ((FoundVad1->ControlArea == NULL) || 03033 (FoundVad2->ControlArea == NULL)) { 03034 Status = STATUS_CONFLICTING_ADDRESSES; 03035 goto ErrorReturn; 03036 } 03037 03038 if ((FoundVad1->ControlArea->FilePointer == NULL) || 03039 (FoundVad2->ControlArea->FilePointer == NULL)) { 03040 Status = STATUS_CONFLICTING_ADDRESSES; 03041 goto ErrorReturn; 03042 } 03043 03044 Status = STATUS_NOT_SAME_DEVICE; 03045 03046 if ((PVOID)FoundVad1->ControlArea == 03047 FoundVad2->ControlArea->FilePointer->SectionObjectPointer->ImageSectionObject) { 03048 Status = STATUS_SUCCESS; 03049 } 03050 03051 ErrorReturn: 03052 03053 UNLOCK_ADDRESS_SPACE (PsGetCurrentProcess()); 03054 return Status; 03055 }

NTSTATUS NtMapViewOfSection IN HANDLE  SectionHandle,
IN HANDLE  ProcessHandle,
IN OUT PVOID *  BaseAddress,
IN ULONG_PTR  ZeroBits,
IN SIZE_T  CommitSize,
IN OUT PLARGE_INTEGER SectionOffset  OPTIONAL,
IN OUT PSIZE_T  ViewSize,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG  AllocationType,
IN ULONG  Protect
 

Definition at line 199 of file mapview.c.

References DbgkMapViewOfSection(), DbgPrint, EXCEPTION_EXECUTE_HANDLER, ExSystemExceptionFilter(), FALSE, KernelMode, KPROCESSOR_MODE, MiIsProtectionCompatible(), MiMakeProtectionMask(), MM_DBG_SHOW_NT_CALLS, MM_HIGHEST_VAD_ADDRESS, MM_MAXIMUM_ZERO_BITS, MM_USER_ADDRESS_RANGE_LIMIT, MmHighestPhysicalPage, MmMakeSectionAccess, MmMapViewInSystemSpace(), MmMapViewOfSection(), MmSectionObjectType, MmUnmapViewInSystemSpace(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGE_SHIFT, PAGE_SIZE, PAGED_CODE, ProbeForWrite(), ProbeForWritePointer, ProbeForWriteUlong_ptr, PSECTION, PsGetCurrentProcess, PsProcessType, RtlFindMostSignificantBit(), Size, Status, TRUE, X64K, and ZERO_LARGE.

Referenced by CreateConsoleBitmap(), LdrLoadAlternateResourceModule(), LdrpCheckForLoadedDll(), LdrpMapDll(), LdrVerifyImageMatchesChecksum(), MapViewOfSection(), NapCreateDataSection(), PropertiesDlgShow(), PropertiesUpdate(), RtlCreateQueryDebugBuffer(), and RtlpChangeQueryDebugBufferTarget().

00214 : 00215 00216 This function maps a view in the specified subject process to 00217 the section object. 00218 00219 Arguments: 00220 00221 SectionHandle - Supplies an open handle to a section object. 00222 00223 ProcessHandle - Supplies an open handle to a process object. 00224 00225 BaseAddress - Supplies a pointer to a variable that will receive 00226 the base address of the view. If the initial value 00227 of this argument is not null, then the view will 00228 be allocated starting at the specified virtual 00229 address rounded down to the next 64kb address 00230 boundary. If the initial value of this argument is 00231 null, then the operating system will determine 00232 where to allocate the view using the information 00233 specified by the ZeroBits argument value and the 00234 section allocation attributes (i.e. based and 00235 tiled). 00236 00237 ZeroBits - Supplies the number of high order address bits that 00238 must be zero in the base address of the section 00239 view. The value of this argument must be less than 00240 or equal to the maximum number of zero bits and is only 00241 used when memory management determines where to allocate 00242 the view (i.e. when BaseAddress is null). 00243 00244 If ZeroBits is zero, then no zero bit constraints are applied. 00245 00246 If ZeroBits is greater than 0 and less than 32, then it is 00247 the number of leading zero bits from bit 31. Bits 63:32 are 00248 also required to be zero. This retains compatibility 00249 with 32-bit systems. 00250 00251 If ZeroBits is greater than 32, then it is considered as 00252 a mask and then number of leading zero are counted out 00253 in the mask. This then becomes the zero bits argument. 00254 00255 CommitSize - Supplies the size of the initially committed region 00256 of the view in bytes. This value is rounded up to 00257 the next host page size boundary. 00258 00259 SectionOffset - Supplies the offset from the beginning of the 00260 section to the view in bytes. This value is 00261 rounded down to the next host page size boundary. 00262 00263 ViewSize - Supplies a pointer to a variable that will receive 00264 the actual size in bytes of the view. If the value 00265 of this argument is zero, then a view of the 00266 section will be mapped starting at the specified 00267 section offset and continuing to the end of the 00268 section. Otherwise the initial value of this 00269 argument specifies the size of the view in bytes 00270 and is rounded up to the next host page size 00271 boundary. 00272 00273 InheritDisposition - Supplies a value that specifies how the 00274 view is to be shared by a child process created 00275 with a create process operation. 00276 00277 InheritDisposition Values 00278 00279 ViewShare - Inherit view and share a single copy 00280 of the committed pages with a child process 00281 using the current protection value. 00282 00283 ViewUnmap - Do not map the view into a child process. 00284 00285 AllocationType - Supplies the type of allocation. 00286 00287 MEM_TOP_DOWN 00288 MEM_DOS_LIM 00289 MEM_LARGE_PAGES 00290 MEM_RESERVE - for file mapped sections only. 00291 00292 Protect - Supplies the protection desired for the region of 00293 initially committed pages. 00294 00295 Protect Values 00296 00297 00298 PAGE_NOACCESS - No access to the committed region 00299 of pages is allowed. An attempt to read, 00300 write, or execute the committed region 00301 results in an access violation (i.e. a GP 00302 fault). 00303 00304 PAGE_EXECUTE - Execute access to the committed 00305 region of pages is allowed. An attempt to 00306 read or write the committed region results in 00307 an access violation. 00308 00309 PAGE_READONLY - Read only and execute access to the 00310 committed region of pages is allowed. An 00311 attempt to write the committed region results 00312 in an access violation. 00313 00314 PAGE_READWRITE - Read, write, and execute access to 00315 the region of committed pages is allowed. If 00316 write access to the underlying section is 00317 allowed, then a single copy of the pages are 00318 shared. Otherwise the pages are shared read 00319 only/copy on write. 00320 00321 Return Value: 00322 00323 Various NTSTATUS codes. 00324 00325 --*/ 00326 00327 { 00328 PSECTION Section; 00329 PEPROCESS Process; 00330 KPROCESSOR_MODE PreviousMode; 00331 NTSTATUS Status; 00332 PVOID CapturedBase; 00333 SIZE_T CapturedViewSize; 00334 LARGE_INTEGER TempViewSize; 00335 LARGE_INTEGER CapturedOffset; 00336 ULONGLONG HighestPhysicalAddressInPfnDatabase; 00337 ACCESS_MASK DesiredSectionAccess; 00338 ULONG ProtectMaskForAccess; 00339 BOOLEAN WriteCombined; 00340 00341 PAGED_CODE(); 00342 00343 // 00344 // Check the zero bits argument for correctness. 00345 // 00346 00347 #if defined (_WIN64) 00348 00349 if (ZeroBits >= 32) { 00350 00351 // 00352 // ZeroBits is a mask instead of a count. Translate it to a count now. 00353 // 00354 00355 ZeroBits = 64 - RtlFindMostSignificantBit (ZeroBits); 00356 } 00357 else if (ZeroBits) { 00358 ZeroBits += 32; 00359 } 00360 00361 #endif 00362 00363 if (ZeroBits > MM_MAXIMUM_ZERO_BITS) { 00364 return STATUS_INVALID_PARAMETER_4; 00365 } 00366 00367 // 00368 // Check the inherit disposition flags. 00369 // 00370 00371 if ((InheritDisposition > ViewUnmap) || 00372 (InheritDisposition < ViewShare)) { 00373 return STATUS_INVALID_PARAMETER_8; 00374 } 00375 00376 // 00377 // Check the allocation type field. 00378 // 00379 00380 #ifdef i386 00381 00382 // 00383 // Only allow DOS_LIM support for i386. The MEM_DOS_LIM flag allows 00384 // map views of data sections to be done on 4k boundaries rather 00385 // than 64k boundaries. 00386 // 00387 00388 if ((AllocationType & ~(MEM_TOP_DOWN | MEM_LARGE_PAGES | MEM_DOS_LIM | 00389 SEC_NO_CHANGE | MEM_RESERVE)) != 0) { 00390 return STATUS_INVALID_PARAMETER_9; 00391 } 00392 #else 00393 if ((AllocationType & ~(MEM_TOP_DOWN | MEM_LARGE_PAGES | 00394 SEC_NO_CHANGE | MEM_RESERVE)) != 0) { 00395 return STATUS_INVALID_PARAMETER_9; 00396 } 00397 00398 #endif //i386 00399 00400 // 00401 // Check the protection field. This could raise an exception. 00402 // 00403 00404 if (Protect & PAGE_WRITECOMBINE) { 00405 Protect &= ~PAGE_WRITECOMBINE; 00406 WriteCombined = TRUE; 00407 } 00408 else { 00409 WriteCombined = FALSE; 00410 } 00411 00412 try { 00413 ProtectMaskForAccess = MiMakeProtectionMask (Protect) & 0x7; 00414 } except (EXCEPTION_EXECUTE_HANDLER) { 00415 return GetExceptionCode(); 00416 } 00417 00418 DesiredSectionAccess = MmMakeSectionAccess[ProtectMaskForAccess]; 00419 00420 PreviousMode = KeGetPreviousMode(); 00421 00422 // 00423 // Establish an exception handler, probe the specified addresses 00424 // for write access and capture the initial values. 00425 // 00426 00427 try { 00428 if (PreviousMode != KernelMode) { 00429 ProbeForWritePointer ((PULONG)BaseAddress); 00430 ProbeForWriteUlong_ptr (ViewSize); 00431 00432 } 00433 00434 if (ARGUMENT_PRESENT (SectionOffset)) { 00435 if (PreviousMode != KernelMode) { 00436 ProbeForWrite (SectionOffset, 00437 sizeof(LARGE_INTEGER), 00438 sizeof(ULONG_PTR)); 00439 } 00440 CapturedOffset = *SectionOffset; 00441 } else { 00442 ZERO_LARGE (CapturedOffset); 00443 } 00444 00445 // 00446 // Capture the base address. 00447 // 00448 00449 CapturedBase = *BaseAddress; 00450 00451 // 00452 // Capture the region size. 00453 // 00454 00455 CapturedViewSize = *ViewSize; 00456 00457 } except (ExSystemExceptionFilter()) { 00458 00459 // 00460 // If an exception occurs during the probe or capture 00461 // of the initial values, then handle the exception and 00462 // return the exception code as the status value. 00463 // 00464 00465 return GetExceptionCode(); 00466 } 00467 00468 #if DBG 00469 if (MmDebug & MM_DBG_SHOW_NT_CALLS) { 00470 if ( !MmWatchProcess ) { 00471 DbgPrint("mapview process handle %lx section %lx base address %p zero bits %lx\n", 00472 ProcessHandle, SectionHandle, CapturedBase, ZeroBits); 00473 DbgPrint(" view size %p offset %p commitsize %p protect %lx\n", 00474 CapturedViewSize, CapturedOffset, CommitSize, Protect); 00475 DbgPrint(" Inheritdisp %lx Allocation type %lx\n", 00476 InheritDisposition, AllocationType); 00477 } 00478 } 00479 #endif 00480 00481 // 00482 // Make sure the specified starting and ending addresses are 00483 // within the user part of the virtual address space. 00484 // 00485 00486 if (CapturedBase > MM_HIGHEST_VAD_ADDRESS) { 00487 00488 // 00489 // Invalid base address. 00490 // 00491 00492 return STATUS_INVALID_PARAMETER_3; 00493 } 00494 00495 if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)CapturedBase) < 00496 CapturedViewSize) { 00497 00498 // 00499 // Invalid region size; 00500 // 00501 00502 return STATUS_INVALID_PARAMETER_3; 00503 00504 } 00505 00506 if (((ULONG_PTR)CapturedBase + CapturedViewSize) > ((ULONG_PTR)MM_USER_ADDRESS_RANGE_LIMIT >> ZeroBits)) { 00507 00508 // 00509 // Desired Base and zero_bits conflict. 00510 // 00511 00512 return STATUS_INVALID_PARAMETER_4; 00513 } 00514 00515 Status = ObReferenceObjectByHandle ( ProcessHandle, 00516 PROCESS_VM_OPERATION, 00517 PsProcessType, 00518 PreviousMode, 00519 (PVOID *)&Process, 00520 NULL ); 00521 if (!NT_SUCCESS(Status)) { 00522 return Status; 00523 } 00524 00525 // 00526 // Reference the section object, if a view is mapped to the section 00527 // object, the object is not dereferenced as the virtual address 00528 // descriptor contains a pointer to the section object. 00529 // 00530 00531 Status = ObReferenceObjectByHandle ( SectionHandle, 00532 DesiredSectionAccess, 00533 MmSectionObjectType, 00534 PreviousMode, 00535 (PVOID *)&Section, 00536 NULL ); 00537 00538 if (!NT_SUCCESS(Status)) { 00539 goto ErrorReturn1; 00540 } 00541 00542 if (Section->u.Flags.Image == 0) { 00543 00544 // 00545 // This is not an image section, make sure the section page 00546 // protection is compatible with the specified page protection. 00547 // 00548 00549 if (!MiIsProtectionCompatible (Section->InitialPageProtection, 00550 Protect)) { 00551 Status = STATUS_SECTION_PROTECTION; 00552 goto ErrorReturn; 00553 } 00554 } 00555 00556 // 00557 // Check to see if this the section backs physical memory, if 00558 // so DON'T align the offset on a 64K boundary, just a 4k boundary. 00559 // 00560 00561 if (Section->Segment->ControlArea->u.Flags.PhysicalMemory) { 00562 HighestPhysicalAddressInPfnDatabase = (ULONGLONG)MmHighestPhysicalPage << PAGE_SHIFT; 00563 CapturedOffset.LowPart = CapturedOffset.LowPart & ~(PAGE_SIZE - 1); 00564 00565 // 00566 // No usermode mappings past the end of the PFN database are allowed. 00567 // Address wrap is checked in the common path. 00568 // 00569 00570 if (PreviousMode != KernelMode) { 00571 00572 if ((ULONGLONG)(CapturedOffset.QuadPart + CapturedViewSize) > HighestPhysicalAddressInPfnDatabase) { 00573 Status = STATUS_INVALID_PARAMETER_6; 00574 goto ErrorReturn; 00575 } 00576 } 00577 00578 } else { 00579 00580 // 00581 // Make sure alignments are correct for specified address 00582 // and offset into the file. 00583 // 00584 00585 if ((AllocationType & MEM_DOS_LIM) == 0) { 00586 if (((ULONG_PTR)CapturedBase & (X64K - 1)) != 0) { 00587 Status = STATUS_MAPPED_ALIGNMENT; 00588 goto ErrorReturn; 00589 } 00590 00591 if ((ARGUMENT_PRESENT (SectionOffset)) && 00592 ((CapturedOffset.LowPart & (X64K - 1)) != 0)) { 00593 Status = STATUS_MAPPED_ALIGNMENT; 00594 goto ErrorReturn; 00595 } 00596 } 00597 } 00598 00599 // 00600 // Check to make sure the view size plus the offset is less 00601 // than the size of the section. 00602 // 00603 00604 if ((ULONGLONG) (CapturedOffset.QuadPart + CapturedViewSize) < 00605 (ULONGLONG)CapturedOffset.QuadPart) { 00606 00607 Status = STATUS_INVALID_VIEW_SIZE; 00608 goto ErrorReturn; 00609 } 00610 00611 if (((ULONGLONG) (CapturedOffset.QuadPart + CapturedViewSize) > 00612 (ULONGLONG)Section->SizeOfSection.QuadPart) && 00613 ((AllocationType & MEM_RESERVE) == 0)) { 00614 00615 Status = STATUS_INVALID_VIEW_SIZE; 00616 goto ErrorReturn; 00617 } 00618 00619 if (CapturedViewSize == 0) { 00620 00621 // 00622 // Set the view size to be size of the section less the offset. 00623 // 00624 00625 TempViewSize.QuadPart = Section->SizeOfSection.QuadPart - 00626 CapturedOffset.QuadPart; 00627 00628 CapturedViewSize = (SIZE_T)TempViewSize.QuadPart; 00629 00630 if ( 00631 00632 #if !defined(_WIN64) 00633 00634 (TempViewSize.HighPart != 0) || 00635 00636 #endif 00637 00638 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)CapturedBase) < 00639 CapturedViewSize)) { 00640 00641 // 00642 // Invalid region size; 00643 // 00644 00645 Status = STATUS_INVALID_VIEW_SIZE; 00646 goto ErrorReturn; 00647 } 00648 } 00649 00650 // 00651 // Check commit size. 00652 // 00653 00654 if ((CommitSize > CapturedViewSize) && 00655 ((AllocationType & MEM_RESERVE) == 0)) { 00656 Status = STATUS_INVALID_PARAMETER_5; 00657 goto ErrorReturn; 00658 } 00659 00660 if (WriteCombined == TRUE) { 00661 Protect |= PAGE_WRITECOMBINE; 00662 } 00663 00664 Status = MmMapViewOfSection ( (PVOID)Section, 00665 Process, 00666 &CapturedBase, 00667 ZeroBits, 00668 CommitSize, 00669 &CapturedOffset, 00670 &CapturedViewSize, 00671 InheritDisposition, 00672 AllocationType, 00673 Protect); 00674 00675 if (!NT_SUCCESS(Status) ) { 00676 if ( (Section->Segment->ControlArea->u.Flags.Image) && 00677 Process == PsGetCurrentProcess() ) { 00678 if (Status == STATUS_CONFLICTING_ADDRESSES ) { 00679 DbgkMapViewOfSection( 00680 SectionHandle, 00681 CapturedBase, 00682 CapturedOffset.LowPart, 00683 CapturedViewSize 00684 ); 00685 } 00686 } 00687 goto ErrorReturn; 00688 } 00689 00690 // 00691 // Anytime the current process maps an image file, 00692 // a potential debug event occurs. DbgkMapViewOfSection 00693 // handles these events. 00694 // 00695 00696 if ( (Section->Segment->ControlArea->u.Flags.Image) && 00697 Process == PsGetCurrentProcess() ) { 00698 if (Status != STATUS_IMAGE_NOT_AT_BASE ) { 00699 DbgkMapViewOfSection( 00700 SectionHandle, 00701 CapturedBase, 00702 CapturedOffset.LowPart, 00703 CapturedViewSize 00704 ); 00705 } 00706 } 00707 00708 // 00709 // Establish an exception handler and write the size and base 00710 // address. 00711 // 00712 00713 try { 00714 00715 *ViewSize = CapturedViewSize; 00716 *BaseAddress = CapturedBase; 00717 00718 if (ARGUMENT_PRESENT(SectionOffset)) { 00719 *SectionOffset = CapturedOffset; 00720 } 00721 00722 } except (EXCEPTION_EXECUTE_HANDLER) { 00723 goto ErrorReturn; 00724 } 00725 00726 #if 0 // test code... 00727 if ((Status == STATUS_SUCCESS) && 00728 (Section->u.Flags.Image == 0)) { 00729 00730 PVOID Base; 00731 ULONG Size = 0; 00732 NTSTATUS Status; 00733 00734 Status = MmMapViewInSystemSpace ((PVOID)Section, 00735 &Base, 00736 &Size); 00737 if (Status == STATUS_SUCCESS) { 00738 MmUnmapViewInSystemSpace (Base); 00739 } 00740 } 00741 #endif //0 00742 00743 { 00744 ErrorReturn: 00745 ObDereferenceObject (Section); 00746 ErrorReturn1: 00747 ObDereferenceObject (Process); 00748 return Status; 00749 } 00750 }

VOID VadTreeWalk PMMVAD  Start  ) 
 


Variable Documentation

ULONG MMDB = 'bDmM'
 

Definition at line 26 of file mapview.c.

Referenced by MiMapViewOfImageSection().

LIST_ENTRY MmLoadedUserImageList
 

Definition at line 34 of file mapview.c.

ULONG MMPPTE_NAME = 'tPmM'
 

Definition at line 25 of file mapview.c.

Referenced by MiMapViewOfPhysicalSection().

MMSESSION MmSession
 

Definition at line 44 of file mapview.c.

Referenced by MiInitializeSystemSpaceMap(), MiLoadSystemImage(), MiMapViewInSystemSpace(), MiUnmapViewInSystemSpace(), MmMapViewInSessionSpace(), MmMapViewInSystemSpace(), MmUnmapViewInSessionSpace(), and MmUnmapViewInSystemSpace().

ULONG MMVADKEY
 

Definition at line 27 of file mapview.c.


Generated on Sat May 15 19:44:36 2004 for test by doxygen 1.3.7