ReactOS  r76032
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
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
union _MMPTE::@2072 u
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
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPTE MmFirstFreeSystemPte[MaximumPtePoolTypes]
Definition: syspte.c:24
smooth NULL
Definition: ftsmooth.c:557
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
union _MMPTE::@2072 u
VOID NTAPI MiSpecialPoolCheckPattern ( PUCHAR  P,
PPOOL_HEADER  Header 
)

Definition at line 418 of file special.c.

Referenced by MmFreeSpecialPool().

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 }
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:63
#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(row, col)
Definition: m_matrix.c:147
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 }
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:76
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:457
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  /* 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 */
363  Header = (PPOOL_HEADER)((PUCHAR)Entry + PAGE_SIZE - sizeof(POOL_HEADER));
364  }
365  else
366  {
367  /* We catch overruns. Data is at the end of the page */
368  Header = (PPOOL_HEADER)Entry;
369  Entry = (PVOID)((ULONG_PTR)((PUCHAR)Entry - NumberOfBytes + PAGE_SIZE) & ~((LONG_PTR)sizeof(POOL_HEADER) - 1));
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 }
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
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:250
smooth NULL
Definition: ftsmooth.c:557
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
void DPRINT(...)
Definition: polytest.cpp:61
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
#define MI_SET_USAGE(x)
Definition: mm.h:249
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:24
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:104
#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 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:155
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:261
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
PFN_COUNT MmSpecialPagesInUsePeak
Definition: special.c:47
union _MMPTE::@2072 u
#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
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
return STATUS_SUCCESS
Definition: btrfs.c:2664
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
union _MMPTE::@2072 u
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43
VOID NTAPI MmFreeSpecialPool ( PVOID  P)

Definition at line 457 of file special.c.

Referenced by MiTestSpecialPool().

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 */
502  Header = (PPOOL_HEADER)((PUCHAR)PAGE_ALIGN(P) + PAGE_SIZE - sizeof(POOL_HEADER));
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 */
509  PoolType = NonPagedPool;
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 */
523  PoolType = PagedPool;
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 */
580  MiSpecialPoolCheckPattern(P, Header);
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 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:957
#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: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 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
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
#define FALSE
Definition: types.h:117
Definition: Header.h:8
PFN_COUNT MiSpecialPagesPagable
Definition: special.c:48
#define SPECIAL_POOL_PAGED_PTE
Definition: special.c:34
smooth NULL
Definition: ftsmooth.c:557
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:76
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:301
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1452
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
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
unsigned int ULONG
Definition: retypes.h:1
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2072 u
#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(row, col)
Definition: m_matrix.c:147
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(row, col)
Definition: m_matrix.c:147
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
#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
union _MMPTE::@2072 u
#define P(row, col)
Definition: m_matrix.c:147
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 FALSE
Definition: types.h:117
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:155

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().