ReactOS 0.4.16-dev-2332-g4cba65d
section.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/section.c
5 * PURPOSE: ARM Memory Manager Section Support
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
21{
30};
31
33{
42};
43
45{
46 0,
62};
63
65{
66 0,
82};
83
85{
87
89
91
94
96
98
102
105};
106
112
113/* PRIVATE FUNCTIONS **********************************************************/
114
115static
118 IN ULONG NewSectionPageProtection)
119{
120 ULONG ProtectionMask, CompatibleMask;
121
122 /* Calculate the protection mask and make sure it's valid */
124 if (ProtectionMask == MM_INVALID_PROTECTION)
125 {
126 DPRINT1("Invalid protection mask\n");
127 return FALSE;
128 }
129
130 /* Calculate the compatible mask */
131 CompatibleMask = MmCompatibleProtectionMask[ProtectionMask & 0x7] |
133
134 /* See if the mapping protection is compatible with the create protection */
135 return ((CompatibleMask | NewSectionPageProtection) == CompatibleMask);
136}
137
138ULONG
139NTAPI
141{
142 ULONG Mask1, Mask2, ProtectMask;
143
144 /* PAGE_EXECUTE_WRITECOMBINE is theoretically the maximum */
146
147 /*
148 * Windows API protection mask can be understood as two bitfields, differing
149 * by whether or not execute rights are being requested
150 */
151 Mask1 = Protect & 0xF;
152 Mask2 = (Protect >> 4) & 0xF;
153
154 /* Check which field is there */
155 if (!Mask1)
156 {
157 /* Mask2 must be there, use it to determine the PTE protection */
158 if (!Mask2) return MM_INVALID_PROTECTION;
159 ProtectMask = MmUserProtectionToMask2[Mask2];
160 }
161 else
162 {
163 /* Mask2 should not be there, use Mask1 to determine the PTE mask */
164 if (Mask2) return MM_INVALID_PROTECTION;
165 ProtectMask = MmUserProtectionToMask1[Mask1];
166 }
167
168 /* Make sure the final mask is a valid one */
169 if (ProtectMask == MM_INVALID_PROTECTION) return MM_INVALID_PROTECTION;
170
171 /* Check for PAGE_GUARD option */
172 if (Protect & PAGE_GUARD)
173 {
174 /* It's not valid on no-access, nocache, or writecombine pages */
175 if ((ProtectMask == MM_NOACCESS) ||
177 {
178 /* Fail such requests */
180 }
181
182 /* This actually turns on guard page in this scenario! */
183 ProtectMask |= MM_GUARDPAGE;
184 }
185
186 /* Check for nocache option */
187 if (Protect & PAGE_NOCACHE)
188 {
189 /* The earlier check should've eliminated this possibility */
190 ASSERT((Protect & PAGE_GUARD) == 0);
191
192 /* Check for no-access page or write combine page */
193 if ((ProtectMask == MM_NOACCESS) || (Protect & PAGE_WRITECOMBINE))
194 {
195 /* Such a request is invalid */
197 }
198
199 /* Add the PTE flag */
200 ProtectMask |= MM_NOCACHE;
201 }
202
203 /* Check for write combine option */
205 {
206 /* The two earlier scenarios should've caught this */
208
209 /* Don't allow on no-access pages */
210 if (ProtectMask == MM_NOACCESS) return MM_INVALID_PROTECTION;
211
212 /* This actually turns on write-combine in this scenario! */
213 ProtectMask |= MM_NOACCESS;
214 }
215
216 /* Return the final MM PTE protection mask */
217 return ProtectMask;
218}
219
221NTAPI
223{
224 SIZE_T AllocSize, BitmapSize, Size;
225 PVOID ViewStart;
226 PMMSESSION Session;
227
228 /* Check if this a session or system space */
229 if (InputSession)
230 {
231 /* Use the input session */
232 Session = InputSession;
233 ViewStart = MiSessionViewStart;
235 }
236 else
237 {
238 /* Use the system space "session" */
239 Session = &MmSession;
240 ViewStart = MiSystemViewStart;
242 }
243
244 /* Initialize the system space lock */
247
248 /* Set the start address */
249 Session->SystemSpaceViewStart = ViewStart;
250
251 /* Create a bitmap to describe system space */
252 BitmapSize = sizeof(RTL_BITMAP) + ((((Size / MI_SYSTEM_VIEW_BUCKET_SIZE) + 31) / 32) * sizeof(ULONG));
254 BitmapSize,
255 TAG_MM);
256 ASSERT(Session->SystemSpaceBitMap);
258 (PULONG)(Session->SystemSpaceBitMap + 1),
260
261 /* Set system space fully empty to begin with */
263
264 /* Set default hash flags */
265 Session->SystemSpaceHashSize = 31;
266 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
267 Session->SystemSpaceHashEntries = 0;
268
269 /* Calculate how much space for the hash views we'll need */
270 AllocSize = sizeof(MMVIEW) * Session->SystemSpaceHashSize;
271 ASSERT(AllocSize < PAGE_SIZE);
272
273 /* Allocate and zero the view table */
276 PagedPool,
277 AllocSize,
278 TAG_MM);
279 ASSERT(Session->SystemSpaceViewTable != NULL);
280 RtlZeroMemory(Session->SystemSpaceViewTable, AllocSize);
281
282 /* Success */
283 return TRUE;
284}
285
286static
287PVOID
289 IN ULONG Buckets,
290 IN PCONTROL_AREA ControlArea)
291{
292 PVOID Base;
293 ULONG Hash, i, HashSize;
295 PMMVIEW OldTable;
296 PAGED_CODE();
297
298 /* Stay within 4GB */
300
301 /* Lock system space */
302 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
303
304 /* Check if we're going to exhaust hash entries */
305 if ((Session->SystemSpaceHashEntries + 8) > Session->SystemSpaceHashSize)
306 {
307 /* Double the hash size */
308 HashSize = Session->SystemSpaceHashSize * 2;
309
310 /* Save the old table and allocate a new one */
311 OldTable = Session->SystemSpaceViewTable;
312 Session->SystemSpaceViewTable = ExAllocatePoolWithTag(Session ==
313 &MmSession ?
315 PagedPool,
316 HashSize *
317 sizeof(MMVIEW),
318 TAG_MM);
319 if (!Session->SystemSpaceViewTable)
320 {
321 /* Failed to allocate a new table, keep the old one for now */
322 Session->SystemSpaceViewTable = OldTable;
323 }
324 else
325 {
326 /* Clear the new table and set the new ahsh and key */
327 RtlZeroMemory(Session->SystemSpaceViewTable, HashSize * sizeof(MMVIEW));
328 Session->SystemSpaceHashSize = HashSize;
329 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
330
331 /* Loop the old table */
332 for (i = 0; i < Session->SystemSpaceHashSize / 2; i++)
333 {
334 /* Check if the entry was valid */
335 if (OldTable[i].Entry)
336 {
337 /* Re-hash the old entry and search for space in the new table */
338 Hash = (OldTable[i].Entry >> 16) % Session->SystemSpaceHashKey;
339 while (Session->SystemSpaceViewTable[Hash].Entry)
340 {
341 /* Loop back at the beginning if we had an overflow */
342 if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
343 }
344
345 /* Write the old entry in the new table */
346 Session->SystemSpaceViewTable[Hash] = OldTable[i];
347 }
348 }
349
350 /* Free the old table */
351 ExFreePool(OldTable);
352 }
353 }
354
355 /* Check if we ran out */
356 if (Session->SystemSpaceHashEntries == Session->SystemSpaceHashSize)
357 {
358 DPRINT1("Ran out of system view hash entries\n");
359 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
360 return NULL;
361 }
362
363 /* Find space where to map this view */
364 i = RtlFindClearBitsAndSet(Session->SystemSpaceBitMap, Buckets, 0);
365 if (i == 0xFFFFFFFF)
366 {
367 /* Out of space, fail */
368 Session->BitmapFailures++;
369 DPRINT1("Out of system view space\n");
370 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
371 return NULL;
372 }
373
374 /* Compute the base address */
375 Base = (PVOID)((ULONG_PTR)Session->SystemSpaceViewStart + (i * MI_SYSTEM_VIEW_BUCKET_SIZE));
377
378 /* Get the hash entry for this allocation */
379 Entry = (ULONG_PTR)Base + Buckets;
380 Hash = (Entry >> 16) % Session->SystemSpaceHashKey;
381
382 /* Loop hash entries until a free one is found */
383 while (Session->SystemSpaceViewTable[Hash].Entry)
384 {
385 /* Unless we overflow, in which case loop back at hash o */
386 if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
387 }
388
389 /* Add this entry into the hash table */
390 Session->SystemSpaceViewTable[Hash].Entry = Entry;
391 Session->SystemSpaceViewTable[Hash].ControlArea = ControlArea;
392
393 /* Hash entry found, increment total and return the base address */
394 Session->SystemSpaceHashEntries++;
395 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
396 return Base;
397}
398
399static
402 IN PFN_NUMBER PteCount,
403 IN PCONTROL_AREA ControlArea,
405{
407 PMMPTE PointerPte, ProtoPte, LastProtoPte, LastPte;
408 PSUBSECTION Subsection;
409
410 /* Mapping at offset not supported yet */
411 ASSERT(SectionOffset == 0);
412
413 /* ARM3 doesn't support this yet */
414 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
415 ASSERT(ControlArea->u.Flags.Rom == 0);
416 ASSERT(ControlArea->FilePointer == NULL);
417
418 /* Sanity checks */
419 ASSERT(PteCount != 0);
420 ASSERT(ControlArea->NumberOfMappedViews >= 1);
421 ASSERT(ControlArea->NumberOfUserReferences >= 1);
422 ASSERT(ControlArea->NumberOfSectionReferences != 0);
423 ASSERT(ControlArea->u.Flags.BeingCreated == 0);
424 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
425 ASSERT(ControlArea->u.Flags.BeingPurged == 0);
426
427 /* Get the PTEs for the actual mapping */
428 PointerPte = FirstPte;
429 LastPte = FirstPte + PteCount;
430
431 /* Get the prototype PTEs that desribe the section mapping in the subsection */
432 Subsection = (PSUBSECTION)(ControlArea + 1);
433 ProtoPte = Subsection->SubsectionBase;
434 LastProtoPte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
435
436 /* Loop the PTEs for the mapping */
437 while (PointerPte < LastPte)
438 {
439 /* We may have run out of prototype PTEs in this subsection */
440 if (ProtoPte >= LastProtoPte)
441 {
442 /* But we don't handle this yet */
443 ASSERT(FALSE);
444 }
445
446 /* The PTE should be completely clear */
447 ASSERT(PointerPte->u.Long == 0);
448
449 /* Build the prototype PTE and write it */
450 MI_MAKE_PROTOTYPE_PTE(&TempPte, ProtoPte);
451 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
452
453 /* Keep going */
454 PointerPte++;
455 ProtoPte++;
456 }
457
458 /* No failure path */
459 return STATUS_SUCCESS;
460}
461
462VOID
463NTAPI
466{
467 PMMPDE PointerPde, LastPde, SystemMapPde;
469 PFN_NUMBER PageFrameIndex, ParentPage;
471 PAGED_CODE();
472
473 /* Find the PDEs needed for this mapping */
474 PointerPde = MiAddressToPde(Base);
475 LastPde = MiAddressToPde((PVOID)((ULONG_PTR)Base + NumberOfBytes - 1));
476
477#if (_MI_PAGING_LEVELS == 2)
478 /* Find the system double-mapped PDE that describes this mapping */
479 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
480#else
481 /* We don't have a double mapping */
482 SystemMapPde = PointerPde;
483#endif
484
485 /* Use the PDE template and loop the PDEs */
487 while (PointerPde <= LastPde)
488 {
489 /* Lock the PFN database */
490 OldIrql = MiAcquirePfnLock();
491
492 /* Check if we don't already have this PDE mapped */
493 if (SystemMapPde->u.Hard.Valid == 0)
494 {
495 /* Grab a page for it */
497 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
498 PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
499 ASSERT(PageFrameIndex);
500 TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
501
502#if (_MI_PAGING_LEVELS == 2)
503 ParentPage = MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_PER_PAGE];
504#else
505 ParentPage = MiPdeToPpe(PointerPde)->u.Hard.PageFrameNumber;
506#endif
507 /* Initialize its PFN entry, with the parent system page directory page table */
508 MiInitializePfnForOtherProcess(PageFrameIndex,
509 (PMMPTE)PointerPde,
510 ParentPage);
511
512 /* Make the system PDE entry valid */
513 MI_WRITE_VALID_PDE(SystemMapPde, TempPde);
514
515 /* The system PDE entry might be the PDE itself, so check for this */
516 if (PointerPde->u.Hard.Valid == 0)
517 {
518 /* It's different, so make the real PDE valid too */
519 MI_WRITE_VALID_PDE(PointerPde, TempPde);
520 }
521 }
522
523 /* Release the lock and keep going with the next PDE */
524 MiReleasePfnLock(OldIrql);
525 SystemMapPde++;
526 PointerPde++;
527 }
528}
529
530static
533 IN BOOLEAN FailIfSystemViews)
534{
536
537 /* Flag not yet supported */
538 ASSERT(FailIfSystemViews == FALSE);
539
540 /* Lock the PFN database */
541 OldIrql = MiAcquirePfnLock();
542
543 /* State not yet supported */
544 ASSERT(ControlArea->u.Flags.BeingPurged == 0);
545
546 /* Increase the reference counts */
547 ControlArea->NumberOfMappedViews++;
548 ControlArea->NumberOfUserReferences++;
549 ASSERT(ControlArea->NumberOfSectionReferences != 0);
550
551 /* Release the PFN lock and return success */
552 MiReleasePfnLock(OldIrql);
553 return STATUS_SUCCESS;
554}
555
557NTAPI
559 IN ULONG_PTR Vpn)
560{
561 PSUBSECTION Subsection;
562 PCONTROL_AREA ControlArea;
563 ULONG_PTR PteOffset;
564
565 /* Get the control area */
566 ControlArea = Vad->ControlArea;
567 ASSERT(ControlArea->u.Flags.Rom == 0);
568 ASSERT(ControlArea->u.Flags.Image == 0);
569 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
570
571 /* Get the subsection */
572 Subsection = (PSUBSECTION)(ControlArea + 1);
573
574 /* We only support single-subsection segments */
575 ASSERT(Subsection->SubsectionBase != NULL);
576 ASSERT(Vad->FirstPrototypePte >= Subsection->SubsectionBase);
577 ASSERT(Vad->FirstPrototypePte < &Subsection->SubsectionBase[Subsection->PtesInSubsection]);
578
579 /* Compute the PTE offset */
580 PteOffset = Vpn - Vad->StartingVpn;
581 PteOffset += Vad->FirstPrototypePte - Subsection->SubsectionBase;
582
583 /* Again, we only support single-subsection segments */
584 ASSERT(PteOffset < 0xF0000000);
585 ASSERT(PteOffset < Subsection->PtesInSubsection);
586
587 /* Return the subsection */
588 return Subsection;
589}
590
591static
592VOID
594{
595 PCONTROL_AREA ControlArea;
596 SEGMENT_FLAGS SegmentFlags;
597 PSUBSECTION Subsection;
598 PMMPTE PointerPte, LastPte, PteForProto;
599 PMMPFN Pfn1;
600 PFN_NUMBER PageFrameIndex;
603
604 /* Capture data */
605 SegmentFlags = Segment->SegmentFlags;
606 ControlArea = Segment->ControlArea;
607
608 /* Make sure control area is on the right delete path */
609 ASSERT(ControlArea->u.Flags.BeingDeleted == 1);
610 ASSERT(ControlArea->WritableUserReferences == 0);
611
612 /* These things are not supported yet */
613 ASSERT(ControlArea->DereferenceList.Flink == NULL);
614 ASSERT(!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File));
615 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
616 ASSERT(ControlArea->u.Flags.Rom == 0);
617
618 /* Get the subsection and PTEs for this segment */
619 Subsection = (PSUBSECTION)(ControlArea + 1);
620 PointerPte = Subsection->SubsectionBase;
621 LastPte = PointerPte + Segment->NonExtendedPtes;
622
623 /* Lock the PFN database */
624 OldIrql = MiAcquirePfnLock();
625
626 /* Check if the master PTE is invalid */
627 PteForProto = MiAddressToPte(PointerPte);
628 if (!PteForProto->u.Hard.Valid)
629 {
630 /* Fault it in */
632 }
633
634 /* Loop all the segment PTEs */
635 while (PointerPte < LastPte)
636 {
637 /* Check if it's time to switch master PTEs if we passed a PDE boundary */
638 if (MiIsPteOnPdeBoundary(PointerPte) &&
639 (PointerPte != Subsection->SubsectionBase))
640 {
641 /* Check if the master PTE is invalid */
642 PteForProto = MiAddressToPte(PointerPte);
643 if (!PteForProto->u.Hard.Valid)
644 {
645 /* Fault it in */
647 }
648 }
649
650 /* This should be a prototype PTE */
651 TempPte = *PointerPte;
652 ASSERT(SegmentFlags.LargePages == 0);
653 ASSERT(TempPte.u.Hard.Valid == 0);
654
655 /* See if we should clean things up */
656 if (!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File))
657 {
658 /*
659 * This is a section backed by the pagefile. Now that it doesn't exist anymore,
660 * we can give everything back to the system.
661 */
662 ASSERT(TempPte.u.Soft.Prototype == 0);
663
664 if (TempPte.u.Soft.Transition == 1)
665 {
666 /* We can give the page back for other use */
667 DPRINT("Releasing page for transition PTE %p\n", PointerPte);
668 PageFrameIndex = PFN_FROM_PTE(&TempPte);
669 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
670
671 /* As this is a paged-backed section, nobody should reference it anymore (no cache or whatever) */
672 ASSERT(Pfn1->u3.ReferenceCount == 0);
673
674 /* And it should be in standby or modified list */
676
677 /* Unlink it and put it back in free list */
679
680 /* Temporarily mark this as active and make it free again */
682 MI_SET_PFN_DELETED(Pfn1);
683
684 MiInsertPageInFreeList(PageFrameIndex);
685 }
686 else if (TempPte.u.Soft.PageFileHigh != 0)
687 {
688 /* Should not happen for now */
689 ASSERT(FALSE);
690 }
691 }
692 else
693 {
694 /* unsupported for now */
695 ASSERT(FALSE);
696
697 /* File-backed section must have prototype PTEs */
698 ASSERT(TempPte.u.Soft.Prototype == 1);
699 }
700
701 /* Zero the PTE and keep going */
702 PointerPte->u.Long = 0;
703 PointerPte++;
704 }
705
706 /* Release the PFN lock */
707 MiReleasePfnLock(OldIrql);
708
709 /* Free the structures */
710 ExFreePool(ControlArea);
712}
713
714static
715VOID
718{
719 BOOLEAN DeleteSegment = FALSE;
721
722 /* Check if this is the last reference or view */
723 if (!(ControlArea->NumberOfMappedViews) &&
724 !(ControlArea->NumberOfSectionReferences))
725 {
726 /* There should be no more user references either */
727 ASSERT(ControlArea->NumberOfUserReferences == 0);
728
729 /* Not yet supported */
730 ASSERT(ControlArea->FilePointer == NULL);
731
732 /* The control area is being destroyed */
733 ControlArea->u.Flags.BeingDeleted = TRUE;
734 DeleteSegment = TRUE;
735 }
736
737 /* Release the PFN lock */
738 MiReleasePfnLock(OldIrql);
739
740 /* Delete the segment if needed */
741 if (DeleteSegment)
742 {
743 /* No more user write references at all */
744 ASSERT(ControlArea->WritableUserReferences == 0);
745 MiSegmentDelete(ControlArea->Segment);
746 }
747}
748
749static
750VOID
752{
754
755 /* Lock the PFN database */
756 OldIrql = MiAcquirePfnLock();
757
758 /* Drop reference counts */
759 ControlArea->NumberOfMappedViews--;
760 ControlArea->NumberOfUserReferences--;
761
762 /* Check if it's time to delete the CA. This releases the lock */
763 MiCheckControlArea(ControlArea, OldIrql);
764}
765
766VOID
767NTAPI
769 IN PMMVAD Vad)
770{
772 PCONTROL_AREA ControlArea;
773 PETHREAD CurrentThread = PsGetCurrentThread();
774
775 /* Get the control area */
776 ControlArea = Vad->ControlArea;
777
778 /* We only support non-extendable, non-image, pagefile-backed regular sections */
779 ASSERT(Vad->u.VadFlags.VadType == VadNone);
780 ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
781 ASSERT(ControlArea);
782 ASSERT(ControlArea->FilePointer == NULL);
784
785 /* Delete the actual virtual memory pages */
786 MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
787 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
788 Vad);
789
790 /* Release the working set */
791 MiUnlockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
792
793 /* Lock the PFN database */
794 OldIrql = MiAcquirePfnLock();
795
796 /* Remove references */
797 ControlArea->NumberOfMappedViews--;
798 ControlArea->NumberOfUserReferences--;
799
800 /* Check if it should be destroyed */
801 MiCheckControlArea(ControlArea, OldIrql);
802}
803
804static
808 IN ULONG Flags)
809{
812 PMMVAD Vad;
813 PVOID DbgBase = NULL;
816 PETHREAD CurrentThread = PsGetCurrentThread();
817 PEPROCESS CurrentProcess = PsGetCurrentProcess();
818 PAGED_CODE();
819
820 /* Check if we need to lock the address space */
821 if (!Flags) MmLockAddressSpace(&Process->Vm);
822
823 /* Find the VAD for the address and make sure it's a section VAD */
824 Vad = MiLocateVad(&Process->VadRoot, BaseAddress);
825 if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
826 {
827 /* Couldn't find it, or invalid VAD, fail */
828 DPRINT1("No VAD or invalid VAD\n");
831 }
832
833 /* Check for RosMm memory area */
834 if (MI_IS_MEMORY_AREA_VAD(Vad))
835 {
836 /* Call Mm API */
840 return Status;
841 }
842
843 /* Check if we should attach to the process */
844 if (CurrentProcess != Process)
845 {
846 /* The process is different, do an attach */
848 Attached = TRUE;
849 }
850
851 /* Check if the process is already dead */
852 if (Process->VmDeleted)
853 {
854 /* Fail the call */
855 DPRINT1("Process died!\n");
858 goto Quickie;
859 }
860
861 /* We should be attached */
863
864 /* We need the base address for the debugger message on image-backed VADs */
865 if (Vad->u.VadFlags.VadType == VadImageMap)
866 {
867 DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
868 }
869
870 /* Compute the size of the VAD region */
871 RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
872
873 /* For SEC_NO_CHANGE sections, we need some extra checks */
874 if (Vad->u.VadFlags.NoChange == 1)
875 {
876 /* Are we allowed to mess with this VAD? */
878 (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
881 if (!NT_SUCCESS(Status))
882 {
883 /* We failed */
884 DPRINT1("Trying to unmap protected VAD!\n");
886 goto Quickie;
887 }
888 }
889
890 /* Not currently supported */
892
893 /* FIXME: Remove VAD charges */
894
895 /* Lock the working set */
897
898 /* Remove the VAD */
899 ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
900 MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
902
903 /* Remove the PTEs for this view, which also releases the working set lock */
905
906 /* FIXME: Remove commitment */
907
908 /* Update performance counter and release the lock */
909 Process->VirtualSize -= RegionSize;
911
912 /* Destroy the VAD and return success */
913 ExFreePool(Vad);
915
916 /* Failure and success case -- send debugger message, detach, and return */
917Quickie:
918 if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
920 return Status;
921}
922
923static
926 IN PVOID EndVa)
927{
930 PMMPDE StartPde, EndPde;
932 PMMPFN Pfn1;
933 PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
934
935 /* Windows sanity checks */
936 ASSERT(StartVa >= (PVOID)MmSessionBase);
938 ASSERT(PAGE_ALIGN(EndVa) == EndVa);
939
940 /* Get the start and end PDE, then loop each one */
941 StartPde = MiAddressToPde(StartVa);
942 EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
943 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
944 while (StartPde <= EndPde)
945 {
946#ifndef _M_AMD64
947 /* If we don't already have a page table for it, increment count */
948 if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
949#endif
950 /* Move to the next one */
951 StartPde++;
952 Index++;
953 }
954
955 /* If there's no page tables to create, bail out */
956 if (PageCount == 0) return STATUS_SUCCESS;
957
958 /* Reset the start PDE and index */
959 StartPde = MiAddressToPde(StartVa);
960 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
961
962 /* Loop each PDE while holding the working set lock */
963// MiLockWorkingSet(PsGetCurrentThread(),
964// &MmSessionSpace->GlobalVirtualAddress->Vm);
965#ifdef _M_AMD64
966_WARN("MiSessionCommitPageTables halfplemented for amd64")
971 DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
972 ASSERT(FALSE);
973#else
974 while (StartPde <= EndPde)
975 {
976 /* Check if we already have a page table */
978 {
979 /* We don't, so the PDE shouldn't be ready yet */
980 ASSERT(StartPde->u.Hard.Valid == 0);
981
982 /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
984
985 /* Acquire the PFN lock and grab a zero page */
986 OldIrql = MiAcquirePfnLock();
988 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
990 PageFrameNumber = MiRemoveZeroPage(Color);
991 TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
992 MI_WRITE_VALID_PDE(StartPde, TempPde);
993
994 /* Write the page table in session space structure */
997
998 /* Initialize the PFN */
999 MiInitializePfnForOtherProcess(PageFrameNumber,
1000 StartPde,
1002
1003 /* And now release the lock */
1004 MiReleasePfnLock(OldIrql);
1005
1006 /* Get the PFN entry and make sure there's no event for it */
1007 Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1008 ASSERT(Pfn1->u1.Event == NULL);
1009
1010 /* Increment the number of pages */
1011 ActualPages++;
1012 }
1013
1014 /* Move to the next PDE */
1015 StartPde++;
1016 Index++;
1017 }
1018#endif
1019
1020 /* Make sure we didn't do more pages than expected */
1021 ASSERT(ActualPages <= PageCount);
1022
1023 /* Release the working set lock */
1024// MiUnlockWorkingSet(PsGetCurrentThread(),
1025// &MmSessionSpace->GlobalVirtualAddress->Vm);
1026
1027
1028 /* If we did at least one page... */
1029 if (ActualPages)
1030 {
1031 /* Update the performance counters! */
1034 }
1035
1036 /* Return status */
1037 return STATUS_SUCCESS;
1038}
1039
1042 _In_ PVOID Section,
1043 _In_ PMMSESSION Session,
1047{
1048 PVOID Base;
1049 PCONTROL_AREA ControlArea;
1050 ULONG Buckets;
1051 LONGLONG SectionSize;
1053 PAGED_CODE();
1054
1055 /* Get the control area, check for any flags ARM3 doesn't yet support */
1056 ControlArea = ((PSECTION)Section)->Segment->ControlArea;
1057 ASSERT(ControlArea->u.Flags.Image == 0);
1058 ASSERT(ControlArea->FilePointer == NULL);
1059 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1060 ASSERT(ControlArea->u.Flags.Rom == 0);
1061 ASSERT(ControlArea->u.Flags.WasPurged == 0);
1062
1063 /* Increase the reference and map count on the control area, no purges yet */
1064 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1066
1067 /* Get the section size at creation time */
1068 SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart;
1069
1070 /* If the caller didn't specify a view size, assume until the end of the section */
1071 if (!(*ViewSize))
1072 {
1073 /* Check for overflow first */
1074 if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX)
1075 {
1076 DPRINT1("Section end is too far away from the specified offset.\n");
1077 MiDereferenceControlArea(ControlArea);
1079 }
1080 *ViewSize = SectionSize - SectionOffset->QuadPart;
1081 }
1082
1083 /* Check overflow */
1084 if ((SectionOffset->QuadPart + *ViewSize) < SectionOffset->QuadPart)
1085 {
1086 DPRINT1("Integer overflow between size & offset!\n");
1087 MiDereferenceControlArea(ControlArea);
1089 }
1090
1091 /* Check if the caller wanted a larger section than the view */
1092 if (SectionOffset->QuadPart + *ViewSize > SectionSize)
1093 {
1094 /* Fail */
1095 DPRINT1("View is too large\n");
1096 MiDereferenceControlArea(ControlArea);
1098 }
1099
1100 /* Get the number of 64K buckets required for this mapping */
1102 if (*ViewSize & (MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) Buckets++;
1103
1104 /* Check if the view is more than 4GB large */
1105 if (Buckets >= MI_SYSTEM_VIEW_BUCKET_SIZE)
1106 {
1107 /* Fail */
1108 DPRINT1("View is too large\n");
1109 MiDereferenceControlArea(ControlArea);
1111 }
1112
1113 /* Insert this view into system space and get a base address for it */
1114 Base = MiInsertInSystemSpace(Session, Buckets, ControlArea);
1115 if (!Base)
1116 {
1117 /* Fail */
1118 DPRINT1("Out of system space\n");
1119 MiDereferenceControlArea(ControlArea);
1120 return STATUS_NO_MEMORY;
1121 }
1122
1123 /* What's the underlying session? */
1124 if (Session == &MmSession)
1125 {
1126 /* Create the PDEs needed for this mapping, and double-map them if needed */
1129 }
1130 else
1131 {
1132 /* Create the PDEs needed for this mapping */
1134 (PVOID)((ULONG_PTR)Base +
1135 Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
1137 }
1138
1139 /* Create the actual prototype PTEs for this mapping */
1142 ControlArea,
1143 SectionOffset->QuadPart);
1145
1146 /* Return the base address of the mapping and success */
1147 *MappedBase = Base;
1148 return STATUS_SUCCESS;
1149}
1150
1151static
1158 IN PSECTION Section,
1160 IN ULONG ProtectionMask,
1164{
1165 PMMVAD_LONG Vad;
1166 ULONG_PTR StartAddress;
1167 ULONG_PTR ViewSizeInPages;
1168 PSUBSECTION Subsection;
1170 PFN_NUMBER PteOffset;
1172 ULONG QuotaCharge = 0, QuotaExcess = 0;
1173 PMMPTE PointerPte, LastPte;
1174 MMPTE TempPte;
1175 ULONG Granularity = MM_VIRTMEM_GRANULARITY;
1176
1177 DPRINT("Mapping ARM3 data section\n");
1178
1179 /* Get the segment for this section */
1180 Segment = ControlArea->Segment;
1181
1182#ifdef _M_IX86
1183 /* ALlow being less restrictive on x86. */
1185 Granularity = PAGE_SIZE;
1186#endif
1187
1188 /* One can only reserve a file-based mapping, not shared memory! */
1189 if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1190 {
1192 }
1193
1194 /* First, increase the map count. No purging is supported yet */
1195 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1196 if (!NT_SUCCESS(Status)) return Status;
1197
1198 /* Check if the caller specified the view size */
1199 if (!(*ViewSize))
1200 {
1201 LONGLONG ViewSizeLL;
1202
1203 /* The caller did not, so pick a 64K aligned view size based on the offset */
1204 SectionOffset->LowPart &= ~(_64K - 1);
1205
1206 /* Calculate size and make sure this fits */
1207 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &ViewSizeLL))
1208 || !NT_SUCCESS(RtlLongLongToSIZET(ViewSizeLL, ViewSize))
1209 || (*ViewSize > MAXLONG_PTR))
1210 {
1211 MiDereferenceControlArea(ControlArea);
1213 }
1214 }
1215 else
1216 {
1217 /* A size was specified, align it to a 64K boundary
1218 * and check for overflow or huge value. */
1219 if (!NT_SUCCESS(RtlSIZETAdd(*ViewSize, SectionOffset->LowPart & (_64K - 1), ViewSize))
1220 || (*ViewSize > MAXLONG_PTR))
1221 {
1222 MiDereferenceControlArea(ControlArea);
1224 }
1225
1226 /* Align the offset as well to make this an aligned map */
1227 SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1228 }
1229
1230 /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1231 ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1232
1233 /* Windows ASSERTs for this flag */
1234 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1235
1236 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1237 ASSERT(ControlArea->u.Flags.Rom == 0);
1238 Subsection = (PSUBSECTION)(ControlArea + 1);
1239
1240 /* Sections with extended segments are not supported in ARM3 */
1241 ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1242
1243 /* Within this section, figure out which PTEs will describe the view */
1244 PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1245
1246 /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1247 ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1248 ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1249
1250 /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1251 ASSERT(PteOffset < Subsection->PtesInSubsection);
1252
1253 /* In ARM3, only page-file backed sections (shared memory) are supported now */
1254 ASSERT(ControlArea->FilePointer == NULL);
1255
1256 /* Windows ASSERTs for this too -- there must be a subsection base address */
1257 ASSERT(Subsection->SubsectionBase != NULL);
1258
1259 /* Compute how much commit space the segment will take */
1260 if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1261 {
1262 /* Charge for the maximum pages */
1263 QuotaCharge = BYTES_TO_PAGES(CommitSize);
1264 }
1265
1266 /* ARM3 does not currently support large pages */
1267 ASSERT(Segment->SegmentFlags.LargePages == 0);
1268
1269 /* Calculate how many pages the region spans */
1270 ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1271
1272 /* A VAD can now be allocated. Do so and zero it out */
1273 /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1274 ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1275 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1276 if (!Vad)
1277 {
1278 MiDereferenceControlArea(ControlArea);
1280 }
1281
1282 RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1283 Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1284
1285 /* Write all the data required in the VAD for handling a fault */
1286 Vad->ControlArea = ControlArea;
1287 Vad->u.VadFlags.CommitCharge = 0;
1288 Vad->u.VadFlags.Protection = ProtectionMask;
1289 Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1291 if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1292 {
1293 /* This isn't really implemented yet, but handle setting the flag */
1294 Vad->u.VadFlags.NoChange = 1;
1295 Vad->u2.VadFlags2.SecNoChange = 1;
1296 }
1297
1298 /* Finally, write down the first and last prototype PTE */
1299 Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1300 PteOffset += ViewSizeInPages - 1;
1301 ASSERT(PteOffset < Subsection->PtesInSubsection);
1302 Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1303
1304 /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1306
1307 /* FIXME: Should setup VAD bitmap */
1309
1310 /* Check if anything was committed */
1311 if (QuotaCharge)
1312 {
1313 /* Set the start and end PTE addresses, and pick the template PTE */
1314 PointerPte = Vad->FirstPrototypePte;
1315 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1316 TempPte = Segment->SegmentPteTemplate;
1317
1318 /* Acquire the commit lock and loop all prototype PTEs to be committed */
1320 while (PointerPte < LastPte)
1321 {
1322 /* Make sure the PTE is already invalid */
1323 if (PointerPte->u.Long == 0)
1324 {
1325 /* And write the invalid PTE */
1326 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1327 }
1328 else
1329 {
1330 /* The PTE is valid, so skip it */
1331 QuotaExcess++;
1332 }
1333
1334 /* Move to the next PTE */
1335 PointerPte++;
1336 }
1337
1338 /* Now check how many pages exactly we committed, and update accounting */
1339 ASSERT(QuotaCharge >= QuotaExcess);
1340 QuotaCharge -= QuotaExcess;
1341 Segment->NumberOfCommittedPages += QuotaCharge;
1342 ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1343
1344 /* Now that we're done, release the lock */
1346 }
1347
1348 /* Is it SEC_BASED, or did the caller manually specify an address? */
1349 if (*BaseAddress != NULL)
1350 {
1351 /* Just align what the caller gave us */
1352 StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1353 }
1354 else if (Section->Address.StartingVpn != 0)
1355 {
1356 /* It is a SEC_BASED mapping, use the address that was generated */
1357 StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1358 }
1359 else
1360 {
1361 StartAddress = 0;
1362 }
1363
1365 if (!NT_SUCCESS(Status))
1366 {
1367 ExFreePoolWithTag(Vad, 'ldaV');
1368 MiDereferenceControlArea(ControlArea);
1369
1371 Segment->NumberOfCommittedPages -= QuotaCharge;
1373 return Status;
1374 }
1375
1376 /* Insert the VAD */
1378 &StartAddress,
1379 ViewSizeInPages * PAGE_SIZE,
1381 Granularity,
1383 if (!NT_SUCCESS(Status))
1384 {
1385 ExFreePoolWithTag(Vad, 'ldaV');
1386 MiDereferenceControlArea(ControlArea);
1387
1389 Segment->NumberOfCommittedPages -= QuotaCharge;
1391
1393 return Status;
1394 }
1395
1396 /* Windows stores this for accounting purposes, do so as well */
1397 if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1398
1399 /* Finally, let the caller know where, and for what size, the view was mapped */
1400 *ViewSize = ViewSizeInPages * PAGE_SIZE;
1401 *BaseAddress = (PVOID)StartAddress;
1402 DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1403 return STATUS_SUCCESS;
1404}
1405
1406static
1413 IN ULONG IgnoreFileSizing)
1414{
1415 /* Not yet implemented */
1416 ASSERT(FALSE);
1417 *Segment = NULL;
1419}
1420
1421static
1425 IN ULONG ProtectionMask,
1427{
1428 ULONGLONG SizeLimit;
1429 PFN_COUNT PteCount;
1430 PMMPTE PointerPte;
1431 MMPTE TempPte;
1432 PCONTROL_AREA ControlArea;
1433 PSEGMENT NewSegment;
1434 PSUBSECTION Subsection;
1435 PAGED_CODE();
1436
1437 /* No large pages in ARM3 yet */
1439
1440 /* Pagefile-backed sections need a known size */
1441 if (MaximumSize == 0)
1443
1444 /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1445 SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
1446 SizeLimit /= sizeof(MMPTE);
1447 SizeLimit <<= PAGE_SHIFT;
1448
1449 /* Fail if this size is too big */
1450 if (MaximumSize > SizeLimit)
1451 {
1453 }
1454
1455 /* Calculate how many Prototype PTEs will be needed */
1456 PteCount = (PFN_COUNT)((MaximumSize + PAGE_SIZE - 1) >> PAGE_SHIFT);
1457
1458 /* For commited memory, we must have a valid protection mask */
1459 if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1460
1461 /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1462 NewSegment = ExAllocatePoolWithTag(PagedPool,
1463 sizeof(SEGMENT) +
1464 sizeof(MMPTE) * (PteCount - 1),
1465 'tSmM');
1466 if (!NewSegment)
1467 {
1469 }
1470 *Segment = NewSegment;
1471
1472 /* Now allocate the control area, which has the subsection structure */
1473 ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1474 sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1475 'tCmM');
1476 if (!ControlArea)
1477 {
1478 ExFreePoolWithTag(Segment, 'tSmM');
1480 }
1481
1482 /* And zero it out, filling the basic segmnet pointer and reference fields */
1483 RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1484 ControlArea->Segment = NewSegment;
1485 ControlArea->NumberOfSectionReferences = 1;
1486 ControlArea->NumberOfUserReferences = 1;
1487
1488 /* Convert allocation attributes to control area flags */
1489 if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1490 if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1491 if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1492
1493 /* We just allocated it */
1494 ControlArea->u.Flags.BeingCreated = 1;
1495
1496 /* The subsection follows, write the mask, PTE count and point back to the CA */
1497 Subsection = (PSUBSECTION)(ControlArea + 1);
1498 Subsection->ControlArea = ControlArea;
1499 Subsection->PtesInSubsection = PteCount;
1500 Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1501
1502 /* Zero out the segment's prototype PTEs, and link it with the control area */
1503 PointerPte = &NewSegment->ThePtes[0];
1504 RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1505 NewSegment->PrototypePte = PointerPte;
1506 NewSegment->ControlArea = ControlArea;
1507
1508 /* Save some extra accounting data for the segment as well */
1509 NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1510 NewSegment->SizeOfSegment = ((ULONGLONG)PteCount) * PAGE_SIZE;
1511 NewSegment->TotalNumberOfPtes = PteCount;
1512 NewSegment->NonExtendedPtes = PteCount;
1513
1514 /* The subsection's base address is the first Prototype PTE in the segment */
1515 Subsection->SubsectionBase = PointerPte;
1516
1517 /* Start with an empty PTE, unless this is a commit operation */
1518 TempPte.u.Long = 0;
1520 {
1521 /* In which case, write down the protection mask in the Prototype PTEs */
1522 TempPte.u.Soft.Protection = ProtectionMask;
1523
1524 /* For accounting, also mark these pages as being committed */
1525 NewSegment->NumberOfCommittedPages = PteCount;
1526 }
1527
1528 /* The template PTE itself for the segment should also have the mask set */
1529 NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1530
1531 /* Write out the prototype PTEs, for now they're simply demand zero */
1532#ifdef _WIN64
1533 RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1534#else
1535 RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1536#endif
1537 return STATUS_SUCCESS;
1538}
1539
1541NTAPI
1543{
1544 PSECTION Section = SectionObject;
1547
1548 /* Check if it's an ARM3, or ReactOS section */
1550 {
1551 /* Return the file pointer stored in the control area */
1552 return Section->Segment->ControlArea->FilePointer;
1553 }
1554
1555 /* Return the file object */
1556 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1557}
1558
1559static
1562 _In_ PMMVAD Vad)
1563{
1564 PCONTROL_AREA ControlArea;
1566
1567 /* Check if this is a RosMm memory area */
1568 if (MI_IS_MEMORY_AREA_VAD(Vad))
1569 {
1571
1572 /* We do not expect ARM3 memory areas here, those are kernel only */
1573 ASSERT(MI_IS_ROSMM_VAD(Vad));
1574
1575 /* Check if it's a section view (RosMm section) */
1577 {
1578 /* Get the section pointer to the SECTION_OBJECT */
1579 FileObject = MemoryArea->SectionData.Segment->FileObject;
1580 }
1581 else
1582 {
1583#ifdef NEWCC
1584 ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1585 DPRINT1("VAD is a cache section!\n");
1586#else
1587 ASSERT(FALSE);
1588#endif
1589 return NULL;
1590 }
1591 }
1592 else
1593 {
1594 /* Make sure it's not a VM VAD */
1595 if (Vad->u.VadFlags.PrivateMemory == 1)
1596 {
1597 DPRINT1("VAD is not a section\n");
1598 return NULL;
1599 }
1600
1601 /* Get the control area */
1602 ControlArea = Vad->ControlArea;
1603 if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1604 {
1605 DPRINT1("Address is not a section\n");
1606 return NULL;
1607 }
1608
1609 /* Get the file object */
1610 FileObject = ControlArea->FilePointer;
1611 }
1612
1613 /* Return the file object */
1614 return FileObject;
1615}
1616
1617VOID
1618NTAPI
1620{
1622
1623 /* Get the section object of this process*/
1624 SectionObject = PsGetCurrentProcess()->SectionObject;
1627
1628 if (SectionObject->u.Flags.Image == 0)
1629 {
1630 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1631 return;
1632 }
1633
1634 /* Return the image information */
1635 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1636}
1637
1638static
1642{
1643 POBJECT_NAME_INFORMATION ObjectNameInfo;
1646
1647 /* Allocate memory for our structure */
1648 ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, 1024, TAG_MM);
1649 if (!ObjectNameInfo) return STATUS_NO_MEMORY;
1650
1651 /* Query the name */
1653 ObjectNameInfo,
1654 1024,
1655 &ReturnLength);
1656 if (!NT_SUCCESS(Status))
1657 {
1658 /* Failed, free memory */
1659 DPRINT1("Name query failed\n");
1660 ExFreePoolWithTag(ObjectNameInfo, TAG_MM);
1661 *ModuleName = NULL;
1662 return Status;
1663 }
1664
1665 /* Success */
1666 *ModuleName = ObjectNameInfo;
1667 return STATUS_SUCCESS;
1668}
1669
1671NTAPI
1674{
1676 PSECTION SectionObject = Section;
1677
1678 /* Make sure it's an image section */
1679 if (SectionObject->u.Flags.Image == 0)
1680 {
1681 /* It's not, fail */
1682 DPRINT1("Not an image section\n");
1684 }
1685
1686 /* Get the file object */
1689}
1690
1692NTAPI
1695{
1696 POBJECT_NAME_INFORMATION ModuleNameInformation;
1699 PMMVAD Vad;
1701
1702 /* Lock address space */
1705
1706 /* Get the VAD */
1707 Vad = MiLocateAddress(Address);
1708 if (Vad == NULL)
1709 {
1710 /* Fail, the address does not exist */
1711 DPRINT1("No VAD at address %p\n", Address);
1714 }
1715
1716 /* Get the file object pointer for the VAD */
1718 if (FileObject == NULL)
1719 {
1720 DPRINT1("Failed to get file object for Address %p\n", Address);
1723 }
1724
1725 /* Reference the file object */
1727
1728 /* Unlock address space */
1730
1731 /* Get the filename of the file object */
1732 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1733
1734 /* Dereference the file object */
1736
1737 /* Check if we were able to get the file object name */
1738 if (NT_SUCCESS(Status))
1739 {
1740 /* Init modulename */
1741 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1743
1744 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1745 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1746
1747 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1748 }
1749
1750 /* Return status */
1751 return Status;
1752}
1753
1755NTAPI
1758 OUT PVOID MemoryInformation,
1759 IN SIZE_T MemoryInformationLength,
1761{
1765 PMEMORY_SECTION_NAME SectionName = NULL;
1767
1770 NULL,
1772 (PVOID*)(&Process),
1773 NULL);
1774
1775 if (!NT_SUCCESS(Status))
1776 {
1777 DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1778 return Status;
1779 }
1780
1782
1783 if (NT_SUCCESS(Status))
1784 {
1785 SectionName = MemoryInformation;
1786 if (PreviousMode != KernelMode)
1787 {
1788 _SEH2_TRY
1789 {
1790 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1791 (PWSTR)(SectionName + 1),
1792 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1794
1796
1797 }
1799 {
1801 }
1802 _SEH2_END;
1803 }
1804 else
1805 {
1806 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1807 (PWSTR)(SectionName + 1),
1808 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1810
1812
1813 }
1814
1816 }
1818 return Status;
1819}
1820
1821VOID
1822NTAPI
1824 IN PMMPTE PointerPte,
1825 IN ULONG ProtectionMask,
1826 IN PMMPFN Pfn1,
1827 IN BOOLEAN UpdateDirty)
1828{
1829 MMPTE TempPte, PreviousPte;
1830 KIRQL OldIrql;
1831 BOOLEAN RebuildPte = FALSE;
1832
1833 //
1834 // User for sanity checking later on
1835 //
1836 PreviousPte = *PointerPte;
1837
1838 //
1839 // Build the PTE and acquire the PFN lock
1840 //
1842 PointerPte,
1843 ProtectionMask,
1844 PreviousPte.u.Hard.PageFrameNumber);
1845 OldIrql = MiAcquirePfnLock();
1846
1847 //
1848 // We don't support I/O mappings in this path yet
1849 //
1850 ASSERT(Pfn1 != NULL);
1851 ASSERT(Pfn1->u3.e1.CacheAttribute != MiWriteCombined);
1852
1853 //
1854 // Make sure new protection mask doesn't get in conflict and fix it if it does
1855 //
1856 if (Pfn1->u3.e1.CacheAttribute == MiCached)
1857 {
1858 //
1859 // This is a cached PFN
1860 //
1861 if (ProtectionMask & (MM_NOCACHE | MM_NOACCESS))
1862 {
1863 RebuildPte = TRUE;
1864 ProtectionMask &= ~(MM_NOCACHE | MM_NOACCESS);
1865 }
1866 }
1867 else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
1868 {
1869 //
1870 // This is a non-cached PFN
1871 //
1872 if ((ProtectionMask & (MM_NOCACHE | MM_NOACCESS)) != MM_NOCACHE)
1873 {
1874 RebuildPte = TRUE;
1875 ProtectionMask &= ~MM_NOACCESS;
1876 ProtectionMask |= MM_NOCACHE;
1877 }
1878 }
1879
1880 if (RebuildPte)
1881 {
1883 PointerPte,
1884 ProtectionMask,
1885 PreviousPte.u.Hard.PageFrameNumber);
1886 }
1887
1888 //
1889 // Write the new PTE, making sure we are only changing the bits
1890 //
1891 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
1892
1893 //
1894 // Flush the TLB
1895 //
1896 ASSERT(PreviousPte.u.Hard.Valid == 1);
1898 ASSERT(PreviousPte.u.Hard.Valid == 1);
1899
1900 //
1901 // Windows updates the relevant PFN1 information, we currently don't.
1902 //
1903 if (UpdateDirty && PreviousPte.u.Hard.Dirty)
1904 {
1905 if (!Pfn1->u3.e1.Modified)
1906 {
1907 DPRINT1("FIXME: Mark PFN as dirty\n");
1908 }
1909 }
1910
1911 //
1912 // Not supported in ARM3
1913 //
1914 ASSERT(FoundVad->u.VadFlags.VadType != VadWriteWatch);
1915
1916 //
1917 // Release the PFN lock, we are done
1918 //
1919 MiReleasePfnLock(OldIrql);
1920}
1921
1922static
1923VOID
1925 IN ULONG NumberOfPtes,
1926 IN PCONTROL_AREA ControlArea,
1927 IN PMMSUPPORT Ws)
1928{
1929 PMMPTE PointerPte, ProtoPte;//, FirstPte;
1930 PMMPDE PointerPde, SystemMapPde;
1931 PMMPFN Pfn1, Pfn2;
1932 MMPTE PteContents;
1933 KIRQL OldIrql;
1934 DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
1935
1936 ASSERT(Ws == NULL);
1937
1938 /* Get the PTE and loop each one */
1939 PointerPte = MiAddressToPte(BaseAddress);
1940 //FirstPte = PointerPte;
1941 while (NumberOfPtes)
1942 {
1943 /* Check if the PTE is already valid */
1944 PteContents = *PointerPte;
1945 if (PteContents.u.Hard.Valid == 1)
1946 {
1947 /* Get the PFN entry */
1948 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
1949
1950 /* Get the PTE */
1951 PointerPde = MiPteToPde(PointerPte);
1952
1953 /* Lock the PFN database and make sure this isn't a mapped file */
1954 OldIrql = MiAcquirePfnLock();
1955 ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
1956
1957 /* Mark the page as modified accordingly */
1958 if (MI_IS_PAGE_DIRTY(&PteContents))
1959 Pfn1->u3.e1.Modified = 1;
1960
1961 /* Was the PDE invalid */
1962 if (PointerPde->u.Long == 0)
1963 {
1964#if (_MI_PAGING_LEVELS == 2)
1965 /* Find the system double-mapped PDE that describes this mapping */
1966 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
1967
1968 /* Make it valid */
1969 ASSERT(SystemMapPde->u.Hard.Valid == 1);
1970 MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
1971#else
1972 DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
1973 ASSERT(FALSE);
1974#endif
1975 }
1976
1977 /* Dereference the PDE and the PTE */
1978 Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
1979 MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
1981 MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
1982
1983 /* Release the PFN lock */
1984 MiReleasePfnLock(OldIrql);
1985 }
1986 else
1987 {
1988 /* Windows ASSERT */
1989 ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
1990
1991 /* Check if this is a prototype pointer PTE */
1992 if (PteContents.u.Soft.Prototype == 1)
1993 {
1994 /* Get the prototype PTE */
1995 ProtoPte = MiProtoPteToPte(&PteContents);
1996
1997 /* We don't support anything else atm */
1998 ASSERT(ProtoPte->u.Long == 0);
1999 }
2000 }
2001
2002 /* Make the PTE into a zero PTE */
2003 PointerPte->u.Long = 0;
2004
2005 /* Move to the next PTE */
2006 PointerPte++;
2007 NumberOfPtes--;
2008 }
2009
2010 /* Flush the TLB */
2012
2013 /* Acquire the PFN lock */
2014 OldIrql = MiAcquirePfnLock();
2015
2016 /* Decrement the accounting counters */
2017 ControlArea->NumberOfUserReferences--;
2018 ControlArea->NumberOfMappedViews--;
2019
2020 /* Check if we should destroy the CA and release the lock */
2021 MiCheckControlArea(ControlArea, OldIrql);
2022}
2023
2024static
2025ULONG
2027 IN PVOID Base,
2028 OUT PCONTROL_AREA *ControlArea)
2029{
2030 ULONG Hash, Size, Count = 0;
2032 PAGED_CODE();
2033
2034 /* Compute the hash for this entry and loop trying to find it */
2035 Entry = (ULONG_PTR)Base >> 16;
2036 Hash = Entry % Session->SystemSpaceHashKey;
2037 while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2038 {
2039 /* Check if we overflew past the end of the hash table */
2040 if (++Hash >= Session->SystemSpaceHashSize)
2041 {
2042 /* Reset the hash to zero and keep searching from the bottom */
2043 Hash = 0;
2044 if (++Count == 2)
2045 {
2046 /* But if we overflew twice, then this is not a real mapping */
2047 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2048 (ULONG_PTR)Base,
2049 1,
2050 0,
2051 0);
2052 }
2053 }
2054 }
2055
2056 /* One less entry */
2057 Session->SystemSpaceHashEntries--;
2058
2059 /* Extract the size and clear the entry */
2060 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2061 Session->SystemSpaceViewTable[Hash].Entry = 0;
2062
2063 /* Return the control area and the size */
2064 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2065 return Size;
2066}
2067
2068static
2072{
2073 ULONG Size;
2074 PCONTROL_AREA ControlArea;
2075 PAGED_CODE();
2076
2077 /* Remove this mapping */
2078 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2079 Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2080
2081 /* Clear the bits for this mapping */
2082 RtlClearBits(Session->SystemSpaceBitMap,
2083 (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2084 Size);
2085
2086 /* Convert the size from a bit size into the actual size */
2087 Size = Size * (_64K >> PAGE_SHIFT);
2088
2089 /* Remove the PTEs now */
2090 MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2091 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2092
2093 /* Return success */
2094 return STATUS_SUCCESS;
2095}
2096
2097/* PUBLIC FUNCTIONS ***********************************************************/
2098
2099/*
2100 * @implemented
2101 */
2103NTAPI
2107 IN PLARGE_INTEGER InputMaximumSize,
2112{
2113 SECTION Section;
2114 PSECTION NewSection;
2115 PSUBSECTION Subsection;
2116 PSEGMENT NewSegment, Segment;
2118 PCONTROL_AREA ControlArea;
2119 ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2121 BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2122 KIRQL OldIrql;
2124 BOOLEAN UserRefIncremented = FALSE;
2125 PVOID PreviousSectionPointer;
2126
2127 /* Make the same sanity checks that the Nt interface should've validated */
2130 SEC_NO_CHANGE)) == 0);
2140
2141 /* Convert section flag to page flag */
2144
2145 /* Check to make sure the protection is correct. Nt* does this already */
2147 if (ProtectionMask == MM_INVALID_PROTECTION)
2148 {
2149 DPRINT1("Invalid protection mask\n");
2151 }
2152
2153 /* Check if this is going to be a data or image backed file section */
2154 if ((FileHandle) || (FileObject))
2155 {
2156 /* These cannot be mapped with large pages */
2158
2159 /* For now, only support the mechanism through a file handle */
2161
2162 /* Reference the file handle to get the object */
2164 MmMakeFileAccess[ProtectionMask],
2167 (PVOID*)&File,
2168 NULL);
2169 if (!NT_SUCCESS(Status)) return Status;
2170
2171 /* Make sure Cc has been doing its job */
2172 if (!File->SectionObjectPointer)
2173 {
2174 /* This is not a valid file system-based file, fail */
2177 }
2178
2179 /* Image-file backed sections are not yet supported */
2181
2182 /* Compute the size of the control area, and allocate it */
2183 ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2184 ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2185 if (!ControlArea)
2186 {
2189 }
2190
2191 /* Zero it out */
2192 RtlZeroMemory(ControlArea, ControlAreaSize);
2193
2194 /* Did we get a handle, or an object? */
2195 if (FileHandle)
2196 {
2197 /* We got a file handle so we have to lock down the file */
2198#if 0
2200 if (!NT_SUCCESS(Status))
2201 {
2202 ExFreePool(ControlArea);
2204 return Status;
2205 }
2206#else
2207 /* ReactOS doesn't support this API yet, so do nothing */
2210#endif
2211 /* Update the top-level IRP so that drivers know what's happening */
2213 FileLock = TRUE;
2214 }
2215
2216 /* Lock the PFN database while we play with the section pointers */
2217 OldIrql = MiAcquirePfnLock();
2218
2219 /* Image-file backed sections are not yet supported */
2221
2222 /* There should not already be a control area for this file */
2223 ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2224 NewSegment = NULL;
2225
2226 /* Write down that this CA is being created, and set it */
2227 ControlArea->u.Flags.BeingCreated = TRUE;
2229 PreviousSectionPointer = File->SectionObjectPointer;
2230 File->SectionObjectPointer->DataSectionObject = ControlArea;
2231
2232 /* We can release the PFN lock now */
2233 MiReleasePfnLock(OldIrql);
2234
2235 /* We don't support previously-mapped file */
2236 ASSERT(NewSegment == NULL);
2237
2238 /* Image-file backed sections are not yet supported */
2240
2241 /* So we always create a data file map */
2243 &Segment,
2244 InputMaximumSize,
2247 KernelCall);
2248 if (!NT_SUCCESS(Status))
2249 {
2250 /* Lock the PFN database while we play with the section pointers */
2251 OldIrql = MiAcquirePfnLock();
2252
2253 /* Reset the waiting-for-deletion event */
2254 ASSERT(ControlArea->WaitingForDeletion == NULL);
2255 ControlArea->WaitingForDeletion = NULL;
2256
2257 /* Set the file pointer NULL flag */
2258 ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2259 ControlArea->u.Flags.FilePointerNull = TRUE;
2260
2261 /* Delete the data section object */
2263 File->SectionObjectPointer->DataSectionObject = NULL;
2264
2265 /* No longer being created */
2266 ControlArea->u.Flags.BeingCreated = FALSE;
2267
2268 /* We can release the PFN lock now */
2269 MiReleasePfnLock(OldIrql);
2270
2271 /* Check if we locked and set the IRP */
2272 if (FileLock)
2273 {
2274 /* Undo */
2276 //FsRtlReleaseFile(File);
2277 }
2278
2279 /* Free the control area and de-ref the file object */
2280 ExFreePool(ControlArea);
2282
2283 /* All done */
2284 return Status;
2285 }
2286
2287 /* On success, we expect this */
2288 ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2289
2290 /* Check if a maximum size was specified */
2291 if (!InputMaximumSize->QuadPart)
2292 {
2293 /* Nope, use the segment size */
2294 Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2295 }
2296 else
2297 {
2298 /* Yep, use the entered size */
2299 Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2300 }
2301 }
2302 else
2303 {
2304 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2306
2307 /* Not yet supported */
2309
2310 /* So this must be a pagefile-backed section, create the mappings needed */
2311 Status = MiCreatePagingFileMap(&NewSegment,
2312 InputMaximumSize->QuadPart,
2313 ProtectionMask,
2315 if (!NT_SUCCESS(Status)) return Status;
2316
2317 /* Set the size here, and read the control area */
2318 Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2319 ControlArea = NewSegment->ControlArea;
2320
2321 /* MiCreatePagingFileMap increments user references */
2322 UserRefIncremented = TRUE;
2323 }
2324
2325 /* Did we already have a segment? */
2326 if (!NewSegment)
2327 {
2328 /* This must be the file path and we created a segment */
2329 NewSegment = Segment;
2330 ASSERT(File != NULL);
2331
2332 /* Acquire the PFN lock while we set control area flags */
2333 OldIrql = MiAcquirePfnLock();
2334
2335 /* We don't support this race condition yet, so assume no waiters */
2336 ASSERT(ControlArea->WaitingForDeletion == NULL);
2337 ControlArea->WaitingForDeletion = NULL;
2338
2339 /* Image-file backed sections are not yet supported, nor ROM images */
2341 ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2342
2343 /* Take off the being created flag, and then release the lock */
2344 ControlArea->u.Flags.BeingCreated = FALSE;
2345 MiReleasePfnLock(OldIrql);
2346 }
2347
2348 /* Check if we locked the file earlier */
2349 if (FileLock)
2350 {
2351 /* Reset the top-level IRP and release the lock */
2353 //FsRtlReleaseFile(File);
2354 FileLock = FALSE;
2355 }
2356
2357 /* Set the initial section object data */
2359
2360 /* The mapping created a control area and segment, save the flags */
2361 Section.Segment = NewSegment;
2362 Section.u.LongFlags = ControlArea->u.LongFlags;
2363
2364 /* Check if this is a user-mode read-write non-image file mapping */
2365 if (!(FileObject) &&
2367 !(ControlArea->u.Flags.Image) &&
2368 (ControlArea->FilePointer))
2369 {
2370 /* Add a reference and set the flag */
2371 Section.u.Flags.UserWritable = TRUE;
2372 InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2373 }
2374
2375 /* Check for image mappings or page file mappings */
2376 if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2377 {
2378 /* Charge the segment size, and allocate a subsection */
2379 PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2380 Size = sizeof(SUBSECTION);
2381 }
2382 else
2383 {
2384 /* Charge nothing, and allocate a mapped subsection */
2385 PagedCharge = 0;
2386 Size = sizeof(MSUBSECTION);
2387 }
2388
2389 /* Check if this is a normal CA */
2390 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2391 ASSERT(ControlArea->u.Flags.Rom == 0);
2392
2393 /* Charge only a CA, and the subsection is right after */
2394 NonPagedCharge = sizeof(CONTROL_AREA);
2395 Subsection = (PSUBSECTION)(ControlArea + 1);
2396
2397 /* We only support single-subsection mappings */
2398 NonPagedCharge += Size;
2399 ASSERT(Subsection->NextSubsection == NULL);
2400
2401 /* Create the actual section object, with enough space for the prototype PTEs */
2406 NULL,
2407 sizeof(SECTION),
2408 PagedCharge,
2409 NonPagedCharge,
2410 (PVOID*)&NewSection);
2411 if (!NT_SUCCESS(Status))
2412 {
2413 /* Check if this is a user-mode read-write non-image file mapping */
2414 if (!(FileObject) &&
2416 !(ControlArea->u.Flags.Image) &&
2417 (ControlArea->FilePointer))
2418 {
2419 /* Remove a reference and check the flag */
2420 ASSERT(Section.u.Flags.UserWritable == 1);
2421 InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2422 }
2423
2424 /* Check if a user reference was added */
2425 if (UserRefIncremented)
2426 {
2427 /* Acquire the PFN lock while we change counters */
2428 OldIrql = MiAcquirePfnLock();
2429
2430 /* Decrement the accounting counters */
2431 ControlArea->NumberOfSectionReferences--;
2432 ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2433 ControlArea->NumberOfUserReferences--;
2434
2435 /* Check if we should destroy the CA and release the lock */
2436 MiCheckControlArea(ControlArea, OldIrql);
2437 }
2438
2439 /* Return the failure code */
2440 return Status;
2441 }
2442
2443 /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2444
2445 /* Now copy the local section object from the stack into this new object */
2446 RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2447 NewSection->Address.StartingVpn = 0;
2448
2449 /* For now, only user calls are supported */
2450 ASSERT(KernelCall == FALSE);
2451 NewSection->u.Flags.UserReference = TRUE;
2452
2453 /* Is this a "based" allocation, in which all mappings are identical? */
2455 {
2456 /* Lock the VAD tree during the search */
2458
2459 /* Is it a brand new ControArea ? */
2460 if (ControlArea->u.Flags.BeingCreated == 1)
2461 {
2462 ASSERT(ControlArea->u.Flags.Based == 1);
2463 /* Then we must find a global address, top-down */
2466 _64K,
2468 (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2469
2470 if (!NT_SUCCESS(Status))
2471 {
2472 /* No way to find a valid range. */
2474 ControlArea->u.Flags.Based = 0;
2475 NewSection->u.Flags.Based = 0;
2476 ObDereferenceObject(NewSection);
2477 return Status;
2478 }
2479
2480 /* Compute the ending address and insert it into the VAD tree */
2481 NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2482 NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2483 MiInsertBasedSection(NewSection);
2484 }
2485 else
2486 {
2487 /* FIXME : Should we deny section creation if SEC_BASED is not set ? Can we have two different section objects on the same based address ? Investigate !*/
2488 ASSERT(FALSE);
2489 }
2490
2492 }
2493
2494 /* The control area is not being created anymore */
2495 if (ControlArea->u.Flags.BeingCreated == 1)
2496 {
2497 /* Acquire the PFN lock while we set control area flags */
2498 OldIrql = MiAcquirePfnLock();
2499
2500 /* Take off the being created flag, and then release the lock */
2501 ControlArea->u.Flags.BeingCreated = 0;
2502 NewSection->u.Flags.BeingCreated = 0;
2503
2504 MiReleasePfnLock(OldIrql);
2505 }
2506
2507 /* Migrate the attribute into a flag */
2509
2510 /* If R/W access is not requested, this might eventually become a CoW mapping */
2512 {
2513 NewSection->u.Flags.CopyOnWrite = TRUE;
2514 }
2515
2516 /* Write down if this was a kernel call */
2517 ControlArea->u.Flags.WasPurged |= KernelCall;
2518 ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2519
2520 /* Make sure the segment and the section are the same size, or the section is smaller */
2521 ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2522
2523 /* Return the object and the creation status */
2524 *SectionObject = (PVOID)NewSection;
2525 return Status;
2526}
2527
2528/*
2529 * @implemented
2530 */
2532NTAPI
2543{
2546 PSECTION Section;
2547 PCONTROL_AREA ControlArea;
2548 ULONG ProtectionMask;
2550 ULONG64 CalculatedViewSize;
2551 PAGED_CODE();
2552
2553 /* Get the segment and control area */
2554 Section = (PSECTION)SectionObject;
2555 ControlArea = Section->Segment->ControlArea;
2556
2557 /* These flags/states are not yet supported by ARM3 */
2558 ASSERT(Section->u.Flags.Image == 0);
2559 ASSERT(Section->u.Flags.NoCache == 0);
2560 ASSERT(Section->u.Flags.WriteCombined == 0);
2561 ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
2562
2563 /* FIXME */
2564 if ((AllocationType & MEM_RESERVE) != 0)
2565 {
2566 DPRINT1("MmMapViewOfArm3Section called with MEM_RESERVE, this is not implemented yet!!!\n");
2568 }
2569
2570 /* Check if the mapping protection is compatible with the create */
2572 {
2573 DPRINT1("Mapping protection is incompatible\n");
2575 }
2576
2577 /* Check if the offset and size would cause an overflow */
2578 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) <
2579 (ULONG64)SectionOffset->QuadPart)
2580 {
2581 DPRINT1("Section offset overflows\n");
2583 }
2584
2585 /* Check if the offset and size are bigger than the section itself */
2586 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) >
2587 (ULONG64)Section->SizeOfSection.QuadPart)
2588 {
2589 DPRINT1("Section offset is larger than section\n");
2591 }
2592
2593 /* Check if the caller did not specify a view size */
2594 if (!(*ViewSize))
2595 {
2596 /* Compute it for the caller */
2597 CalculatedViewSize = Section->SizeOfSection.QuadPart -
2598 SectionOffset->QuadPart;
2599
2600 /* Check if it's larger than 4GB or overflows into kernel-mode */
2601 if (!NT_SUCCESS(RtlULongLongToSIZET(CalculatedViewSize, ViewSize)) ||
2602 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < CalculatedViewSize))
2603 {
2604 DPRINT1("Section view won't fit\n");
2606 }
2607 }
2608
2609 /* Check if the commit size is larger than the view size */
2610 if (CommitSize > *ViewSize)
2611 {
2612 DPRINT1("Attempting to commit more than the view itself\n");
2614 }
2615
2616 /* Check if the view size is larger than the section */
2617 if (*ViewSize > (ULONG64)Section->SizeOfSection.QuadPart)
2618 {
2619 DPRINT1("The view is larger than the section\n");
2621 }
2622
2623 /* Compute and validate the protection mask */
2624 ProtectionMask = MiMakeProtectionMask(Protect);
2625 if (ProtectionMask == MM_INVALID_PROTECTION)
2626 {
2627 DPRINT1("The protection is invalid\n");
2629 }
2630
2631 /* We only handle pagefile-backed sections, which cannot be writecombined */
2633 {
2634 DPRINT1("Cannot write combine a pagefile-backed section\n");
2636 }
2637
2638 /* Start by attaching to the current process if needed */
2640 {
2642 Attached = TRUE;
2643 }
2644
2645 /* Do the actual mapping */
2646 Status = MiMapViewOfDataSection(ControlArea,
2647 Process,
2650 ViewSize,
2651 Section,
2653 ProtectionMask,
2654 CommitSize,
2655 ZeroBits,
2657
2658 /* Detach if needed, then return status */
2660 return Status;
2661}
2662
2663/*
2664 * @unimplemented
2665 */
2666BOOLEAN
2667NTAPI
2669{
2671 return FALSE;
2672}
2673
2674/*
2675 * @unimplemented
2676 */
2677BOOLEAN
2678NTAPI
2681{
2683 return FALSE;
2684}
2685
2686/*
2687 * @implemented
2688 */
2690NTAPI
2694{
2695 PAGED_CODE();
2697
2698 // HACK
2699 if (MiIsRosSectionObject(Section))
2700 {
2701 return MmMapViewInSystemSpace(Section, MappedBase, ViewSize);
2702 }
2703
2704 /* Process must be in a session */
2705 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2706 {
2707 DPRINT1("Process is not in session\n");
2709 }
2710
2711 /* Use the system space API, but with the session view instead */
2713 SectionOffset.QuadPart = 0;
2714 return MiMapViewInSystemSpace(Section,
2716 MappedBase,
2717 ViewSize,
2718 &SectionOffset);
2719}
2720
2721/*
2722 * @implemented
2723 */
2725NTAPI
2727{
2728 PAGED_CODE();
2729
2730 // HACK
2732 {
2734 }
2735
2736 /* Process must be in a session */
2737 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2738 {
2739 DPRINT1("Proess is not in session\n");
2741 }
2742
2743 /* Use the system space API, but with the session view instead */
2746 MappedBase);
2747}
2748
2749/*
2750 * @implemented
2751 */
2753NTAPI
2756{
2758}
2759
2760/*
2761 * @implemented
2762 */
2764NTAPI
2766{
2768 PAGED_CODE();
2769
2770 /* Was this mapped by RosMm? */
2774 {
2777 return Status;
2778 }
2780
2781 /* It was not, call the ARM3 routine */
2783}
2784
2785/*
2786 * @implemented
2787 */
2789NTAPI
2792{
2793 ULONG_PTR StartAddress, EndingAddress, Base;
2794 ULONG Hash, Count = 0, Size, QuotaCharge;
2795 PMMSESSION Session;
2796 PMMPTE LastProtoPte, PointerPte, ProtoPte;
2797 PCONTROL_AREA ControlArea;
2799 PSUBSECTION Subsection;
2800 MMPTE TempPte;
2801 PAGED_CODE();
2802
2803 /* Make sure the base isn't past the session view range */
2806 {
2807 DPRINT1("Base outside of valid range\n");
2809 }
2810
2811 /* Make sure the size isn't past the session view range */
2814 {
2815 DPRINT1("Size outside of valid range\n");
2817 }
2818
2819 /* Sanity check */
2820 ASSERT(ViewSize != 0);
2821
2822 /* Process must be in a session */
2823 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2824 {
2825 DPRINT1("Process is not in session\n");
2827 }
2828
2829 /* Compute the correctly aligned base and end addresses */
2830 StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
2831 EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
2832
2833 /* Sanity check and grab the session */
2835 Session = &MmSessionSpace->Session;
2836
2837 /* Get the hash entry for this allocation */
2838 Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
2839
2840 /* Lock system space */
2842
2843 /* Loop twice so we can try rolling over if needed */
2844 while (TRUE)
2845 {
2846 /* Extract the size and base addresses from the entry */
2847 Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
2848 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2849
2850 /* Convert the size to bucket chunks */
2852
2853 /* Bail out if this entry fits in here */
2854 if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
2855
2856 /* Check if we overflew past the end of the hash table */
2857 if (++Hash >= Session->SystemSpaceHashSize)
2858 {
2859 /* Reset the hash to zero and keep searching from the bottom */
2860 Hash = 0;
2861 if (++Count == 2)
2862 {
2863 /* But if we overflew twice, then this is not a real mapping */
2864 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2865 Base,
2866 2,
2867 0,
2868 0);
2869 }
2870 }
2871 }
2872
2873 /* Make sure the view being mapped is not file-based */
2874 ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2875 if (ControlArea->FilePointer != NULL)
2876 {
2877 /* It is, so we have to bail out */
2878 DPRINT1("Only page-filed backed sections can be commited\n");
2881 }
2882
2883 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
2884 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2885 ASSERT(ControlArea->u.Flags.Rom == 0);
2886 Subsection = (PSUBSECTION)(ControlArea + 1);
2887
2888 /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
2889 ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
2890 QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
2891 LastProtoPte = ProtoPte + QuotaCharge;
2892 if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
2893 {
2894 DPRINT1("PTE is out of bounds\n");
2897 }
2898
2899 /* Acquire the commit lock and count all the non-committed PTEs */
2901 PointerPte = ProtoPte;
2902 while (PointerPte < LastProtoPte)
2903 {
2904 if (PointerPte->u.Long) QuotaCharge--;
2905 PointerPte++;
2906 }
2907
2908 /* Was everything committed already? */
2909 if (!QuotaCharge)
2910 {
2911 /* Nothing to do! */
2914 return STATUS_SUCCESS;
2915 }
2916
2917 /* Pick the segment and template PTE */
2918 Segment = ControlArea->Segment;
2919 TempPte = Segment->SegmentPteTemplate;
2920 ASSERT(TempPte.u.Long != 0);
2921
2922 /* Loop all prototype PTEs to be committed */
2923 PointerPte = ProtoPte;
2924 while (PointerPte < LastProtoPte)
2925 {
2926 /* Make sure the PTE is already invalid */
2927 if (PointerPte->u.Long == 0)
2928 {
2929 /* And write the invalid PTE */
2930 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2931 }
2932
2933 /* Move to the next PTE */
2934 PointerPte++;
2935 }
2936
2937 /* Check if we had at least one page charged */
2938 if (QuotaCharge)
2939 {
2940 /* Update the accounting data */
2941 Segment->NumberOfCommittedPages += QuotaCharge;
2943 }
2944
2945 /* Release all */
2948 return STATUS_SUCCESS;
2949}
2950
2951VOID
2952NTAPI
2954{
2956 PCONTROL_AREA ControlArea;
2957 KIRQL OldIrql;
2958
2959 SectionObject = (PSECTION)ObjectBody;
2960
2961 if (SectionObject->u.Flags.Based == 1)
2962 {
2963 /* Remove the node from the global section address tree */
2967 }
2968
2969 /* Lock the PFN database */
2970 OldIrql = MiAcquirePfnLock();
2971
2972 ASSERT(SectionObject->Segment);
2973 ASSERT(SectionObject->Segment->ControlArea);
2974
2975 ControlArea = SectionObject->Segment->ControlArea;
2976
2977 /* Dereference */
2978 ControlArea->NumberOfSectionReferences--;
2979 ControlArea->NumberOfUserReferences--;
2980
2981 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
2982
2983 /* Check it. It will delete it if there is no more reference to it */
2984 MiCheckControlArea(ControlArea, OldIrql);
2985}
2986
2987ULONG
2988NTAPI
2990{
2992 return 0;
2993}
2994
2995/* SYSTEM CALLS ***************************************************************/
2996
2998NTAPI
2999NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage,
3000 IN PVOID File2MappedAsFile)
3001{
3003 PMMVAD Vad1, Vad2;
3004 PFILE_OBJECT FileObject1, FileObject2;
3006
3007 /* Lock address space */
3010
3011 /* Get the VAD for Address 1 */
3012 Vad1 = MiLocateAddress(File1MappedAsAnImage);
3013 if (Vad1 == NULL)
3014 {
3015 /* Fail, the address does not exist */
3016 DPRINT1("No VAD at address 1 %p\n", File1MappedAsAnImage);
3018 goto Exit;
3019 }
3020
3021 /* Get the VAD for Address 2 */
3022 Vad2 = MiLocateAddress(File2MappedAsFile);
3023 if (Vad2 == NULL)
3024 {
3025 /* Fail, the address does not exist */
3026 DPRINT1("No VAD at address 2 %p\n", File2MappedAsFile);
3028 goto Exit;
3029 }
3030
3031 /* Get the file object pointer for VAD 1 */
3032 FileObject1 = MiGetFileObjectForVad(Vad1);
3033 if (FileObject1 == NULL)
3034 {
3035 DPRINT1("Failed to get file object for Address 1 %p\n", File1MappedAsAnImage);
3037 goto Exit;
3038 }
3039
3040 /* Get the file object pointer for VAD 2 */
3041 FileObject2 = MiGetFileObjectForVad(Vad2);
3042 if (FileObject2 == NULL)
3043 {
3044 DPRINT1("Failed to get file object for Address 2 %p\n", File2MappedAsFile);
3046 goto Exit;
3047 }
3048
3049 /* Make sure Vad1 is an image mapping */
3050 if (Vad1->u.VadFlags.VadType != VadImageMap)
3051 {
3052 DPRINT1("Address 1 (%p) is not an image mapping\n", File1MappedAsAnImage);
3054 goto Exit;
3055 }
3056
3057 /* SectionObjectPointer is equal if the files are equal */
3058 if (FileObject1->SectionObjectPointer == FileObject2->SectionObjectPointer)
3059 {
3061 }
3062 else
3063 {
3065 }
3066
3067Exit:
3068 /* Unlock address space */
3070 return Status;
3071}
3072
3073/*
3074 * @implemented
3075 */
3077NTAPI
3085{
3086 LARGE_INTEGER SafeMaximumSize;
3088 HANDLE Handle;
3091 PAGED_CODE();
3092
3093 /* Check for non-existing flags */
3096 SEC_NO_CHANGE)))
3097 {
3098 if (!(AllocationAttributes & 1))
3099 {
3100 DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
3102 }
3103 }
3104
3105 /* Check for no allocation type */
3107 {
3108 DPRINT1("Missing allocation type in allocation attributes\n");
3110 }
3111
3112 /* Check for image allocation with invalid attributes */
3116 {
3117 DPRINT1("Image allocation with invalid attributes\n");
3119 }
3120
3121 /* Check for allocation type is both commit and reserve */
3123 {
3124 DPRINT1("Commit and reserve in the same time\n");
3126 }
3127
3128 /* Now check for valid protection */
3133 {
3134 DPRINT1("Sections don't support these protections\n");
3136 }
3137
3138 /* Use a maximum size of zero, if none was specified */
3139 SafeMaximumSize.QuadPart = 0;
3140
3141 /* Check for user-mode caller */
3142 if (PreviousMode != KernelMode)
3143 {
3144 /* Enter SEH */
3145 _SEH2_TRY
3146 {
3147 /* Safely check user-mode parameters */
3148 if (MaximumSize) SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
3149 MaximumSize = &SafeMaximumSize;
3150 ProbeForWriteHandle(SectionHandle);
3151 }
3153 {
3154 /* Return the exception code */
3156 }
3157 _SEH2_END;
3158 }
3159 else if (!MaximumSize) MaximumSize = &SafeMaximumSize;
3160
3161 /* Check that MaximumSize is valid if backed by paging file */
3162 if ((!FileHandle) && (!MaximumSize->QuadPart))
3164
3165 /* Create the section */
3172 FileHandle,
3173 NULL);
3174 if (!NT_SUCCESS(Status)) return Status;
3175
3176 /* FIXME: Should zero last page for a file mapping */
3177
3178 /* Now insert the object */
3180 NULL,
3182 0,
3183 NULL,
3184 &Handle);
3185 if (NT_SUCCESS(Status))
3186 {
3187 /* Enter SEH */
3188 _SEH2_TRY
3189 {
3190 /* Return the handle safely */
3191 *SectionHandle = Handle;
3192 }
3194 {
3195 /* Nothing here */
3196 }
3197 _SEH2_END;
3198 }
3199
3200 /* Return the status */
3201 return Status;
3202}
3203
3205NTAPI
3209{
3210 HANDLE Handle;
3213 PAGED_CODE();
3214
3215 /* Check for user-mode caller */
3216 if (PreviousMode != KernelMode)
3217 {
3218 /* Enter SEH */
3219 _SEH2_TRY
3220 {
3221 /* Safely check user-mode parameters */
3222 ProbeForWriteHandle(SectionHandle);
3223 }
3225 {
3226 /* Return the exception code */
3228 }
3229 _SEH2_END;
3230 }
3231
3232 /* Try opening the object */
3236 NULL,
3238 NULL,
3239 &Handle);
3240
3241 /* Enter SEH */
3242 _SEH2_TRY
3243 {
3244 /* Return the handle safely */
3245 *SectionHandle = Handle;
3246 }
3248 {
3249 /* Nothing here */
3250 }
3251 _SEH2_END;
3252
3253 /* Return the status */
3254 return Status;
3255}
3256
3258NTAPI
3269{
3270 PVOID SafeBaseAddress;
3271 LARGE_INTEGER SafeSectionOffset;
3272 SIZE_T SafeViewSize;
3273 PSECTION Section;
3277 ULONG ProtectionMask;
3279#if defined(_M_IX86) || defined(_M_AMD64)
3280 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3282#else
3283 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3285#endif
3286
3287 /* Check for invalid inherit disposition */
3289 {
3290 DPRINT1("Invalid inherit disposition\n");
3292 }
3293
3294 /* Allow only valid allocation types */
3295 if (AllocationType & ~ValidAllocationType)
3296 {
3297 DPRINT1("Invalid allocation type\n");
3299 }
3300
3301 /* Convert the protection mask, and validate it */
3302 ProtectionMask = MiMakeProtectionMask(Protect);
3303 if (ProtectionMask == MM_INVALID_PROTECTION)
3304 {
3305 DPRINT1("Invalid page protection\n");
3307 }
3308
3309 /* Now convert the protection mask into desired section access mask */
3310 DesiredAccess = MmMakeSectionAccess[ProtectionMask & 0x7];
3311
3312 /* Assume no section offset */
3313 SafeSectionOffset.QuadPart = 0;
3314
3315 /* Enter SEH */
3316 _SEH2_TRY
3317 {
3318 /* Check for unsafe parameters */
3319 if (PreviousMode != KernelMode)
3320 {
3321 /* Probe the parameters */
3324 }
3325
3326 /* Check if a section offset was given */
3327 if (SectionOffset)
3328 {
3329 /* Check for unsafe parameters and capture section offset */
3331 SafeSectionOffset = *SectionOffset;
3332 }
3333
3334 /* Capture the other parameters */
3335 SafeBaseAddress = *BaseAddress;
3336 SafeViewSize = *ViewSize;
3337 }
3339 {
3340 /* Return the exception code */
3342 }
3343 _SEH2_END;
3344
3345 /* Check for kernel-mode address */
3346 if (SafeBaseAddress > MM_HIGHEST_VAD_ADDRESS)
3347 {
3348 DPRINT1("Kernel base not allowed\n");
3350 }
3351
3352 /* Check for range entering kernel-mode */
3353 if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)SafeBaseAddress) < SafeViewSize)
3354 {
3355 DPRINT1("Overflowing into kernel base not allowed\n");
3357 }
3358
3359 /* Check for invalid zero bits */
3360 if (ZeroBits)
3361 {
3363 {
3364 DPRINT1("Invalid zero bits\n");
3366 }
3367
3368 if ((((ULONG_PTR)SafeBaseAddress << ZeroBits) >> ZeroBits) != (ULONG_PTR)SafeBaseAddress)
3369 {
3370 DPRINT1("Invalid zero bits\n");
3372 }
3373
3374 if (((((ULONG_PTR)SafeBaseAddress + SafeViewSize) << ZeroBits) >> ZeroBits) != ((ULONG_PTR)SafeBaseAddress + SafeViewSize))
3375 {
3376 DPRINT1("Invalid zero bits\n");
3378 }
3379 }
3380
3381 /* Reference the process */
3386 (PVOID*)&Process,
3387 NULL);
3388 if (!NT_SUCCESS(Status)) return Status;
3389
3390 /* Reference the section */
3391 Status = ObReferenceObjectByHandle(SectionHandle,
3395 (PVOID*)&Section,
3396 NULL);
3397 if (!NT_SUCCESS(Status))
3398 {
3400 return Status;
3401 }
3402
3403 if (Section->u.Flags.PhysicalMemory)
3404 {
3405 if (PreviousMode == UserMode &&
3406 SafeSectionOffset.QuadPart + SafeViewSize > MmHighestPhysicalPage << PAGE_SHIFT)
3407 {
3408 DPRINT1("Denying map past highest physical page.\n");
3409 ObDereferenceObject(Section);
3412 }
3413 }
3414 else if (!(AllocationType & MEM_DOS_LIM))
3415 {
3416 /* Check for non-allocation-granularity-aligned BaseAddress */
3417 if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
3418 {
3419 DPRINT("BaseAddress is not at 64-kilobyte address boundary.\n");
3420 ObDereferenceObject(Section);
3423 }
3424
3425 /* Do the same for the section offset */
3426 if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
3427 {
3428 DPRINT("SectionOffset is not at 64-kilobyte address boundary.\n");
3429 ObDereferenceObject(Section);
3432 }
3433 }
3434
3435 /* Now do the actual mapping */
3436 Status = MmMapViewOfSection(Section,
3437 Process,
3438 &SafeBaseAddress,
3439 ZeroBits,
3440 CommitSize,
3441 &SafeSectionOffset,
3442 &SafeViewSize,
3445 Protect);
3446
3447 /* Return data only on success */
3448 if (NT_SUCCESS(Status))
3449 {
3450 /* Check if this is an image for the current process */
3451 if ((Section->u.Flags.Image) &&
3454 {
3455 /* Notify the debugger */
3456 DbgkMapViewOfSection(Section,
3457 SafeBaseAddress,
3458 SafeSectionOffset.LowPart,
3459 SafeViewSize);
3460 }
3461
3462 /* Enter SEH */
3463 _SEH2_TRY
3464 {
3465 /* Return parameters to user */
3466 *BaseAddress = SafeBaseAddress;
3467 *ViewSize = SafeViewSize;
3468 if (SectionOffset) *SectionOffset = SafeSectionOffset;
3469 }
3471 {
3472 /* Nothing to do */
3473 }
3474 _SEH2_END;
3475 }
3476
3477 /* Dereference all objects and return status */
3478 ObDereferenceObject(Section);
3480 return Status;
3481}
3482
3484NTAPI
3487{
3491
3492 /* Don't allowing mapping kernel views */
3494 {
3495 DPRINT1("Trying to unmap a kernel view\n");
3497 }
3498
3499 /* Reference the process */
3504 (PVOID*)&Process,
3505 NULL);
3506 if (!NT_SUCCESS(Status)) return Status;
3507
3508 /* Unmap the view */
3510
3511 /* Dereference the process and return status */
3513 return Status;
3514}
3515
3517NTAPI
3519 IN OUT PLARGE_INTEGER NewMaximumSize)
3520{
3521 LARGE_INTEGER SafeNewMaximumSize;
3522 PSECTION Section;
3525
3526 /* Check for user-mode parameters */
3527 if (PreviousMode != KernelMode)
3528 {
3529 /* Enter SEH */
3530 _SEH2_TRY
3531 {
3532 /* Probe and capture the maximum size, it's both read and write */
3533 ProbeForWriteLargeInteger(NewMaximumSize);
3534 SafeNewMaximumSize = *NewMaximumSize;
3535 }
3537 {
3538 /* Return the exception code */
3540 }
3541 _SEH2_END;
3542 }
3543 else
3544 {
3545 /* Just read the size directly */
3546 SafeNewMaximumSize = *NewMaximumSize;
3547 }
3548
3549 /* Reference the section */
3550 Status = ObReferenceObjectByHandle(SectionHandle,
3554 (PVOID*)&Section,
3555 NULL);
3556 if (!NT_SUCCESS(Status)) return Status;
3557
3558 Status = MmExtendSection(Section, &SafeNewMaximumSize);
3559
3560 /* Dereference the section */
3561 ObDereferenceObject(Section);
3562
3563 if (NT_SUCCESS(Status))
3564 {
3565 _SEH2_TRY
3566 {
3567 /* Write back the new size */
3568 *NewMaximumSize = SafeNewMaximumSize;
3569 }
3571 {
3573 }
3574 _SEH2_END;
3575 }
3576
3577 /* Return the status */
3579}
3580
3581/* EOF */
static NTSTATUS MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:532
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:2765
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1561
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
NTSTATUS NTAPI MiQueryMemorySectionName(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
Definition: section.c:1756
CHAR MmUserProtectionToMask1[16]
Definition: section.c:44
NTSTATUS MiMapViewInSystemSpace(_In_ PVOID Section, _In_ PMMSESSION Session, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset)
Definition: section.c:1041
BOOLEAN NTAPI MmForceSectionClosed(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
Definition: section.c:2679
static NTSTATUS MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1408
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3485
VOID NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:464
ACCESS_MASK MmMakeSectionAccess[8]
Definition: section.c:20
NTSTATUS NTAPI MmGetFileNameForSection(IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1672
ULONG MmCompatibleProtectionMask[8]
Definition: section.c:84
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3078
MMSESSION MmSession
Definition: section.c:107
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3206
static ULONG MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2026
VOID NTAPI MiFlushTbAndCapture(IN PMMVAD FoundVad, IN PMMPTE PointerPte, IN ULONG ProtectionMask, IN PMMPFN Pfn1, IN BOOLEAN UpdateDirty)
Definition: section.c:1823
ULONG NTAPI MmDoesFileHaveUserWritableReferences(IN PSECTION_OBJECT_POINTERS SectionPointer)
Definition: section.c:2989
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:768
NTSTATUS NTAPI MmCreateArm3Section(OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER InputMaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: section.c:2104
static NTSTATUS MiAddMappedPtes(IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea, IN LONGLONG SectionOffset)
Definition: section.c:401
static VOID MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:751
static NTSTATUS MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN ULONG64 MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1423
CHAR MmUserProtectionToMask2[16]
Definition: section.c:64
VOID NTAPI MmGetImageInformation(OUT PSECTION_IMAGE_INFORMATION ImageInformation)
Definition: section.c:1619
VOID NTAPI MiDeleteARM3Section(PVOID ObjectBody)
Definition: section.c:2953
NTSTATUS NTAPI NtMapViewOfSection(IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3259
static PVOID MiInsertInSystemSpace(IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
Definition: section.c:288
NTSTATUS NTAPI MmMapViewOfArm3Section(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:2533
NTSTATUS NTAPI MmUnmapViewInSessionSpace(IN PVOID MappedBase)
Definition: section.c:2726
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:2691
static NTSTATUS MiSessionCommitPageTables(IN PVOID StartVa, IN PVOID EndVa)
Definition: section.c:925
static VOID MiRemoveMappedPtes(IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
Definition: section.c:1924
PVOID MmHighSectionBase
Definition: section.c:111
static NTSTATUS MiUnmapViewInSystemSpace(IN PMMSESSION Session, IN PVOID MappedBase)
Definition: section.c:2070
PSUBSECTION NTAPI MiLocateSubsection(IN PMMVAD Vad, IN ULONG_PTR Vpn)
Definition: section.c:558
NTSTATUS NTAPI NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, IN PVOID File2MappedAsFile)
Definition: section.c:2999
static NTSTATUS MiUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
Definition: section.c:806
NTSTATUS NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName)
Definition: section.c:1693
KGUARDED_MUTEX MmSectionCommitMutex
Definition: section.c:108
BOOLEAN NTAPI MiInitializeSystemSpaceMap(IN PMMSESSION InputSession OPTIONAL)
Definition: section.c:222
static NTSTATUS MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *BaseAddress, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T ViewSize, IN PSECTION Section, IN SECTION_INHERIT InheritDisposition, IN ULONG ProtectionMask, IN SIZE_T CommitSize, IN ULONG_PTR ZeroBits, IN ULONG AllocationType)
Definition: section.c:1153
NTSTATUS NTAPI MmCommitSessionMappedView(IN PVOID MappedBase, IN SIZE_T ViewSize)
Definition: section.c:2790
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID SectionObject)
Definition: section.c:1542
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:2754
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
BOOLEAN NTAPI MmDisableModifiedWriteOfSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: section.c:2668
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
static VOID MiSegmentDelete(IN PSEGMENT Segment)
Definition: section.c:593
static VOID MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:716
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:140
static BOOLEAN MiIsProtectionCompatible(IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
Definition: section.c:117
static NTSTATUS MmGetFileNameForFileObject(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1640
NTSTATUS NTAPI NtExtendSection(IN HANDLE SectionHandle, IN OUT PLARGE_INTEGER NewMaximumSize)
Definition: section.c:3518
#define PAGED_CODE()
#define ALIGN_DOWN_BY(size, align)
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
ULONG_PTR PFN_NUMBER
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
unsigned char BOOLEAN
Definition: actypes.h:127
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define CHAR(Char)
#define MAXULONG_PTR
Definition: basetsd.h:97
#define MAXLONG_PTR
Definition: basetsd.h:98
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:502
#define MM_READWRITE
Definition: bootanim.c:19
#define MM_READONLY
Definition: bootanim.c:18
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
Definition: File.h:16
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define RtlClearBits
Definition: dbgbitmap.h:331
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlClearAllBits
Definition: dbgbitmap.h:329
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
#define RTL_BITMAP
Definition: dbgbitmap.h:323
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
VOID NTAPI DbgkMapViewOfSection(IN PVOID Section, IN PVOID BaseAddress, IN ULONG SectionOffset, IN ULONG_PTR ViewSize)
Definition: dbgkutil.c:380
#define SIZE_T_MAX
Definition: dhcpd.h:91
#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:33
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
static int Hash(const char *)
Definition: reader.c:2237
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
#define ExGetPreviousMode
Definition: ex.h:143
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1369
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
ULONG Handle
Definition: gdb_input.c:15
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 const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL KeReleaseGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:75
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
VOID FASTCALL KeAcquireGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:64
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:167
#define PROCESS_VM_OPERATION
Definition: pstypes.h:161
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:211
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
#define MM_EXECUTE_WRITECOPY
Definition: miarm.h:50
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:537
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:834
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:386
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:403
ULONG MmSecondaryColorMask
Definition: mminit.c:258
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1105
#define MM_GUARDPAGE
Definition: miarm.h:57
PMMVAD NTAPI MiLocateVad(_In_ PMM_AVL_TABLE Table, _In_ PVOID VirtualAddress)
Definition: vadnode.c:116
ULONG NTAPI MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress, IN KIRQL OldIrql)
Definition: virtual.c:235
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:208
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree(IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base)
Definition: vadnode.c:711
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:185
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:611
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:236
#define MM_NOCACHE
Definition: miarm.h:56
#define MM_DELETE_CHECK
Definition: miarm.h:260
#define MM_EXECUTE_READWRITE
Definition: miarm.h:49
#define _64K
Definition: miarm.h:23
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1301
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1025
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:265
#define MM_EXECUTE
Definition: miarm.h:45
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1246
#define MM_EXECUTE_READ
Definition: miarm.h:46
@ MiWriteCombined
Definition: miarm.h:416
@ MiCached
Definition: miarm.h:415
@ MiNonCached
Definition: miarm.h:414
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:1000
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:4608
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:265
#define SYSTEM_PD_SIZE
Definition: miarm.h:32
#define MM_NOACCESS
Definition: miarm.h:65
NTSTATUS NTAPI MiInsertVadEx(_Inout_ PMMVAD Vad, _In_ ULONG_PTR *BaseAddress, _In_ SIZE_T ViewSize, _In_ ULONG_PTR HighestAddress, _In_ ULONG_PTR Alignment, _In_ ULONG AllocationType)
Definition: vadnode.c:245
VOID NTAPI MiDeleteVirtualAddresses(_In_ ULONG_PTR Va, _In_ ULONG_PTR EndingAddress, _In_opt_ PMMVAD Vad)
Definition: virtual.c:530
struct _MMVIEW MMVIEW
NTSTATUS NTAPI MiCheckSecuredVad(IN PMMVAD Vad, IN PVOID Base, IN SIZE_T Size, IN ULONG ProtectionMask)
Definition: vadnode.c:815
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:985
NTSTATUS NTAPI MiRosUnmapViewOfSection(_In_ PEPROCESS Process, _In_ PMEMORY_AREA MemoryArea, _In_ PVOID BaseAddress, _In_ BOOLEAN SkipDebuggerNotify)
Definition: section.c:3626
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1581
SIZE_T MmSizeOfPagedPoolInBytes
Definition: miarm.h:590
#define MM_WRITECOPY
Definition: miarm.h:48
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1176
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned __int64 ULONG64
Definition: imports.h:198
#define SECTION
Definition: profile.c:31
struct _MMPTE MMPTE
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT InheritDisposition
Definition: mmfuncs.h:409
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:363
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:405
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:364
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG AllocationType
Definition: mmfuncs.h:410
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
struct _SUBSECTION * PSUBSECTION
@ VadWriteWatch
Definition: mmtypes.h:208
@ VadRotatePhysical
Definition: mmtypes.h:210
@ VadImageMap
Definition: mmtypes.h:206
@ VadNone
Definition: mmtypes.h:204
struct _SUBSECTION SUBSECTION
#define SEC_NOCACHE
Definition: mmtypes.h:101
struct _SEGMENT SEGMENT
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SEC_IMAGE
Definition: mmtypes.h:97
#define MEM_DOS_LIM
Definition: mmtypes.h:90
struct _MSUBSECTION MSUBSECTION
#define SEC_LARGE_PAGES
Definition: mmtypes.h:103
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
struct _SECTION * PSECTION
struct _CONTROL_AREA CONTROL_AREA
@ ActiveAndValid
Definition: mmtypes.h:159
@ ModifiedPageList
Definition: mmtypes.h:156
@ StandbyPageList
Definition: mmtypes.h:155
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
_In_ PMEMORY_AREA MemoryArea
Definition: newmm.h:207
#define _Outptr_result_bytebuffer_(s)
Definition: no_sal2.h:288
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define MEM_TOP_DOWN
Definition: nt_native.h:1324
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1293
#define PAGE_WRITECOPY
Definition: nt_native.h:1308
#define SECTION_MAP_WRITE
Definition: nt_native.h:1291
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
#define PAGE_NOCACHE
Definition: nt_native.h:1314
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1310
#define PAGE_EXECUTE
Definition: nt_native.h:1309
#define SEC_RESERVE
Definition: nt_native.h:1326
enum _SECTION_INHERIT SECTION_INHERIT
#define FILE_EXECUTE
Definition: nt_native.h:642
@ ViewUnmap
Definition: nt_native.h:1282
@ ViewShare
Definition: nt_native.h:1281
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1312
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SECTION_EXTEND_SIZE
Definition: nt_native.h:1294
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MEM_LARGE_PAGES
Definition: nt_native.h:1325
#define PAGE_NOACCESS
Definition: nt_native.h:1305
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311
#define PAGE_GUARD
Definition: nt_native.h:1313
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:331
#define SEC_BASED
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1653
#define MI_IS_PAGE_DIRTY(x)
Definition: mm.h:112
#define MiAddressToPte(x)
Definition: mm.h:145
#define MI_MAX_ZERO_BITS
Definition: mm.h:83
FORCEINLINE PMMPDE MiPdeToPpe(PMMPDE PointerPde)
Definition: mm.h:292
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, IN PMMPTE PointerPte)
Definition: mm.h:342
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
#define MiProtoPteToPte(x)
Definition: mm.h:316
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:306
#define MiAddressToPde(x)
Definition: mm.h:156
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToPde(_Pte)
Definition: mm.h:121
#define PDE_PER_PAGE
Definition: mm.h:21
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:535
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace(VOID)
Definition: mm.h:1723
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1046
#define MI_SET_PROCESS2(x)
Definition: mm.h:329
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:344
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1695
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:1042
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:61
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:97
struct _MEMORY_AREA * PMEMORY_AREA
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1708
#define MI_SET_USAGE(x)
Definition: mm.h:327
NTSTATUS NTAPI MmExtendSection(_In_ PVOID Section, _Inout_ PLARGE_INTEGER NewSize)
Definition: section.c:5445
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
#define MI_IS_MEMORY_AREA_VAD(Vad)
Definition: mm.h:271
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define MI_IS_ROSMM_VAD(Vad)
Definition: mm.h:273
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
SIZE_T MmSharedCommit
Definition: freelist.c:31
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1730
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
PMMPDE MmSystemPagePtes
Definition: init.c:41
PVOID MiSessionViewStart
Definition: init.c:30
ULONG MmSessionViewSize
Definition: init.c:35
ULONG MmSystemViewSize
Definition: init.c:39
PVOID MmSessionBase
Definition: init.c:33
PVOID MiSystemViewStart
Definition: init.c:38
PVOID MiSessionSpaceEnd
Definition: init.c:27
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
MMPTE ValidKernelPdeLocal
Definition: init.c:32
MMPTE ValidKernelPde
Definition: init.c:28
POBJECT_TYPE PsProcessType
Definition: process.c:20
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:361
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:651
#define STATUS_MAPPED_ALIGNMENT
Definition: ntstatus.h:798
#define STATUS_SECTION_PROTECTION
Definition: ntstatus.h:408
#define STATUS_INVALID_PARAMETER_10
Definition: ntstatus.h:578
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:403
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:355
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:577
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:572
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:363
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:570
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:362
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:574
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:354
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:399
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:394
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:569
#define STATUS_INVALID_PARAMETER_8
Definition: ntstatus.h:576
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:571
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:192
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:573
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:542
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184
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
TCHAR ModuleFileName[MAX_PATH+1]
Definition: rundll32.c:56
#define _WARN(msg)
Definition: debug.h:263
#define ProbeForWriteLargeInteger(Ptr)
Definition: probe.h:46
#define ProbeForWritePointer(Ptr)
Definition: probe.h:42
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define ProbeForWriteSize_t(Ptr)
Definition: probe.h:45
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
NTSTATUS NTAPI MmMapViewInSystemSpace(IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:4498
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:4027
NTSTATUS NTAPI MmCreateSection(OUT PVOID *Section, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: section.c:4671
POBJECT_TYPE MmSectionObjectType
Definition: section.c:192
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
static void Exit(void)
Definition: sock.c:1330
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
base of all file and directory entries
Definition: entries.h:83
UNICODE_STRING SectionFileName
Definition: mmtypes.h:326
PSEGMENT Segment
Definition: mmtypes.h:521
ULONG NumberOfSectionReferences
Definition: mmtypes.h:523
PEVENT_COUNTER WaitingForDeletion
Definition: mmtypes.h:534
ULONG NumberOfMappedViews
Definition: mmtypes.h:525
ULONG NumberOfUserReferences
Definition: mmtypes.h:527
ULONG LongFlags
Definition: mmtypes.h:530
ULONG WritableUserReferences
Definition: mmtypes.h:537
MMSECTION_FLAGS Flags
Definition: mmtypes.h:531
PFILE_OBJECT FilePointer
Definition: mmtypes.h:533
union _CONTROL_AREA::@2781 u
LIST_ENTRY DereferenceList
Definition: mmtypes.h:522
ULONG PageFrameNumber
Definition: mmtypes.h:74
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG Type
Definition: mm.h:257
struct _MEMORY_AREA::@1913 SectionData
ULONG_PTR StartingVpn
Definition: mmtypes.h:653
ULONG_PTR EndingVpn
Definition: mmtypes.h:654
USHORT PrototypePte
Definition: mm.h:373
USHORT Modified
Definition: mm.h:370
USHORT PageLocation
Definition: mm.h:375
Definition: mm.h:390
MMPTE OriginalPte
Definition: mm.h:426
union _MMPFN::@1914 u1
MMPFNENTRY e1
Definition: mm.h:413
PKEVENT Event
Definition: mm.h:395
USHORT ReferenceCount
Definition: mm.h:412
union _MMPFN::@1916 u3
ULONG64 Dirty
Definition: mmtypes.h:164
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
ULONG64 Protection
Definition: mmtypes.h:88
ULONG64 Prototype
Definition: mmtypes.h:89
union _MMPTE::@2499 u
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG PhysicalMemory
Definition: mmtypes.h:473
ULONG BeingDeleted
Definition: mmtypes.h:463
ULONG NoChange
Definition: mmtypes.h:486
ULONG UserReference
Definition: mmtypes.h:479
ULONG CopyOnWrite
Definition: mmtypes.h:474
ULONG FilePointerNull
Definition: mmtypes.h:482
ULONG WriteCombined
Definition: mmtypes.h:493
ULONG BeingCreated
Definition: mmtypes.h:464
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:491
ULONG WasPurged
Definition: mmtypes.h:478
ULONG UserWritable
Definition: mmtypes.h:489
ULONG SystemSpaceHashKey
Definition: miarm.h:460
ULONG SystemSpaceHashEntries
Definition: miarm.h:459
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:455
PRTL_BITMAP SystemSpaceBitMap
Definition: miarm.h:462
PCHAR SystemSpaceViewStart
Definition: miarm.h:456
ULONG SystemSpaceHashSize
Definition: miarm.h:458
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:457
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:454
ULONG FileOffset
Definition: mmtypes.h:706
ULONG Inherit
Definition: mmtypes.h:713
ULONG SecNoChange
Definition: mmtypes.h:707
ULONG_PTR NoChange
Definition: mmtypes.h:693
ULONG_PTR Protection
Definition: mmtypes.h:696
ULONG_PTR CommitCharge
Definition: mmtypes.h:691
ULONG_PTR VadType
Definition: mmtypes.h:694
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
union _MMVAD_LONG::@2794 u4
PMMPTE LastContiguousPte
Definition: mmtypes.h:767
PMMPTE FirstPrototypePte
Definition: mmtypes.h:766
PVOID Banked
Definition: mmtypes.h:780
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
union _MMVAD_LONG::@2791 u
union _MMVAD_LONG::@2792 u2
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
union _MMVAD::@2788 u
Definition: miarm.h:447
PCONTROL_AREA ControlArea
Definition: miarm.h:449
ULONG_PTR Entry
Definition: miarm.h:448
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:484
PMMPDE PageTables
Definition: miarm.h:511
MMSESSION Session
Definition: miarm.h:501
SIZE_T CommittedPages
Definition: miarm.h:486
SIZE_T NonPageablePages
Definition: miarm.h:485
UNICODE_STRING Name
Definition: nt_native.h:1273
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
ULONG LongFlags
Definition: mmtypes.h:816
union _SECTION::@2797 u
PSEGMENT Segment
Definition: mmtypes.h:812
ULONG InitialPageProtection
Definition: mmtypes.h:819
MMADDRESS_NODE Address
Definition: mmtypes.h:811
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:813
ULONG LargePages
Definition: mmtypes.h:403
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:409
PEPROCESS CreatingProcess
Definition: mmtypes.h:422
ULONG TotalNumberOfPtes
Definition: mmtypes.h:410
PVOID BasedAddress
Definition: mmtypes.h:418
MMPTE SegmentPteTemplate
Definition: mmtypes.h:414
PMMPTE PrototypePte
Definition: mmtypes.h:429
MMPTE ThePtes[1]
Definition: mmtypes.h:430
ULONGLONG SizeOfSegment
Definition: mmtypes.h:413
union _SEGMENT::@2779 u1
ULONG NonExtendedPtes
Definition: mmtypes.h:411
ULONG NumberOfCommittedPages
Definition: mmtypes.h:415
ULONG PtesInSubsection
Definition: mmtypes.h:583
union _SUBSECTION::@2783 u
MMSUBSECTION_FLAGS SubsectionFlags
Definition: mmtypes.h:577
PCONTROL_AREA ControlArea
Definition: mmtypes.h:573
PMMPTE SubsectionBase
Definition: mmtypes.h:581
struct _SUBSECTION * NextSubsection
Definition: mmtypes.h:584
#define TAG_MM
Definition: tag.h:112
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#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
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ALIGN_DOWN_POINTER_BY(ptr, align)
Definition: umtypes.h:82
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
static BOOL Attached
Definition: vidbios.c:3905
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
* PFILE_OBJECT
Definition: iotypes.h:1998
_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
KAPC_STATE
Definition: ketypes.h:1711
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492
#define BYTES_TO_PAGES(Size)
#define PAGE_ALIGN(Va)
_In_ BOOLEAN DelayClose
Definition: mmfuncs.h:592
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define NT_ASSERT
Definition: rtlfuncs.h:3327
NTSYSAPI VOID NTAPI RtlFillMemoryUlonglong(_Out_writes_bytes_all_(Length) PVOID Destination, _In_ SIZE_T Length, _In_ ULONGLONG Pattern)
char CHAR
Definition: xmlstorage.h:175
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:221