ReactOS 0.4.16-dev-1172-g2041f3c
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);
782
783 /* Delete the actual virtual memory pages */
784 MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
785 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
786 Vad);
787
788 /* Release the working set */
789 MiUnlockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
790
791 /* Lock the PFN database */
792 OldIrql = MiAcquirePfnLock();
793
794 /* Remove references */
795 ControlArea->NumberOfMappedViews--;
796 ControlArea->NumberOfUserReferences--;
797
798 /* Check if it should be destroyed */
799 MiCheckControlArea(ControlArea, OldIrql);
800}
801
802static
806 IN ULONG Flags)
807{
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 /* Find the VAD for the address and make sure it's a section VAD */
822 Vad = MiLocateVad(&Process->VadRoot, BaseAddress);
823 if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
824 {
825 /* Couldn't find it, or invalid VAD, fail */
826 DPRINT1("No VAD or invalid VAD\n");
829 }
830
831 /* Check for RosMm memory area */
832 if (MI_IS_MEMORY_AREA_VAD(Vad))
833 {
834 /* Call Mm API */
838 return Status;
839 }
840
841 /* Check if we should attach to the process */
842 if (CurrentProcess != Process)
843 {
844 /* The process is different, do an attach */
846 Attached = TRUE;
847 }
848
849 /* Check if the process is already dead */
850 if (Process->VmDeleted)
851 {
852 /* Fail the call */
853 DPRINT1("Process died!\n");
856 goto Quickie;
857 }
858
859 /* We should be attached */
861
862 /* We need the base address for the debugger message on image-backed VADs */
863 if (Vad->u.VadFlags.VadType == VadImageMap)
864 {
865 DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
866 }
867
868 /* Compute the size of the VAD region */
869 RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
870
871 /* For SEC_NO_CHANGE sections, we need some extra checks */
872 if (Vad->u.VadFlags.NoChange == 1)
873 {
874 /* Are we allowed to mess with this VAD? */
876 (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
879 if (!NT_SUCCESS(Status))
880 {
881 /* We failed */
882 DPRINT1("Trying to unmap protected VAD!\n");
884 goto Quickie;
885 }
886 }
887
888 /* Not currently supported */
890
891 /* FIXME: Remove VAD charges */
892
893 /* Lock the working set */
895
896 /* Remove the VAD */
897 ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
898 MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
900
901 /* Remove the PTEs for this view, which also releases the working set lock */
903
904 /* FIXME: Remove commitment */
905
906 /* Update performance counter and release the lock */
907 Process->VirtualSize -= RegionSize;
909
910 /* Destroy the VAD and return success */
911 ExFreePool(Vad);
913
914 /* Failure and success case -- send debugger message, detach, and return */
915Quickie:
916 if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
918 return Status;
919}
920
921static
924 IN PVOID EndVa)
925{
928 PMMPDE StartPde, EndPde;
930 PMMPFN Pfn1;
931 PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
932
933 /* Windows sanity checks */
934 ASSERT(StartVa >= (PVOID)MmSessionBase);
936 ASSERT(PAGE_ALIGN(EndVa) == EndVa);
937
938 /* Get the start and end PDE, then loop each one */
939 StartPde = MiAddressToPde(StartVa);
940 EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
941 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
942 while (StartPde <= EndPde)
943 {
944#ifndef _M_AMD64
945 /* If we don't already have a page table for it, increment count */
946 if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
947#endif
948 /* Move to the next one */
949 StartPde++;
950 Index++;
951 }
952
953 /* If there's no page tables to create, bail out */
954 if (PageCount == 0) return STATUS_SUCCESS;
955
956 /* Reset the start PDE and index */
957 StartPde = MiAddressToPde(StartVa);
958 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
959
960 /* Loop each PDE while holding the working set lock */
961// MiLockWorkingSet(PsGetCurrentThread(),
962// &MmSessionSpace->GlobalVirtualAddress->Vm);
963#ifdef _M_AMD64
964_WARN("MiSessionCommitPageTables halfplemented for amd64")
969 DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
970 ASSERT(FALSE);
971#else
972 while (StartPde <= EndPde)
973 {
974 /* Check if we already have a page table */
976 {
977 /* We don't, so the PDE shouldn't be ready yet */
978 ASSERT(StartPde->u.Hard.Valid == 0);
979
980 /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
982
983 /* Acquire the PFN lock and grab a zero page */
984 OldIrql = MiAcquirePfnLock();
986 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
988 PageFrameNumber = MiRemoveZeroPage(Color);
989 TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
990 MI_WRITE_VALID_PDE(StartPde, TempPde);
991
992 /* Write the page table in session space structure */
995
996 /* Initialize the PFN */
997 MiInitializePfnForOtherProcess(PageFrameNumber,
998 StartPde,
1000
1001 /* And now release the lock */
1002 MiReleasePfnLock(OldIrql);
1003
1004 /* Get the PFN entry and make sure there's no event for it */
1005 Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1006 ASSERT(Pfn1->u1.Event == NULL);
1007
1008 /* Increment the number of pages */
1009 ActualPages++;
1010 }
1011
1012 /* Move to the next PDE */
1013 StartPde++;
1014 Index++;
1015 }
1016#endif
1017
1018 /* Make sure we didn't do more pages than expected */
1019 ASSERT(ActualPages <= PageCount);
1020
1021 /* Release the working set lock */
1022// MiUnlockWorkingSet(PsGetCurrentThread(),
1023// &MmSessionSpace->GlobalVirtualAddress->Vm);
1024
1025
1026 /* If we did at least one page... */
1027 if (ActualPages)
1028 {
1029 /* Update the performance counters! */
1032 }
1033
1034 /* Return status */
1035 return STATUS_SUCCESS;
1036}
1037
1040 _In_ PVOID Section,
1041 _In_ PMMSESSION Session,
1045{
1046 PVOID Base;
1047 PCONTROL_AREA ControlArea;
1048 ULONG Buckets;
1049 LONGLONG SectionSize;
1051 PAGED_CODE();
1052
1053 /* Get the control area, check for any flags ARM3 doesn't yet support */
1054 ControlArea = ((PSECTION)Section)->Segment->ControlArea;
1055 ASSERT(ControlArea->u.Flags.Image == 0);
1056 ASSERT(ControlArea->FilePointer == NULL);
1057 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1058 ASSERT(ControlArea->u.Flags.Rom == 0);
1059 ASSERT(ControlArea->u.Flags.WasPurged == 0);
1060
1061 /* Increase the reference and map count on the control area, no purges yet */
1062 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1064
1065 /* Get the section size at creation time */
1066 SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart;
1067
1068 /* If the caller didn't specify a view size, assume until the end of the section */
1069 if (!(*ViewSize))
1070 {
1071 /* Check for overflow first */
1072 if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX)
1073 {
1074 DPRINT1("Section end is too far away from the specified offset.\n");
1075 MiDereferenceControlArea(ControlArea);
1077 }
1078 *ViewSize = SectionSize - SectionOffset->QuadPart;
1079 }
1080
1081 /* Check overflow */
1082 if ((SectionOffset->QuadPart + *ViewSize) < SectionOffset->QuadPart)
1083 {
1084 DPRINT1("Integer overflow between size & offset!\n");
1085 MiDereferenceControlArea(ControlArea);
1087 }
1088
1089 /* Check if the caller wanted a larger section than the view */
1090 if (SectionOffset->QuadPart + *ViewSize > SectionSize)
1091 {
1092 /* Fail */
1093 DPRINT1("View is too large\n");
1094 MiDereferenceControlArea(ControlArea);
1096 }
1097
1098 /* Get the number of 64K buckets required for this mapping */
1100 if (*ViewSize & (MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) Buckets++;
1101
1102 /* Check if the view is more than 4GB large */
1103 if (Buckets >= MI_SYSTEM_VIEW_BUCKET_SIZE)
1104 {
1105 /* Fail */
1106 DPRINT1("View is too large\n");
1107 MiDereferenceControlArea(ControlArea);
1109 }
1110
1111 /* Insert this view into system space and get a base address for it */
1112 Base = MiInsertInSystemSpace(Session, Buckets, ControlArea);
1113 if (!Base)
1114 {
1115 /* Fail */
1116 DPRINT1("Out of system space\n");
1117 MiDereferenceControlArea(ControlArea);
1118 return STATUS_NO_MEMORY;
1119 }
1120
1121 /* What's the underlying session? */
1122 if (Session == &MmSession)
1123 {
1124 /* Create the PDEs needed for this mapping, and double-map them if needed */
1127 }
1128 else
1129 {
1130 /* Create the PDEs needed for this mapping */
1132 (PVOID)((ULONG_PTR)Base +
1133 Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
1135 }
1136
1137 /* Create the actual prototype PTEs for this mapping */
1140 ControlArea,
1141 SectionOffset->QuadPart);
1143
1144 /* Return the base address of the mapping and success */
1145 *MappedBase = Base;
1146 return STATUS_SUCCESS;
1147}
1148
1149static
1156 IN PSECTION Section,
1158 IN ULONG ProtectionMask,
1162{
1163 PMMVAD_LONG Vad;
1164 ULONG_PTR StartAddress;
1165 ULONG_PTR ViewSizeInPages;
1166 PSUBSECTION Subsection;
1168 PFN_NUMBER PteOffset;
1170 ULONG QuotaCharge = 0, QuotaExcess = 0;
1171 PMMPTE PointerPte, LastPte;
1172 MMPTE TempPte;
1173 ULONG Granularity = MM_VIRTMEM_GRANULARITY;
1174
1175 DPRINT("Mapping ARM3 data section\n");
1176
1177 /* Get the segment for this section */
1178 Segment = ControlArea->Segment;
1179
1180#ifdef _M_IX86
1181 /* ALlow being less restrictive on x86. */
1183 Granularity = PAGE_SIZE;
1184#endif
1185
1186 /* One can only reserve a file-based mapping, not shared memory! */
1187 if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1188 {
1190 }
1191
1192 /* First, increase the map count. No purging is supported yet */
1193 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1194 if (!NT_SUCCESS(Status)) return Status;
1195
1196 /* Check if the caller specified the view size */
1197 if (!(*ViewSize))
1198 {
1199 LONGLONG ViewSizeLL;
1200
1201 /* The caller did not, so pick a 64K aligned view size based on the offset */
1202 SectionOffset->LowPart &= ~(_64K - 1);
1203
1204 /* Calculate size and make sure this fits */
1205 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &ViewSizeLL))
1206 || !NT_SUCCESS(RtlLongLongToSIZET(ViewSizeLL, ViewSize))
1207 || (*ViewSize > MAXLONG_PTR))
1208 {
1209 MiDereferenceControlArea(ControlArea);
1211 }
1212 }
1213 else
1214 {
1215 /* A size was specified, align it to a 64K boundary
1216 * and check for overflow or huge value. */
1217 if (!NT_SUCCESS(RtlSIZETAdd(*ViewSize, SectionOffset->LowPart & (_64K - 1), ViewSize))
1218 || (*ViewSize > MAXLONG_PTR))
1219 {
1220 MiDereferenceControlArea(ControlArea);
1222 }
1223
1224 /* Align the offset as well to make this an aligned map */
1225 SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1226 }
1227
1228 /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1229 ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1230
1231 /* Windows ASSERTs for this flag */
1232 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1233
1234 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1235 ASSERT(ControlArea->u.Flags.Rom == 0);
1236 Subsection = (PSUBSECTION)(ControlArea + 1);
1237
1238 /* Sections with extended segments are not supported in ARM3 */
1239 ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1240
1241 /* Within this section, figure out which PTEs will describe the view */
1242 PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1243
1244 /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1245 ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1246 ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1247
1248 /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1249 ASSERT(PteOffset < Subsection->PtesInSubsection);
1250
1251 /* In ARM3, only page-file backed sections (shared memory) are supported now */
1252 ASSERT(ControlArea->FilePointer == NULL);
1253
1254 /* Windows ASSERTs for this too -- there must be a subsection base address */
1255 ASSERT(Subsection->SubsectionBase != NULL);
1256
1257 /* Compute how much commit space the segment will take */
1258 if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1259 {
1260 /* Charge for the maximum pages */
1261 QuotaCharge = BYTES_TO_PAGES(CommitSize);
1262 }
1263
1264 /* ARM3 does not currently support large pages */
1265 ASSERT(Segment->SegmentFlags.LargePages == 0);
1266
1267 /* Calculate how many pages the region spans */
1268 ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1269
1270 /* A VAD can now be allocated. Do so and zero it out */
1271 /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1272 ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1273 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1274 if (!Vad)
1275 {
1276 MiDereferenceControlArea(ControlArea);
1278 }
1279
1280 RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1281 Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1282
1283 /* Write all the data required in the VAD for handling a fault */
1284 Vad->ControlArea = ControlArea;
1285 Vad->u.VadFlags.CommitCharge = 0;
1286 Vad->u.VadFlags.Protection = ProtectionMask;
1287 Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1289 if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1290 {
1291 /* This isn't really implemented yet, but handle setting the flag */
1292 Vad->u.VadFlags.NoChange = 1;
1293 Vad->u2.VadFlags2.SecNoChange = 1;
1294 }
1295
1296 /* Finally, write down the first and last prototype PTE */
1297 Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1298 PteOffset += ViewSizeInPages - 1;
1299 ASSERT(PteOffset < Subsection->PtesInSubsection);
1300 Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1301
1302 /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1304
1305 /* FIXME: Should setup VAD bitmap */
1307
1308 /* Check if anything was committed */
1309 if (QuotaCharge)
1310 {
1311 /* Set the start and end PTE addresses, and pick the template PTE */
1312 PointerPte = Vad->FirstPrototypePte;
1313 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1314 TempPte = Segment->SegmentPteTemplate;
1315
1316 /* Acquire the commit lock and loop all prototype PTEs to be committed */
1318 while (PointerPte < LastPte)
1319 {
1320 /* Make sure the PTE is already invalid */
1321 if (PointerPte->u.Long == 0)
1322 {
1323 /* And write the invalid PTE */
1324 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1325 }
1326 else
1327 {
1328 /* The PTE is valid, so skip it */
1329 QuotaExcess++;
1330 }
1331
1332 /* Move to the next PTE */
1333 PointerPte++;
1334 }
1335
1336 /* Now check how many pages exactly we committed, and update accounting */
1337 ASSERT(QuotaCharge >= QuotaExcess);
1338 QuotaCharge -= QuotaExcess;
1339 Segment->NumberOfCommittedPages += QuotaCharge;
1340 ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1341
1342 /* Now that we're done, release the lock */
1344 }
1345
1346 /* Is it SEC_BASED, or did the caller manually specify an address? */
1347 if (*BaseAddress != NULL)
1348 {
1349 /* Just align what the caller gave us */
1350 StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1351 }
1352 else if (Section->Address.StartingVpn != 0)
1353 {
1354 /* It is a SEC_BASED mapping, use the address that was generated */
1355 StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1356 }
1357 else
1358 {
1359 StartAddress = 0;
1360 }
1361
1363 if (!NT_SUCCESS(Status))
1364 {
1365 ExFreePoolWithTag(Vad, 'ldaV');
1366 MiDereferenceControlArea(ControlArea);
1367
1369 Segment->NumberOfCommittedPages -= QuotaCharge;
1371 return Status;
1372 }
1373
1374 /* Insert the VAD */
1376 &StartAddress,
1377 ViewSizeInPages * PAGE_SIZE,
1379 Granularity,
1381 if (!NT_SUCCESS(Status))
1382 {
1383 ExFreePoolWithTag(Vad, 'ldaV');
1384 MiDereferenceControlArea(ControlArea);
1385
1387 Segment->NumberOfCommittedPages -= QuotaCharge;
1389
1391 return Status;
1392 }
1393
1394 /* Windows stores this for accounting purposes, do so as well */
1395 if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1396
1397 /* Finally, let the caller know where, and for what size, the view was mapped */
1398 *ViewSize = ViewSizeInPages * PAGE_SIZE;
1399 *BaseAddress = (PVOID)StartAddress;
1400 DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1401 return STATUS_SUCCESS;
1402}
1403
1404static
1411 IN ULONG IgnoreFileSizing)
1412{
1413 /* Not yet implemented */
1414 ASSERT(FALSE);
1415 *Segment = NULL;
1417}
1418
1419static
1423 IN ULONG ProtectionMask,
1425{
1426 ULONGLONG SizeLimit;
1427 PFN_COUNT PteCount;
1428 PMMPTE PointerPte;
1429 MMPTE TempPte;
1430 PCONTROL_AREA ControlArea;
1431 PSEGMENT NewSegment;
1432 PSUBSECTION Subsection;
1433 PAGED_CODE();
1434
1435 /* No large pages in ARM3 yet */
1437
1438 /* Pagefile-backed sections need a known size */
1439 if (!MaximumSize || !MaximumSize->QuadPart || MaximumSize->QuadPart < 0)
1441
1442 /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1443 SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
1444 SizeLimit /= sizeof(MMPTE);
1445 SizeLimit <<= PAGE_SHIFT;
1446
1447 /* Fail if this size is too big */
1448 if (MaximumSize->QuadPart > SizeLimit)
1449 {
1451 }
1452
1453 /* Calculate how many Prototype PTEs will be needed */
1454 PteCount = (PFN_COUNT)((MaximumSize->QuadPart + PAGE_SIZE - 1) >> PAGE_SHIFT);
1455
1456 /* For commited memory, we must have a valid protection mask */
1457 if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1458
1459 /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1460 NewSegment = ExAllocatePoolWithTag(PagedPool,
1461 sizeof(SEGMENT) +
1462 sizeof(MMPTE) * (PteCount - 1),
1463 'tSmM');
1464 if (!NewSegment)
1465 {
1467 }
1468 *Segment = NewSegment;
1469
1470 /* Now allocate the control area, which has the subsection structure */
1471 ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1472 sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1473 'tCmM');
1474 if (!ControlArea)
1475 {
1476 ExFreePoolWithTag(Segment, 'tSmM');
1478 }
1479
1480 /* And zero it out, filling the basic segmnet pointer and reference fields */
1481 RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1482 ControlArea->Segment = NewSegment;
1483 ControlArea->NumberOfSectionReferences = 1;
1484 ControlArea->NumberOfUserReferences = 1;
1485
1486 /* Convert allocation attributes to control area flags */
1487 if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1488 if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1489 if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1490
1491 /* We just allocated it */
1492 ControlArea->u.Flags.BeingCreated = 1;
1493
1494 /* The subsection follows, write the mask, PTE count and point back to the CA */
1495 Subsection = (PSUBSECTION)(ControlArea + 1);
1496 Subsection->ControlArea = ControlArea;
1497 Subsection->PtesInSubsection = PteCount;
1498 Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1499
1500 /* Zero out the segment's prototype PTEs, and link it with the control area */
1501 PointerPte = &NewSegment->ThePtes[0];
1502 RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1503 NewSegment->PrototypePte = PointerPte;
1504 NewSegment->ControlArea = ControlArea;
1505
1506 /* Save some extra accounting data for the segment as well */
1507 NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1508 NewSegment->SizeOfSegment = ((ULONGLONG)PteCount) * PAGE_SIZE;
1509 NewSegment->TotalNumberOfPtes = PteCount;
1510 NewSegment->NonExtendedPtes = PteCount;
1511
1512 /* The subsection's base address is the first Prototype PTE in the segment */
1513 Subsection->SubsectionBase = PointerPte;
1514
1515 /* Start with an empty PTE, unless this is a commit operation */
1516 TempPte.u.Long = 0;
1518 {
1519 /* In which case, write down the protection mask in the Prototype PTEs */
1520 TempPte.u.Soft.Protection = ProtectionMask;
1521
1522 /* For accounting, also mark these pages as being committed */
1523 NewSegment->NumberOfCommittedPages = PteCount;
1524 }
1525
1526 /* The template PTE itself for the segment should also have the mask set */
1527 NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1528
1529 /* Write out the prototype PTEs, for now they're simply demand zero */
1530#ifdef _WIN64
1531 RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1532#else
1533 RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1534#endif
1535 return STATUS_SUCCESS;
1536}
1537
1539NTAPI
1541{
1542 PSECTION Section = SectionObject;
1545
1546 /* Check if it's an ARM3, or ReactOS section */
1548 {
1549 /* Return the file pointer stored in the control area */
1550 return Section->Segment->ControlArea->FilePointer;
1551 }
1552
1553 /* Return the file object */
1554 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1555}
1556
1557static
1560 _In_ PMMVAD Vad)
1561{
1562 PCONTROL_AREA ControlArea;
1564
1565 /* Check if this is a RosMm memory area */
1566 if (MI_IS_MEMORY_AREA_VAD(Vad))
1567 {
1569
1570 /* We do not expect ARM3 memory areas here, those are kernel only */
1571 ASSERT(MI_IS_ROSMM_VAD(Vad));
1572
1573 /* Check if it's a section view (RosMm section) */
1575 {
1576 /* Get the section pointer to the SECTION_OBJECT */
1577 FileObject = MemoryArea->SectionData.Segment->FileObject;
1578 }
1579 else
1580 {
1581#ifdef NEWCC
1582 ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1583 DPRINT1("VAD is a cache section!\n");
1584#else
1585 ASSERT(FALSE);
1586#endif
1587 return NULL;
1588 }
1589 }
1590 else
1591 {
1592 /* Make sure it's not a VM VAD */
1593 if (Vad->u.VadFlags.PrivateMemory == 1)
1594 {
1595 DPRINT1("VAD is not a section\n");
1596 return NULL;
1597 }
1598
1599 /* Get the control area */
1600 ControlArea = Vad->ControlArea;
1601 if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1602 {
1603 DPRINT1("Address is not a section\n");
1604 return NULL;
1605 }
1606
1607 /* Get the file object */
1608 FileObject = ControlArea->FilePointer;
1609 }
1610
1611 /* Return the file object */
1612 return FileObject;
1613}
1614
1615VOID
1616NTAPI
1618{
1620
1621 /* Get the section object of this process*/
1622 SectionObject = PsGetCurrentProcess()->SectionObject;
1625
1626 if (SectionObject->u.Flags.Image == 0)
1627 {
1628 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1629 return;
1630 }
1631
1632 /* Return the image information */
1633 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1634}
1635
1636static
1640{
1641 POBJECT_NAME_INFORMATION ObjectNameInfo;
1644
1645 /* Allocate memory for our structure */
1646 ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, 1024, TAG_MM);
1647 if (!ObjectNameInfo) return STATUS_NO_MEMORY;
1648
1649 /* Query the name */
1651 ObjectNameInfo,
1652 1024,
1653 &ReturnLength);
1654 if (!NT_SUCCESS(Status))
1655 {
1656 /* Failed, free memory */
1657 DPRINT1("Name query failed\n");
1658 ExFreePoolWithTag(ObjectNameInfo, TAG_MM);
1659 *ModuleName = NULL;
1660 return Status;
1661 }
1662
1663 /* Success */
1664 *ModuleName = ObjectNameInfo;
1665 return STATUS_SUCCESS;
1666}
1667
1669NTAPI
1672{
1674 PSECTION SectionObject = Section;
1675
1676 /* Make sure it's an image section */
1677 if (SectionObject->u.Flags.Image == 0)
1678 {
1679 /* It's not, fail */
1680 DPRINT1("Not an image section\n");
1682 }
1683
1684 /* Get the file object */
1687}
1688
1690NTAPI
1693{
1694 POBJECT_NAME_INFORMATION ModuleNameInformation;
1697 PMMVAD Vad;
1699
1700 /* Lock address space */
1703
1704 /* Get the VAD */
1705 Vad = MiLocateAddress(Address);
1706 if (Vad == NULL)
1707 {
1708 /* Fail, the address does not exist */
1709 DPRINT1("No VAD at address %p\n", Address);
1712 }
1713
1714 /* Get the file object pointer for the VAD */
1716 if (FileObject == NULL)
1717 {
1718 DPRINT1("Failed to get file object for Address %p\n", Address);
1721 }
1722
1723 /* Reference the file object */
1725
1726 /* Unlock address space */
1728
1729 /* Get the filename of the file object */
1730 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1731
1732 /* Dereference the file object */
1734
1735 /* Check if we were able to get the file object name */
1736 if (NT_SUCCESS(Status))
1737 {
1738 /* Init modulename */
1739 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1741
1742 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1743 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1744
1745 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1746 }
1747
1748 /* Return status */
1749 return Status;
1750}
1751
1753NTAPI
1756 OUT PVOID MemoryInformation,
1757 IN SIZE_T MemoryInformationLength,
1759{
1763 PMEMORY_SECTION_NAME SectionName = NULL;
1765
1768 NULL,
1770 (PVOID*)(&Process),
1771 NULL);
1772
1773 if (!NT_SUCCESS(Status))
1774 {
1775 DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1776 return Status;
1777 }
1778
1780
1781 if (NT_SUCCESS(Status))
1782 {
1783 SectionName = MemoryInformation;
1784 if (PreviousMode != KernelMode)
1785 {
1786 _SEH2_TRY
1787 {
1788 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1789 (PWSTR)(SectionName + 1),
1790 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1792
1794
1795 }
1797 {
1799 }
1800 _SEH2_END;
1801 }
1802 else
1803 {
1804 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1805 (PWSTR)(SectionName + 1),
1806 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1808
1810
1811 }
1812
1814 }
1816 return Status;
1817}
1818
1819VOID
1820NTAPI
1822 IN PMMPTE PointerPte,
1823 IN ULONG ProtectionMask,
1824 IN PMMPFN Pfn1,
1825 IN BOOLEAN UpdateDirty)
1826{
1827 MMPTE TempPte, PreviousPte;
1828 KIRQL OldIrql;
1829 BOOLEAN RebuildPte = FALSE;
1830
1831 //
1832 // User for sanity checking later on
1833 //
1834 PreviousPte = *PointerPte;
1835
1836 //
1837 // Build the PTE and acquire the PFN lock
1838 //
1840 PointerPte,
1841 ProtectionMask,
1842 PreviousPte.u.Hard.PageFrameNumber);
1843 OldIrql = MiAcquirePfnLock();
1844
1845 //
1846 // We don't support I/O mappings in this path yet
1847 //
1848 ASSERT(Pfn1 != NULL);
1849 ASSERT(Pfn1->u3.e1.CacheAttribute != MiWriteCombined);
1850
1851 //
1852 // Make sure new protection mask doesn't get in conflict and fix it if it does
1853 //
1854 if (Pfn1->u3.e1.CacheAttribute == MiCached)
1855 {
1856 //
1857 // This is a cached PFN
1858 //
1859 if (ProtectionMask & (MM_NOCACHE | MM_NOACCESS))
1860 {
1861 RebuildPte = TRUE;
1862 ProtectionMask &= ~(MM_NOCACHE | MM_NOACCESS);
1863 }
1864 }
1865 else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
1866 {
1867 //
1868 // This is a non-cached PFN
1869 //
1870 if ((ProtectionMask & (MM_NOCACHE | MM_NOACCESS)) != MM_NOCACHE)
1871 {
1872 RebuildPte = TRUE;
1873 ProtectionMask &= ~MM_NOACCESS;
1874 ProtectionMask |= MM_NOCACHE;
1875 }
1876 }
1877
1878 if (RebuildPte)
1879 {
1881 PointerPte,
1882 ProtectionMask,
1883 PreviousPte.u.Hard.PageFrameNumber);
1884 }
1885
1886 //
1887 // Write the new PTE, making sure we are only changing the bits
1888 //
1889 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
1890
1891 //
1892 // Flush the TLB
1893 //
1894 ASSERT(PreviousPte.u.Hard.Valid == 1);
1896 ASSERT(PreviousPte.u.Hard.Valid == 1);
1897
1898 //
1899 // Windows updates the relevant PFN1 information, we currently don't.
1900 //
1901 if (UpdateDirty && PreviousPte.u.Hard.Dirty)
1902 {
1903 if (!Pfn1->u3.e1.Modified)
1904 {
1905 DPRINT1("FIXME: Mark PFN as dirty\n");
1906 }
1907 }
1908
1909 //
1910 // Not supported in ARM3
1911 //
1912 ASSERT(FoundVad->u.VadFlags.VadType != VadWriteWatch);
1913
1914 //
1915 // Release the PFN lock, we are done
1916 //
1917 MiReleasePfnLock(OldIrql);
1918}
1919
1920static
1921VOID
1923 IN ULONG NumberOfPtes,
1924 IN PCONTROL_AREA ControlArea,
1925 IN PMMSUPPORT Ws)
1926{
1927 PMMPTE PointerPte, ProtoPte;//, FirstPte;
1928 PMMPDE PointerPde, SystemMapPde;
1929 PMMPFN Pfn1, Pfn2;
1930 MMPTE PteContents;
1931 KIRQL OldIrql;
1932 DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
1933
1934 ASSERT(Ws == NULL);
1935
1936 /* Get the PTE and loop each one */
1937 PointerPte = MiAddressToPte(BaseAddress);
1938 //FirstPte = PointerPte;
1939 while (NumberOfPtes)
1940 {
1941 /* Check if the PTE is already valid */
1942 PteContents = *PointerPte;
1943 if (PteContents.u.Hard.Valid == 1)
1944 {
1945 /* Get the PFN entry */
1946 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
1947
1948 /* Get the PTE */
1949 PointerPde = MiPteToPde(PointerPte);
1950
1951 /* Lock the PFN database and make sure this isn't a mapped file */
1952 OldIrql = MiAcquirePfnLock();
1953 ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
1954
1955 /* Mark the page as modified accordingly */
1956 if (MI_IS_PAGE_DIRTY(&PteContents))
1957 Pfn1->u3.e1.Modified = 1;
1958
1959 /* Was the PDE invalid */
1960 if (PointerPde->u.Long == 0)
1961 {
1962#if (_MI_PAGING_LEVELS == 2)
1963 /* Find the system double-mapped PDE that describes this mapping */
1964 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
1965
1966 /* Make it valid */
1967 ASSERT(SystemMapPde->u.Hard.Valid == 1);
1968 MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
1969#else
1970 DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
1971 ASSERT(FALSE);
1972#endif
1973 }
1974
1975 /* Dereference the PDE and the PTE */
1976 Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
1977 MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
1979 MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
1980
1981 /* Release the PFN lock */
1982 MiReleasePfnLock(OldIrql);
1983 }
1984 else
1985 {
1986 /* Windows ASSERT */
1987 ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
1988
1989 /* Check if this is a prototype pointer PTE */
1990 if (PteContents.u.Soft.Prototype == 1)
1991 {
1992 /* Get the prototype PTE */
1993 ProtoPte = MiProtoPteToPte(&PteContents);
1994
1995 /* We don't support anything else atm */
1996 ASSERT(ProtoPte->u.Long == 0);
1997 }
1998 }
1999
2000 /* Make the PTE into a zero PTE */
2001 PointerPte->u.Long = 0;
2002
2003 /* Move to the next PTE */
2004 PointerPte++;
2005 NumberOfPtes--;
2006 }
2007
2008 /* Flush the TLB */
2010
2011 /* Acquire the PFN lock */
2012 OldIrql = MiAcquirePfnLock();
2013
2014 /* Decrement the accounting counters */
2015 ControlArea->NumberOfUserReferences--;
2016 ControlArea->NumberOfMappedViews--;
2017
2018 /* Check if we should destroy the CA and release the lock */
2019 MiCheckControlArea(ControlArea, OldIrql);
2020}
2021
2022static
2023ULONG
2025 IN PVOID Base,
2026 OUT PCONTROL_AREA *ControlArea)
2027{
2028 ULONG Hash, Size, Count = 0;
2030 PAGED_CODE();
2031
2032 /* Compute the hash for this entry and loop trying to find it */
2033 Entry = (ULONG_PTR)Base >> 16;
2034 Hash = Entry % Session->SystemSpaceHashKey;
2035 while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2036 {
2037 /* Check if we overflew past the end of the hash table */
2038 if (++Hash >= Session->SystemSpaceHashSize)
2039 {
2040 /* Reset the hash to zero and keep searching from the bottom */
2041 Hash = 0;
2042 if (++Count == 2)
2043 {
2044 /* But if we overflew twice, then this is not a real mapping */
2045 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2046 (ULONG_PTR)Base,
2047 1,
2048 0,
2049 0);
2050 }
2051 }
2052 }
2053
2054 /* One less entry */
2055 Session->SystemSpaceHashEntries--;
2056
2057 /* Extract the size and clear the entry */
2058 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2059 Session->SystemSpaceViewTable[Hash].Entry = 0;
2060
2061 /* Return the control area and the size */
2062 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2063 return Size;
2064}
2065
2066static
2070{
2071 ULONG Size;
2072 PCONTROL_AREA ControlArea;
2073 PAGED_CODE();
2074
2075 /* Remove this mapping */
2076 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2077 Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2078
2079 /* Clear the bits for this mapping */
2080 RtlClearBits(Session->SystemSpaceBitMap,
2081 (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2082 Size);
2083
2084 /* Convert the size from a bit size into the actual size */
2085 Size = Size * (_64K >> PAGE_SHIFT);
2086
2087 /* Remove the PTEs now */
2088 MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2089 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2090
2091 /* Return success */
2092 return STATUS_SUCCESS;
2093}
2094
2095/* PUBLIC FUNCTIONS ***********************************************************/
2096
2097/*
2098 * @implemented
2099 */
2101NTAPI
2105 IN PLARGE_INTEGER InputMaximumSize,
2110{
2111 SECTION Section;
2112 PSECTION NewSection;
2113 PSUBSECTION Subsection;
2114 PSEGMENT NewSegment, Segment;
2116 PCONTROL_AREA ControlArea;
2117 ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2119 BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2120 KIRQL OldIrql;
2122 BOOLEAN UserRefIncremented = FALSE;
2123 PVOID PreviousSectionPointer;
2124
2125 /* Make the same sanity checks that the Nt interface should've validated */
2128 SEC_NO_CHANGE)) == 0);
2138
2139 /* Convert section flag to page flag */
2142
2143 /* Check to make sure the protection is correct. Nt* does this already */
2145 if (ProtectionMask == MM_INVALID_PROTECTION)
2146 {
2147 DPRINT1("Invalid protection mask\n");
2149 }
2150
2151 /* Check if this is going to be a data or image backed file section */
2152 if ((FileHandle) || (FileObject))
2153 {
2154 /* These cannot be mapped with large pages */
2156
2157 /* For now, only support the mechanism through a file handle */
2159
2160 /* Reference the file handle to get the object */
2162 MmMakeFileAccess[ProtectionMask],
2165 (PVOID*)&File,
2166 NULL);
2167 if (!NT_SUCCESS(Status)) return Status;
2168
2169 /* Make sure Cc has been doing its job */
2170 if (!File->SectionObjectPointer)
2171 {
2172 /* This is not a valid file system-based file, fail */
2175 }
2176
2177 /* Image-file backed sections are not yet supported */
2179
2180 /* Compute the size of the control area, and allocate it */
2181 ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2182 ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2183 if (!ControlArea)
2184 {
2187 }
2188
2189 /* Zero it out */
2190 RtlZeroMemory(ControlArea, ControlAreaSize);
2191
2192 /* Did we get a handle, or an object? */
2193 if (FileHandle)
2194 {
2195 /* We got a file handle so we have to lock down the file */
2196#if 0
2198 if (!NT_SUCCESS(Status))
2199 {
2200 ExFreePool(ControlArea);
2202 return Status;
2203 }
2204#else
2205 /* ReactOS doesn't support this API yet, so do nothing */
2208#endif
2209 /* Update the top-level IRP so that drivers know what's happening */
2211 FileLock = TRUE;
2212 }
2213
2214 /* Lock the PFN database while we play with the section pointers */
2215 OldIrql = MiAcquirePfnLock();
2216
2217 /* Image-file backed sections are not yet supported */
2219
2220 /* There should not already be a control area for this file */
2221 ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2222 NewSegment = NULL;
2223
2224 /* Write down that this CA is being created, and set it */
2225 ControlArea->u.Flags.BeingCreated = TRUE;
2227 PreviousSectionPointer = File->SectionObjectPointer;
2228 File->SectionObjectPointer->DataSectionObject = ControlArea;
2229
2230 /* We can release the PFN lock now */
2231 MiReleasePfnLock(OldIrql);
2232
2233 /* We don't support previously-mapped file */
2234 ASSERT(NewSegment == NULL);
2235
2236 /* Image-file backed sections are not yet supported */
2238
2239 /* So we always create a data file map */
2241 &Segment,
2242 (PSIZE_T)InputMaximumSize,
2245 KernelCall);
2246 if (!NT_SUCCESS(Status))
2247 {
2248 /* Lock the PFN database while we play with the section pointers */
2249 OldIrql = MiAcquirePfnLock();
2250
2251 /* Reset the waiting-for-deletion event */
2252 ASSERT(ControlArea->WaitingForDeletion == NULL);
2253 ControlArea->WaitingForDeletion = NULL;
2254
2255 /* Set the file pointer NULL flag */
2256 ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2257 ControlArea->u.Flags.FilePointerNull = TRUE;
2258
2259 /* Delete the data section object */
2261 File->SectionObjectPointer->DataSectionObject = NULL;
2262
2263 /* No longer being created */
2264 ControlArea->u.Flags.BeingCreated = FALSE;
2265
2266 /* We can release the PFN lock now */
2267 MiReleasePfnLock(OldIrql);
2268
2269 /* Check if we locked and set the IRP */
2270 if (FileLock)
2271 {
2272 /* Undo */
2274 //FsRtlReleaseFile(File);
2275 }
2276
2277 /* Free the control area and de-ref the file object */
2278 ExFreePool(ControlArea);
2280
2281 /* All done */
2282 return Status;
2283 }
2284
2285 /* On success, we expect this */
2286 ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2287
2288 /* Check if a maximum size was specified */
2289 if (!InputMaximumSize->QuadPart)
2290 {
2291 /* Nope, use the segment size */
2292 Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2293 }
2294 else
2295 {
2296 /* Yep, use the entered size */
2297 Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2298 }
2299 }
2300 else
2301 {
2302 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2304
2305 /* Not yet supported */
2307
2308 /* So this must be a pagefile-backed section, create the mappings needed */
2309 Status = MiCreatePagingFileMap(&NewSegment,
2310 InputMaximumSize,
2311 ProtectionMask,
2313 if (!NT_SUCCESS(Status)) return Status;
2314
2315 /* Set the size here, and read the control area */
2316 Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2317 ControlArea = NewSegment->ControlArea;
2318
2319 /* MiCreatePagingFileMap increments user references */
2320 UserRefIncremented = TRUE;
2321 }
2322
2323 /* Did we already have a segment? */
2324 if (!NewSegment)
2325 {
2326 /* This must be the file path and we created a segment */
2327 NewSegment = Segment;
2328 ASSERT(File != NULL);
2329
2330 /* Acquire the PFN lock while we set control area flags */
2331 OldIrql = MiAcquirePfnLock();
2332
2333 /* We don't support this race condition yet, so assume no waiters */
2334 ASSERT(ControlArea->WaitingForDeletion == NULL);
2335 ControlArea->WaitingForDeletion = NULL;
2336
2337 /* Image-file backed sections are not yet supported, nor ROM images */
2339 ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2340
2341 /* Take off the being created flag, and then release the lock */
2342 ControlArea->u.Flags.BeingCreated = FALSE;
2343 MiReleasePfnLock(OldIrql);
2344 }
2345
2346 /* Check if we locked the file earlier */
2347 if (FileLock)
2348 {
2349 /* Reset the top-level IRP and release the lock */
2351 //FsRtlReleaseFile(File);
2352 FileLock = FALSE;
2353 }
2354
2355 /* Set the initial section object data */
2357
2358 /* The mapping created a control area and segment, save the flags */
2359 Section.Segment = NewSegment;
2360 Section.u.LongFlags = ControlArea->u.LongFlags;
2361
2362 /* Check if this is a user-mode read-write non-image file mapping */
2363 if (!(FileObject) &&
2365 !(ControlArea->u.Flags.Image) &&
2366 (ControlArea->FilePointer))
2367 {
2368 /* Add a reference and set the flag */
2369 Section.u.Flags.UserWritable = TRUE;
2370 InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2371 }
2372
2373 /* Check for image mappings or page file mappings */
2374 if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2375 {
2376 /* Charge the segment size, and allocate a subsection */
2377 PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2378 Size = sizeof(SUBSECTION);
2379 }
2380 else
2381 {
2382 /* Charge nothing, and allocate a mapped subsection */
2383 PagedCharge = 0;
2384 Size = sizeof(MSUBSECTION);
2385 }
2386
2387 /* Check if this is a normal CA */
2388 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2389 ASSERT(ControlArea->u.Flags.Rom == 0);
2390
2391 /* Charge only a CA, and the subsection is right after */
2392 NonPagedCharge = sizeof(CONTROL_AREA);
2393 Subsection = (PSUBSECTION)(ControlArea + 1);
2394
2395 /* We only support single-subsection mappings */
2396 NonPagedCharge += Size;
2397 ASSERT(Subsection->NextSubsection == NULL);
2398
2399 /* Create the actual section object, with enough space for the prototype PTEs */
2404 NULL,
2405 sizeof(SECTION),
2406 PagedCharge,
2407 NonPagedCharge,
2408 (PVOID*)&NewSection);
2409 if (!NT_SUCCESS(Status))
2410 {
2411 /* Check if this is a user-mode read-write non-image file mapping */
2412 if (!(FileObject) &&
2414 !(ControlArea->u.Flags.Image) &&
2415 (ControlArea->FilePointer))
2416 {
2417 /* Remove a reference and check the flag */
2418 ASSERT(Section.u.Flags.UserWritable == 1);
2419 InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2420 }
2421
2422 /* Check if a user reference was added */
2423 if (UserRefIncremented)
2424 {
2425 /* Acquire the PFN lock while we change counters */
2426 OldIrql = MiAcquirePfnLock();
2427
2428 /* Decrement the accounting counters */
2429 ControlArea->NumberOfSectionReferences--;
2430 ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2431 ControlArea->NumberOfUserReferences--;
2432
2433 /* Check if we should destroy the CA and release the lock */
2434 MiCheckControlArea(ControlArea, OldIrql);
2435 }
2436
2437 /* Return the failure code */
2438 return Status;
2439 }
2440
2441 /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2442
2443 /* Now copy the local section object from the stack into this new object */
2444 RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2445 NewSection->Address.StartingVpn = 0;
2446
2447 /* For now, only user calls are supported */
2448 ASSERT(KernelCall == FALSE);
2449 NewSection->u.Flags.UserReference = TRUE;
2450
2451 /* Is this a "based" allocation, in which all mappings are identical? */
2453 {
2454 /* Lock the VAD tree during the search */
2456
2457 /* Is it a brand new ControArea ? */
2458 if (ControlArea->u.Flags.BeingCreated == 1)
2459 {
2460 ASSERT(ControlArea->u.Flags.Based == 1);
2461 /* Then we must find a global address, top-down */
2464 _64K,
2466 (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2467
2468 if (!NT_SUCCESS(Status))
2469 {
2470 /* No way to find a valid range. */
2472 ControlArea->u.Flags.Based = 0;
2473 NewSection->u.Flags.Based = 0;
2474 ObDereferenceObject(NewSection);
2475 return Status;
2476 }
2477
2478 /* Compute the ending address and insert it into the VAD tree */
2479 NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2480 NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2481 MiInsertBasedSection(NewSection);
2482 }
2483 else
2484 {
2485 /* 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 !*/
2486 ASSERT(FALSE);
2487 }
2488
2490 }
2491
2492 /* The control area is not being created anymore */
2493 if (ControlArea->u.Flags.BeingCreated == 1)
2494 {
2495 /* Acquire the PFN lock while we set control area flags */
2496 OldIrql = MiAcquirePfnLock();
2497
2498 /* Take off the being created flag, and then release the lock */
2499 ControlArea->u.Flags.BeingCreated = 0;
2500 NewSection->u.Flags.BeingCreated = 0;
2501
2502 MiReleasePfnLock(OldIrql);
2503 }
2504
2505 /* Migrate the attribute into a flag */
2507
2508 /* If R/W access is not requested, this might eventually become a CoW mapping */
2510 {
2511 NewSection->u.Flags.CopyOnWrite = TRUE;
2512 }
2513
2514 /* Write down if this was a kernel call */
2515 ControlArea->u.Flags.WasPurged |= KernelCall;
2516 ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2517
2518 /* Make sure the segment and the section are the same size, or the section is smaller */
2519 ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2520
2521 /* Return the object and the creation status */
2522 *SectionObject = (PVOID)NewSection;
2523 return Status;
2524}
2525
2526/*
2527 * @implemented
2528 */
2530NTAPI
2541{
2544 PSECTION Section;
2545 PCONTROL_AREA ControlArea;
2546 ULONG ProtectionMask;
2548 ULONG64 CalculatedViewSize;
2549 PAGED_CODE();
2550
2551 /* Get the segment and control area */
2552 Section = (PSECTION)SectionObject;
2553 ControlArea = Section->Segment->ControlArea;
2554
2555 /* These flags/states are not yet supported by ARM3 */
2556 ASSERT(Section->u.Flags.Image == 0);
2557 ASSERT(Section->u.Flags.NoCache == 0);
2558 ASSERT(Section->u.Flags.WriteCombined == 0);
2559 ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
2560
2561 /* FIXME */
2562 if ((AllocationType & MEM_RESERVE) != 0)
2563 {
2564 DPRINT1("MmMapViewOfArm3Section called with MEM_RESERVE, this is not implemented yet!!!\n");
2566 }
2567
2568 /* Check if the mapping protection is compatible with the create */
2570 {
2571 DPRINT1("Mapping protection is incompatible\n");
2573 }
2574
2575 /* Check if the offset and size would cause an overflow */
2576 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) <
2577 (ULONG64)SectionOffset->QuadPart)
2578 {
2579 DPRINT1("Section offset overflows\n");
2581 }
2582
2583 /* Check if the offset and size are bigger than the section itself */
2584 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) >
2585 (ULONG64)Section->SizeOfSection.QuadPart)
2586 {
2587 DPRINT1("Section offset is larger than section\n");
2589 }
2590
2591 /* Check if the caller did not specify a view size */
2592 if (!(*ViewSize))
2593 {
2594 /* Compute it for the caller */
2595 CalculatedViewSize = Section->SizeOfSection.QuadPart -
2596 SectionOffset->QuadPart;
2597
2598 /* Check if it's larger than 4GB or overflows into kernel-mode */
2599 if (!NT_SUCCESS(RtlULongLongToSIZET(CalculatedViewSize, ViewSize)) ||
2600 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < CalculatedViewSize))
2601 {
2602 DPRINT1("Section view won't fit\n");
2604 }
2605 }
2606
2607 /* Check if the commit size is larger than the view size */
2608 if (CommitSize > *ViewSize)
2609 {
2610 DPRINT1("Attempting to commit more than the view itself\n");
2612 }
2613
2614 /* Check if the view size is larger than the section */
2615 if (*ViewSize > (ULONG64)Section->SizeOfSection.QuadPart)
2616 {
2617 DPRINT1("The view is larger than the section\n");
2619 }
2620
2621 /* Compute and validate the protection mask */
2622 ProtectionMask = MiMakeProtectionMask(Protect);
2623 if (ProtectionMask == MM_INVALID_PROTECTION)
2624 {
2625 DPRINT1("The protection is invalid\n");
2627 }
2628
2629 /* We only handle pagefile-backed sections, which cannot be writecombined */
2631 {
2632 DPRINT1("Cannot write combine a pagefile-backed section\n");
2634 }
2635
2636 /* Start by attaching to the current process if needed */
2638 {
2640 Attached = TRUE;
2641 }
2642
2643 /* Do the actual mapping */
2644 Status = MiMapViewOfDataSection(ControlArea,
2645 Process,
2648 ViewSize,
2649 Section,
2651 ProtectionMask,
2652 CommitSize,
2653 ZeroBits,
2655
2656 /* Detach if needed, then return status */
2658 return Status;
2659}
2660
2661/*
2662 * @unimplemented
2663 */
2664BOOLEAN
2665NTAPI
2667{
2669 return FALSE;
2670}
2671
2672/*
2673 * @unimplemented
2674 */
2675BOOLEAN
2676NTAPI
2679{
2681 return FALSE;
2682}
2683
2684/*
2685 * @implemented
2686 */
2688NTAPI
2692{
2693 PAGED_CODE();
2695
2696 // HACK
2697 if (MiIsRosSectionObject(Section))
2698 {
2699 return MmMapViewInSystemSpace(Section, MappedBase, ViewSize);
2700 }
2701
2702 /* Process must be in a session */
2703 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2704 {
2705 DPRINT1("Process is not in session\n");
2707 }
2708
2709 /* Use the system space API, but with the session view instead */
2711 SectionOffset.QuadPart = 0;
2712 return MiMapViewInSystemSpace(Section,
2714 MappedBase,
2715 ViewSize,
2716 &SectionOffset);
2717}
2718
2719/*
2720 * @implemented
2721 */
2723NTAPI
2725{
2726 PAGED_CODE();
2727
2728 // HACK
2730 {
2732 }
2733
2734 /* Process must be in a session */
2735 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2736 {
2737 DPRINT1("Proess is not in session\n");
2739 }
2740
2741 /* Use the system space API, but with the session view instead */
2744 MappedBase);
2745}
2746
2747/*
2748 * @implemented
2749 */
2751NTAPI
2754{
2756}
2757
2758/*
2759 * @implemented
2760 */
2762NTAPI
2764{
2766 PAGED_CODE();
2767
2768 /* Was this mapped by RosMm? */
2772 {
2775 return Status;
2776 }
2778
2779 /* It was not, call the ARM3 routine */
2781}
2782
2783/*
2784 * @implemented
2785 */
2787NTAPI
2790{
2791 ULONG_PTR StartAddress, EndingAddress, Base;
2792 ULONG Hash, Count = 0, Size, QuotaCharge;
2793 PMMSESSION Session;
2794 PMMPTE LastProtoPte, PointerPte, ProtoPte;
2795 PCONTROL_AREA ControlArea;
2797 PSUBSECTION Subsection;
2798 MMPTE TempPte;
2799 PAGED_CODE();
2800
2801 /* Make sure the base isn't past the session view range */
2804 {
2805 DPRINT1("Base outside of valid range\n");
2807 }
2808
2809 /* Make sure the size isn't past the session view range */
2812 {
2813 DPRINT1("Size outside of valid range\n");
2815 }
2816
2817 /* Sanity check */
2818 ASSERT(ViewSize != 0);
2819
2820 /* Process must be in a session */
2821 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2822 {
2823 DPRINT1("Process is not in session\n");
2825 }
2826
2827 /* Compute the correctly aligned base and end addresses */
2828 StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
2829 EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
2830
2831 /* Sanity check and grab the session */
2833 Session = &MmSessionSpace->Session;
2834
2835 /* Get the hash entry for this allocation */
2836 Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
2837
2838 /* Lock system space */
2840
2841 /* Loop twice so we can try rolling over if needed */
2842 while (TRUE)
2843 {
2844 /* Extract the size and base addresses from the entry */
2845 Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
2846 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2847
2848 /* Convert the size to bucket chunks */
2850
2851 /* Bail out if this entry fits in here */
2852 if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
2853
2854 /* Check if we overflew past the end of the hash table */
2855 if (++Hash >= Session->SystemSpaceHashSize)
2856 {
2857 /* Reset the hash to zero and keep searching from the bottom */
2858 Hash = 0;
2859 if (++Count == 2)
2860 {
2861 /* But if we overflew twice, then this is not a real mapping */
2862 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2863 Base,
2864 2,
2865 0,
2866 0);
2867 }
2868 }
2869 }
2870
2871 /* Make sure the view being mapped is not file-based */
2872 ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2873 if (ControlArea->FilePointer != NULL)
2874 {
2875 /* It is, so we have to bail out */
2876 DPRINT1("Only page-filed backed sections can be commited\n");
2879 }
2880
2881 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
2882 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2883 ASSERT(ControlArea->u.Flags.Rom == 0);
2884 Subsection = (PSUBSECTION)(ControlArea + 1);
2885
2886 /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
2887 ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
2888 QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
2889 LastProtoPte = ProtoPte + QuotaCharge;
2890 if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
2891 {
2892 DPRINT1("PTE is out of bounds\n");
2895 }
2896
2897 /* Acquire the commit lock and count all the non-committed PTEs */
2899 PointerPte = ProtoPte;
2900 while (PointerPte < LastProtoPte)
2901 {
2902 if (PointerPte->u.Long) QuotaCharge--;
2903 PointerPte++;
2904 }
2905
2906 /* Was everything committed already? */
2907 if (!QuotaCharge)
2908 {
2909 /* Nothing to do! */
2912 return STATUS_SUCCESS;
2913 }
2914
2915 /* Pick the segment and template PTE */
2916 Segment = ControlArea->Segment;
2917 TempPte = Segment->SegmentPteTemplate;
2918 ASSERT(TempPte.u.Long != 0);
2919
2920 /* Loop all prototype PTEs to be committed */
2921 PointerPte = ProtoPte;
2922 while (PointerPte < LastProtoPte)
2923 {
2924 /* Make sure the PTE is already invalid */
2925 if (PointerPte->u.Long == 0)
2926 {
2927 /* And write the invalid PTE */
2928 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2929 }
2930
2931 /* Move to the next PTE */
2932 PointerPte++;
2933 }
2934
2935 /* Check if we had at least one page charged */
2936 if (QuotaCharge)
2937 {
2938 /* Update the accounting data */
2939 Segment->NumberOfCommittedPages += QuotaCharge;
2941 }
2942
2943 /* Release all */
2946 return STATUS_SUCCESS;
2947}
2948
2949VOID
2950NTAPI
2952{
2954 PCONTROL_AREA ControlArea;
2955 KIRQL OldIrql;
2956
2957 SectionObject = (PSECTION)ObjectBody;
2958
2959 if (SectionObject->u.Flags.Based == 1)
2960 {
2961 /* Remove the node from the global section address tree */
2965 }
2966
2967 /* Lock the PFN database */
2968 OldIrql = MiAcquirePfnLock();
2969
2970 ASSERT(SectionObject->Segment);
2971 ASSERT(SectionObject->Segment->ControlArea);
2972
2973 ControlArea = SectionObject->Segment->ControlArea;
2974
2975 /* Dereference */
2976 ControlArea->NumberOfSectionReferences--;
2977 ControlArea->NumberOfUserReferences--;
2978
2979 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
2980
2981 /* Check it. It will delete it if there is no more reference to it */
2982 MiCheckControlArea(ControlArea, OldIrql);
2983}
2984
2985ULONG
2986NTAPI
2988{
2990 return 0;
2991}
2992
2993/* SYSTEM CALLS ***************************************************************/
2994
2996NTAPI
2997NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage,
2998 IN PVOID File2MappedAsFile)
2999{
3001 PMMVAD Vad1, Vad2;
3002 PFILE_OBJECT FileObject1, FileObject2;
3004
3005 /* Lock address space */
3008
3009 /* Get the VAD for Address 1 */
3010 Vad1 = MiLocateAddress(File1MappedAsAnImage);
3011 if (Vad1 == NULL)
3012 {
3013 /* Fail, the address does not exist */
3014 DPRINT1("No VAD at address 1 %p\n", File1MappedAsAnImage);
3016 goto Exit;
3017 }
3018
3019 /* Get the VAD for Address 2 */
3020 Vad2 = MiLocateAddress(File2MappedAsFile);
3021 if (Vad2 == NULL)
3022 {
3023 /* Fail, the address does not exist */
3024 DPRINT1("No VAD at address 2 %p\n", File2MappedAsFile);
3026 goto Exit;
3027 }
3028
3029 /* Get the file object pointer for VAD 1 */
3030 FileObject1 = MiGetFileObjectForVad(Vad1);
3031 if (FileObject1 == NULL)
3032 {
3033 DPRINT1("Failed to get file object for Address 1 %p\n", File1MappedAsAnImage);
3035 goto Exit;
3036 }
3037
3038 /* Get the file object pointer for VAD 2 */
3039 FileObject2 = MiGetFileObjectForVad(Vad2);
3040 if (FileObject2 == NULL)
3041 {
3042 DPRINT1("Failed to get file object for Address 2 %p\n", File2MappedAsFile);
3044 goto Exit;
3045 }
3046
3047 /* Make sure Vad1 is an image mapping */
3048 if (Vad1->u.VadFlags.VadType != VadImageMap)
3049 {
3050 DPRINT1("Address 1 (%p) is not an image mapping\n", File1MappedAsAnImage);
3052 goto Exit;
3053 }
3054
3055 /* SectionObjectPointer is equal if the files are equal */
3056 if (FileObject1->SectionObjectPointer == FileObject2->SectionObjectPointer)
3057 {
3059 }
3060 else
3061 {
3063 }
3064
3065Exit:
3066 /* Unlock address space */
3068 return Status;
3069}
3070
3071/*
3072 * @implemented
3073 */
3075NTAPI
3083{
3084 LARGE_INTEGER SafeMaximumSize;
3086 HANDLE Handle;
3089 PAGED_CODE();
3090
3091 /* Check for non-existing flags */
3094 SEC_NO_CHANGE)))
3095 {
3096 if (!(AllocationAttributes & 1))
3097 {
3098 DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
3100 }
3101 }
3102
3103 /* Check for no allocation type */
3105 {
3106 DPRINT1("Missing allocation type in allocation attributes\n");
3108 }
3109
3110 /* Check for image allocation with invalid attributes */
3114 {
3115 DPRINT1("Image allocation with invalid attributes\n");
3117 }
3118
3119 /* Check for allocation type is both commit and reserve */
3121 {
3122 DPRINT1("Commit and reserve in the same time\n");
3124 }
3125
3126 /* Now check for valid protection */
3131 {
3132 DPRINT1("Sections don't support these protections\n");
3134 }
3135
3136 /* Use a maximum size of zero, if none was specified */
3137 SafeMaximumSize.QuadPart = 0;
3138
3139 /* Check for user-mode caller */
3140 if (PreviousMode != KernelMode)
3141 {
3142 /* Enter SEH */
3143 _SEH2_TRY
3144 {
3145 /* Safely check user-mode parameters */
3146 if (MaximumSize) SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
3147 MaximumSize = &SafeMaximumSize;
3148 ProbeForWriteHandle(SectionHandle);
3149 }
3151 {
3152 /* Return the exception code */
3154 }
3155 _SEH2_END;
3156 }
3157 else if (!MaximumSize) MaximumSize = &SafeMaximumSize;
3158
3159 /* Check that MaximumSize is valid if backed by paging file */
3160 if ((!FileHandle) && (!MaximumSize->QuadPart))
3162
3163 /* Create the section */
3170 FileHandle,
3171 NULL);
3172 if (!NT_SUCCESS(Status)) return Status;
3173
3174 /* FIXME: Should zero last page for a file mapping */
3175
3176 /* Now insert the object */
3178 NULL,
3180 0,
3181 NULL,
3182 &Handle);
3183 if (NT_SUCCESS(Status))
3184 {
3185 /* Enter SEH */
3186 _SEH2_TRY
3187 {
3188 /* Return the handle safely */
3189 *SectionHandle = Handle;
3190 }
3192 {
3193 /* Nothing here */
3194 }
3195 _SEH2_END;
3196 }
3197
3198 /* Return the status */
3199 return Status;
3200}
3201
3203NTAPI
3207{
3208 HANDLE Handle;
3211 PAGED_CODE();
3212
3213 /* Check for user-mode caller */
3214 if (PreviousMode != KernelMode)
3215 {
3216 /* Enter SEH */
3217 _SEH2_TRY
3218 {
3219 /* Safely check user-mode parameters */
3220 ProbeForWriteHandle(SectionHandle);
3221 }
3223 {
3224 /* Return the exception code */
3226 }
3227 _SEH2_END;
3228 }
3229
3230 /* Try opening the object */
3234 NULL,
3236 NULL,
3237 &Handle);
3238
3239 /* Enter SEH */
3240 _SEH2_TRY
3241 {
3242 /* Return the handle safely */
3243 *SectionHandle = Handle;
3244 }
3246 {
3247 /* Nothing here */
3248 }
3249 _SEH2_END;
3250
3251 /* Return the status */
3252 return Status;
3253}
3254
3256NTAPI
3267{
3268 PVOID SafeBaseAddress;
3269 LARGE_INTEGER SafeSectionOffset;
3270 SIZE_T SafeViewSize;
3271 PSECTION Section;
3275 ULONG ProtectionMask;
3277#if defined(_M_IX86) || defined(_M_AMD64)
3278 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3280#else
3281 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3283#endif
3284
3285 /* Check for invalid inherit disposition */
3287 {
3288 DPRINT1("Invalid inherit disposition\n");
3290 }
3291
3292 /* Allow only valid allocation types */
3293 if (AllocationType & ~ValidAllocationType)
3294 {
3295 DPRINT1("Invalid allocation type\n");
3297 }
3298
3299 /* Convert the protection mask, and validate it */
3300 ProtectionMask = MiMakeProtectionMask(Protect);
3301 if (ProtectionMask == MM_INVALID_PROTECTION)
3302 {
3303 DPRINT1("Invalid page protection\n");
3305 }
3306
3307 /* Now convert the protection mask into desired section access mask */
3308 DesiredAccess = MmMakeSectionAccess[ProtectionMask & 0x7];
3309
3310 /* Assume no section offset */
3311 SafeSectionOffset.QuadPart = 0;
3312
3313 /* Enter SEH */
3314 _SEH2_TRY
3315 {
3316 /* Check for unsafe parameters */
3317 if (PreviousMode != KernelMode)
3318 {
3319 /* Probe the parameters */
3322 }
3323
3324 /* Check if a section offset was given */
3325 if (SectionOffset)
3326 {
3327 /* Check for unsafe parameters and capture section offset */
3329 SafeSectionOffset = *SectionOffset;
3330 }
3331
3332 /* Capture the other parameters */
3333 SafeBaseAddress = *BaseAddress;
3334 SafeViewSize = *ViewSize;
3335 }
3337 {
3338 /* Return the exception code */
3340 }
3341 _SEH2_END;
3342
3343 /* Check for kernel-mode address */
3344 if (SafeBaseAddress > MM_HIGHEST_VAD_ADDRESS)
3345 {
3346 DPRINT1("Kernel base not allowed\n");
3348 }
3349
3350 /* Check for range entering kernel-mode */
3351 if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)SafeBaseAddress) < SafeViewSize)
3352 {
3353 DPRINT1("Overflowing into kernel base not allowed\n");
3355 }
3356
3357 /* Check for invalid zero bits */
3358 if (ZeroBits)
3359 {
3361 {
3362 DPRINT1("Invalid zero bits\n");
3364 }
3365
3366 if ((((ULONG_PTR)SafeBaseAddress << ZeroBits) >> ZeroBits) != (ULONG_PTR)SafeBaseAddress)
3367 {
3368 DPRINT1("Invalid zero bits\n");
3370 }
3371
3372 if (((((ULONG_PTR)SafeBaseAddress + SafeViewSize) << ZeroBits) >> ZeroBits) != ((ULONG_PTR)SafeBaseAddress + SafeViewSize))
3373 {
3374 DPRINT1("Invalid zero bits\n");
3376 }
3377 }
3378
3379 /* Reference the process */
3384 (PVOID*)&Process,
3385 NULL);
3386 if (!NT_SUCCESS(Status)) return Status;
3387
3388 /* Reference the section */
3389 Status = ObReferenceObjectByHandle(SectionHandle,
3393 (PVOID*)&Section,
3394 NULL);
3395 if (!NT_SUCCESS(Status))
3396 {
3398 return Status;
3399 }
3400
3401 if (Section->u.Flags.PhysicalMemory)
3402 {
3403 if (PreviousMode == UserMode &&
3404 SafeSectionOffset.QuadPart + SafeViewSize > MmHighestPhysicalPage << PAGE_SHIFT)
3405 {
3406 DPRINT1("Denying map past highest physical page.\n");
3407 ObDereferenceObject(Section);
3410 }
3411 }
3412 else if (!(AllocationType & MEM_DOS_LIM))
3413 {
3414 /* Check for non-allocation-granularity-aligned BaseAddress */
3415 if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
3416 {
3417 DPRINT("BaseAddress is not at 64-kilobyte address boundary.\n");
3418 ObDereferenceObject(Section);
3421 }
3422
3423 /* Do the same for the section offset */
3424 if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
3425 {
3426 DPRINT("SectionOffset is not at 64-kilobyte address boundary.\n");
3427 ObDereferenceObject(Section);
3430 }
3431 }
3432
3433 /* Now do the actual mapping */
3434 Status = MmMapViewOfSection(Section,
3435 Process,
3436 &SafeBaseAddress,
3437 ZeroBits,
3438 CommitSize,
3439 &SafeSectionOffset,
3440 &SafeViewSize,
3443 Protect);
3444
3445 /* Return data only on success */
3446 if (NT_SUCCESS(Status))
3447 {
3448 /* Check if this is an image for the current process */
3449 if ((Section->u.Flags.Image) &&
3452 {
3453 /* Notify the debugger */
3454 DbgkMapViewOfSection(Section,
3455 SafeBaseAddress,
3456 SafeSectionOffset.LowPart,
3457 SafeViewSize);
3458 }
3459
3460 /* Enter SEH */
3461 _SEH2_TRY
3462 {
3463 /* Return parameters to user */
3464 *BaseAddress = SafeBaseAddress;
3465 *ViewSize = SafeViewSize;
3466 if (SectionOffset) *SectionOffset = SafeSectionOffset;
3467 }
3469 {
3470 /* Nothing to do */
3471 }
3472 _SEH2_END;
3473 }
3474
3475 /* Dereference all objects and return status */
3476 ObDereferenceObject(Section);
3478 return Status;
3479}
3480
3482NTAPI
3485{
3489
3490 /* Don't allowing mapping kernel views */
3492 {
3493 DPRINT1("Trying to unmap a kernel view\n");
3495 }
3496
3497 /* Reference the process */
3502 (PVOID*)&Process,
3503 NULL);
3504 if (!NT_SUCCESS(Status)) return Status;
3505
3506 /* Unmap the view */
3508
3509 /* Dereference the process and return status */
3511 return Status;
3512}
3513
3515NTAPI
3517 IN OUT PLARGE_INTEGER NewMaximumSize)
3518{
3519 LARGE_INTEGER SafeNewMaximumSize;
3520 PSECTION Section;
3523
3524 /* Check for user-mode parameters */
3525 if (PreviousMode != KernelMode)
3526 {
3527 /* Enter SEH */
3528 _SEH2_TRY
3529 {
3530 /* Probe and capture the maximum size, it's both read and write */
3531 ProbeForWriteLargeInteger(NewMaximumSize);
3532 SafeNewMaximumSize = *NewMaximumSize;
3533 }
3535 {
3536 /* Return the exception code */
3538 }
3539 _SEH2_END;
3540 }
3541 else
3542 {
3543 /* Just read the size directly */
3544 SafeNewMaximumSize = *NewMaximumSize;
3545 }
3546
3547 /* Reference the section */
3548 Status = ObReferenceObjectByHandle(SectionHandle,
3552 (PVOID*)&Section,
3553 NULL);
3554 if (!NT_SUCCESS(Status)) return Status;
3555
3556 Status = MmExtendSection(Section, &SafeNewMaximumSize);
3557
3558 /* Dereference the section */
3559 ObDereferenceObject(Section);
3560
3561 if (NT_SUCCESS(Status))
3562 {
3563 _SEH2_TRY
3564 {
3565 /* Write back the new size */
3566 *NewMaximumSize = SafeNewMaximumSize;
3567 }
3569 {
3571 }
3572 _SEH2_END;
3573 }
3574
3575 /* Return the status */
3577}
3578
3579/* EOF */
static NTSTATUS MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:530
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:2763
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1559
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:1754
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:1039
BOOLEAN NTAPI MmForceSectionClosed(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
Definition: section.c:2677
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3483
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:1670
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:3076
MMSESSION MmSession
Definition: section.c:107
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3204
static ULONG MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2024
VOID NTAPI MiFlushTbAndCapture(IN PMMVAD FoundVad, IN PMMPTE PointerPte, IN ULONG ProtectionMask, IN PMMPFN Pfn1, IN BOOLEAN UpdateDirty)
Definition: section.c:1821
ULONG NTAPI MmDoesFileHaveUserWritableReferences(IN PSECTION_OBJECT_POINTERS SectionPointer)
Definition: section.c:2987
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:2102
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:1617
VOID NTAPI MiDeleteARM3Section(PVOID ObjectBody)
Definition: section.c:2951
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:3257
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:1406
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:2531
NTSTATUS NTAPI MmUnmapViewInSessionSpace(IN PVOID MappedBase)
Definition: section.c:2724
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:2689
static NTSTATUS MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1421
static NTSTATUS MiSessionCommitPageTables(IN PVOID StartVa, IN PVOID EndVa)
Definition: section.c:923
static VOID MiRemoveMappedPtes(IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
Definition: section.c:1922
PVOID MmHighSectionBase
Definition: section.c:111
static NTSTATUS MiUnmapViewInSystemSpace(IN PMMSESSION Session, IN PVOID MappedBase)
Definition: section.c:2068
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:2997
static NTSTATUS MiUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
Definition: section.c:804
NTSTATUS NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName)
Definition: section.c:1691
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:1151
NTSTATUS NTAPI MmCommitSessionMappedView(IN PVOID MappedBase, IN SIZE_T ViewSize)
Definition: section.c:2788
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID SectionObject)
Definition: section.c:1540
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:2752
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
BOOLEAN NTAPI MmDisableModifiedWriteOfSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: section.c:2666
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:1638
NTSTATUS NTAPI NtExtendSection(IN HANDLE SectionHandle, IN OUT PLARGE_INTEGER NewMaximumSize)
Definition: section.c:3516
#define PAGED_CODE()
#define ALIGN_DOWN_BY(size, align)
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
ULONG_PTR PFN_NUMBER
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
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
#define ExGetPreviousMode
Definition: ex.h:143
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1369
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL KeReleaseGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:75
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
VOID FASTCALL KeAcquireGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:64
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:167
#define PROCESS_VM_OPERATION
Definition: pstypes.h:161
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:211
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
#define MM_EXECUTE_WRITECOPY
Definition: miarm.h:50
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:537
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:831
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:386
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:403
ULONG MmSecondaryColorMask
Definition: mminit.c:257
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1101
#define MM_GUARDPAGE
Definition: miarm.h:57
PMMVAD NTAPI MiLocateVad(_In_ PMM_AVL_TABLE Table, _In_ PVOID VirtualAddress)
Definition: vadnode.c:116
ULONG NTAPI MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress, IN KIRQL OldIrql)
Definition: virtual.c:235
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:208
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree(IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base)
Definition: vadnode.c:711
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:185
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:611
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:236
#define MM_NOCACHE
Definition: miarm.h:56
#define MM_DELETE_CHECK
Definition: miarm.h:260
#define MM_EXECUTE_READWRITE
Definition: miarm.h:49
#define _64K
Definition: miarm.h:23
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1301
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1021
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:265
#define MM_EXECUTE
Definition: miarm.h:45
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1242
#define MM_EXECUTE_READ
Definition: miarm.h:46
@ MiWriteCombined
Definition: miarm.h:416
@ MiCached
Definition: miarm.h:415
@ MiNonCached
Definition: miarm.h:414
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:996
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:4569
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:265
#define SYSTEM_PD_SIZE
Definition: miarm.h:32
#define MM_NOACCESS
Definition: miarm.h:65
NTSTATUS NTAPI MiInsertVadEx(_Inout_ PMMVAD Vad, _In_ ULONG_PTR *BaseAddress, _In_ SIZE_T ViewSize, _In_ ULONG_PTR HighestAddress, _In_ ULONG_PTR Alignment, _In_ ULONG AllocationType)
Definition: vadnode.c:245
VOID NTAPI MiDeleteVirtualAddresses(_In_ ULONG_PTR Va, _In_ ULONG_PTR EndingAddress, _In_opt_ PMMVAD Vad)
Definition: virtual.c:530
struct _MMVIEW MMVIEW
NTSTATUS NTAPI MiCheckSecuredVad(IN PMMVAD Vad, IN PVOID Base, IN SIZE_T Size, IN ULONG ProtectionMask)
Definition: vadnode.c:815
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:981
NTSTATUS NTAPI MiRosUnmapViewOfSection(_In_ PEPROCESS Process, _In_ PMEMORY_AREA MemoryArea, _In_ PVOID BaseAddress, _In_ BOOLEAN SkipDebuggerNotify)
Definition: section.c:3602
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1577
SIZE_T MmSizeOfPagedPoolInBytes
Definition: miarm.h:589
#define MM_WRITECOPY
Definition: miarm.h:48
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1172
#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
struct _MMPTE MMPTE
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT InheritDisposition
Definition: mmfuncs.h:409
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:363
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:405
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:364
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG AllocationType
Definition: mmfuncs.h:410
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
struct _SUBSECTION * PSUBSECTION
@ VadWriteWatch
Definition: mmtypes.h:208
@ VadRotatePhysical
Definition: mmtypes.h:210
@ VadImageMap
Definition: mmtypes.h:206
@ VadNone
Definition: mmtypes.h:204
struct _SUBSECTION SUBSECTION
#define SEC_NOCACHE
Definition: mmtypes.h:101
struct _SEGMENT SEGMENT
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SEC_IMAGE
Definition: mmtypes.h:97
#define MEM_DOS_LIM
Definition: mmtypes.h:90
struct _MSUBSECTION MSUBSECTION
#define SEC_LARGE_PAGES
Definition: mmtypes.h:103
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
struct _SECTION * PSECTION
struct _CONTROL_AREA CONTROL_AREA
@ ActiveAndValid
Definition: mmtypes.h:159
@ ModifiedPageList
Definition: mmtypes.h:156
@ StandbyPageList
Definition: mmtypes.h:155
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2478
_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:331
#define SEC_BASED
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1653
#define MI_IS_PAGE_DIRTY(x)
Definition: mm.h:112
#define 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:528
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace(VOID)
Definition: mm.h:1724
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MI_SET_PROCESS2(x)
Definition: mm.h:330
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:345
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1696
#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:61
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:97
struct _MEMORY_AREA * PMEMORY_AREA
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1709
#define MI_SET_USAGE(x)
Definition: mm.h:328
NTSTATUS NTAPI MmExtendSection(_In_ PVOID Section, _Inout_ PLARGE_INTEGER NewSize)
Definition: section.c:5390
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1770
#define MI_IS_MEMORY_AREA_VAD(Vad)
Definition: mm.h:272
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define MI_IS_ROSMM_VAD(Vad)
Definition: mm.h:274
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
SIZE_T MmSharedCommit
Definition: freelist.c:31
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1731
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:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
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
NTSTATUS NTAPI MmMapViewInSystemSpace(IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:4459
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:4009
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:4632
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::@2705 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::@1841 SectionData
ULONG Type
Definition: mm.h:258
ULONG_PTR StartingVpn
Definition: mmtypes.h:653
ULONG_PTR EndingVpn
Definition: mmtypes.h:654
USHORT PrototypePte
Definition: mm.h:374
USHORT Modified
Definition: mm.h:371
USHORT PageLocation
Definition: mm.h:376
Definition: mm.h:391
union _MMPFN::@1842 u1
MMPTE OriginalPte
Definition: mm.h:427
MMPFNENTRY e1
Definition: mm.h:414
union _MMPFN::@1844 u3
PKEVENT Event
Definition: mm.h:396
USHORT ReferenceCount
Definition: mm.h:413
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::@2423 u
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG PhysicalMemory
Definition: mmtypes.h:473
ULONG BeingDeleted
Definition: mmtypes.h:463
ULONG NoChange
Definition: mmtypes.h:486
ULONG UserReference
Definition: mmtypes.h:479
ULONG CopyOnWrite
Definition: mmtypes.h:474
ULONG FilePointerNull
Definition: mmtypes.h:482
ULONG WriteCombined
Definition: mmtypes.h:493
ULONG BeingCreated
Definition: mmtypes.h:464
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:491
ULONG WasPurged
Definition: mmtypes.h:478
ULONG UserWritable
Definition: mmtypes.h:489
ULONG SystemSpaceHashKey
Definition: miarm.h:460
ULONG SystemSpaceHashEntries
Definition: miarm.h:459
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:455
PRTL_BITMAP SystemSpaceBitMap
Definition: miarm.h:462
PCHAR SystemSpaceViewStart
Definition: miarm.h:456
ULONG SystemSpaceHashSize
Definition: miarm.h:458
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:457
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:454
ULONG FileOffset
Definition: mmtypes.h:706
ULONG Inherit
Definition: mmtypes.h:713
ULONG SecNoChange
Definition: mmtypes.h:707
ULONG_PTR NoChange
Definition: mmtypes.h:693
ULONG_PTR Protection
Definition: mmtypes.h:696
ULONG_PTR CommitCharge
Definition: mmtypes.h:691
ULONG_PTR VadType
Definition: mmtypes.h:694
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
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::@2716 u2
union _MMVAD_LONG::@2718 u4
union _MMVAD_LONG::@2715 u
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
union _MMVAD::@2712 u
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
Definition: miarm.h:447
PCONTROL_AREA ControlArea
Definition: miarm.h:449
ULONG_PTR Entry
Definition: miarm.h:448
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:484
PMMPDE PageTables
Definition: miarm.h:511
MMSESSION Session
Definition: miarm.h:501
SIZE_T CommittedPages
Definition: miarm.h:486
SIZE_T NonPageablePages
Definition: miarm.h:485
UNICODE_STRING Name
Definition: nt_native.h:1270
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
ULONG LongFlags
Definition: mmtypes.h:816
PSEGMENT Segment
Definition: mmtypes.h:812
ULONG InitialPageProtection
Definition: mmtypes.h:819
union _SECTION::@2721 u
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
union _SEGMENT::@2703 u1
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
ULONG NonExtendedPtes
Definition: mmtypes.h:411
ULONG NumberOfCommittedPages
Definition: mmtypes.h:415
union _SUBSECTION::@2707 u
ULONG PtesInSubsection
Definition: mmtypes.h:583
MMSUBSECTION_FLAGS SubsectionFlags
Definition: mmtypes.h:577
PCONTROL_AREA ControlArea
Definition: mmtypes.h:573
PMMPTE SubsectionBase
Definition: mmtypes.h:581
struct _SUBSECTION * NextSubsection
Definition: mmtypes.h:584
#define TAG_MM
Definition: tag.h:112
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ALIGN_DOWN_POINTER_BY(ptr, align)
Definition: umtypes.h:82
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
static BOOL Attached
Definition: vidbios.c:3905
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h: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:1572
_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)
char CHAR
Definition: xmlstorage.h:175
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:221