ReactOS 0.4.15-dev-8191-gbc6c731
page.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/i386/page.c
5 * PURPOSE: Low level memory management manipulation
6 *
7 * PROGRAMMERS: David Welch (welch@cwcom.net)
8 */
9
10/* INCLUDES ***************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16#include <mm/ARM3/miarm.h>
17
18#ifndef _MI_PAGING_LEVELS
19#error "Dude, fix your stuff before using this file"
20#endif
21
22/* GLOBALS *****************************************************************/
23const
26{
27 //
28 // These are the base MM_ protection flags
29 //
30 0,
31 PTE_READONLY | PTE_ENABLE_CACHE,
32 PTE_EXECUTE | PTE_ENABLE_CACHE,
33 PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
34 PTE_READWRITE | PTE_ENABLE_CACHE,
35 PTE_WRITECOPY | PTE_ENABLE_CACHE,
36 PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
37 PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
38 //
39 // These OR in the MM_NOCACHE flag
40 //
41 0,
42 PTE_READONLY | PTE_DISABLE_CACHE,
43 PTE_EXECUTE | PTE_DISABLE_CACHE,
44 PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
45 PTE_READWRITE | PTE_DISABLE_CACHE,
46 PTE_WRITECOPY | PTE_DISABLE_CACHE,
47 PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
48 PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
49 //
50 // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
51 //
52 0,
53 PTE_READONLY | PTE_ENABLE_CACHE,
54 PTE_EXECUTE | PTE_ENABLE_CACHE,
55 PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
56 PTE_READWRITE | PTE_ENABLE_CACHE,
57 PTE_WRITECOPY | PTE_ENABLE_CACHE,
58 PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
59 PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
60 //
61 // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
62 //
63 0,
64 PTE_READONLY | PTE_WRITECOMBINED_CACHE,
65 PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
66 PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
67 PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
68 PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
69 PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
70 PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
71};
72
73const
75{
108};
109
110/* FUNCTIONS ***************************************************************/
111
113NTAPI
116
117static
120{
121#if _MI_PAGING_LEVELS == 2
123
124 /* Some sanity check while we're here */
125 ASSERT(Ret == (MiAddressToPde(Address)->u.Hard.Valid != 0));
126
127 return Ret;
128#else
129 PMMPDE PointerPde;
130 PMMPPE PointerPpe;
131#if _MI_PAGING_LEVELS == 4
132 PMMPXE PointerPxe;
133#endif
134 PMMPFN Pfn;
135
136 /* Make sure we're locked */
137 ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared));
138
139 /* Must not hold the PFN lock! */
141
142 /* Check if PXE or PPE have references first. */
143#if _MI_PAGING_LEVELS == 4
144 PointerPxe = MiAddressToPxe(Address);
145 if ((PointerPxe->u.Hard.Valid == 1) || (PointerPxe->u.Soft.Transition == 1))
146 {
147 Pfn = MiGetPfnEntry(PFN_FROM_PXE(PointerPxe));
149 return FALSE;
150 }
151 else if (PointerPxe->u.Soft.UsedPageTableEntries == 0)
152 {
153 return FALSE;
154 }
155
156 if (PointerPxe->u.Hard.Valid == 0)
157 {
159 }
160#endif
161
162 PointerPpe = MiAddressToPpe(Address);
163 if ((PointerPpe->u.Hard.Valid == 1) || (PointerPpe->u.Soft.Transition == 1))
164 {
165 Pfn = MiGetPfnEntry(PFN_FROM_PPE(PointerPpe));
167 return FALSE;
168 }
169 else if (PointerPpe->u.Soft.UsedPageTableEntries == 0)
170 {
171 return FALSE;
172 }
173
174 if (PointerPpe->u.Hard.Valid == 0)
175 {
177 }
178
179 PointerPde = MiAddressToPde(Address);
180 if ((PointerPde->u.Hard.Valid == 0) && (PointerPde->u.Soft.Transition == 0))
181 {
182 return PointerPde->u.Soft.UsedPageTableEntries != 0;
183 }
184
185 /* This lies on the PFN */
186 Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde));
187 return Pfn->OriginalPte.u.Soft.UsedPageTableEntries != 0;
188#endif
189}
190
192NTAPI
195{
196 PMMPTE PointerPte;
198
199 /* Must be called for user mode only */
200 ASSERT(Process != NULL);
202
203 /* And for our process */
205
206 /* Lock for reading */
208
210 {
212 return 0;
213 }
214
215 /* Make sure we can read the PTE */
217
218 PointerPte = MiAddressToPte(Address);
219 Page = PointerPte->u.Hard.Valid ? PFN_FROM_PTE(PointerPte) : 0;
220
222 return Page;
223}
224
237MmDeleteVirtualMappingEx(
242 _In_ BOOLEAN IsPhysical)
243{
244 PMMPTE PointerPte;
245 MMPTE OldPte;
246 BOOLEAN ValidPde;
247
248 OldPte.u.Long = 0;
249
250 DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n", Process, Address, WasDirty, Page);
251
253
254 /* And we should be at low IRQL */
256
257 /* Make sure our PDE is valid, and that everything is going fine */
258 if (Process == NULL)
259 {
261 {
262 DPRINT1("NULL process given for user-mode mapping at %p\n", Address);
263 KeBugCheck(MEMORY_MANAGEMENT);
264 }
265#if (_MI_PAGING_LEVELS == 2)
266 ValidPde = MiSynchronizeSystemPde(MiAddressToPde(Address));
267#else
269#endif
270 }
271 else
272 {
274 {
275 DPRINT1("Process %p given for kernel-mode mapping at %p\n", Process, Address);
276 KeBugCheck(MEMORY_MANAGEMENT);
277 }
278
279 /* Only for current process !!! */
282
283 ValidPde = MiIsPageTablePresent(Address);
284 if (ValidPde)
285 {
287 }
288 }
289
290 /* Get the PTE if we're having anything */
291 if (ValidPde)
292 {
293 PointerPte = MiAddressToPte(Address);
294 OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
295
297
298 if (OldPte.u.Long != 0)
299 {
300 /* It must have been present, or not a swap entry */
301 ASSERT(OldPte.u.Hard.Valid || !FlagOn(OldPte.u.Long, 0x800));
302 if (WasDirty != NULL)
303 {
304 *WasDirty = !!OldPte.u.Hard.Dirty;
305 }
306 if (Page != NULL)
307 {
308 *Page = OldPte.u.Hard.PageFrameNumber;
309 }
310 }
311 }
312
313 if (Process != NULL)
314 {
315 /* Remove PDE reference, if needed */
316 if (OldPte.u.Long != 0)
317 {
319 {
320 KIRQL OldIrql = MiAcquirePfnLock();
322 MiReleasePfnLock(OldIrql);
323 }
324 }
325
326 if (!IsPhysical && OldPte.u.Hard.Valid)
327 {
328 PMMPFN Pfn1;
330
331 OldIrql = MiAcquirePfnLock();
332 Pfn1 = &MmPfnDatabase[OldPte.u.Hard.PageFrameNumber];
334 ASSERT(Pfn1->u2.ShareCount > 0);
335 if (--Pfn1->u2.ShareCount == 0)
336 {
338 }
339 MiReleasePfnLock(OldIrql);
340 }
341
343 }
344
345 return OldPte.u.Long != 0;
346}
347
348_Success_(return)
355{
356 return MmDeleteVirtualMappingEx(Process, Address, WasDirty, Page, FALSE);
357}
358
359_Success_(return)
361MmDeletePhysicalMapping(
366{
367 return MmDeleteVirtualMappingEx(Process, Address, WasDirty, Page, TRUE);
368}
369
370VOID
371NTAPI
375 SWAPENTRY* SwapEntry)
376{
377 PMMPTE PointerPte;
378 MMPTE OldPte;
379
380 /* This should not be called for kernel space anymore */
381 ASSERT(Process != NULL);
383
384 /* And we don't support deleting for other process */
386
387 /* And we should be at low IRQL */
389
390 /* We are tinkering with the PDE here. Ensure it will be there */
392
393 /* Callers must ensure there is actually something there */
394 ASSERT(MiAddressToPde(Address)->u.Long != 0);
395
397
398 PointerPte = MiAddressToPte(Address);
399 OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
400 /* This must be a swap entry ! */
401 if (!FlagOn(OldPte.u.Long, 0x800) || OldPte.u.Hard.Valid)
402 {
403 KeBugCheckEx(MEMORY_MANAGEMENT, OldPte.u.Long, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
404 }
405
406 /* This used to be a non-zero PTE, now we can let the PDE go. */
408 {
409 /* We can let it go */
410 KIRQL OldIrql = MiAcquirePfnLock();
411 MiDeletePde(MiPteToPde(PointerPte), Process);
412 MiReleasePfnLock(OldIrql);
413 }
414
416
417 *SwapEntry = OldPte.u.Long >> 1;
418}
419
421NTAPI
423{
424 BOOLEAN Ret;
425
427 {
428 ASSERT(Process == NULL);
429#if _MI_PAGING_LEVELS == 2
430 if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
431#else
433#endif
434 {
435 /* It can't be present if there is no PDE */
436 return FALSE;
437 }
438
439 return MiAddressToPte(Address)->u.Hard.Valid;
440 }
441
442 ASSERT(Process != NULL);
444
446
448 {
449 /* It can't be present if there is no PDE */
451 return FALSE;
452 }
453
455
456 Ret = MiAddressToPte(Address)->u.Hard.Valid;
457
459
460 return Ret;
461}
462
464NTAPI
466{
467 BOOLEAN Ret;
468 PMMPTE PointerPte;
469
471 {
472 ASSERT(Process == NULL);
473#if _MI_PAGING_LEVELS == 2
474 if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
475#else
477#endif
478 {
479 /* It's not disabled if it's not present */
480 return FALSE;
481 }
482 }
483 else
484 {
485 ASSERT(Process != NULL);
487
489
491 {
492 /* It can't be disabled if there is no PDE */
494 return FALSE;
495 }
496
498 }
499
500 PointerPte = MiAddressToPte(Address);
501 Ret = !PointerPte->u.Hard.Valid
502 && !FlagOn(PointerPte->u.Long, 0x800)
503 && (PointerPte->u.Hard.PageFrameNumber != 0);
504
507
508 return Ret;
509}
510
512NTAPI
514{
515 BOOLEAN Ret;
516 PMMPTE PointerPte;
517
518 /* We never set swap entries for kernel addresses */
520 {
521 ASSERT(Process == NULL);
522 return FALSE;
523 }
524
525 ASSERT(Process != NULL);
527
529
531 {
532 /* There can't be a swap entry if there is no PDE */
534 return FALSE;
535 }
536
538
539 PointerPte = MiAddressToPte(Address);
540 Ret = !PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800);
541
543
544 return Ret;
545}
546
547VOID
548NTAPI
550{
551 PMMPTE PointerPte;
552
553 /* We never set swap entries for kernel addresses */
555 {
556 ASSERT(Process == NULL);
557 *SwapEntry = 0;
558 return;
559 }
560
561 ASSERT(Process != NULL);
563
565
567 {
568 /* There can't be a swap entry if there is no PDE */
570 *SwapEntry = 0;
571 return;
572 }
573
575
576 PointerPte = MiAddressToPte(Address);
577 if (!PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800))
578 *SwapEntry = PointerPte->u.Long >> 1;
579 else
580 *SwapEntry = 0;
581
583}
584
586NTAPI
589 SWAPENTRY SwapEntry)
590{
591 PMMPTE PointerPte;
592 ULONG_PTR Pte;
593
594 /* This should not be called for kernel space anymore */
595 ASSERT(Process != NULL);
597
598 /* And we don't support creating for other process */
600
601 if (SwapEntry & ((ULONG_PTR)1 << (RTL_BITS_OF(SWAPENTRY) - 1)))
602 {
603 KeBugCheck(MEMORY_MANAGEMENT);
604 }
605
606 /* We are tinkering with the PDE here. Ensure it will be there */
609
611
612 PointerPte = MiAddressToPte(Address);
613 Pte = InterlockedExchangePte(PointerPte, SwapEntry << 1);
614 if (Pte != 0)
615 {
616 KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
617 }
618
619 /* This used to be a 0 PTE, now we need a valid PDE to keep it around */
622
623 return STATUS_SUCCESS;
624}
625
626
628NTAPI
632 _In_ ULONG flProtect,
634 _In_ BOOLEAN IsPhysical)
635{
636 ULONG ProtectionMask;
637 PMMPTE PointerPte;
639 ULONG_PTR Pte;
640
641 DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %x)\n",
642 Process, Address, flProtect, Page);
643
645
646 ProtectionMask = MiMakeProtectionMask(flProtect);
647 /* Caller must have checked ! */
648 ASSERT(ProtectionMask != MM_INVALID_PROTECTION);
649 ASSERT(ProtectionMask != MM_NOACCESS);
650 ASSERT(ProtectionMask != MM_ZERO_ACCESS);
651
652 /* Make sure our PDE is valid, and that everything is going fine */
653 if (Process == NULL)
654 {
655 /* We don't support this in legacy Mm for kernel mappings */
656 ASSERT(ProtectionMask != MM_WRITECOPY);
657 ASSERT(ProtectionMask != MM_EXECUTE_WRITECOPY);
658
660 {
661 DPRINT1("NULL process given for user-mode mapping at %p\n", Address);
662 KeBugCheck(MEMORY_MANAGEMENT);
663 }
664#if _MI_PAGING_LEVELS == 2
665 if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
667#endif
668 }
669 else
670 {
672 {
673 DPRINT1("Process %p given for kernel-mode mapping at %p -- 1 page starting at %Ix\n",
675 KeBugCheck(MEMORY_MANAGEMENT);
676 }
677
678 /* Only for current process !!! */
681
683 }
684
685 PointerPte = MiAddressToPte(Address);
686
687 MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, ProtectionMask, Page);
688
689 Pte = InterlockedExchangePte(PointerPte, TempPte.u.Long);
690 /* There should not have been anything valid here */
691 if (Pte != 0)
692 {
693 DPRINT1("Bad PTE %lx at %p for %p\n", Pte, PointerPte, Address);
694 KeBugCheck(MEMORY_MANAGEMENT);
695 }
696
697 if (!IsPhysical)
698 {
699 PMMPFN Pfn1;
701
702 OldIrql = MiAcquirePfnLock();
703 Pfn1 = &MmPfnDatabase[TempPte.u.Hard.PageFrameNumber];
704 Pfn1->u2.ShareCount++;
706 MiReleasePfnLock(OldIrql);
707 }
708
709 /* We don't need to flush the TLB here because it only caches valid translations
710 * and we're moving this PTE from invalid to valid so it can't be cached right now */
711
713 {
714 /* Add PDE reference */
717 }
718
719 return(STATUS_SUCCESS);
720}
721
723NTAPI
727 _In_ ULONG flProtect,
729{
731}
732
734NTAPI
738 _In_ ULONG flProtect,
740{
742}
743
745NTAPI
748 ULONG flProtect,
750{
752 if (!MmIsPageInUse(Page))
753 {
754 DPRINT1("Page %lx is not in use\n", Page);
755 KeBugCheck(MEMORY_MANAGEMENT);
756 }
757
759}
760
761ULONG
762NTAPI
764{
765 PMMPTE PointerPte;
767
769 {
770 ASSERT(Process == NULL);
771
772#if _MI_PAGING_LEVELS == 2
773 if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
774#else
776#endif
777 {
778 return PAGE_NOACCESS;
779 }
780 }
781 else
782 {
784 ASSERT(Process != NULL);
785
787
789
791 {
792 /* It can't be present if there is no PDE */
794 return PAGE_NOACCESS;
795 }
796
798 }
799
800 PointerPte = MiAddressToPte(Address);
801
802 if (!PointerPte->u.Flush.Valid)
803 {
805 }
806 else
807 {
808 if (PointerPte->u.Flush.CopyOnWrite)
810 else if (PointerPte->u.Flush.Write)
812 else
814#if _MI_PAGING_LEVELS >= 3
815 /* PAE & AMD64 long mode support NoExecute bit */
816 if (!PointerPte->u.Flush.NoExecute)
817 Protect <<= 4;
818#endif
819 if (PointerPte->u.Flush.CacheDisable)
821 if (PointerPte->u.Flush.WriteThrough)
823 }
824
827
828 return(Protect);
829}
830
831VOID
832NTAPI
834{
835 ULONG ProtectionMask;
836 PMMPTE PointerPte;
837 MMPTE TempPte, OldPte;
838
839 DPRINT("MmSetPageProtect(Process %p Address %p flProtect %x)\n",
840 Process, Address, flProtect);
841
842 ASSERT(Process != NULL);
844
846
847 ProtectionMask = MiMakeProtectionMask(flProtect);
848 /* Caller must have checked ! */
849 ASSERT(ProtectionMask != MM_INVALID_PROTECTION);
850
852
854
855 PointerPte = MiAddressToPte(Address);
856
857 /* Sanity check */
858 ASSERT(PointerPte->u.Hard.Owner == 1);
859
860 TempPte.u.Long = 0;
861 TempPte.u.Hard.PageFrameNumber = PointerPte->u.Hard.PageFrameNumber;
862 TempPte.u.Long |= MmProtectToPteMask[ProtectionMask];
863 TempPte.u.Hard.Owner = 1;
864
865 /* Only set valid bit if we have to */
866 if ((ProtectionMask != MM_NOACCESS) && !FlagOn(ProtectionMask, MM_GUARDPAGE))
867 TempPte.u.Hard.Valid = 1;
868
869 /* Keep dirty & accessed bits */
870 TempPte.u.Hard.Accessed = PointerPte->u.Hard.Accessed;
871 TempPte.u.Hard.Dirty = PointerPte->u.Hard.Dirty;
872
873 OldPte.u.Long = InterlockedExchangePte(PointerPte, TempPte.u.Long);
874
875 // We should be able to bring a page back from PAGE_NOACCESS
876 if (!OldPte.u.Hard.Valid && (FlagOn(OldPte.u.Long, 0x800) || (OldPte.u.Hard.PageFrameNumber == 0)))
877 {
878 DPRINT1("Invalid Pte %lx\n", OldPte.u.Long);
879 KeBugCheck(MEMORY_MANAGEMENT);
880 }
881
882 if (OldPte.u.Long != TempPte.u.Long)
884
886}
887
888VOID
889NTAPI
891{
892 PMMPTE PointerPte;
893
894 DPRINT("MmSetDirtyBit(Process %p Address %p Bit %x)\n",
895 Process, Address, Bit);
896
897 ASSERT(Process != NULL);
899
901
903
905
906 PointerPte = MiAddressToPte(Address);
907 // We shouldnl't set dirty bit on non-mapped addresses
908 if (!PointerPte->u.Hard.Valid && (FlagOn(PointerPte->u.Long, 0x800) || (PointerPte->u.Hard.PageFrameNumber == 0)))
909 {
910 DPRINT1("Invalid Pte %lx\n", PointerPte->u.Long);
911 KeBugCheck(MEMORY_MANAGEMENT);
912 }
913
914 PointerPte->u.Hard.Dirty = !!Bit;
915
916 if (!Bit)
918
920}
921
922CODE_SEG("INIT")
923VOID
924NTAPI
926{
927 /* Nothing to do here */
928}
929
930#ifdef _M_IX86
933{
934 PMMPDE PointerPde = MiAddressToPde(Address);
935 PMMPTE PointerPte = MiAddressToPte(Address);
936
937 if (PointerPde->u.Hard.Valid == 0)
938 {
939 if (!MiSynchronizeSystemPde(PointerPde))
940 return FALSE;
941 return PointerPte->u.Hard.Valid != 0;
942 }
943 return FALSE;
944}
945#endif
946
947/* EOF */
#define CODE_SEG(...)
unsigned char BOOLEAN
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1430
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PAGE_READONLY
Definition: compat.h:138
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
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 Add2Ptr(PTR, INC)
#define MM_EXECUTE_WRITECOPY
Definition: miarm.h:50
FORCEINLINE VOID MiLockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1146
FORCEINLINE VOID MiDeletePde(_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
Definition: miarm.h:2526
#define MM_GUARDPAGE
Definition: miarm.h:57
FORCEINLINE VOID MiUnlockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1215
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2492
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1239
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2481
ULONG NTAPI MiMakeSystemAddressValid(IN PVOID PageTableVirtualAddress, IN PEPROCESS CurrentProcess)
Definition: virtual.c:183
#define MM_NOACCESS
Definition: miarm.h:65
#define MM_ZERO_ACCESS
Definition: miarm.h:43
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:807
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:140
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2466
#define MM_WRITECOPY
Definition: miarm.h:48
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1169
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define ASSERT(a)
Definition: mode.c:44
#define _Out_opt_
Definition: ms_sal.h:346
#define _Success_(expr)
Definition: ms_sal.h:259
#define _Inout_opt_
Definition: ms_sal.h:379
#define _In_
Definition: ms_sal.h:308
@ ActiveAndValid
Definition: mmtypes.h:159
@ TransitionPage
Definition: mmtypes.h:160
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define PAGE_GUARD
Definition: nt_native.h:1310
#define RTL_BITS_OF(sizeOfArg)
Definition: ntbasedef.h:668
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:264
#define PFN_FROM_PXE(v)
Definition: mm.h:95
FORCEINLINE BOOLEAN MiIsPdeForAddressValid(PVOID Address)
Definition: mm.h:366
#define MiGetPdeOffset(x)
Definition: mm.h:195
#define PFN_FROM_PPE(v)
Definition: mm.h:94
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:161
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
#define MmSystemRangeStart
Definition: mm.h:32
#define PFN_FROM_PDE(v)
Definition: mm.h:93
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToPde(_Pte)
Definition: mm.h:121
#define MiPteToAddress(_Pte)
Definition: mm.h:116
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MM_NOIRQL
Definition: mm.h:70
_In_ PVOID _Out_opt_ BOOLEAN * WasDirty
Definition: mm.h:1304
PMMPFN MmPfnDatabase
Definition: freelist.c:24
#define PAGE_WRITETHROUGH
Definition: mm.h:109
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
ULONG_PTR SWAPENTRY
Definition: mm.h:57
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:558
#define InterlockedExchangePte(PointerPte, Value)
Definition: mm.h:190
VOID NTAPI MmSetPageProtect(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection)
Definition: page.c:267
NTSTATUS NTAPI MmCreatePageFileMapping(IN PEPROCESS Process, IN PVOID Address, IN SWAPENTRY SwapEntry)
Definition: page.c:196
BOOLEAN NTAPI MmIsDisabledPage(PEPROCESS Process, PVOID Address)
Definition: page.c:309
ULONG NTAPI MmGetPageProtect(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:258
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
BOOLEAN NTAPI MmIsPagePresent(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:240
NTSTATUS NTAPI MmCreateVirtualMapping(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection, IN PPFN_NUMBER Pages, IN ULONG PageCount)
Definition: page.c:158
VOID NTAPI MmDeletePageFileMapping(IN PEPROCESS Process, IN PVOID Address, IN SWAPENTRY *SwapEntry)
Definition: page.c:187
const ULONG MmProtectToPteMask[32]
Definition: page.c:22
PFN_NUMBER NTAPI MmGetPfnForProcess(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:206
const ULONG MmProtectToValue[32]
Definition: page.c:71
BOOLEAN NTAPI MmIsPageSwapEntry(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:249
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection, IN PPFN_NUMBER Pages, IN ULONG PageCount)
Definition: page.c:146
VOID NTAPI MmDeleteVirtualMapping(IN PEPROCESS Process, IN PVOID Address, OUT PBOOLEAN WasDirty, OUT PPFN_NUMBER Page)
Definition: page.c:177
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:277
VOID NTAPI MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN Bit)
Definition: page.c:890
static BOOLEAN MiIsPageTablePresent(PVOID Address)
Definition: page.c:119
NTSTATUS NTAPI MmCreateVirtualMappingUnsafeEx(_Inout_opt_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG flProtect, _In_ PFN_NUMBER Page, _In_ BOOLEAN IsPhysical)
Definition: page.c:629
NTSTATUS NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:462
NTSTATUS NTAPI MmCreatePhysicalMapping(_Inout_opt_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG flProtect, _In_ PFN_NUMBER Page)
Definition: page.c:735
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
Definition: pagepae.c:844
static WCHAR Address[46]
Definition: ping.c:68
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
ULONG * PPFN_NUMBER
Definition: ke.h:9
ULONG PFN_NUMBER
Definition: ke.h:9
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
ULONG PageFrameNumber
Definition: mmtypes.h:109
ULONG64 WriteThrough
Definition: mmtypes.h:69
ULONG64 Write
Definition: mmtypes.h:67
ULONG64 Valid
Definition: mmtypes.h:66
ULONG64 CacheDisable
Definition: mmtypes.h:70
ULONG64 NoExecute
Definition: mmtypes.h:81
ULONG64 CopyOnWrite
Definition: mmtypes.h:75
USHORT PageLocation
Definition: mm.h:365
Definition: mm.h:374
MMPTE OriginalPte
Definition: mm.h:407
union _MMPFN::@1803 u2
MMPFNENTRY e1
Definition: mm.h:397
ULONG_PTR ShareCount
Definition: mm.h:390
union _MMPFN::@1804 u3
ULONG64 Dirty
Definition: mmtypes.h:164
ULONG64 Accessed
Definition: mmtypes.h:163
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 Owner
Definition: mmtypes.h:160
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
ULONG64 UsedPageTableEntries
Definition: mmtypes.h:91
ULONG64 Transition
Definition: mmtypes.h:90
union _MMPTE::@2339 u
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
HARDWARE_PTE Flush
Definition: mmtypes.h:216
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR Long
Definition: mmtypes.h:215
USHORT UsedPageTableEntries[768]
Definition: mmtypes.h:886
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:221