ReactOS  0.4.15-dev-499-g1f31905
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 }
struct _Entry Entry
Definition: kefuncs.h:627
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
base of all file and directory entries
Definition: entries.h:82

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 }
struct _LIST_ENTRY * Blink
Definition: typedefs.h:121
#define TAG_MM_REGION
Definition: tag.h:130
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
Definition: mm.h:390
uint32_t ULONG_PTR
Definition: typedefs.h:64
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
while(1)
Definition: macro.lex.yy.c:740
ULONG Type
Definition: mm.h:392
smooth NULL
Definition: ftsmooth.c:416
SIZE_T Length
Definition: mm.h:394
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG Protect
Definition: mm.h:393
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Definition: typedefs.h:118
ULONG_PTR SIZE_T
Definition: typedefs.h:79
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:683
LIST_ENTRY RegionListEntry
Definition: mm.h:395
#define ULONG_PTR
Definition: config.h:101
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by 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 }
Definition: mm.h:390
uint32_t ULONG_PTR
Definition: typedefs.h:64
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
Definition: typedefs.h:118
struct task_struct * current
Definition: linux.c:32

Referenced by MmAccessFaultSectionView(), MmAlterRegion(), MmNotPresentFaultSectionView(), 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 
245  TAG_MM_REGION);
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:6
_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:214
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define TAG_MM_REGION
Definition: tag.h:130
Definition: mm.h:390
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944

Referenced by _MiMapViewOfSegment(), and 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  {
56  ExFreePoolWithTag(NewRegion2, TAG_MM_REGION);
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);
84  InsertAfterEntry(&NewRegion1->RegionListEntry,
85  &NewRegion2->RegionListEntry);
86  }
87  else
88  {
89  ExFreePoolWithTag(NewRegion2, TAG_MM_REGION);
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 TAG_MM_REGION
Definition: tag.h:130
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
Definition: mm.h:390
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
ULONG Type
Definition: mm.h:392
smooth NULL
Definition: ftsmooth.c:416
SIZE_T Length
Definition: mm.h:394
ULONG Protect
Definition: mm.h:393
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static VOID InsertAfterEntry(PLIST_ENTRY Previous, PLIST_ENTRY Entry)
Definition: region.c:19
ULONG_PTR SIZE_T
Definition: typedefs.h:79
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:683
#define min(a, b)
Definition: monoChain.cc:55
LIST_ENTRY RegionListEntry
Definition: mm.h:395
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by MmAlterRegion().