ReactOS  0.4.12-dev-918-g6c6e7b8
special.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for special.c:

Go to the source code of this file.

Classes

struct  _MI_FREED_SPECIAL_POOL
 

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 
#define SPECIAL_POOL_PAGED_PTE   0x2000
 
#define SPECIAL_POOL_NONPAGED_PTE   0x4000
 
#define SPECIAL_POOL_PAGED   0x8000
 

Typedefs

typedef struct _MI_FREED_SPECIAL_POOL MI_FREED_SPECIAL_POOL
 
typedef struct _MI_FREED_SPECIAL_POOLPMI_FREED_SPECIAL_POOL
 

Functions

PMMPTE NTAPI MiReserveAlignedSystemPtes (IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType, IN ULONG Alignment)
 
VOID NTAPI MiTestSpecialPool (VOID)
 
BOOLEAN NTAPI MmUseSpecialPool (SIZE_T NumberOfBytes, ULONG Tag)
 
BOOLEAN NTAPI MmIsSpecialPoolAddress (PVOID P)
 
BOOLEAN NTAPI MmIsSpecialPoolAddressFree (PVOID P)
 
VOID NTAPI MiInitializeSpecialPool (VOID)
 
NTSTATUS NTAPI MmExpandSpecialPool (VOID)
 
PVOID NTAPI MmAllocateSpecialPool (SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG SpecialType)
 
VOID NTAPI MiSpecialPoolCheckPattern (PUCHAR P, PPOOL_HEADER Header)
 
VOID NTAPI MmFreeSpecialPool (PVOID P)
 

Variables

ULONG ExpPoolFlags
 
PMMPTE MmSystemPteBase
 
PVOID MmSpecialPoolStart
 
PVOID MmSpecialPoolEnd
 
PVOID MiSpecialPoolExtra
 
ULONG MiSpecialPoolExtraCount
 
PMMPTE MiSpecialPoolFirstPte
 
PMMPTE MiSpecialPoolLastPte
 
PFN_COUNT MmSpecialPagesInUse
 
PFN_COUNT MmSpecialPagesInUsePeak
 
PFN_COUNT MiSpecialPagesPagable
 
PFN_COUNT MiSpecialPagesPagablePeak
 
PFN_COUNT MiSpecialPagesNonPaged
 
PFN_COUNT MiSpecialPagesNonPagedPeak
 
PFN_COUNT MiSpecialPagesNonPagedMaximum
 
BOOLEAN MmSpecialPoolCatchOverruns = TRUE
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 20 of file special.c.

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file special.c.

◆ SPECIAL_POOL_NONPAGED_PTE

#define SPECIAL_POOL_NONPAGED_PTE   0x4000

Definition at line 35 of file special.c.

◆ SPECIAL_POOL_PAGED

#define SPECIAL_POOL_PAGED   0x8000

Definition at line 36 of file special.c.

◆ SPECIAL_POOL_PAGED_PTE

#define SPECIAL_POOL_PAGED_PTE   0x2000

Definition at line 34 of file special.c.

Typedef Documentation

◆ MI_FREED_SPECIAL_POOL

◆ PMI_FREED_SPECIAL_POOL

Function Documentation

◆ MiInitializeSpecialPool()

VOID NTAPI MiInitializeSpecialPool ( VOID  )

Definition at line 123 of file special.c.

124 {
125  ULONG SpecialPoolPtes, i;
126  PMMPTE PointerPte;
127 
128  /* Check if there is a special pool tag */
129  if ((MmSpecialPoolTag == 0) ||
130  (MmSpecialPoolTag == -1)) return;
131 
132  /* Calculate number of system PTEs for the special pool */
133  if (MmNumberOfSystemPtes >= 0x3000)
134  SpecialPoolPtes = MmNumberOfSystemPtes / 3;
135  else
136  SpecialPoolPtes = MmNumberOfSystemPtes / 6;
137 
138  /* Don't let the number go too high */
139  if (SpecialPoolPtes > 0x6000) SpecialPoolPtes = 0x6000;
140 
141  /* Round up to the page size */
142  SpecialPoolPtes = PAGE_ROUND_UP(SpecialPoolPtes);
143 
144  ASSERT((SpecialPoolPtes & (PTE_PER_PAGE - 1)) == 0);
145 
146  /* Reserve those PTEs */
147  do
148  {
149  PointerPte = MiReserveAlignedSystemPtes(SpecialPoolPtes,
151  /*0x400000*/0); // FIXME:
152  if (PointerPte) break;
153 
154  /* Reserving didn't work, so try to reduce the requested size */
155  ASSERT(SpecialPoolPtes >= PTE_PER_PAGE);
156  SpecialPoolPtes -= PTE_PER_PAGE;
157  } while (SpecialPoolPtes);
158 
159  /* Fail if we couldn't reserve them at all */
160  if (!SpecialPoolPtes) return;
161 
162  /* Make sure we got enough */
163  ASSERT(SpecialPoolPtes >= PTE_PER_PAGE);
164 
165  /* Save first PTE and its address */
166  MiSpecialPoolFirstPte = PointerPte;
167  MmSpecialPoolStart = MiPteToAddress(PointerPte);
168 
169  for (i = 0; i < PTE_PER_PAGE / 2; i++)
170  {
171  /* Point it to the next entry */
172  PointerPte->u.List.NextEntry = &PointerPte[2] - MmSystemPteBase;
173 
174  /* Move to the next pair */
175  PointerPte += 2;
176  }
177 
178  /* Save extra values */
179  MiSpecialPoolExtra = PointerPte;
180  MiSpecialPoolExtraCount = SpecialPoolPtes - PTE_PER_PAGE;
181 
182  /* Mark the previous PTE as the last one */
183  MiSpecialPoolLastPte = PointerPte - 2;
185 
186  /* Save end address of the special pool */
188 
189  /* Calculate maximum non-paged part of the special pool */
191 
192  /* And limit it if it turned out to be too big */
193  if (MmNumberOfPhysicalPages > 0x3FFF)
195 
196  DPRINT1("Special pool start %p - end %p\n", MmSpecialPoolStart, MmSpecialPoolEnd);
198 
199  //MiTestSpecialPool();
200 }
PFN_NUMBER MmResidentAvailablePages
Definition: freelist.c:27
ULONG MiSpecialPoolExtraCount
Definition: special.c:41
ULONG64 NextEntry
Definition: mmtypes.h:145
union _MMPTE::@2227 u
#define MM_EMPTY_PTE_LIST
Definition: mm.h:84
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:297
ULONG MmNumberOfSystemPtes
Definition: init.c:42
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
PVOID MmSpecialPoolEnd
Definition: special.c:39
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG MmSpecialPoolTag
Definition: pool.c:27
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
PFN_COUNT MiSpecialPagesNonPagedMaximum
Definition: special.c:52
PVOID MiSpecialPoolExtra
Definition: special.c:40
MMPTE_LIST List
Definition: mmtypes.h:222
#define PTE_PER_PAGE
Definition: mm.h:20
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PMMPTE NTAPI MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType, IN ULONG Alignment)
Definition: syspte.c:88
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
PVOID MmSpecialPoolStart
Definition: special.c:38
PMMPTE MmSystemPteBase
Definition: syspte.c:21
#define DPRINT1
Definition: precomp.h:8
ULONG ExpPoolFlags
Definition: expool.c:48
unsigned int ULONG
Definition: retypes.h:1
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43

Referenced by MiBuildPagedPool().

◆ MiReserveAlignedSystemPtes()

PMMPTE NTAPI MiReserveAlignedSystemPtes ( IN ULONG  NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE  SystemPtePoolType,
IN ULONG  Alignment 
)

Definition at line 88 of file syspte.c.

91 {
92  KIRQL OldIrql;
93  PMMPTE PreviousPte, NextPte, ReturnPte;
95 
96  //
97  // Sanity check
98  //
100 
101  //
102  // Acquire the System PTE lock
103  //
105 
106  //
107  // Find the last cluster in the list that doesn't contain enough PTEs
108  //
109  PreviousPte = &MmFirstFreeSystemPte[SystemPtePoolType];
110 
111  while (PreviousPte->u.List.NextEntry != MM_EMPTY_PTE_LIST)
112  {
113  //
114  // Get the next cluster and its size
115  //
116  NextPte = MmSystemPteBase + PreviousPte->u.List.NextEntry;
117  ClusterSize = MI_GET_CLUSTER_SIZE(NextPte);
118 
119  //
120  // Check if this cluster contains enough PTEs
121  //
122  if (NumberOfPtes <= ClusterSize)
123  break;
124 
125  //
126  // On to the next cluster
127  //
128  PreviousPte = NextPte;
129  }
130 
131  //
132  // Make sure we didn't reach the end of the cluster list
133  //
134  if (PreviousPte->u.List.NextEntry == MM_EMPTY_PTE_LIST)
135  {
136  //
137  // Release the System PTE lock and return failure
138  //
140  return NULL;
141  }
142 
143  //
144  // Unlink the cluster
145  //
146  PreviousPte->u.List.NextEntry = NextPte->u.List.NextEntry;
147 
148  //
149  // Check if the reservation spans the whole cluster
150  //
151  if (ClusterSize == NumberOfPtes)
152  {
153  //
154  // Return the first PTE of this cluster
155  //
156  ReturnPte = NextPte;
157 
158  //
159  // Zero the cluster
160  //
161  if (NextPte->u.List.OneEntry == 0)
162  {
163  NextPte->u.Long = 0;
164  NextPte++;
165  }
166  NextPte->u.Long = 0;
167  }
168  else
169  {
170  //
171  // Divide the cluster into two parts
172  //
173  ClusterSize -= NumberOfPtes;
174  ReturnPte = NextPte + ClusterSize;
175 
176  //
177  // Set the size of the first cluster, zero the second if needed
178  //
179  if (ClusterSize == 1)
180  {
181  NextPte->u.List.OneEntry = 1;
182  ReturnPte->u.Long = 0;
183  }
184  else
185  {
186  NextPte++;
187  NextPte->u.List.NextEntry = ClusterSize;
188  }
189 
190  //
191  // Step through the cluster list to find out where to insert the first
192  //
193  PreviousPte = &MmFirstFreeSystemPte[SystemPtePoolType];
194 
195  while (PreviousPte->u.List.NextEntry != MM_EMPTY_PTE_LIST)
196  {
197  //
198  // Get the next cluster
199  //
200  NextPte = MmSystemPteBase + PreviousPte->u.List.NextEntry;
201 
202  //
203  // Check if the cluster to insert is smaller or of equal size
204  //
205  if (ClusterSize <= MI_GET_CLUSTER_SIZE(NextPte))
206  break;
207 
208  //
209  // On to the next cluster
210  //
211  PreviousPte = NextPte;
212  }
213 
214  //
215  // Retrieve the first cluster and link it back into the cluster list
216  //
217  NextPte = ReturnPte - ClusterSize;
218 
219  NextPte->u.List.NextEntry = PreviousPte->u.List.NextEntry;
220  PreviousPte->u.List.NextEntry = NextPte - MmSystemPteBase;
221  }
222 
223  //
224  // Decrease availability
225  //
226  MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
227 
228  //
229  // Release the System PTE lock
230  //
232 
233  //
234  // Flush the TLB
235  //
237 
238  //
239  // Return the reserved PTEs
240  //
241  return ReturnPte;
242 }
ULONG64 NextEntry
Definition: mmtypes.h:145
union _MMPTE::@2227 u
#define MM_EMPTY_PTE_LIST
Definition: mm.h:84
ULONG64 OneEntry
Definition: mmtypes.h:139
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPTE MmFirstFreeSystemPte[MaximumPtePoolTypes]
Definition: syspte.c:24
smooth NULL
Definition: ftsmooth.c:416
ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes]
Definition: syspte.c:25
MMPTE_LIST List
Definition: mmtypes.h:222
DWORD ClusterSize
Definition: format.c:67
FORCEINLINE ULONG MI_GET_CLUSTER_SIZE(IN PMMPTE Pte)
Definition: syspte.c:71
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define PAGE_SIZE
Definition: env_spec_w32.h:49
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
PMMPTE MmSystemPteBase
Definition: syspte.c:21
ULONG_PTR Long
Definition: mmtypes.h:215
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:209
unsigned int ULONG
Definition: retypes.h:1

Referenced by MiInitializeSpecialPool(), and MiReserveSystemPtes().

◆ MiSpecialPoolCheckPattern()

VOID NTAPI MiSpecialPoolCheckPattern ( PUCHAR  P,
PPOOL_HEADER  Header 
)

Definition at line 418 of file special.c.

419 {
420  ULONG BytesToCheck, BytesRequested, Index;
421  PUCHAR Ptr;
422 
423  /* Get amount of bytes user requested to be allocated by clearing out the paged mask */
424  BytesRequested = (Header->Ulong1 & ~SPECIAL_POOL_PAGED) & 0xFFFF;
425  ASSERT(BytesRequested <= PAGE_SIZE - sizeof(POOL_HEADER));
426 
427  /* Get a pointer to the end of user's area */
428  Ptr = P + BytesRequested;
429 
430  /* Calculate how many bytes to check */
431  BytesToCheck = (ULONG)((PUCHAR)PAGE_ALIGN(P) + PAGE_SIZE - Ptr);
432 
433  /* Remove pool header size if we're catching underruns */
434  if (((ULONG_PTR)P & (PAGE_SIZE - 1)) == 0)
435  {
436  /* User buffer is located in the beginning of the page */
437  BytesToCheck -= sizeof(POOL_HEADER);
438  }
439 
440  /* Check the pattern after user buffer */
441  for (Index = 0; Index < BytesToCheck; Index++)
442  {
443  /* Bugcheck if bytes don't match */
444  if (Ptr[Index] != Header->BlockSize)
445  {
446  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
447  (ULONG_PTR)P,
448  (ULONG_PTR)&Ptr[Index],
449  Header->BlockSize,
450  0x24);
451  }
452  }
453 }
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
struct _POOL_HEADER POOL_HEADER
uint32_t ULONG_PTR
Definition: typedefs.h:63
Definition: Header.h:8
static const UCHAR Index[8]
Definition: usbohci.c:18
#define PAGE_ALIGN(Va)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define P(row, col)
#define SPECIAL_POOL_PAGED
Definition: special.c:36
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107

Referenced by MmFreeSpecialPool().

◆ MiTestSpecialPool()

VOID NTAPI MiTestSpecialPool ( VOID  )

Definition at line 652 of file special.c.

653 {
654  ULONG i;
655  PVOID p1, p2[100];
656  //PUCHAR p3;
657  ULONG ByteSize;
659 
660  // First allocate/free
661  for (i=0; i<100; i++)
662  {
663  ByteSize = (100 * (i+1)) % (PAGE_SIZE - sizeof(POOL_HEADER));
664  p1 = MmAllocateSpecialPool(ByteSize, 'TEST', PoolType, 0);
665  DPRINT1("p1 %p size %lu\n", p1, ByteSize);
666  MmFreeSpecialPool(p1);
667  }
668 
669  // Now allocate all at once, then free at once
670  for (i=0; i<100; i++)
671  {
672  ByteSize = (100 * (i+1)) % (PAGE_SIZE - sizeof(POOL_HEADER));
673  p2[i] = MmAllocateSpecialPool(ByteSize, 'TEST', PoolType, 0);
674  DPRINT1("p2[%lu] %p size %lu\n", i, p1, ByteSize);
675  }
676  for (i=0; i<100; i++)
677  {
678  DPRINT1("Freeing %p\n", p2[i]);
679  MmFreeSpecialPool(p2[i]);
680  }
681 
682  // Overrun the buffer to test
683  //ByteSize = 16;
684  //p3 = MmAllocateSpecialPool(ByteSize, 'TEST', NonPagedPool, 0);
685  //p3[ByteSize] = 0xF1; // This should cause an exception
686 
687  // Underrun the buffer to test
688  //p3 = MmAllocateSpecialPool(ByteSize, 'TEST', NonPagedPool, 1);
689  //p3--;
690  //*p3 = 0xF1; // This should cause an exception
691 
692 }
PVOID NTAPI MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG SpecialType)
Definition: special.c:245
struct _POOL_HEADER POOL_HEADER
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
INT POOL_TYPE
Definition: typedefs.h:76
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI MmFreeSpecialPool(PVOID P)
Definition: special.c:457
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:389
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444

◆ MmAllocateSpecialPool()

PVOID NTAPI MmAllocateSpecialPool ( SIZE_T  NumberOfBytes,
ULONG  Tag,
POOL_TYPE  PoolType,
ULONG  SpecialType 
)

Definition at line 245 of file special.c.

246 {
247  KIRQL Irql;
249  PMMPTE PointerPte;
250  PFN_NUMBER PageFrameNumber;
251  LARGE_INTEGER TickCount;
252  PVOID Entry;
254  PFN_COUNT PagesInUse;
255 
256  DPRINT("MmAllocateSpecialPool(%x %x %x %x)\n", NumberOfBytes, Tag, PoolType, SpecialType);
257 
258  /* Check if the pool is initialized and quit if it's not */
259  if (!MiSpecialPoolFirstPte) return NULL;
260 
261  /* Get the pool type */
263 
264  /* Check whether current IRQL matches the pool type */
266 
267  if (((PoolType == PagedPool) && (Irql > APC_LEVEL)) ||
268  ((PoolType != PagedPool) && (Irql > DISPATCH_LEVEL)))
269  {
270  /* Bad caller */
271  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
272  Irql,
273  PoolType,
275  0x30);
276  }
277 
278  /* Some allocations from Mm must never use special pool */
279  if (Tag == 'tSmM')
280  {
281  /* Reject and let normal pool handle it */
282  return NULL;
283  }
284 
285  /* TODO: Take into account various limitations */
286 
287  /* Heed the maximum limit of nonpaged pages */
288  if ((PoolType == NonPagedPool) &&
290  {
291  return NULL;
292  }
293 
294  /* Lock PFN database */
296 
297  /* Reject allocation in case amount of available pages is too small */
298  if (MmAvailablePages < 0x100)
299  {
300  /* Release the PFN database lock */
302  DPRINT1("Special pool: MmAvailablePages 0x%x is too small\n", MmAvailablePages);
303  return NULL;
304  }
305 
306  /* Check if special pool PTE list is exhausted */
308  {
309  /* Try to expand it */
311  {
312  /* No reserves left, reject this allocation */
313  static int once;
315  if (!once++) DPRINT1("Special pool: No PTEs left!\n");
316  return NULL;
317  }
319  }
320 
321  /* Save allocation time */
322  KeQueryTickCount(&TickCount);
323 
324  /* Get a pointer to the first PTE */
325  PointerPte = MiSpecialPoolFirstPte;
326 
327  /* Set the first PTE pointer to the next one in the list */
329 
330  /* Allocate a physical page */
331  if (PoolType == PagedPool)
332  {
334  }
335  else
336  {
338  }
339  MI_SET_PROCESS2("Kernel-Special");
340  PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
341 
342  /* Initialize PFN and make it valid */
343  TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
344  MiInitializePfnAndMakePteValid(PageFrameNumber, PointerPte, TempPte);
345 
346  /* Release the PFN database lock */
348 
349  /* Increase page counter */
351  if (PagesInUse > MmSpecialPagesInUsePeak)
352  MmSpecialPagesInUsePeak = PagesInUse;
353 
354  /* Put some content into the page. Low value of tick count would do */
355  Entry = MiPteToAddress(PointerPte);
356  RtlFillMemory(Entry, PAGE_SIZE, TickCount.LowPart);
357 
358  /* Calculate header and entry addresses */
359  if ((SpecialType != 0) &&
360  ((SpecialType == 1) || (!MmSpecialPoolCatchOverruns)))
361  {
362  /* We catch underruns. Data is at the beginning of the page */
364  }
365  else
366  {
367  /* We catch overruns. Data is at the end of the page */
370  }
371 
372  /* Initialize the header */
373  RtlZeroMemory(Header, sizeof(POOL_HEADER));
374 
375  /* Save allocation size there */
376  Header->Ulong1 = (ULONG)NumberOfBytes;
377 
378  /* Make sure it's all good */
379  ASSERT((NumberOfBytes <= PAGE_SIZE - sizeof(POOL_HEADER)) &&
380  (PAGE_SIZE <= 32 * 1024));
381 
382  /* Mark it as paged or nonpaged */
383  if (PoolType == PagedPool)
384  {
385  /* Add pagedpool flag into the pool header too */
386  Header->Ulong1 |= SPECIAL_POOL_PAGED;
387 
388  /* Also mark the next PTE as special-pool-paged */
389  PointerPte[1].u.Soft.PageFileHigh |= SPECIAL_POOL_PAGED_PTE;
390 
391  /* Increase pagable counter */
393  if (PagesInUse > MiSpecialPagesPagablePeak)
394  MiSpecialPagesPagablePeak = PagesInUse;
395  }
396  else
397  {
398  /* Mark the next PTE as special-pool-nonpaged */
399  PointerPte[1].u.Soft.PageFileHigh |= SPECIAL_POOL_NONPAGED_PTE;
400 
401  /* Increase nonpaged counter */
403  if (PagesInUse > MiSpecialPagesNonPagedPeak)
404  MiSpecialPagesNonPagedPeak = PagesInUse;
405  }
406 
407  /* Finally save tag and put allocation time into the header's blocksize.
408  That time will be used to check memory consistency within the allocated
409  page. */
410  Header->PoolTag = Tag;
411  Header->BlockSize = (UCHAR)TickCount.LowPart;
412  DPRINT("%p\n", Entry);
413  return Entry;
414 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define LONG_PTR
Definition: treelist.c:79
ULONG64 NextEntry
Definition: mmtypes.h:145
struct _Entry Entry
Definition: kefuncs.h:640
union _MMPTE::@2227 u
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define MM_EMPTY_PTE_LIST
Definition: mm.h:84
unsigned char * PUCHAR
Definition: retypes.h:3
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:246
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
struct _POOL_HEADER POOL_HEADER
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
_Out_ PKIRQL Irql
Definition: csq.h:179
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:8
PFN_COUNT MiSpecialPagesNonPagedPeak
Definition: special.c:51
Definition: Header.h:8
PFN_COUNT MiSpecialPagesPagable
Definition: special.c:48
#define SPECIAL_POOL_PAGED_PTE
Definition: special.c:34
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
smooth NULL
Definition: ftsmooth.c:416
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
void DPRINT(...)
Definition: polytest.cpp:61
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
#define MI_SET_USAGE(x)
Definition: mm.h:253
void * PVOID
Definition: retypes.h:9
struct _POOL_HEADER * PPOOL_HEADER
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
PFN_COUNT MiSpecialPagesNonPagedMaximum
Definition: special.c:52
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
MMPTE_LIST List
Definition: mmtypes.h:222
PFN_COUNT MiSpecialPagesNonPaged
Definition: special.c:50
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: init.c:31
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
ULONG64 PageFileHigh
Definition: mmtypes.h:93
ULONG LowPart
Definition: typedefs.h:104
#define PAGE_SIZE
Definition: env_spec_w32.h:49
BOOLEAN MmSpecialPoolCatchOverruns
Definition: special.c:54
#define SPECIAL_POOL_PAGED
Definition: special.c:36
PFN_COUNT MmSpecialPagesInUse
Definition: special.c:46
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
NTSTATUS NTAPI MmExpandSpecialPool(VOID)
Definition: special.c:204
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1513
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
PMMPTE MmSystemPteBase
Definition: syspte.c:21
#define DPRINT1
Definition: precomp.h:8
#define SPECIAL_POOL_NONPAGED_PTE
Definition: special.c:35
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
PFN_COUNT MiSpecialPagesPagablePeak
Definition: special.c:49
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1036
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:997
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PFN_COUNT MmSpecialPagesInUsePeak
Definition: special.c:47
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define APC_LEVEL
Definition: env_spec_w32.h:695
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107
ULONG PageFrameNumber
Definition: mmtypes.h:109

Referenced by MiTestSpecialPool().

◆ MmExpandSpecialPool()

NTSTATUS NTAPI MmExpandSpecialPool ( VOID  )

Definition at line 204 of file special.c.

205 {
206  ULONG i;
207  PMMPTE PointerPte;
208 
210 
211  if (MiSpecialPoolExtraCount == 0)
213 
214  PointerPte = MiSpecialPoolExtra;
218 
220  for (i = 0; i < PTE_PER_PAGE / 2; i++)
221  {
222  /* Point it to the next entry */
223  PointerPte->u.List.NextEntry = &PointerPte[2] - MmSystemPteBase;
224 
225  /* Move to the next pair */
226  PointerPte += 2;
227  }
228 
229  /* Save remaining extra values */
230  MiSpecialPoolExtra = PointerPte;
232 
233  /* Mark the previous PTE as the last one */
234  MiSpecialPoolLastPte = PointerPte - 2;
236 
237  /* Save new end address of the special pool */
239 
240  return STATUS_SUCCESS;
241 }
ULONG MiSpecialPoolExtraCount
Definition: special.c:41
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
ULONG64 NextEntry
Definition: mmtypes.h:145
union _MMPTE::@2227 u
#define MM_EMPTY_PTE_LIST
Definition: mm.h:84
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
PVOID MmSpecialPoolEnd
Definition: special.c:39
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
PVOID MiSpecialPoolExtra
Definition: special.c:40
MMPTE_LIST List
Definition: mmtypes.h:222
#define PTE_PER_PAGE
Definition: mm.h:20
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PMMPTE MmSystemPteBase
Definition: syspte.c:21
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2725
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43

Referenced by MmAllocateSpecialPool().

◆ MmFreeSpecialPool()

VOID NTAPI MmFreeSpecialPool ( PVOID  P)

Definition at line 457 of file special.c.

458 {
459  PMMPTE PointerPte;
461  BOOLEAN Overruns = FALSE;
464  ULONG BytesRequested, BytesReal = 0;
466  PUCHAR b;
467  PMI_FREED_SPECIAL_POOL FreedHeader;
468  LARGE_INTEGER TickCount;
469  PMMPFN Pfn;
470 
471  DPRINT("MmFreeSpecialPool(%p)\n", P);
472 
473  /* Get the PTE */
474  PointerPte = MiAddressToPte(P);
475 
476  /* Check if it's valid */
477  if (PointerPte->u.Hard.Valid == 0)
478  {
479  /* Bugcheck if it has NOACCESS or 0 set as protection */
480  if (PointerPte->u.Soft.Protection == MM_NOACCESS ||
481  !PointerPte->u.Soft.Protection)
482  {
483  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
484  (ULONG_PTR)P,
485  (ULONG_PTR)PointerPte,
486  0,
487  0x20);
488  }
489  }
490 
491  /* Determine if it's a underruns or overruns pool pointer */
492  PtrOffset = (ULONG)((ULONG_PTR)P & (PAGE_SIZE - 1));
493  if (PtrOffset)
494  {
495  /* Pool catches overruns */
496  Header = PAGE_ALIGN(P);
497  Overruns = TRUE;
498  }
499  else
500  {
501  /* Pool catches underruns */
503  }
504 
505  /* Check if it's non paged pool */
506  if ((Header->Ulong1 & SPECIAL_POOL_PAGED) == 0)
507  {
508  /* Non-paged allocation, ensure that IRQ is not higher that DISPATCH */
510  ASSERT(PointerPte[1].u.Soft.PageFileHigh == SPECIAL_POOL_NONPAGED_PTE);
511  if (Irql > DISPATCH_LEVEL)
512  {
513  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
514  Irql,
515  PoolType,
516  (ULONG_PTR)P,
517  0x31);
518  }
519  }
520  else
521  {
522  /* Paged allocation, ensure */
524  ASSERT(PointerPte[1].u.Soft.PageFileHigh == SPECIAL_POOL_PAGED_PTE);
525  if (Irql > APC_LEVEL)
526  {
527  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
528  Irql,
529  PoolType,
530  (ULONG_PTR)P,
531  0x31);
532  }
533  }
534 
535  /* Get amount of bytes user requested to be allocated by clearing out the paged mask */
536  BytesRequested = (Header->Ulong1 & ~SPECIAL_POOL_PAGED) & 0xFFFF;
537  ASSERT(BytesRequested <= PAGE_SIZE - sizeof(POOL_HEADER));
538 
539  /* Check memory before the allocated user buffer in case of overruns detection */
540  if (Overruns)
541  {
542  /* Calculate the real placement of the buffer */
543  BytesReal = PAGE_SIZE - PtrOffset;
544 
545  /* If they mismatch, it's unrecoverable */
546  if (BytesRequested > BytesReal)
547  {
548  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
549  (ULONG_PTR)P,
550  BytesRequested,
551  BytesReal,
552  0x21);
553  }
554 
555  if (BytesRequested + sizeof(POOL_HEADER) < BytesReal)
556  {
557  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
558  (ULONG_PTR)P,
559  BytesRequested,
560  BytesReal,
561  0x22);
562  }
563 
564  /* Actually check the memory pattern */
565  for (b = (PUCHAR)(Header + 1); b < (PUCHAR)P; b++)
566  {
567  if (*b != Header->BlockSize)
568  {
569  /* Bytes mismatch */
570  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
571  (ULONG_PTR)P,
572  (ULONG_PTR)b,
573  Header->BlockSize,
574  0x23);
575  }
576  }
577  }
578 
579  /* Check the memory pattern after the user buffer */
581 
582  /* Fill the freed header */
583  KeQueryTickCount(&TickCount);
584  FreedHeader = (PMI_FREED_SPECIAL_POOL)PAGE_ALIGN(P);
585  FreedHeader->Signature = 0x98764321;
586  FreedHeader->TickCount = TickCount.LowPart;
587  FreedHeader->NumberOfBytesRequested = BytesRequested;
588  FreedHeader->Pagable = PoolType;
589  FreedHeader->VirtualAddress = P;
590  FreedHeader->Thread = PsGetCurrentThread();
591  /* TODO: Fill StackPointer and StackBytes */
592  FreedHeader->StackPointer = NULL;
593  FreedHeader->StackBytes = 0;
594 
595  if (PoolType == NonPagedPool)
596  {
597  /* Non pagable. Get PFN element corresponding to the PTE */
598  Pfn = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
599 
600  /* Count the page as free */
602 
603  /* Lock PFN database */
605 
606  /* Delete this PFN */
607  MI_SET_PFN_DELETED(Pfn);
608 
609  /* Decrement share count of this PFN */
610  MiDecrementShareCount(Pfn, PointerPte->u.Hard.PageFrameNumber);
611 
612  MI_ERASE_PTE(PointerPte);
613 
614  /* Flush the TLB */
615  //FIXME: Use KeFlushSingleTb() instead
617  }
618  else
619  {
620  /* Pagable. Delete that virtual address */
621  MiDeleteSystemPageableVm(PointerPte, 1, 0, NULL);
622 
623  /* Count the page as free */
625 
626  /* Lock PFN database */
628  }
629 
630  /* Mark next PTE as invalid */
631  MI_ERASE_PTE(PointerPte + 1);
632 
633  /* Make sure that the last entry is really the last one */
635 
636  /* Update the current last PTE next pointer */
638 
639  /* PointerPte becomes the new last PTE */
640  PointerPte->u.List.NextEntry = MM_EMPTY_PTE_LIST;
641  MiSpecialPoolLastPte = PointerPte;
642 
643  /* Release the PFN database lock */
645 
646  /* Update page counter */
648 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:994
#define TRUE
Definition: types.h:120
ULONG64 NextEntry
Definition: mmtypes.h:145
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PtrOffset(BASE, OFFSET)
Definition: cdprocs.h:1557
union _MMPTE::@2227 u
#define MM_EMPTY_PTE_LIST
Definition: mm.h:84
unsigned char * PUCHAR
Definition: retypes.h:3
#define MM_NOACCESS
Definition: miarm.h:69
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
struct _POOL_HEADER POOL_HEADER
_Out_ PKIRQL Irql
Definition: csq.h:179
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
uint32_t ULONG_PTR
Definition: typedefs.h:63
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MiAddressToPte(x)
Definition: mmx86.c:19
Definition: Header.h:8
PFN_COUNT MiSpecialPagesPagable
Definition: special.c:48
#define SPECIAL_POOL_PAGED_PTE
Definition: special.c:34
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
ULONG64 Protection
Definition: mmtypes.h:88
struct _POOL_HEADER * PPOOL_HEADER
ULONG NumberOfBytesRequested
Definition: special.c:62
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:413
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
MMPTE_LIST List
Definition: mmtypes.h:222
INT POOL_TYPE
Definition: typedefs.h:76
ULONG64 Valid
Definition: mmtypes.h:150
#define PAGE_ALIGN(Va)
PFN_COUNT MiSpecialPagesNonPaged
Definition: special.c:50
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1428
Definition: mm.h:305
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1510
ULONG LowPart
Definition: typedefs.h:104
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI MiSpecialPoolCheckPattern(PUCHAR P, PPOOL_HEADER Header)
Definition: special.c:418
#define P(row, col)
#define SPECIAL_POOL_PAGED
Definition: special.c:36
PFN_COUNT MmSpecialPagesInUse
Definition: special.c:46
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:297
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:198
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
PMMPTE MmSystemPteBase
Definition: syspte.c:21
#define SPECIAL_POOL_NONPAGED_PTE
Definition: special.c:35
struct _MI_FREED_SPECIAL_POOL * PMI_FREED_SPECIAL_POOL
unsigned int ULONG
Definition: retypes.h:1
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107

Referenced by MiTestSpecialPool().

◆ MmIsSpecialPoolAddress()

BOOLEAN NTAPI MmIsSpecialPoolAddress ( PVOID  P)

Definition at line 95 of file special.c.

96 {
97  return ((P >= MmSpecialPoolStart) &&
98  (P <= MmSpecialPoolEnd));
99 }
PVOID MmSpecialPoolEnd
Definition: special.c:39
#define P(row, col)
PVOID MmSpecialPoolStart
Definition: special.c:38

Referenced by MmIsSpecialPoolAddressFree().

◆ MmIsSpecialPoolAddressFree()

BOOLEAN NTAPI MmIsSpecialPoolAddressFree ( PVOID  P)

Definition at line 103 of file special.c.

104 {
105  PMMPTE PointerPte;
106 
108  PointerPte = MiAddressToPte(P);
109 
110  if (PointerPte->u.Soft.PageFileHigh == SPECIAL_POOL_PAGED_PTE ||
112  {
113  /* Guard page PTE */
114  return FALSE;
115  }
116 
117  /* Free PTE */
118  return TRUE;
119 }
#define TRUE
Definition: types.h:120
union _MMPTE::@2227 u
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define SPECIAL_POOL_PAGED_PTE
Definition: special.c:34
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG64 PageFileHigh
Definition: mmtypes.h:93
#define P(row, col)
BOOLEAN NTAPI MmIsSpecialPoolAddress(PVOID P)
Definition: special.c:95
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
#define SPECIAL_POOL_NONPAGED_PTE
Definition: special.c:35

◆ MmUseSpecialPool()

BOOLEAN NTAPI MmUseSpecialPool ( SIZE_T  NumberOfBytes,
ULONG  Tag 
)

Definition at line 77 of file special.c.

78 {
79  /* Special pool is not suitable for allocations bigger than 1 page */
80  if (NumberOfBytes > (PAGE_SIZE - sizeof(POOL_HEADER)))
81  {
82  return FALSE;
83  }
84 
85  if (MmSpecialPoolTag == '*')
86  {
87  return TRUE;
88  }
89 
90  return Tag == MmSpecialPoolTag;
91 }
#define TRUE
Definition: types.h:120
ULONG MmSpecialPoolTag
Definition: pool.c:27
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:997

Variable Documentation

◆ ExpPoolFlags

◆ MiSpecialPagesNonPaged

PFN_COUNT MiSpecialPagesNonPaged

Definition at line 50 of file special.c.

Referenced by MmAllocateSpecialPool(), and MmFreeSpecialPool().

◆ MiSpecialPagesNonPagedMaximum

PFN_COUNT MiSpecialPagesNonPagedMaximum

Definition at line 52 of file special.c.

Referenced by MiInitializeSpecialPool(), and MmAllocateSpecialPool().

◆ MiSpecialPagesNonPagedPeak

PFN_COUNT MiSpecialPagesNonPagedPeak

Definition at line 51 of file special.c.

Referenced by MmAllocateSpecialPool().

◆ MiSpecialPagesPagable

PFN_COUNT MiSpecialPagesPagable

Definition at line 48 of file special.c.

Referenced by MmAllocateSpecialPool(), and MmFreeSpecialPool().

◆ MiSpecialPagesPagablePeak

PFN_COUNT MiSpecialPagesPagablePeak

Definition at line 49 of file special.c.

Referenced by MmAllocateSpecialPool().

◆ MiSpecialPoolExtra

PVOID MiSpecialPoolExtra

Definition at line 40 of file special.c.

Referenced by MiInitializeSpecialPool(), and MmExpandSpecialPool().

◆ MiSpecialPoolExtraCount

ULONG MiSpecialPoolExtraCount

Definition at line 41 of file special.c.

Referenced by MiInitializeSpecialPool(), and MmExpandSpecialPool().

◆ MiSpecialPoolFirstPte

PMMPTE MiSpecialPoolFirstPte

Definition at line 43 of file special.c.

Referenced by MiInitializeSpecialPool(), MmAllocateSpecialPool(), and MmExpandSpecialPool().

◆ MiSpecialPoolLastPte

PMMPTE MiSpecialPoolLastPte

Definition at line 44 of file special.c.

Referenced by MiInitializeSpecialPool(), MmExpandSpecialPool(), and MmFreeSpecialPool().

◆ MmSpecialPagesInUse

PFN_COUNT MmSpecialPagesInUse

Definition at line 46 of file special.c.

Referenced by MmAllocateSpecialPool(), and MmFreeSpecialPool().

◆ MmSpecialPagesInUsePeak

PFN_COUNT MmSpecialPagesInUsePeak

Definition at line 47 of file special.c.

Referenced by MmAllocateSpecialPool().

◆ MmSpecialPoolCatchOverruns

BOOLEAN MmSpecialPoolCatchOverruns = TRUE

Definition at line 54 of file special.c.

Referenced by MmAllocateSpecialPool().

◆ MmSpecialPoolEnd

PVOID MmSpecialPoolEnd

Definition at line 39 of file special.c.

Referenced by MiInitializeSpecialPool(), MmExpandSpecialPool(), and MmIsSpecialPoolAddress().

◆ MmSpecialPoolStart

PVOID MmSpecialPoolStart

Definition at line 38 of file special.c.

Referenced by MiInitializeSpecialPool(), and MmIsSpecialPoolAddress().

◆ MmSystemPteBase