ReactOS 0.4.15-dev-7918-g2a2556c
region.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for region.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static VOID InsertAfterEntry (PLIST_ENTRY Previous, PLIST_ENTRY Entry)
 
static PMM_REGION MmSplitRegion (PMM_REGION InitialRegion, PVOID InitialBaseAddress, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMMSUPPORT AddressSpace, PMM_ALTER_REGION_FUNC AlterFunc)
 
NTSTATUS NTAPI MmAlterRegion (PMMSUPPORT AddressSpace, PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc)
 
VOID NTAPI MmInitializeRegion (PLIST_ENTRY RegionListHead, SIZE_T Length, ULONG Type, ULONG Protect)
 
PMM_REGION NTAPI MmFindRegion (PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file region.c.

Function Documentation

◆ InsertAfterEntry()

static VOID InsertAfterEntry ( PLIST_ENTRY  Previous,
PLIST_ENTRY  Entry 
)
static

Definition at line 19 of file region.c.

24{
25 Previous->Flink->Blink = Entry;
26
27 Entry->Flink = Previous->Flink;
28 Entry->Blink = Previous;
29
30 Previous->Flink = Entry;
31}
base of all file and directory entries
Definition: entries.h:83
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

Referenced by MmSplitRegion().

◆ MmAlterRegion()

NTSTATUS NTAPI MmAlterRegion ( PMMSUPPORT  AddressSpace,
PVOID  BaseAddress,
PLIST_ENTRY  RegionListHead,
PVOID  StartAddress,
SIZE_T  Length,
ULONG  NewType,
ULONG  NewProtect,
PMM_ALTER_REGION_FUNC  AlterFunc 
)

Definition at line 108 of file region.c.

111{
112 PMM_REGION InitialRegion;
113 PVOID InitialBaseAddress = NULL;
114 PMM_REGION NewRegion;
115 PLIST_ENTRY CurrentEntry;
116 PMM_REGION CurrentRegion = NULL;
117 PVOID CurrentBaseAddress;
118 SIZE_T RemainingLength;
119
120 /*
121 * Find the first region containing part of the range of addresses to
122 * be altered.
123 */
124 InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress,
125 &InitialBaseAddress);
126 /*
127 * If necessary then split the region into the affected and unaffected parts.
128 */
129 if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect)
130 {
131 NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress,
132 StartAddress, Length, NewType, NewProtect,
133 AddressSpace, AlterFunc);
134 if (NewRegion == NULL)
135 {
136 return(STATUS_NO_MEMORY);
137 }
138 if(NewRegion->Length < Length)
139 RemainingLength = Length - NewRegion->Length;
140 else
141 RemainingLength = 0;
142 }
143 else
144 {
145 NewRegion = InitialRegion;
146 if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) <
147 ((ULONG_PTR)StartAddress + Length))
148 RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length);
149 else
150 RemainingLength = 0;
151 }
152
153 /*
154 * Free any complete regions that are containing in the range of addresses
155 * and call the helper function to actually do the changes.
156 */
157 CurrentEntry = NewRegion->RegionListEntry.Flink;
158 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
159 RegionListEntry);
160 CurrentBaseAddress = (char*)StartAddress + NewRegion->Length;
161 while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength &&
162 CurrentEntry != RegionListHead)
163 {
164 if (CurrentRegion->Type != NewType ||
165 CurrentRegion->Protect != NewProtect)
166 {
167 AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length,
168 CurrentRegion->Type, CurrentRegion->Protect,
169 NewType, NewProtect);
170 }
171
172 CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length);
173 NewRegion->Length += CurrentRegion->Length;
174 RemainingLength -= CurrentRegion->Length;
175 CurrentEntry = CurrentEntry->Flink;
176 RemoveEntryList(&CurrentRegion->RegionListEntry);
177 ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
178 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
179 RegionListEntry);
180 }
181
182 /*
183 * Split any final region.
184 */
185 if (RemainingLength > 0 && CurrentEntry != RegionListHead)
186 {
187 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
188 RegionListEntry);
189 if (CurrentRegion->Type != NewType ||
190 CurrentRegion->Protect != NewProtect)
191 {
192 AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength,
193 CurrentRegion->Type, CurrentRegion->Protect,
194 NewType, NewProtect);
195 }
196 NewRegion->Length += RemainingLength;
197 CurrentRegion->Length -= RemainingLength;
198 }
199
200 /*
201 * If the region after the new region has the same type then merge them.
202 */
203 if (NewRegion->RegionListEntry.Flink != RegionListHead)
204 {
205 CurrentEntry = NewRegion->RegionListEntry.Flink;
206 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
207 RegionListEntry);
208 if (CurrentRegion->Type == NewRegion->Type &&
209 CurrentRegion->Protect == NewRegion->Protect)
210 {
211 NewRegion->Length += CurrentRegion->Length;
212 RemoveEntryList(&CurrentRegion->RegionListEntry);
213 ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
214 }
215 }
216
217 /*
218 * If the region before the new region has the same type then merge them.
219 */
220 if (NewRegion->RegionListEntry.Blink != RegionListHead)
221 {
222 CurrentEntry = NewRegion->RegionListEntry.Blink;
223 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
224 RegionListEntry);
225 if (CurrentRegion->Type == NewRegion->Type &&
226 CurrentRegion->Protect == NewRegion->Protect)
227 {
228 NewRegion->Length += CurrentRegion->Length;
229 RemoveEntryList(&CurrentRegion->RegionListEntry);
230 ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
231 }
232 }
233
234 return(STATUS_SUCCESS);
235}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define NULL
Definition: types.h:112
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static PMM_REGION MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMMSUPPORT AddressSpace, PMM_ALTER_REGION_FUNC AlterFunc)
Definition: region.c:34
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
Definition: mm.h:463
LIST_ENTRY RegionListEntry
Definition: mm.h:467
ULONG Type
Definition: mm.h:464
SIZE_T Length
Definition: mm.h:466
ULONG Protect
Definition: mm.h:465
#define TAG_MM_REGION
Definition: tag.h:111
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682

Referenced by MmAccessFaultSectionView(), MmNotPresentFaultSectionView(), and MmProtectSectionView().

◆ MmFindRegion()

PMM_REGION NTAPI MmFindRegion ( PVOID  BaseAddress,
PLIST_ENTRY  RegionListHead,
PVOID  Address,
PVOID RegionBaseAddress 
)

Definition at line 257 of file region.c.

259{
260 PLIST_ENTRY current_entry;
262 PVOID StartAddress = BaseAddress;
263
264 current_entry = RegionListHead->Flink;
265 while (current_entry != RegionListHead)
266 {
267 current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry);
268
269 if (StartAddress <= Address &&
270 ((char*)StartAddress + current->Length) > (char*)Address)
271 {
272 if (RegionBaseAddress != NULL)
273 {
274 *RegionBaseAddress = StartAddress;
275 }
276 return(current);
277 }
278
279 current_entry = current_entry->Flink;
280
281 StartAddress = (PVOID)((ULONG_PTR)StartAddress + current->Length);
282
283 }
284 return(NULL);
285}
struct task_struct * current
Definition: linux.c:32
static WCHAR Address[46]
Definition: ping.c:68

Referenced by MmAccessFaultSectionView(), MmAlterRegion(), MmNotPresentFaultSectionView(), MmPageOutPhysicalAddress(), MmProtectSectionView(), and MmQuerySectionView().

◆ MmInitializeRegion()

VOID NTAPI MmInitializeRegion ( PLIST_ENTRY  RegionListHead,
SIZE_T  Length,
ULONG  Type,
ULONG  Protect 
)

Definition at line 239 of file region.c.

241{
243
246 if (!Region) return;
247
248 Region->Type = Type;
249 Region->Protect = Protect;
250 Region->Length = Length;
251 InitializeListHead(RegionListHead);
252 InsertHeadList(RegionListHead, &Region->RegionListEntry);
253}
Type
Definition: Type.h:7
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:221

Referenced by MmMapViewOfSegment().

◆ MmSplitRegion()

static PMM_REGION MmSplitRegion ( PMM_REGION  InitialRegion,
PVOID  InitialBaseAddress,
PVOID  StartAddress,
SIZE_T  Length,
ULONG  NewType,
ULONG  NewProtect,
PMMSUPPORT  AddressSpace,
PMM_ALTER_REGION_FUNC  AlterFunc 
)
static

Definition at line 34 of file region.c.

38{
39 PMM_REGION NewRegion1;
40 PMM_REGION NewRegion2;
41 SIZE_T InternalLength;
42
43 /* Allocate this in front otherwise the failure case is too difficult. */
44 NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
46 if (NewRegion2 == NULL)
47 {
48 return(NULL);
49 }
50
51 /* Create the new region. */
52 NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
54 if (NewRegion1 == NULL)
55 {
57 return(NULL);
58 }
59 NewRegion1->Type = NewType;
60 NewRegion1->Protect = NewProtect;
61 InternalLength = ((char*)InitialBaseAddress + InitialRegion->Length) - (char*)StartAddress;
62 InternalLength = min(InternalLength, Length);
63 NewRegion1->Length = InternalLength;
64 InsertAfterEntry(&InitialRegion->RegionListEntry,
65 &NewRegion1->RegionListEntry);
66
67 /*
68 * Call our helper function to do the changes on the addresses contained
69 * in the initial region.
70 */
71 AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type,
72 InitialRegion->Protect, NewType, NewProtect);
73
74 /*
75 * If necessary create a new region for the portion of the initial region
76 * beyond the range of addresses to alter.
77 */
78 if (((char*)InitialBaseAddress + InitialRegion->Length) > ((char*)StartAddress + Length))
79 {
80 NewRegion2->Type = InitialRegion->Type;
81 NewRegion2->Protect = InitialRegion->Protect;
82 NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) -
83 ((char*)StartAddress + Length);
85 &NewRegion2->RegionListEntry);
86 }
87 else
88 {
90 }
91
92 /* Either remove or shrink the initial region. */
93 if (InitialBaseAddress == StartAddress)
94 {
95 RemoveEntryList(&InitialRegion->RegionListEntry);
96 ExFreePoolWithTag(InitialRegion, TAG_MM_REGION);
97 }
98 else
99 {
100 InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress;
101 }
102
103 return(NewRegion1);
104}
#define min(a, b)
Definition: monoChain.cc:55
static VOID InsertAfterEntry(PLIST_ENTRY Previous, PLIST_ENTRY Entry)
Definition: region.c:19

Referenced by MmAlterRegion().