ReactOS 0.4.15-dev-7834-g00c4b3d
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
23extern ULONG ExpPoolFlags;
25
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
57{
59 /* TODO: Add overlaid verifier pool header */
70
71/* PRIVATE FUNCTIONS **********************************************************/
72
74
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
96{
97 return ((P >= MmSpecialPoolStart) &&
98 (P <= MmSpecialPoolEnd));
99}
100
102NTAPI
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
121VOID
122NTAPI
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;
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}
201
203NTAPI
205{
206 ULONG i;
207 PMMPTE PointerPte;
208
210
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}
242
243PVOID
244NTAPI
246{
247 KIRQL Irql;
249 PMMPTE PointerPte;
250 PFN_NUMBER PageFrameNumber;
251 LARGE_INTEGER TickCount;
252 PVOID Entry;
254 PFN_COUNT PagesInUse;
255
256 DPRINT("MmAllocateSpecialPool(%x %x %x %x)\n", NumberOfBytes, Tag, PoolType, SpecialType);
257
258 /* Check if the pool is initialized and quit if it's not */
259 if (!MiSpecialPoolFirstPte) return NULL;
260
261 /* Get the pool type */
263
264 /* Check whether current IRQL matches the pool type */
266
267 if (((PoolType == PagedPool) && (Irql > APC_LEVEL)) ||
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 */
295 Irql = MiAcquirePfnLock();
296
297 /* Reject allocation in case amount of available pages is too small */
298 if (MmAvailablePages < 0x100)
299 {
300 /* Release the PFN database lock */
301 MiReleasePfnLock(Irql);
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;
314 MiReleasePfnLock(Irql);
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 */
347 MiReleasePfnLock(Irql);
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);
357
358 /* Calculate header and entry addresses */
359 if ((SpecialType != 0) &&
360 ((SpecialType == 1) || (!MmSpecialPoolCatchOverruns)))
361 {
362 /* We catch underruns. Data is at the beginning of the page */
364 }
365 else
366 {
367 /* We catch overruns. Data is at the end of the page */
370 }
371
372 /* Initialize the header */
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 */
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
416VOID
417NTAPI
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,
449 Header->BlockSize,
450 0x24);
451 }
452 }
453}
454
455VOID
456NTAPI
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 */
497 Overruns = TRUE;
498 }
499 else
500 {
501 /* Pool catches underruns */
503 }
504
505 /* Check if it's non paged pool */
506 if ((Header->Ulong1 & SPECIAL_POOL_PAGED) == 0)
507 {
508 /* Non-paged allocation, ensure that IRQ is not higher that DISPATCH */
510 ASSERT(PointerPte[1].u.Soft.PageFileHigh == SPECIAL_POOL_NONPAGED_PTE);
511 if (Irql > DISPATCH_LEVEL)
512 {
513 KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
514 Irql,
515 PoolType,
516 (ULONG_PTR)P,
517 0x31);
518 }
519 }
520 else
521 {
522 /* Paged allocation, ensure */
524 ASSERT(PointerPte[1].u.Soft.PageFileHigh == SPECIAL_POOL_PAGED_PTE);
525 if (Irql > APC_LEVEL)
526 {
527 KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
528 Irql,
529 PoolType,
530 (ULONG_PTR)P,
531 0x31);
532 }
533 }
534
535 /* Get amount of bytes user requested to be allocated by clearing out the paged mask */
536 BytesRequested = (Header->Ulong1 & ~SPECIAL_POOL_PAGED) & 0xFFFF;
537 ASSERT(BytesRequested <= PAGE_SIZE - sizeof(POOL_HEADER));
538
539 /* Check memory before the allocated user buffer in case of overruns detection */
540 if (Overruns)
541 {
542 /* Calculate the real placement of the buffer */
543 BytesReal = PAGE_SIZE - PtrOffset;
544
545 /* If they mismatch, it's unrecoverable */
546 if (BytesRequested > BytesReal)
547 {
548 KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
549 (ULONG_PTR)P,
550 BytesRequested,
551 BytesReal,
552 0x21);
553 }
554
555 if (BytesRequested + sizeof(POOL_HEADER) < BytesReal)
556 {
557 KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
558 (ULONG_PTR)P,
559 BytesRequested,
560 BytesReal,
561 0x22);
562 }
563
564 /* Actually check the memory pattern */
565 for (b = (PUCHAR)(Header + 1); b < (PUCHAR)P; b++)
566 {
567 if (*b != Header->BlockSize)
568 {
569 /* Bytes mismatch */
570 KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
571 (ULONG_PTR)P,
572 (ULONG_PTR)b,
573 Header->BlockSize,
574 0x23);
575 }
576 }
577 }
578
579 /* Check the memory pattern after the user buffer */
581
582 /* Fill the freed header */
583 KeQueryTickCount(&TickCount);
584 FreedHeader = (PMI_FREED_SPECIAL_POOL)PAGE_ALIGN(P);
585 FreedHeader->Signature = 0x98764321;
586 FreedHeader->TickCount = TickCount.LowPart;
587 FreedHeader->NumberOfBytesRequested = BytesRequested;
588 FreedHeader->Pagable = PoolType;
589 FreedHeader->VirtualAddress = P;
590 FreedHeader->Thread = PsGetCurrentThread();
591 /* TODO: Fill StackPointer and StackBytes */
592 FreedHeader->StackPointer = NULL;
593 FreedHeader->StackBytes = 0;
594
595 if (PoolType == NonPagedPool)
596 {
597 /* Non pagable. Get PFN element corresponding to the PTE */
598 Pfn = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
599
600 /* Count the page as free */
602
603 /* Lock PFN database */
604 Irql = MiAcquirePfnLock();
605
606 /* Delete this PFN */
608
609 /* Decrement share count of this PFN */
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 */
627 Irql = MiAcquirePfnLock();
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 */
644 MiReleasePfnLock(Irql);
645
646 /* Update page counter */
648}
649
650VOID
651NTAPI
653{
654 ULONG i;
655 PVOID p1, p2[100];
656 //PUCHAR p3;
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);
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 */
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
unsigned char BOOLEAN
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define PtrOffset(BASE, OFFSET)
Definition: cdprocs.h:1547
Definition: Header.h:9
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define P(row, col)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define PagedPool
Definition: env_spec_w32.h:308
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1524
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1527
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define b
Definition: ke_i.h:79
struct _POOL_HEADER POOL_HEADER
struct _POOL_HEADER * PPOOL_HEADER
@ SystemPteSpace
Definition: miarm.h:403
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:232
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1041
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:1006
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
#define MM_NOACCESS
Definition: miarm.h:65
ULONG MmSpecialPoolTag
Definition: pool.c:29
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:283
enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1574
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define ASSERT(a)
Definition: mode.c:44
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
#define MM_EMPTY_PTE_LIST
Definition: mm.h:87
#define PTE_PER_PAGE
Definition: mm.h:20
#define MiPteToAddress(_Pte)
Definition: mm.h:116
PFN_NUMBER MmResidentAvailablePages
Definition: freelist.c:27
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
@ MI_USAGE_PAGED_POOL
Definition: mm.h:325
@ MI_USAGE_NONPAGED_POOL
Definition: mm.h:326
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:1043
#define MI_SET_USAGE(x)
Definition: mm.h:317
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:617
ULONG MmNumberOfSystemPtes
Definition: init.c:42
MMPTE ValidKernelPte
Definition: init.c:29
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:108
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
ULONG PFN_NUMBER
Definition: ke.h:9
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN NTAPI MmIsSpecialPoolAddressFree(PVOID P)
Definition: special.c:103
PVOID MmSpecialPoolEnd
Definition: special.c:39
VOID NTAPI MiTestSpecialPool(VOID)
Definition: special.c:652
BOOLEAN NTAPI MmIsSpecialPoolAddress(PVOID P)
Definition: special.c:95
PFN_COUNT MmSpecialPagesInUse
Definition: special.c:46
struct _MI_FREED_SPECIAL_POOL MI_FREED_SPECIAL_POOL
ULONG MiSpecialPoolExtraCount
Definition: special.c:41
VOID NTAPI MiSpecialPoolCheckPattern(PUCHAR P, PPOOL_HEADER Header)
Definition: special.c:418
PFN_COUNT MiSpecialPagesNonPagedPeak
Definition: special.c:51
#define SPECIAL_POOL_NONPAGED_PTE
Definition: special.c:35
#define SPECIAL_POOL_PAGED_PTE
Definition: special.c:34
PMMPTE MmSystemPteBase
Definition: syspte.c:21
PFN_COUNT MiSpecialPagesPagable
Definition: special.c:48
PVOID MmSpecialPoolStart
Definition: special.c:38
struct _MI_FREED_SPECIAL_POOL * PMI_FREED_SPECIAL_POOL
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
NTSTATUS NTAPI MmExpandSpecialPool(VOID)
Definition: special.c:204
BOOLEAN NTAPI MmUseSpecialPool(SIZE_T NumberOfBytes, ULONG Tag)
Definition: special.c:77
PFN_COUNT MiSpecialPagesNonPaged
Definition: special.c:50
PFN_COUNT MmSpecialPagesInUsePeak
Definition: special.c:47
PFN_COUNT MiSpecialPagesNonPagedMaximum
Definition: special.c:52
PMMPTE NTAPI MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType, IN ULONG Alignment)
Definition: syspte.c:88
VOID NTAPI MiInitializeSpecialPool(VOID)
Definition: special.c:123
PVOID NTAPI MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG SpecialType)
Definition: special.c:245
BOOLEAN MmSpecialPoolCatchOverruns
Definition: special.c:54
PVOID MiSpecialPoolExtra
Definition: special.c:40
ULONG ExpPoolFlags
Definition: expool.c:56
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43
#define SPECIAL_POOL_PAGED
Definition: special.c:36
PFN_COUNT MiSpecialPagesPagablePeak
Definition: special.c:49
VOID NTAPI MmFreeSpecialPool(PVOID P)
Definition: special.c:457
base of all file and directory entries
Definition: entries.h:83
ULONG PageFrameNumber
Definition: mmtypes.h:109
POOL_HEADER OverlaidPoolHeader
Definition: special.c:58
UCHAR StackData[0x400]
Definition: special.c:68
ULONG NumberOfBytesRequested
Definition: special.c:62
Definition: mm.h:374
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
ULONG64 NextEntry
Definition: mmtypes.h:145
ULONG64 Protection
Definition: mmtypes.h:88
ULONG64 PageFileHigh
Definition: mmtypes.h:93
MMPTE_LIST List
Definition: mmtypes.h:222
union _MMPTE::@2325 u
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define LONG_PTR
Definition: treelist.c:79
INT POOL_TYPE
Definition: typedefs.h:78
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG LowPart
Definition: typedefs.h:106
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
#define PAGE_ALIGN(Va)
ULONG PFN_COUNT
Definition: mmtypes.h:102
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:399
unsigned char UCHAR
Definition: xmlstorage.h:181