ReactOS  r74006
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_POOL
PMI_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

#define MODULE_INVOLVED_IN_ARM3

Definition at line 20 of file special.c.

#define NDEBUG

Definition at line 17 of file special.c.

#define SPECIAL_POOL_NONPAGED_PTE   0x4000

Definition at line 35 of file special.c.

Referenced by MmAllocateSpecialPool(), MmFreeSpecialPool(), and MmIsSpecialPoolAddressFree().

#define SPECIAL_POOL_PAGED   0x8000

Definition at line 36 of file special.c.

Referenced by MiSpecialPoolCheckPattern(), MmAllocateSpecialPool(), and MmFreeSpecialPool().

#define SPECIAL_POOL_PAGED_PTE   0x2000

Definition at line 34 of file special.c.

Referenced by MmAllocateSpecialPool(), MmFreeSpecialPool(), and MmIsSpecialPoolAddressFree().

Typedef Documentation

Function Documentation

VOID NTAPI MiInitializeSpecialPool ( VOID  )

Definition at line 123 of file special.c.

Referenced by MiBuildPagedPool().

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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MM_EMPTY_PTE_LIST
Definition: mm.h:77
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:260
ULONG MmNumberOfSystemPtes
Definition: init.c:42
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
union _MMPTE::@1889 u
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
PVOID MmSpecialPoolEnd
Definition: special.c:39
GLenum GLclampf GLint i
Definition: glfuncs.h:14
ULONG MmSpecialPoolTag
Definition: pool.c:27
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
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:18
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:47
unsigned int ULONG
Definition: retypes.h:1
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43
PMMPTE NTAPI MiReserveAlignedSystemPtes ( IN ULONG  NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE  SystemPtePoolType,
IN ULONG  Alignment 
)

Definition at line 88 of file syspte.c.

Referenced by MiInitializeSpecialPool(), and MiReserveSystemPtes().

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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MM_EMPTY_PTE_LIST
Definition: mm.h:77
ULONG64 OneEntry
Definition: mmtypes.h:139
union _MMPTE::@1889 u
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPTE MmFirstFreeSystemPte[MaximumPtePoolTypes]
Definition: syspte.c:24
#define NULL
Definition: mystdio.h:57
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
_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:185
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI MiSpecialPoolCheckPattern ( PUCHAR  P,
PPOOL_HEADER  Header 
)

Definition at line 402 of file special.c.

Referenced by MmFreeSpecialPool().

403 {
404  ULONG BytesToCheck, BytesRequested, Index;
405  PUCHAR Ptr;
406 
407  /* Get amount of bytes user requested to be allocated by clearing out the paged mask */
408  BytesRequested = (Header->Ulong1 & ~SPECIAL_POOL_PAGED) & 0xFFFF;
409  ASSERT(BytesRequested <= PAGE_SIZE - sizeof(POOL_HEADER));
410 
411  /* Get a pointer to the end of user's area */
412  Ptr = P + BytesRequested;
413 
414  /* Calculate how many bytes to check */
415  BytesToCheck = (ULONG)((PUCHAR)PAGE_ALIGN(P) + PAGE_SIZE - Ptr);
416 
417  /* Remove pool header size if we're catching underruns */
418  if (((ULONG_PTR)P & (PAGE_SIZE - 1)) == 0)
419  {
420  /* User buffer is located in the beginning of the page */
421  BytesToCheck -= sizeof(POOL_HEADER);
422  }
423 
424  /* Check the pattern after user buffer */
425  for (Index = 0; Index < BytesToCheck; Index++)
426  {
427  /* Bugcheck if bytes don't match */
428  if (Ptr[Index] != Header->BlockSize)
429  {
430  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
431  (ULONG_PTR)P,
432  (ULONG_PTR)&Ptr[Index],
433  Header->BlockSize,
434  0x24);
435  }
436  }
437 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
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
_Must_inspect_result_ _In_ ULONG Index
Definition: fltkernel.h:1824
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define PAGE_ALIGN(Va)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#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:90
#define P(a, b, c, d, e, x)
VOID NTAPI MiTestSpecialPool ( VOID  )

Definition at line 636 of file special.c.

637 {
638  ULONG i;
639  PVOID p1, p2[100];
640  //PUCHAR p3;
641  ULONG ByteSize;
643 
644  // First allocate/free
645  for (i=0; i<100; i++)
646  {
647  ByteSize = (100 * (i+1)) % (PAGE_SIZE - sizeof(POOL_HEADER));
648  p1 = MmAllocateSpecialPool(ByteSize, 'TEST', PoolType, 0);
649  DPRINT1("p1 %p size %lu\n", p1, ByteSize);
650  MmFreeSpecialPool(p1);
651  }
652 
653  // Now allocate all at once, then free at once
654  for (i=0; i<100; i++)
655  {
656  ByteSize = (100 * (i+1)) % (PAGE_SIZE - sizeof(POOL_HEADER));
657  p2[i] = MmAllocateSpecialPool(ByteSize, 'TEST', PoolType, 0);
658  DPRINT1("p2[%lu] %p size %lu\n", i, p1, ByteSize);
659  }
660  for (i=0; i<100; i++)
661  {
662  DPRINT1("Freeing %p\n", p2[i]);
663  MmFreeSpecialPool(p2[i]);
664  }
665 
666  // Overrun the buffer to test
667  //ByteSize = 16;
668  //p3 = MmAllocateSpecialPool(ByteSize, 'TEST', NonPagedPool, 0);
669  //p3[ByteSize] = 0xF1; // This should cause an exception
670 
671  // Underrun the buffer to test
672  //p3 = MmAllocateSpecialPool(ByteSize, 'TEST', NonPagedPool, 1);
673  //p3--;
674  //*p3 = 0xF1; // This should cause an exception
675 
676 }
DWORD *typedef PVOID
Definition: winlogon.h:52
PVOID NTAPI MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG SpecialType)
Definition: special.c:245
struct _POOL_HEADER POOL_HEADER
const GLfloat * p2
Definition: s_aatritemp.h:44
GLenum GLclampf GLint i
Definition: glfuncs.h:14
INT POOL_TYPE
Definition: typedefs.h:77
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
#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:441
const GLfloat * p1
Definition: s_aatritemp.h:43
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:389
PVOID NTAPI MmAllocateSpecialPool ( SIZE_T  NumberOfBytes,
ULONG  Tag,
POOL_TYPE  PoolType,
ULONG  SpecialType 
)

Definition at line 245 of file special.c.

Referenced by MiTestSpecialPool().

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 */
265  Irql = KeGetCurrentIrql();
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  /* TODO: Take into account various limitations */
279 
280  /* Heed the maximum limit of nonpaged pages */
281  if ((PoolType == NonPagedPool) &&
283  {
284  return NULL;
285  }
286 
287  /* Lock PFN database */
289 
290  /* Reject allocation in case amount of available pages is too small */
291  if (MmAvailablePages < 0x100)
292  {
293  /* Release the PFN database lock */
295  DPRINT1("Special pool: MmAvailablePages 0x%x is too small\n", MmAvailablePages);
296  return NULL;
297  }
298 
299  /* Check if special pool PTE list is exhausted */
301  {
302  /* Try to expand it */
304  {
305  /* No reserves left, reject this allocation */
306  static int once;
308  if (!once++) DPRINT1("Special pool: No PTEs left!\n");
309  return NULL;
310  }
312  }
313 
314  /* Save allocation time */
315  KeQueryTickCount(&TickCount);
316 
317  /* Get a pointer to the first PTE */
318  PointerPte = MiSpecialPoolFirstPte;
319 
320  /* Set the first PTE pointer to the next one in the list */
322 
323  /* Allocate a physical page */
324  PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
325 
326  /* Initialize PFN and make it valid */
327  TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
328  MiInitializePfnAndMakePteValid(PageFrameNumber, PointerPte, TempPte);
329 
330  /* Release the PFN database lock */
332 
333  /* Increase page counter */
335  if (PagesInUse > MmSpecialPagesInUsePeak)
336  MmSpecialPagesInUsePeak = PagesInUse;
337 
338  /* Put some content into the page. Low value of tick count would do */
339  Entry = MiPteToAddress(PointerPte);
340  RtlFillMemory(Entry, PAGE_SIZE, TickCount.LowPart);
341 
342  /* Calculate header and entry addresses */
343  if ((SpecialType != 0) &&
344  ((SpecialType == 1) || (!MmSpecialPoolCatchOverruns)))
345  {
346  /* We catch underruns. Data is at the beginning of the page */
347  Header = (PPOOL_HEADER)((PUCHAR)Entry + PAGE_SIZE - sizeof(POOL_HEADER));
348  }
349  else
350  {
351  /* We catch overruns. Data is at the end of the page */
352  Header = (PPOOL_HEADER)Entry;
353  Entry = (PVOID)((ULONG_PTR)((PUCHAR)Entry - NumberOfBytes + PAGE_SIZE) & ~((LONG_PTR)sizeof(POOL_HEADER) - 1));
354  }
355 
356  /* Initialize the header */
357  RtlZeroMemory(Header, sizeof(POOL_HEADER));
358 
359  /* Save allocation size there */
360  Header->Ulong1 = (ULONG)NumberOfBytes;
361 
362  /* Make sure it's all good */
363  ASSERT((NumberOfBytes <= PAGE_SIZE - sizeof(POOL_HEADER)) &&
364  (PAGE_SIZE <= 32 * 1024));
365 
366  /* Mark it as paged or nonpaged */
367  if (PoolType == PagedPool)
368  {
369  /* Add pagedpool flag into the pool header too */
370  Header->Ulong1 |= SPECIAL_POOL_PAGED;
371 
372  /* Also mark the next PTE as special-pool-paged */
373  PointerPte[1].u.Soft.PageFileHigh |= SPECIAL_POOL_PAGED_PTE;
374 
375  /* Increase pagable counter */
377  if (PagesInUse > MiSpecialPagesPagablePeak)
378  MiSpecialPagesPagablePeak = PagesInUse;
379  }
380  else
381  {
382  /* Mark the next PTE as special-pool-nonpaged */
383  PointerPte[1].u.Soft.PageFileHigh |= SPECIAL_POOL_NONPAGED_PTE;
384 
385  /* Increase nonpaged counter */
387  if (PagesInUse > MiSpecialPagesNonPagedPeak)
388  MiSpecialPagesNonPagedPeak = PagesInUse;
389  }
390 
391  /* Finally save tag and put allocation time into the header's blocksize.
392  That time will be used to check memory consistency within the allocated
393  page. */
394  Header->PoolTag = Tag;
395  Header->BlockSize = (UCHAR)TickCount.LowPart;
396  DPRINT("%p\n", Entry);
397  return Entry;
398 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
ULONG64 NextEntry
Definition: mmtypes.h:145
struct _Entry Entry
Definition: kefuncs.h:640
ULONG PFN_COUNT
Definition: mmtypes.h:102
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MM_EMPTY_PTE_LIST
Definition: mm.h:77
unsigned char * PUCHAR
Definition: retypes.h:3
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:209
struct _POOL_HEADER POOL_HEADER
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
_Out_ PKIRQL Irql
Definition: csq.h:179
union _MMPTE::@1889 u
uint32_t ULONG_PTR
Definition: typedefs.h:64
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 NULL
Definition: mystdio.h:57
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
void DPRINT(...)
Definition: polytest.cpp:61
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
struct _POOL_HEADER * PPOOL_HEADER
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
PFN_COUNT MiSpecialPagesNonPagedMaximum
Definition: special.c:52
MMPTE_LIST List
Definition: mmtypes.h:222
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
PFN_COUNT MiSpecialPagesNonPaged
Definition: special.c:50
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: init.c:31
unsigned char UCHAR
Definition: xmlstorage.h:181
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
ULONG64 PageFileHigh
Definition: mmtypes.h:93
IN SIZE_T NumberOfBytes
Definition: ndis.h:3914
ULONG LowPart
Definition: typedefs.h:105
#define PAGE_SIZE
Definition: env_spec_w32.h:49
BOOLEAN MmSpecialPoolCatchOverruns
Definition: special.c:54
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#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
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1455
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:153
PFN_COUNT MiSpecialPagesPagablePeak
Definition: special.c:49
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1036
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
PFN_COUNT MmSpecialPagesInUsePeak
Definition: special.c:47
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define APC_LEVEL
Definition: env_spec_w32.h:695
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43
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:90
#define LONG_PTR
Definition: generated.c:23
NTSTATUS NTAPI MmExpandSpecialPool ( VOID  )

Definition at line 204 of file special.c.

Referenced by MmAllocateSpecialPool().

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 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
ULONG MiSpecialPoolExtraCount
Definition: special.c:41
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG64 NextEntry
Definition: mmtypes.h:145
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MM_EMPTY_PTE_LIST
Definition: mm.h:77
union _MMPTE::@1889 u
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
PVOID MmSpecialPoolEnd
Definition: special.c:39
GLenum GLclampf GLint i
Definition: glfuncs.h:14
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
PVOID MiSpecialPoolExtra
Definition: special.c:40
MMPTE_LIST List
Definition: mmtypes.h:222
#define PTE_PER_PAGE
Definition: mm.h:18
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
PMMPTE MmSystemPteBase
Definition: syspte.c:21
unsigned int ULONG
Definition: retypes.h:1
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43
VOID NTAPI MmFreeSpecialPool ( PVOID  P)

Definition at line 441 of file special.c.

Referenced by MiTestSpecialPool().

442 {
443  PMMPTE PointerPte;
445  BOOLEAN Overruns = FALSE;
448  ULONG BytesRequested, BytesReal = 0;
450  PUCHAR b;
451  PMI_FREED_SPECIAL_POOL FreedHeader;
452  LARGE_INTEGER TickCount;
453  PMMPFN Pfn;
454 
455  DPRINT("MmFreeSpecialPool(%p)\n", P);
456 
457  /* Get the PTE */
458  PointerPte = MiAddressToPte(P);
459 
460  /* Check if it's valid */
461  if (PointerPte->u.Hard.Valid == 0)
462  {
463  /* Bugcheck if it has NOACCESS or 0 set as protection */
464  if (PointerPte->u.Soft.Protection == MM_NOACCESS ||
465  !PointerPte->u.Soft.Protection)
466  {
467  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
468  (ULONG_PTR)P,
469  (ULONG_PTR)PointerPte,
470  0,
471  0x20);
472  }
473  }
474 
475  /* Determine if it's a underruns or overruns pool pointer */
476  PtrOffset = (ULONG)((ULONG_PTR)P & (PAGE_SIZE - 1));
477  if (PtrOffset)
478  {
479  /* Pool catches overruns */
480  Header = PAGE_ALIGN(P);
481  Overruns = TRUE;
482  }
483  else
484  {
485  /* Pool catches underruns */
486  Header = (PPOOL_HEADER)((PUCHAR)PAGE_ALIGN(P) + PAGE_SIZE - sizeof(POOL_HEADER));
487  }
488 
489  /* Check if it's non paged pool */
490  if ((Header->Ulong1 & SPECIAL_POOL_PAGED) == 0)
491  {
492  /* Non-paged allocation, ensure that IRQ is not higher that DISPATCH */
493  PoolType = NonPagedPool;
494  ASSERT(PointerPte[1].u.Soft.PageFileHigh == SPECIAL_POOL_NONPAGED_PTE);
495  if (Irql > DISPATCH_LEVEL)
496  {
497  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
498  Irql,
499  PoolType,
500  (ULONG_PTR)P,
501  0x31);
502  }
503  }
504  else
505  {
506  /* Paged allocation, ensure */
507  PoolType = PagedPool;
508  ASSERT(PointerPte[1].u.Soft.PageFileHigh == SPECIAL_POOL_PAGED_PTE);
509  if (Irql > APC_LEVEL)
510  {
511  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
512  Irql,
513  PoolType,
514  (ULONG_PTR)P,
515  0x31);
516  }
517  }
518 
519  /* Get amount of bytes user requested to be allocated by clearing out the paged mask */
520  BytesRequested = (Header->Ulong1 & ~SPECIAL_POOL_PAGED) & 0xFFFF;
521  ASSERT(BytesRequested <= PAGE_SIZE - sizeof(POOL_HEADER));
522 
523  /* Check memory before the allocated user buffer in case of overruns detection */
524  if (Overruns)
525  {
526  /* Calculate the real placement of the buffer */
527  BytesReal = PAGE_SIZE - PtrOffset;
528 
529  /* If they mismatch, it's unrecoverable */
530  if (BytesRequested > BytesReal)
531  {
532  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
533  (ULONG_PTR)P,
534  BytesRequested,
535  BytesReal,
536  0x21);
537  }
538 
539  if (BytesRequested + sizeof(POOL_HEADER) < BytesReal)
540  {
541  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
542  (ULONG_PTR)P,
543  BytesRequested,
544  BytesReal,
545  0x22);
546  }
547 
548  /* Actually check the memory pattern */
549  for (b = (PUCHAR)(Header + 1); b < (PUCHAR)P; b++)
550  {
551  if (*b != Header->BlockSize)
552  {
553  /* Bytes mismatch */
554  KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
555  (ULONG_PTR)P,
556  (ULONG_PTR)b,
557  Header->BlockSize,
558  0x23);
559  }
560  }
561  }
562 
563  /* Check the memory pattern after the user buffer */
564  MiSpecialPoolCheckPattern(P, Header);
565 
566  /* Fill the freed header */
567  KeQueryTickCount(&TickCount);
568  FreedHeader = (PMI_FREED_SPECIAL_POOL)PAGE_ALIGN(P);
569  FreedHeader->Signature = 0x98764321;
570  FreedHeader->TickCount = TickCount.LowPart;
571  FreedHeader->NumberOfBytesRequested = BytesRequested;
572  FreedHeader->Pagable = PoolType;
573  FreedHeader->VirtualAddress = P;
574  FreedHeader->Thread = PsGetCurrentThread();
575  /* TODO: Fill StackPointer and StackBytes */
576  FreedHeader->StackPointer = NULL;
577  FreedHeader->StackBytes = 0;
578 
579  if (PoolType == NonPagedPool)
580  {
581  /* Non pagable. Get PFN element corresponding to the PTE */
582  Pfn = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
583 
584  /* Count the page as free */
586 
587  /* Lock PFN database */
589 
590  /* Delete this PFN */
591  MI_SET_PFN_DELETED(Pfn);
592 
593  /* Decrement share count of this PFN */
594  MiDecrementShareCount(Pfn, PointerPte->u.Hard.PageFrameNumber);
595 
596  MI_ERASE_PTE(PointerPte);
597 
598  /* Flush the TLB */
599  //FIXME: Use KeFlushSingleTb() instead
601  }
602  else
603  {
604  /* Pagable. Delete that virtual address */
605  MiDeleteSystemPageableVm(PointerPte, 1, 0, NULL);
606 
607  /* Count the page as free */
609 
610  /* Lock PFN database */
612  }
613 
614  /* Mark next PTE as invalid */
615  MI_ERASE_PTE(PointerPte + 1);
616 
617  /* Make sure that the last entry is really the last one */
619 
620  /* Update the current last PTE next pointer */
622 
623  /* PointerPte becomes the new last PTE */
624  PointerPte->u.List.NextEntry = MM_EMPTY_PTE_LIST;
625  MiSpecialPoolLastPte = PointerPte;
626 
627  /* Release the PFN database lock */
629 
630  /* Update page counter */
632 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:957
ULONG64 NextEntry
Definition: mmtypes.h:145
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PtrOffset(BASE, OFFSET)
Definition: cdprocs.h:1344
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MM_EMPTY_PTE_LIST
Definition: mm.h:77
unsigned char * PUCHAR
Definition: retypes.h:3
#define TRUE
Definition: numbers.c:17
#define MM_NOACCESS
Definition: miarm.h:67
struct _POOL_HEADER POOL_HEADER
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble * u
Definition: glfuncs.h:88
_Out_ PKIRQL Irql
Definition: csq.h:179
union _MMPTE::@1889 u
uint32_t ULONG_PTR
Definition: typedefs.h:64
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
#define NULL
Definition: mystdio.h:57
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:423
#define b
Definition: ke_i.h:79
unsigned char BOOLEAN
MMPTE_LIST List
Definition: mmtypes.h:222
INT POOL_TYPE
Definition: typedefs.h:77
ULONG64 Valid
Definition: mmtypes.h:150
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define PAGE_ALIGN(Va)
PFN_COUNT MiSpecialPagesNonPaged
Definition: special.c:50
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1391
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
Definition: mm.h:305
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1452
ULONG LowPart
Definition: typedefs.h:105
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI MiSpecialPoolCheckPattern(PUCHAR P, PPOOL_HEADER Header)
Definition: special.c:402
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#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:161
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
#define FALSE
Definition: numbers.c:16
unsigned int ULONG
Definition: retypes.h:1
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#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:90
#define P(a, b, c, d, e, x)
BOOLEAN NTAPI MmIsSpecialPoolAddress ( PVOID  P)

Definition at line 95 of file special.c.

Referenced by MmIsSpecialPoolAddressFree().

96 {
97  return ((P >= MmSpecialPoolStart) &&
98  (P <= MmSpecialPoolEnd));
99 }
PVOID MmSpecialPoolEnd
Definition: special.c:39
PVOID MmSpecialPoolStart
Definition: special.c:38
#define P(a, b, c, d, e, x)
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 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define TRUE
Definition: numbers.c:17
union _MMPTE::@1889 u
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define SPECIAL_POOL_PAGED_PTE
Definition: special.c:34
ULONG64 PageFileHigh
Definition: mmtypes.h:93
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
#define FALSE
Definition: numbers.c:16
#define P(a, b, c, d, e, x)
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: numbers.c:17
ULONG MmSpecialPoolTag
Definition: pool.c:27
IN SIZE_T NumberOfBytes
Definition: ndis.h:3914
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN ULONG IN ULONG Tag
Definition: evtlib.h:153
#define FALSE
Definition: numbers.c:16

Variable Documentation

PFN_COUNT MiSpecialPagesNonPaged

Definition at line 50 of file special.c.

Referenced by MmAllocateSpecialPool(), and MmFreeSpecialPool().

PFN_COUNT MiSpecialPagesNonPagedMaximum

Definition at line 52 of file special.c.

Referenced by MiInitializeSpecialPool(), and MmAllocateSpecialPool().

PFN_COUNT MiSpecialPagesNonPagedPeak

Definition at line 51 of file special.c.

Referenced by MmAllocateSpecialPool().

PFN_COUNT MiSpecialPagesPagable

Definition at line 48 of file special.c.

Referenced by MmAllocateSpecialPool(), and MmFreeSpecialPool().

PFN_COUNT MiSpecialPagesPagablePeak

Definition at line 49 of file special.c.

Referenced by MmAllocateSpecialPool().

PVOID MiSpecialPoolExtra

Definition at line 40 of file special.c.

Referenced by MiInitializeSpecialPool(), and MmExpandSpecialPool().

ULONG MiSpecialPoolExtraCount

Definition at line 41 of file special.c.

Referenced by MiInitializeSpecialPool(), and MmExpandSpecialPool().

PMMPTE MiSpecialPoolFirstPte

Definition at line 43 of file special.c.

Referenced by MmAllocateSpecialPool().

PMMPTE MiSpecialPoolLastPte

Definition at line 44 of file special.c.

PFN_COUNT MmSpecialPagesInUse

Definition at line 46 of file special.c.

Referenced by MmAllocateSpecialPool(), and MmFreeSpecialPool().

PFN_COUNT MmSpecialPagesInUsePeak

Definition at line 47 of file special.c.

Referenced by MmAllocateSpecialPool().

BOOLEAN MmSpecialPoolCatchOverruns = TRUE

Definition at line 54 of file special.c.

Referenced by MmAllocateSpecialPool().

PVOID MmSpecialPoolEnd

Definition at line 39 of file special.c.

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

PVOID MmSpecialPoolStart

Definition at line 38 of file special.c.

Referenced by MiInitializeSpecialPool(), and MmIsSpecialPoolAddress().