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