ReactOS 0.4.15-dev-7788-g1ad9096
mdlsup.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/mdlsup.c
5 * PURPOSE: ARM Memory Manager Memory Descriptor List (MDL) Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15#define MODULE_INVOLVED_IN_ARM3
16#include <mm/ARM3/miarm.h>
17
18/* GLOBALS ********************************************************************/
19
23
25
26/* INTERNAL FUNCTIONS *********************************************************/
27static
32 _In_ PVOID StartVa,
35{
40 MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
41 MI_PFN_CACHE_ATTRIBUTE EffectiveCacheAttribute;
42 BOOLEAN IsIoMapping;
44 ULONG_PTR StartingVa;
45 ULONG_PTR EndingVa;
47 PMMVAD_LONG Vad;
48 ULONG NumberOfPages;
49 PMMPTE PointerPte;
50 PMMPDE PointerPde;
52 PPFN_NUMBER MdlPages;
53 PMMPFN Pfn1;
54 PMMPFN Pfn2;
55 BOOLEAN AddressSpaceLocked = FALSE;
56
57 PAGED_CODE();
58
59 DPRINT("MiMapLockedPagesInUserSpace(%p, %p, 0x%x, %p)\n",
60 Mdl, StartVa, CacheType, BaseAddress);
61
62 NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(StartVa,
64 MdlPages = MmGetMdlPfnArray(Mdl);
65
67
68 IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
69 CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
70
71 /* Large pages are always cached, make sure we're not asking for those */
72 if (CacheAttribute != MiCached)
73 {
74 DPRINT1("FIXME: Need to check for large pages\n");
75 }
76
78 if (!NT_SUCCESS(Status))
79 {
80 Vad = NULL;
81 goto Error;
82 }
83
84 /* Allocate a VAD for our mapped region */
85 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
86 if (Vad == NULL)
87 {
90 goto Error;
91 }
92
93 /* Initialize PhysicalMemory VAD */
94 RtlZeroMemory(Vad, sizeof(*Vad));
95 Vad->u2.VadFlags2.LongVad = 1;
98 Vad->u.VadFlags.PrivateMemory = 1;
99
100 /* Did the caller specify an address? */
101 if (BaseAddress == NULL)
102 {
103 /* We get to pick the address */
105 AddressSpaceLocked = TRUE;
106 if (Process->VmDeleted)
107 {
109 goto Error;
110 }
111
114 &Process->VadRoot,
115 &Parent,
116 &StartingVa);
117 if (Result == TableFoundNode)
118 {
120 goto Error;
121 }
122 EndingVa = StartingVa + NumberOfPages * PAGE_SIZE - 1;
123 BaseAddress = (PVOID)StartingVa;
124 }
125 else
126 {
127 /* Caller specified a base address */
128 StartingVa = (ULONG_PTR)BaseAddress;
129 EndingVa = StartingVa + NumberOfPages * PAGE_SIZE - 1;
130
131 /* Make sure it's valid */
132 if (BYTE_OFFSET(StartingVa) != 0 ||
133 EndingVa <= StartingVa ||
135 {
137 goto Error;
138 }
139
141 AddressSpaceLocked = TRUE;
142 if (Process->VmDeleted)
143 {
145 goto Error;
146 }
147
148 /* Check if it's already in use */
150 EndingVa >> PAGE_SHIFT,
151 &Process->VadRoot,
152 &Parent);
153 if (Result == TableFoundNode)
154 {
156 goto Error;
157 }
158 }
159
160 Vad->StartingVpn = StartingVa >> PAGE_SHIFT;
161 Vad->EndingVpn = EndingVa >> PAGE_SHIFT;
162
164
165 ASSERT(Vad->EndingVpn >= Vad->StartingVpn);
166 MiInsertVad((PMMVAD)Vad, &Process->VadRoot);
167
168 /* Check if this is uncached */
169 if (CacheAttribute != MiCached)
170 {
171 /* Flush all caches */
174 }
175
176 PointerPte = MiAddressToPte(BaseAddress);
177 while (NumberOfPages != 0 &&
178 *MdlPages != LIST_HEAD)
179 {
180 PointerPde = MiPteToPde(PointerPte);
182 ASSERT(PointerPte->u.Hard.Valid == 0);
183
184 /* Add a PDE reference for each page */
186
187 /* Set up our basic user PTE */
189 PointerPte,
191 *MdlPages);
192
193 EffectiveCacheAttribute = CacheAttribute;
194
195 /* We need to respect the PFN's caching information in some cases */
196 Pfn2 = MiGetPfnEntry(*MdlPages);
197 if (Pfn2 != NULL)
198 {
199 ASSERT(Pfn2->u3.e2.ReferenceCount != 0);
200
201 switch (Pfn2->u3.e1.CacheAttribute)
202 {
203 case MiNonCached:
204 if (CacheAttribute != MiNonCached)
205 {
206 MiCacheOverride[1]++;
207 EffectiveCacheAttribute = MiNonCached;
208 }
209 break;
210
211 case MiCached:
212 if (CacheAttribute != MiCached)
213 {
214 MiCacheOverride[0]++;
215 EffectiveCacheAttribute = MiCached;
216 }
217 break;
218
219 case MiWriteCombined:
220 if (CacheAttribute != MiWriteCombined)
221 {
222 MiCacheOverride[2]++;
223 EffectiveCacheAttribute = MiWriteCombined;
224 }
225 break;
226
227 default:
228 /* We don't support AWE magic (MiNotMapped) */
229 DPRINT1("FIXME: MiNotMapped is not supported\n");
230 ASSERT(FALSE);
231 break;
232 }
233 }
234
235 /* Configure caching */
236 switch (EffectiveCacheAttribute)
237 {
238 case MiNonCached:
241 break;
242 case MiCached:
243 break;
244 case MiWriteCombined:
247 break;
248 default:
249 ASSERT(FALSE);
250 break;
251 }
252
253 /* Make the page valid */
254 MI_WRITE_VALID_PTE(PointerPte, TempPte);
255
256 /* Acquire a share count */
257 Pfn1 = MI_PFN_ELEMENT(PointerPde->u.Hard.PageFrameNumber);
258 DPRINT("Incrementing %p from %p\n", Pfn1, _ReturnAddress());
259 OldIrql = MiAcquirePfnLock();
260 Pfn1->u2.ShareCount++;
261 MiReleasePfnLock(OldIrql);
262
263 /* Next page */
264 MdlPages++;
265 PointerPte++;
266 NumberOfPages--;
268 }
269
271 ASSERT(AddressSpaceLocked);
273
274 ASSERT(StartingVa != 0);
275 return (PVOID)((ULONG_PTR)StartingVa + MmGetMdlByteOffset(Mdl));
276
277Error:
278 if (AddressSpaceLocked)
279 {
281 }
282 if (Vad != NULL)
283 {
284 ExFreePoolWithTag(Vad, 'ldaV');
286 }
288}
289
290static
291VOID
292NTAPI
295 _In_ PMDL Mdl)
296{
299 PMMVAD Vad;
300 PMMPTE PointerPte;
301 PMMPDE PointerPde;
303 ULONG NumberOfPages;
304 PPFN_NUMBER MdlPages;
305 PFN_NUMBER PageTablePage;
306
307 DPRINT("MiUnmapLockedPagesInUserSpace(%p, %p)\n", BaseAddress, Mdl);
308
311 ASSERT(NumberOfPages != 0);
312 MdlPages = MmGetMdlPfnArray(Mdl);
313
314 /* Find the VAD */
317 if (!Vad ||
319 {
320 DPRINT1("MiUnmapLockedPagesInUserSpace invalid for %p\n", BaseAddress);
322 return;
323 }
324
326
327 /* Remove it from the process VAD tree */
328 ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
329 MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
331
332 /* MiRemoveNode should have removed us if we were the hint */
333 ASSERT(Process->VadRoot.NodeHint != Vad);
334
335 PointerPte = MiAddressToPte(BaseAddress);
336 OldIrql = MiAcquirePfnLock();
337 while (NumberOfPages != 0 &&
338 *MdlPages != LIST_HEAD)
339 {
340 ASSERT(MiAddressToPte(PointerPte)->u.Hard.Valid == 1);
341 ASSERT(PointerPte->u.Hard.Valid == 1);
342
343 /* Invalidate it */
344 MI_ERASE_PTE(PointerPte);
345
346 /* We invalidated this PTE, so dereference the PDE */
347 PointerPde = MiAddressToPde(BaseAddress);
348 PageTablePage = PointerPde->u.Hard.PageFrameNumber;
349 MiDecrementShareCount(MiGetPfnEntry(PageTablePage), PageTablePage);
350
352 {
353 ASSERT(MiIsPteOnPdeBoundary(PointerPte + 1) || (NumberOfPages == 1));
354 MiDeletePde(PointerPde, Process);
355 }
356
357 /* Next page */
358 PointerPte++;
359 NumberOfPages--;
361 MdlPages++;
362 }
363
365 MiReleasePfnLock(OldIrql);
368 ExFreePoolWithTag(Vad, 'ldaV');
369}
370
371/* PUBLIC FUNCTIONS ***********************************************************/
372
373/*
374 * @implemented
375 */
376PMDL
377NTAPI
379 IN PVOID Base,
381{
382 SIZE_T Size;
383
384 //
385 // Check if we don't have an MDL built
386 //
387 if (!Mdl)
388 {
389 //
390 // Calculate the size we'll need and allocate the MDL
391 //
394 if (!Mdl) return NULL;
395 }
396
397 //
398 // Initialize it
399 //
401 return Mdl;
402}
403
404/*
405 * @implemented
406 */
407SIZE_T
408NTAPI
411{
412 //
413 // Return the MDL size
414 //
415 return sizeof(MDL) +
417}
418
419/*
420 * @implemented
421 */
422VOID
423NTAPI
425{
426 PPFN_NUMBER MdlPages, EndPage;
427 PFN_NUMBER Pfn, PageCount;
428 PVOID Base;
429 PMMPTE PointerPte;
430
431 //
432 // Sanity checks
433 //
434 ASSERT(Mdl->ByteCount != 0);
435 ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
438 MDL_PARTIAL)) == 0);
439
440 //
441 // We know the MDL isn't associated to a process now
442 //
443 Mdl->Process = NULL;
444
445 //
446 // Get page and VA information
447 //
448 MdlPages = (PPFN_NUMBER)(Mdl + 1);
449 Base = Mdl->StartVa;
450
451 //
452 // Set the system address and now get the page count
453 //
454 Mdl->MappedSystemVa = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
455 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Mdl->MappedSystemVa,
456 Mdl->ByteCount);
457 ASSERT(PageCount != 0);
458 EndPage = MdlPages + PageCount;
459
460 //
461 // Loop the PTEs
462 //
463 PointerPte = MiAddressToPte(Base);
464 do
465 {
466 //
467 // Write the PFN
468 //
469 Pfn = PFN_FROM_PTE(PointerPte++);
470 *MdlPages++ = Pfn;
471 } while (MdlPages < EndPage);
472
473 //
474 // Set the nonpaged pool flag
475 //
476 Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
477
478 //
479 // Check if this is an I/O mapping
480 //
481 if (!MiGetPfnEntry(Pfn)) Mdl->MdlFlags |= MDL_IO_SPACE;
482}
483
484/*
485 * @implemented
486 */
487PMDL
488NTAPI
493{
494 //
495 // Call the internal routine
496 //
497 return MiAllocatePagesForMdl(LowAddress,
499 SkipBytes,
502 0);
503}
504
505/*
506 * @implemented
507 */
508PMDL
509NTAPI
515 IN ULONG Flags)
516{
517 MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
518
519 //
520 // Check for invalid cache type
521 //
523 {
524 //
525 // Normalize to default
526 //
527 CacheAttribute = MiNotMapped;
528 }
529 else
530 {
531 //
532 // Conver to internal caching attribute
533 //
534 CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType];
535 }
536
537 //
538 // Only these flags are allowed
539 //
541 {
542 //
543 // Silently fail
544 //
545 return NULL;
546 }
547
548 //
549 // Call the internal routine
550 //
551 return MiAllocatePagesForMdl(LowAddress,
553 SkipBytes,
555 CacheAttribute,
556 Flags);
557}
558
559/*
560 * @implemented
561 */
562VOID
563NTAPI
565{
566 PVOID Base;
567 PPFN_NUMBER Pages;
568 LONG NumberOfPages;
569 PMMPFN Pfn1;
571 DPRINT("Freeing MDL: %p\n", Mdl);
572
573 //
574 // Sanity checks
575 //
577 ASSERT((Mdl->MdlFlags & MDL_IO_SPACE) == 0);
578 ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
579
580 //
581 // Get address and page information
582 //
583 Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
584 NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
585
586 //
587 // Acquire PFN lock
588 //
589 OldIrql = MiAcquirePfnLock();
590
591 //
592 // Loop all the MDL pages
593 //
594 Pages = (PPFN_NUMBER)(Mdl + 1);
595 do
596 {
597 //
598 // Reached the last page
599 //
600 if (*Pages == LIST_HEAD) break;
601
602 //
603 // Get the page entry
604 //
605 Pfn1 = MiGetPfnEntry(*Pages);
606 ASSERT(Pfn1);
607 ASSERT(Pfn1->u2.ShareCount == 1);
608 ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
609 if (Pfn1->u4.PteFrame != 0x1FFEDCB)
610 {
611 /* Corrupted PFN entry or invalid free */
612 KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages);
613 }
614
615 //
616 // Clear it
617 //
618 Pfn1->u3.e1.StartOfAllocation = 0;
619 Pfn1->u3.e1.EndOfAllocation = 0;
621 Pfn1->u2.ShareCount = 0;
622
623 //
624 // Dereference it
625 //
626 ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
627 if (Pfn1->u3.e2.ReferenceCount != 1)
628 {
629 /* Just take off one reference */
630 InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
631 }
632 else
633 {
634 /* We'll be nuking the whole page */
635 MiDecrementReferenceCount(Pfn1, *Pages);
636 }
637
638 //
639 // Clear this page and move on
640 //
641 *Pages++ = LIST_HEAD;
642 } while (--NumberOfPages != 0);
643
644 //
645 // Release the lock
646 //
647 MiReleasePfnLock(OldIrql);
648
649 //
650 // Remove the pages locked flag
651 //
652 Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
653}
654
655/*
656 * @implemented
657 */
658PVOID
659NTAPI
664 IN ULONG BugCheckOnFailure,
665 IN ULONG Priority) // MM_PAGE_PRIORITY
666{
667 PVOID Base;
668 PPFN_NUMBER MdlPages, LastPage;
669 PFN_COUNT PageCount;
670 BOOLEAN IsIoMapping;
671 MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
672 PMMPTE PointerPte;
674
675 //
676 // Sanity check
677 //
678 ASSERT(Mdl->ByteCount != 0);
679
680 //
681 // Get the base
682 //
683 Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
684
685 //
686 // Handle kernel case first
687 //
688 if (AccessMode == KernelMode)
689 {
690 //
691 // Get the list of pages and count
692 //
693 MdlPages = (PPFN_NUMBER)(Mdl + 1);
694 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
695 LastPage = MdlPages + PageCount;
696
697 //
698 // Sanity checks
699 //
700 ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
703 ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_PARTIAL)) != 0);
704
705 //
706 // Get the correct cache type
707 //
708 IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
709 CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
710
711 //
712 // Reserve the PTEs
713 //
714 PointerPte = MiReserveSystemPtes(PageCount, SystemPteSpace);
715 if (!PointerPte)
716 {
717 //
718 // If it can fail, return NULL
719 //
720 if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) return NULL;
721
722 //
723 // Should we bugcheck?
724 //
725 if (!BugCheckOnFailure) return NULL;
726
727 //
728 // Yes, crash the system
729 //
730 KeBugCheckEx(NO_MORE_SYSTEM_PTES, 0, PageCount, 0, 0);
731 }
732
733 //
734 // Get the mapped address
735 //
736 Base = (PVOID)((ULONG_PTR)MiPteToAddress(PointerPte) + Mdl->ByteOffset);
737
738 //
739 // Get the template
740 //
742 switch (CacheAttribute)
743 {
744 case MiNonCached:
745
746 //
747 // Disable caching
748 //
751 break;
752
753 case MiWriteCombined:
754
755 //
756 // Enable write combining
757 //
760 break;
761
762 default:
763 //
764 // Nothing to do
765 //
766 break;
767 }
768
769 //
770 // Loop all PTEs
771 //
772 do
773 {
774 //
775 // We're done here
776 //
777 if (*MdlPages == LIST_HEAD) break;
778
779 //
780 // Write the PTE
781 //
782 TempPte.u.Hard.PageFrameNumber = *MdlPages;
783 MI_WRITE_VALID_PTE(PointerPte++, TempPte);
784 } while (++MdlPages < LastPage);
785
786 //
787 // Mark it as mapped
788 //
789 ASSERT((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0);
790 Mdl->MappedSystemVa = Base;
791 Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
792
793 //
794 // Check if it was partial
795 //
796 if (Mdl->MdlFlags & MDL_PARTIAL)
797 {
798 //
799 // Write the appropriate flag here too
800 //
801 Mdl->MdlFlags |= MDL_PARTIAL_HAS_BEEN_MAPPED;
802 }
803
804 //
805 // Return the mapped address
806 //
807 return Base;
808 }
809
811}
812
813/*
814 * @implemented
815 */
816PVOID
817NTAPI
820{
821 //
822 // Call the extended version
823 //
826 MmCached,
827 NULL,
828 TRUE,
830}
831
832/*
833 * @implemented
834 */
835VOID
836NTAPI
838 IN PMDL Mdl)
839{
840 PVOID Base;
841 PFN_COUNT PageCount, ExtraPageCount;
842 PPFN_NUMBER MdlPages;
843 PMMPTE PointerPte;
844
845 //
846 // Sanity check
847 //
848 ASSERT(Mdl->ByteCount != 0);
849
850 //
851 // Check if this is a kernel request
852 //
854 {
855 //
856 // Get base and count information
857 //
858 Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
859 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
860
861 //
862 // Sanity checks
863 //
864 ASSERT((Mdl->MdlFlags & MDL_PARENT_MAPPED_SYSTEM_VA) == 0);
865 ASSERT(PageCount != 0);
867
868 //
869 // Get the PTE
870 //
871 PointerPte = MiAddressToPte(BaseAddress);
872
873 //
874 // This should be a resident system PTE
875 //
877 ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
878 ASSERT(PointerPte->u.Hard.Valid == 1);
879
880 //
881 // Check if the caller wants us to free advanced pages
882 //
883 if (Mdl->MdlFlags & MDL_FREE_EXTRA_PTES)
884 {
885 //
886 // Get the MDL page array
887 //
888 MdlPages = MmGetMdlPfnArray(Mdl);
889
890 /* Number of extra pages stored after the PFN array */
891 ExtraPageCount = (PFN_COUNT)*(MdlPages + PageCount);
892
893 //
894 // Do the math
895 //
896 PageCount += ExtraPageCount;
897 PointerPte -= ExtraPageCount;
899 ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
900
901 //
902 // Get the new base address
903 //
905 (ExtraPageCount << PAGE_SHIFT));
906 }
907
908 //
909 // Remove flags
910 //
911 Mdl->MdlFlags &= ~(MDL_MAPPED_TO_SYSTEM_VA |
914
915 //
916 // Release the system PTEs
917 //
918 MiReleaseSystemPtes(PointerPte, PageCount, SystemPteSpace);
919 }
920 else
921 {
923 }
924}
925
926/*
927 * @implemented
928 */
929VOID
930NTAPI
934{
935 PPFN_NUMBER MdlPages;
936 PVOID Base, Address, LastAddress, StartAddress;
937 ULONG LockPages, TotalPages;
939 PEPROCESS CurrentProcess;
940 NTSTATUS ProbeStatus;
941 PMMPTE PointerPte, LastPte;
942 PMMPDE PointerPde;
943#if (_MI_PAGING_LEVELS >= 3)
944 PMMPDE PointerPpe;
945#endif
946#if (_MI_PAGING_LEVELS == 4)
947 PMMPDE PointerPxe;
948#endif
949 PFN_NUMBER PageFrameIndex;
950 BOOLEAN UsePfnLock;
952 PMMPFN Pfn1;
953 DPRINT("Probing MDL: %p\n", Mdl);
954
955 //
956 // Sanity checks
957 //
958 ASSERT(Mdl->ByteCount != 0);
959 ASSERT(((ULONG)Mdl->ByteOffset & ~(PAGE_SIZE - 1)) == 0);
960 ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
961 ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
965 MDL_IO_SPACE)) == 0);
966
967 //
968 // Get page and base information
969 //
970 MdlPages = (PPFN_NUMBER)(Mdl + 1);
971 Base = Mdl->StartVa;
972
973 //
974 // Get the addresses and how many pages we span (and need to lock)
975 //
976 Address = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
977 LastAddress = (PVOID)((ULONG_PTR)Address + Mdl->ByteCount);
978 LockPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Address, Mdl->ByteCount);
979 ASSERT(LockPages != 0);
980
981 /* Block invalid access */
982 if ((AccessMode != KernelMode) &&
983 ((LastAddress > (PVOID)MM_USER_PROBE_ADDRESS) || (Address >= LastAddress)))
984 {
985 /* Caller should be in SEH, raise the error */
986 *MdlPages = LIST_HEAD;
988 }
989
990 //
991 // Get the process
992 //
994 {
995 //
996 // Get the process
997 //
998 CurrentProcess = PsGetCurrentProcess();
999 }
1000 else
1001 {
1002 //
1003 // No process
1004 //
1005 CurrentProcess = NULL;
1006 }
1007
1008 //
1009 // Save the number of pages we'll have to lock, and the start address
1010 //
1011 TotalPages = LockPages;
1012 StartAddress = Address;
1013
1014 /* Large pages not supported */
1016
1017 //
1018 // Now probe them
1019 //
1020 ProbeStatus = STATUS_SUCCESS;
1021 _SEH2_TRY
1022 {
1023 //
1024 // Enter probe loop
1025 //
1026 do
1027 {
1028 //
1029 // Assume failure
1030 //
1031 *MdlPages = LIST_HEAD;
1032
1033 //
1034 // Read
1035 //
1036 *(volatile CHAR*)Address;
1037
1038 //
1039 // Check if this is write access (only probe for user-mode)
1040 //
1041 if ((Operation != IoReadAccess) &&
1043 {
1044 //
1045 // Probe for write too
1046 //
1048 }
1049
1050 //
1051 // Next address...
1052 //
1054
1055 //
1056 // Next page...
1057 //
1058 LockPages--;
1059 MdlPages++;
1060 } while (Address < LastAddress);
1061
1062 //
1063 // Reset back to the original page
1064 //
1065 ASSERT(LockPages == 0);
1066 MdlPages = (PPFN_NUMBER)(Mdl + 1);
1067 }
1069 {
1070 //
1071 // Oops :(
1072 //
1073 ProbeStatus = _SEH2_GetExceptionCode();
1074 }
1075 _SEH2_END;
1076
1077 //
1078 // So how did that go?
1079 //
1080 if (ProbeStatus != STATUS_SUCCESS)
1081 {
1082 //
1083 // Fail
1084 //
1085 DPRINT1("MDL PROBE FAILED!\n");
1086 Mdl->Process = NULL;
1087 ExRaiseStatus(ProbeStatus);
1088 }
1089
1090 //
1091 // Get the PTE and PDE
1092 //
1093 PointerPte = MiAddressToPte(StartAddress);
1094 PointerPde = MiAddressToPde(StartAddress);
1095#if (_MI_PAGING_LEVELS >= 3)
1096 PointerPpe = MiAddressToPpe(StartAddress);
1097#endif
1098#if (_MI_PAGING_LEVELS == 4)
1099 PointerPxe = MiAddressToPxe(StartAddress);
1100#endif
1101
1102 //
1103 // Sanity check
1104 //
1105 ASSERT(MdlPages == (PPFN_NUMBER)(Mdl + 1));
1106
1107 //
1108 // Check what kind of operation this is
1109 //
1110 if (Operation != IoReadAccess)
1111 {
1112 //
1113 // Set the write flag
1114 //
1115 Mdl->MdlFlags |= MDL_WRITE_OPERATION;
1116 }
1117 else
1118 {
1119 //
1120 // Remove the write flag
1121 //
1122 Mdl->MdlFlags &= ~(MDL_WRITE_OPERATION);
1123 }
1124
1125 //
1126 // Mark the MDL as locked *now*
1127 //
1128 Mdl->MdlFlags |= MDL_PAGES_LOCKED;
1129
1130 //
1131 // Check if this came from kernel mode
1132 //
1134 {
1135 //
1136 // We should not have a process
1137 //
1138 ASSERT(CurrentProcess == NULL);
1139 Mdl->Process = NULL;
1140
1141 //
1142 // In kernel mode, we don't need to check for write access
1143 //
1145
1146 //
1147 // Use the PFN lock
1148 //
1149 UsePfnLock = TRUE;
1150 OldIrql = MiAcquirePfnLock();
1151 }
1152 else
1153 {
1154 //
1155 // Sanity checks
1156 //
1157 ASSERT(TotalPages != 0);
1158 ASSERT(CurrentProcess == PsGetCurrentProcess());
1159
1160 //
1161 // Track locked pages
1162 //
1164 TotalPages);
1165
1166 //
1167 // Save the process
1168 //
1169 Mdl->Process = CurrentProcess;
1170
1171 /* Lock the process working set */
1173 UsePfnLock = FALSE;
1175 }
1176
1177 //
1178 // Get the last PTE
1179 //
1180 LastPte = MiAddressToPte((PVOID)((ULONG_PTR)LastAddress - 1));
1181
1182 //
1183 // Loop the pages
1184 //
1185 do
1186 {
1187 //
1188 // Assume failure and check for non-mapped pages
1189 //
1190 *MdlPages = LIST_HEAD;
1191 while (
1192#if (_MI_PAGING_LEVELS == 4)
1193 (PointerPxe->u.Hard.Valid == 0) ||
1194#endif
1195#if (_MI_PAGING_LEVELS >= 3)
1196 (PointerPpe->u.Hard.Valid == 0) ||
1197#endif
1198 (PointerPde->u.Hard.Valid == 0) ||
1199 (PointerPte->u.Hard.Valid == 0))
1200 {
1201 //
1202 // What kind of lock were we using?
1203 //
1204 if (UsePfnLock)
1205 {
1206 //
1207 // Release PFN lock
1208 //
1209 MiReleasePfnLock(OldIrql);
1210 }
1211 else
1212 {
1213 /* Release process working set */
1215 }
1216
1217 //
1218 // Access the page
1219 //
1220 Address = MiPteToAddress(PointerPte);
1221
1222 //HACK: Pass a placeholder TrapInformation so the fault handler knows we're unlocked
1223 Status = MmAccessFault(FALSE, Address, KernelMode, (PVOID)(ULONG_PTR)0xBADBADA3BADBADA3ULL);
1224 if (!NT_SUCCESS(Status))
1225 {
1226 //
1227 // Fail
1228 //
1229 DPRINT1("Access fault failed\n");
1230 goto Cleanup;
1231 }
1232
1233 //
1234 // What lock should we use?
1235 //
1236 if (UsePfnLock)
1237 {
1238 //
1239 // Grab the PFN lock
1240 //
1241 OldIrql = MiAcquirePfnLock();
1242 }
1243 else
1244 {
1245 /* Lock the process working set */
1247 }
1248 }
1249
1250 //
1251 // Check if this was a write or modify
1252 //
1253 if (Operation != IoReadAccess)
1254 {
1255 //
1256 // Check if the PTE is not writable
1257 //
1258 if (MI_IS_PAGE_WRITEABLE(PointerPte) == FALSE)
1259 {
1260 //
1261 // Check if it's copy on write
1262 //
1263 if (MI_IS_PAGE_COPY_ON_WRITE(PointerPte))
1264 {
1265 //
1266 // Get the base address and allow a change for user-mode
1267 //
1268 Address = MiPteToAddress(PointerPte);
1270 {
1271 //
1272 // What kind of lock were we using?
1273 //
1274 if (UsePfnLock)
1275 {
1276 //
1277 // Release PFN lock
1278 //
1279 MiReleasePfnLock(OldIrql);
1280 }
1281 else
1282 {
1283 /* Release process working set */
1285 }
1286
1287 //
1288 // Access the page
1289 //
1290
1291 //HACK: Pass a placeholder TrapInformation so the fault handler knows we're unlocked
1292 Status = MmAccessFault(TRUE, Address, KernelMode, (PVOID)(ULONG_PTR)0xBADBADA3BADBADA3ULL);
1293 if (!NT_SUCCESS(Status))
1294 {
1295 //
1296 // Fail
1297 //
1298 DPRINT1("Access fault failed\n");
1299 goto Cleanup;
1300 }
1301
1302 //
1303 // Re-acquire the lock
1304 //
1305 if (UsePfnLock)
1306 {
1307 //
1308 // Grab the PFN lock
1309 //
1310 OldIrql = MiAcquirePfnLock();
1311 }
1312 else
1313 {
1314 /* Lock the process working set */
1316 }
1317
1318 //
1319 // Start over
1320 //
1321 continue;
1322 }
1323 }
1324
1325 //
1326 // Fail, since we won't allow this
1327 //
1329 goto CleanupWithLock;
1330 }
1331 }
1332
1333 //
1334 // Grab the PFN
1335 //
1336 PageFrameIndex = PFN_FROM_PTE(PointerPte);
1337 Pfn1 = MiGetPfnEntry(PageFrameIndex);
1338 if (Pfn1)
1339 {
1340 /* Either this is for kernel-mode, or the working set is held */
1341 ASSERT((CurrentProcess == NULL) || (UsePfnLock == FALSE));
1342
1343 /* No Physical VADs supported yet */
1344 if (CurrentProcess) ASSERT(CurrentProcess->PhysicalVadRoot == NULL);
1345
1346 /* This address should already exist and be fully valid */
1348 }
1349 else
1350 {
1351 //
1352 // For I/O addresses, just remember this
1353 //
1354 Mdl->MdlFlags |= MDL_IO_SPACE;
1355 }
1356
1357 //
1358 // Write the page and move on
1359 //
1360 *MdlPages++ = PageFrameIndex;
1361 PointerPte++;
1362
1363 /* Check if we're on a PDE boundary */
1364 if (MiIsPteOnPdeBoundary(PointerPte)) PointerPde++;
1365#if (_MI_PAGING_LEVELS >= 3)
1366 if (MiIsPteOnPpeBoundary(PointerPte)) PointerPpe++;
1367#endif
1368#if (_MI_PAGING_LEVELS == 4)
1369 if (MiIsPteOnPxeBoundary(PointerPte)) PointerPxe++;
1370#endif
1371
1372 } while (PointerPte <= LastPte);
1373
1374 //
1375 // What kind of lock were we using?
1376 //
1377 if (UsePfnLock)
1378 {
1379 //
1380 // Release PFN lock
1381 //
1382 MiReleasePfnLock(OldIrql);
1383 }
1384 else
1385 {
1386 /* Release process working set */
1388 }
1389
1390 //
1391 // Sanity check
1392 //
1393 ASSERT((Mdl->MdlFlags & MDL_DESCRIBES_AWE) == 0);
1394 return;
1395
1396CleanupWithLock:
1397 //
1398 // This is the failure path
1399 //
1401
1402 //
1403 // What kind of lock were we using?
1404 //
1405 if (UsePfnLock)
1406 {
1407 //
1408 // Release PFN lock
1409 //
1410 MiReleasePfnLock(OldIrql);
1411 }
1412 else
1413 {
1414 /* Release process working set */
1416 }
1417Cleanup:
1418 //
1419 // Pages must be locked so MmUnlock can work
1420 //
1421 ASSERT(Mdl->MdlFlags & MDL_PAGES_LOCKED);
1423
1424 //
1425 // Raise the error
1426 //
1428}
1429
1430/*
1431 * @implemented
1432 */
1433VOID
1434NTAPI
1436{
1437 PPFN_NUMBER MdlPages, LastPage;
1439 PVOID Base;
1440 ULONG Flags, PageCount;
1441 KIRQL OldIrql;
1442 PMMPFN Pfn1;
1443 DPRINT("Unlocking MDL: %p\n", Mdl);
1444
1445 //
1446 // Sanity checks
1447 //
1448 ASSERT((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0);
1449 ASSERT((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0);
1450 ASSERT((Mdl->MdlFlags & MDL_PARTIAL) == 0);
1451 ASSERT(Mdl->ByteCount != 0);
1452
1453 //
1454 // Get the process associated and capture the flags which are volatile
1455 //
1456 Process = Mdl->Process;
1457 Flags = Mdl->MdlFlags;
1458
1459 //
1460 // Automagically undo any calls to MmGetSystemAddressForMdl's for this MDL
1461 //
1462 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
1463 {
1464 //
1465 // Unmap the pages from system space
1466 //
1467 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
1468 }
1469
1470 //
1471 // Get the page count
1472 //
1473 MdlPages = (PPFN_NUMBER)(Mdl + 1);
1474 Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
1475 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
1476 ASSERT(PageCount != 0);
1477
1478 //
1479 // We don't support AWE
1480 //
1482
1483 //
1484 // Check if the buffer is mapped I/O space
1485 //
1486 if (Flags & MDL_IO_SPACE)
1487 {
1488 //
1489 // Acquire PFN lock
1490 //
1491 OldIrql = MiAcquirePfnLock();
1492
1493 //
1494 // Loop every page
1495 //
1496 LastPage = MdlPages + PageCount;
1497 do
1498 {
1499 //
1500 // Last page, break out
1501 //
1502 if (*MdlPages == LIST_HEAD) break;
1503
1504 //
1505 // Check if this page is in the PFN database
1506 //
1507 Pfn1 = MiGetPfnEntry(*MdlPages);
1508 if (Pfn1) MiDereferencePfnAndDropLockCount(Pfn1);
1509 } while (++MdlPages < LastPage);
1510
1511 //
1512 // Release the lock
1513 //
1514 MiReleasePfnLock(OldIrql);
1515
1516 //
1517 // Check if we have a process
1518 //
1519 if (Process)
1520 {
1521 //
1522 // Handle the accounting of locked pages
1523 //
1524 ASSERT(Process->NumberOfLockedPages > 0);
1525 InterlockedExchangeAddSizeT(&Process->NumberOfLockedPages,
1526 -(LONG_PTR)PageCount);
1527 }
1528
1529 //
1530 // We're done
1531 //
1532 Mdl->MdlFlags &= ~MDL_IO_SPACE;
1533 Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1534 return;
1535 }
1536
1537 //
1538 // Check if we have a process
1539 //
1540 if (Process)
1541 {
1542 //
1543 // Handle the accounting of locked pages
1544 //
1545 ASSERT(Process->NumberOfLockedPages > 0);
1546 InterlockedExchangeAddSizeT(&Process->NumberOfLockedPages,
1547 -(LONG_PTR)PageCount);
1548 }
1549
1550 //
1551 // Loop every page
1552 //
1553 LastPage = MdlPages + PageCount;
1554 do
1555 {
1556 //
1557 // Last page reached
1558 //
1559 if (*MdlPages == LIST_HEAD)
1560 {
1561 //
1562 // Were there no pages at all?
1563 //
1564 if (MdlPages == (PPFN_NUMBER)(Mdl + 1))
1565 {
1566 //
1567 // We're already done
1568 //
1569 Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1570 return;
1571 }
1572
1573 //
1574 // Otherwise, stop here
1575 //
1576 LastPage = MdlPages;
1577 break;
1578 }
1579
1580 /* Save the PFN entry instead for the secondary loop */
1581 *MdlPages = (PFN_NUMBER)MiGetPfnEntry(*MdlPages);
1582 ASSERT(*MdlPages != 0);
1583 } while (++MdlPages < LastPage);
1584
1585 //
1586 // Reset pointer
1587 //
1588 MdlPages = (PPFN_NUMBER)(Mdl + 1);
1589
1590 //
1591 // Now grab the PFN lock for the actual unlock and dereference
1592 //
1593 OldIrql = MiAcquirePfnLock();
1594 do
1595 {
1596 /* Get the current entry and reference count */
1597 Pfn1 = (PMMPFN)*MdlPages;
1599 } while (++MdlPages < LastPage);
1600
1601 //
1602 // Release the lock
1603 //
1604 MiReleasePfnLock(OldIrql);
1605
1606 //
1607 // We're done
1608 //
1609 Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1610}
1611
1612/*
1613 * @unimplemented
1614 */
1616NTAPI
1619{
1622}
1623
1624/*
1625 * @unimplemented
1626 */
1627PVOID
1628NTAPI
1633{
1635 return 0;
1636}
1637
1638/*
1639 * @unimplemented
1640 */
1641VOID
1642NTAPI
1646{
1648}
1649
1650/*
1651 * @unimplemented
1652 */
1654NTAPI
1656 IN PREAD_LIST *ReadLists)
1657{
1660}
1661
1662/*
1663 * @unimplemented
1664 */
1666NTAPI
1669{
1672}
1673
1674/*
1675 * @unimplemented
1676 */
1677VOID
1678NTAPI
1683{
1685}
1686
1687
1688/*
1689 * @unimplemented
1690 */
1691VOID
1692NTAPI
1694 IN LARGE_INTEGER PageList[],
1697{
1699}
1700
1701/*
1702 * @unimplemented
1703 */
1704VOID
1705NTAPI
1707{
1709}
1710
1711/* EOF */
#define PAGED_CODE()
unsigned char BOOLEAN
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define MM_USER_PROBE_ADDRESS
Definition: armddk.h:19
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOL Error
Definition: chkdsk.c:66
#define UNIMPLEMENTED
Definition: debug.h:115
#define MM_READWRITE
Definition: bootanim.c:19
#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
static const WCHAR Cleanup[]
Definition: register.c:80
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
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 PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
FP_OP Operation
Definition: fpcontrol.c:150
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
#define InterlockedDecrement16
Definition: interlocked.h:139
#define _ReturnAddress()
Definition: intrin_arm.h:35
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
if(dx< 0)
Definition: linetemp.h:194
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:116
@ SystemPteSpace
Definition: miarm.h:403
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:945
PMDL NTAPI MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes, IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute, IN ULONG Flags)
Definition: freelist.c:182
PMMPTE MmSystemPtesStart[MaximumPtePoolTypes]
Definition: syspte.c:22
FORCEINLINE VOID MiDeletePde(_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
Definition: miarm.h:2541
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:827
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:440
PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes]
Definition: syspte.c:23
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:1006
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2507
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
FORCEINLINE VOID MiUnlockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1194
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1239
@ MiWriteCombined
Definition: miarm.h:412
@ MiCached
Definition: miarm.h:411
@ MiNotMapped
Definition: miarm.h:413
@ MiNonCached
Definition: miarm.h:410
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2479
FORCEINLINE VOID MiDereferencePfnAndDropLockCount(IN PMMPFN Pfn1)
Definition: miarm.h:1615
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
FORCEINLINE VOID MiReferenceProbedPageAndBumpLockCount(IN PMMPFN Pfn1)
Definition: miarm.h:1687
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1236
TABLE_SEARCH_RESULT NTAPI MiFindEmptyAddressRangeInTree(IN SIZE_T Length, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PMMADDRESS_NODE *PreviousVad, OUT PULONG_PTR Base)
Definition: vadnode.c:584
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:959
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:195
TABLE_SEARCH_RESULT NTAPI MiCheckForConflictingNode(IN ULONG_PTR StartVpn, IN ULONG_PTR EndVpn, IN PMM_AVL_TABLE Table, OUT PMMADDRESS_NODE *NodeOrParent)
Definition: vadnode.c:150
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2481
VOID NTAPI MiInsertVad(_Inout_ PMMVAD Vad, _Inout_ PMM_AVL_TABLE VadRoot)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1574
FORCEINLINE VOID MiLockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1124
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1169
VOID NTAPI MmMapMemoryDumpMdl(IN PMDL Mdl)
Definition: mdlsup.c:1706
BOOLEAN MmTrackLockedPages
Definition: mdlsup.c:21
PVOID NTAPI MmMapLockedPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode)
Definition: mdlsup.c:818
VOID NTAPI MmFreePagesFromMdl(IN PMDL Mdl)
Definition: mdlsup.c:564
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
VOID NTAPI MmProbeAndLockSelectedPages(IN OUT PMDL MemoryDescriptorList, IN LARGE_INTEGER PageList[], IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:1693
PMDL NTAPI MmAllocatePagesForMdlEx(IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes, IN MEMORY_CACHING_TYPE CacheType, IN ULONG Flags)
Definition: mdlsup.c:510
VOID NTAPI MmUnmapReservedMapping(IN PVOID BaseAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList)
Definition: mdlsup.c:1643
NTSTATUS NTAPI MmPrefetchPages(IN ULONG NumberOfLists, IN PREAD_LIST *ReadLists)
Definition: mdlsup.c:1655
PVOID NTAPI MmMapLockedPagesWithReservedMapping(IN PVOID MappingAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType)
Definition: mdlsup.c:1629
VOID NTAPI MmProbeAndLockProcessPages(IN OUT PMDL MemoryDescriptorList, IN PEPROCESS Process, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:1679
PMDL NTAPI MmAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes)
Definition: mdlsup.c:489
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
static VOID NTAPI MiUnmapLockedPagesInUserSpace(_In_ PVOID BaseAddress, _In_ PMDL Mdl)
Definition: mdlsup.c:293
ULONG MiCacheOverride[MiNotMapped+1]
Definition: mdlsup.c:24
SIZE_T MmSystemLockPagesCount
Definition: mdlsup.c:22
PMDL NTAPI MmCreateMdl(IN PMDL Mdl, IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:378
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN ULONG Priority)
Definition: mdlsup.c:660
BOOLEAN MmTrackPtes
Definition: mdlsup.c:20
SIZE_T NTAPI MmSizeOfMdl(IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:409
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
static PVOID NTAPI MiMapLockedPagesInUserSpace(_In_ PMDL Mdl, _In_ PVOID StartVa, _In_ MEMORY_CACHING_TYPE CacheType, _In_opt_ PVOID BaseAddress)
Definition: mdlsup.c:30
NTSTATUS NTAPI MmProtectMdlSystemAddress(IN PMDL MemoryDescriptorList, IN ULONG NewProtect)
Definition: mdlsup.c:1667
NTSTATUS NTAPI MmAdvanceMdl(IN PMDL Mdl, IN ULONG NumberOfBytes)
Definition: mdlsup.c:1617
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ HighPagePriority
Definition: imports.h:57
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define KernelMode
Definition: asm.h:34
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
@ VadDevicePhysicalMemory
Definition: mmtypes.h:205
@ StandbyPageList
Definition: mmtypes.h:155
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:272
#define MI_IS_PAGE_COPY_ON_WRITE(x)
Definition: mm.h:110
#define MI_PAGE_WRITE_COMBINED(x)
Definition: mm.h:103
#define MI_PAGE_DISABLE_CACHE(x)
Definition: mm.h:101
#define MI_IS_PAGE_WRITEABLE(x)
Definition: mm.h:106
#define MiIsPteOnPpeBoundary(PointerPte)
Definition: mm.h:308
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
#define _MI_PAGING_LEVELS
Definition: mm.h:6
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:161
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:306
#define MiIsPteOnPxeBoundary(PointerPte)
Definition: mm.h:310
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:102
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToPde(_Pte)
Definition: mm.h:121
#define MiPteToAddress(_Pte)
Definition: mm.h:116
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:663
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MM_NOIRQL
Definition: mm.h:70
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1691
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
struct _MMPFN * PMMPFN
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1704
NTSTATUS NTAPI MmAccessFault(IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: mmfault.c:209
#define ExRaiseStatus
Definition: ntoskrnl.h:114
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:617
MMPTE ValidKernelPte
Definition: init.c:29
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:557
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
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 ProbeForWriteChar(Ptr)
Definition: probe.h:33
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:71
PMM_AVL_TABLE PhysicalVadRoot
Definition: pstypes.h:1298
PFN_NUMBER NumberOfLockedPages
Definition: pstypes.h:1301
ULONG PageFrameNumber
Definition: mmtypes.h:109
USHORT CacheAttribute
Definition: mm.h:367
USHORT PageLocation
Definition: mm.h:365
Definition: mm.h:374
union _MMPFN::@1790 u3
union _MMPFN::@1789 u2
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1793 u4
ULONG_PTR ShareCount
Definition: mm.h:390
struct _MMPFN::@1790::@1796 e2
ULONG_PTR PteFrame
Definition: mm.h:418
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2325 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG LongVad
Definition: mmtypes.h:711
ULONG_PTR Protection
Definition: mmtypes.h:696
ULONG_PTR VadType
Definition: mmtypes.h:694
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
union _MMVAD_LONG::@2610 u2
ULONG_PTR EndingVpn
Definition: mmtypes.h:759
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
union _MMVAD_LONG::@2609 u
ULONG_PTR StartingVpn
Definition: mmtypes.h:758
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
union _MMVAD::@2606 u
#define LIST_HEAD(name, type)
Definition: queue.h:167
#define TAG_MDL
Definition: tag.h:89
int16_t * PSHORT
Definition: typedefs.h:55
#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
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG PoolTag
Definition: wdfmemory.h:164
int WINAPI EndPage(_In_ HDC)
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_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
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
enum _LOCK_OPERATION LOCK_OPERATION
@ IoReadAccess
Definition: ketypes.h:863
#define MmGetMdlByteOffset(_Mdl)
#define MmGetMdlByteCount(_Mdl)
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
#define MmGetMdlVirtualAddress(_Mdl)
_Inout_ PMDL MemoryDescriptorList
Definition: mmfuncs.h:405
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
#define BYTE_OFFSET(Va)
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define PAGE_ALIGN(Va)
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
#define MmGetMdlPfnArray(_Mdl)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:227
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:217
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_ SIZE_T TotalBytes
Definition: mmfuncs.h:228
#define MDL_PARTIAL_HAS_BEEN_MAPPED
Definition: mmtypes.h:23
#define MDL_WRITE_OPERATION
Definition: mmtypes.h:25
#define MDL_FREE_EXTRA_PTES
Definition: mmtypes.h:27
MDL
Definition: mmtypes.h:117
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
@ MmCached
Definition: mmtypes.h:130
@ MmWriteCombined
Definition: mmtypes.h:131
#define MM_DONT_ZERO_ALLOCATION
Definition: mmtypes.h:11
#define MDL_MAPPING_CAN_FAIL
Definition: mmtypes.h:31
#define MDL_PARENT_MAPPED_SYSTEM_VA
Definition: mmtypes.h:26
#define MM_ALLOCATE_FROM_LOCAL_NODE_ONLY
Definition: mmtypes.h:12
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_IO_SPACE
Definition: mmtypes.h:29
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define MDL_DESCRIBES_AWE
Definition: mmtypes.h:28
#define MDL_PARTIAL
Definition: mmtypes.h:22
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
#define PsGetCurrentProcess
Definition: psfuncs.h:17
TABLE_SEARCH_RESULT
Definition: rtltypes.h:373
char CHAR
Definition: xmlstorage.h:175