ReactOS 0.4.15-dev-7788-g1ad9096
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
116NTAPI
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
286PVOID
287NTAPI
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
529NTAPI
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
589VOID
590NTAPI
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
712VOID
713NTAPI
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
747VOID
748NTAPI
750{
752
753 /* Lock the PFN database */
754 OldIrql = MiAcquirePfnLock();
755
756 /* Drop reference counts */
757 ControlArea->NumberOfMappedViews--;
758 ControlArea->NumberOfUserReferences--;
759
760 /* Check if it's time to delete the CA. This releases the lock */
761 MiCheckControlArea(ControlArea, OldIrql);
762}
763
764VOID
765NTAPI
767 IN PMMVAD Vad)
768{
770 PCONTROL_AREA ControlArea;
771 PETHREAD CurrentThread = PsGetCurrentThread();
772
773 /* Get the control area */
774 ControlArea = Vad->ControlArea;
775
776 /* We only support non-extendable, non-image, pagefile-backed regular sections */
777 ASSERT(Vad->u.VadFlags.VadType == VadNone);
778 ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
779 ASSERT(ControlArea);
780 ASSERT(ControlArea->FilePointer == NULL);
781
782 /* Delete the actual virtual memory pages */
783 MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
784 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
785 Vad);
786
787 /* Release the working set */
788 MiUnlockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
789
790 /* Lock the PFN database */
791 OldIrql = MiAcquirePfnLock();
792
793 /* Remove references */
794 ControlArea->NumberOfMappedViews--;
795 ControlArea->NumberOfUserReferences--;
796
797 /* Check if it should be destroyed */
798 MiCheckControlArea(ControlArea, OldIrql);
799}
800
802NTAPI
805 IN ULONG Flags)
806{
810 PMMVAD Vad;
811 PVOID DbgBase = NULL;
814 PETHREAD CurrentThread = PsGetCurrentThread();
815 PEPROCESS CurrentProcess = PsGetCurrentProcess();
816 PAGED_CODE();
817
818 /* Check if we need to lock the address space */
819 if (!Flags) MmLockAddressSpace(&Process->Vm);
820
821 /* Check for Mm Region */
824 {
825 /* Call Mm API */
828 return Status;
829 }
830
831 /* Check if we should attach to the process */
832 if (CurrentProcess != Process)
833 {
834 /* The process is different, do an attach */
836 Attached = TRUE;
837 }
838
839 /* Check if the process is already dead */
840 if (Process->VmDeleted)
841 {
842 /* Fail the call */
843 DPRINT1("Process died!\n");
846 goto Quickie;
847 }
848
849 /* Find the VAD for the address and make sure it's a section VAD */
851 if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
852 {
853 /* Couldn't find it, or invalid VAD, fail */
854 DPRINT1("No VAD or invalid VAD\n");
857 goto Quickie;
858 }
859
860 /* We should be attached */
862
863 /* We need the base address for the debugger message on image-backed VADs */
864 if (Vad->u.VadFlags.VadType == VadImageMap)
865 {
866 DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
867 }
868
869 /* Compute the size of the VAD region */
870 RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
871
872 /* For SEC_NO_CHANGE sections, we need some extra checks */
873 if (Vad->u.VadFlags.NoChange == 1)
874 {
875 /* Are we allowed to mess with this VAD? */
877 (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
880 if (!NT_SUCCESS(Status))
881 {
882 /* We failed */
883 DPRINT1("Trying to unmap protected VAD!\n");
885 goto Quickie;
886 }
887 }
888
889 /* Not currently supported */
891
892 /* FIXME: Remove VAD charges */
893
894 /* Lock the working set */
896
897 /* Remove the VAD */
898 ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
899 MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
901
902 /* Remove the PTEs for this view, which also releases the working set lock */
904
905 /* FIXME: Remove commitment */
906
907 /* Update performance counter and release the lock */
908 Process->VirtualSize -= RegionSize;
910
911 /* Destroy the VAD and return success */
912 ExFreePool(Vad);
914
915 /* Failure and success case -- send debugger message, detach, and return */
916Quickie:
917 if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
919 return Status;
920}
921
923NTAPI
925 IN PVOID EndVa)
926{
929 PMMPDE StartPde, EndPde;
931 PMMPFN Pfn1;
932 PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
933
934 /* Windows sanity checks */
935 ASSERT(StartVa >= (PVOID)MmSessionBase);
937 ASSERT(PAGE_ALIGN(EndVa) == EndVa);
938
939 /* Get the start and end PDE, then loop each one */
940 StartPde = MiAddressToPde(StartVa);
941 EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
942 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
943 while (StartPde <= EndPde)
944 {
945#ifndef _M_AMD64
946 /* If we don't already have a page table for it, increment count */
947 if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
948#endif
949 /* Move to the next one */
950 StartPde++;
951 Index++;
952 }
953
954 /* If there's no page tables to create, bail out */
955 if (PageCount == 0) return STATUS_SUCCESS;
956
957 /* Reset the start PDE and index */
958 StartPde = MiAddressToPde(StartVa);
959 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
960
961 /* Loop each PDE while holding the working set lock */
962// MiLockWorkingSet(PsGetCurrentThread(),
963// &MmSessionSpace->GlobalVirtualAddress->Vm);
964#ifdef _M_AMD64
965_WARN("MiSessionCommitPageTables halfplemented for amd64")
970 DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
971 ASSERT(FALSE);
972#else
973 while (StartPde <= EndPde)
974 {
975 /* Check if we already have a page table */
977 {
978 /* We don't, so the PDE shouldn't be ready yet */
979 ASSERT(StartPde->u.Hard.Valid == 0);
980
981 /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
983
984 /* Acquire the PFN lock and grab a zero page */
985 OldIrql = MiAcquirePfnLock();
987 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
989 PageFrameNumber = MiRemoveZeroPage(Color);
990 TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
991 MI_WRITE_VALID_PDE(StartPde, TempPde);
992
993 /* Write the page table in session space structure */
996
997 /* Initialize the PFN */
998 MiInitializePfnForOtherProcess(PageFrameNumber,
999 StartPde,
1001
1002 /* And now release the lock */
1003 MiReleasePfnLock(OldIrql);
1004
1005 /* Get the PFN entry and make sure there's no event for it */
1006 Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1007 ASSERT(Pfn1->u1.Event == NULL);
1008
1009 /* Increment the number of pages */
1010 ActualPages++;
1011 }
1012
1013 /* Move to the next PDE */
1014 StartPde++;
1015 Index++;
1016 }
1017#endif
1018
1019 /* Make sure we didn't do more pages than expected */
1020 ASSERT(ActualPages <= PageCount);
1021
1022 /* Release the working set lock */
1023// MiUnlockWorkingSet(PsGetCurrentThread(),
1024// &MmSessionSpace->GlobalVirtualAddress->Vm);
1025
1026
1027 /* If we did at least one page... */
1028 if (ActualPages)
1029 {
1030 /* Update the performance counters! */
1033 }
1034
1035 /* Return status */
1036 return STATUS_SUCCESS;
1037}
1038
1041 _In_ PVOID Section,
1042 _In_ PMMSESSION Session,
1046{
1047 PVOID Base;
1048 PCONTROL_AREA ControlArea;
1049 ULONG Buckets;
1050 LONGLONG SectionSize;
1052 PAGED_CODE();
1053
1054 /* Get the control area, check for any flags ARM3 doesn't yet support */
1055 ControlArea = ((PSECTION)Section)->Segment->ControlArea;
1056 ASSERT(ControlArea->u.Flags.Image == 0);
1057 ASSERT(ControlArea->FilePointer == NULL);
1058 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1059 ASSERT(ControlArea->u.Flags.Rom == 0);
1060 ASSERT(ControlArea->u.Flags.WasPurged == 0);
1061
1062 /* Increase the reference and map count on the control area, no purges yet */
1063 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1065
1066 /* Get the section size at creation time */
1067 SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart;
1068
1069 /* If the caller didn't specify a view size, assume until the end of the section */
1070 if (!(*ViewSize))
1071 {
1072 /* Check for overflow first */
1073 if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX)
1074 {
1075 DPRINT1("Section end is too far away from the specified offset.\n");
1076 MiDereferenceControlArea(ControlArea);
1078 }
1079 *ViewSize = SectionSize - SectionOffset->QuadPart;
1080 }
1081
1082 /* Check overflow */
1083 if ((SectionOffset->QuadPart + *ViewSize) < SectionOffset->QuadPart)
1084 {
1085 DPRINT1("Integer overflow between size & offset!\n");
1086 MiDereferenceControlArea(ControlArea);
1088 }
1089
1090 /* Check if the caller wanted a larger section than the view */
1091 if (SectionOffset->QuadPart + *ViewSize > SectionSize)
1092 {
1093 /* Fail */
1094 DPRINT1("View is too large\n");
1095 MiDereferenceControlArea(ControlArea);
1097 }
1098
1099 /* Get the number of 64K buckets required for this mapping */
1101 if (*ViewSize & (MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) Buckets++;
1102
1103 /* Check if the view is more than 4GB large */
1104 if (Buckets >= MI_SYSTEM_VIEW_BUCKET_SIZE)
1105 {
1106 /* Fail */
1107 DPRINT1("View is too large\n");
1108 MiDereferenceControlArea(ControlArea);
1110 }
1111
1112 /* Insert this view into system space and get a base address for it */
1113 Base = MiInsertInSystemSpace(Session, Buckets, ControlArea);
1114 if (!Base)
1115 {
1116 /* Fail */
1117 DPRINT1("Out of system space\n");
1118 MiDereferenceControlArea(ControlArea);
1119 return STATUS_NO_MEMORY;
1120 }
1121
1122 /* What's the underlying session? */
1123 if (Session == &MmSession)
1124 {
1125 /* Create the PDEs needed for this mapping, and double-map them if needed */
1128 }
1129 else
1130 {
1131 /* Create the PDEs needed for this mapping */
1133 (PVOID)((ULONG_PTR)Base +
1134 Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
1136 }
1137
1138 /* Create the actual prototype PTEs for this mapping */
1141 ControlArea,
1142 SectionOffset->QuadPart);
1144
1145 /* Return the base address of the mapping and success */
1146 *MappedBase = Base;
1147 return STATUS_SUCCESS;
1148}
1149
1150VOID
1151NTAPI
1153{
1154 KIRQL OldIrql;
1155
1157
1158 OldIrql = MiAcquirePfnLock();
1159 ControlArea->u.Flags.DebugSymbolsLoaded |= 1;
1160
1162 MiReleasePfnLock(OldIrql);
1164}
1165
1166VOID
1167NTAPI
1171{
1174 PLIST_ENTRY NextEntry;
1176 PIMAGE_NT_HEADERS NtHeaders;
1177 PLDR_DATA_TABLE_ENTRY LdrEntry;
1178
1179 FileName = &ControlArea->FilePointer->FileName;
1180 if (FileName->Length == 0)
1181 {
1182 return;
1183 }
1184
1185 /* Acquire module list lock */
1188
1189 /* Browse list to try to find current module */
1190 for (NextEntry = MmLoadedUserImageList.Flink;
1191 NextEntry != &MmLoadedUserImageList;
1192 NextEntry = NextEntry->Flink)
1193 {
1194 /* Get the entry */
1195 LdrEntry = CONTAINING_RECORD(NextEntry,
1197 InLoadOrderLinks);
1198
1199 /* If already in the list, increase load count */
1200 if (LdrEntry->DllBase == BaseAddress)
1201 {
1202 ++LdrEntry->LoadCount;
1203 break;
1204 }
1205 }
1206
1207 /* Not in the list, we'll add it */
1208 if (NextEntry == &MmLoadedUserImageList)
1209 {
1210 /* Allocate our element, taking to the name string and its null char */
1211 LdrEntry = ExAllocatePoolWithTag(NonPagedPool, FileName->Length + sizeof(UNICODE_NULL) + sizeof(*LdrEntry), 'bDmM');
1212 if (LdrEntry)
1213 {
1214 memset(LdrEntry, 0, FileName->Length + sizeof(UNICODE_NULL) + sizeof(*LdrEntry));
1215
1216 _SEH2_TRY
1217 {
1218 /* Get image checksum and size */
1219 NtHeaders = RtlImageNtHeader(BaseAddress);
1220 if (NtHeaders)
1221 {
1222 LdrEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
1223 LdrEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
1224 }
1225 }
1227 {
1228 ExFreePoolWithTag(LdrEntry, 'bDmM');
1231 _SEH2_YIELD(return);
1232 }
1233 _SEH2_END;
1234
1235 /* Fill all the details */
1236 LdrEntry->DllBase = BaseAddress;
1237 LdrEntry->FullDllName.Buffer = (PVOID)((ULONG_PTR)LdrEntry + sizeof(*LdrEntry));
1238 LdrEntry->FullDllName.Length = FileName->Length;
1239 LdrEntry->FullDllName.MaximumLength = FileName->Length + sizeof(UNICODE_NULL);
1240 memcpy(LdrEntry->FullDllName.Buffer, FileName->Buffer, FileName->Length);
1241 LdrEntry->FullDllName.Buffer[LdrEntry->FullDllName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1242 LdrEntry->LoadCount = 1;
1243
1244 /* Insert! */
1246 }
1247 }
1248
1249 /* Release locks */
1252
1253 /* Load symbols */
1255 if (NT_SUCCESS(Status))
1256 {
1259 }
1260}
1261
1263NTAPI
1269 IN PSECTION Section,
1271 IN ULONG ProtectionMask,
1275{
1276 PMMVAD_LONG Vad;
1277 ULONG_PTR StartAddress;
1278 ULONG_PTR ViewSizeInPages;
1279 PSUBSECTION Subsection;
1281 PFN_NUMBER PteOffset;
1283 ULONG QuotaCharge = 0, QuotaExcess = 0;
1284 PMMPTE PointerPte, LastPte;
1285 MMPTE TempPte;
1286 ULONG Granularity = MM_VIRTMEM_GRANULARITY;
1287
1288 DPRINT("Mapping ARM3 data section\n");
1289
1290 /* Get the segment for this section */
1291 Segment = ControlArea->Segment;
1292
1293#ifdef _M_IX86
1294 /* ALlow being less restrictive on x86. */
1296 Granularity = PAGE_SIZE;
1297#endif
1298
1299 /* One can only reserve a file-based mapping, not shared memory! */
1300 if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1301 {
1303 }
1304
1305 /* First, increase the map count. No purging is supported yet */
1306 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1307 if (!NT_SUCCESS(Status)) return Status;
1308
1309 /* Check if the caller specified the view size */
1310 if (!(*ViewSize))
1311 {
1312 LONGLONG ViewSizeLL;
1313
1314 /* The caller did not, so pick a 64K aligned view size based on the offset */
1315 SectionOffset->LowPart &= ~(_64K - 1);
1316
1317 /* Calculate size and make sure this fits */
1318 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &ViewSizeLL))
1319 || !NT_SUCCESS(RtlLongLongToSIZET(ViewSizeLL, ViewSize))
1320 || (*ViewSize > MAXLONG_PTR))
1321 {
1322 MiDereferenceControlArea(ControlArea);
1324 }
1325 }
1326 else
1327 {
1328 /* A size was specified, align it to a 64K boundary
1329 * and check for overflow or huge value. */
1330 if (!NT_SUCCESS(RtlSIZETAdd(*ViewSize, SectionOffset->LowPart & (_64K - 1), ViewSize))
1331 || (*ViewSize > MAXLONG_PTR))
1332 {
1333 MiDereferenceControlArea(ControlArea);
1335 }
1336
1337 /* Align the offset as well to make this an aligned map */
1338 SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1339 }
1340
1341 /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1342 ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1343
1344 /* Windows ASSERTs for this flag */
1345 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1346
1347 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1348 ASSERT(ControlArea->u.Flags.Rom == 0);
1349 Subsection = (PSUBSECTION)(ControlArea + 1);
1350
1351 /* Sections with extended segments are not supported in ARM3 */
1352 ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1353
1354 /* Within this section, figure out which PTEs will describe the view */
1355 PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1356
1357 /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1358 ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1359 ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1360
1361 /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1362 ASSERT(PteOffset < Subsection->PtesInSubsection);
1363
1364 /* In ARM3, only page-file backed sections (shared memory) are supported now */
1365 ASSERT(ControlArea->FilePointer == NULL);
1366
1367 /* Windows ASSERTs for this too -- there must be a subsection base address */
1368 ASSERT(Subsection->SubsectionBase != NULL);
1369
1370 /* Compute how much commit space the segment will take */
1371 if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1372 {
1373 /* Charge for the maximum pages */
1374 QuotaCharge = BYTES_TO_PAGES(CommitSize);
1375 }
1376
1377 /* ARM3 does not currently support large pages */
1378 ASSERT(Segment->SegmentFlags.LargePages == 0);
1379
1380 /* Calculate how many pages the region spans */
1381 ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1382
1383 /* A VAD can now be allocated. Do so and zero it out */
1384 /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1385 ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1386 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1387 if (!Vad)
1388 {
1389 MiDereferenceControlArea(ControlArea);
1391 }
1392
1393 RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1394 Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1395
1396 /* Write all the data required in the VAD for handling a fault */
1397 Vad->ControlArea = ControlArea;
1398 Vad->u.VadFlags.CommitCharge = 0;
1399 Vad->u.VadFlags.Protection = ProtectionMask;
1400 Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1402 if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1403 {
1404 /* This isn't really implemented yet, but handle setting the flag */
1405 Vad->u.VadFlags.NoChange = 1;
1406 Vad->u2.VadFlags2.SecNoChange = 1;
1407 }
1408
1409 /* Finally, write down the first and last prototype PTE */
1410 Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1411 PteOffset += ViewSizeInPages - 1;
1412 ASSERT(PteOffset < Subsection->PtesInSubsection);
1413 Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1414
1415 /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1417
1418 /* FIXME: Should setup VAD bitmap */
1420
1421 /* Check if anything was committed */
1422 if (QuotaCharge)
1423 {
1424 /* Set the start and end PTE addresses, and pick the template PTE */
1425 PointerPte = Vad->FirstPrototypePte;
1426 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1427 TempPte = Segment->SegmentPteTemplate;
1428
1429 /* Acquire the commit lock and loop all prototype PTEs to be committed */
1431 while (PointerPte < LastPte)
1432 {
1433 /* Make sure the PTE is already invalid */
1434 if (PointerPte->u.Long == 0)
1435 {
1436 /* And write the invalid PTE */
1437 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1438 }
1439 else
1440 {
1441 /* The PTE is valid, so skip it */
1442 QuotaExcess++;
1443 }
1444
1445 /* Move to the next PTE */
1446 PointerPte++;
1447 }
1448
1449 /* Now check how many pages exactly we committed, and update accounting */
1450 ASSERT(QuotaCharge >= QuotaExcess);
1451 QuotaCharge -= QuotaExcess;
1452 Segment->NumberOfCommittedPages += QuotaCharge;
1453 ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1454
1455 /* Now that we're done, release the lock */
1457 }
1458
1459 /* Is it SEC_BASED, or did the caller manually specify an address? */
1460 if (*BaseAddress != NULL)
1461 {
1462 /* Just align what the caller gave us */
1463 StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1464 }
1465 else if (Section->Address.StartingVpn != 0)
1466 {
1467 /* It is a SEC_BASED mapping, use the address that was generated */
1468 StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1469 }
1470 else
1471 {
1472 StartAddress = 0;
1473 }
1474
1476 if (!NT_SUCCESS(Status))
1477 {
1478 ExFreePoolWithTag(Vad, 'ldaV');
1479 MiDereferenceControlArea(ControlArea);
1480
1482 Segment->NumberOfCommittedPages -= QuotaCharge;
1484 return Status;
1485 }
1486
1487 /* Insert the VAD */
1489 &StartAddress,
1490 ViewSizeInPages * PAGE_SIZE,
1492 Granularity,
1494 if (!NT_SUCCESS(Status))
1495 {
1496 ExFreePoolWithTag(Vad, 'ldaV');
1497 MiDereferenceControlArea(ControlArea);
1498
1500 Segment->NumberOfCommittedPages -= QuotaCharge;
1502
1504 return Status;
1505 }
1506
1507 /* Windows stores this for accounting purposes, do so as well */
1508 if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1509
1510 /* Finally, let the caller know where, and for what size, the view was mapped */
1511 *ViewSize = ViewSizeInPages * PAGE_SIZE;
1512 *BaseAddress = (PVOID)StartAddress;
1513 DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1514 return STATUS_SUCCESS;
1515}
1516
1517VOID
1518NTAPI
1520{
1521 /* ReactOS only supports systems with 4K pages and 4K sectors */
1522 ASSERT(Subsection->u.SubsectionFlags.SectorEndOffset == 0);
1523
1524 /* Therefore, then number of PTEs should be equal to the number of sectors */
1525 if (Subsection->NumberOfFullSectors != Subsection->PtesInSubsection)
1526 {
1527 /* Break and warn if this is inconsistent */
1528 DPRINT1("Mm: Subsection inconsistent (%x vs %x)\n",
1529 Subsection->NumberOfFullSectors, Subsection->PtesInSubsection);
1530 DbgBreakPoint();
1531 }
1532}
1533
1535NTAPI
1541 IN ULONG IgnoreFileSizing)
1542{
1543 /* Not yet implemented */
1544 ASSERT(FALSE);
1545 *Segment = NULL;
1547}
1548
1549static
1551NTAPI
1554 IN ULONG ProtectionMask,
1556{
1557 ULONGLONG SizeLimit;
1558 PFN_COUNT PteCount;
1559 PMMPTE PointerPte;
1560 MMPTE TempPte;
1561 PCONTROL_AREA ControlArea;
1562 PSEGMENT NewSegment;
1563 PSUBSECTION Subsection;
1564 PAGED_CODE();
1565
1566 /* No large pages in ARM3 yet */
1568
1569 /* Pagefile-backed sections need a known size */
1570 if (!MaximumSize || !MaximumSize->QuadPart || MaximumSize->QuadPart < 0)
1572
1573 /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1574 SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
1575 SizeLimit /= sizeof(MMPTE);
1576 SizeLimit <<= PAGE_SHIFT;
1577
1578 /* Fail if this size is too big */
1579 if (MaximumSize->QuadPart > SizeLimit)
1580 {
1582 }
1583
1584 /* Calculate how many Prototype PTEs will be needed */
1585 PteCount = (PFN_COUNT)((MaximumSize->QuadPart + PAGE_SIZE - 1) >> PAGE_SHIFT);
1586
1587 /* For commited memory, we must have a valid protection mask */
1588 if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1589
1590 /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1591 NewSegment = ExAllocatePoolWithTag(PagedPool,
1592 sizeof(SEGMENT) +
1593 sizeof(MMPTE) * (PteCount - 1),
1594 'tSmM');
1595 if (!NewSegment)
1596 {
1598 }
1599 *Segment = NewSegment;
1600
1601 /* Now allocate the control area, which has the subsection structure */
1602 ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1603 sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1604 'tCmM');
1605 if (!ControlArea)
1606 {
1607 ExFreePoolWithTag(Segment, 'tSmM');
1609 }
1610
1611 /* And zero it out, filling the basic segmnet pointer and reference fields */
1612 RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1613 ControlArea->Segment = NewSegment;
1614 ControlArea->NumberOfSectionReferences = 1;
1615 ControlArea->NumberOfUserReferences = 1;
1616
1617 /* Convert allocation attributes to control area flags */
1618 if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1619 if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1620 if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1621
1622 /* We just allocated it */
1623 ControlArea->u.Flags.BeingCreated = 1;
1624
1625 /* The subsection follows, write the mask, PTE count and point back to the CA */
1626 Subsection = (PSUBSECTION)(ControlArea + 1);
1627 Subsection->ControlArea = ControlArea;
1628 Subsection->PtesInSubsection = PteCount;
1629 Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1630
1631 /* Zero out the segment's prototype PTEs, and link it with the control area */
1632 PointerPte = &NewSegment->ThePtes[0];
1633 RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1634 NewSegment->PrototypePte = PointerPte;
1635 NewSegment->ControlArea = ControlArea;
1636
1637 /* Save some extra accounting data for the segment as well */
1638 NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1639 NewSegment->SizeOfSegment = ((ULONGLONG)PteCount) * PAGE_SIZE;
1640 NewSegment->TotalNumberOfPtes = PteCount;
1641 NewSegment->NonExtendedPtes = PteCount;
1642
1643 /* The subsection's base address is the first Prototype PTE in the segment */
1644 Subsection->SubsectionBase = PointerPte;
1645
1646 /* Start with an empty PTE, unless this is a commit operation */
1647 TempPte.u.Long = 0;
1649 {
1650 /* In which case, write down the protection mask in the Prototype PTEs */
1651 TempPte.u.Soft.Protection = ProtectionMask;
1652
1653 /* For accounting, also mark these pages as being committed */
1654 NewSegment->NumberOfCommittedPages = PteCount;
1655 }
1656
1657 /* The template PTE itself for the segment should also have the mask set */
1658 NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1659
1660 /* Write out the prototype PTEs, for now they're simply demand zero */
1661#ifdef _WIN64
1662 RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1663#else
1664 RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1665#endif
1666 return STATUS_SUCCESS;
1667}
1668
1670NTAPI
1674{
1675 PMMVAD Vad;
1676 PCONTROL_AREA ControlArea;
1677
1678 /* Get the VAD */
1679 Vad = MiLocateAddress(Address);
1680 if (Vad == NULL)
1681 {
1682 /* Fail, the address does not exist */
1683 DPRINT1("Invalid address\n");
1685 }
1686
1687 /* Check if this is a RosMm memory area */
1688 if (Vad->u.VadFlags.Spare != 0)
1689 {
1691
1692 /* Check if it's a section view (RosMm section) */
1694 {
1695 /* Get the section pointer to the SECTION_OBJECT */
1696 *FileObject = MemoryArea->SectionData.Segment->FileObject;
1697 }
1698 else
1699 {
1700#ifdef NEWCC
1701 ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1702 DPRINT1("Address is a cache section!\n");
1704#else
1705 ASSERT(FALSE);
1707#endif
1708 }
1709 }
1710 else
1711 {
1712 /* Make sure it's not a VM VAD */
1713 if (Vad->u.VadFlags.PrivateMemory == 1)
1714 {
1715 DPRINT1("Address is not a section\n");
1717 }
1718
1719 /* Get the control area */
1720 ControlArea = Vad->ControlArea;
1721 if (!(ControlArea) || !(ControlArea->u.Flags.Image))
1722 {
1723 DPRINT1("Address is not a section\n");
1725 }
1726
1727 /* Get the file object */
1728 *FileObject = ControlArea->FilePointer;
1729 }
1730
1731 /* Return success */
1732 return STATUS_SUCCESS;
1733}
1734
1736NTAPI
1738{
1739 PSECTION Section = SectionObject;
1742
1743 /* Check if it's an ARM3, or ReactOS section */
1745 {
1746 /* Return the file pointer stored in the control area */
1747 return Section->Segment->ControlArea->FilePointer;
1748 }
1749
1750 /* Return the file object */
1751 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1752}
1753
1754static
1757 _In_ PMMVAD Vad)
1758{
1759 PCONTROL_AREA ControlArea;
1761
1762 /* Check if this is a RosMm memory area */
1763 if (Vad->u.VadFlags.Spare != 0)
1764 {
1766
1767 /* Check if it's a section view (RosMm section) */
1769 {
1770 /* Get the section pointer to the SECTION_OBJECT */
1771 FileObject = MemoryArea->SectionData.Segment->FileObject;
1772 }
1773 else
1774 {
1775#ifdef NEWCC
1776 ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1777 DPRINT1("VAD is a cache section!\n");
1778#else
1779 ASSERT(FALSE);
1780#endif
1781 return NULL;
1782 }
1783 }
1784 else
1785 {
1786 /* Make sure it's not a VM VAD */
1787 if (Vad->u.VadFlags.PrivateMemory == 1)
1788 {
1789 DPRINT1("VAD is not a section\n");
1790 return NULL;
1791 }
1792
1793 /* Get the control area */
1794 ControlArea = Vad->ControlArea;
1795 if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1796 {
1797 DPRINT1("Address is not a section\n");
1798 return NULL;
1799 }
1800
1801 /* Get the file object */
1802 FileObject = ControlArea->FilePointer;
1803 }
1804
1805 /* Return the file object */
1806 return FileObject;
1807}
1808
1809VOID
1810NTAPI
1812{
1814
1815 /* Get the section object of this process*/
1816 SectionObject = PsGetCurrentProcess()->SectionObject;
1819
1820 if (SectionObject->u.Flags.Image == 0)
1821 {
1822 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1823 return;
1824 }
1825
1826 /* Return the image information */
1827 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1828}
1829
1831NTAPI
1834{
1835 POBJECT_NAME_INFORMATION ObjectNameInfo;
1838
1839 /* Allocate memory for our structure */
1840 ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, 1024, TAG_MM);
1841 if (!ObjectNameInfo) return STATUS_NO_MEMORY;
1842
1843 /* Query the name */
1845 ObjectNameInfo,
1846 1024,
1847 &ReturnLength);
1848 if (!NT_SUCCESS(Status))
1849 {
1850 /* Failed, free memory */
1851 DPRINT1("Name query failed\n");
1852 ExFreePoolWithTag(ObjectNameInfo, TAG_MM);
1853 *ModuleName = NULL;
1854 return Status;
1855 }
1856
1857 /* Success */
1858 *ModuleName = ObjectNameInfo;
1859 return STATUS_SUCCESS;
1860}
1861
1863NTAPI
1866{
1868 PSECTION SectionObject = Section;
1869
1870 /* Make sure it's an image section */
1871 if (SectionObject->u.Flags.Image == 0)
1872 {
1873 /* It's not, fail */
1874 DPRINT1("Not an image section\n");
1876 }
1877
1878 /* Get the file object */
1881}
1882
1884NTAPI
1887{
1888 POBJECT_NAME_INFORMATION ModuleNameInformation;
1891 PMMVAD Vad;
1893
1894 /* Lock address space */
1897
1898 /* Get the VAD */
1899 Vad = MiLocateAddress(Address);
1900 if (Vad == NULL)
1901 {
1902 /* Fail, the address does not exist */
1903 DPRINT1("No VAD at address %p\n", Address);
1906 }
1907
1908 /* Get the file object pointer for the VAD */
1910 if (FileObject == NULL)
1911 {
1912 DPRINT1("Failed to get file object for Address %p\n", Address);
1915 }
1916
1917 /* Reference the file object */
1919
1920 /* Unlock address space */
1922
1923 /* Get the filename of the file object */
1924 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1925
1926 /* Dereference the file object */
1928
1929 /* Check if we were able to get the file object name */
1930 if (NT_SUCCESS(Status))
1931 {
1932 /* Init modulename */
1933 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1935
1936 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1937 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1938
1939 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1940 }
1941
1942 /* Return status */
1943 return Status;
1944}
1945
1947NTAPI
1950 OUT PVOID MemoryInformation,
1951 IN SIZE_T MemoryInformationLength,
1953{
1957 PMEMORY_SECTION_NAME SectionName = NULL;
1959
1962 NULL,
1964 (PVOID*)(&Process),
1965 NULL);
1966
1967 if (!NT_SUCCESS(Status))
1968 {
1969 DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1970 return Status;
1971 }
1972
1974
1975 if (NT_SUCCESS(Status))
1976 {
1977 SectionName = MemoryInformation;
1978 if (PreviousMode != KernelMode)
1979 {
1980 _SEH2_TRY
1981 {
1982 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1983 (PWSTR)(SectionName + 1),
1984 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1986
1988
1989 }
1991 {
1993 }
1994 _SEH2_END;
1995 }
1996 else
1997 {
1998 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1999 (PWSTR)(SectionName + 1),
2000 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
2002
2004
2005 }
2006
2008 }
2010 return Status;
2011}
2012
2013VOID
2014NTAPI
2016 IN PMMPTE PointerPte,
2017 IN ULONG ProtectionMask,
2018 IN PMMPFN Pfn1,
2019 IN BOOLEAN UpdateDirty)
2020{
2021 MMPTE TempPte, PreviousPte;
2022 KIRQL OldIrql;
2023 BOOLEAN RebuildPte = FALSE;
2024
2025 //
2026 // User for sanity checking later on
2027 //
2028 PreviousPte = *PointerPte;
2029
2030 //
2031 // Build the PTE and acquire the PFN lock
2032 //
2034 PointerPte,
2035 ProtectionMask,
2036 PreviousPte.u.Hard.PageFrameNumber);
2037 OldIrql = MiAcquirePfnLock();
2038
2039 //
2040 // We don't support I/O mappings in this path yet
2041 //
2042 ASSERT(Pfn1 != NULL);
2043 ASSERT(Pfn1->u3.e1.CacheAttribute != MiWriteCombined);
2044
2045 //
2046 // Make sure new protection mask doesn't get in conflict and fix it if it does
2047 //
2048 if (Pfn1->u3.e1.CacheAttribute == MiCached)
2049 {
2050 //
2051 // This is a cached PFN
2052 //
2053 if (ProtectionMask & (MM_NOCACHE | MM_NOACCESS))
2054 {
2055 RebuildPte = TRUE;
2056 ProtectionMask &= ~(MM_NOCACHE | MM_NOACCESS);
2057 }
2058 }
2059 else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
2060 {
2061 //
2062 // This is a non-cached PFN
2063 //
2064 if ((ProtectionMask & (MM_NOCACHE | MM_NOACCESS)) != MM_NOCACHE)
2065 {
2066 RebuildPte = TRUE;
2067 ProtectionMask &= ~MM_NOACCESS;
2068 ProtectionMask |= MM_NOCACHE;
2069 }
2070 }
2071
2072 if (RebuildPte)
2073 {
2075 PointerPte,
2076 ProtectionMask,
2077 PreviousPte.u.Hard.PageFrameNumber);
2078 }
2079
2080 //
2081 // Write the new PTE, making sure we are only changing the bits
2082 //
2083 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2084
2085 //
2086 // Flush the TLB
2087 //
2088 ASSERT(PreviousPte.u.Hard.Valid == 1);
2090 ASSERT(PreviousPte.u.Hard.Valid == 1);
2091
2092 //
2093 // Windows updates the relevant PFN1 information, we currently don't.
2094 //
2095 if (UpdateDirty && PreviousPte.u.Hard.Dirty)
2096 {
2097 if (!Pfn1->u3.e1.Modified)
2098 {
2099 DPRINT1("FIXME: Mark PFN as dirty\n");
2100 }
2101 }
2102
2103 //
2104 // Not supported in ARM3
2105 //
2106 ASSERT(FoundVad->u.VadFlags.VadType != VadWriteWatch);
2107
2108 //
2109 // Release the PFN lock, we are done
2110 //
2111 MiReleasePfnLock(OldIrql);
2112}
2113
2114//
2115// NOTE: This function gets a lot more complicated if we want Copy-on-Write support
2116//
2118NTAPI
2120 IN PMMVAD FoundVad,
2121 IN PVOID StartingAddress,
2122 IN PVOID EndingAddress,
2124 OUT PULONG CapturedOldProtect,
2125 IN ULONG DontCharge,
2127{
2128 PMMPTE PointerPte, LastPte;
2129 MMPTE TempPte, PteContents;
2130 PMMPDE PointerPde;
2131 PMMPFN Pfn1;
2132 ULONG ProtectionMask, QuotaCharge = 0;
2134 PAGED_CODE();
2135
2136 //
2137 // Tell caller nothing is being locked
2138 //
2139 *Locked = FALSE;
2140
2141 //
2142 // This function should only be used for section VADs. Windows ASSERT */
2143 //
2144 ASSERT(FoundVad->u.VadFlags.PrivateMemory == 0);
2145
2146 //
2147 // We don't support these features in ARM3
2148 //
2149 ASSERT(FoundVad->u.VadFlags.VadType != VadImageMap);
2150 ASSERT(FoundVad->u2.VadFlags2.CopyOnWrite == 0);
2151
2152 //
2153 // Convert and validate the protection mask
2154 //
2155 ProtectionMask = MiMakeProtectionMask(NewProtect);
2156 if (ProtectionMask == MM_INVALID_PROTECTION)
2157 {
2158 DPRINT1("Invalid section protect\n");
2160 }
2161
2162 //
2163 // Get the PTE and PDE for the address, as well as the final PTE
2164 //
2166 PointerPde = MiAddressToPde(StartingAddress);
2167 PointerPte = MiAddressToPte(StartingAddress);
2168 LastPte = MiAddressToPte(EndingAddress);
2169
2170 //
2171 // Make the PDE valid, and check the status of the first PTE
2172 //
2174 if (PointerPte->u.Long)
2175 {
2176 //
2177 // Not supported in ARM3
2178 //
2179 ASSERT(FoundVad->u.VadFlags.VadType != VadRotatePhysical);
2180
2181 //
2182 // Capture the page protection and make the PDE valid
2183 //
2184 *CapturedOldProtect = MiGetPageProtection(PointerPte);
2186 }
2187 else
2188 {
2189 //
2190 // Only pagefile-backed section VADs are supported for now
2191 //
2192 ASSERT(FoundVad->u.VadFlags.VadType != VadImageMap);
2193
2194 //
2195 // Grab the old protection from the VAD itself
2196 //
2197 *CapturedOldProtect = MmProtectToValue[FoundVad->u.VadFlags.Protection];
2198 }
2199
2200 //
2201 // Loop all the PTEs now
2202 //
2204 while (PointerPte <= LastPte)
2205 {
2206 //
2207 // Check if we've crossed a PDE boundary and make the new PDE valid too
2208 //
2209 if (MiIsPteOnPdeBoundary(PointerPte))
2210 {
2211 PointerPde = MiPteToPde(PointerPte);
2213 }
2214
2215 //
2216 // Capture the PTE and see what we're dealing with
2217 //
2218 PteContents = *PointerPte;
2219 if (PteContents.u.Long == 0)
2220 {
2221 //
2222 // This used to be a zero PTE and it no longer is, so we must add a
2223 // reference to the pagetable.
2224 //
2226
2227 //
2228 // Create the demand-zero prototype PTE
2229 //
2231 TempPte.u.Soft.Protection = ProtectionMask;
2232 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2233 }
2234 else if (PteContents.u.Hard.Valid == 1)
2235 {
2236 //
2237 // Get the PFN entry
2238 //
2239 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
2240
2241 //
2242 // We don't support these yet
2243 //
2245 ASSERT(Pfn1->u3.e1.PrototypePte == 0);
2246
2247 //
2248 // Write the protection mask and write it with a TLB flush
2249 //
2250 Pfn1->OriginalPte.u.Soft.Protection = ProtectionMask;
2251 MiFlushTbAndCapture(FoundVad,
2252 PointerPte,
2253 ProtectionMask,
2254 Pfn1,
2255 TRUE);
2256 }
2257 else
2258 {
2259 //
2260 // We don't support these cases yet
2261 //
2262 ASSERT(PteContents.u.Soft.Prototype == 0);
2263 ASSERT(PteContents.u.Soft.Transition == 0);
2264
2265 //
2266 // The PTE is already demand-zero, just update the protection mask
2267 //
2268 PointerPte->u.Soft.Protection = ProtectionMask;
2269 }
2270
2271 PointerPte++;
2272 }
2273
2274 //
2275 // Unlock the working set and update quota charges if needed, then return
2276 //
2278 if ((QuotaCharge > 0) && (!DontCharge))
2279 {
2280 FoundVad->u.VadFlags.CommitCharge -= QuotaCharge;
2281 Process->CommitCharge -= QuotaCharge;
2282 }
2283 return STATUS_SUCCESS;
2284}
2285
2286VOID
2287NTAPI
2289 IN ULONG NumberOfPtes,
2290 IN PCONTROL_AREA ControlArea,
2291 IN PMMSUPPORT Ws)
2292{
2293 PMMPTE PointerPte, ProtoPte;//, FirstPte;
2294 PMMPDE PointerPde, SystemMapPde;
2295 PMMPFN Pfn1, Pfn2;
2296 MMPTE PteContents;
2297 KIRQL OldIrql;
2298 DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
2299
2300 ASSERT(Ws == NULL);
2301
2302 /* Get the PTE and loop each one */
2303 PointerPte = MiAddressToPte(BaseAddress);
2304 //FirstPte = PointerPte;
2305 while (NumberOfPtes)
2306 {
2307 /* Check if the PTE is already valid */
2308 PteContents = *PointerPte;
2309 if (PteContents.u.Hard.Valid == 1)
2310 {
2311 /* Get the PFN entry */
2312 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
2313
2314 /* Get the PTE */
2315 PointerPde = MiPteToPde(PointerPte);
2316
2317 /* Lock the PFN database and make sure this isn't a mapped file */
2318 OldIrql = MiAcquirePfnLock();
2319 ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
2320
2321 /* Mark the page as modified accordingly */
2322 if (MI_IS_PAGE_DIRTY(&PteContents))
2323 Pfn1->u3.e1.Modified = 1;
2324
2325 /* Was the PDE invalid */
2326 if (PointerPde->u.Long == 0)
2327 {
2328#if (_MI_PAGING_LEVELS == 2)
2329 /* Find the system double-mapped PDE that describes this mapping */
2330 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
2331
2332 /* Make it valid */
2333 ASSERT(SystemMapPde->u.Hard.Valid == 1);
2334 MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
2335#else
2336 DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
2337 ASSERT(FALSE);
2338#endif
2339 }
2340
2341 /* Dereference the PDE and the PTE */
2342 Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
2343 MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
2345 MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
2346
2347 /* Release the PFN lock */
2348 MiReleasePfnLock(OldIrql);
2349 }
2350 else
2351 {
2352 /* Windows ASSERT */
2353 ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
2354
2355 /* Check if this is a prototype pointer PTE */
2356 if (PteContents.u.Soft.Prototype == 1)
2357 {
2358 /* Get the prototype PTE */
2359 ProtoPte = MiProtoPteToPte(&PteContents);
2360
2361 /* We don't support anything else atm */
2362 ASSERT(ProtoPte->u.Long == 0);
2363 }
2364 }
2365
2366 /* Make the PTE into a zero PTE */
2367 PointerPte->u.Long = 0;
2368
2369 /* Move to the next PTE */
2370 PointerPte++;
2371 NumberOfPtes--;
2372 }
2373
2374 /* Flush the TLB */
2376
2377 /* Acquire the PFN lock */
2378 OldIrql = MiAcquirePfnLock();
2379
2380 /* Decrement the accounting counters */
2381 ControlArea->NumberOfUserReferences--;
2382 ControlArea->NumberOfMappedViews--;
2383
2384 /* Check if we should destroy the CA and release the lock */
2385 MiCheckControlArea(ControlArea, OldIrql);
2386}
2387
2388ULONG
2389NTAPI
2391 IN PVOID Base,
2392 OUT PCONTROL_AREA *ControlArea)
2393{
2394 ULONG Hash, Size, Count = 0;
2396 PAGED_CODE();
2397
2398 /* Compute the hash for this entry and loop trying to find it */
2399 Entry = (ULONG_PTR)Base >> 16;
2400 Hash = Entry % Session->SystemSpaceHashKey;
2401 while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2402 {
2403 /* Check if we overflew past the end of the hash table */
2404 if (++Hash >= Session->SystemSpaceHashSize)
2405 {
2406 /* Reset the hash to zero and keep searching from the bottom */
2407 Hash = 0;
2408 if (++Count == 2)
2409 {
2410 /* But if we overflew twice, then this is not a real mapping */
2411 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2412 (ULONG_PTR)Base,
2413 1,
2414 0,
2415 0);
2416 }
2417 }
2418 }
2419
2420 /* One less entry */
2421 Session->SystemSpaceHashEntries--;
2422
2423 /* Extract the size and clear the entry */
2424 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2425 Session->SystemSpaceViewTable[Hash].Entry = 0;
2426
2427 /* Return the control area and the size */
2428 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2429 return Size;
2430}
2431
2433NTAPI
2436{
2437 ULONG Size;
2438 PCONTROL_AREA ControlArea;
2439 PAGED_CODE();
2440
2441 /* Remove this mapping */
2442 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2443 Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2444
2445 /* Clear the bits for this mapping */
2446 RtlClearBits(Session->SystemSpaceBitMap,
2447 (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2448 Size);
2449
2450 /* Convert the size from a bit size into the actual size */
2451 Size = Size * (_64K >> PAGE_SHIFT);
2452
2453 /* Remove the PTEs now */
2454 MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2455 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2456
2457 /* Return success */
2458 return STATUS_SUCCESS;
2459}
2460
2461/* PUBLIC FUNCTIONS ***********************************************************/
2462
2463/*
2464 * @implemented
2465 */
2467NTAPI
2471 IN PLARGE_INTEGER InputMaximumSize,
2476{
2477 SECTION Section;
2478 PSECTION NewSection;
2479 PSUBSECTION Subsection;
2480 PSEGMENT NewSegment, Segment;
2482 PCONTROL_AREA ControlArea;
2483 ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2485 BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2486 KIRQL OldIrql;
2488 BOOLEAN UserRefIncremented = FALSE;
2489 PVOID PreviousSectionPointer;
2490
2491 /* Make the same sanity checks that the Nt interface should've validated */
2494 SEC_NO_CHANGE)) == 0);
2504
2505 /* Convert section flag to page flag */
2508
2509 /* Check to make sure the protection is correct. Nt* does this already */
2511 if (ProtectionMask == MM_INVALID_PROTECTION)
2512 {
2513 DPRINT1("Invalid protection mask\n");
2515 }
2516
2517 /* Check if this is going to be a data or image backed file section */
2518 if ((FileHandle) || (FileObject))
2519 {
2520 /* These cannot be mapped with large pages */
2522
2523 /* For now, only support the mechanism through a file handle */
2525
2526 /* Reference the file handle to get the object */
2528 MmMakeFileAccess[ProtectionMask],
2531 (PVOID*)&File,
2532 NULL);
2533 if (!NT_SUCCESS(Status)) return Status;
2534
2535 /* Make sure Cc has been doing its job */
2536 if (!File->SectionObjectPointer)
2537 {
2538 /* This is not a valid file system-based file, fail */
2541 }
2542
2543 /* Image-file backed sections are not yet supported */
2545
2546 /* Compute the size of the control area, and allocate it */
2547 ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2548 ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2549 if (!ControlArea)
2550 {
2553 }
2554
2555 /* Zero it out */
2556 RtlZeroMemory(ControlArea, ControlAreaSize);
2557
2558 /* Did we get a handle, or an object? */
2559 if (FileHandle)
2560 {
2561 /* We got a file handle so we have to lock down the file */
2562#if 0
2564 if (!NT_SUCCESS(Status))
2565 {
2566 ExFreePool(ControlArea);
2568 return Status;
2569 }
2570#else
2571 /* ReactOS doesn't support this API yet, so do nothing */
2573#endif
2574 /* Update the top-level IRP so that drivers know what's happening */
2576 FileLock = TRUE;
2577 }
2578
2579 /* Lock the PFN database while we play with the section pointers */
2580 OldIrql = MiAcquirePfnLock();
2581
2582 /* Image-file backed sections are not yet supported */
2584
2585 /* There should not already be a control area for this file */
2586 ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2587 NewSegment = NULL;
2588
2589 /* Write down that this CA is being created, and set it */
2590 ControlArea->u.Flags.BeingCreated = TRUE;
2592 PreviousSectionPointer = File->SectionObjectPointer;
2593 File->SectionObjectPointer->DataSectionObject = ControlArea;
2594
2595 /* We can release the PFN lock now */
2596 MiReleasePfnLock(OldIrql);
2597
2598 /* We don't support previously-mapped file */
2599 ASSERT(NewSegment == NULL);
2600
2601 /* Image-file backed sections are not yet supported */
2603
2604 /* So we always create a data file map */
2606 &Segment,
2607 (PSIZE_T)InputMaximumSize,
2610 KernelCall);
2611 if (!NT_SUCCESS(Status))
2612 {
2613 /* Lock the PFN database while we play with the section pointers */
2614 OldIrql = MiAcquirePfnLock();
2615
2616 /* Reset the waiting-for-deletion event */
2617 ASSERT(ControlArea->WaitingForDeletion == NULL);
2618 ControlArea->WaitingForDeletion = NULL;
2619
2620 /* Set the file pointer NULL flag */
2621 ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2622 ControlArea->u.Flags.FilePointerNull = TRUE;
2623
2624 /* Delete the data section object */
2626 File->SectionObjectPointer->DataSectionObject = NULL;
2627
2628 /* No longer being created */
2629 ControlArea->u.Flags.BeingCreated = FALSE;
2630
2631 /* We can release the PFN lock now */
2632 MiReleasePfnLock(OldIrql);
2633
2634 /* Check if we locked and set the IRP */
2635 if (FileLock)
2636 {
2637 /* Undo */
2639 //FsRtlReleaseFile(File);
2640 }
2641
2642 /* Free the control area and de-ref the file object */
2643 ExFreePool(ControlArea);
2645
2646 /* All done */
2647 return Status;
2648 }
2649
2650 /* On success, we expect this */
2651 ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2652
2653 /* Check if a maximum size was specified */
2654 if (!InputMaximumSize->QuadPart)
2655 {
2656 /* Nope, use the segment size */
2657 Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2658 }
2659 else
2660 {
2661 /* Yep, use the entered size */
2662 Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2663 }
2664 }
2665 else
2666 {
2667 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2669
2670 /* Not yet supported */
2672
2673 /* So this must be a pagefile-backed section, create the mappings needed */
2674 Status = MiCreatePagingFileMap(&NewSegment,
2675 InputMaximumSize,
2676 ProtectionMask,
2678 if (!NT_SUCCESS(Status)) return Status;
2679
2680 /* Set the size here, and read the control area */
2681 Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2682 ControlArea = NewSegment->ControlArea;
2683
2684 /* MiCreatePagingFileMap increments user references */
2685 UserRefIncremented = TRUE;
2686 }
2687
2688 /* Did we already have a segment? */
2689 if (!NewSegment)
2690 {
2691 /* This must be the file path and we created a segment */
2692 NewSegment = Segment;
2693 ASSERT(File != NULL);
2694
2695 /* Acquire the PFN lock while we set control area flags */
2696 OldIrql = MiAcquirePfnLock();
2697
2698 /* We don't support this race condition yet, so assume no waiters */
2699 ASSERT(ControlArea->WaitingForDeletion == NULL);
2700 ControlArea->WaitingForDeletion = NULL;
2701
2702 /* Image-file backed sections are not yet supported, nor ROM images */
2704 ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2705
2706 /* Take off the being created flag, and then release the lock */
2707 ControlArea->u.Flags.BeingCreated = FALSE;
2708 MiReleasePfnLock(OldIrql);
2709 }
2710
2711 /* Check if we locked the file earlier */
2712 if (FileLock)
2713 {
2714 /* Reset the top-level IRP and release the lock */
2716 //FsRtlReleaseFile(File);
2717 FileLock = FALSE;
2718 }
2719
2720 /* Set the initial section object data */
2721 Section.InitialPageProtection = SectionPageProtection;
2722
2723 /* The mapping created a control area and segment, save the flags */
2724 Section.Segment = NewSegment;
2725 Section.u.LongFlags = ControlArea->u.LongFlags;
2726
2727 /* Check if this is a user-mode read-write non-image file mapping */
2728 if (!(FileObject) &&
2730 !(ControlArea->u.Flags.Image) &&
2731 (ControlArea->FilePointer))
2732 {
2733 /* Add a reference and set the flag */
2734 Section.u.Flags.UserWritable = TRUE;
2735 InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2736 }
2737
2738 /* Check for image mappings or page file mappings */
2739 if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2740 {
2741 /* Charge the segment size, and allocate a subsection */
2742 PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2743 Size = sizeof(SUBSECTION);
2744 }
2745 else
2746 {
2747 /* Charge nothing, and allocate a mapped subsection */
2748 PagedCharge = 0;
2749 Size = sizeof(MSUBSECTION);
2750 }
2751
2752 /* Check if this is a normal CA */
2753 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2754 ASSERT(ControlArea->u.Flags.Rom == 0);
2755
2756 /* Charge only a CA, and the subsection is right after */
2757 NonPagedCharge = sizeof(CONTROL_AREA);
2758 Subsection = (PSUBSECTION)(ControlArea + 1);
2759
2760 /* We only support single-subsection mappings */
2761 NonPagedCharge += Size;
2762 ASSERT(Subsection->NextSubsection == NULL);
2763
2764 /* Create the actual section object, with enough space for the prototype PTEs */
2769 NULL,
2770 sizeof(SECTION),
2771 PagedCharge,
2772 NonPagedCharge,
2773 (PVOID*)&NewSection);
2774 if (!NT_SUCCESS(Status))
2775 {
2776 /* Check if this is a user-mode read-write non-image file mapping */
2777 if (!(FileObject) &&
2779 !(ControlArea->u.Flags.Image) &&
2780 (ControlArea->FilePointer))
2781 {
2782 /* Remove a reference and check the flag */
2783 ASSERT(Section.u.Flags.UserWritable == 1);
2784 InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2785 }
2786
2787 /* Check if a user reference was added */
2788 if (UserRefIncremented)
2789 {
2790 /* Acquire the PFN lock while we change counters */
2791 OldIrql = MiAcquirePfnLock();
2792
2793 /* Decrement the accounting counters */
2794 ControlArea->NumberOfSectionReferences--;
2795 ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2796 ControlArea->NumberOfUserReferences--;
2797
2798 /* Check if we should destroy the CA and release the lock */
2799 MiCheckControlArea(ControlArea, OldIrql);
2800 }
2801
2802 /* Return the failure code */
2803 return Status;
2804 }
2805
2806 /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2807
2808 /* Now copy the local section object from the stack into this new object */
2809 RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2810 NewSection->Address.StartingVpn = 0;
2811
2812 /* For now, only user calls are supported */
2813 ASSERT(KernelCall == FALSE);
2814 NewSection->u.Flags.UserReference = TRUE;
2815
2816 /* Is this a "based" allocation, in which all mappings are identical? */
2818 {
2819 /* Lock the VAD tree during the search */
2821
2822 /* Is it a brand new ControArea ? */
2823 if (ControlArea->u.Flags.BeingCreated == 1)
2824 {
2825 ASSERT(ControlArea->u.Flags.Based == 1);
2826 /* Then we must find a global address, top-down */
2829 _64K,
2831 (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2832
2833 if (!NT_SUCCESS(Status))
2834 {
2835 /* No way to find a valid range. */
2837 ControlArea->u.Flags.Based = 0;
2838 NewSection->u.Flags.Based = 0;
2839 ObDereferenceObject(NewSection);
2840 return Status;
2841 }
2842
2843 /* Compute the ending address and insert it into the VAD tree */
2844 NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2845 NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2846 MiInsertBasedSection(NewSection);
2847 }
2848 else
2849 {
2850 /* 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 !*/
2851 ASSERT(FALSE);
2852 }
2853
2855 }
2856
2857 /* The control area is not being created anymore */
2858 if (ControlArea->u.Flags.BeingCreated == 1)
2859 {
2860 /* Acquire the PFN lock while we set control area flags */
2861 OldIrql = MiAcquirePfnLock();
2862
2863 /* Take off the being created flag, and then release the lock */
2864 ControlArea->u.Flags.BeingCreated = 0;
2865 NewSection->u.Flags.BeingCreated = 0;
2866
2867 MiReleasePfnLock(OldIrql);
2868 }
2869
2870 /* Migrate the attribute into a flag */
2872
2873 /* If R/W access is not requested, this might eventually become a CoW mapping */
2875 {
2876 NewSection->u.Flags.CopyOnWrite = TRUE;
2877 }
2878
2879 /* Write down if this was a kernel call */
2880 ControlArea->u.Flags.WasPurged |= KernelCall;
2881 ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2882
2883 /* Make sure the segment and the section are the same size, or the section is smaller */
2884 ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2885
2886 /* Return the object and the creation status */
2887 *SectionObject = (PVOID)NewSection;
2888 return Status;
2889}
2890
2891/*
2892 * @implemented
2893 */
2895NTAPI
2906{
2909 PSECTION Section;
2910 PCONTROL_AREA ControlArea;
2911 ULONG ProtectionMask;
2913 ULONG64 CalculatedViewSize;
2914 PAGED_CODE();
2915
2916 /* Get the segment and control area */
2917 Section = (PSECTION)SectionObject;
2918 ControlArea = Section->Segment->ControlArea;
2919
2920 /* These flags/states are not yet supported by ARM3 */
2921 ASSERT(Section->u.Flags.Image == 0);
2922 ASSERT(Section->u.Flags.NoCache == 0);
2923 ASSERT(Section->u.Flags.WriteCombined == 0);
2924 ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
2925
2926 /* FIXME */
2927 if ((AllocationType & MEM_RESERVE) != 0)
2928 {
2929 DPRINT1("MmMapViewOfArm3Section called with MEM_RESERVE, this is not implemented yet!!!\n");
2931 }
2932
2933 /* Check if the mapping protection is compatible with the create */
2935 {
2936 DPRINT1("Mapping protection is incompatible\n");
2938 }
2939
2940 /* Check if the offset and size would cause an overflow */
2941 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) <
2942 (ULONG64)SectionOffset->QuadPart)
2943 {
2944 DPRINT1("Section offset overflows\n");
2946 }
2947
2948 /* Check if the offset and size are bigger than the section itself */
2949 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) >
2950 (ULONG64)Section->SizeOfSection.QuadPart)
2951 {
2952 DPRINT1("Section offset is larger than section\n");
2954 }
2955
2956 /* Check if the caller did not specify a view size */
2957 if (!(*ViewSize))
2958 {
2959 /* Compute it for the caller */
2960 CalculatedViewSize = Section->SizeOfSection.QuadPart -
2961 SectionOffset->QuadPart;
2962
2963 /* Check if it's larger than 4GB or overflows into kernel-mode */
2964 if (!NT_SUCCESS(RtlULongLongToSIZET(CalculatedViewSize, ViewSize)) ||
2965 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < CalculatedViewSize))
2966 {
2967 DPRINT1("Section view won't fit\n");
2969 }
2970 }
2971
2972 /* Check if the commit size is larger than the view size */
2973 if (CommitSize > *ViewSize)
2974 {
2975 DPRINT1("Attempting to commit more than the view itself\n");
2977 }
2978
2979 /* Check if the view size is larger than the section */
2980 if (*ViewSize > (ULONG64)Section->SizeOfSection.QuadPart)
2981 {
2982 DPRINT1("The view is larger than the section\n");
2984 }
2985
2986 /* Compute and validate the protection mask */
2987 ProtectionMask = MiMakeProtectionMask(Protect);
2988 if (ProtectionMask == MM_INVALID_PROTECTION)
2989 {
2990 DPRINT1("The protection is invalid\n");
2992 }
2993
2994 /* We only handle pagefile-backed sections, which cannot be writecombined */
2996 {
2997 DPRINT1("Cannot write combine a pagefile-backed section\n");
2999 }
3000
3001 /* Start by attaching to the current process if needed */
3003 {
3005 Attached = TRUE;
3006 }
3007
3008 /* Do the actual mapping */
3009 Status = MiMapViewOfDataSection(ControlArea,
3010 Process,
3013 ViewSize,
3014 Section,
3016 ProtectionMask,
3017 CommitSize,
3018 ZeroBits,
3020
3021 /* Detach if needed, then return status */
3023 return Status;
3024}
3025
3026/*
3027 * @unimplemented
3028 */
3029BOOLEAN
3030NTAPI
3032{
3034 return FALSE;
3035}
3036
3037/*
3038 * @unimplemented
3039 */
3040BOOLEAN
3041NTAPI
3044{
3046 return FALSE;
3047}
3048
3049/*
3050 * @implemented
3051 */
3053NTAPI
3057{
3058 PAGED_CODE();
3060
3061 // HACK
3062 if (MiIsRosSectionObject(Section))
3063 {
3064 return MmMapViewInSystemSpace(Section, MappedBase, ViewSize);
3065 }
3066
3067 /* Process must be in a session */
3068 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
3069 {
3070 DPRINT1("Process is not in session\n");
3072 }
3073
3074 /* Use the system space API, but with the session view instead */
3076 SectionOffset.QuadPart = 0;
3077 return MiMapViewInSystemSpace(Section,
3079 MappedBase,
3080 ViewSize,
3081 &SectionOffset);
3082}
3083
3084/*
3085 * @implemented
3086 */
3088NTAPI
3090{
3091 PAGED_CODE();
3092
3093 // HACK
3095 {
3097 }
3098
3099 /* Process must be in a session */
3100 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
3101 {
3102 DPRINT1("Proess is not in session\n");
3104 }
3105
3106 /* Use the system space API, but with the session view instead */
3109 MappedBase);
3110}
3111
3112/*
3113 * @implemented
3114 */
3116NTAPI
3119{
3121}
3122
3123/*
3124 * @implemented
3125 */
3127NTAPI
3129{
3131 PAGED_CODE();
3132
3133 /* Was this mapped by RosMm? */
3137 {
3140 return Status;
3141 }
3143
3144 /* It was not, call the ARM3 routine */
3146}
3147
3148/*
3149 * @implemented
3150 */
3152NTAPI
3155{
3156 ULONG_PTR StartAddress, EndingAddress, Base;
3157 ULONG Hash, Count = 0, Size, QuotaCharge;
3158 PMMSESSION Session;
3159 PMMPTE LastProtoPte, PointerPte, ProtoPte;
3160 PCONTROL_AREA ControlArea;
3162 PSUBSECTION Subsection;
3163 MMPTE TempPte;
3164 PAGED_CODE();
3165
3166 /* Make sure the base isn't past the session view range */
3169 {
3170 DPRINT1("Base outside of valid range\n");
3172 }
3173
3174 /* Make sure the size isn't past the session view range */
3177 {
3178 DPRINT1("Size outside of valid range\n");
3180 }
3181
3182 /* Sanity check */
3183 ASSERT(ViewSize != 0);
3184
3185 /* Process must be in a session */
3186 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
3187 {
3188 DPRINT1("Process is not in session\n");
3190 }
3191
3192 /* Compute the correctly aligned base and end addresses */
3193 StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
3194 EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
3195
3196 /* Sanity check and grab the session */
3198 Session = &MmSessionSpace->Session;
3199
3200 /* Get the hash entry for this allocation */
3201 Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
3202
3203 /* Lock system space */
3205
3206 /* Loop twice so we can try rolling over if needed */
3207 while (TRUE)
3208 {
3209 /* Extract the size and base addresses from the entry */
3210 Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
3211 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
3212
3213 /* Convert the size to bucket chunks */
3215
3216 /* Bail out if this entry fits in here */
3217 if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
3218
3219 /* Check if we overflew past the end of the hash table */
3220 if (++Hash >= Session->SystemSpaceHashSize)
3221 {
3222 /* Reset the hash to zero and keep searching from the bottom */
3223 Hash = 0;
3224 if (++Count == 2)
3225 {
3226 /* But if we overflew twice, then this is not a real mapping */
3227 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
3228 Base,
3229 2,
3230 0,
3231 0);
3232 }
3233 }
3234 }
3235
3236 /* Make sure the view being mapped is not file-based */
3237 ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
3238 if (ControlArea->FilePointer != NULL)
3239 {
3240 /* It is, so we have to bail out */
3241 DPRINT1("Only page-filed backed sections can be commited\n");
3244 }
3245
3246 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
3247 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
3248 ASSERT(ControlArea->u.Flags.Rom == 0);
3249 Subsection = (PSUBSECTION)(ControlArea + 1);
3250
3251 /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
3252 ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
3253 QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
3254 LastProtoPte = ProtoPte + QuotaCharge;
3255 if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
3256 {
3257 DPRINT1("PTE is out of bounds\n");
3260 }
3261
3262 /* Acquire the commit lock and count all the non-committed PTEs */
3264 PointerPte = ProtoPte;
3265 while (PointerPte < LastProtoPte)
3266 {
3267 if (PointerPte->u.Long) QuotaCharge--;
3268 PointerPte++;
3269 }
3270
3271 /* Was everything committed already? */
3272 if (!QuotaCharge)
3273 {
3274 /* Nothing to do! */
3277 return STATUS_SUCCESS;
3278 }
3279
3280 /* Pick the segment and template PTE */
3281 Segment = ControlArea->Segment;
3282 TempPte = Segment->SegmentPteTemplate;
3283 ASSERT(TempPte.u.Long != 0);
3284
3285 /* Loop all prototype PTEs to be committed */
3286 PointerPte = ProtoPte;
3287 while (PointerPte < LastProtoPte)
3288 {
3289 /* Make sure the PTE is already invalid */
3290 if (PointerPte->u.Long == 0)
3291 {
3292 /* And write the invalid PTE */
3293 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
3294 }
3295
3296 /* Move to the next PTE */
3297 PointerPte++;
3298 }
3299
3300 /* Check if we had at least one page charged */
3301 if (QuotaCharge)
3302 {
3303 /* Update the accounting data */
3304 Segment->NumberOfCommittedPages += QuotaCharge;
3306 }
3307
3308 /* Release all */
3311 return STATUS_SUCCESS;
3312}
3313
3314VOID
3315NTAPI
3317{
3319 PCONTROL_AREA ControlArea;
3320 KIRQL OldIrql;
3321
3322 SectionObject = (PSECTION)ObjectBody;
3323
3324 if (SectionObject->u.Flags.Based == 1)
3325 {
3326 /* Remove the node from the global section address tree */
3330 }
3331
3332 /* Lock the PFN database */
3333 OldIrql = MiAcquirePfnLock();
3334
3335 ASSERT(SectionObject->Segment);
3336 ASSERT(SectionObject->Segment->ControlArea);
3337
3338 ControlArea = SectionObject->Segment->ControlArea;
3339
3340 /* Dereference */
3341 ControlArea->NumberOfSectionReferences--;
3342 ControlArea->NumberOfUserReferences--;
3343
3344 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
3345
3346 /* Check it. It will delete it if there is no more reference to it */
3347 MiCheckControlArea(ControlArea, OldIrql);
3348}
3349
3350ULONG
3351NTAPI
3353{
3355 return 0;
3356}
3357
3358/* SYSTEM CALLS ***************************************************************/
3359
3361NTAPI
3362NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage,
3363 IN PVOID File2MappedAsFile)
3364{
3366 PMMVAD Vad1, Vad2;
3367 PFILE_OBJECT FileObject1, FileObject2;
3369
3370 /* Lock address space */
3373
3374 /* Get the VAD for Address 1 */
3375 Vad1 = MiLocateAddress(File1MappedAsAnImage);
3376 if (Vad1 == NULL)
3377 {
3378 /* Fail, the address does not exist */
3379 DPRINT1("No VAD at address 1 %p\n", File1MappedAsAnImage);
3381 goto Exit;
3382 }
3383
3384 /* Get the VAD for Address 2 */
3385 Vad2 = MiLocateAddress(File2MappedAsFile);
3386 if (Vad2 == NULL)
3387 {
3388 /* Fail, the address does not exist */
3389 DPRINT1("No VAD at address 2 %p\n", File2MappedAsFile);
3391 goto Exit;
3392 }
3393
3394 /* Get the file object pointer for VAD 1 */
3395 FileObject1 = MiGetFileObjectForVad(Vad1);
3396 if (FileObject1 == NULL)
3397 {
3398 DPRINT1("Failed to get file object for Address 1 %p\n", File1MappedAsAnImage);
3400 goto Exit;
3401 }
3402
3403 /* Get the file object pointer for VAD 2 */
3404 FileObject2 = MiGetFileObjectForVad(Vad2);
3405 if (FileObject2 == NULL)
3406 {
3407 DPRINT1("Failed to get file object for Address 2 %p\n", File2MappedAsFile);
3409 goto Exit;
3410 }
3411
3412 /* Make sure Vad1 is an image mapping */
3413 if (Vad1->u.VadFlags.VadType != VadImageMap)
3414 {
3415 DPRINT1("Address 1 (%p) is not an image mapping\n", File1MappedAsAnImage);
3417 goto Exit;
3418 }
3419
3420 /* SectionObjectPointer is equal if the files are equal */
3421 if (FileObject1->SectionObjectPointer == FileObject2->SectionObjectPointer)
3422 {
3424 }
3425 else
3426 {
3428 }
3429
3430Exit:
3431 /* Unlock address space */
3433 return Status;
3434}
3435
3436/*
3437 * @implemented
3438 */
3440NTAPI
3448{
3449 LARGE_INTEGER SafeMaximumSize;
3451 HANDLE Handle;
3454 PAGED_CODE();
3455
3456 /* Check for non-existing flags */
3459 SEC_NO_CHANGE)))
3460 {
3461 if (!(AllocationAttributes & 1))
3462 {
3463 DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
3465 }
3466 }
3467
3468 /* Check for no allocation type */
3470 {
3471 DPRINT1("Missing allocation type in allocation attributes\n");
3473 }
3474
3475 /* Check for image allocation with invalid attributes */
3479 {
3480 DPRINT1("Image allocation with invalid attributes\n");
3482 }
3483
3484 /* Check for allocation type is both commit and reserve */
3486 {
3487 DPRINT1("Commit and reserve in the same time\n");
3489 }
3490
3491 /* Now check for valid protection */
3496 {
3497 DPRINT1("Sections don't support these protections\n");
3499 }
3500
3501 /* Use a maximum size of zero, if none was specified */
3502 SafeMaximumSize.QuadPart = 0;
3503
3504 /* Check for user-mode caller */
3505 if (PreviousMode != KernelMode)
3506 {
3507 /* Enter SEH */
3508 _SEH2_TRY
3509 {
3510 /* Safely check user-mode parameters */
3511 if (MaximumSize) SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
3512 MaximumSize = &SafeMaximumSize;
3513 ProbeForWriteHandle(SectionHandle);
3514 }
3516 {
3517 /* Return the exception code */
3519 }
3520 _SEH2_END;
3521 }
3522 else if (!MaximumSize) MaximumSize = &SafeMaximumSize;
3523
3524 /* Check that MaximumSize is valid if backed by paging file */
3525 if ((!FileHandle) && (!MaximumSize->QuadPart))
3527
3528 /* Create the section */
3535 FileHandle,
3536 NULL);
3537 if (!NT_SUCCESS(Status)) return Status;
3538
3539 /* FIXME: Should zero last page for a file mapping */
3540
3541 /* Now insert the object */
3543 NULL,
3545 0,
3546 NULL,
3547 &Handle);
3548 if (NT_SUCCESS(Status))
3549 {
3550 /* Enter SEH */
3551 _SEH2_TRY
3552 {
3553 /* Return the handle safely */
3554 *SectionHandle = Handle;
3555 }
3557 {
3558 /* Nothing here */
3559 }
3560 _SEH2_END;
3561 }
3562
3563 /* Return the status */
3564 return Status;
3565}
3566
3568NTAPI
3572{
3573 HANDLE Handle;
3576 PAGED_CODE();
3577
3578 /* Check for user-mode caller */
3579 if (PreviousMode != KernelMode)
3580 {
3581 /* Enter SEH */
3582 _SEH2_TRY
3583 {
3584 /* Safely check user-mode parameters */
3585 ProbeForWriteHandle(SectionHandle);
3586 }
3588 {
3589 /* Return the exception code */
3591 }
3592 _SEH2_END;
3593 }
3594
3595 /* Try opening the object */
3599 NULL,
3601 NULL,
3602 &Handle);
3603
3604 /* Enter SEH */
3605 _SEH2_TRY
3606 {
3607 /* Return the handle safely */
3608 *SectionHandle = Handle;
3609 }
3611 {
3612 /* Nothing here */
3613 }
3614 _SEH2_END;
3615
3616 /* Return the status */
3617 return Status;
3618}
3619
3621NTAPI
3632{
3633 PVOID SafeBaseAddress;
3634 LARGE_INTEGER SafeSectionOffset;
3635 SIZE_T SafeViewSize;
3636 PSECTION Section;
3640 ULONG ProtectionMask;
3642#if defined(_M_IX86) || defined(_M_AMD64)
3643 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3645#else
3646 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3648#endif
3649
3650 /* Check for invalid inherit disposition */
3652 {
3653 DPRINT1("Invalid inherit disposition\n");
3655 }
3656
3657 /* Allow only valid allocation types */
3658 if (AllocationType & ~ValidAllocationType)
3659 {
3660 DPRINT1("Invalid allocation type\n");
3662 }
3663
3664 /* Convert the protection mask, and validate it */
3665 ProtectionMask = MiMakeProtectionMask(Protect);
3666 if (ProtectionMask == MM_INVALID_PROTECTION)
3667 {
3668 DPRINT1("Invalid page protection\n");
3670 }
3671
3672 /* Now convert the protection mask into desired section access mask */
3673 DesiredAccess = MmMakeSectionAccess[ProtectionMask & 0x7];
3674
3675 /* Assume no section offset */
3676 SafeSectionOffset.QuadPart = 0;
3677
3678 /* Enter SEH */
3679 _SEH2_TRY
3680 {
3681 /* Check for unsafe parameters */
3682 if (PreviousMode != KernelMode)
3683 {
3684 /* Probe the parameters */
3687 }
3688
3689 /* Check if a section offset was given */
3690 if (SectionOffset)
3691 {
3692 /* Check for unsafe parameters and capture section offset */
3694 SafeSectionOffset = *SectionOffset;
3695 }
3696
3697 /* Capture the other parameters */
3698 SafeBaseAddress = *BaseAddress;
3699 SafeViewSize = *ViewSize;
3700 }
3702 {
3703 /* Return the exception code */
3705 }
3706 _SEH2_END;
3707
3708 /* Check for kernel-mode address */
3709 if (SafeBaseAddress > MM_HIGHEST_VAD_ADDRESS)
3710 {
3711 DPRINT1("Kernel base not allowed\n");
3713 }
3714
3715 /* Check for range entering kernel-mode */
3716 if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)SafeBaseAddress) < SafeViewSize)
3717 {
3718 DPRINT1("Overflowing into kernel base not allowed\n");
3720 }
3721
3722 /* Check for invalid zero bits */
3723 if (ZeroBits)
3724 {
3726 {
3727 DPRINT1("Invalid zero bits\n");
3729 }
3730
3731 if ((((ULONG_PTR)SafeBaseAddress << ZeroBits) >> ZeroBits) != (ULONG_PTR)SafeBaseAddress)
3732 {
3733 DPRINT1("Invalid zero bits\n");
3735 }
3736
3737 if (((((ULONG_PTR)SafeBaseAddress + SafeViewSize) << ZeroBits) >> ZeroBits) != ((ULONG_PTR)SafeBaseAddress + SafeViewSize))
3738 {
3739 DPRINT1("Invalid zero bits\n");
3741 }
3742 }
3743
3744 /* Reference the process */
3749 (PVOID*)&Process,
3750 NULL);
3751 if (!NT_SUCCESS(Status)) return Status;
3752
3753 /* Reference the section */
3754 Status = ObReferenceObjectByHandle(SectionHandle,
3758 (PVOID*)&Section,
3759 NULL);
3760 if (!NT_SUCCESS(Status))
3761 {
3763 return Status;
3764 }
3765
3766 if (Section->u.Flags.PhysicalMemory)
3767 {
3768 if (PreviousMode == UserMode &&
3769 SafeSectionOffset.QuadPart + SafeViewSize > MmHighestPhysicalPage << PAGE_SHIFT)
3770 {
3771 DPRINT1("Denying map past highest physical page.\n");
3772 ObDereferenceObject(Section);
3775 }
3776 }
3777 else if (!(AllocationType & MEM_DOS_LIM))
3778 {
3779 /* Check for non-allocation-granularity-aligned BaseAddress */
3780 if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
3781 {
3782 DPRINT("BaseAddress is not at 64-kilobyte address boundary.\n");
3783 ObDereferenceObject(Section);
3786 }
3787
3788 /* Do the same for the section offset */
3789 if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
3790 {
3791 DPRINT("SectionOffset is not at 64-kilobyte address boundary.\n");
3792 ObDereferenceObject(Section);
3795 }
3796 }
3797
3798 /* Now do the actual mapping */
3799 Status = MmMapViewOfSection(Section,
3800 Process,
3801 &SafeBaseAddress,
3802 ZeroBits,
3803 CommitSize,
3804 &SafeSectionOffset,
3805 &SafeViewSize,
3808 Protect);
3809
3810 /* Return data only on success */
3811 if (NT_SUCCESS(Status))
3812 {
3813 /* Check if this is an image for the current process */
3814 if ((Section->u.Flags.Image) &&
3817 {
3818 /* Notify the debugger */
3819 DbgkMapViewOfSection(Section,
3820 SafeBaseAddress,
3821 SafeSectionOffset.LowPart,
3822 SafeViewSize);
3823 }
3824
3825 /* Enter SEH */
3826 _SEH2_TRY
3827 {
3828 /* Return parameters to user */
3829 *BaseAddress = SafeBaseAddress;
3830 *ViewSize = SafeViewSize;
3831 if (SectionOffset) *SectionOffset = SafeSectionOffset;
3832 }
3834 {
3835 /* Nothing to do */
3836 }
3837 _SEH2_END;
3838 }
3839
3840 /* Dereference all objects and return status */
3841 ObDereferenceObject(Section);
3843 return Status;
3844}
3845
3847NTAPI
3850{
3854
3855 /* Don't allowing mapping kernel views */
3857 {
3858 DPRINT1("Trying to unmap a kernel view\n");
3860 }
3861
3862 /* Reference the process */
3867 (PVOID*)&Process,
3868 NULL);
3869 if (!NT_SUCCESS(Status)) return Status;
3870
3871 /* Unmap the view */
3873
3874 /* Dereference the process and return status */
3876 return Status;
3877}
3878
3880NTAPI
3882 IN OUT PLARGE_INTEGER NewMaximumSize)
3883{
3884 LARGE_INTEGER SafeNewMaximumSize;
3885 PSECTION Section;
3888
3889 /* Check for user-mode parameters */
3890 if (PreviousMode != KernelMode)
3891 {
3892 /* Enter SEH */
3893 _SEH2_TRY
3894 {
3895 /* Probe and capture the maximum size, it's both read and write */
3896 ProbeForWriteLargeInteger(NewMaximumSize);
3897 SafeNewMaximumSize = *NewMaximumSize;
3898 }
3900 {
3901 /* Return the exception code */
3903 }
3904 _SEH2_END;
3905 }
3906 else
3907 {
3908 /* Just read the size directly */
3909 SafeNewMaximumSize = *NewMaximumSize;
3910 }
3911
3912 /* Reference the section */
3913 Status = ObReferenceObjectByHandle(SectionHandle,
3917 (PVOID*)&Section,
3918 NULL);
3919 if (!NT_SUCCESS(Status)) return Status;
3920
3921 Status = MmExtendSection(Section, &SafeNewMaximumSize);
3922
3923 /* Dereference the section */
3924 ObDereferenceObject(Section);
3925
3926 if (NT_SUCCESS(Status))
3927 {
3928 _SEH2_TRY
3929 {
3930 /* Write back the new size */
3931 *NewMaximumSize = SafeNewMaximumSize;
3932 }
3934 {
3936 }
3937 _SEH2_END;
3938 }
3939
3940 /* Return the status */
3942}
3943
3944/* EOF */
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:3128
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1756
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:1948
CHAR MmUserProtectionToMask1[16]
Definition: section.c:44
NTSTATUS MiMapViewInSystemSpace(_In_ PVOID Section, _In_ PMMSESSION Session, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset)
Definition: section.c:1040
BOOLEAN NTAPI MmForceSectionClosed(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
Definition: section.c:3042
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3848
NTSTATUS NTAPI MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:530
VOID NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:462
BOOLEAN NTAPI MiIsProtectionCompatible(IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
Definition: section.c:117
ACCESS_MASK MmMakeSectionAccess[8]
Definition: section.c:20
NTSTATUS NTAPI MmGetFileNameForSection(IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1864
ULONG MmCompatibleProtectionMask[8]
Definition: section.c:84
NTSTATUS NTAPI MiSetProtectionOnSection(IN PEPROCESS Process, IN PMMVAD FoundVad, IN PVOID StartingAddress, IN PVOID EndingAddress, IN ULONG NewProtect, OUT PULONG CapturedOldProtect, IN ULONG DontCharge, OUT PULONG Locked)
Definition: section.c:2119
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:3441
static NTSTATUS NTAPI MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1552
MMSESSION MmSession
Definition: section.c:107
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3569
NTSTATUS NTAPI MiUnmapViewInSystemSpace(IN PMMSESSION Session, IN PVOID MappedBase)
Definition: section.c:2434
VOID NTAPI MiSetControlAreaSymbolsLoaded(IN PCONTROL_AREA ControlArea)
Definition: section.c:1152
VOID NTAPI MiFlushTbAndCapture(IN PMMVAD FoundVad, IN PMMPTE PointerPte, IN ULONG ProtectionMask, IN PMMPFN Pfn1, IN BOOLEAN UpdateDirty)
Definition: section.c:2015
ULONG NTAPI MmDoesFileHaveUserWritableReferences(IN PSECTION_OBJECT_POINTERS SectionPointer)
Definition: section.c:3352
ULONG NTAPI MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2390
NTSTATUS NTAPI 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:1264
VOID NTAPI MiLoadUserSymbols(IN PCONTROL_AREA ControlArea, IN PVOID BaseAddress, IN PEPROCESS Process)
Definition: section.c:1168
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:2468
static NTSTATUS MiAddMappedPtes(IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea, IN LONGLONG SectionOffset)
Definition: section.c:399
CHAR MmUserProtectionToMask2[16]
Definition: section.c:64
VOID NTAPI MmGetImageInformation(OUT PSECTION_IMAGE_INFORMATION ImageInformation)
Definition: section.c:1811
VOID NTAPI MiDeleteARM3Section(PVOID ObjectBody)
Definition: section.c:3316
VOID NTAPI MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:749
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:3622
VOID NTAPI MiSubsectionConsistent(IN PSUBSECTION Subsection)
Definition: section.c:1519
NTSTATUS NTAPI MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1536
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:2896
NTSTATUS NTAPI MmUnmapViewInSessionSpace(IN PVOID MappedBase)
Definition: section.c:3089
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:3054
NTSTATUS NTAPI MiSessionCommitPageTables(IN PVOID StartVa, IN PVOID EndVa)
Definition: section.c:924
NTSTATUS NTAPI MiGetFileObjectForSectionAddress(IN PVOID Address, OUT PFILE_OBJECT *FileObject)
Definition: section.c:1671
PVOID MmHighSectionBase
Definition: section.c:111
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:3362
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:714
NTSTATUS NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName)
Definition: section.c:1885
KGUARDED_MUTEX MmSectionCommitMutex
Definition: section.c:108
BOOLEAN NTAPI MiInitializeSystemSpaceMap(IN PMMSESSION InputSession OPTIONAL)
Definition: section.c:222
NTSTATUS NTAPI MmCommitSessionMappedView(IN PVOID MappedBase, IN SIZE_T ViewSize)
Definition: section.c:3153
NTSTATUS NTAPI MiUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
Definition: section.c:803
NTSTATUS NTAPI MmGetFileNameForFileObject(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1832
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID SectionObject)
Definition: section.c:1737
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3117
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
PVOID NTAPI MiInsertInSystemSpace(IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
Definition: section.c:288
BOOLEAN NTAPI MmDisableModifiedWriteOfSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: section.c:3031
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
VOID NTAPI MiRemoveMappedPtes(IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
Definition: section.c:2288
VOID NTAPI MiSegmentDelete(IN PSEGMENT Segment)
Definition: section.c:591
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:140
NTSTATUS NTAPI NtExtendSection(IN HANDLE SectionHandle, IN OUT PLARGE_INTEGER NewMaximumSize)
Definition: section.c:3881
#define PAGED_CODE()
#define ALIGN_DOWN_BY(size, align)
static const CHAR FileNameA[]
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: debug.h:115
#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
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:32
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
#define RtlImageNtHeader
Definition: compat.h:806
static int Hash(const char *)
Definition: reader.c:2257
#define ULONG_PTR
Definition: config.h:101
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define InsertHeadList(ListHead, Entry)
#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 APC_LEVEL
Definition: env_spec_w32.h:695
#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 ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
#define ExGetPreviousMode
Definition: ex.h:140
struct _FileName FileName
Definition: fatprocs.h:896
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:166
#define PROCESS_VM_OPERATION
Definition: pstypes.h:160
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
NTSYSAPI void WINAPI DbgBreakPoint(void)
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:116
#define MM_EXECUTE_WRITECOPY
Definition: miarm.h:50
VOID NTAPI MiDeleteVirtualAddresses(IN ULONG_PTR Va, IN ULONG_PTR EndingAddress, IN PMMVAD Vad)
Definition: virtual.c:530
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:537
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:827
ULONG NTAPI MiGetPageProtection(IN PMMPTE PointerPte)
Definition: virtual.c:1353
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:423
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:440
ULONG MmSecondaryColorMask
Definition: mminit.c:257
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1098
#define MM_GUARDPAGE
Definition: miarm.h:57
ULONG NTAPI MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress, IN KIRQL OldIrql)
Definition: virtual.c:235
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree(IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base)
Definition: vadnode.c:799
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:611
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:232
#define MM_NOCACHE
Definition: miarm.h:56
#define MM_DELETE_CHECK
Definition: miarm.h:256
#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:1018
#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:261
#define MM_EXECUTE
Definition: miarm.h:45
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1239
#define MM_EXECUTE_READ
Definition: miarm.h:46
@ MiWriteCombined
Definition: miarm.h:412
@ MiCached
Definition: miarm.h:411
@ MiNonCached
Definition: miarm.h:410
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:992
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2479
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:4557
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:265
#define SYSTEM_PD_SIZE
Definition: miarm.h:32
#define MM_NOACCESS
Definition: miarm.h:65
NTSTATUS NTAPI MiRosUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
Definition: section.c:3589
NTSTATUS NTAPI MiInsertVadEx(_Inout_ PMMVAD Vad, _In_ ULONG_PTR *BaseAddress, _In_ SIZE_T ViewSize, _In_ ULONG_PTR HighestAddress, _In_ ULONG_PTR Alignment, _In_ ULONG AllocationType)
Definition: vadnode.c:282
struct _MMVIEW MMVIEW
NTSTATUS NTAPI MiCheckSecuredVad(IN PMMVAD Vad, IN PVOID Base, IN SIZE_T Size, IN ULONG ProtectionMask)
Definition: vadnode.c:903
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:977
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2481
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1574
SIZE_T MmSizeOfPagedPoolInBytes
Definition: miarm.h:585
#define MM_WRITECOPY
Definition: miarm.h:48
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1169
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned __int64 ULONG64
Definition: imports.h:198
#define SECTION
Definition: profile.c:31
#define _Outptr_result_bytebuffer_(size)
Definition: ms_sal.h:472
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
struct _MMPTE MMPTE
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT InheritDisposition
Definition: mmfuncs.h:409
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:363
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:405
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:364
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG AllocationType
Definition: mmfuncs.h:410
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
struct _SUBSECTION * PSUBSECTION
@ VadWriteWatch
Definition: mmtypes.h:208
@ VadRotatePhysical
Definition: mmtypes.h:210
@ VadImageMap
Definition: mmtypes.h:206
@ VadNone
Definition: mmtypes.h:204
struct _SUBSECTION SUBSECTION
#define SEC_NOCACHE
Definition: mmtypes.h:101
struct _SEGMENT SEGMENT
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SEC_IMAGE
Definition: mmtypes.h:97
#define MEM_DOS_LIM
Definition: mmtypes.h:90
struct _MSUBSECTION MSUBSECTION
#define SEC_LARGE_PAGES
Definition: mmtypes.h:103
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
struct _SECTION * PSECTION
struct _CONTROL_AREA CONTROL_AREA
@ ActiveAndValid
Definition: mmtypes.h:159
@ ModifiedPageList
Definition: mmtypes.h:156
@ StandbyPageList
Definition: mmtypes.h:155
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
VOID NTAPI DbgLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
_In_ PMEMORY_AREA MemoryArea
Definition: newmm.h:207
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
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
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#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
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
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:319
#define UNICODE_NULL
#define SEC_BASED
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1647
#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 MiPteToAddress(_Pte)
Definition: mm.h:116
#define PDE_PER_PAGE
Definition: mm.h:21
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:526
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace(VOID)
Definition: mm.h:1719
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
#define MM_NOIRQL
Definition: mm.h:70
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:334
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1691
LIST_ENTRY MmLoadedUserImageList
Definition: sysldr.c:22
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:1043
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:97
struct _MEMORY_AREA * PMEMORY_AREA
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1704
#define MI_SET_USAGE(x)
Definition: mm.h:317
NTSTATUS NTAPI MmExtendSection(_In_ PVOID Section, _Inout_ PLARGE_INTEGER NewSize)
Definition: section.c:5273
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
SIZE_T MmSharedCommit
Definition: freelist.c:31
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1726
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
PMMPDE MmSystemPagePtes
Definition: init.c:41
PVOID MiSessionViewStart
Definition: init.c:30
ULONG MmSessionViewSize
Definition: init.c:35
ULONG MmSystemViewSize
Definition: init.c:39
PVOID MmSessionBase
Definition: init.c:33
PVOID MiSystemViewStart
Definition: init.c:38
PVOID MiSessionSpaceEnd
Definition: init.c:27
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
MMPTE ValidKernelPdeLocal
Definition: init.c:32
MMPTE PrototypePte
Definition: init.c:40
MMPTE ValidKernelPde
Definition: init.c:28
const ULONG MmProtectToValue[32]
Definition: page.c:71
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_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#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
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
TCHAR ModuleFileName[MAX_PATH+1]
Definition: rundll32.c:56
#define _WARN(msg)
Definition: debug.h:263
#define ProbeForWriteLargeInteger(Ptr)
Definition: probe.h:46
#define ProbeForWritePointer(Ptr)
Definition: probe.h:42
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define ProbeForWriteSize_t(Ptr)
Definition: probe.h:45
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
ULONG PFN_NUMBER
Definition: ke.h:9
#define memset(x, y, z)
Definition: compat.h:39
NTSTATUS NTAPI MmMapViewInSystemSpace(IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:4447
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:3996
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:4620
POBJECT_TYPE MmSectionObjectType
Definition: section.c:194
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
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
union _CONTROL_AREA::@2599 u
PFILE_OBJECT FilePointer
Definition: mmtypes.h:533
LIST_ENTRY DereferenceList
Definition: mmtypes.h:522
ULONG PageFrameNumber
Definition: mmtypes.h:74
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
Definition: btrfs_drv.h:1876
USHORT LoadCount
Definition: ntddk_ex.h:208
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
ULONG SizeOfImage
Definition: ldrtypes.h:143
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG CheckSum
Definition: btrfs_drv.h:1886
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _MEMORY_AREA::@1787 SectionData
ULONG Type
Definition: mm.h:251
ULONG_PTR StartingVpn
Definition: mmtypes.h:653
ULONG_PTR EndingVpn
Definition: mmtypes.h:654
USHORT PrototypePte
Definition: mm.h:363
USHORT Modified
Definition: mm.h:360
USHORT PageLocation
Definition: mm.h:365
Definition: mm.h:374
union _MMPFN::@1790 u3
MMPTE OriginalPte
Definition: mm.h:407
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1788 u1
PKEVENT Event
Definition: mm.h:379
USHORT ReferenceCount
Definition: mm.h:396
ULONG64 Dirty
Definition: mmtypes.h:164
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
ULONG64 Transition
Definition: mmtypes.h:90
ULONG64 Protection
Definition: mmtypes.h:88
ULONG64 Prototype
Definition: mmtypes.h:89
union _MMPTE::@2325 u
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG PhysicalMemory
Definition: mmtypes.h:473
ULONG BeingDeleted
Definition: mmtypes.h:463
ULONG NoChange
Definition: mmtypes.h:486
ULONG UserReference
Definition: mmtypes.h:479
ULONG CopyOnWrite
Definition: mmtypes.h:474
ULONG FilePointerNull
Definition: mmtypes.h:482
ULONG WriteCombined
Definition: mmtypes.h:493
ULONG BeingCreated
Definition: mmtypes.h:464
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:491
ULONG WasPurged
Definition: mmtypes.h:478
ULONG SystemSpaceHashKey
Definition: miarm.h:456
ULONG SystemSpaceHashEntries
Definition: miarm.h:455
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:451
PRTL_BITMAP SystemSpaceBitMap
Definition: miarm.h:458
PCHAR SystemSpaceViewStart
Definition: miarm.h:452
ULONG SystemSpaceHashSize
Definition: miarm.h:454
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:453
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:450
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 Spare
Definition: mmtypes.h:697
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::@2610 u2
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
union _MMVAD_LONG::@2609 u
union _MMVAD_LONG::@2612 u4
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
PCONTROL_AREA ControlArea
Definition: mmtypes.h:736
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
union _MMVAD::@2606 u
Definition: miarm.h:443
PCONTROL_AREA ControlArea
Definition: miarm.h:445
ULONG_PTR Entry
Definition: miarm.h:444
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:480
PMMPDE PageTables
Definition: miarm.h:507
MMSESSION Session
Definition: miarm.h:497
SIZE_T CommittedPages
Definition: miarm.h:482
SIZE_T NonPageablePages
Definition: miarm.h:481
UNICODE_STRING Name
Definition: nt_native.h:1270
union _SECTION::@2615 u
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
PSEGMENT Segment
Definition: mmtypes.h:812
ULONG InitialPageProtection
Definition: mmtypes.h:819
MMADDRESS_NODE Address
Definition: mmtypes.h:811
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:813
ULONG LargePages
Definition: mmtypes.h:403
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:409
PEPROCESS CreatingProcess
Definition: mmtypes.h:422
ULONG TotalNumberOfPtes
Definition: mmtypes.h:410
PVOID BasedAddress
Definition: mmtypes.h:418
MMPTE SegmentPteTemplate
Definition: mmtypes.h:414
PMMPTE PrototypePte
Definition: mmtypes.h:429
union _SEGMENT::@2597 u1
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::@2601 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
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_MM
Definition: tag.h:113
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
struct _RTL_BITMAP RTL_BITMAP
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ALIGN_DOWN_POINTER_BY(ptr, align)
Definition: umtypes.h:82
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
static BOOL Attached
Definition: vidbios.c:3905
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
* PFILE_OBJECT
Definition: iotypes.h:1998
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
KAPC_STATE
Definition: ketypes.h:1409
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492
#define BYTES_TO_PAGES(Size)
#define PAGE_ALIGN(Va)
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
_In_ BOOLEAN DelayClose
Definition: mmfuncs.h:592
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17
NTSYSAPI VOID NTAPI RtlFillMemoryUlonglong(_Out_writes_bytes_all_(Length) PVOID Destination, _In_ SIZE_T Length, _In_ ULONGLONG Pattern)
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
__wchar_t WCHAR
Definition: xmlstorage.h:180
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