ReactOS  r74431
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 
24 /* PUBLIC FUNCTIONS ***********************************************************/
25 
26 /*
27  * @implemented
28  */
29 PMDL
30 NTAPI
32  IN PVOID Base,
34 {
35  SIZE_T Size;
36 
37  //
38  // Check if we don't have an MDL built
39  //
40  if (!Mdl)
41  {
42  //
43  // Calculate the size we'll need and allocate the MDL
44  //
45  Size = MmSizeOfMdl(Base, Length);
47  if (!Mdl) return NULL;
48  }
49 
50  //
51  // Initialize it
52  //
53  MmInitializeMdl(Mdl, Base, Length);
54  return Mdl;
55 }
56 
57 /*
58  * @implemented
59  */
60 SIZE_T
61 NTAPI
64 {
65  //
66  // Return the MDL size
67  //
68  return sizeof(MDL) +
69  (ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Length) * sizeof(PFN_NUMBER));
70 }
71 
72 /*
73  * @implemented
74  */
75 VOID
76 NTAPI
78 {
79  PPFN_NUMBER MdlPages, EndPage;
80  PFN_NUMBER Pfn, PageCount;
81  PVOID Base;
82  PMMPTE PointerPte;
83 
84  //
85  // Sanity checks
86  //
87  ASSERT(Mdl->ByteCount != 0);
88  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
91  MDL_PARTIAL)) == 0);
92 
93  //
94  // We know the MDL isn't associated to a process now
95  //
96  Mdl->Process = NULL;
97 
98  //
99  // Get page and VA information
100  //
101  MdlPages = (PPFN_NUMBER)(Mdl + 1);
102  Base = Mdl->StartVa;
103 
104  //
105  // Set the system address and now get the page count
106  //
107  Mdl->MappedSystemVa = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
108  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Mdl->MappedSystemVa,
109  Mdl->ByteCount);
110  ASSERT(PageCount != 0);
111  EndPage = MdlPages + PageCount;
112 
113  //
114  // Loop the PTEs
115  //
116  PointerPte = MiAddressToPte(Base);
117  do
118  {
119  //
120  // Write the PFN
121  //
122  Pfn = PFN_FROM_PTE(PointerPte++);
123  *MdlPages++ = Pfn;
124  } while (MdlPages < EndPage);
125 
126  //
127  // Set the nonpaged pool flag
128  //
129  Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
130 
131  //
132  // Check if this is an I/O mapping
133  //
134  if (!MiGetPfnEntry(Pfn)) Mdl->MdlFlags |= MDL_IO_SPACE;
135 }
136 
137 /*
138  * @implemented
139  */
140 PMDL
141 NTAPI
146 {
147  //
148  // Call the internal routine
149  //
150  return MiAllocatePagesForMdl(LowAddress,
151  HighAddress,
152  SkipBytes,
153  TotalBytes,
154  MiNotMapped,
155  0);
156 }
157 
158 /*
159  * @implemented
160  */
161 PMDL
162 NTAPI
168  IN ULONG Flags)
169 {
170  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
171 
172  //
173  // Check for invalid cache type
174  //
175  if (CacheType > MmWriteCombined)
176  {
177  //
178  // Normalize to default
179  //
180  CacheAttribute = MiNotMapped;
181  }
182  else
183  {
184  //
185  // Conver to internal caching attribute
186  //
187  CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType];
188  }
189 
190  //
191  // Only these flags are allowed
192  //
194  {
195  //
196  // Silently fail
197  //
198  return NULL;
199  }
200 
201  //
202  // Call the internal routine
203  //
204  return MiAllocatePagesForMdl(LowAddress,
205  HighAddress,
206  SkipBytes,
207  TotalBytes,
208  CacheAttribute,
209  Flags);
210 }
211 
212 /*
213  * @implemented
214  */
215 VOID
216 NTAPI
218 {
219  PVOID Base;
220  PPFN_NUMBER Pages;
221  LONG NumberOfPages;
222  PMMPFN Pfn1;
223  KIRQL OldIrql;
224  DPRINT("Freeing MDL: %p\n", Mdl);
225 
226  //
227  // Sanity checks
228  //
230  ASSERT((Mdl->MdlFlags & MDL_IO_SPACE) == 0);
231  ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
232 
233  //
234  // Get address and page information
235  //
236  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
237  NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
238 
239  //
240  // Acquire PFN lock
241  //
243 
244  //
245  // Loop all the MDL pages
246  //
247  Pages = (PPFN_NUMBER)(Mdl + 1);
248  do
249  {
250  //
251  // Reached the last page
252  //
253  if (*Pages == LIST_HEAD) break;
254 
255  //
256  // Get the page entry
257  //
258  Pfn1 = MiGetPfnEntry(*Pages);
259  ASSERT(Pfn1);
260  ASSERT(Pfn1->u2.ShareCount == 1);
261  ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
262  if (Pfn1->u4.PteFrame != 0x1FFEDCB)
263  {
264  /* Corrupted PFN entry or invalid free */
265  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages);
266  }
267 
268  //
269  // Clear it
270  //
271  Pfn1->u3.e1.StartOfAllocation = 0;
272  Pfn1->u3.e1.EndOfAllocation = 0;
274  Pfn1->u2.ShareCount = 0;
275 
276  //
277  // Dereference it
278  //
279  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
280  if (Pfn1->u3.e2.ReferenceCount != 1)
281  {
282  /* Just take off one reference */
283  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
284  }
285  else
286  {
287  /* We'll be nuking the whole page */
288  MiDecrementReferenceCount(Pfn1, *Pages);
289  }
290 
291  //
292  // Clear this page and move on
293  //
294  *Pages++ = LIST_HEAD;
295  } while (--NumberOfPages != 0);
296 
297  //
298  // Release the lock
299  //
301 
302  //
303  // Remove the pages locked flag
304  //
305  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
306 }
307 
308 /*
309  * @implemented
310  */
311 PVOID
312 NTAPI
317  IN ULONG BugCheckOnFailure,
319 {
320  PVOID Base;
321  PPFN_NUMBER MdlPages, LastPage;
322  PFN_COUNT PageCount;
323  BOOLEAN IsIoMapping;
324  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
325  PMMPTE PointerPte;
326  MMPTE TempPte;
327 
328  //
329  // Sanity check
330  //
331  ASSERT(Mdl->ByteCount != 0);
332 
333  //
334  // Get the base
335  //
336  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
337 
338  //
339  // Handle kernel case first
340  //
341  if (AccessMode == KernelMode)
342  {
343  //
344  // Get the list of pages and count
345  //
346  MdlPages = (PPFN_NUMBER)(Mdl + 1);
347  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
348  LastPage = MdlPages + PageCount;
349 
350  //
351  // Sanity checks
352  //
353  ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
356  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_PARTIAL)) != 0);
357 
358  //
359  // Get the correct cache type
360  //
361  IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
362  CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
363 
364  //
365  // Reserve the PTEs
366  //
367  PointerPte = MiReserveSystemPtes(PageCount, SystemPteSpace);
368  if (!PointerPte)
369  {
370  //
371  // If it can fail, return NULL
372  //
373  if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) return NULL;
374 
375  //
376  // Should we bugcheck?
377  //
378  if (!BugCheckOnFailure) return NULL;
379 
380  //
381  // Yes, crash the system
382  //
383  KeBugCheckEx(NO_MORE_SYSTEM_PTES, 0, PageCount, 0, 0);
384  }
385 
386  //
387  // Get the mapped address
388  //
389  Base = (PVOID)((ULONG_PTR)MiPteToAddress(PointerPte) + Mdl->ByteOffset);
390 
391  //
392  // Get the template
393  //
394  TempPte = ValidKernelPte;
395  switch (CacheAttribute)
396  {
397  case MiNonCached:
398 
399  //
400  // Disable caching
401  //
402  MI_PAGE_DISABLE_CACHE(&TempPte);
403  MI_PAGE_WRITE_THROUGH(&TempPte);
404  break;
405 
406  case MiWriteCombined:
407 
408  //
409  // Enable write combining
410  //
411  MI_PAGE_DISABLE_CACHE(&TempPte);
412  MI_PAGE_WRITE_COMBINED(&TempPte);
413  break;
414 
415  default:
416  //
417  // Nothing to do
418  //
419  break;
420  }
421 
422  //
423  // Loop all PTEs
424  //
425  do
426  {
427  //
428  // We're done here
429  //
430  if (*MdlPages == LIST_HEAD) break;
431 
432  //
433  // Write the PTE
434  //
435  TempPte.u.Hard.PageFrameNumber = *MdlPages;
436  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
437  } while (++MdlPages < LastPage);
438 
439  //
440  // Mark it as mapped
441  //
442  ASSERT((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0);
443  Mdl->MappedSystemVa = Base;
444  Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
445 
446  //
447  // Check if it was partial
448  //
449  if (Mdl->MdlFlags & MDL_PARTIAL)
450  {
451  //
452  // Write the appropriate flag here too
453  //
454  Mdl->MdlFlags |= MDL_PARTIAL_HAS_BEEN_MAPPED;
455  }
456 
457  //
458  // Return the mapped address
459  //
460  return Base;
461  }
462 
464  return NULL;
465 }
466 
467 /*
468  * @implemented
469  */
470 PVOID
471 NTAPI
474 {
475  //
476  // Call the extended version
477  //
478  return MmMapLockedPagesSpecifyCache(Mdl,
479  AccessMode,
480  MmCached,
481  NULL,
482  TRUE,
484 }
485 
486 /*
487  * @implemented
488  */
489 VOID
490 NTAPI
492  IN PMDL Mdl)
493 {
494  PVOID Base;
495  PFN_COUNT PageCount, ExtraPageCount;
496  PPFN_NUMBER MdlPages;
497  PMMPTE PointerPte;
498 
499  //
500  // Sanity check
501  //
502  ASSERT(Mdl->ByteCount != 0);
503 
504  //
505  // Check if this is a kernel request
506  //
507  if (BaseAddress > MM_HIGHEST_USER_ADDRESS)
508  {
509  //
510  // Get base and count information
511  //
512  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
513  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
514 
515  //
516  // Sanity checks
517  //
518  ASSERT((Mdl->MdlFlags & MDL_PARENT_MAPPED_SYSTEM_VA) == 0);
519  ASSERT(PageCount != 0);
520  ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
521 
522  //
523  // Get the PTE
524  //
525  PointerPte = MiAddressToPte(BaseAddress);
526 
527  //
528  // This should be a resident system PTE
529  //
530  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
531  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
532  ASSERT(PointerPte->u.Hard.Valid == 1);
533 
534  //
535  // Check if the caller wants us to free advanced pages
536  //
537  if (Mdl->MdlFlags & MDL_FREE_EXTRA_PTES)
538  {
539  //
540  // Get the MDL page array
541  //
542  MdlPages = MmGetMdlPfnArray(Mdl);
543 
544  /* Number of extra pages stored after the PFN array */
545  ExtraPageCount = (PFN_COUNT)*(MdlPages + PageCount);
546 
547  //
548  // Do the math
549  //
550  PageCount += ExtraPageCount;
551  PointerPte -= ExtraPageCount;
552  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
553  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
554 
555  //
556  // Get the new base address
557  //
558  BaseAddress = (PVOID)((ULONG_PTR)BaseAddress -
559  (ExtraPageCount << PAGE_SHIFT));
560  }
561 
562  //
563  // Remove flags
564  //
565  Mdl->MdlFlags &= ~(MDL_MAPPED_TO_SYSTEM_VA |
568 
569  //
570  // Release the system PTEs
571  //
572  MiReleaseSystemPtes(PointerPte, PageCount, SystemPteSpace);
573  }
574  else
575  {
577  }
578 }
579 
580 /*
581  * @implemented
582  */
583 VOID
584 NTAPI
588 {
589  PPFN_NUMBER MdlPages;
590  PVOID Base, Address, LastAddress, StartAddress;
591  ULONG LockPages, TotalPages;
594  NTSTATUS ProbeStatus;
595  PMMPTE PointerPte, LastPte;
596  PMMPDE PointerPde;
597 #if (_MI_PAGING_LEVELS >= 3)
598  PMMPDE PointerPpe;
599 #endif
600 #if (_MI_PAGING_LEVELS == 4)
601  PMMPDE PointerPxe;
602 #endif
603  PFN_NUMBER PageFrameIndex;
604  BOOLEAN UsePfnLock;
605  KIRQL OldIrql;
606  PMMPFN Pfn1;
607  DPRINT("Probing MDL: %p\n", Mdl);
608 
609  //
610  // Sanity checks
611  //
612  ASSERT(Mdl->ByteCount != 0);
613  ASSERT(((ULONG)Mdl->ByteOffset & ~(PAGE_SIZE - 1)) == 0);
614  ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
615  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
618  MDL_PARTIAL |
619  MDL_IO_SPACE)) == 0);
620 
621  //
622  // Get page and base information
623  //
624  MdlPages = (PPFN_NUMBER)(Mdl + 1);
625  Base = Mdl->StartVa;
626 
627  //
628  // Get the addresses and how many pages we span (and need to lock)
629  //
630  Address = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
631  LastAddress = (PVOID)((ULONG_PTR)Address + Mdl->ByteCount);
632  LockPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Address, Mdl->ByteCount);
633  ASSERT(LockPages != 0);
634 
635  /* Block invalid access */
636  if ((AccessMode != KernelMode) &&
637  ((LastAddress > (PVOID)MM_USER_PROBE_ADDRESS) || (Address >= LastAddress)))
638  {
639  /* Caller should be in SEH, raise the error */
640  *MdlPages = LIST_HEAD;
642  }
643 
644  //
645  // Get the process
646  //
647  if (Address <= MM_HIGHEST_USER_ADDRESS)
648  {
649  //
650  // Get the process
651  //
652  CurrentProcess = PsGetCurrentProcess();
653  }
654  else
655  {
656  //
657  // No process
658  //
659  CurrentProcess = NULL;
660  }
661 
662  //
663  // Save the number of pages we'll have to lock, and the start address
664  //
665  TotalPages = LockPages;
666  StartAddress = Address;
667 
668  /* Large pages not supported */
669  ASSERT(!MI_IS_PHYSICAL_ADDRESS(Address));
670 
671  //
672  // Now probe them
673  //
674  ProbeStatus = STATUS_SUCCESS;
675  _SEH2_TRY
676  {
677  //
678  // Enter probe loop
679  //
680  do
681  {
682  //
683  // Assume failure
684  //
685  *MdlPages = LIST_HEAD;
686 
687  //
688  // Read
689  //
690  *(volatile CHAR*)Address;
691 
692  //
693  // Check if this is write access (only probe for user-mode)
694  //
695  if ((Operation != IoReadAccess) &&
696  (Address <= MM_HIGHEST_USER_ADDRESS))
697  {
698  //
699  // Probe for write too
700  //
701  ProbeForWriteChar(Address);
702  }
703 
704  //
705  // Next address...
706  //
707  Address = PAGE_ALIGN((ULONG_PTR)Address + PAGE_SIZE);
708 
709  //
710  // Next page...
711  //
712  LockPages--;
713  MdlPages++;
714  } while (Address < LastAddress);
715 
716  //
717  // Reset back to the original page
718  //
719  ASSERT(LockPages == 0);
720  MdlPages = (PPFN_NUMBER)(Mdl + 1);
721  }
723  {
724  //
725  // Oops :(
726  //
727  ProbeStatus = _SEH2_GetExceptionCode();
728  }
729  _SEH2_END;
730 
731  //
732  // So how did that go?
733  //
734  if (ProbeStatus != STATUS_SUCCESS)
735  {
736  //
737  // Fail
738  //
739  DPRINT1("MDL PROBE FAILED!\n");
740  Mdl->Process = NULL;
741  ExRaiseStatus(ProbeStatus);
742  }
743 
744  //
745  // Get the PTE and PDE
746  //
747  PointerPte = MiAddressToPte(StartAddress);
748  PointerPde = MiAddressToPde(StartAddress);
749 #if (_MI_PAGING_LEVELS >= 3)
750  PointerPpe = MiAddressToPpe(StartAddress);
751 #endif
752 #if (_MI_PAGING_LEVELS == 4)
753  PointerPxe = MiAddressToPxe(StartAddress);
754 #endif
755 
756  //
757  // Sanity check
758  //
759  ASSERT(MdlPages == (PPFN_NUMBER)(Mdl + 1));
760 
761  //
762  // Check what kind of operation this is
763  //
764  if (Operation != IoReadAccess)
765  {
766  //
767  // Set the write flag
768  //
769  Mdl->MdlFlags |= MDL_WRITE_OPERATION;
770  }
771  else
772  {
773  //
774  // Remove the write flag
775  //
776  Mdl->MdlFlags &= ~(MDL_WRITE_OPERATION);
777  }
778 
779  //
780  // Mark the MDL as locked *now*
781  //
782  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
783 
784  //
785  // Check if this came from kernel mode
786  //
787  if (Base > MM_HIGHEST_USER_ADDRESS)
788  {
789  //
790  // We should not have a process
791  //
792  ASSERT(CurrentProcess == NULL);
793  Mdl->Process = NULL;
794 
795  //
796  // In kernel mode, we don't need to check for write access
797  //
798  Operation = IoReadAccess;
799 
800  //
801  // Use the PFN lock
802  //
803  UsePfnLock = TRUE;
805  }
806  else
807  {
808  //
809  // Sanity checks
810  //
811  ASSERT(TotalPages != 0);
812  ASSERT(CurrentProcess == PsGetCurrentProcess());
813 
814  //
815  // Track locked pages
816  //
818  TotalPages);
819 
820  //
821  // Save the process
822  //
823  Mdl->Process = CurrentProcess;
824 
825  /* Lock the process working set */
826  MiLockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
827  UsePfnLock = FALSE;
828  OldIrql = MM_NOIRQL;
829  }
830 
831  //
832  // Get the last PTE
833  //
834  LastPte = MiAddressToPte((PVOID)((ULONG_PTR)LastAddress - 1));
835 
836  //
837  // Loop the pages
838  //
839  do
840  {
841  //
842  // Assume failure and check for non-mapped pages
843  //
844  *MdlPages = LIST_HEAD;
845  while (
846 #if (_MI_PAGING_LEVELS == 4)
847  (PointerPxe->u.Hard.Valid == 0) ||
848 #endif
849 #if (_MI_PAGING_LEVELS >= 3)
850  (PointerPpe->u.Hard.Valid == 0) ||
851 #endif
852  (PointerPde->u.Hard.Valid == 0) ||
853  (PointerPte->u.Hard.Valid == 0))
854  {
855  //
856  // What kind of lock were we using?
857  //
858  if (UsePfnLock)
859  {
860  //
861  // Release PFN lock
862  //
864  }
865  else
866  {
867  /* Release process working set */
869  }
870 
871  //
872  // Access the page
873  //
874  Address = MiPteToAddress(PointerPte);
875 
876  //HACK: Pass a placeholder TrapInformation so the fault handler knows we're unlocked
877  Status = MmAccessFault(FALSE, Address, KernelMode, (PVOID)0xBADBADA3);
878  if (!NT_SUCCESS(Status))
879  {
880  //
881  // Fail
882  //
883  DPRINT1("Access fault failed\n");
884  goto Cleanup;
885  }
886 
887  //
888  // What lock should we use?
889  //
890  if (UsePfnLock)
891  {
892  //
893  // Grab the PFN lock
894  //
896  }
897  else
898  {
899  /* Lock the process working set */
900  MiLockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
901  }
902  }
903 
904  //
905  // Check if this was a write or modify
906  //
907  if (Operation != IoReadAccess)
908  {
909  //
910  // Check if the PTE is not writable
911  //
912  if (MI_IS_PAGE_WRITEABLE(PointerPte) == FALSE)
913  {
914  //
915  // Check if it's copy on write
916  //
917  if (MI_IS_PAGE_COPY_ON_WRITE(PointerPte))
918  {
919  //
920  // Get the base address and allow a change for user-mode
921  //
922  Address = MiPteToAddress(PointerPte);
923  if (Address <= MM_HIGHEST_USER_ADDRESS)
924  {
925  //
926  // What kind of lock were we using?
927  //
928  if (UsePfnLock)
929  {
930  //
931  // Release PFN lock
932  //
934  }
935  else
936  {
937  /* Release process working set */
939  }
940 
941  //
942  // Access the page
943  //
944 
945  //HACK: Pass a placeholder TrapInformation so the fault handler knows we're unlocked
946  Status = MmAccessFault(TRUE, Address, KernelMode, (PVOID)0xBADBADA3);
947  if (!NT_SUCCESS(Status))
948  {
949  //
950  // Fail
951  //
952  DPRINT1("Access fault failed\n");
953  goto Cleanup;
954  }
955 
956  //
957  // Re-acquire the lock
958  //
959  if (UsePfnLock)
960  {
961  //
962  // Grab the PFN lock
963  //
965  }
966  else
967  {
968  /* Lock the process working set */
969  MiLockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
970  }
971 
972  //
973  // Start over
974  //
975  continue;
976  }
977  }
978 
979  //
980  // Fail, since we won't allow this
981  //
982  Status = STATUS_ACCESS_VIOLATION;
983  goto CleanupWithLock;
984  }
985  }
986 
987  //
988  // Grab the PFN
989  //
990  PageFrameIndex = PFN_FROM_PTE(PointerPte);
991  Pfn1 = MiGetPfnEntry(PageFrameIndex);
992  if (Pfn1)
993  {
994  /* Either this is for kernel-mode, or the working set is held */
995  ASSERT((CurrentProcess == NULL) || (UsePfnLock == FALSE));
996 
997  /* No Physical VADs supported yet */
998  if (CurrentProcess) ASSERT(CurrentProcess->PhysicalVadRoot == NULL);
999 
1000  /* This address should already exist and be fully valid */
1002  }
1003  else
1004  {
1005  //
1006  // For I/O addresses, just remember this
1007  //
1008  Mdl->MdlFlags |= MDL_IO_SPACE;
1009  }
1010 
1011  //
1012  // Write the page and move on
1013  //
1014  *MdlPages++ = PageFrameIndex;
1015  PointerPte++;
1016 
1017  /* Check if we're on a PDE boundary */
1018  if (MiIsPteOnPdeBoundary(PointerPte)) PointerPde++;
1019 #if (_MI_PAGING_LEVELS >= 3)
1020  if (MiIsPteOnPpeBoundary(PointerPte)) PointerPpe++;
1021 #endif
1022 #if (_MI_PAGING_LEVELS == 4)
1023  if (MiIsPteOnPxeBoundary(PointerPte)) PointerPxe++;
1024 #endif
1025 
1026  } while (PointerPte <= LastPte);
1027 
1028  //
1029  // What kind of lock were we using?
1030  //
1031  if (UsePfnLock)
1032  {
1033  //
1034  // Release PFN lock
1035  //
1037  }
1038  else
1039  {
1040  /* Release process working set */
1041  MiUnlockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
1042  }
1043 
1044  //
1045  // Sanity check
1046  //
1047  ASSERT((Mdl->MdlFlags & MDL_DESCRIBES_AWE) == 0);
1048  return;
1049 
1050 CleanupWithLock:
1051  //
1052  // This is the failure path
1053  //
1054  ASSERT(!NT_SUCCESS(Status));
1055 
1056  //
1057  // What kind of lock were we using?
1058  //
1059  if (UsePfnLock)
1060  {
1061  //
1062  // Release PFN lock
1063  //
1065  }
1066  else
1067  {
1068  /* Release process working set */
1069  MiUnlockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
1070  }
1071 Cleanup:
1072  //
1073  // Pages must be locked so MmUnlock can work
1074  //
1075  ASSERT(Mdl->MdlFlags & MDL_PAGES_LOCKED);
1076  MmUnlockPages(Mdl);
1077 
1078  //
1079  // Raise the error
1080  //
1081  ExRaiseStatus(Status);
1082 }
1083 
1084 /*
1085  * @implemented
1086  */
1087 VOID
1088 NTAPI
1090 {
1091  PPFN_NUMBER MdlPages, LastPage;
1093  PVOID Base;
1094  ULONG Flags, PageCount;
1095  KIRQL OldIrql;
1096  PMMPFN Pfn1;
1097  DPRINT("Unlocking MDL: %p\n", Mdl);
1098 
1099  //
1100  // Sanity checks
1101  //
1102  ASSERT((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0);
1103  ASSERT((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0);
1104  ASSERT((Mdl->MdlFlags & MDL_PARTIAL) == 0);
1105  ASSERT(Mdl->ByteCount != 0);
1106 
1107  //
1108  // Get the process associated and capture the flags which are volatile
1109  //
1110  Process = Mdl->Process;
1111  Flags = Mdl->MdlFlags;
1112 
1113  //
1114  // Automagically undo any calls to MmGetSystemAddressForMdl's for this MDL
1115  //
1116  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
1117  {
1118  //
1119  // Unmap the pages from system space
1120  //
1121  MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
1122  }
1123 
1124  //
1125  // Get the page count
1126  //
1127  MdlPages = (PPFN_NUMBER)(Mdl + 1);
1128  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
1129  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
1130  ASSERT(PageCount != 0);
1131 
1132  //
1133  // We don't support AWE
1134  //
1135  if (Flags & MDL_DESCRIBES_AWE) ASSERT(FALSE);
1136 
1137  //
1138  // Check if the buffer is mapped I/O space
1139  //
1140  if (Flags & MDL_IO_SPACE)
1141  {
1142  //
1143  // Acquire PFN lock
1144  //
1146 
1147  //
1148  // Loop every page
1149  //
1150  LastPage = MdlPages + PageCount;
1151  do
1152  {
1153  //
1154  // Last page, break out
1155  //
1156  if (*MdlPages == LIST_HEAD) break;
1157 
1158  //
1159  // Check if this page is in the PFN database
1160  //
1161  Pfn1 = MiGetPfnEntry(*MdlPages);
1162  if (Pfn1) MiDereferencePfnAndDropLockCount(Pfn1);
1163  } while (++MdlPages < LastPage);
1164 
1165  //
1166  // Release the lock
1167  //
1169 
1170  //
1171  // Check if we have a process
1172  //
1173  if (Process)
1174  {
1175  //
1176  // Handle the accounting of locked pages
1177  //
1178  ASSERT(Process->NumberOfLockedPages > 0);
1180  -(LONG_PTR)PageCount);
1181  }
1182 
1183  //
1184  // We're done
1185  //
1186  Mdl->MdlFlags &= ~MDL_IO_SPACE;
1187  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1188  return;
1189  }
1190 
1191  //
1192  // Check if we have a process
1193  //
1194  if (Process)
1195  {
1196  //
1197  // Handle the accounting of locked pages
1198  //
1199  ASSERT(Process->NumberOfLockedPages > 0);
1201  -(LONG_PTR)PageCount);
1202  }
1203 
1204  //
1205  // Loop every page
1206  //
1207  LastPage = MdlPages + PageCount;
1208  do
1209  {
1210  //
1211  // Last page reached
1212  //
1213  if (*MdlPages == LIST_HEAD)
1214  {
1215  //
1216  // Were there no pages at all?
1217  //
1218  if (MdlPages == (PPFN_NUMBER)(Mdl + 1))
1219  {
1220  //
1221  // We're already done
1222  //
1223  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1224  return;
1225  }
1226 
1227  //
1228  // Otherwise, stop here
1229  //
1230  LastPage = MdlPages;
1231  break;
1232  }
1233 
1234  /* Save the PFN entry instead for the secondary loop */
1235  *MdlPages = (PFN_NUMBER)MiGetPfnEntry(*MdlPages);
1236  ASSERT(*MdlPages != 0);
1237  } while (++MdlPages < LastPage);
1238 
1239  //
1240  // Reset pointer
1241  //
1242  MdlPages = (PPFN_NUMBER)(Mdl + 1);
1243 
1244  //
1245  // Now grab the PFN lock for the actual unlock and dereference
1246  //
1248  do
1249  {
1250  /* Get the current entry and reference count */
1251  Pfn1 = (PMMPFN)*MdlPages;
1253  } while (++MdlPages < LastPage);
1254 
1255  //
1256  // Release the lock
1257  //
1259 
1260  //
1261  // We're done
1262  //
1263  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1264 }
1265 
1266 /*
1267  * @unimplemented
1268  */
1269 NTSTATUS
1270 NTAPI
1273 {
1274  UNIMPLEMENTED;
1275  return STATUS_NOT_IMPLEMENTED;
1276 }
1277 
1278 /*
1279  * @unimplemented
1280  */
1281 PVOID
1282 NTAPI
1284  IN ULONG PoolTag,
1287 {
1288  UNIMPLEMENTED;
1289  return 0;
1290 }
1291 
1292 /*
1293  * @unimplemented
1294  */
1295 VOID
1296 NTAPI
1298  IN ULONG PoolTag,
1300 {
1301  UNIMPLEMENTED;
1302 }
1303 
1304 /*
1305  * @unimplemented
1306  */
1307 NTSTATUS
1308 NTAPI
1309 MmPrefetchPages(IN ULONG NumberOfLists,
1310  IN PREAD_LIST *ReadLists)
1311 {
1312  UNIMPLEMENTED;
1313  return STATUS_NOT_IMPLEMENTED;
1314 }
1315 
1316 /*
1317  * @unimplemented
1318  */
1319 NTSTATUS
1320 NTAPI
1323 {
1324  UNIMPLEMENTED;
1325  return STATUS_NOT_IMPLEMENTED;
1326 }
1327 
1328 /*
1329  * @unimplemented
1330  */
1331 VOID
1332 NTAPI
1337 {
1338  UNIMPLEMENTED;
1339 }
1340 
1341 
1342 /*
1343  * @unimplemented
1344  */
1345 VOID
1346 NTAPI
1348  IN LARGE_INTEGER PageList[],
1351 {
1352  UNIMPLEMENTED;
1353 }
1354 
1355 /*
1356  * @unimplemented
1357  */
1358 VOID
1359 NTAPI
1361 {
1362  UNIMPLEMENTED;
1363 }
1364 
1365 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
BOOLEAN MmTrackPtes
Definition: mdlsup.c:20
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
#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 _MI_PAGING_LEVELS
Definition: mm.h:6
enum _MM_PAGE_PRIORITY MM_PAGE_PRIORITY
PVOID ULONG Address
Definition: oprghdlr.h:14
#define MI_PAGE_WRITE_COMBINED(x)
Definition: mm.h:93
#define MmGetMdlPfnArray(_Mdl)
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
FORCEINLINE VOID MiDereferencePfnAndDropLockCount(IN PMMPFN Pfn1)
Definition: miarm.h:1432
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
signed short * PSHORT
Definition: retypes.h:6
PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes]
Definition: syspte.c:23
ULONG PFN_COUNT
Definition: mmtypes.h:102
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
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
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:77
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
#define TRUE
Definition: numbers.c:17
#define ExRaiseStatus
Definition: ntoskrnl.h:94
FORCEINLINE VOID MiLockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1062
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1089
VOID NTAPI MmProbeAndLockSelectedPages(IN OUT PMDL MemoryDescriptorList, IN LARGE_INTEGER PageList[], IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:1347
PFN_NUMBER NumberOfLockedPages
Definition: pstypes.h:1178
#define MI_IS_PAGE_COPY_ON_WRITE(x)
Definition: mm.h:100
PMMPTE FORCEINLINE MiAddressToPpe(PVOID Address)
Definition: mm.h:138
VOID NTAPI MmMapMemoryDumpMdl(IN PMDL Mdl)
Definition: mdlsup.c:1360
union _MMPTE::@1890 u
PVOID PMDL
Definition: usb.h:39
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
PVOID NTAPI MmMapLockedPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode)
Definition: mdlsup.c:472
int WINAPI EndPage(_In_ HDC)
USHORT PageLocation
Definition: mm.h:297
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:163
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define MDL_IO_SPACE
Definition: mmtypes.h:29
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
ULONG * PPFN_NUMBER
Definition: ke.h:8
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:914
ULONG_PTR ShareCount
Definition: mm.h:322
_Inout_ PMDL MemoryDescriptorList
Definition: mmfuncs.h:406
long LONG
Definition: pedump.c:60
#define _SEH2_END
Definition: pseh2_64.h:7
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:491
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
VOID NTAPI MmFreePagesFromMdl(IN PMDL Mdl)
Definition: mdlsup.c:217
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_Must_inspect_result_ _In_ LPCGUID ULONG _In_ FSRTL_ALLOCATE_ECP_FLAGS _In_opt_ PFSRTL_EXTRA_CREATE_PARAMETER_CLEANUP_CALLBACK _In_ ULONG PoolTag
Definition: fltkernel.h:2520
#define MDL_MAPPING_CAN_FAIL
Definition: mmtypes.h:31
smooth NULL
Definition: ftsmooth.c:464
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
#define MDL_FREE_EXTRA_PTES
Definition: mmtypes.h:27
#define MDL_PARENT_MAPPED_SYSTEM_VA
Definition: mmtypes.h:26
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:275
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
UINTN Size
Definition: acefiex.h:550
PMMPTE MmSystemPtesStart[MaximumPtePoolTypes]
Definition: syspte.c:22
unsigned char BOOLEAN
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG CurrentProcess
Definition: shell.c:125
#define MDL_DESCRIBES_AWE
Definition: mmtypes.h:28
if(!(yy_init))
Definition: macro.lex.yy.c:704
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define TAG_MDL
Definition: tag.h:86
ULONG64 Valid
Definition: mmtypes.h:150
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:162
#define MM_USER_PROBE_ADDRESS
Definition: armddk.h:19
#define MiIsPteOnPpeBoundary(PointerPte)
Definition: mm.h:226
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define PAGE_ALIGN(Va)
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: init.c:31
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:92
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define MM_ALLOCATE_FROM_LOCAL_NODE_ONLY
Definition: mmtypes.h:12
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1222
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
MDL
Definition: mmtypes.h:117
NTSTATUS NTAPI MmAccessFault(IN BOOLEAN StoreInstruction, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: mmfault.c:204
VOID UINTN Length
Definition: acefiex.h:718
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define MM_NOIRQL
Definition: miarm.h:203
IN SIZE_T NumberOfBytes
Definition: ndis.h:3914
Definition: mm.h:305
#define MI_IS_PAGE_WRITEABLE(x)
Definition: mm.h:96
SIZE_T NTAPI MmSizeOfMdl(IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:62
PMMPTE FORCEINLINE MiAddressToPxe(PVOID Address)
Definition: mm.h:148
#define PAGE_SIZE
Definition: env_spec_w32.h:49
static const WCHAR Cleanup[]
Definition: register.c:65
LIST_HEAD(acpi_bus_event_list)
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:877
#define InterlockedDecrement16
Definition: interlocked.h:139
Status
Definition: gdiplustypes.h:24
#define MDL_PARTIAL_HAS_BEEN_MAPPED
Definition: mmtypes.h:23
PMM_AVL_TABLE PhysicalVadRoot
Definition: pstypes.h:1175
ULONG_PTR SIZE_T
Definition: typedefs.h:79
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
NTSTATUS NTAPI MmProtectMdlSystemAddress(IN PMDL MemoryDescriptorList, IN ULONG NewProtect)
Definition: mdlsup.c:1321
LONG NTSTATUS
Definition: DriverTester.h:11
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:224
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:585
enum _LOCK_OPERATION LOCK_OPERATION
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN MM_PAGE_PRIORITY Priority)
Definition: mdlsup.c:313
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
ULONG_PTR PteFrame
Definition: mm.h:350
struct _MMPFN::@1493::@1499 e2
PMDL NTAPI MmCreateMdl(IN PMDL Mdl, IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:31
struct _MMPFN * PMMPFN
PVOID NTAPI MmMapLockedPagesWithReservedMapping(IN PVOID MappingAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType)
Definition: mdlsup.c:1283
#define _SEH2_TRY
Definition: pseh2_64.h:5
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:683
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
NTSTATUS NTAPI MmAdvanceMdl(IN PMDL Mdl, IN ULONG NumberOfBytes)
Definition: mdlsup.c:1271
union _MMPFN::@1493 u3
#define MI_PAGE_DISABLE_CACHE(x)
Definition: mm.h:91
#define MM_DONT_ZERO_ALLOCATION
Definition: mmtypes.h:11
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
BOOLEAN MmTrackLockedPages
Definition: mdlsup.c:21
union _MMPFN::@1492 u2
#define OUT
Definition: typedefs.h:40
#define FALSE
Definition: numbers.c:16
#define MDL_PARTIAL
Definition: mmtypes.h:22
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
_In_ FLT_SET_CONTEXT_OPERATION Operation
Definition: fltkernel.h:1468
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
FORCEINLINE VOID MiReferenceProbedPageAndBumpLockCount(IN PMMPFN Pfn1)
Definition: miarm.h:1504
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID NTAPI MmUnmapReservedMapping(IN PVOID BaseAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList)
Definition: mdlsup.c:1297
union _MMPFN::@1496 u4
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:900
#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:142
#define PFN_FROM_PTE(v)
Definition: mm.h:82
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:150
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:90
NTSTATUS NTAPI MmPrefetchPages(IN ULONG NumberOfLists, IN PREAD_LIST *ReadLists)
Definition: mdlsup.c:1309
VOID NTAPI MmProbeAndLockProcessPages(IN OUT PMDL MemoryDescriptorList, IN PEPROCESS Process, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:1333
#define MiIsPteOnPxeBoundary(PointerPte)
Definition: mm.h:228
_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:1132