ReactOS  r76032
special.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/mm/ARM3/special.c
5  * PURPOSE: ARM Memory Manager Special Pool implementation
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /*
10  References:
11  http://msdn.microsoft.com/en-us/library/ff551832(v=VS.85).aspx
12 */
13 
14 /* INCLUDES *******************************************************************/
15 
16 #include <ntoskrnl.h>
17 #define NDEBUG
18 #include <debug.h>
19 
20 #define MODULE_INVOLVED_IN_ARM3
21 #include <mm/ARM3/miarm.h>
22 
23 extern ULONG ExpPoolFlags;
24 extern PMMPTE MmSystemPteBase;
25 
26 PMMPTE
27 NTAPI
29  IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
31 
32 /* GLOBALS ********************************************************************/
33 
34 #define SPECIAL_POOL_PAGED_PTE 0x2000
35 #define SPECIAL_POOL_NONPAGED_PTE 0x4000
36 #define SPECIAL_POOL_PAGED 0x8000
37 
42 
45 
53 
55 
56 typedef struct _MI_FREED_SPECIAL_POOL
57 {
59  /* TODO: Add overlaid verifier pool header */
68  UCHAR StackData[0x400];
70 
71 /* PRIVATE FUNCTIONS **********************************************************/
72 
74 
75 BOOLEAN
76 NTAPI
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 }
92 
93 BOOLEAN
94 NTAPI
96 {
97  return ((P >= MmSpecialPoolStart) &&
98  (P <= MmSpecialPoolEnd));
99 }
100 
101 BOOLEAN
102 NTAPI
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 }
120 
121 VOID
122 NTAPI
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;
184  MiSpecialPoolLastPte->u.List.NextEntry = MM_EMPTY_PTE_LIST;
185 
186  /* Save end address of the special pool */
187  MmSpecialPoolEnd = MiPteToAddress(MiSpecialPoolLastPte + 1);
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 }
201 
202 NTSTATUS
203 NTAPI
205 {
206  ULONG i;
207  PMMPTE PointerPte;
208 
210 
211  if (MiSpecialPoolExtraCount == 0)
213 
214  PointerPte = MiSpecialPoolExtra;
215  ASSERT(MiSpecialPoolFirstPte == MiSpecialPoolLastPte);
216  ASSERT(MiSpecialPoolFirstPte->u.List.NextEntry == MM_EMPTY_PTE_LIST);
217  MiSpecialPoolFirstPte->u.List.NextEntry = PointerPte - MmSystemPteBase;
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;
235  MiSpecialPoolLastPte->u.List.NextEntry = MM_EMPTY_PTE_LIST;
236 
237  /* Save new end address of the special pool */
238  MmSpecialPoolEnd = MiPteToAddress(MiSpecialPoolLastPte + 1);
239 
240  return STATUS_SUCCESS;
241 }
242 
243 PVOID
244 NTAPI
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 */
262  PoolType &= BASE_POOL_TYPE_MASK;
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,
274  NumberOfBytes,
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 */
307  if (MiSpecialPoolFirstPte->u.List.NextEntry == MM_EMPTY_PTE_LIST)
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  }
318  ASSERT(MiSpecialPoolFirstPte->u.List.NextEntry != MM_EMPTY_PTE_LIST);
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 */
328  MiSpecialPoolFirstPte = MmSystemPteBase + PointerPte->u.List.NextEntry;
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 }
415 
416 VOID
417 NTAPI
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 }
454 
455 VOID
456 NTAPI
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 */
634  ASSERT(MiSpecialPoolLastPte->u.List.NextEntry == MM_EMPTY_PTE_LIST);
635 
636  /* Update the current last PTE next pointer */
637  MiSpecialPoolLastPte->u.List.NextEntry = PointerPte - MmSystemPteBase;
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 }
649 
650 VOID
651 NTAPI
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 }
693 
694 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI MiTestSpecialPool(VOID)
Definition: special.c:652
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:957
PFN_NUMBER MmResidentAvailablePages
Definition: freelist.c:27
#define IN
Definition: typedefs.h:38
ULONG MiSpecialPoolExtraCount
Definition: special.c:41
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BOOLEAN NTAPI MmIsSpecialPoolAddressFree(PVOID P)
Definition: special.c:103
ULONG64 NextEntry
Definition: mmtypes.h:145
struct _Entry Entry
Definition: kefuncs.h:640
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
POOL_HEADER OverlaidPoolHeader
Definition: special.c:58
#define PtrOffset(BASE, OFFSET)
Definition: cdprocs.h:1344
ULONG PFN_COUNT
Definition: mmtypes.h:102
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
return STATUS_SUCCESS
Definition: btrfs.c:2664
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG MmNumberOfSystemPtes
Definition: init.c:42
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
PVOID NTAPI MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG SpecialType)
Definition: special.c:245
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:209
#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
_Must_inspect_result_ _In_ ULONG Index
Definition: fltkernel.h:1824
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
_Out_ PKIRQL Irql
Definition: csq.h:179
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
uint32_t ULONG_PTR
Definition: typedefs.h:63
const GLfloat * p2
Definition: s_aatritemp.h:44
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
PVOID MmSpecialPoolEnd
Definition: special.c:39
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG MmSpecialPoolTag
Definition: pool.c:27
ULONG PFN_NUMBER
Definition: ke.h:8
PFN_COUNT MiSpecialPagesNonPagedPeak
Definition: special.c:51
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
Definition: Header.h:8
struct _MI_FREED_SPECIAL_POOL MI_FREED_SPECIAL_POOL
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
BOOLEAN NTAPI MmUseSpecialPool(SIZE_T NumberOfBytes, ULONG Tag)
Definition: special.c:77
smooth NULL
Definition: ftsmooth.c:557
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
#define MI_SET_USAGE(x)
Definition: mm.h:249
ULONG64 Protection
Definition: mmtypes.h:88
struct _POOL_HEADER * PPOOL_HEADER
ULONG NumberOfBytesRequested
Definition: special.c:62
UCHAR StackData[0x400]
Definition: special.c:68
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
PFN_COUNT MiSpecialPagesNonPagedMaximum
Definition: special.c:52
PVOID MiSpecialPoolExtra
Definition: special.c:40
unsigned char BOOLEAN
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
MMPTE_LIST List
Definition: mmtypes.h:222
INT POOL_TYPE
Definition: typedefs.h:76
ULONG64 Valid
Definition: mmtypes.h:150
enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define PAGE_ALIGN(Va)
#define PTE_PER_PAGE
Definition: mm.h:18
PFN_COUNT MiSpecialPagesNonPaged
Definition: special.c:50
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: init.c:31
VOID NTAPI MiInitializeSpecialPool(VOID)
Definition: special.c:123
unsigned char UCHAR
Definition: xmlstorage.h:181
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
ULONG64 PageFileHigh
Definition: mmtypes.h:93
IN SIZE_T NumberOfBytes
Definition: ndis.h:3914
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
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
BOOLEAN NTAPI MmIsSpecialPoolAddress(PVOID P)
Definition: special.c:95
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:297
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
PMMPTE NTAPI MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType, IN ULONG Alignment)
Definition: syspte.c:88
NTSTATUS NTAPI MmExpandSpecialPool(VOID)
Definition: special.c:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:161
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
LONG NTSTATUS
Definition: DriverTester.h:11
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1455
PVOID MmSpecialPoolStart
Definition: special.c:38
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
struct _MI_FREED_SPECIAL_POOL * PMI_FREED_SPECIAL_POOL
PFN_COUNT MiSpecialPagesPagablePeak
Definition: special.c:49
ULONG ExpPoolFlags
Definition: expool.c:47
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
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
#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
#define P(row, col)
Definition: m_matrix.c:147