ReactOS 0.4.16-dev-329-g9223134
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 Entry, Hash, i, HashSize;
294 PMMVIEW OldTable;
295 PAGED_CODE();
296
297 /* Stay within 4GB */
299
300 /* Lock system space */
301 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
302
303 /* Check if we're going to exhaust hash entries */
304 if ((Session->SystemSpaceHashEntries + 8) > Session->SystemSpaceHashSize)
305 {
306 /* Double the hash size */
307 HashSize = Session->SystemSpaceHashSize * 2;
308
309 /* Save the old table and allocate a new one */
310 OldTable = Session->SystemSpaceViewTable;
311 Session->SystemSpaceViewTable = ExAllocatePoolWithTag(Session ==
312 &MmSession ?
314 PagedPool,
315 HashSize *
316 sizeof(MMVIEW),
317 TAG_MM);
318 if (!Session->SystemSpaceViewTable)
319 {
320 /* Failed to allocate a new table, keep the old one for now */
321 Session->SystemSpaceViewTable = OldTable;
322 }
323 else
324 {
325 /* Clear the new table and set the new ahsh and key */
326 RtlZeroMemory(Session->SystemSpaceViewTable, HashSize * sizeof(MMVIEW));
327 Session->SystemSpaceHashSize = HashSize;
328 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
329
330 /* Loop the old table */
331 for (i = 0; i < Session->SystemSpaceHashSize / 2; i++)
332 {
333 /* Check if the entry was valid */
334 if (OldTable[i].Entry)
335 {
336 /* Re-hash the old entry and search for space in the new table */
337 Hash = (OldTable[i].Entry >> 16) % Session->SystemSpaceHashKey;
338 while (Session->SystemSpaceViewTable[Hash].Entry)
339 {
340 /* Loop back at the beginning if we had an overflow */
341 if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
342 }
343
344 /* Write the old entry in the new table */
345 Session->SystemSpaceViewTable[Hash] = OldTable[i];
346 }
347 }
348
349 /* Free the old table */
350 ExFreePool(OldTable);
351 }
352 }
353
354 /* Check if we ran out */
355 if (Session->SystemSpaceHashEntries == Session->SystemSpaceHashSize)
356 {
357 DPRINT1("Ran out of system view hash entries\n");
358 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
359 return NULL;
360 }
361
362 /* Find space where to map this view */
363 i = RtlFindClearBitsAndSet(Session->SystemSpaceBitMap, Buckets, 0);
364 if (i == 0xFFFFFFFF)
365 {
366 /* Out of space, fail */
367 Session->BitmapFailures++;
368 DPRINT1("Out of system view space\n");
369 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
370 return NULL;
371 }
372
373 /* Compute the base address */
374 Base = (PVOID)((ULONG_PTR)Session->SystemSpaceViewStart + (i * MI_SYSTEM_VIEW_BUCKET_SIZE));
375
376 /* Get the hash entry for this allocation */
377 Entry = ((ULONG_PTR)Base & ~(MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) + Buckets;
378 Hash = (Entry >> 16) % Session->SystemSpaceHashKey;
379
380 /* Loop hash entries until a free one is found */
381 while (Session->SystemSpaceViewTable[Hash].Entry)
382 {
383 /* Unless we overflow, in which case loop back at hash o */
384 if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
385 }
386
387 /* Add this entry into the hash table */
388 Session->SystemSpaceViewTable[Hash].Entry = Entry;
389 Session->SystemSpaceViewTable[Hash].ControlArea = ControlArea;
390
391 /* Hash entry found, increment total and return the base address */
392 Session->SystemSpaceHashEntries++;
393 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
394 return Base;
395}
396
397static
400 IN PFN_NUMBER PteCount,
401 IN PCONTROL_AREA ControlArea,
403{
405 PMMPTE PointerPte, ProtoPte, LastProtoPte, LastPte;
406 PSUBSECTION Subsection;
407
408 /* Mapping at offset not supported yet */
409 ASSERT(SectionOffset == 0);
410
411 /* ARM3 doesn't support this yet */
412 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
413 ASSERT(ControlArea->u.Flags.Rom == 0);
414 ASSERT(ControlArea->FilePointer == NULL);
415
416 /* Sanity checks */
417 ASSERT(PteCount != 0);
418 ASSERT(ControlArea->NumberOfMappedViews >= 1);
419 ASSERT(ControlArea->NumberOfUserReferences >= 1);
420 ASSERT(ControlArea->NumberOfSectionReferences != 0);
421 ASSERT(ControlArea->u.Flags.BeingCreated == 0);
422 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
423 ASSERT(ControlArea->u.Flags.BeingPurged == 0);
424
425 /* Get the PTEs for the actual mapping */
426 PointerPte = FirstPte;
427 LastPte = FirstPte + PteCount;
428
429 /* Get the prototype PTEs that desribe the section mapping in the subsection */
430 Subsection = (PSUBSECTION)(ControlArea + 1);
431 ProtoPte = Subsection->SubsectionBase;
432 LastProtoPte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
433
434 /* Loop the PTEs for the mapping */
435 while (PointerPte < LastPte)
436 {
437 /* We may have run out of prototype PTEs in this subsection */
438 if (ProtoPte >= LastProtoPte)
439 {
440 /* But we don't handle this yet */
441 ASSERT(FALSE);
442 }
443
444 /* The PTE should be completely clear */
445 ASSERT(PointerPte->u.Long == 0);
446
447 /* Build the prototype PTE and write it */
448 MI_MAKE_PROTOTYPE_PTE(&TempPte, ProtoPte);
449 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
450
451 /* Keep going */
452 PointerPte++;
453 ProtoPte++;
454 }
455
456 /* No failure path */
457 return STATUS_SUCCESS;
458}
459
460VOID
461NTAPI
464{
465 PMMPDE PointerPde, LastPde, SystemMapPde;
467 PFN_NUMBER PageFrameIndex, ParentPage;
469 PAGED_CODE();
470
471 /* Find the PDEs needed for this mapping */
472 PointerPde = MiAddressToPde(Base);
473 LastPde = MiAddressToPde((PVOID)((ULONG_PTR)Base + NumberOfBytes - 1));
474
475#if (_MI_PAGING_LEVELS == 2)
476 /* Find the system double-mapped PDE that describes this mapping */
477 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
478#else
479 /* We don't have a double mapping */
480 SystemMapPde = PointerPde;
481#endif
482
483 /* Use the PDE template and loop the PDEs */
485 while (PointerPde <= LastPde)
486 {
487 /* Lock the PFN database */
488 OldIrql = MiAcquirePfnLock();
489
490 /* Check if we don't already have this PDE mapped */
491 if (SystemMapPde->u.Hard.Valid == 0)
492 {
493 /* Grab a page for it */
495 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
496 PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
497 ASSERT(PageFrameIndex);
498 TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
499
500#if (_MI_PAGING_LEVELS == 2)
501 ParentPage = MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_PER_PAGE];
502#else
503 ParentPage = MiPdeToPpe(PointerPde)->u.Hard.PageFrameNumber;
504#endif
505 /* Initialize its PFN entry, with the parent system page directory page table */
506 MiInitializePfnForOtherProcess(PageFrameIndex,
507 (PMMPTE)PointerPde,
508 ParentPage);
509
510 /* Make the system PDE entry valid */
511 MI_WRITE_VALID_PDE(SystemMapPde, TempPde);
512
513 /* The system PDE entry might be the PDE itself, so check for this */
514 if (PointerPde->u.Hard.Valid == 0)
515 {
516 /* It's different, so make the real PDE valid too */
517 MI_WRITE_VALID_PDE(PointerPde, TempPde);
518 }
519 }
520
521 /* Release the lock and keep going with the next PDE */
522 MiReleasePfnLock(OldIrql);
523 SystemMapPde++;
524 PointerPde++;
525 }
526}
527
528static
531 IN BOOLEAN FailIfSystemViews)
532{
534
535 /* Flag not yet supported */
536 ASSERT(FailIfSystemViews == FALSE);
537
538 /* Lock the PFN database */
539 OldIrql = MiAcquirePfnLock();
540
541 /* State not yet supported */
542 ASSERT(ControlArea->u.Flags.BeingPurged == 0);
543
544 /* Increase the reference counts */
545 ControlArea->NumberOfMappedViews++;
546 ControlArea->NumberOfUserReferences++;
547 ASSERT(ControlArea->NumberOfSectionReferences != 0);
548
549 /* Release the PFN lock and return success */
550 MiReleasePfnLock(OldIrql);
551 return STATUS_SUCCESS;
552}
553
555NTAPI
557 IN ULONG_PTR Vpn)
558{
559 PSUBSECTION Subsection;
560 PCONTROL_AREA ControlArea;
561 ULONG_PTR PteOffset;
562
563 /* Get the control area */
564 ControlArea = Vad->ControlArea;
565 ASSERT(ControlArea->u.Flags.Rom == 0);
566 ASSERT(ControlArea->u.Flags.Image == 0);
567 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
568
569 /* Get the subsection */
570 Subsection = (PSUBSECTION)(ControlArea + 1);
571
572 /* We only support single-subsection segments */
573 ASSERT(Subsection->SubsectionBase != NULL);
574 ASSERT(Vad->FirstPrototypePte >= Subsection->SubsectionBase);
575 ASSERT(Vad->FirstPrototypePte < &Subsection->SubsectionBase[Subsection->PtesInSubsection]);
576
577 /* Compute the PTE offset */
578 PteOffset = Vpn - Vad->StartingVpn;
579 PteOffset += Vad->FirstPrototypePte - Subsection->SubsectionBase;
580
581 /* Again, we only support single-subsection segments */
582 ASSERT(PteOffset < 0xF0000000);
583 ASSERT(PteOffset < Subsection->PtesInSubsection);
584
585 /* Return the subsection */
586 return Subsection;
587}
588
589static
590VOID
592{
593 PCONTROL_AREA ControlArea;
594 SEGMENT_FLAGS SegmentFlags;
595 PSUBSECTION Subsection;
596 PMMPTE PointerPte, LastPte, PteForProto;
597 PMMPFN Pfn1;
598 PFN_NUMBER PageFrameIndex;
601
602 /* Capture data */
603 SegmentFlags = Segment->SegmentFlags;
604 ControlArea = Segment->ControlArea;
605
606 /* Make sure control area is on the right delete path */
607 ASSERT(ControlArea->u.Flags.BeingDeleted == 1);
608 ASSERT(ControlArea->WritableUserReferences == 0);
609
610 /* These things are not supported yet */
611 ASSERT(ControlArea->DereferenceList.Flink == NULL);
612 ASSERT(!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File));
613 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
614 ASSERT(ControlArea->u.Flags.Rom == 0);
615
616 /* Get the subsection and PTEs for this segment */
617 Subsection = (PSUBSECTION)(ControlArea + 1);
618 PointerPte = Subsection->SubsectionBase;
619 LastPte = PointerPte + Segment->NonExtendedPtes;
620
621 /* Lock the PFN database */
622 OldIrql = MiAcquirePfnLock();
623
624 /* Check if the master PTE is invalid */
625 PteForProto = MiAddressToPte(PointerPte);
626 if (!PteForProto->u.Hard.Valid)
627 {
628 /* Fault it in */
630 }
631
632 /* Loop all the segment PTEs */
633 while (PointerPte < LastPte)
634 {
635 /* Check if it's time to switch master PTEs if we passed a PDE boundary */
636 if (MiIsPteOnPdeBoundary(PointerPte) &&
637 (PointerPte != Subsection->SubsectionBase))
638 {
639 /* Check if the master PTE is invalid */
640 PteForProto = MiAddressToPte(PointerPte);
641 if (!PteForProto->u.Hard.Valid)
642 {
643 /* Fault it in */
645 }
646 }
647
648 /* This should be a prototype PTE */
649 TempPte = *PointerPte;
650 ASSERT(SegmentFlags.LargePages == 0);
651 ASSERT(TempPte.u.Hard.Valid == 0);
652
653 /* See if we should clean things up */
654 if (!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File))
655 {
656 /*
657 * This is a section backed by the pagefile. Now that it doesn't exist anymore,
658 * we can give everything back to the system.
659 */
660 ASSERT(TempPte.u.Soft.Prototype == 0);
661
662 if (TempPte.u.Soft.Transition == 1)
663 {
664 /* We can give the page back for other use */
665 DPRINT("Releasing page for transition PTE %p\n", PointerPte);
666 PageFrameIndex = PFN_FROM_PTE(&TempPte);
667 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
668
669 /* As this is a paged-backed section, nobody should reference it anymore (no cache or whatever) */
670 ASSERT(Pfn1->u3.ReferenceCount == 0);
671
672 /* And it should be in standby or modified list */
674
675 /* Unlink it and put it back in free list */
677
678 /* Temporarily mark this as active and make it free again */
680 MI_SET_PFN_DELETED(Pfn1);
681
682 MiInsertPageInFreeList(PageFrameIndex);
683 }
684 else if (TempPte.u.Soft.PageFileHigh != 0)
685 {
686 /* Should not happen for now */
687 ASSERT(FALSE);
688 }
689 }
690 else
691 {
692 /* unsupported for now */
693 ASSERT(FALSE);
694
695 /* File-backed section must have prototype PTEs */
696 ASSERT(TempPte.u.Soft.Prototype == 1);
697 }
698
699 /* Zero the PTE and keep going */
700 PointerPte->u.Long = 0;
701 PointerPte++;
702 }
703
704 /* Release the PFN lock */
705 MiReleasePfnLock(OldIrql);
706
707 /* Free the structures */
708 ExFreePool(ControlArea);
710}
711
712static
713VOID
716{
717 BOOLEAN DeleteSegment = FALSE;
719
720 /* Check if this is the last reference or view */
721 if (!(ControlArea->NumberOfMappedViews) &&
722 !(ControlArea->NumberOfSectionReferences))
723 {
724 /* There should be no more user references either */
725 ASSERT(ControlArea->NumberOfUserReferences == 0);
726
727 /* Not yet supported */
728 ASSERT(ControlArea->FilePointer == NULL);
729
730 /* The control area is being destroyed */
731 ControlArea->u.Flags.BeingDeleted = TRUE;
732 DeleteSegment = TRUE;
733 }
734
735 /* Release the PFN lock */
736 MiReleasePfnLock(OldIrql);
737
738 /* Delete the segment if needed */
739 if (DeleteSegment)
740 {
741 /* No more user write references at all */
742 ASSERT(ControlArea->WritableUserReferences == 0);
743 MiSegmentDelete(ControlArea->Segment);
744 }
745}
746
747static
748VOID
750{
752
753 /* Lock the PFN database */
754 OldIrql = MiAcquirePfnLock();
755
756 /* Drop reference counts */
757 ControlArea->NumberOfMappedViews--;
758 ControlArea->NumberOfUserReferences--;
759
760 /* Check if it's time to delete the CA. This releases the lock */
761 MiCheckControlArea(ControlArea, OldIrql);
762}
763
764VOID
765NTAPI
767 IN PMMVAD Vad)
768{
770 PCONTROL_AREA ControlArea;
771 PETHREAD CurrentThread = PsGetCurrentThread();
772
773 /* Get the control area */
774 ControlArea = Vad->ControlArea;
775
776 /* We only support non-extendable, non-image, pagefile-backed regular sections */
777 ASSERT(Vad->u.VadFlags.VadType == VadNone);
778 ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
779 ASSERT(ControlArea);
780 ASSERT(ControlArea->FilePointer == NULL);
781
782 /* Delete the actual virtual memory pages */
783 MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
784 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
785 Vad);
786
787 /* Release the working set */
788 MiUnlockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
789
790 /* Lock the PFN database */
791 OldIrql = MiAcquirePfnLock();
792
793 /* Remove references */
794 ControlArea->NumberOfMappedViews--;
795 ControlArea->NumberOfUserReferences--;
796
797 /* Check if it should be destroyed */
798 MiCheckControlArea(ControlArea, OldIrql);
799}
800
801static
805 IN ULONG Flags)
806{
810 PMMVAD Vad;
811 PVOID DbgBase = NULL;
814 PETHREAD CurrentThread = PsGetCurrentThread();
815 PEPROCESS CurrentProcess = PsGetCurrentProcess();
816 PAGED_CODE();
817
818 /* Check if we need to lock the address space */
819 if (!Flags) MmLockAddressSpace(&Process->Vm);
820
821 /* Check for Mm Region */
824 {
825 /* Call Mm API */
828 return Status;
829 }
830
831 /* Check if we should attach to the process */
832 if (CurrentProcess != Process)
833 {
834 /* The process is different, do an attach */
836 Attached = TRUE;
837 }
838
839 /* Check if the process is already dead */
840 if (Process->VmDeleted)
841 {
842 /* Fail the call */
843 DPRINT1("Process died!\n");
846 goto Quickie;
847 }
848
849 /* Find the VAD for the address and make sure it's a section VAD */
851 if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
852 {
853 /* Couldn't find it, or invalid VAD, fail */
854 DPRINT1("No VAD or invalid VAD\n");
857 goto Quickie;
858 }
859
860 /* We should be attached */
862
863 /* We need the base address for the debugger message on image-backed VADs */
864 if (Vad->u.VadFlags.VadType == VadImageMap)
865 {
866 DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
867 }
868
869 /* Compute the size of the VAD region */
870 RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
871
872 /* For SEC_NO_CHANGE sections, we need some extra checks */
873 if (Vad->u.VadFlags.NoChange == 1)
874 {
875 /* Are we allowed to mess with this VAD? */
877 (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
880 if (!NT_SUCCESS(Status))
881 {
882 /* We failed */
883 DPRINT1("Trying to unmap protected VAD!\n");
885 goto Quickie;
886 }
887 }
888
889 /* Not currently supported */
891
892 /* FIXME: Remove VAD charges */
893
894 /* Lock the working set */
896
897 /* Remove the VAD */
898 ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
899 MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
901
902 /* Remove the PTEs for this view, which also releases the working set lock */
904
905 /* FIXME: Remove commitment */
906
907 /* Update performance counter and release the lock */
908 Process->VirtualSize -= RegionSize;
910
911 /* Destroy the VAD and return success */
912 ExFreePool(Vad);
914
915 /* Failure and success case -- send debugger message, detach, and return */
916Quickie:
917 if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
919 return Status;
920}
921
922static
925 IN PVOID EndVa)
926{
929 PMMPDE StartPde, EndPde;
931 PMMPFN Pfn1;
932 PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
933
934 /* Windows sanity checks */
935 ASSERT(StartVa >= (PVOID)MmSessionBase);
937 ASSERT(PAGE_ALIGN(EndVa) == EndVa);
938
939 /* Get the start and end PDE, then loop each one */
940 StartPde = MiAddressToPde(StartVa);
941 EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
942 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
943 while (StartPde <= EndPde)
944 {
945#ifndef _M_AMD64
946 /* If we don't already have a page table for it, increment count */
947 if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
948#endif
949 /* Move to the next one */
950 StartPde++;
951 Index++;
952 }
953
954 /* If there's no page tables to create, bail out */
955 if (PageCount == 0) return STATUS_SUCCESS;
956
957 /* Reset the start PDE and index */
958 StartPde = MiAddressToPde(StartVa);
959 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
960
961 /* Loop each PDE while holding the working set lock */
962// MiLockWorkingSet(PsGetCurrentThread(),
963// &MmSessionSpace->GlobalVirtualAddress->Vm);
964#ifdef _M_AMD64
965_WARN("MiSessionCommitPageTables halfplemented for amd64")
970 DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
971 ASSERT(FALSE);
972#else
973 while (StartPde <= EndPde)
974 {
975 /* Check if we already have a page table */
977 {
978 /* We don't, so the PDE shouldn't be ready yet */
979 ASSERT(StartPde->u.Hard.Valid == 0);
980
981 /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
983
984 /* Acquire the PFN lock and grab a zero page */
985 OldIrql = MiAcquirePfnLock();
987 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
989 PageFrameNumber = MiRemoveZeroPage(Color);
990 TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
991 MI_WRITE_VALID_PDE(StartPde, TempPde);
992
993 /* Write the page table in session space structure */
996
997 /* Initialize the PFN */
998 MiInitializePfnForOtherProcess(PageFrameNumber,
999 StartPde,
1001
1002 /* And now release the lock */
1003 MiReleasePfnLock(OldIrql);
1004
1005 /* Get the PFN entry and make sure there's no event for it */
1006 Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1007 ASSERT(Pfn1->u1.Event == NULL);
1008
1009 /* Increment the number of pages */
1010 ActualPages++;
1011 }
1012
1013 /* Move to the next PDE */
1014 StartPde++;
1015 Index++;
1016 }
1017#endif
1018
1019 /* Make sure we didn't do more pages than expected */
1020 ASSERT(ActualPages <= PageCount);
1021
1022 /* Release the working set lock */
1023// MiUnlockWorkingSet(PsGetCurrentThread(),
1024// &MmSessionSpace->GlobalVirtualAddress->Vm);
1025
1026
1027 /* If we did at least one page... */
1028 if (ActualPages)
1029 {
1030 /* Update the performance counters! */
1033 }
1034
1035 /* Return status */
1036 return STATUS_SUCCESS;
1037}
1038
1041 _In_ PVOID Section,
1042 _In_ PMMSESSION Session,
1046{
1047 PVOID Base;
1048 PCONTROL_AREA ControlArea;
1049 ULONG Buckets;
1050 LONGLONG SectionSize;
1052 PAGED_CODE();
1053
1054 /* Get the control area, check for any flags ARM3 doesn't yet support */
1055 ControlArea = ((PSECTION)Section)->Segment->ControlArea;
1056 ASSERT(ControlArea->u.Flags.Image == 0);
1057 ASSERT(ControlArea->FilePointer == NULL);
1058 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1059 ASSERT(ControlArea->u.Flags.Rom == 0);
1060 ASSERT(ControlArea->u.Flags.WasPurged == 0);
1061
1062 /* Increase the reference and map count on the control area, no purges yet */
1063 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1065
1066 /* Get the section size at creation time */
1067 SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart;
1068
1069 /* If the caller didn't specify a view size, assume until the end of the section */
1070 if (!(*ViewSize))
1071 {
1072 /* Check for overflow first */
1073 if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX)
1074 {
1075 DPRINT1("Section end is too far away from the specified offset.\n");
1076 MiDereferenceControlArea(ControlArea);
1078 }
1079 *ViewSize = SectionSize - SectionOffset->QuadPart;
1080 }
1081
1082 /* Check overflow */
1083 if ((SectionOffset->QuadPart + *ViewSize) < SectionOffset->QuadPart)
1084 {
1085 DPRINT1("Integer overflow between size & offset!\n");
1086 MiDereferenceControlArea(ControlArea);
1088 }
1089
1090 /* Check if the caller wanted a larger section than the view */
1091 if (SectionOffset->QuadPart + *ViewSize > SectionSize)
1092 {
1093 /* Fail */
1094 DPRINT1("View is too large\n");
1095 MiDereferenceControlArea(ControlArea);
1097 }
1098
1099 /* Get the number of 64K buckets required for this mapping */
1101 if (*ViewSize & (MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) Buckets++;
1102
1103 /* Check if the view is more than 4GB large */
1104 if (Buckets >= MI_SYSTEM_VIEW_BUCKET_SIZE)
1105 {
1106 /* Fail */
1107 DPRINT1("View is too large\n");
1108 MiDereferenceControlArea(ControlArea);
1110 }
1111
1112 /* Insert this view into system space and get a base address for it */
1113 Base = MiInsertInSystemSpace(Session, Buckets, ControlArea);
1114 if (!Base)
1115 {
1116 /* Fail */
1117 DPRINT1("Out of system space\n");
1118 MiDereferenceControlArea(ControlArea);
1119 return STATUS_NO_MEMORY;
1120 }
1121
1122 /* What's the underlying session? */
1123 if (Session == &MmSession)
1124 {
1125 /* Create the PDEs needed for this mapping, and double-map them if needed */
1128 }
1129 else
1130 {
1131 /* Create the PDEs needed for this mapping */
1133 (PVOID)((ULONG_PTR)Base +
1134 Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
1136 }
1137
1138 /* Create the actual prototype PTEs for this mapping */
1141 ControlArea,
1142 SectionOffset->QuadPart);
1144
1145 /* Return the base address of the mapping and success */
1146 *MappedBase = Base;
1147 return STATUS_SUCCESS;
1148}
1149
1150static
1157 IN PSECTION Section,
1159 IN ULONG ProtectionMask,
1163{
1164 PMMVAD_LONG Vad;
1165 ULONG_PTR StartAddress;
1166 ULONG_PTR ViewSizeInPages;
1167 PSUBSECTION Subsection;
1169 PFN_NUMBER PteOffset;
1171 ULONG QuotaCharge = 0, QuotaExcess = 0;
1172 PMMPTE PointerPte, LastPte;
1173 MMPTE TempPte;
1174 ULONG Granularity = MM_VIRTMEM_GRANULARITY;
1175
1176 DPRINT("Mapping ARM3 data section\n");
1177
1178 /* Get the segment for this section */
1179 Segment = ControlArea->Segment;
1180
1181#ifdef _M_IX86
1182 /* ALlow being less restrictive on x86. */
1184 Granularity = PAGE_SIZE;
1185#endif
1186
1187 /* One can only reserve a file-based mapping, not shared memory! */
1188 if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1189 {
1191 }
1192
1193 /* First, increase the map count. No purging is supported yet */
1194 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1195 if (!NT_SUCCESS(Status)) return Status;
1196
1197 /* Check if the caller specified the view size */
1198 if (!(*ViewSize))
1199 {
1200 LONGLONG ViewSizeLL;
1201
1202 /* The caller did not, so pick a 64K aligned view size based on the offset */
1203 SectionOffset->LowPart &= ~(_64K - 1);
1204
1205 /* Calculate size and make sure this fits */
1206 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &ViewSizeLL))
1207 || !NT_SUCCESS(RtlLongLongToSIZET(ViewSizeLL, ViewSize))
1208 || (*ViewSize > MAXLONG_PTR))
1209 {
1210 MiDereferenceControlArea(ControlArea);
1212 }
1213 }
1214 else
1215 {
1216 /* A size was specified, align it to a 64K boundary
1217 * and check for overflow or huge value. */
1218 if (!NT_SUCCESS(RtlSIZETAdd(*ViewSize, SectionOffset->LowPart & (_64K - 1), ViewSize))
1219 || (*ViewSize > MAXLONG_PTR))
1220 {
1221 MiDereferenceControlArea(ControlArea);
1223 }
1224
1225 /* Align the offset as well to make this an aligned map */
1226 SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1227 }
1228
1229 /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1230 ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1231
1232 /* Windows ASSERTs for this flag */
1233 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1234
1235 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1236 ASSERT(ControlArea->u.Flags.Rom == 0);
1237 Subsection = (PSUBSECTION)(ControlArea + 1);
1238
1239 /* Sections with extended segments are not supported in ARM3 */
1240 ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1241
1242 /* Within this section, figure out which PTEs will describe the view */
1243 PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1244
1245 /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1246 ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1247 ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1248
1249 /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1250 ASSERT(PteOffset < Subsection->PtesInSubsection);
1251
1252 /* In ARM3, only page-file backed sections (shared memory) are supported now */
1253 ASSERT(ControlArea->FilePointer == NULL);
1254
1255 /* Windows ASSERTs for this too -- there must be a subsection base address */
1256 ASSERT(Subsection->SubsectionBase != NULL);
1257
1258 /* Compute how much commit space the segment will take */
1259 if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1260 {
1261 /* Charge for the maximum pages */
1262 QuotaCharge = BYTES_TO_PAGES(CommitSize);
1263 }
1264
1265 /* ARM3 does not currently support large pages */
1266 ASSERT(Segment->SegmentFlags.LargePages == 0);
1267
1268 /* Calculate how many pages the region spans */
1269 ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1270
1271 /* A VAD can now be allocated. Do so and zero it out */
1272 /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1273 ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1274 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1275 if (!Vad)
1276 {
1277 MiDereferenceControlArea(ControlArea);
1279 }
1280
1281 RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1282 Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1283
1284 /* Write all the data required in the VAD for handling a fault */
1285 Vad->ControlArea = ControlArea;
1286 Vad->u.VadFlags.CommitCharge = 0;
1287 Vad->u.VadFlags.Protection = ProtectionMask;
1288 Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1290 if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1291 {
1292 /* This isn't really implemented yet, but handle setting the flag */
1293 Vad->u.VadFlags.NoChange = 1;
1294 Vad->u2.VadFlags2.SecNoChange = 1;
1295 }
1296
1297 /* Finally, write down the first and last prototype PTE */
1298 Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1299 PteOffset += ViewSizeInPages - 1;
1300 ASSERT(PteOffset < Subsection->PtesInSubsection);
1301 Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1302
1303 /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1305
1306 /* FIXME: Should setup VAD bitmap */
1308
1309 /* Check if anything was committed */
1310 if (QuotaCharge)
1311 {
1312 /* Set the start and end PTE addresses, and pick the template PTE */
1313 PointerPte = Vad->FirstPrototypePte;
1314 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1315 TempPte = Segment->SegmentPteTemplate;
1316
1317 /* Acquire the commit lock and loop all prototype PTEs to be committed */
1319 while (PointerPte < LastPte)
1320 {
1321 /* Make sure the PTE is already invalid */
1322 if (PointerPte->u.Long == 0)
1323 {
1324 /* And write the invalid PTE */
1325 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1326 }
1327 else
1328 {
1329 /* The PTE is valid, so skip it */
1330 QuotaExcess++;
1331 }
1332
1333 /* Move to the next PTE */
1334 PointerPte++;
1335 }
1336
1337 /* Now check how many pages exactly we committed, and update accounting */
1338 ASSERT(QuotaCharge >= QuotaExcess);
1339 QuotaCharge -= QuotaExcess;
1340 Segment->NumberOfCommittedPages += QuotaCharge;
1341 ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1342
1343 /* Now that we're done, release the lock */
1345 }
1346
1347 /* Is it SEC_BASED, or did the caller manually specify an address? */
1348 if (*BaseAddress != NULL)
1349 {
1350 /* Just align what the caller gave us */
1351 StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1352 }
1353 else if (Section->Address.StartingVpn != 0)
1354 {
1355 /* It is a SEC_BASED mapping, use the address that was generated */
1356 StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1357 }
1358 else
1359 {
1360 StartAddress = 0;
1361 }
1362
1364 if (!NT_SUCCESS(Status))
1365 {
1366 ExFreePoolWithTag(Vad, 'ldaV');
1367 MiDereferenceControlArea(ControlArea);
1368
1370 Segment->NumberOfCommittedPages -= QuotaCharge;
1372 return Status;
1373 }
1374
1375 /* Insert the VAD */
1377 &StartAddress,
1378 ViewSizeInPages * PAGE_SIZE,
1380 Granularity,
1382 if (!NT_SUCCESS(Status))
1383 {
1384 ExFreePoolWithTag(Vad, 'ldaV');
1385 MiDereferenceControlArea(ControlArea);
1386
1388 Segment->NumberOfCommittedPages -= QuotaCharge;
1390
1392 return Status;
1393 }
1394
1395 /* Windows stores this for accounting purposes, do so as well */
1396 if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1397
1398 /* Finally, let the caller know where, and for what size, the view was mapped */
1399 *ViewSize = ViewSizeInPages * PAGE_SIZE;
1400 *BaseAddress = (PVOID)StartAddress;
1401 DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1402 return STATUS_SUCCESS;
1403}
1404
1405static
1412 IN ULONG IgnoreFileSizing)
1413{
1414 /* Not yet implemented */
1415 ASSERT(FALSE);
1416 *Segment = NULL;
1418}
1419
1420static
1424 IN ULONG ProtectionMask,
1426{
1427 ULONGLONG SizeLimit;
1428 PFN_COUNT PteCount;
1429 PMMPTE PointerPte;
1430 MMPTE TempPte;
1431 PCONTROL_AREA ControlArea;
1432 PSEGMENT NewSegment;
1433 PSUBSECTION Subsection;
1434 PAGED_CODE();
1435
1436 /* No large pages in ARM3 yet */
1438
1439 /* Pagefile-backed sections need a known size */
1440 if (!MaximumSize || !MaximumSize->QuadPart || MaximumSize->QuadPart < 0)
1442
1443 /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1444 SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
1445 SizeLimit /= sizeof(MMPTE);
1446 SizeLimit <<= PAGE_SHIFT;
1447
1448 /* Fail if this size is too big */
1449 if (MaximumSize->QuadPart > SizeLimit)
1450 {
1452 }
1453
1454 /* Calculate how many Prototype PTEs will be needed */
1455 PteCount = (PFN_COUNT)((MaximumSize->QuadPart + PAGE_SIZE - 1) >> PAGE_SHIFT);
1456
1457 /* For commited memory, we must have a valid protection mask */
1458 if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1459
1460 /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1461 NewSegment = ExAllocatePoolWithTag(PagedPool,
1462 sizeof(SEGMENT) +
1463 sizeof(MMPTE) * (PteCount - 1),
1464 'tSmM');
1465 if (!NewSegment)
1466 {
1468 }
1469 *Segment = NewSegment;
1470
1471 /* Now allocate the control area, which has the subsection structure */
1472 ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1473 sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1474 'tCmM');
1475 if (!ControlArea)
1476 {
1477 ExFreePoolWithTag(Segment, 'tSmM');
1479 }
1480
1481 /* And zero it out, filling the basic segmnet pointer and reference fields */
1482 RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1483 ControlArea->Segment = NewSegment;
1484 ControlArea->NumberOfSectionReferences = 1;
1485 ControlArea->NumberOfUserReferences = 1;
1486
1487 /* Convert allocation attributes to control area flags */
1488 if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1489 if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1490 if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1491
1492 /* We just allocated it */
1493 ControlArea->u.Flags.BeingCreated = 1;
1494
1495 /* The subsection follows, write the mask, PTE count and point back to the CA */
1496 Subsection = (PSUBSECTION)(ControlArea + 1);
1497 Subsection->ControlArea = ControlArea;
1498 Subsection->PtesInSubsection = PteCount;
1499 Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1500
1501 /* Zero out the segment's prototype PTEs, and link it with the control area */
1502 PointerPte = &NewSegment->ThePtes[0];
1503 RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1504 NewSegment->PrototypePte = PointerPte;
1505 NewSegment->ControlArea = ControlArea;
1506
1507 /* Save some extra accounting data for the segment as well */
1508 NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1509 NewSegment->SizeOfSegment = ((ULONGLONG)PteCount) * PAGE_SIZE;
1510 NewSegment->TotalNumberOfPtes = PteCount;
1511 NewSegment->NonExtendedPtes = PteCount;
1512
1513 /* The subsection's base address is the first Prototype PTE in the segment */
1514 Subsection->SubsectionBase = PointerPte;
1515
1516 /* Start with an empty PTE, unless this is a commit operation */
1517 TempPte.u.Long = 0;
1519 {
1520 /* In which case, write down the protection mask in the Prototype PTEs */
1521 TempPte.u.Soft.Protection = ProtectionMask;
1522
1523 /* For accounting, also mark these pages as being committed */
1524 NewSegment->NumberOfCommittedPages = PteCount;
1525 }
1526
1527 /* The template PTE itself for the segment should also have the mask set */
1528 NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1529
1530 /* Write out the prototype PTEs, for now they're simply demand zero */
1531#ifdef _WIN64
1532 RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1533#else
1534 RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1535#endif
1536 return STATUS_SUCCESS;
1537}
1538
1540NTAPI
1542{
1543 PSECTION Section = SectionObject;
1546
1547 /* Check if it's an ARM3, or ReactOS section */
1549 {
1550 /* Return the file pointer stored in the control area */
1551 return Section->Segment->ControlArea->FilePointer;
1552 }
1553
1554 /* Return the file object */
1555 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1556}
1557
1558static
1561 _In_ PMMVAD Vad)
1562{
1563 PCONTROL_AREA ControlArea;
1565
1566 /* Check if this is a RosMm memory area */
1567 if (Vad->u.VadFlags.Spare != 0)
1568 {
1570
1571 /* Check if it's a section view (RosMm section) */
1573 {
1574 /* Get the section pointer to the SECTION_OBJECT */
1575 FileObject = MemoryArea->SectionData.Segment->FileObject;
1576 }
1577 else
1578 {
1579#ifdef NEWCC
1580 ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1581 DPRINT1("VAD is a cache section!\n");
1582#else
1583 ASSERT(FALSE);
1584#endif
1585 return NULL;
1586 }
1587 }
1588 else
1589 {
1590 /* Make sure it's not a VM VAD */
1591 if (Vad->u.VadFlags.PrivateMemory == 1)
1592 {
1593 DPRINT1("VAD is not a section\n");
1594 return NULL;
1595 }
1596
1597 /* Get the control area */
1598 ControlArea = Vad->ControlArea;
1599 if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1600 {
1601 DPRINT1("Address is not a section\n");
1602 return NULL;
1603 }
1604
1605 /* Get the file object */
1606 FileObject = ControlArea->FilePointer;
1607 }
1608
1609 /* Return the file object */
1610 return FileObject;
1611}
1612
1613VOID
1614NTAPI
1616{
1618
1619 /* Get the section object of this process*/
1620 SectionObject = PsGetCurrentProcess()->SectionObject;
1623
1624 if (SectionObject->u.Flags.Image == 0)
1625 {
1626 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1627 return;
1628 }
1629
1630 /* Return the image information */
1631 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1632}
1633
1634static
1638{
1639 POBJECT_NAME_INFORMATION ObjectNameInfo;
1642
1643 /* Allocate memory for our structure */
1644 ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, 1024, TAG_MM);
1645 if (!ObjectNameInfo) return STATUS_NO_MEMORY;
1646
1647 /* Query the name */
1649 ObjectNameInfo,
1650 1024,
1651 &ReturnLength);
1652 if (!NT_SUCCESS(Status))
1653 {
1654 /* Failed, free memory */
1655 DPRINT1("Name query failed\n");
1656 ExFreePoolWithTag(ObjectNameInfo, TAG_MM);
1657 *ModuleName = NULL;
1658 return Status;
1659 }
1660
1661 /* Success */
1662 *ModuleName = ObjectNameInfo;
1663 return STATUS_SUCCESS;
1664}
1665
1667NTAPI
1670{
1672 PSECTION SectionObject = Section;
1673
1674 /* Make sure it's an image section */
1675 if (SectionObject->u.Flags.Image == 0)
1676 {
1677 /* It's not, fail */
1678 DPRINT1("Not an image section\n");
1680 }
1681
1682 /* Get the file object */
1685}
1686
1688NTAPI
1691{
1692 POBJECT_NAME_INFORMATION ModuleNameInformation;
1695 PMMVAD Vad;
1697
1698 /* Lock address space */
1701
1702 /* Get the VAD */
1703 Vad = MiLocateAddress(Address);
1704 if (Vad == NULL)
1705 {
1706 /* Fail, the address does not exist */
1707 DPRINT1("No VAD at address %p\n", Address);
1710 }
1711
1712 /* Get the file object pointer for the VAD */
1714 if (FileObject == NULL)
1715 {
1716 DPRINT1("Failed to get file object for Address %p\n", Address);
1719 }
1720
1721 /* Reference the file object */
1723
1724 /* Unlock address space */
1726
1727 /* Get the filename of the file object */
1728 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1729
1730 /* Dereference the file object */
1732
1733 /* Check if we were able to get the file object name */
1734 if (NT_SUCCESS(Status))
1735 {
1736 /* Init modulename */
1737 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1739
1740 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1741 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1742
1743 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1744 }
1745
1746 /* Return status */
1747 return Status;
1748}
1749
1751NTAPI
1754 OUT PVOID MemoryInformation,
1755 IN SIZE_T MemoryInformationLength,
1757{
1761 PMEMORY_SECTION_NAME SectionName = NULL;
1763
1766 NULL,
1768 (PVOID*)(&Process),
1769 NULL);
1770
1771 if (!NT_SUCCESS(Status))
1772 {
1773 DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1774 return Status;
1775 }
1776
1778
1779 if (NT_SUCCESS(Status))
1780 {
1781 SectionName = MemoryInformation;
1782 if (PreviousMode != KernelMode)
1783 {
1784 _SEH2_TRY
1785 {
1786 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1787 (PWSTR)(SectionName + 1),
1788 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1790
1792
1793 }
1795 {
1797 }
1798 _SEH2_END;
1799 }
1800 else
1801 {
1802 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1803 (PWSTR)(SectionName + 1),
1804 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1806
1808
1809 }
1810
1812 }
1814 return Status;
1815}
1816
1817VOID
1818NTAPI
1820 IN PMMPTE PointerPte,
1821 IN ULONG ProtectionMask,
1822 IN PMMPFN Pfn1,
1823 IN BOOLEAN UpdateDirty)
1824{
1825 MMPTE TempPte, PreviousPte;
1826 KIRQL OldIrql;
1827 BOOLEAN RebuildPte = FALSE;
1828
1829 //
1830 // User for sanity checking later on
1831 //
1832 PreviousPte = *PointerPte;
1833
1834 //
1835 // Build the PTE and acquire the PFN lock
1836 //
1838 PointerPte,
1839 ProtectionMask,
1840 PreviousPte.u.Hard.PageFrameNumber);
1841 OldIrql = MiAcquirePfnLock();
1842
1843 //
1844 // We don't support I/O mappings in this path yet
1845 //
1846 ASSERT(Pfn1 != NULL);
1847 ASSERT(Pfn1->u3.e1.CacheAttribute != MiWriteCombined);
1848
1849 //
1850 // Make sure new protection mask doesn't get in conflict and fix it if it does
1851 //
1852 if (Pfn1->u3.e1.CacheAttribute == MiCached)
1853 {
1854 //
1855 // This is a cached PFN
1856 //
1857 if (ProtectionMask & (MM_NOCACHE | MM_NOACCESS))
1858 {
1859 RebuildPte = TRUE;
1860 ProtectionMask &= ~(MM_NOCACHE | MM_NOACCESS);
1861 }
1862 }
1863 else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
1864 {
1865 //
1866 // This is a non-cached PFN
1867 //
1868 if ((ProtectionMask & (MM_NOCACHE | MM_NOACCESS)) != MM_NOCACHE)
1869 {
1870 RebuildPte = TRUE;
1871 ProtectionMask &= ~MM_NOACCESS;
1872 ProtectionMask |= MM_NOCACHE;
1873 }
1874 }
1875
1876 if (RebuildPte)
1877 {
1879 PointerPte,
1880 ProtectionMask,
1881 PreviousPte.u.Hard.PageFrameNumber);
1882 }
1883
1884 //
1885 // Write the new PTE, making sure we are only changing the bits
1886 //
1887 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
1888
1889 //
1890 // Flush the TLB
1891 //
1892 ASSERT(PreviousPte.u.Hard.Valid == 1);
1894 ASSERT(PreviousPte.u.Hard.Valid == 1);
1895
1896 //
1897 // Windows updates the relevant PFN1 information, we currently don't.
1898 //
1899 if (UpdateDirty && PreviousPte.u.Hard.Dirty)
1900 {
1901 if (!Pfn1->u3.e1.Modified)
1902 {
1903 DPRINT1("FIXME: Mark PFN as dirty\n");
1904 }
1905 }
1906
1907 //
1908 // Not supported in ARM3
1909 //
1910 ASSERT(FoundVad->u.VadFlags.VadType != VadWriteWatch);
1911
1912 //
1913 // Release the PFN lock, we are done
1914 //
1915 MiReleasePfnLock(OldIrql);
1916}
1917
1918static
1919VOID
1921 IN ULONG NumberOfPtes,
1922 IN PCONTROL_AREA ControlArea,
1923 IN PMMSUPPORT Ws)
1924{
1925 PMMPTE PointerPte, ProtoPte;//, FirstPte;
1926 PMMPDE PointerPde, SystemMapPde;
1927 PMMPFN Pfn1, Pfn2;
1928 MMPTE PteContents;
1929 KIRQL OldIrql;
1930 DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
1931
1932 ASSERT(Ws == NULL);
1933
1934 /* Get the PTE and loop each one */
1935 PointerPte = MiAddressToPte(BaseAddress);
1936 //FirstPte = PointerPte;
1937 while (NumberOfPtes)
1938 {
1939 /* Check if the PTE is already valid */
1940 PteContents = *PointerPte;
1941 if (PteContents.u.Hard.Valid == 1)
1942 {
1943 /* Get the PFN entry */
1944 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
1945
1946 /* Get the PTE */
1947 PointerPde = MiPteToPde(PointerPte);
1948
1949 /* Lock the PFN database and make sure this isn't a mapped file */
1950 OldIrql = MiAcquirePfnLock();
1951 ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
1952
1953 /* Mark the page as modified accordingly */
1954 if (MI_IS_PAGE_DIRTY(&PteContents))
1955 Pfn1->u3.e1.Modified = 1;
1956
1957 /* Was the PDE invalid */
1958 if (PointerPde->u.Long == 0)
1959 {
1960#if (_MI_PAGING_LEVELS == 2)
1961 /* Find the system double-mapped PDE that describes this mapping */
1962 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
1963
1964 /* Make it valid */
1965 ASSERT(SystemMapPde->u.Hard.Valid == 1);
1966 MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
1967#else
1968 DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
1969 ASSERT(FALSE);
1970#endif
1971 }
1972
1973 /* Dereference the PDE and the PTE */
1974 Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
1975 MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
1977 MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
1978
1979 /* Release the PFN lock */
1980 MiReleasePfnLock(OldIrql);
1981 }
1982 else
1983 {
1984 /* Windows ASSERT */
1985 ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
1986
1987 /* Check if this is a prototype pointer PTE */
1988 if (PteContents.u.Soft.Prototype == 1)
1989 {
1990 /* Get the prototype PTE */
1991 ProtoPte = MiProtoPteToPte(&PteContents);
1992
1993 /* We don't support anything else atm */
1994 ASSERT(ProtoPte->u.Long == 0);
1995 }
1996 }
1997
1998 /* Make the PTE into a zero PTE */
1999 PointerPte->u.Long = 0;
2000
2001 /* Move to the next PTE */
2002 PointerPte++;
2003 NumberOfPtes--;
2004 }
2005
2006 /* Flush the TLB */
2008
2009 /* Acquire the PFN lock */
2010 OldIrql = MiAcquirePfnLock();
2011
2012 /* Decrement the accounting counters */
2013 ControlArea->NumberOfUserReferences--;
2014 ControlArea->NumberOfMappedViews--;
2015
2016 /* Check if we should destroy the CA and release the lock */
2017 MiCheckControlArea(ControlArea, OldIrql);
2018}
2019
2020static
2021ULONG
2023 IN PVOID Base,
2024 OUT PCONTROL_AREA *ControlArea)
2025{
2026 ULONG Hash, Size, Count = 0;
2028 PAGED_CODE();
2029
2030 /* Compute the hash for this entry and loop trying to find it */
2031 Entry = (ULONG_PTR)Base >> 16;
2032 Hash = Entry % Session->SystemSpaceHashKey;
2033 while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2034 {
2035 /* Check if we overflew past the end of the hash table */
2036 if (++Hash >= Session->SystemSpaceHashSize)
2037 {
2038 /* Reset the hash to zero and keep searching from the bottom */
2039 Hash = 0;
2040 if (++Count == 2)
2041 {
2042 /* But if we overflew twice, then this is not a real mapping */
2043 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2044 (ULONG_PTR)Base,
2045 1,
2046 0,
2047 0);
2048 }
2049 }
2050 }
2051
2052 /* One less entry */
2053 Session->SystemSpaceHashEntries--;
2054
2055 /* Extract the size and clear the entry */
2056 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2057 Session->SystemSpaceViewTable[Hash].Entry = 0;
2058
2059 /* Return the control area and the size */
2060 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2061 return Size;
2062}
2063
2064static
2068{
2069 ULONG Size;
2070 PCONTROL_AREA ControlArea;
2071 PAGED_CODE();
2072
2073 /* Remove this mapping */
2074 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2075 Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2076
2077 /* Clear the bits for this mapping */
2078 RtlClearBits(Session->SystemSpaceBitMap,
2079 (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2080 Size);
2081
2082 /* Convert the size from a bit size into the actual size */
2083 Size = Size * (_64K >> PAGE_SHIFT);
2084
2085 /* Remove the PTEs now */
2086 MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2087 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2088
2089 /* Return success */
2090 return STATUS_SUCCESS;
2091}
2092
2093/* PUBLIC FUNCTIONS ***********************************************************/
2094
2095/*
2096 * @implemented
2097 */
2099NTAPI
2103 IN PLARGE_INTEGER InputMaximumSize,
2108{
2109 SECTION Section;
2110 PSECTION NewSection;
2111 PSUBSECTION Subsection;
2112 PSEGMENT NewSegment, Segment;
2114 PCONTROL_AREA ControlArea;
2115 ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2117 BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2118 KIRQL OldIrql;
2120 BOOLEAN UserRefIncremented = FALSE;
2121 PVOID PreviousSectionPointer;
2122
2123 /* Make the same sanity checks that the Nt interface should've validated */
2126 SEC_NO_CHANGE)) == 0);
2136
2137 /* Convert section flag to page flag */
2140
2141 /* Check to make sure the protection is correct. Nt* does this already */
2143 if (ProtectionMask == MM_INVALID_PROTECTION)
2144 {
2145 DPRINT1("Invalid protection mask\n");
2147 }
2148
2149 /* Check if this is going to be a data or image backed file section */
2150 if ((FileHandle) || (FileObject))
2151 {
2152 /* These cannot be mapped with large pages */
2154
2155 /* For now, only support the mechanism through a file handle */
2157
2158 /* Reference the file handle to get the object */
2160 MmMakeFileAccess[ProtectionMask],
2163 (PVOID*)&File,
2164 NULL);
2165 if (!NT_SUCCESS(Status)) return Status;
2166
2167 /* Make sure Cc has been doing its job */
2168 if (!File->SectionObjectPointer)
2169 {
2170 /* This is not a valid file system-based file, fail */
2173 }
2174
2175 /* Image-file backed sections are not yet supported */
2177
2178 /* Compute the size of the control area, and allocate it */
2179 ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2180 ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2181 if (!ControlArea)
2182 {
2185 }
2186
2187 /* Zero it out */
2188 RtlZeroMemory(ControlArea, ControlAreaSize);
2189
2190 /* Did we get a handle, or an object? */
2191 if (FileHandle)
2192 {
2193 /* We got a file handle so we have to lock down the file */
2194#if 0
2196 if (!NT_SUCCESS(Status))
2197 {
2198 ExFreePool(ControlArea);
2200 return Status;
2201 }
2202#else
2203 /* ReactOS doesn't support this API yet, so do nothing */
2206#endif
2207 /* Update the top-level IRP so that drivers know what's happening */
2209 FileLock = TRUE;
2210 }
2211
2212 /* Lock the PFN database while we play with the section pointers */
2213 OldIrql = MiAcquirePfnLock();
2214
2215 /* Image-file backed sections are not yet supported */
2217
2218 /* There should not already be a control area for this file */
2219 ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2220 NewSegment = NULL;
2221
2222 /* Write down that this CA is being created, and set it */
2223 ControlArea->u.Flags.BeingCreated = TRUE;
2225 PreviousSectionPointer = File->SectionObjectPointer;
2226 File->SectionObjectPointer->DataSectionObject = ControlArea;
2227
2228 /* We can release the PFN lock now */
2229 MiReleasePfnLock(OldIrql);
2230
2231 /* We don't support previously-mapped file */
2232 ASSERT(NewSegment == NULL);
2233
2234 /* Image-file backed sections are not yet supported */
2236
2237 /* So we always create a data file map */
2239 &Segment,
2240 (PSIZE_T)InputMaximumSize,
2243 KernelCall);
2244 if (!NT_SUCCESS(Status))
2245 {
2246 /* Lock the PFN database while we play with the section pointers */
2247 OldIrql = MiAcquirePfnLock();
2248
2249 /* Reset the waiting-for-deletion event */
2250 ASSERT(ControlArea->WaitingForDeletion == NULL);
2251 ControlArea->WaitingForDeletion = NULL;
2252
2253 /* Set the file pointer NULL flag */
2254 ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2255 ControlArea->u.Flags.FilePointerNull = TRUE;
2256
2257 /* Delete the data section object */
2259 File->SectionObjectPointer->DataSectionObject = NULL;
2260
2261 /* No longer being created */
2262 ControlArea->u.Flags.BeingCreated = FALSE;
2263
2264 /* We can release the PFN lock now */
2265 MiReleasePfnLock(OldIrql);
2266
2267 /* Check if we locked and set the IRP */
2268 if (FileLock)
2269 {
2270 /* Undo */
2272 //FsRtlReleaseFile(File);
2273 }
2274
2275 /* Free the control area and de-ref the file object */
2276 ExFreePool(ControlArea);
2278
2279 /* All done */
2280 return Status;
2281 }
2282
2283 /* On success, we expect this */
2284 ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2285
2286 /* Check if a maximum size was specified */
2287 if (!InputMaximumSize->QuadPart)
2288 {
2289 /* Nope, use the segment size */
2290 Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2291 }
2292 else
2293 {
2294 /* Yep, use the entered size */
2295 Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2296 }
2297 }
2298 else
2299 {
2300 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2302
2303 /* Not yet supported */
2305
2306 /* So this must be a pagefile-backed section, create the mappings needed */
2307 Status = MiCreatePagingFileMap(&NewSegment,
2308 InputMaximumSize,
2309 ProtectionMask,
2311 if (!NT_SUCCESS(Status)) return Status;
2312
2313 /* Set the size here, and read the control area */
2314 Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2315 ControlArea = NewSegment->ControlArea;
2316
2317 /* MiCreatePagingFileMap increments user references */
2318 UserRefIncremented = TRUE;
2319 }
2320
2321 /* Did we already have a segment? */
2322 if (!NewSegment)
2323 {
2324 /* This must be the file path and we created a segment */
2325 NewSegment = Segment;
2326 ASSERT(File != NULL);
2327
2328 /* Acquire the PFN lock while we set control area flags */
2329 OldIrql = MiAcquirePfnLock();
2330
2331 /* We don't support this race condition yet, so assume no waiters */
2332 ASSERT(ControlArea->WaitingForDeletion == NULL);
2333 ControlArea->WaitingForDeletion = NULL;
2334
2335 /* Image-file backed sections are not yet supported, nor ROM images */
2337 ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2338
2339 /* Take off the being created flag, and then release the lock */
2340 ControlArea->u.Flags.BeingCreated = FALSE;
2341 MiReleasePfnLock(OldIrql);
2342 }
2343
2344 /* Check if we locked the file earlier */
2345 if (FileLock)
2346 {
2347 /* Reset the top-level IRP and release the lock */
2349 //FsRtlReleaseFile(File);
2350 FileLock = FALSE;
2351 }
2352
2353 /* Set the initial section object data */
2354 Section.InitialPageProtection = SectionPageProtection;
2355
2356 /* The mapping created a control area and segment, save the flags */
2357 Section.Segment = NewSegment;
2358 Section.u.LongFlags = ControlArea->u.LongFlags;
2359
2360 /* Check if this is a user-mode read-write non-image file mapping */
2361 if (!(FileObject) &&
2363 !(ControlArea->u.Flags.Image) &&
2364 (ControlArea->FilePointer))
2365 {
2366 /* Add a reference and set the flag */
2367 Section.u.Flags.UserWritable = TRUE;
2368 InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2369 }
2370
2371 /* Check for image mappings or page file mappings */
2372 if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2373 {
2374 /* Charge the segment size, and allocate a subsection */
2375 PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2376 Size = sizeof(SUBSECTION);
2377 }
2378 else
2379 {
2380 /* Charge nothing, and allocate a mapped subsection */
2381 PagedCharge = 0;
2382 Size = sizeof(MSUBSECTION);
2383 }
2384
2385 /* Check if this is a normal CA */
2386 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2387 ASSERT(ControlArea->u.Flags.Rom == 0);
2388
2389 /* Charge only a CA, and the subsection is right after */
2390 NonPagedCharge = sizeof(CONTROL_AREA);
2391 Subsection = (PSUBSECTION)(ControlArea + 1);
2392
2393 /* We only support single-subsection mappings */
2394 NonPagedCharge += Size;
2395 ASSERT(Subsection->NextSubsection == NULL);
2396
2397 /* Create the actual section object, with enough space for the prototype PTEs */
2402 NULL,
2403 sizeof(SECTION),
2404 PagedCharge,
2405 NonPagedCharge,
2406 (PVOID*)&NewSection);
2407 if (!NT_SUCCESS(Status))
2408 {
2409 /* Check if this is a user-mode read-write non-image file mapping */
2410 if (!(FileObject) &&
2412 !(ControlArea->u.Flags.Image) &&
2413 (ControlArea->FilePointer))
2414 {
2415 /* Remove a reference and check the flag */
2416 ASSERT(Section.u.Flags.UserWritable == 1);
2417 InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2418 }
2419
2420 /* Check if a user reference was added */
2421 if (UserRefIncremented)
2422 {
2423 /* Acquire the PFN lock while we change counters */
2424 OldIrql = MiAcquirePfnLock();
2425
2426 /* Decrement the accounting counters */
2427 ControlArea->NumberOfSectionReferences--;
2428 ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2429 ControlArea->NumberOfUserReferences--;
2430
2431 /* Check if we should destroy the CA and release the lock */
2432 MiCheckControlArea(ControlArea, OldIrql);
2433 }
2434
2435 /* Return the failure code */
2436 return Status;
2437 }
2438
2439 /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2440
2441 /* Now copy the local section object from the stack into this new object */
2442 RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2443 NewSection->Address.StartingVpn = 0;
2444
2445 /* For now, only user calls are supported */
2446 ASSERT(KernelCall == FALSE);
2447 NewSection->u.Flags.UserReference = TRUE;
2448
2449 /* Is this a "based" allocation, in which all mappings are identical? */
2451 {
2452 /* Lock the VAD tree during the search */
2454
2455 /* Is it a brand new ControArea ? */
2456 if (ControlArea->u.Flags.BeingCreated == 1)
2457 {
2458 ASSERT(ControlArea->u.Flags.Based == 1);
2459 /* Then we must find a global address, top-down */
2462 _64K,
2464 (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2465
2466 if (!NT_SUCCESS(Status))
2467 {
2468 /* No way to find a valid range. */
2470 ControlArea->u.Flags.Based = 0;
2471 NewSection->u.Flags.Based = 0;
2472 ObDereferenceObject(NewSection);
2473 return Status;
2474 }
2475
2476 /* Compute the ending address and insert it into the VAD tree */
2477 NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2478 NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2479 MiInsertBasedSection(NewSection);
2480 }
2481 else
2482 {
2483 /* 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 !*/
2484 ASSERT(FALSE);
2485 }
2486
2488 }
2489
2490 /* The control area is not being created anymore */
2491 if (ControlArea->u.Flags.BeingCreated == 1)
2492 {
2493 /* Acquire the PFN lock while we set control area flags */
2494 OldIrql = MiAcquirePfnLock();
2495
2496 /* Take off the being created flag, and then release the lock */
2497 ControlArea->u.Flags.BeingCreated = 0;
2498 NewSection->u.Flags.BeingCreated = 0;
2499
2500 MiReleasePfnLock(OldIrql);
2501 }
2502
2503 /* Migrate the attribute into a flag */
2505
2506 /* If R/W access is not requested, this might eventually become a CoW mapping */
2508 {
2509 NewSection->u.Flags.CopyOnWrite = TRUE;
2510 }
2511
2512 /* Write down if this was a kernel call */
2513 ControlArea->u.Flags.WasPurged |= KernelCall;
2514 ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2515
2516 /* Make sure the segment and the section are the same size, or the section is smaller */
2517 ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2518
2519 /* Return the object and the creation status */
2520 *SectionObject = (PVOID)NewSection;
2521 return Status;
2522}
2523
2524/*
2525 * @implemented
2526 */
2528NTAPI
2539{
2542 PSECTION Section;
2543 PCONTROL_AREA ControlArea;
2544 ULONG ProtectionMask;
2546 ULONG64 CalculatedViewSize;
2547 PAGED_CODE();
2548
2549 /* Get the segment and control area */
2550 Section = (PSECTION)SectionObject;
2551 ControlArea = Section->Segment->ControlArea;
2552
2553 /* These flags/states are not yet supported by ARM3 */
2554 ASSERT(Section->u.Flags.Image == 0);
2555 ASSERT(Section->u.Flags.NoCache == 0);
2556 ASSERT(Section->u.Flags.WriteCombined == 0);
2557 ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
2558
2559 /* FIXME */
2560 if ((AllocationType & MEM_RESERVE) != 0)
2561 {
2562 DPRINT1("MmMapViewOfArm3Section called with MEM_RESERVE, this is not implemented yet!!!\n");
2564 }
2565
2566 /* Check if the mapping protection is compatible with the create */
2568 {
2569 DPRINT1("Mapping protection is incompatible\n");
2571 }
2572
2573 /* Check if the offset and size would cause an overflow */
2574 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) <
2575 (ULONG64)SectionOffset->QuadPart)
2576 {
2577 DPRINT1("Section offset overflows\n");
2579 }
2580
2581 /* Check if the offset and size are bigger than the section itself */
2582 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) >
2583 (ULONG64)Section->SizeOfSection.QuadPart)
2584 {
2585 DPRINT1("Section offset is larger than section\n");
2587 }
2588
2589 /* Check if the caller did not specify a view size */
2590 if (!(*ViewSize))
2591 {
2592 /* Compute it for the caller */
2593 CalculatedViewSize = Section->SizeOfSection.QuadPart -
2594 SectionOffset->QuadPart;
2595
2596 /* Check if it's larger than 4GB or overflows into kernel-mode */
2597 if (!NT_SUCCESS(RtlULongLongToSIZET(CalculatedViewSize, ViewSize)) ||
2598 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < CalculatedViewSize))
2599 {
2600 DPRINT1("Section view won't fit\n");
2602 }
2603 }
2604
2605 /* Check if the commit size is larger than the view size */
2606 if (CommitSize > *ViewSize)
2607 {
2608 DPRINT1("Attempting to commit more than the view itself\n");
2610 }
2611
2612 /* Check if the view size is larger than the section */
2613 if (*ViewSize > (ULONG64)Section->SizeOfSection.QuadPart)
2614 {
2615 DPRINT1("The view is larger than the section\n");
2617 }
2618
2619 /* Compute and validate the protection mask */
2620 ProtectionMask = MiMakeProtectionMask(Protect);
2621 if (ProtectionMask == MM_INVALID_PROTECTION)
2622 {
2623 DPRINT1("The protection is invalid\n");
2625 }
2626
2627 /* We only handle pagefile-backed sections, which cannot be writecombined */
2629 {
2630 DPRINT1("Cannot write combine a pagefile-backed section\n");
2632 }
2633
2634 /* Start by attaching to the current process if needed */
2636 {
2638 Attached = TRUE;
2639 }
2640
2641 /* Do the actual mapping */
2642 Status = MiMapViewOfDataSection(ControlArea,
2643 Process,
2646 ViewSize,
2647 Section,
2649 ProtectionMask,
2650 CommitSize,
2651 ZeroBits,
2653
2654 /* Detach if needed, then return status */
2656 return Status;
2657}
2658
2659/*
2660 * @unimplemented
2661 */
2662BOOLEAN
2663NTAPI
2665{
2667 return FALSE;
2668}
2669
2670/*
2671 * @unimplemented
2672 */
2673BOOLEAN
2674NTAPI
2677{
2679 return FALSE;
2680}
2681
2682/*
2683 * @implemented
2684 */
2686NTAPI
2690{
2691 PAGED_CODE();
2693
2694 // HACK
2695 if (MiIsRosSectionObject(Section))
2696 {
2697 return MmMapViewInSystemSpace(Section, MappedBase, ViewSize);
2698 }
2699
2700 /* Process must be in a session */
2701 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2702 {
2703 DPRINT1("Process is not in session\n");
2705 }
2706
2707 /* Use the system space API, but with the session view instead */
2709 SectionOffset.QuadPart = 0;
2710 return MiMapViewInSystemSpace(Section,
2712 MappedBase,
2713 ViewSize,
2714 &SectionOffset);
2715}
2716
2717/*
2718 * @implemented
2719 */
2721NTAPI
2723{
2724 PAGED_CODE();
2725
2726 // HACK
2728 {
2730 }
2731
2732 /* Process must be in a session */
2733 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2734 {
2735 DPRINT1("Proess is not in session\n");
2737 }
2738
2739 /* Use the system space API, but with the session view instead */
2742 MappedBase);
2743}
2744
2745/*
2746 * @implemented
2747 */
2749NTAPI
2752{
2754}
2755
2756/*
2757 * @implemented
2758 */
2760NTAPI
2762{
2764 PAGED_CODE();
2765
2766 /* Was this mapped by RosMm? */
2770 {
2773 return Status;
2774 }
2776
2777 /* It was not, call the ARM3 routine */
2779}
2780
2781/*
2782 * @implemented
2783 */
2785NTAPI
2788{
2789 ULONG_PTR StartAddress, EndingAddress, Base;
2790 ULONG Hash, Count = 0, Size, QuotaCharge;
2791 PMMSESSION Session;
2792 PMMPTE LastProtoPte, PointerPte, ProtoPte;
2793 PCONTROL_AREA ControlArea;
2795 PSUBSECTION Subsection;
2796 MMPTE TempPte;
2797 PAGED_CODE();
2798
2799 /* Make sure the base isn't past the session view range */
2802 {
2803 DPRINT1("Base outside of valid range\n");
2805 }
2806
2807 /* Make sure the size isn't past the session view range */
2810 {
2811 DPRINT1("Size outside of valid range\n");
2813 }
2814
2815 /* Sanity check */
2816 ASSERT(ViewSize != 0);
2817
2818 /* Process must be in a session */
2819 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2820 {
2821 DPRINT1("Process is not in session\n");
2823 }
2824
2825 /* Compute the correctly aligned base and end addresses */
2826 StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
2827 EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
2828
2829 /* Sanity check and grab the session */
2831 Session = &MmSessionSpace->Session;
2832
2833 /* Get the hash entry for this allocation */
2834 Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
2835
2836 /* Lock system space */
2838
2839 /* Loop twice so we can try rolling over if needed */
2840 while (TRUE)
2841 {
2842 /* Extract the size and base addresses from the entry */
2843 Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
2844 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2845
2846 /* Convert the size to bucket chunks */
2848
2849 /* Bail out if this entry fits in here */
2850 if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
2851
2852 /* Check if we overflew past the end of the hash table */
2853 if (++Hash >= Session->SystemSpaceHashSize)
2854 {
2855 /* Reset the hash to zero and keep searching from the bottom */
2856 Hash = 0;
2857 if (++Count == 2)
2858 {
2859 /* But if we overflew twice, then this is not a real mapping */
2860 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2861 Base,
2862 2,
2863 0,
2864 0);
2865 }
2866 }
2867 }
2868
2869 /* Make sure the view being mapped is not file-based */
2870 ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2871 if (ControlArea->FilePointer != NULL)
2872 {
2873 /* It is, so we have to bail out */
2874 DPRINT1("Only page-filed backed sections can be commited\n");
2877 }
2878
2879 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
2880 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2881 ASSERT(ControlArea->u.Flags.Rom == 0);
2882 Subsection = (PSUBSECTION)(ControlArea + 1);
2883
2884 /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
2885 ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
2886 QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
2887 LastProtoPte = ProtoPte + QuotaCharge;
2888 if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
2889 {
2890 DPRINT1("PTE is out of bounds\n");
2893 }
2894
2895 /* Acquire the commit lock and count all the non-committed PTEs */
2897 PointerPte = ProtoPte;
2898 while (PointerPte < LastProtoPte)
2899 {
2900 if (PointerPte->u.Long) QuotaCharge--;
2901 PointerPte++;
2902 }
2903
2904 /* Was everything committed already? */
2905 if (!QuotaCharge)
2906 {
2907 /* Nothing to do! */
2910 return STATUS_SUCCESS;
2911 }
2912
2913 /* Pick the segment and template PTE */
2914 Segment = ControlArea->Segment;
2915 TempPte = Segment->SegmentPteTemplate;
2916 ASSERT(TempPte.u.Long != 0);
2917
2918 /* Loop all prototype PTEs to be committed */
2919 PointerPte = ProtoPte;
2920 while (PointerPte < LastProtoPte)
2921 {
2922 /* Make sure the PTE is already invalid */
2923 if (PointerPte->u.Long == 0)
2924 {
2925 /* And write the invalid PTE */
2926 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2927 }
2928
2929 /* Move to the next PTE */
2930 PointerPte++;
2931 }
2932
2933 /* Check if we had at least one page charged */
2934 if (QuotaCharge)
2935 {
2936 /* Update the accounting data */
2937 Segment->NumberOfCommittedPages += QuotaCharge;
2939 }
2940
2941 /* Release all */
2944 return STATUS_SUCCESS;
2945}
2946
2947VOID
2948NTAPI
2950{
2952 PCONTROL_AREA ControlArea;
2953 KIRQL OldIrql;
2954
2955 SectionObject = (PSECTION)ObjectBody;
2956
2957 if (SectionObject->u.Flags.Based == 1)
2958 {
2959 /* Remove the node from the global section address tree */
2963 }
2964
2965 /* Lock the PFN database */
2966 OldIrql = MiAcquirePfnLock();
2967
2968 ASSERT(SectionObject->Segment);
2969 ASSERT(SectionObject->Segment->ControlArea);
2970
2971 ControlArea = SectionObject->Segment->ControlArea;
2972
2973 /* Dereference */
2974 ControlArea->NumberOfSectionReferences--;
2975 ControlArea->NumberOfUserReferences--;
2976
2977 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
2978
2979 /* Check it. It will delete it if there is no more reference to it */
2980 MiCheckControlArea(ControlArea, OldIrql);
2981}
2982
2983ULONG
2984NTAPI
2986{
2988 return 0;
2989}
2990
2991/* SYSTEM CALLS ***************************************************************/
2992
2994NTAPI
2995NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage,
2996 IN PVOID File2MappedAsFile)
2997{
2999 PMMVAD Vad1, Vad2;
3000 PFILE_OBJECT FileObject1, FileObject2;
3002
3003 /* Lock address space */
3006
3007 /* Get the VAD for Address 1 */
3008 Vad1 = MiLocateAddress(File1MappedAsAnImage);
3009 if (Vad1 == NULL)
3010 {
3011 /* Fail, the address does not exist */
3012 DPRINT1("No VAD at address 1 %p\n", File1MappedAsAnImage);
3014 goto Exit;
3015 }
3016
3017 /* Get the VAD for Address 2 */
3018 Vad2 = MiLocateAddress(File2MappedAsFile);
3019 if (Vad2 == NULL)
3020 {
3021 /* Fail, the address does not exist */
3022 DPRINT1("No VAD at address 2 %p\n", File2MappedAsFile);
3024 goto Exit;
3025 }
3026
3027 /* Get the file object pointer for VAD 1 */
3028 FileObject1 = MiGetFileObjectForVad(Vad1);
3029 if (FileObject1 == NULL)
3030 {
3031 DPRINT1("Failed to get file object for Address 1 %p\n", File1MappedAsAnImage);
3033 goto Exit;
3034 }
3035
3036 /* Get the file object pointer for VAD 2 */
3037 FileObject2 = MiGetFileObjectForVad(Vad2);
3038 if (FileObject2 == NULL)
3039 {
3040 DPRINT1("Failed to get file object for Address 2 %p\n", File2MappedAsFile);
3042 goto Exit;
3043 }
3044
3045 /* Make sure Vad1 is an image mapping */
3046 if (Vad1->u.VadFlags.VadType != VadImageMap)
3047 {
3048 DPRINT1("Address 1 (%p) is not an image mapping\n", File1MappedAsAnImage);
3050 goto Exit;
3051 }
3052
3053 /* SectionObjectPointer is equal if the files are equal */
3054 if (FileObject1->SectionObjectPointer == FileObject2->SectionObjectPointer)
3055 {
3057 }
3058 else
3059 {
3061 }
3062
3063Exit:
3064 /* Unlock address space */
3066 return Status;
3067}
3068
3069/*
3070 * @implemented
3071 */
3073NTAPI
3081{
3082 LARGE_INTEGER SafeMaximumSize;
3084 HANDLE Handle;
3087 PAGED_CODE();
3088
3089 /* Check for non-existing flags */
3092 SEC_NO_CHANGE)))
3093 {
3094 if (!(AllocationAttributes & 1))
3095 {
3096 DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
3098 }
3099 }
3100
3101 /* Check for no allocation type */
3103 {
3104 DPRINT1("Missing allocation type in allocation attributes\n");
3106 }
3107
3108 /* Check for image allocation with invalid attributes */
3112 {
3113 DPRINT1("Image allocation with invalid attributes\n");
3115 }
3116
3117 /* Check for allocation type is both commit and reserve */
3119 {
3120 DPRINT1("Commit and reserve in the same time\n");
3122 }
3123
3124 /* Now check for valid protection */
3129 {
3130 DPRINT1("Sections don't support these protections\n");
3132 }
3133
3134 /* Use a maximum size of zero, if none was specified */
3135 SafeMaximumSize.QuadPart = 0;
3136
3137 /* Check for user-mode caller */
3138 if (PreviousMode != KernelMode)
3139 {
3140 /* Enter SEH */
3141 _SEH2_TRY
3142 {
3143 /* Safely check user-mode parameters */
3144 if (MaximumSize) SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
3145 MaximumSize = &SafeMaximumSize;
3146 ProbeForWriteHandle(SectionHandle);
3147 }
3149 {
3150 /* Return the exception code */
3152 }
3153 _SEH2_END;
3154 }
3155 else if (!MaximumSize) MaximumSize = &SafeMaximumSize;
3156
3157 /* Check that MaximumSize is valid if backed by paging file */
3158 if ((!FileHandle) && (!MaximumSize->QuadPart))
3160
3161 /* Create the section */
3168 FileHandle,
3169 NULL);
3170 if (!NT_SUCCESS(Status)) return Status;
3171
3172 /* FIXME: Should zero last page for a file mapping */
3173
3174 /* Now insert the object */
3176 NULL,
3178 0,
3179 NULL,
3180 &Handle);
3181 if (NT_SUCCESS(Status))
3182 {
3183 /* Enter SEH */
3184 _SEH2_TRY
3185 {
3186 /* Return the handle safely */
3187 *SectionHandle = Handle;
3188 }
3190 {
3191 /* Nothing here */
3192 }
3193 _SEH2_END;
3194 }
3195
3196 /* Return the status */
3197 return Status;
3198}
3199
3201NTAPI
3205{
3206 HANDLE Handle;
3209 PAGED_CODE();
3210
3211 /* Check for user-mode caller */
3212 if (PreviousMode != KernelMode)
3213 {
3214 /* Enter SEH */
3215 _SEH2_TRY
3216 {
3217 /* Safely check user-mode parameters */
3218 ProbeForWriteHandle(SectionHandle);
3219 }
3221 {
3222 /* Return the exception code */
3224 }
3225 _SEH2_END;
3226 }
3227
3228 /* Try opening the object */
3232 NULL,
3234 NULL,
3235 &Handle);
3236
3237 /* Enter SEH */
3238 _SEH2_TRY
3239 {
3240 /* Return the handle safely */
3241 *SectionHandle = Handle;
3242 }
3244 {
3245 /* Nothing here */
3246 }
3247 _SEH2_END;
3248
3249 /* Return the status */
3250 return Status;
3251}
3252
3254NTAPI
3265{
3266 PVOID SafeBaseAddress;
3267 LARGE_INTEGER SafeSectionOffset;
3268 SIZE_T SafeViewSize;
3269 PSECTION Section;
3273 ULONG ProtectionMask;
3275#if defined(_M_IX86) || defined(_M_AMD64)
3276 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3278#else
3279 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3281#endif
3282
3283 /* Check for invalid inherit disposition */
3285 {
3286 DPRINT1("Invalid inherit disposition\n");
3288 }
3289
3290 /* Allow only valid allocation types */
3291 if (AllocationType & ~ValidAllocationType)
3292 {
3293 DPRINT1("Invalid allocation type\n");
3295 }
3296
3297 /* Convert the protection mask, and validate it */
3298 ProtectionMask = MiMakeProtectionMask(Protect);
3299 if (ProtectionMask == MM_INVALID_PROTECTION)
3300 {
3301 DPRINT1("Invalid page protection\n");
3303 }
3304
3305 /* Now convert the protection mask into desired section access mask */
3306 DesiredAccess = MmMakeSectionAccess[ProtectionMask & 0x7];
3307
3308 /* Assume no section offset */
3309 SafeSectionOffset.QuadPart = 0;
3310
3311 /* Enter SEH */
3312 _SEH2_TRY
3313 {
3314 /* Check for unsafe parameters */
3315 if (PreviousMode != KernelMode)
3316 {
3317 /* Probe the parameters */
3320 }
3321
3322 /* Check if a section offset was given */
3323 if (SectionOffset)
3324 {
3325 /* Check for unsafe parameters and capture section offset */
3327 SafeSectionOffset = *SectionOffset;
3328 }
3329
3330 /* Capture the other parameters */
3331 SafeBaseAddress = *BaseAddress;
3332 SafeViewSize = *ViewSize;
3333 }
3335 {
3336 /* Return the exception code */
3338 }
3339 _SEH2_END;
3340
3341 /* Check for kernel-mode address */
3342 if (SafeBaseAddress > MM_HIGHEST_VAD_ADDRESS)
3343 {
3344 DPRINT1("Kernel base not allowed\n");
3346 }
3347
3348 /* Check for range entering kernel-mode */
3349 if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)SafeBaseAddress) < SafeViewSize)
3350 {
3351 DPRINT1("Overflowing into kernel base not allowed\n");
3353 }
3354
3355 /* Check for invalid zero bits */
3356 if (ZeroBits)
3357 {
3359 {
3360 DPRINT1("Invalid zero bits\n");
3362 }
3363
3364 if ((((ULONG_PTR)SafeBaseAddress << ZeroBits) >> ZeroBits) != (ULONG_PTR)SafeBaseAddress)
3365 {
3366 DPRINT1("Invalid zero bits\n");
3368 }
3369
3370 if (((((ULONG_PTR)SafeBaseAddress + SafeViewSize) << ZeroBits) >> ZeroBits) != ((ULONG_PTR)SafeBaseAddress + SafeViewSize))
3371 {
3372 DPRINT1("Invalid zero bits\n");
3374 }
3375 }
3376
3377 /* Reference the process */
3382 (PVOID*)&Process,
3383 NULL);
3384 if (!NT_SUCCESS(Status)) return Status;
3385
3386 /* Reference the section */
3387 Status = ObReferenceObjectByHandle(SectionHandle,
3391 (PVOID*)&Section,
3392 NULL);
3393 if (!NT_SUCCESS(Status))
3394 {
3396 return Status;
3397 }
3398
3399 if (Section->u.Flags.PhysicalMemory)
3400 {
3401 if (PreviousMode == UserMode &&
3402 SafeSectionOffset.QuadPart + SafeViewSize > MmHighestPhysicalPage << PAGE_SHIFT)
3403 {
3404 DPRINT1("Denying map past highest physical page.\n");
3405 ObDereferenceObject(Section);
3408 }
3409 }
3410 else if (!(AllocationType & MEM_DOS_LIM))
3411 {
3412 /* Check for non-allocation-granularity-aligned BaseAddress */
3413 if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
3414 {
3415 DPRINT("BaseAddress is not at 64-kilobyte address boundary.\n");
3416 ObDereferenceObject(Section);
3419 }
3420
3421 /* Do the same for the section offset */
3422 if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
3423 {
3424 DPRINT("SectionOffset is not at 64-kilobyte address boundary.\n");
3425 ObDereferenceObject(Section);
3428 }
3429 }
3430
3431 /* Now do the actual mapping */
3432 Status = MmMapViewOfSection(Section,
3433 Process,
3434 &SafeBaseAddress,
3435 ZeroBits,
3436 CommitSize,
3437 &SafeSectionOffset,
3438 &SafeViewSize,
3441 Protect);
3442
3443 /* Return data only on success */
3444 if (NT_SUCCESS(Status))
3445 {
3446 /* Check if this is an image for the current process */
3447 if ((Section->u.Flags.Image) &&
3450 {
3451 /* Notify the debugger */
3452 DbgkMapViewOfSection(Section,
3453 SafeBaseAddress,
3454 SafeSectionOffset.LowPart,
3455 SafeViewSize);
3456 }
3457
3458 /* Enter SEH */
3459 _SEH2_TRY
3460 {
3461 /* Return parameters to user */
3462 *BaseAddress = SafeBaseAddress;
3463 *ViewSize = SafeViewSize;
3464 if (SectionOffset) *SectionOffset = SafeSectionOffset;
3465 }
3467 {
3468 /* Nothing to do */
3469 }
3470 _SEH2_END;
3471 }
3472
3473 /* Dereference all objects and return status */
3474 ObDereferenceObject(Section);
3476 return Status;
3477}
3478
3480NTAPI
3483{
3487
3488 /* Don't allowing mapping kernel views */
3490 {
3491 DPRINT1("Trying to unmap a kernel view\n");
3493 }
3494
3495 /* Reference the process */
3500 (PVOID*)&Process,
3501 NULL);
3502 if (!NT_SUCCESS(Status)) return Status;
3503
3504 /* Unmap the view */
3506
3507 /* Dereference the process and return status */
3509 return Status;
3510}
3511
3513NTAPI
3515 IN OUT PLARGE_INTEGER NewMaximumSize)
3516{
3517 LARGE_INTEGER SafeNewMaximumSize;
3518 PSECTION Section;
3521
3522 /* Check for user-mode parameters */
3523 if (PreviousMode != KernelMode)
3524 {
3525 /* Enter SEH */
3526 _SEH2_TRY
3527 {
3528 /* Probe and capture the maximum size, it's both read and write */
3529 ProbeForWriteLargeInteger(NewMaximumSize);
3530 SafeNewMaximumSize = *NewMaximumSize;
3531 }
3533 {
3534 /* Return the exception code */
3536 }
3537 _SEH2_END;
3538 }
3539 else
3540 {
3541 /* Just read the size directly */
3542 SafeNewMaximumSize = *NewMaximumSize;
3543 }
3544
3545 /* Reference the section */
3546 Status = ObReferenceObjectByHandle(SectionHandle,
3550 (PVOID*)&Section,
3551 NULL);
3552 if (!NT_SUCCESS(Status)) return Status;
3553
3554 Status = MmExtendSection(Section, &SafeNewMaximumSize);
3555
3556 /* Dereference the section */
3557 ObDereferenceObject(Section);
3558
3559 if (NT_SUCCESS(Status))
3560 {
3561 _SEH2_TRY
3562 {
3563 /* Write back the new size */
3564 *NewMaximumSize = SafeNewMaximumSize;
3565 }
3567 {
3569 }
3570 _SEH2_END;
3571 }
3572
3573 /* Return the status */
3575}
3576
3577/* EOF */
static NTSTATUS MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:530
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:2761
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1560
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:1752
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:1040
BOOLEAN NTAPI MmForceSectionClosed(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
Definition: section.c:2675
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3481
VOID NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:462
ACCESS_MASK MmMakeSectionAccess[8]
Definition: section.c:20
NTSTATUS NTAPI MmGetFileNameForSection(IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1668
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:3074
MMSESSION MmSession
Definition: section.c:107
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3202
static ULONG MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2022
VOID NTAPI MiFlushTbAndCapture(IN PMMVAD FoundVad, IN PMMPTE PointerPte, IN ULONG ProtectionMask, IN PMMPFN Pfn1, IN BOOLEAN UpdateDirty)
Definition: section.c:1819
ULONG NTAPI MmDoesFileHaveUserWritableReferences(IN PSECTION_OBJECT_POINTERS SectionPointer)
Definition: section.c:2985
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:766
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:2100
static NTSTATUS MiAddMappedPtes(IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea, IN LONGLONG SectionOffset)
Definition: section.c:399
static VOID MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:749
CHAR MmUserProtectionToMask2[16]
Definition: section.c:64
VOID NTAPI MmGetImageInformation(OUT PSECTION_IMAGE_INFORMATION ImageInformation)
Definition: section.c:1615
VOID NTAPI MiDeleteARM3Section(PVOID ObjectBody)
Definition: section.c:2949
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:3255
static PVOID MiInsertInSystemSpace(IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
Definition: section.c:288
static NTSTATUS MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1407
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:2529
NTSTATUS NTAPI MmUnmapViewInSessionSpace(IN PVOID MappedBase)
Definition: section.c:2722
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:2687
static NTSTATUS MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1422
static NTSTATUS MiSessionCommitPageTables(IN PVOID StartVa, IN PVOID EndVa)
Definition: section.c:924
static VOID MiRemoveMappedPtes(IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
Definition: section.c:1920
PVOID MmHighSectionBase
Definition: section.c:111
static NTSTATUS MiUnmapViewInSystemSpace(IN PMMSESSION Session, IN PVOID MappedBase)
Definition: section.c:2066
PSUBSECTION NTAPI MiLocateSubsection(IN PMMVAD Vad, IN ULONG_PTR Vpn)
Definition: section.c:556
NTSTATUS NTAPI NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, IN PVOID File2MappedAsFile)
Definition: section.c:2995
static NTSTATUS MiUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
Definition: section.c:803
NTSTATUS NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName)
Definition: section.c:1689
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:1152
NTSTATUS NTAPI MmCommitSessionMappedView(IN PVOID MappedBase, IN SIZE_T ViewSize)
Definition: section.c:2786
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID SectionObject)
Definition: section.c:1541
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:2750
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
BOOLEAN NTAPI MmDisableModifiedWriteOfSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: section.c:2664
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
static VOID MiSegmentDelete(IN PSEGMENT Segment)
Definition: section.c:591
static VOID MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:714
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:1636
NTSTATUS NTAPI NtExtendSection(IN HANDLE SectionHandle, IN OUT PLARGE_INTEGER NewMaximumSize)
Definition: section.c:3514
#define PAGED_CODE()
#define ALIGN_DOWN_BY(size, align)
unsigned char BOOLEAN
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
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:103
#define MAXLONG_PTR
Definition: basetsd.h:104
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#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:2257
#define ULONG_PTR
Definition: config.h:101
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#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:140
_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:196
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:116
#define MM_EXECUTE_WRITECOPY
Definition: miarm.h:50
VOID NTAPI MiDeleteVirtualAddresses(IN ULONG_PTR Va, IN ULONG_PTR EndingAddress, IN PMMVAD Vad)
Definition: virtual.c:530
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:841
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:423
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:440
ULONG MmSecondaryColorMask
Definition: mminit.c:257
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1111
#define MM_GUARDPAGE
Definition: miarm.h:57
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:799
#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:246
#define MM_NOCACHE
Definition: miarm.h:56
#define MM_DELETE_CHECK
Definition: miarm.h:270
#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:1031
#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:275
#define MM_EXECUTE
Definition: miarm.h:45
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1252
#define MM_EXECUTE_READ
Definition: miarm.h:46
@ MiWriteCombined
Definition: miarm.h:426
@ MiCached
Definition: miarm.h:425
@ MiNonCached
Definition: miarm.h:424
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:1006
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:4562
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 MiRosUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
Definition: section.c:3594
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:282
struct _MMVIEW MMVIEW
NTSTATUS NTAPI MiCheckSecuredVad(IN PMMVAD Vad, IN PVOID Base, IN SIZE_T Size, IN ULONG ProtectionMask)
Definition: vadnode.c:903
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:991
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1587
SIZE_T MmSizeOfPagedPoolInBytes
Definition: miarm.h:599
#define MM_WRITECOPY
Definition: miarm.h:48
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1182
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned __int64 ULONG64
Definition: imports.h:198
#define SECTION
Definition: profile.c:31
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
struct _MMPTE MMPTE
_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:2451
_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:1321
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
#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:1311
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define SEC_RESERVE
Definition: nt_native.h:1323
enum _SECTION_INHERIT SECTION_INHERIT
#define FILE_EXECUTE
Definition: nt_native.h:642
@ ViewUnmap
Definition: nt_native.h:1279
@ ViewShare
Definition: nt_native.h:1278
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SECTION_EXTEND_SIZE
Definition: nt_native.h:1291
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MEM_LARGE_PAGES
Definition: nt_native.h:1322
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define PAGE_GUARD
Definition: nt_native.h:1310
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:327
#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 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 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:526
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace(VOID)
Definition: mm.h:1719
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:334
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1691
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:1043
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
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:1704
#define MI_SET_USAGE(x)
Definition: mm.h:317
NTSTATUS NTAPI MmExtendSection(_In_ PVOID Section, _Inout_ PLARGE_INTEGER NewSize)
Definition: section.c:5383
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
SIZE_T MmSharedCommit
Definition: freelist.c:31
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1726
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:268
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:557
#define STATUS_MAPPED_ALIGNMENT
Definition: ntstatus.h:676
#define STATUS_SECTION_PROTECTION
Definition: ntstatus.h:314
#define STATUS_INVALID_PARAMETER_10
Definition: ntstatus.h:484
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:309
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:262
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:483
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:478
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:270
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:480
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:300
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
#define STATUS_INVALID_PARAMETER_8
Definition: ntstatus.h:482
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:117
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:479
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
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:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
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
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS NTAPI MmMapViewInSystemSpace(IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:4452
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:4001
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:4625
POBJECT_TYPE MmSectionObjectType
Definition: section.c:194
#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::@2613 u
LIST_ENTRY DereferenceList
Definition: mmtypes.h:522
ULONG PageFrameNumber
Definition: mmtypes.h:74
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _MEMORY_AREA::@1802 SectionData
ULONG Type
Definition: mm.h:251
ULONG_PTR StartingVpn
Definition: mmtypes.h:653
ULONG_PTR EndingVpn
Definition: mmtypes.h:654
USHORT PrototypePte
Definition: mm.h:363
USHORT Modified
Definition: mm.h:360
USHORT PageLocation
Definition: mm.h:365
Definition: mm.h:374
MMPTE OriginalPte
Definition: mm.h:407
union _MMPFN::@1803 u1
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1805 u3
PKEVENT Event
Definition: mm.h:379
USHORT ReferenceCount
Definition: mm.h:396
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::@2339 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 SystemSpaceHashKey
Definition: miarm.h:470
ULONG SystemSpaceHashEntries
Definition: miarm.h:469
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:465
PRTL_BITMAP SystemSpaceBitMap
Definition: miarm.h:472
PCHAR SystemSpaceViewStart
Definition: miarm.h:466
ULONG SystemSpaceHashSize
Definition: miarm.h:468
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:467
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:464
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
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::@2626 u4
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
union _MMVAD_LONG::@2624 u2
union _MMVAD_LONG::@2623 u
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
union _MMVAD::@2620 u
Definition: miarm.h:457
PCONTROL_AREA ControlArea
Definition: miarm.h:459
ULONG_PTR Entry
Definition: miarm.h:458
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:494
PMMPDE PageTables
Definition: miarm.h:521
MMSESSION Session
Definition: miarm.h:511
SIZE_T CommittedPages
Definition: miarm.h:496
SIZE_T NonPageablePages
Definition: miarm.h:495
UNICODE_STRING Name
Definition: nt_native.h:1270
union _SECTION::@2629 u
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
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::@2611 u1
ULONG NonExtendedPtes
Definition: mmtypes.h:411
ULONG NumberOfCommittedPages
Definition: mmtypes.h:415
ULONG PtesInSubsection
Definition: mmtypes.h:583
MMSUBSECTION_FLAGS SubsectionFlags
Definition: mmtypes.h:577
PCONTROL_AREA ControlArea
Definition: mmtypes.h:573
union _SUBSECTION::@2615 u
PMMPTE SubsectionBase
Definition: mmtypes.h:581
struct _SUBSECTION * NextSubsection
Definition: mmtypes.h:584
#define TAG_MM
Definition: tag.h:113
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:2658
_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:4533
_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:1409
_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
NTSYSAPI VOID NTAPI RtlFillMemoryUlonglong(_Out_writes_bytes_all_(Length) PVOID Destination, _In_ SIZE_T Length, _In_ ULONGLONG Pattern)
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
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_ U