ReactOS 0.4.17-dev-1190-g4c812f4
section.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for section.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 

Functions

static BOOLEAN MiIsProtectionCompatible (IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
 
ULONG NTAPI MiMakeProtectionMask (IN ULONG Protect)
 
BOOLEAN NTAPI MiInitializeSystemSpaceMap (IN PMMSESSION InputSession OPTIONAL)
 
static PVOID MiInsertInSystemSpace (IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
 
static NTSTATUS MiAddMappedPtes (IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea, IN LONGLONG SectionOffset)
 
VOID NTAPI MiFillSystemPageDirectory (IN PVOID Base, IN SIZE_T NumberOfBytes)
 
static NTSTATUS MiCheckPurgeAndUpMapCount (IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
 
PSUBSECTION NTAPI MiLocateSubsection (IN PMMVAD Vad, IN ULONG_PTR Vpn)
 
static VOID MiSegmentDelete (IN PSEGMENT Segment)
 
static VOID MiCheckControlArea (IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
 
static VOID MiDereferenceControlArea (IN PCONTROL_AREA ControlArea)
 
VOID NTAPI MiRemoveMappedView (IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
 
static NTSTATUS MiUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
 
static NTSTATUS MiSessionCommitPageTables (IN PVOID StartVa, IN PVOID EndVa)
 
NTSTATUS MiMapViewInSystemSpace (_In_ PVOID Section, _In_ PMMSESSION Session, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset)
 
static NTSTATUS MiMapViewOfDataSection (_In_ PCONTROL_AREA ControlArea, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _Inout_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_ PSECTION Section, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG ProtectionMask, _In_ SIZE_T CommitSize, _In_ ULONG_PTR ZeroBits, _In_ ULONG AllocationType)
 
static NTSTATUS MiCreateDataFileMap (IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
 
static NTSTATUS MiCreatePagingFileMap (OUT PSEGMENT *Segment, IN ULONG64 MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
 
PFILE_OBJECT NTAPI MmGetFileObjectForSection (IN PVOID SectionObject)
 
static PFILE_OBJECT MiGetFileObjectForVad (_In_ PMMVAD Vad)
 
VOID NTAPI MmGetImageInformation (OUT PSECTION_IMAGE_INFORMATION ImageInformation)
 
static NTSTATUS MmGetFileNameForFileObject (IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
 
NTSTATUS NTAPI MmGetFileNameForSection (IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
 
NTSTATUS NTAPI MmGetFileNameForAddress (IN PVOID Address, OUT PUNICODE_STRING ModuleName)
 
NTSTATUS NTAPI MiQueryMemorySectionName (IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
 
VOID NTAPI MiFlushTbAndCapture (IN PMMVAD FoundVad, IN PMMPTE PointerPte, IN ULONG ProtectionMask, IN PMMPFN Pfn1, IN BOOLEAN UpdateDirty)
 
static VOID MiRemoveMappedPtes (IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
 
static ULONG MiRemoveFromSystemSpace (IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
 
static NTSTATUS MiUnmapViewInSystemSpace (IN PMMSESSION Session, IN PVOID MappedBase)
 
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)
 
NTSTATUS NTAPI MmMapViewOfArm3Section (_In_ PVOID SectionObject, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _When_(*ViewSize !=0, _Pre_opt_valid_) _When_(*ViewSize==0, _Pre_valid_) PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Protect)
 
BOOLEAN NTAPI MmDisableModifiedWriteOfSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
 
BOOLEAN NTAPI MmForceSectionClosed (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
 
NTSTATUS NTAPI MmMapViewInSessionSpace (IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
 
NTSTATUS NTAPI MmUnmapViewInSessionSpace (IN PVOID MappedBase)
 
NTSTATUS NTAPI MmUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress)
 
NTSTATUS NTAPI MmUnmapViewInSystemSpace (IN PVOID MappedBase)
 
NTSTATUS NTAPI MmCommitSessionMappedView (IN PVOID MappedBase, IN SIZE_T ViewSize)
 
VOID NTAPI MiDeleteARM3Section (PVOID ObjectBody)
 
ULONG NTAPI MmDoesFileHaveUserWritableReferences (IN PSECTION_OBJECT_POINTERS SectionPointer)
 
NTSTATUS NTAPI NtAreMappedFilesTheSame (IN PVOID File1MappedAsAnImage, IN PVOID File2MappedAsFile)
 
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)
 
NTSTATUS NTAPI NtOpenSection (OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
 
NTSTATUS NTAPI NtMapViewOfSection (_In_ HANDLE SectionHandle, _In_ HANDLE ProcessHandle, _Outptr_result_bytebuffer_(*ViewSize) _Pre_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Win32Protect)
 
NTSTATUS NTAPI NtUnmapViewOfSection (IN HANDLE ProcessHandle, IN PVOID BaseAddress)
 
NTSTATUS NTAPI NtExtendSection (IN HANDLE SectionHandle, IN OUT PLARGE_INTEGER NewMaximumSize)
 

Variables

ACCESS_MASK MmMakeSectionAccess [8]
 
ACCESS_MASK MmMakeFileAccess [8]
 
CHAR MmUserProtectionToMask1 [16]
 
CHAR MmUserProtectionToMask2 [16]
 
ULONG MmCompatibleProtectionMask [8]
 
MMSESSION MmSession
 
KGUARDED_MUTEX MmSectionCommitMutex
 
MM_AVL_TABLE MmSectionBasedRoot
 
KGUARDED_MUTEX MmSectionBasedMutex
 
PVOID MmHighSectionBase
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 15 of file section.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file section.c.

Function Documentation

◆ MiAddMappedPtes()

static NTSTATUS MiAddMappedPtes ( IN PMMPTE  FirstPte,
IN PFN_NUMBER  PteCount,
IN PCONTROL_AREA  ControlArea,
IN LONGLONG  SectionOffset 
)
static

Definition at line 408 of file section.c.

412{
414 PMMPTE PointerPte, ProtoPte, LastProtoPte, LastPte;
415 PSUBSECTION Subsection;
416
417 /* Mapping at offset not supported yet */
418 ASSERT(SectionOffset == 0);
419
420 /* ARM3 doesn't support this yet */
421 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
422 ASSERT(ControlArea->u.Flags.Rom == 0);
423 ASSERT(ControlArea->FilePointer == NULL);
424
425 /* Sanity checks */
426 ASSERT(PteCount != 0);
427 ASSERT(ControlArea->NumberOfMappedViews >= 1);
428 ASSERT(ControlArea->NumberOfUserReferences >= 1);
429 ASSERT(ControlArea->NumberOfSectionReferences != 0);
430 ASSERT(ControlArea->u.Flags.BeingCreated == 0);
431 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
432 ASSERT(ControlArea->u.Flags.BeingPurged == 0);
433
434 /* Get the PTEs for the actual mapping */
435 PointerPte = FirstPte;
436 LastPte = FirstPte + PteCount;
437
438 /* Get the prototype PTEs that desribe the section mapping in the subsection */
439 Subsection = (PSUBSECTION)(ControlArea + 1);
440 ProtoPte = Subsection->SubsectionBase;
441 LastProtoPte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
442
443 /* Loop the PTEs for the mapping */
444 while (PointerPte < LastPte)
445 {
446 /* We may have run out of prototype PTEs in this subsection */
447 if (ProtoPte >= LastProtoPte)
448 {
449 /* But we don't handle this yet */
450 ASSERT(FALSE);
451 }
452
453 /* The PTE should be completely clear */
454 ASSERT(PointerPte->u.Long == 0);
455
456 /* Build the prototype PTE and write it */
457 MI_MAKE_PROTOTYPE_PTE(&TempPte, ProtoPte);
458 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
459
460 /* Keep going */
461 PointerPte++;
462 ProtoPte++;
463 }
464
465 /* No failure path */
466 return STATUS_SUCCESS;
467}
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:1000
#define ASSERT(a)
Definition: mode.c:44
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:411
struct _SUBSECTION * PSUBSECTION
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, IN PMMPTE PointerPte)
Definition: mm.h:341
#define STATUS_SUCCESS
Definition: shellext.h:65
union _MMPTE::@2788 u
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG PtesInSubsection
Definition: mmtypes.h:583
PMMPTE SubsectionBase
Definition: mmtypes.h:581

Referenced by MiMapViewInSystemSpace().

◆ MiCheckControlArea()

static VOID MiCheckControlArea ( IN PCONTROL_AREA  ControlArea,
IN KIRQL  OldIrql 
)
static

Definition at line 723 of file section.c.

725{
726 BOOLEAN DeleteSegment = FALSE;
728
729 /* Check if this is the last reference or view */
730 if (!(ControlArea->NumberOfMappedViews) &&
731 !(ControlArea->NumberOfSectionReferences))
732 {
733 /* There should be no more user references either */
734 ASSERT(ControlArea->NumberOfUserReferences == 0);
735
736 /* Not yet supported */
737 ASSERT(ControlArea->FilePointer == NULL);
738
739 /* The control area is being destroyed */
740 ControlArea->u.Flags.BeingDeleted = TRUE;
741 DeleteSegment = TRUE;
742 }
743
744 /* Release the PFN lock */
745 MiReleasePfnLock(OldIrql);
746
747 /* Delete the segment if needed */
748 if (DeleteSegment)
749 {
750 /* No more user write references at all */
751 ASSERT(ControlArea->WritableUserReferences == 0);
752 MiSegmentDelete(ControlArea->Segment);
753 }
754}
static VOID MiSegmentDelete(IN PSEGMENT Segment)
Definition: section.c:600
unsigned char BOOLEAN
Definition: actypes.h:127
#define TRUE
Definition: types.h:120
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:1038
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by MiDeleteARM3Section(), MiDereferenceControlArea(), MiRemoveMappedPtes(), MiRemoveMappedView(), and MmCreateArm3Section().

◆ MiCheckPurgeAndUpMapCount()

static NTSTATUS MiCheckPurgeAndUpMapCount ( IN PCONTROL_AREA  ControlArea,
IN BOOLEAN  FailIfSystemViews 
)
static

Definition at line 539 of file section.c.

541{
543
544 /* Flag not yet supported */
545 ASSERT(FailIfSystemViews == FALSE);
546
547 /* Lock the PFN database */
548 OldIrql = MiAcquirePfnLock();
549
550 /* State not yet supported */
551 ASSERT(ControlArea->u.Flags.BeingPurged == 0);
552
553 /* Increase the reference counts */
554 ControlArea->NumberOfMappedViews++;
555 ControlArea->NumberOfUserReferences++;
556 ASSERT(ControlArea->NumberOfSectionReferences != 0);
557
558 /* Release the PFN lock and return success */
559 MiReleasePfnLock(OldIrql);
560 return STATUS_SUCCESS;
561}
UCHAR KIRQL
Definition: env_spec_w32.h:591

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

◆ MiCreateDataFileMap()

static NTSTATUS MiCreateDataFileMap ( IN PFILE_OBJECT  File,
OUT PSEGMENT *  Segment,
IN PLARGE_INTEGER  MaximumSize,
IN ULONG  SectionPageProtection,
IN ULONG  AllocationAttributes,
IN ULONG  IgnoreFileSizing 
)
static

Definition at line 1419 of file section.c.

1425{
1426 /* Not yet implemented */
1427 ASSERT(FALSE);
1428 *Segment = NULL;
1430}
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

Referenced by MmCreateArm3Section().

◆ MiCreatePagingFileMap()

static NTSTATUS MiCreatePagingFileMap ( OUT PSEGMENT *  Segment,
IN ULONG64  MaximumSize,
IN ULONG  ProtectionMask,
IN ULONG  AllocationAttributes 
)
static

Definition at line 1434 of file section.c.

1438{
1439 ULONGLONG SizeLimit;
1440 PFN_COUNT PteCount;
1441 PMMPTE PointerPte;
1442 MMPTE TempPte;
1443 PCONTROL_AREA ControlArea;
1444 PSEGMENT NewSegment;
1445 PSUBSECTION Subsection;
1446 PAGED_CODE();
1447
1448 /* No large pages in ARM3 yet */
1450
1451 /* Pagefile-backed sections need a known size */
1452 if (MaximumSize == 0)
1454
1455 /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1456 SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
1457 SizeLimit /= sizeof(MMPTE);
1458 SizeLimit <<= PAGE_SHIFT;
1459
1460 /* Fail if this size is too big */
1461 if (MaximumSize > SizeLimit)
1462 {
1464 }
1465
1466 /* Calculate how many Prototype PTEs will be needed */
1467 PteCount = (PFN_COUNT)((MaximumSize + PAGE_SIZE - 1) >> PAGE_SHIFT);
1468
1469 /* For commited memory, we must have a valid protection mask */
1470 if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1471
1472 /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1473 NewSegment = ExAllocatePoolWithTag(PagedPool,
1474 sizeof(SEGMENT) +
1475 sizeof(MMPTE) * (PteCount - 1),
1476 'tSmM');
1477 if (!NewSegment)
1478 {
1480 }
1481 *Segment = NewSegment;
1482
1483 /* Now allocate the control area, which has the subsection structure */
1484 ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1485 sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1486 'tCmM');
1487 if (!ControlArea)
1488 {
1489 ExFreePoolWithTag(Segment, 'tSmM');
1491 }
1492
1493 /* And zero it out, filling the basic segmnet pointer and reference fields */
1494 RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1495 ControlArea->Segment = NewSegment;
1496 ControlArea->NumberOfSectionReferences = 1;
1497 ControlArea->NumberOfUserReferences = 1;
1498
1499 /* Convert allocation attributes to control area flags */
1500 if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1501 if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1502 if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1503
1504 /* We just allocated it */
1505 ControlArea->u.Flags.BeingCreated = 1;
1506
1507 /* The subsection follows, write the mask, PTE count and point back to the CA */
1508 Subsection = (PSUBSECTION)(ControlArea + 1);
1509 Subsection->ControlArea = ControlArea;
1510 Subsection->PtesInSubsection = PteCount;
1511 Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1512
1513 /* Zero out the segment's prototype PTEs, and link it with the control area */
1514 PointerPte = &NewSegment->ThePtes[0];
1515 RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1516 NewSegment->PrototypePte = PointerPte;
1517 NewSegment->ControlArea = ControlArea;
1518
1519 /* Save some extra accounting data for the segment as well */
1520 NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1521 NewSegment->SizeOfSegment = ((ULONGLONG)PteCount) * PAGE_SIZE;
1522 NewSegment->TotalNumberOfPtes = PteCount;
1523 NewSegment->NonExtendedPtes = PteCount;
1524
1525 /* The subsection's base address is the first Prototype PTE in the segment */
1526 Subsection->SubsectionBase = PointerPte;
1527
1528 /* Start with an empty PTE, unless this is a commit operation */
1529 TempPte.u.Long = 0;
1531 {
1532 /* In which case, write down the protection mask in the Prototype PTEs */
1533 TempPte.u.Soft.Protection = ProtectionMask;
1534
1535 /* For accounting, also mark these pages as being committed */
1536 NewSegment->NumberOfCommittedPages = PteCount;
1537 }
1538
1539 /* The template PTE itself for the segment should also have the mask set */
1540 NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1541
1542 /* Write out the prototype PTEs, for now they're simply demand zero */
1543#ifdef _WIN64
1544 RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1545#else
1546 RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1547#endif
1548 return STATUS_SUCCESS;
1549}
#define PAGED_CODE()
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
SIZE_T MmSizeOfPagedPoolInBytes
Definition: miarm.h:590
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _MMPTE MMPTE
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:366
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:368
struct _SEGMENT SEGMENT
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SEC_LARGE_PAGES
Definition: mmtypes.h:103
#define SEC_RESERVE
Definition: nt_native.h:1326
#define SEC_BASED
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:572
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:394
PSEGMENT Segment
Definition: mmtypes.h:521
ULONG NumberOfSectionReferences
Definition: mmtypes.h:523
ULONG NumberOfUserReferences
Definition: mmtypes.h:527
union _CONTROL_AREA::@3107 u
MMSECTION_FLAGS Flags
Definition: mmtypes.h:531
ULONG64 Protection
Definition: mmtypes.h:88
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
ULONG BeingCreated
Definition: mmtypes.h:464
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:409
PEPROCESS CreatingProcess
Definition: mmtypes.h:422
ULONG TotalNumberOfPtes
Definition: mmtypes.h:410
MMPTE SegmentPteTemplate
Definition: mmtypes.h:414
PMMPTE PrototypePte
Definition: mmtypes.h:429
union _SEGMENT::@3105 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
MMSUBSECTION_FLAGS SubsectionFlags
Definition: mmtypes.h:577
PCONTROL_AREA ControlArea
Definition: mmtypes.h:573
union _SUBSECTION::@3109 u
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define PsGetCurrentProcess
Definition: psfuncs.h:17
NTSYSAPI VOID NTAPI RtlFillMemoryUlonglong(_Out_writes_bytes_all_(Length) PVOID Destination, _In_ SIZE_T Length, _In_ ULONGLONG Pattern)

Referenced by MmCreateArm3Section().

◆ MiDeleteARM3Section()

VOID NTAPI MiDeleteARM3Section ( PVOID  ObjectBody)

Definition at line 2972 of file section.c.

2973{
2975 PCONTROL_AREA ControlArea;
2976 KIRQL OldIrql;
2977
2978 SectionObject = (PSECTION)ObjectBody;
2979
2980 if (SectionObject->u.Flags.Based == 1)
2981 {
2982 /* Remove the node from the global section address tree */
2986 }
2987
2988 /* Lock the PFN database */
2989 OldIrql = MiAcquirePfnLock();
2990
2991 ASSERT(SectionObject->Segment);
2992 ASSERT(SectionObject->Segment->ControlArea);
2993
2994 ControlArea = SectionObject->Segment->ControlArea;
2995
2996 /* Dereference */
2997 ControlArea->NumberOfSectionReferences--;
2998 ControlArea->NumberOfUserReferences--;
2999
3000 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
3001
3002 /* Check it. It will delete it if there is no more reference to it */
3003 MiCheckControlArea(ControlArea, OldIrql);
3004}
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
static VOID MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:723
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:403
struct _SECTION * PSECTION
ULONG BeingDeleted
Definition: mmtypes.h:463

Referenced by MmpDeleteSection().

◆ MiDereferenceControlArea()

static VOID MiDereferenceControlArea ( IN PCONTROL_AREA  ControlArea)
static

Definition at line 758 of file section.c.

759{
761
762 /* Lock the PFN database */
763 OldIrql = MiAcquirePfnLock();
764
765 /* Drop reference counts */
766 ControlArea->NumberOfMappedViews--;
767 ControlArea->NumberOfUserReferences--;
768
769 /* Check if it's time to delete the CA. This releases the lock */
770 MiCheckControlArea(ControlArea, OldIrql);
771}

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

◆ MiFillSystemPageDirectory()

VOID NTAPI MiFillSystemPageDirectory ( IN PVOID  Base,
IN SIZE_T  NumberOfBytes 
)

Definition at line 471 of file section.c.

473{
474 PMMPDE PointerPde, LastPde, SystemMapPde;
476 PFN_NUMBER PageFrameIndex, ParentPage;
478 PAGED_CODE();
479
480 /* Find the PDEs needed for this mapping */
481 PointerPde = MiAddressToPde(Base);
482 LastPde = MiAddressToPde((PVOID)((ULONG_PTR)Base + NumberOfBytes - 1));
483
484#if (_MI_PAGING_LEVELS == 2)
485 /* Find the system double-mapped PDE that describes this mapping */
486 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
487#else
488 /* We don't have a double mapping */
489 SystemMapPde = PointerPde;
490#endif
491
492 /* Use the PDE template and loop the PDEs */
494 while (PointerPde <= LastPde)
495 {
496 /* Lock the PFN database */
497 OldIrql = MiAcquirePfnLock();
498
499 /* Check if we don't already have this PDE mapped */
500 if (SystemMapPde->u.Hard.Valid == 0)
501 {
502 /* Grab a page for it */
504 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
505 PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
506 ASSERT(PageFrameIndex);
507 TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
508
509#if (_MI_PAGING_LEVELS == 2)
510 ParentPage = MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_PER_PAGE];
511#else
512 ParentPage = MiPdeToPpe(PointerPde)->u.Hard.PageFrameNumber;
513#endif
514 /* Initialize its PFN entry, with the parent system page directory page table */
515 MiInitializePfnForOtherProcess(PageFrameIndex,
516 (PMMPTE)PointerPde,
517 ParentPage);
518
519 /* Make the system PDE entry valid */
520 MI_WRITE_VALID_PDE(SystemMapPde, TempPde);
521
522 /* The system PDE entry might be the PDE itself, so check for this */
523 if (PointerPde->u.Hard.Valid == 0)
524 {
525 /* It's different, so make the real PDE valid too */
526 MI_WRITE_VALID_PDE(PointerPde, TempPde);
527 }
528 }
529
530 /* Release the lock and keep going with the next PDE */
531 MiReleasePfnLock(OldIrql);
532 SystemMapPde++;
533 PointerPde++;
534 }
535}
ULONG_PTR PFN_NUMBER
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
#define ULONG_PTR
Definition: config.h:101
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:537
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:236
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1301
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1025
#define SYSTEM_PD_SIZE
Definition: miarm.h:32
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
FORCEINLINE PMMPDE MiPdeToPpe(PMMPDE PointerPde)
Definition: mm.h:291
#define MiAddressToPde(x)
Definition: mm.h:155
#define PDE_PER_PAGE
Definition: mm.h:21
#define MI_SET_PROCESS2(x)
Definition: mm.h:325
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:340
#define MI_SET_USAGE(x)
Definition: mm.h:323
PMMPDE MmSystemPagePtes
Definition: init.c:41
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
MMPTE ValidKernelPde
Definition: init.c:28
ULONG PageFrameNumber
Definition: mmtypes.h:74
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036

Referenced by MiMapViewInSystemSpace(), and MmCreateVirtualMappingUnsafeEx().

◆ MiFlushTbAndCapture()

VOID NTAPI MiFlushTbAndCapture ( IN PMMVAD  FoundVad,
IN PMMPTE  PointerPte,
IN ULONG  ProtectionMask,
IN PMMPFN  Pfn1,
IN BOOLEAN  UpdateDirty 
)

Definition at line 1834 of file section.c.

1839{
1840 MMPTE TempPte, PreviousPte;
1841 KIRQL OldIrql;
1842 BOOLEAN RebuildPte = FALSE;
1843
1844 //
1845 // User for sanity checking later on
1846 //
1847 PreviousPte = *PointerPte;
1848
1849 //
1850 // Build the PTE and acquire the PFN lock
1851 //
1853 PointerPte,
1854 ProtectionMask,
1855 PreviousPte.u.Hard.PageFrameNumber);
1856 OldIrql = MiAcquirePfnLock();
1857
1858 //
1859 // We don't support I/O mappings in this path yet
1860 //
1861 ASSERT(Pfn1 != NULL);
1862 ASSERT(Pfn1->u3.e1.CacheAttribute != MiWriteCombined);
1863
1864 //
1865 // Make sure new protection mask doesn't get in conflict and fix it if it does
1866 //
1867 if (Pfn1->u3.e1.CacheAttribute == MiCached)
1868 {
1869 //
1870 // This is a cached PFN
1871 //
1872 if (ProtectionMask & (MM_NOCACHE | MM_NOACCESS))
1873 {
1874 RebuildPte = TRUE;
1875 ProtectionMask &= ~(MM_NOCACHE | MM_NOACCESS);
1876 }
1877 }
1878 else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
1879 {
1880 //
1881 // This is a non-cached PFN
1882 //
1883 if ((ProtectionMask & (MM_NOCACHE | MM_NOACCESS)) != MM_NOCACHE)
1884 {
1885 RebuildPte = TRUE;
1886 ProtectionMask &= ~MM_NOACCESS;
1887 ProtectionMask |= MM_NOCACHE;
1888 }
1889 }
1890
1891 if (RebuildPte)
1892 {
1894 PointerPte,
1895 ProtectionMask,
1896 PreviousPte.u.Hard.PageFrameNumber);
1897 }
1898
1899 //
1900 // Write the new PTE, making sure we are only changing the bits
1901 //
1902 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
1903
1904 //
1905 // Flush the TLB
1906 //
1907 ASSERT(PreviousPte.u.Hard.Valid == 1);
1909 ASSERT(PreviousPte.u.Hard.Valid == 1);
1910
1911 //
1912 // Windows updates the relevant PFN1 information, we currently don't.
1913 //
1914 if (UpdateDirty && PreviousPte.u.Hard.Dirty)
1915 {
1916 if (!Pfn1->u3.e1.Modified)
1917 {
1918 DPRINT1("FIXME: Mark PFN as dirty\n");
1919 }
1920 }
1921
1922 //
1923 // Not supported in ARM3
1924 //
1925 ASSERT(FoundVad->u.VadFlags.VadType != VadWriteWatch);
1926
1927 //
1928 // Release the PFN lock, we are done
1929 //
1930 MiReleasePfnLock(OldIrql);
1931}
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:834
#define MM_NOCACHE
Definition: miarm.h:56
@ MiWriteCombined
Definition: miarm.h:416
@ MiCached
Definition: miarm.h:415
@ MiNonCached
Definition: miarm.h:414
#define MM_NOACCESS
Definition: miarm.h:65
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:985
@ VadWriteWatch
Definition: mmtypes.h:208
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:361
ULONG64 Dirty
Definition: mmtypes.h:164

Referenced by MiProtectVirtualMemory().

◆ MiGetFileObjectForVad()

static PFILE_OBJECT MiGetFileObjectForVad ( _In_ PMMVAD  Vad)
static

Definition at line 1572 of file section.c.

1574{
1575 PCONTROL_AREA ControlArea;
1577
1578 /* Check if this is a RosMm memory area */
1579 if (MI_IS_MEMORY_AREA_VAD(Vad))
1580 {
1582
1583 /* We do not expect ARM3 memory areas here, those are kernel only */
1584 ASSERT(MI_IS_ROSMM_VAD(Vad));
1585
1586 /* Check if it's a section view (RosMm section) */
1588 {
1589 /* Get the section pointer to the SECTION_OBJECT */
1590 FileObject = MemoryArea->SectionData.Segment->FileObject;
1591 }
1592 else
1593 {
1594#ifdef NEWCC
1595 ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1596 DPRINT1("VAD is a cache section!\n");
1597#else
1598 ASSERT(FALSE);
1599#endif
1600 return NULL;
1601 }
1602 }
1603 else
1604 {
1605 /* Make sure it's not a VM VAD */
1606 if (Vad->u.VadFlags.PrivateMemory == 1)
1607 {
1608 DPRINT1("VAD is not a section\n");
1609 return NULL;
1610 }
1611
1612 /* Get the control area */
1613 ControlArea = Vad->ControlArea;
1614 if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1615 {
1616 DPRINT1("Address is not a section\n");
1617 return NULL;
1618 }
1619
1620 /* Get the file object */
1621 FileObject = ControlArea->FilePointer;
1622 }
1623
1624 /* Return the file object */
1625 return FileObject;
1626}
_In_ PMEMORY_AREA MemoryArea
Definition: newmm.h:207
struct _MEMORY_AREA * PMEMORY_AREA
#define MI_IS_MEMORY_AREA_VAD(Vad)
Definition: mm.h:267
#define MI_IS_ROSMM_VAD(Vad)
Definition: mm.h:269
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:90
PFILE_OBJECT FilePointer
Definition: mmtypes.h:533
ULONG Type
Definition: mm.h:253
struct _MEMORY_AREA::@2098 SectionData
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by MmGetFileNameForAddress(), and NtAreMappedFilesTheSame().

◆ MiInitializeSystemSpaceMap()

BOOLEAN NTAPI MiInitializeSystemSpaceMap ( IN PMMSESSION InputSession  OPTIONAL)

Definition at line 229 of file section.c.

230{
231 SIZE_T AllocSize, BitmapSize, Size;
232 PVOID ViewStart;
233 PMMSESSION Session;
234
235 /* Check if this a session or system space */
236 if (InputSession)
237 {
238 /* Use the input session */
239 Session = InputSession;
240 ViewStart = MiSessionViewStart;
242 }
243 else
244 {
245 /* Use the system space "session" */
246 Session = &MmSession;
247 ViewStart = MiSystemViewStart;
249 }
250
251 /* Initialize the system space lock */
254
255 /* Set the start address */
256 Session->SystemSpaceViewStart = ViewStart;
257
258 /* Create a bitmap to describe system space */
259 BitmapSize = sizeof(RTL_BITMAP) + ((((Size / MI_SYSTEM_VIEW_BUCKET_SIZE) + 31) / 32) * sizeof(ULONG));
261 BitmapSize,
262 TAG_MM);
263 ASSERT(Session->SystemSpaceBitMap);
265 (PULONG)(Session->SystemSpaceBitMap + 1),
267
268 /* Set system space fully empty to begin with */
270
271 /* Set default hash flags */
272 Session->SystemSpaceHashSize = 31;
273 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
274 Session->SystemSpaceHashEntries = 0;
275
276 /* Calculate how much space for the hash views we'll need */
277 AllocSize = sizeof(MMVIEW) * Session->SystemSpaceHashSize;
278 ASSERT(AllocSize < PAGE_SIZE);
279
280 /* Allocate and zero the view table */
283 PagedPool,
284 AllocSize,
285 TAG_MM);
286 ASSERT(Session->SystemSpaceViewTable != NULL);
287 RtlZeroMemory(Session->SystemSpaceViewTable, AllocSize);
288
289 /* Success */
290 return TRUE;
291}
MMSESSION MmSession
Definition: section.c:107
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlClearAllBits
Definition: dbgbitmap.h:329
#define RTL_BITMAP
Definition: dbgbitmap.h:323
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:265
struct _MMVIEW MMVIEW
PVOID MiSessionViewStart
Definition: init.c:30
ULONG MmSessionViewSize
Definition: init.c:35
ULONG MmSystemViewSize
Definition: init.c:39
PVOID MiSystemViewStart
Definition: init.c:38
ULONG SystemSpaceHashKey
Definition: miarm.h:460
ULONG SystemSpaceHashEntries
Definition: miarm.h:459
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:455
PRTL_BITMAP SystemSpaceBitMap
Definition: miarm.h:462
PCHAR SystemSpaceViewStart
Definition: miarm.h:456
ULONG SystemSpaceHashSize
Definition: miarm.h:458
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:457
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:454
#define TAG_MM
Definition: tag.h:113
uint32_t * PULONG
Definition: typedefs.h:59
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by MiBuildPagedPool(), and MiSessionCreateInternal().

◆ MiInsertInSystemSpace()

static PVOID MiInsertInSystemSpace ( IN PMMSESSION  Session,
IN ULONG  Buckets,
IN PCONTROL_AREA  ControlArea 
)
static

Definition at line 295 of file section.c.

298{
299 PVOID Base;
300 ULONG Hash, i, HashSize;
302 PMMVIEW OldTable;
303 PAGED_CODE();
304
305 /* Stay within 4GB */
307
308 /* Lock system space */
309 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
310
311 /* Check if we're going to exhaust hash entries */
312 if ((Session->SystemSpaceHashEntries + 8) > Session->SystemSpaceHashSize)
313 {
314 /* Double the hash size */
315 HashSize = Session->SystemSpaceHashSize * 2;
316
317 /* Save the old table and allocate a new one */
318 OldTable = Session->SystemSpaceViewTable;
319 Session->SystemSpaceViewTable = ExAllocatePoolWithTag(Session ==
320 &MmSession ?
322 PagedPool,
323 HashSize *
324 sizeof(MMVIEW),
325 TAG_MM);
326 if (!Session->SystemSpaceViewTable)
327 {
328 /* Failed to allocate a new table, keep the old one for now */
329 Session->SystemSpaceViewTable = OldTable;
330 }
331 else
332 {
333 /* Clear the new table and set the new ahsh and key */
334 RtlZeroMemory(Session->SystemSpaceViewTable, HashSize * sizeof(MMVIEW));
335 Session->SystemSpaceHashSize = HashSize;
336 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
337
338 /* Loop the old table */
339 for (i = 0; i < Session->SystemSpaceHashSize / 2; i++)
340 {
341 /* Check if the entry was valid */
342 if (OldTable[i].Entry)
343 {
344 /* Re-hash the old entry and search for space in the new table */
345 Hash = (OldTable[i].Entry >> 16) % Session->SystemSpaceHashKey;
346 while (Session->SystemSpaceViewTable[Hash].Entry)
347 {
348 /* Loop back at the beginning if we had an overflow */
349 if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
350 }
351
352 /* Write the old entry in the new table */
353 Session->SystemSpaceViewTable[Hash] = OldTable[i];
354 }
355 }
356
357 /* Free the old table */
358 ExFreePool(OldTable);
359 }
360 }
361
362 /* Check if we ran out */
363 if (Session->SystemSpaceHashEntries == Session->SystemSpaceHashSize)
364 {
365 DPRINT1("Ran out of system view hash entries\n");
366 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
367 return NULL;
368 }
369
370 /* Find space where to map this view */
371 i = RtlFindClearBitsAndSet(Session->SystemSpaceBitMap, Buckets, 0);
372 if (i == 0xFFFFFFFF)
373 {
374 /* Out of space, fail */
375 Session->BitmapFailures++;
376 DPRINT1("Out of system view space\n");
377 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
378 return NULL;
379 }
380
381 /* Compute the base address */
382 Base = (PVOID)((ULONG_PTR)Session->SystemSpaceViewStart + (i * MI_SYSTEM_VIEW_BUCKET_SIZE));
384
385 /* Get the hash entry for this allocation */
386 Entry = (ULONG_PTR)Base + Buckets;
387 Hash = (Entry >> 16) % Session->SystemSpaceHashKey;
388
389 /* Loop hash entries until a free one is found */
390 while (Session->SystemSpaceViewTable[Hash].Entry)
391 {
392 /* Unless we overflow, in which case loop back at hash o */
393 if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
394 }
395
396 /* Add this entry into the hash table */
397 Session->SystemSpaceViewTable[Hash].Entry = Entry;
398 Session->SystemSpaceViewTable[Hash].ControlArea = ControlArea;
399
400 /* Hash entry found, increment total and return the base address */
401 Session->SystemSpaceHashEntries++;
402 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
403 return Base;
404}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
static int Hash(const char *)
Definition: reader.c:2237
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
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
Entry
Definition: section.c:5216
Definition: miarm.h:447
ULONG_PTR Entry
Definition: miarm.h:448
void * PVOID
Definition: typedefs.h:50
#define NT_ASSERT
Definition: rtlfuncs.h:3334

Referenced by MiMapViewInSystemSpace().

◆ MiIsProtectionCompatible()

static BOOLEAN MiIsProtectionCompatible ( IN ULONG  SectionPageProtection,
IN ULONG  NewSectionPageProtection 
)
static

Definition at line 117 of file section.c.

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}
ULONG MmCompatibleProtectionMask[8]
Definition: section.c:84
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:140
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:367
#define PAGE_NOCACHE
Definition: nt_native.h:1314
#define PAGE_GUARD
Definition: nt_native.h:1313
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78

Referenced by MmMapViewOfArm3Section().

◆ MiLocateSubsection()

PSUBSECTION NTAPI MiLocateSubsection ( IN PMMVAD  Vad,
IN ULONG_PTR  Vpn 
)

Definition at line 565 of file section.c.

567{
568 PSUBSECTION Subsection;
569 PCONTROL_AREA ControlArea;
570 ULONG_PTR PteOffset;
571
572 /* Get the control area */
573 ControlArea = Vad->ControlArea;
574 ASSERT(ControlArea->u.Flags.Rom == 0);
575 ASSERT(ControlArea->u.Flags.Image == 0);
576 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
577
578 /* Get the subsection */
579 Subsection = (PSUBSECTION)(ControlArea + 1);
580
581 /* We only support single-subsection segments */
582 ASSERT(Subsection->SubsectionBase != NULL);
583 ASSERT(Vad->FirstPrototypePte >= Subsection->SubsectionBase);
584 ASSERT(Vad->FirstPrototypePte < &Subsection->SubsectionBase[Subsection->PtesInSubsection]);
585
586 /* Compute the PTE offset */
587 PteOffset = Vpn - Vad->StartingVpn;
588 PteOffset += Vad->FirstPrototypePte - Subsection->SubsectionBase;
589
590 /* Again, we only support single-subsection segments */
591 ASSERT(PteOffset < 0xF0000000);
592 ASSERT(PteOffset < Subsection->PtesInSubsection);
593
594 /* Return the subsection */
595 return Subsection;
596}
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:491

Referenced by MiDeleteVirtualAddresses().

◆ MiMakeProtectionMask()

ULONG NTAPI MiMakeProtectionMask ( IN ULONG  Protect)

Definition at line 140 of file section.c.

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 /* Select write-combining, or safely fall back if PAT is unavailable. */
213#if defined(_M_IX86)
214 if (KeFeatureBits & KF_PAT)
215 ProtectMask |= MM_WRITECOMBINE;
216 else
217 ProtectMask |= MM_NOCACHE;
218#else
219 ProtectMask |= MM_WRITECOMBINE;
220#endif
221 }
222
223 /* Return the final MM PTE protection mask */
224 return ProtectMask;
225}
CHAR MmUserProtectionToMask1[16]
Definition: section.c:44
CHAR MmUserProtectionToMask2[16]
Definition: section.c:64
ULONG64 KeFeatureBits
Definition: krnlinit.c:22
#define MM_GUARDPAGE
Definition: miarm.h:57
#define MM_WRITECOMBINE
Definition: miarm.h:58
#define KF_PAT
Definition: ketypes.h:41
#define PAGE_NOACCESS
Definition: nt_native.h:1305
static int Protect(const char **args)
Definition: vfdcmd.c:2132

Referenced by MiIsProtectionCompatible(), MiProtectVirtualMemory(), MmCreateArm3Section(), MmCreateSection(), MmCreateVirtualMappingUnsafeEx(), MmInsertMemoryArea(), MmMapViewOfArm3Section(), MmSetPageProtect(), NtAllocateVirtualMemory(), and NtMapViewOfSection().

◆ MiMapViewInSystemSpace()

NTSTATUS MiMapViewInSystemSpace ( _In_ PVOID  Section,
_In_ PMMSESSION  Session,
_Outptr_result_bytebuffer_ *ViewSize PVOID *  MappedBase,
_Inout_ PSIZE_T  ViewSize,
_Inout_ PLARGE_INTEGER  SectionOffset 
)

Definition at line 1048 of file section.c.

1054{
1055 PVOID Base;
1056 PCONTROL_AREA ControlArea;
1057 ULONG Buckets;
1058 LONGLONG SectionSize;
1060 PAGED_CODE();
1061
1062 /* Get the control area, check for any flags ARM3 doesn't yet support */
1063 ControlArea = ((PSECTION)Section)->Segment->ControlArea;
1064 ASSERT(ControlArea->u.Flags.Image == 0);
1065 ASSERT(ControlArea->FilePointer == NULL);
1066 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1067 ASSERT(ControlArea->u.Flags.Rom == 0);
1068 ASSERT(ControlArea->u.Flags.WasPurged == 0);
1069
1070 /* Increase the reference and map count on the control area, no purges yet */
1071 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1073
1074 /* Get the section size at creation time */
1075 SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart;
1076
1077 /* If the caller didn't specify a view size, assume until the end of the section */
1078 if (!(*ViewSize))
1079 {
1080 /* Check for overflow first */
1081 if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX)
1082 {
1083 DPRINT1("Section end is too far away from the specified offset.\n");
1084 MiDereferenceControlArea(ControlArea);
1086 }
1087 *ViewSize = SectionSize - SectionOffset->QuadPart;
1088 }
1089
1090 /* Check overflow */
1091 if ((SectionOffset->QuadPart + *ViewSize) < SectionOffset->QuadPart)
1092 {
1093 DPRINT1("Integer overflow between size & offset!\n");
1094 MiDereferenceControlArea(ControlArea);
1096 }
1097
1098 /* Check if the caller wanted a larger section than the view */
1099 if (SectionOffset->QuadPart + *ViewSize > SectionSize)
1100 {
1101 /* Fail */
1102 DPRINT1("View is too large\n");
1103 MiDereferenceControlArea(ControlArea);
1105 }
1106
1107 /* Get the number of 64K buckets required for this mapping */
1109 if (*ViewSize & (MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) Buckets++;
1110
1111 /* Check if the view is more than 4GB large */
1112 if (Buckets >= MI_SYSTEM_VIEW_BUCKET_SIZE)
1113 {
1114 /* Fail */
1115 DPRINT1("View is too large\n");
1116 MiDereferenceControlArea(ControlArea);
1118 }
1119
1120 /* Insert this view into system space and get a base address for it */
1121 Base = MiInsertInSystemSpace(Session, Buckets, ControlArea);
1122 if (!Base)
1123 {
1124 /* Fail */
1125 DPRINT1("Out of system space\n");
1126 MiDereferenceControlArea(ControlArea);
1127 return STATUS_NO_MEMORY;
1128 }
1129
1130 /* What's the underlying session? */
1131 if (Session == &MmSession)
1132 {
1133 /* Create the PDEs needed for this mapping, and double-map them if needed */
1136 }
1137 else
1138 {
1139 /* Create the PDEs needed for this mapping */
1141 (PVOID)((ULONG_PTR)Base +
1142 Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
1144 }
1145
1146 /* Create the actual prototype PTEs for this mapping */
1149 ControlArea,
1150 SectionOffset->QuadPart);
1152
1153 /* Return the base address of the mapping and success */
1154 *MappedBase = Base;
1155 return STATUS_SUCCESS;
1156}
static NTSTATUS MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:539
VOID NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:471
static NTSTATUS MiAddMappedPtes(IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea, IN LONGLONG SectionOffset)
Definition: section.c:408
static VOID MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:758
static PVOID MiInsertInSystemSpace(IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
Definition: section.c:295
static NTSTATUS MiSessionCommitPageTables(IN PVOID StartVa, IN PVOID EndVa)
Definition: section.c:932
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define SIZE_T_MAX
Definition: dhcpd.h:91
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:412
#define MiAddressToPte(x)
Definition: mm.h:144
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:361
ULONG WasPurged
Definition: mmtypes.h:478
int64_t LONGLONG
Definition: typedefs.h:68
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492
#define BYTES_TO_PAGES(Size)

Referenced by MmMapViewInSessionSpace(), and MmMapViewInSystemSpaceEx().

◆ MiMapViewOfDataSection()

static NTSTATUS MiMapViewOfDataSection ( _In_ PCONTROL_AREA  ControlArea,
_In_ PEPROCESS  Process,
_Outptr_result_bytebuffer_ *ViewSize _Pre_opt_valid_ PVOID *  BaseAddress,
_Inout_ PLARGE_INTEGER  SectionOffset,
_Inout_ PSIZE_T  ViewSize,
_In_ PSECTION  Section,
_In_range_(ViewShare, ViewUnmap) SECTION_INHERIT  InheritDisposition,
_In_ ULONG  ProtectionMask,
_In_ SIZE_T  CommitSize,
_In_ ULONG_PTR  ZeroBits,
_In_ ULONG  AllocationType 
)
static

Definition at line 1160 of file section.c.

1172{
1173 PMMVAD_LONG Vad;
1174 ULONG_PTR StartAddress;
1175 ULONG_PTR ViewSizeInPages;
1176 PSUBSECTION Subsection;
1178 PFN_NUMBER PteOffset;
1180 ULONG QuotaCharge = 0, QuotaExcess = 0;
1181 PMMPTE PointerPte, LastPte;
1182 MMPTE TempPte;
1183 ULONG Granularity = MM_VIRTMEM_GRANULARITY;
1184
1185 DPRINT("Mapping ARM3 data section\n");
1186
1187 /* Check for invalid inherit disposition */
1188 ASSERT((InheritDisposition >= ViewShare) && (InheritDisposition <= ViewUnmap));
1189
1190 /* Get the segment for this section */
1191 Segment = ControlArea->Segment;
1192
1193#ifdef _M_IX86
1194 /* ALlow being less restrictive on x86. */
1196 Granularity = PAGE_SIZE;
1197#endif
1198
1199 /* One can only reserve a file-based mapping, not shared memory! */
1200 if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1201 {
1203 }
1204
1205 /* First, increase the map count. No purging is supported yet */
1206 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1207 if (!NT_SUCCESS(Status)) return Status;
1208
1209 /* Check if the caller specified the view size */
1210 if (!(*ViewSize))
1211 {
1212 LONGLONG ViewSizeLL;
1213
1214 /* The caller did not, so pick a 64K aligned view size based on the offset */
1215 SectionOffset->LowPart &= ~(_64K - 1);
1216
1217 /* Calculate size and make sure this fits */
1218 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &ViewSizeLL))
1219 || !NT_SUCCESS(RtlLongLongToSIZET(ViewSizeLL, ViewSize))
1220 || (*ViewSize > MAXLONG_PTR))
1221 {
1222 MiDereferenceControlArea(ControlArea);
1224 }
1225 }
1226 else
1227 {
1228 /* A size was specified, align it to a 64K boundary
1229 * and check for overflow or huge value. */
1230 if (!NT_SUCCESS(RtlSIZETAdd(*ViewSize, SectionOffset->LowPart & (_64K - 1), ViewSize))
1231 || (*ViewSize > MAXLONG_PTR))
1232 {
1233 MiDereferenceControlArea(ControlArea);
1235 }
1236
1237 /* Align the offset as well to make this an aligned map */
1238 SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1239 }
1240
1241 /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1242 ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1243
1244 /* Windows ASSERTs for this flag */
1245 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1246
1247 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1248 ASSERT(ControlArea->u.Flags.Rom == 0);
1249 Subsection = (PSUBSECTION)(ControlArea + 1);
1250
1251 /* Sections with extended segments are not supported in ARM3 */
1252 ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1253
1254 /* Within this section, figure out which PTEs will describe the view */
1255 PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1256
1257 /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1258 ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1259 ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1260
1261 /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1262 ASSERT(PteOffset < Subsection->PtesInSubsection);
1263
1264 /* In ARM3, only page-file backed sections (shared memory) are supported now */
1265 ASSERT(ControlArea->FilePointer == NULL);
1266
1267 /* Windows ASSERTs for this too -- there must be a subsection base address */
1268 ASSERT(Subsection->SubsectionBase != NULL);
1269
1270 /* Compute how much commit space the segment will take */
1271 if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1272 {
1273 /* Charge for the maximum pages */
1274 QuotaCharge = BYTES_TO_PAGES(CommitSize);
1275 }
1276
1277 /* ARM3 does not currently support large pages */
1278 ASSERT(Segment->SegmentFlags.LargePages == 0);
1279
1280 /* Calculate how many pages the region spans */
1281 ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1282
1283 /* A VAD can now be allocated. Do so and zero it out */
1284 /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1285 ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1286 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1287 if (!Vad)
1288 {
1289 MiDereferenceControlArea(ControlArea);
1291 }
1292
1293 RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1294 Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1295
1296 /* Write all the data required in the VAD for handling a fault */
1297 Vad->ControlArea = ControlArea;
1298 Vad->u.VadFlags.CommitCharge = 0;
1299 Vad->u.VadFlags.Protection = ProtectionMask;
1300 Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1301 Vad->u2.VadFlags2.Inherit = (InheritDisposition == ViewShare);
1302 if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1303 {
1304 /* This isn't really implemented yet, but handle setting the flag */
1305 Vad->u.VadFlags.NoChange = 1;
1306 Vad->u2.VadFlags2.SecNoChange = 1;
1307 }
1308
1309 /* Finally, write down the first and last prototype PTE */
1310 Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1311 PteOffset += ViewSizeInPages - 1;
1312 ASSERT(PteOffset < Subsection->PtesInSubsection);
1313 Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1314
1315 /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1317
1318 /* FIXME: Should setup VAD bitmap */
1320
1321 /* Check if anything was committed */
1322 if (QuotaCharge)
1323 {
1324 /* Set the start and end PTE addresses, and pick the template PTE */
1325 PointerPte = Vad->FirstPrototypePte;
1326 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1327 TempPte = Segment->SegmentPteTemplate;
1328
1329 /* Acquire the commit lock and loop all prototype PTEs to be committed */
1331 while (PointerPte < LastPte)
1332 {
1333 /* Make sure the PTE is already invalid */
1334 if (PointerPte->u.Long == 0)
1335 {
1336 /* And write the invalid PTE */
1337 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1338 }
1339 else
1340 {
1341 /* The PTE is valid, so skip it */
1342 QuotaExcess++;
1343 }
1344
1345 /* Move to the next PTE */
1346 PointerPte++;
1347 }
1348
1349 /* Now check how many pages exactly we committed, and update accounting */
1350 ASSERT(QuotaCharge >= QuotaExcess);
1351 QuotaCharge -= QuotaExcess;
1352 Segment->NumberOfCommittedPages += QuotaCharge;
1353 ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1354
1355 /* Now that we're done, release the lock */
1357 }
1358
1359 /* Is it SEC_BASED, or did the caller manually specify an address? */
1360 if (*BaseAddress != NULL)
1361 {
1362 /* Just align what the caller gave us */
1363 StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1364 }
1365 else if (Section->Address.StartingVpn != 0)
1366 {
1367 /* It is a SEC_BASED mapping, use the address that was generated */
1368 StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1369 }
1370 else
1371 {
1372 StartAddress = 0;
1373 }
1374
1376 if (!NT_SUCCESS(Status))
1377 {
1378 ExFreePoolWithTag(Vad, 'ldaV');
1379 MiDereferenceControlArea(ControlArea);
1380
1382 Segment->NumberOfCommittedPages -= QuotaCharge;
1384 return Status;
1385 }
1386
1387 /* Insert the VAD */
1389 &StartAddress,
1390 ViewSizeInPages * PAGE_SIZE,
1392 Granularity,
1394 if (!NT_SUCCESS(Status))
1395 {
1396 ExFreePoolWithTag(Vad, 'ldaV');
1397 MiDereferenceControlArea(ControlArea);
1398
1400 Segment->NumberOfCommittedPages -= QuotaCharge;
1402
1404 return Status;
1405 }
1406
1407 /* Windows stores this for accounting purposes, do so as well */
1408 if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1409
1410 /* Finally, let the caller know where, and for what size, the view was mapped */
1411 *ViewSize = ViewSizeInPages * PAGE_SIZE;
1412 *BaseAddress = (PVOID)StartAddress;
1413 DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1414 return STATUS_SUCCESS;
1415}
KGUARDED_MUTEX MmSectionCommitMutex
Definition: section.c:108
#define ALIGN_DOWN_BY(size, align)
#define MAXULONG_PTR
Definition: basetsd.h:97
#define MAXLONG_PTR
Definition: basetsd.h:98
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define _64K
Definition: miarm.h:23
NTSTATUS NTAPI MiInsertVadEx(_Inout_ PMMVAD Vad, _In_ ULONG_PTR *BaseAddress, _In_ SIZE_T ViewSize, _In_ ULONG_PTR HighestAddress, _In_ ULONG_PTR Alignment, _In_ ULONG AllocationType)
Definition: vadnode.c:245
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:409
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ ULONG AllocationType
Definition: mmfuncs.h:414
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID * BaseAddress
Definition: mmfuncs.h:408
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:410
#define MEM_DOS_LIM
Definition: mmtypes.h:90
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
@ ViewUnmap
Definition: nt_native.h:1282
@ ViewShare
Definition: nt_native.h:1281
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:99
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:577
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
#define DPRINT
Definition: sndvol32.h:73
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
PMMPTE LastContiguousPte
Definition: mmtypes.h:767
PMMPTE FirstPrototypePte
Definition: mmtypes.h:766
PVOID Banked
Definition: mmtypes.h:780
union _MMVAD_LONG::@3117 u
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
union _MMVAD_LONG::@3118 u2
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
union _MMVAD_LONG::@3120 u4

Referenced by MmMapViewOfArm3Section().

◆ MiQueryMemorySectionName()

NTSTATUS NTAPI MiQueryMemorySectionName ( IN HANDLE  ProcessHandle,
IN PVOID  BaseAddress,
OUT PVOID  MemoryInformation,
IN SIZE_T  MemoryInformationLength,
OUT PSIZE_T  ReturnLength 
)

Definition at line 1767 of file section.c.

1772{
1776 PMEMORY_SECTION_NAME SectionName = NULL;
1778
1781 NULL,
1783 (PVOID*)(&Process),
1784 NULL);
1785
1786 if (!NT_SUCCESS(Status))
1787 {
1788 DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1789 return Status;
1790 }
1791
1793
1794 if (NT_SUCCESS(Status))
1795 {
1796 SectionName = MemoryInformation;
1797 if (PreviousMode != KernelMode)
1798 {
1799 _SEH2_TRY
1800 {
1801 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1802 (PWSTR)(SectionName + 1),
1803 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1805
1807
1808 }
1810 {
1812 }
1813 _SEH2_END;
1814 }
1815 else
1816 {
1817 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1818 (PWSTR)(SectionName + 1),
1819 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1821
1823
1824 }
1825
1827 }
1829 return Status;
1830}
NTSTATUS NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName)
Definition: section.c:1704
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
#define ExGetPreviousMode
Definition: ex.h:143
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:162
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define KernelMode
Definition: asm.h:38
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:407
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
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:493
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
TCHAR ModuleFileName[MAX_PATH+1]
Definition: rundll32.c:56
UNICODE_STRING SectionFileName
Definition: mmtypes.h:326
uint16_t * PWSTR
Definition: typedefs.h:56
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by NtQueryVirtualMemory().

◆ MiRemoveFromSystemSpace()

static ULONG MiRemoveFromSystemSpace ( IN PMMSESSION  Session,
IN PVOID  Base,
OUT PCONTROL_AREA *  ControlArea 
)
static

Definition at line 2037 of file section.c.

2040{
2041 ULONG Hash, Size, Count = 0;
2043 PAGED_CODE();
2044
2045 /* Compute the hash for this entry and loop trying to find it */
2046 Entry = (ULONG_PTR)Base >> 16;
2047 Hash = Entry % Session->SystemSpaceHashKey;
2048 while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2049 {
2050 /* Check if we overflew past the end of the hash table */
2051 if (++Hash >= Session->SystemSpaceHashSize)
2052 {
2053 /* Reset the hash to zero and keep searching from the bottom */
2054 Hash = 0;
2055 if (++Count == 2)
2056 {
2057 /* But if we overflew twice, then this is not a real mapping */
2058 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2059 (ULONG_PTR)Base,
2060 1,
2061 0,
2062 0);
2063 }
2064 }
2065 }
2066
2067 /* One less entry */
2068 Session->SystemSpaceHashEntries--;
2069
2070 /* Extract the size and clear the entry */
2071 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2072 Session->SystemSpaceViewTable[Hash].Entry = 0;
2073
2074 /* Return the control area and the size */
2075 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2076 return Size;
2077}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
int Count
Definition: noreturn.cpp:7

Referenced by MiUnmapViewInSystemSpace().

◆ MiRemoveMappedPtes()

static VOID MiRemoveMappedPtes ( IN PVOID  BaseAddress,
IN ULONG  NumberOfPtes,
IN PCONTROL_AREA  ControlArea,
IN PMMSUPPORT  Ws 
)
static

Definition at line 1935 of file section.c.

1939{
1940 PMMPTE PointerPte, ProtoPte;//, FirstPte;
1941 PMMPDE PointerPde, SystemMapPde;
1942 PMMPFN Pfn1, Pfn2;
1943 MMPTE PteContents;
1944 KIRQL OldIrql;
1945 DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
1946
1947 ASSERT(Ws == NULL);
1948
1949 /* Get the PTE and loop each one */
1950 PointerPte = MiAddressToPte(BaseAddress);
1951 //FirstPte = PointerPte;
1952 while (NumberOfPtes)
1953 {
1954 /* Check if the PTE is already valid */
1955 PteContents = *PointerPte;
1956 if (PteContents.u.Hard.Valid == 1)
1957 {
1958 /* Get the PFN entry */
1959 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
1960
1961 /* Get the PTE */
1962 PointerPde = MiPteToPde(PointerPte);
1963
1964 /* Lock the PFN database and make sure this isn't a mapped file */
1965 OldIrql = MiAcquirePfnLock();
1966 ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
1967
1968 /* Mark the page as modified accordingly */
1969 if (MI_IS_PAGE_DIRTY(&PteContents))
1970 Pfn1->u3.e1.Modified = 1;
1971
1972 /* Was the PDE invalid */
1973 if (PointerPde->u.Long == 0)
1974 {
1975#if (_MI_PAGING_LEVELS == 2)
1976 /* Find the system double-mapped PDE that describes this mapping */
1977 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
1978
1979 /* Make it valid */
1980 ASSERT(SystemMapPde->u.Hard.Valid == 1);
1981 MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
1982#else
1983 DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
1984 ASSERT(FALSE);
1985#endif
1986 }
1987
1988 /* Dereference the PDE and the PTE */
1989 Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
1990 MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
1992 MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
1993
1994 /* Release the PFN lock */
1995 MiReleasePfnLock(OldIrql);
1996 }
1997 else
1998 {
1999 /* Windows ASSERT */
2000 ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
2001
2002 /* Check if this is a prototype pointer PTE */
2003 if (PteContents.u.Soft.Prototype == 1)
2004 {
2005 /* Get the prototype PTE */
2006 ProtoPte = MiProtoPteToPte(&PteContents);
2007
2008 /* We don't support anything else atm */
2009 ASSERT(ProtoPte->u.Long == 0);
2010 }
2011 }
2012
2013 /* Make the PTE into a zero PTE */
2014 PointerPte->u.Long = 0;
2015
2016 /* Move to the next PTE */
2017 PointerPte++;
2018 NumberOfPtes--;
2019 }
2020
2021 /* Flush the TLB */
2023
2024 /* Acquire the PFN lock */
2025 OldIrql = MiAcquirePfnLock();
2026
2027 /* Decrement the accounting counters */
2028 ControlArea->NumberOfUserReferences--;
2029 ControlArea->NumberOfMappedViews--;
2030
2031 /* Check if we should destroy the CA and release the lock */
2032 MiCheckControlArea(ControlArea, OldIrql);
2033}
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:331
#define MI_IS_PAGE_DIRTY(x)
Definition: mm.h:111
#define MiProtoPteToPte(x)
Definition: mm.h:315
#define PFN_FROM_PTE(v)
Definition: mm.h:94
#define MiPteToPde(_Pte)
Definition: mm.h:136
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1042
USHORT PrototypePte
Definition: mm.h:369
USHORT Modified
Definition: mm.h:366
Definition: mm.h:386
MMPTE OriginalPte
Definition: mm.h:422
MMPFNENTRY e1
Definition: mm.h:409
union _MMPFN::@2101 u3
ULONG64 Prototype
Definition: mmtypes.h:89

Referenced by MiUnmapViewInSystemSpace().

◆ MiRemoveMappedView()

VOID NTAPI MiRemoveMappedView ( IN PEPROCESS  CurrentProcess,
IN PMMVAD  Vad 
)

Definition at line 775 of file section.c.

777{
779 PCONTROL_AREA ControlArea;
780 PETHREAD CurrentThread = PsGetCurrentThread();
781
782 /* Get the control area */
783 ControlArea = Vad->ControlArea;
784
785 /* We only support non-extendable, non-image, pagefile-backed regular sections */
786 ASSERT(Vad->u.VadFlags.VadType == VadNone);
787 ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
788 ASSERT(ControlArea);
789 ASSERT(ControlArea->FilePointer == NULL);
791
792 /* Delete the actual virtual memory pages */
793 MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
794 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
795 Vad);
796
797 /* Release the working set */
798 MiUnlockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
799
800 /* Lock the PFN database */
801 OldIrql = MiAcquirePfnLock();
802
803 /* Remove references */
804 ControlArea->NumberOfMappedViews--;
805 ControlArea->NumberOfUserReferences--;
806
807 /* Check if it should be destroyed */
808 MiCheckControlArea(ControlArea, OldIrql);
809}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1246
VOID NTAPI MiDeleteVirtualAddresses(_In_ ULONG_PTR Va, _In_ ULONG_PTR EndingAddress, _In_opt_ PMMVAD Vad)
Definition: virtual.c:530
@ VadNone
Definition: mmtypes.h:204
ULONG NumberOfMappedViews
Definition: mmtypes.h:525

Referenced by MiUnmapViewOfSection(), and MmCleanProcessAddressSpace().

◆ MiSegmentDelete()

static VOID MiSegmentDelete ( IN PSEGMENT  Segment)
static

Definition at line 600 of file section.c.

601{
602 PCONTROL_AREA ControlArea;
603 SEGMENT_FLAGS SegmentFlags;
604 PSUBSECTION Subsection;
605 PMMPTE PointerPte, LastPte, PteForProto;
606 PMMPFN Pfn1;
607 PFN_NUMBER PageFrameIndex;
610
611 /* Capture data */
612 SegmentFlags = Segment->SegmentFlags;
613 ControlArea = Segment->ControlArea;
614
615 /* Make sure control area is on the right delete path */
616 ASSERT(ControlArea->u.Flags.BeingDeleted == 1);
617 ASSERT(ControlArea->WritableUserReferences == 0);
618
619 /* These things are not supported yet */
620 ASSERT(ControlArea->DereferenceList.Flink == NULL);
621 ASSERT(!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File));
622 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
623 ASSERT(ControlArea->u.Flags.Rom == 0);
624
625 /* Get the subsection and PTEs for this segment */
626 Subsection = (PSUBSECTION)(ControlArea + 1);
627 PointerPte = Subsection->SubsectionBase;
628 LastPte = PointerPte + Segment->NonExtendedPtes;
629
630 /* Lock the PFN database */
631 OldIrql = MiAcquirePfnLock();
632
633 /* Check if the master PTE is invalid */
634 PteForProto = MiAddressToPte(PointerPte);
635 if (!PteForProto->u.Hard.Valid)
636 {
637 /* Fault it in */
639 }
640
641 /* Loop all the segment PTEs */
642 while (PointerPte < LastPte)
643 {
644 /* Check if it's time to switch master PTEs if we passed a PDE boundary */
645 if (MiIsPteOnPdeBoundary(PointerPte) &&
646 (PointerPte != Subsection->SubsectionBase))
647 {
648 /* Check if the master PTE is invalid */
649 PteForProto = MiAddressToPte(PointerPte);
650 if (!PteForProto->u.Hard.Valid)
651 {
652 /* Fault it in */
654 }
655 }
656
657 /* This should be a prototype PTE */
658 TempPte = *PointerPte;
659 ASSERT(SegmentFlags.LargePages == 0);
660 ASSERT(TempPte.u.Hard.Valid == 0);
661
662 /* See if we should clean things up */
663 if (!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File))
664 {
665 /*
666 * This is a section backed by the pagefile. Now that it doesn't exist anymore,
667 * we can give everything back to the system.
668 */
669 ASSERT(TempPte.u.Soft.Prototype == 0);
670
671 if (TempPte.u.Soft.Transition == 1)
672 {
673 /* We can give the page back for other use */
674 DPRINT("Releasing page for transition PTE %p\n", PointerPte);
675 PageFrameIndex = PFN_FROM_PTE(&TempPte);
676 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
677
678 /* As this is a paged-backed section, nobody should reference it anymore (no cache or whatever) */
679 ASSERT(Pfn1->u3.ReferenceCount == 0);
680
681 /* And it should be in standby or modified list */
683
684 /* Unlink it and put it back in free list */
686
687 /* Temporarily mark this as active and make it free again */
689 MI_SET_PFN_DELETED(Pfn1);
690
691 MiInsertPageInFreeList(PageFrameIndex);
692 }
693 else if (TempPte.u.Soft.PageFileHigh != 0)
694 {
695 /* Should not happen for now */
696 ASSERT(FALSE);
697 }
698 }
699 else
700 {
701 /* unsupported for now */
702 ASSERT(FALSE);
703
704 /* File-backed section must have prototype PTEs */
705 ASSERT(TempPte.u.Soft.Prototype == 1);
706 }
707
708 /* Zero the PTE and keep going */
709 PointerPte->u.Long = 0;
710 PointerPte++;
711 }
712
713 /* Release the PFN lock */
714 MiReleasePfnLock(OldIrql);
715
716 /* Free the structures */
717 ExFreePool(ControlArea);
719}
ULONG NTAPI MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress, IN KIRQL OldIrql)
Definition: virtual.c:235
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:208
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:611
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:265
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1581
@ ActiveAndValid
Definition: mmtypes.h:159
@ ModifiedPageList
Definition: mmtypes.h:156
@ StandbyPageList
Definition: mmtypes.h:155
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:305
ULONG WritableUserReferences
Definition: mmtypes.h:537
LIST_ENTRY DereferenceList
Definition: mmtypes.h:522
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT PageLocation
Definition: mm.h:371
USHORT ReferenceCount
Definition: mm.h:408
ULONG LargePages
Definition: mmtypes.h:403

Referenced by MiCheckControlArea().

◆ MiSessionCommitPageTables()

static NTSTATUS MiSessionCommitPageTables ( IN PVOID  StartVa,
IN PVOID  EndVa 
)
static

Definition at line 932 of file section.c.

934{
937 PMMPDE StartPde, EndPde;
939 PMMPFN Pfn1;
940 PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
941
942 /* Windows sanity checks */
943 ASSERT(StartVa >= (PVOID)MmSessionBase);
945 ASSERT(PAGE_ALIGN(EndVa) == EndVa);
946
947 /* Get the start and end PDE, then loop each one */
948 StartPde = MiAddressToPde(StartVa);
949 EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
950 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
951 while (StartPde <= EndPde)
952 {
953#ifndef _M_AMD64
954 /* If we don't already have a page table for it, increment count */
955 if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
956#endif
957 /* Move to the next one */
958 StartPde++;
959 Index++;
960 }
961
962 /* If there's no page tables to create, bail out */
963 if (PageCount == 0) return STATUS_SUCCESS;
964
965 /* Reset the start PDE and index */
966 StartPde = MiAddressToPde(StartVa);
967 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
968
969 /* Loop each PDE while holding the working set lock */
970// MiLockWorkingSet(PsGetCurrentThread(),
971// &MmSessionSpace->GlobalVirtualAddress->Vm);
972#ifdef _M_AMD64
973_WARN("MiSessionCommitPageTables halfplemented for amd64")
978 DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
979 ASSERT(FALSE);
980#else
981 while (StartPde <= EndPde)
982 {
983 /* Check if we already have a page table */
985 {
986 /* We don't, so the PDE shouldn't be ready yet */
987 ASSERT(StartPde->u.Hard.Valid == 0);
988
989 /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
991
992 /* Acquire the PFN lock and grab a zero page */
993 OldIrql = MiAcquirePfnLock();
995 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
997 PageFrameNumber = MiRemoveZeroPage(Color);
998 TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
999 MI_WRITE_VALID_PDE(StartPde, TempPde);
1000
1001 /* Write the page table in session space structure */
1004
1005 /* Initialize the PFN */
1006 MiInitializePfnForOtherProcess(PageFrameNumber,
1007 StartPde,
1009
1010 /* And now release the lock */
1011 MiReleasePfnLock(OldIrql);
1012
1013 /* Get the PFN entry and make sure there's no event for it */
1014 Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1015 ASSERT(Pfn1->u1.Event == NULL);
1016
1017 /* Increment the number of pages */
1018 ActualPages++;
1019 }
1020
1021 /* Move to the next PDE */
1022 StartPde++;
1023 Index++;
1024 }
1025#endif
1026
1027 /* Make sure we didn't do more pages than expected */
1028 ASSERT(ActualPages <= PageCount);
1029
1030 /* Release the working set lock */
1031// MiUnlockWorkingSet(PsGetCurrentThread(),
1032// &MmSessionSpace->GlobalVirtualAddress->Vm);
1033
1034
1035 /* If we did at least one page... */
1036 if (ActualPages)
1037 {
1038 /* Update the performance counters! */
1041 }
1042
1043 /* Return status */
1044 return STATUS_SUCCESS;
1045}
#define _WARN(msg)
Definition: debug.h:135
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:211
ULONG MmSecondaryColorMask
Definition: mminit.c:258
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
PVOID MmSessionBase
Definition: init.c:33
PVOID MiSessionSpaceEnd
Definition: init.c:27
MMPTE ValidKernelPdeLocal
Definition: init.c:32
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:484
PMMPDE PageTables
Definition: miarm.h:511
SIZE_T CommittedPages
Definition: miarm.h:486
SIZE_T NonPageablePages
Definition: miarm.h:485
_In_ WDFCOLLECTION _In_ ULONG Index
#define PAGE_ALIGN(Va)

Referenced by MiMapViewInSystemSpace().

◆ MiUnmapViewInSystemSpace()

static NTSTATUS MiUnmapViewInSystemSpace ( IN PMMSESSION  Session,
IN PVOID  MappedBase 
)
static

Definition at line 2081 of file section.c.

2083{
2084 ULONG Size;
2085 PCONTROL_AREA ControlArea;
2086 PAGED_CODE();
2087
2088 /* Remove this mapping */
2089 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2090 Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2091
2092 /* Clear the bits for this mapping */
2093 RtlClearBits(Session->SystemSpaceBitMap,
2094 (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2095 Size);
2096
2097 /* Convert the size from a bit size into the actual size */
2098 Size = Size * (_64K >> PAGE_SHIFT);
2099
2100 /* Remove the PTEs now */
2101 MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2102 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2103
2104 /* Return success */
2105 return STATUS_SUCCESS;
2106}
static ULONG MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2037
static VOID MiRemoveMappedPtes(IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
Definition: section.c:1935
#define RtlClearBits
Definition: dbgbitmap.h:331

Referenced by MmUnmapViewInSessionSpace(), and MmUnmapViewInSystemSpace().

◆ MiUnmapViewOfSection()

static NTSTATUS MiUnmapViewOfSection ( IN PEPROCESS  Process,
IN PVOID  BaseAddress,
IN ULONG  Flags 
)
static

Definition at line 813 of file section.c.

816{
819 PMMVAD Vad;
820 PVOID DbgBase = NULL;
823 PETHREAD CurrentThread = PsGetCurrentThread();
824 PEPROCESS CurrentProcess = PsGetCurrentProcess();
825 PAGED_CODE();
826
827 /* Check if we need to lock the address space */
828 if (!Flags) MmLockAddressSpace(&Process->Vm);
829
830 /* Find the VAD for the address and make sure it's a section VAD */
831 Vad = MiLocateVad(&Process->VadRoot, BaseAddress);
832 if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
833 {
834 /* Couldn't find it, or invalid VAD, fail */
835 DPRINT1("No VAD or invalid VAD\n");
838 }
839
840 /* Check for RosMm memory area */
841 if (MI_IS_MEMORY_AREA_VAD(Vad))
842 {
843 /* Call Mm API */
847 return Status;
848 }
849
850 /* Check if we should attach to the process */
851 if (CurrentProcess != Process)
852 {
853 /* The process is different, do an attach */
855 Attached = TRUE;
856 }
857
858 /* Check if the process is already dead */
859 if (Process->VmDeleted)
860 {
861 /* Fail the call */
862 DPRINT1("Process died!\n");
865 goto Quickie;
866 }
867
868 /* We should be attached */
870
871 /* We need the base address for the debugger message on image-backed VADs */
872 if (Vad->u.VadFlags.VadType == VadImageMap)
873 {
874 DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
875 }
876
877 /* Compute the size of the VAD region */
878 RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
879
880 /* For SEC_NO_CHANGE sections, we need some extra checks */
881 if (Vad->u.VadFlags.NoChange == 1)
882 {
883 /* Are we allowed to mess with this VAD? */
885 (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
888 if (!NT_SUCCESS(Status))
889 {
890 /* We failed */
891 DPRINT1("Trying to unmap protected VAD!\n");
893 goto Quickie;
894 }
895 }
896
897 /* Not currently supported */
899
900 /* FIXME: Remove VAD charges */
901
902 /* Lock the working set */
904
905 /* Remove the VAD */
906 ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
907 MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
909
910 /* Remove the PTEs for this view, which also releases the working set lock */
912
913 /* FIXME: Remove commitment */
914
915 /* Update performance counter and release the lock */
916 Process->VirtualSize -= RegionSize;
918
919 /* Destroy the VAD and return success */
920 ExFreePool(Vad);
922
923 /* Failure and success case -- send debugger message, detach, and return */
924Quickie:
925 if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
927 return Status;
928}
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:775
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
PMMVAD NTAPI MiLocateVad(_In_ PMM_AVL_TABLE Table, _In_ PVOID VirtualAddress)
Definition: vadnode.c:116
#define MM_DELETE_CHECK
Definition: miarm.h:260
NTSTATUS NTAPI MiCheckSecuredVad(IN PMMVAD Vad, IN PVOID Base, IN SIZE_T Size, IN ULONG ProtectionMask)
Definition: vadnode.c:815
NTSTATUS NTAPI MiRosUnmapViewOfSection(_In_ PEPROCESS Process, _In_ PMEMORY_AREA MemoryArea, _In_ PVOID BaseAddress, _In_ BOOLEAN SkipDebuggerNotify)
Definition: section.c:3630
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1176
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:176
@ VadRotatePhysical
Definition: mmtypes.h:210
@ VadImageMap
Definition: mmtypes.h:206
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1677
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1690
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1751
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:355
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
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
ULONG_PTR VadType
Definition: mmtypes.h:694
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
union _MMVAD::@3114 u
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
static BOOL Attached
Definition: vidbios.c:3905
KAPC_STATE
Definition: ketypes.h:1727

Referenced by MmUnmapViewOfSection(), and NtUnmapViewOfSection().

◆ MmCommitSessionMappedView()

NTSTATUS NTAPI MmCommitSessionMappedView ( IN PVOID  MappedBase,
IN SIZE_T  ViewSize 
)

Definition at line 2809 of file section.c.

2811{
2812 ULONG_PTR StartAddress, EndingAddress, Base;
2813 ULONG Hash, Count = 0, Size, QuotaCharge;
2814 PMMSESSION Session;
2815 PMMPTE LastProtoPte, PointerPte, ProtoPte;
2816 PCONTROL_AREA ControlArea;
2818 PSUBSECTION Subsection;
2819 MMPTE TempPte;
2820 PAGED_CODE();
2821
2822 /* Make sure the base isn't past the session view range */
2825 {
2826 DPRINT1("Base outside of valid range\n");
2828 }
2829
2830 /* Make sure the size isn't past the session view range */
2833 {
2834 DPRINT1("Size outside of valid range\n");
2836 }
2837
2838 /* Sanity check */
2839 ASSERT(ViewSize != 0);
2840
2841 /* Process must be in a session */
2842 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2843 {
2844 DPRINT1("Process is not in session\n");
2846 }
2847
2848 /* Compute the correctly aligned base and end addresses */
2849 StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
2850 EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
2851
2852 /* Sanity check and grab the session */
2854 Session = &MmSessionSpace->Session;
2855
2856 /* Get the hash entry for this allocation */
2857 Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
2858
2859 /* Lock system space */
2861
2862 /* Loop twice so we can try rolling over if needed */
2863 while (TRUE)
2864 {
2865 /* Extract the size and base addresses from the entry */
2866 Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
2867 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2868
2869 /* Convert the size to bucket chunks */
2871
2872 /* Bail out if this entry fits in here */
2873 if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
2874
2875 /* Check if we overflew past the end of the hash table */
2876 if (++Hash >= Session->SystemSpaceHashSize)
2877 {
2878 /* Reset the hash to zero and keep searching from the bottom */
2879 Hash = 0;
2880 if (++Count == 2)
2881 {
2882 /* But if we overflew twice, then this is not a real mapping */
2883 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2884 Base,
2885 2,
2886 0,
2887 0);
2888 }
2889 }
2890 }
2891
2892 /* Make sure the view being mapped is not file-based */
2893 ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2894 if (ControlArea->FilePointer != NULL)
2895 {
2896 /* It is, so we have to bail out */
2897 DPRINT1("Only page-filed backed sections can be commited\n");
2900 }
2901
2902 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
2903 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2904 ASSERT(ControlArea->u.Flags.Rom == 0);
2905 Subsection = (PSUBSECTION)(ControlArea + 1);
2906
2907 /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
2908 ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
2909 QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
2910 LastProtoPte = ProtoPte + QuotaCharge;
2911 if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
2912 {
2913 DPRINT1("PTE is out of bounds\n");
2916 }
2917
2918 /* Acquire the commit lock and count all the non-committed PTEs */
2920 PointerPte = ProtoPte;
2921 while (PointerPte < LastProtoPte)
2922 {
2923 if (PointerPte->u.Long) QuotaCharge--;
2924 PointerPte++;
2925 }
2926
2927 /* Was everything committed already? */
2928 if (!QuotaCharge)
2929 {
2930 /* Nothing to do! */
2933 return STATUS_SUCCESS;
2934 }
2935
2936 /* Pick the segment and template PTE */
2937 Segment = ControlArea->Segment;
2938 TempPte = Segment->SegmentPteTemplate;
2939 ASSERT(TempPte.u.Long != 0);
2940
2941 /* Loop all prototype PTEs to be committed */
2942 PointerPte = ProtoPte;
2943 while (PointerPte < LastProtoPte)
2944 {
2945 /* Make sure the PTE is already invalid */
2946 if (PointerPte->u.Long == 0)
2947 {
2948 /* And write the invalid PTE */
2949 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2950 }
2951
2952 /* Move to the next PTE */
2953 PointerPte++;
2954 }
2955
2956 /* Check if we had at least one page charged */
2957 if (QuotaCharge)
2958 {
2959 /* Update the accounting data */
2960 Segment->NumberOfCommittedPages += QuotaCharge;
2962 }
2963
2964 /* Release all */
2967 return STATUS_SUCCESS;
2968}
VOID FASTCALL KeReleaseGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:75
VOID FASTCALL KeAcquireGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:64
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
SIZE_T MmSharedCommit
Definition: freelist.c:31
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:363
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:570
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:569
PCONTROL_AREA ControlArea
Definition: miarm.h:449
MMSESSION Session
Definition: miarm.h:501

◆ MmCreateArm3Section()

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 at line 2115 of file section.c.

2123{
2124 SECTION Section;
2125 PSECTION NewSection;
2126 PSUBSECTION Subsection;
2127 PSEGMENT NewSegment, Segment;
2129 PCONTROL_AREA ControlArea;
2130 ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2132 BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2133 KIRQL OldIrql;
2135 BOOLEAN UserRefIncremented = FALSE;
2136 PVOID PreviousSectionPointer;
2137
2138 /* Make the same sanity checks that the Nt interface should've validated */
2141 SEC_NO_CHANGE)) == 0);
2151
2152 /* Convert section flag to page flag */
2155
2156 /* Check to make sure the protection is correct. Nt* does this already */
2158 if (ProtectionMask == MM_INVALID_PROTECTION)
2159 {
2160 DPRINT1("Invalid protection mask\n");
2162 }
2163
2164 /* Check if this is going to be a data or image backed file section */
2165 if ((FileHandle) || (FileObject))
2166 {
2167 /* These cannot be mapped with large pages */
2169
2170 /* For now, only support the mechanism through a file handle */
2172
2173 /* Reference the file handle to get the object */
2175 MmMakeFileAccess[ProtectionMask],
2178 (PVOID*)&File,
2179 NULL);
2180 if (!NT_SUCCESS(Status)) return Status;
2181
2182 /* Make sure Cc has been doing its job */
2183 if (!File->SectionObjectPointer)
2184 {
2185 /* This is not a valid file system-based file, fail */
2188 }
2189
2190 /* Image-file backed sections are not yet supported */
2192
2193 /* Compute the size of the control area, and allocate it */
2194 ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2195 ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2196 if (!ControlArea)
2197 {
2200 }
2201
2202 /* Zero it out */
2203 RtlZeroMemory(ControlArea, ControlAreaSize);
2204
2205 /* Did we get a handle, or an object? */
2206 if (FileHandle)
2207 {
2208 /* We got a file handle so we have to lock down the file */
2209#if 0
2211 if (!NT_SUCCESS(Status))
2212 {
2213 ExFreePool(ControlArea);
2215 return Status;
2216 }
2217#else
2218 /* ReactOS doesn't support this API yet, so do nothing */
2221#endif
2222 /* Update the top-level IRP so that drivers know what's happening */
2224 FileLock = TRUE;
2225 }
2226
2227 /* Lock the PFN database while we play with the section pointers */
2228 OldIrql = MiAcquirePfnLock();
2229
2230 /* Image-file backed sections are not yet supported */
2232
2233 /* There should not already be a control area for this file */
2234 ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2235 NewSegment = NULL;
2236
2237 /* Write down that this CA is being created, and set it */
2238 ControlArea->u.Flags.BeingCreated = TRUE;
2240 PreviousSectionPointer = File->SectionObjectPointer;
2241 File->SectionObjectPointer->DataSectionObject = ControlArea;
2242
2243 /* We can release the PFN lock now */
2244 MiReleasePfnLock(OldIrql);
2245
2246 /* We don't support previously-mapped file */
2247 ASSERT(NewSegment == NULL);
2248
2249 /* Image-file backed sections are not yet supported */
2251
2252 /* So we always create a data file map */
2254 &Segment,
2255 InputMaximumSize,
2258 KernelCall);
2259 if (!NT_SUCCESS(Status))
2260 {
2261 /* Lock the PFN database while we play with the section pointers */
2262 OldIrql = MiAcquirePfnLock();
2263
2264 /* Reset the waiting-for-deletion event */
2265 ASSERT(ControlArea->WaitingForDeletion == NULL);
2266 ControlArea->WaitingForDeletion = NULL;
2267
2268 /* Set the file pointer NULL flag */
2269 ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2270 ControlArea->u.Flags.FilePointerNull = TRUE;
2271
2272 /* Delete the data section object */
2274 File->SectionObjectPointer->DataSectionObject = NULL;
2275
2276 /* No longer being created */
2277 ControlArea->u.Flags.BeingCreated = FALSE;
2278
2279 /* We can release the PFN lock now */
2280 MiReleasePfnLock(OldIrql);
2281
2282 /* Check if we locked and set the IRP */
2283 if (FileLock)
2284 {
2285 /* Undo */
2287 //FsRtlReleaseFile(File);
2288 }
2289
2290 /* Free the control area and de-ref the file object */
2291 ExFreePool(ControlArea);
2293
2294 /* All done */
2295 return Status;
2296 }
2297
2298 /* On success, we expect this */
2299 ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2300
2301 /* Check if a maximum size was specified */
2302 if (!InputMaximumSize->QuadPart)
2303 {
2304 /* Nope, use the segment size */
2305 Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2306 }
2307 else
2308 {
2309 /* Yep, use the entered size */
2310 Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2311 }
2312 }
2313 else
2314 {
2315 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2317
2318 /* Not yet supported */
2320
2321 /* So this must be a pagefile-backed section, create the mappings needed */
2322 Status = MiCreatePagingFileMap(&NewSegment,
2323 InputMaximumSize->QuadPart,
2324 ProtectionMask,
2326 if (!NT_SUCCESS(Status)) return Status;
2327
2328 /* Set the size here, and read the control area */
2329 Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2330 ControlArea = NewSegment->ControlArea;
2331
2332 /* MiCreatePagingFileMap increments user references */
2333 UserRefIncremented = TRUE;
2334 }
2335
2336 /* Did we already have a segment? */
2337 if (!NewSegment)
2338 {
2339 /* This must be the file path and we created a segment */
2340 NewSegment = Segment;
2341 ASSERT(File != NULL);
2342
2343 /* Acquire the PFN lock while we set control area flags */
2344 OldIrql = MiAcquirePfnLock();
2345
2346 /* We don't support this race condition yet, so assume no waiters */
2347 ASSERT(ControlArea->WaitingForDeletion == NULL);
2348 ControlArea->WaitingForDeletion = NULL;
2349
2350 /* Image-file backed sections are not yet supported, nor ROM images */
2352 ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2353
2354 /* Take off the being created flag, and then release the lock */
2355 ControlArea->u.Flags.BeingCreated = FALSE;
2356 MiReleasePfnLock(OldIrql);
2357 }
2358
2359 /* Check if we locked the file earlier */
2360 if (FileLock)
2361 {
2362 /* Reset the top-level IRP and release the lock */
2364 //FsRtlReleaseFile(File);
2365 FileLock = FALSE;
2366 }
2367
2368 /* Set the initial section object data */
2370
2371 /* The mapping created a control area and segment, save the flags */
2372 Section.Segment = NewSegment;
2373 Section.u.LongFlags = ControlArea->u.LongFlags;
2374
2375 /* Check if this is a user-mode read-write non-image file mapping */
2376 if (!(FileObject) &&
2378 !(ControlArea->u.Flags.Image) &&
2379 (ControlArea->FilePointer))
2380 {
2381 /* Add a reference and set the flag */
2382 Section.u.Flags.UserWritable = TRUE;
2383 InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2384 }
2385
2386 /* Check for image mappings or page file mappings */
2387 if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2388 {
2389 /* Charge the segment size, and allocate a subsection */
2390 PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2391 Size = sizeof(SUBSECTION);
2392 }
2393 else
2394 {
2395 /* Charge nothing, and allocate a mapped subsection */
2396 PagedCharge = 0;
2397 Size = sizeof(MSUBSECTION);
2398 }
2399
2400 /* Check if this is a normal CA */
2401 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2402 ASSERT(ControlArea->u.Flags.Rom == 0);
2403
2404 /* Charge only a CA, and the subsection is right after */
2405 NonPagedCharge = sizeof(CONTROL_AREA);
2406 Subsection = (PSUBSECTION)(ControlArea + 1);
2407
2408 /* We only support single-subsection mappings */
2409 NonPagedCharge += Size;
2410 ASSERT(Subsection->NextSubsection == NULL);
2411
2412 /* Create the actual section object, with enough space for the prototype PTEs */
2417 NULL,
2418 sizeof(SECTION),
2419 PagedCharge,
2420 NonPagedCharge,
2421 (PVOID*)&NewSection);
2422 if (!NT_SUCCESS(Status))
2423 {
2424 /* Check if this is a user-mode read-write non-image file mapping */
2425 if (!(FileObject) &&
2427 !(ControlArea->u.Flags.Image) &&
2428 (ControlArea->FilePointer))
2429 {
2430 /* Remove a reference and check the flag */
2431 ASSERT(Section.u.Flags.UserWritable == 1);
2432 InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2433 }
2434
2435 /* Check if a user reference was added */
2436 if (UserRefIncremented)
2437 {
2438 /* Acquire the PFN lock while we change counters */
2439 OldIrql = MiAcquirePfnLock();
2440
2441 /* Decrement the accounting counters */
2442 ControlArea->NumberOfSectionReferences--;
2443 ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2444 ControlArea->NumberOfUserReferences--;
2445
2446 /* Check if we should destroy the CA and release the lock */
2447 MiCheckControlArea(ControlArea, OldIrql);
2448 }
2449
2450 /* Return the failure code */
2451 return Status;
2452 }
2453
2454 /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2455
2456 /* Now copy the local section object from the stack into this new object */
2457 RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2458 NewSection->Address.StartingVpn = 0;
2459
2460 /* For now, only user calls are supported */
2461 ASSERT(KernelCall == FALSE);
2462 NewSection->u.Flags.UserReference = TRUE;
2463
2464 /* Is this a "based" allocation, in which all mappings are identical? */
2466 {
2467 /* Lock the VAD tree during the search */
2469
2470 /* Is it a brand new ControArea ? */
2471 if (ControlArea->u.Flags.BeingCreated == 1)
2472 {
2473 ASSERT(ControlArea->u.Flags.Based == 1);
2474 /* Then we must find a global address, top-down */
2477 _64K,
2479 (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2480
2481 if (!NT_SUCCESS(Status))
2482 {
2483 /* No way to find a valid range. */
2485 ControlArea->u.Flags.Based = 0;
2486 NewSection->u.Flags.Based = 0;
2487 ObDereferenceObject(NewSection);
2488 return Status;
2489 }
2490
2491 /* Compute the ending address and insert it into the VAD tree */
2492 NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2493 NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2494 MiInsertBasedSection(NewSection);
2495 }
2496 else
2497 {
2498 /* 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 !*/
2499 ASSERT(FALSE);
2500 }
2501
2503 }
2504
2505 /* The control area is not being created anymore */
2506 if (ControlArea->u.Flags.BeingCreated == 1)
2507 {
2508 /* Acquire the PFN lock while we set control area flags */
2509 OldIrql = MiAcquirePfnLock();
2510
2511 /* Take off the being created flag, and then release the lock */
2512 ControlArea->u.Flags.BeingCreated = 0;
2513 NewSection->u.Flags.BeingCreated = 0;
2514
2515 MiReleasePfnLock(OldIrql);
2516 }
2517
2518 /* Migrate the attribute into a flag */
2520
2521 /* If R/W access is not requested, this might eventually become a CoW mapping */
2523 {
2524 NewSection->u.Flags.CopyOnWrite = TRUE;
2525 }
2526
2527 /* Write down if this was a kernel call */
2528 ControlArea->u.Flags.WasPurged |= KernelCall;
2529 ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2530
2531 /* Make sure the segment and the section are the same size, or the section is smaller */
2532 ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2533
2534 /* Return the object and the creation status */
2535 *SectionObject = (PVOID)NewSection;
2536 return Status;
2537}
static NTSTATUS MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1419
static NTSTATUS MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN ULONG64 MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1434
PVOID MmHighSectionBase
Definition: section.c:111
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
Definition: File.h:16
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:386
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree(IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base)
Definition: vadnode.c:711
unsigned __int64 ULONG64
Definition: imports.h:198
#define SECTION
Definition: profile.c:31
struct _SUBSECTION SUBSECTION
#define SEC_NOCACHE
Definition: mmtypes.h:101
#define SEC_IMAGE
Definition: mmtypes.h:97
struct _MSUBSECTION MSUBSECTION
struct _CONTROL_AREA CONTROL_AREA
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1653
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2032
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:362
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:574
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:399
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:1049
long LONG
Definition: pedump.c:60
POBJECT_TYPE MmSectionObjectType
Definition: section.c:196
PEVENT_COUNTER WaitingForDeletion
Definition: mmtypes.h:534
ULONG LongFlags
Definition: mmtypes.h:530
ULONG_PTR StartingVpn
Definition: mmtypes.h:653
ULONG_PTR EndingVpn
Definition: mmtypes.h:654
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 UserWritable
Definition: mmtypes.h:489
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
ULONG LongFlags
Definition: mmtypes.h:816
union _SECTION::@3123 u
PSEGMENT Segment
Definition: mmtypes.h:812
ULONG InitialPageProtection
Definition: mmtypes.h:819
MMADDRESS_NODE Address
Definition: mmtypes.h:811
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:813
PVOID BasedAddress
Definition: mmtypes.h:418
struct _SUBSECTION * NextSubsection
Definition: mmtypes.h:584
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106

Referenced by MmCreateSection().

◆ MmDisableModifiedWriteOfSection()

BOOLEAN NTAPI MmDisableModifiedWriteOfSection ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointer)

Definition at line 2687 of file section.c.

2688{
2690 return FALSE;
2691}

◆ MmDoesFileHaveUserWritableReferences()

ULONG NTAPI MmDoesFileHaveUserWritableReferences ( IN PSECTION_OBJECT_POINTERS  SectionPointer)

Definition at line 3008 of file section.c.

3009{
3011 return 0;
3012}
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30

Referenced by FatCheckShareAccess().

◆ MmForceSectionClosed()

BOOLEAN NTAPI MmForceSectionClosed ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointer,
IN BOOLEAN  DelayClose 
)

Definition at line 2698 of file section.c.

2700{
2702 return FALSE;
2703}

Referenced by RxPurgeFcbInSystemCache(), and RxPurgeNetFcb().

◆ MmGetFileNameForAddress()

NTSTATUS NTAPI MmGetFileNameForAddress ( IN PVOID  Address,
OUT PUNICODE_STRING  ModuleName 
)

Definition at line 1704 of file section.c.

1706{
1707 POBJECT_NAME_INFORMATION ModuleNameInformation;
1710 PMMVAD Vad;
1712
1713 /* Lock address space */
1716
1717 /* Get the VAD */
1718 Vad = MiLocateAddress(Address);
1719 if (Vad == NULL)
1720 {
1721 /* Fail, the address does not exist */
1722 DPRINT1("No VAD at address %p\n", Address);
1725 }
1726
1727 /* Get the file object pointer for the VAD */
1729 if (FileObject == NULL)
1730 {
1731 DPRINT1("Failed to get file object for Address %p\n", Address);
1734 }
1735
1736 /* Reference the file object */
1738
1739 /* Unlock address space */
1741
1742 /* Get the filename of the file object */
1743 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1744
1745 /* Dereference the file object */
1747
1748 /* Check if we were able to get the file object name */
1749 if (NT_SUCCESS(Status))
1750 {
1751 /* Init modulename */
1752 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1754
1755 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1756 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1757
1758 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1759 }
1760
1761 /* Return status */
1762 return Status;
1763}
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1572
static NTSTATUS MmGetFileNameForFileObject(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1651
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
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace(VOID)
Definition: mm.h:1705
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:651
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:403
static WCHAR Address[46]
Definition: ping.c:68
UNICODE_STRING Name
Definition: nt_native.h:1273
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by DbgkpPostFakeModuleMessages(), and MiQueryMemorySectionName().

◆ MmGetFileNameForFileObject()

static NTSTATUS MmGetFileNameForFileObject ( IN PFILE_OBJECT  FileObject,
OUT POBJECT_NAME_INFORMATION *  ModuleName 
)
static

Definition at line 1651 of file section.c.

1653{
1654 POBJECT_NAME_INFORMATION ObjectNameInfo;
1657
1658 /* Allocate memory for our structure */
1659 ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, 1024, TAG_MM);
1660 if (!ObjectNameInfo) return STATUS_NO_MEMORY;
1661
1662 /* Query the name */
1664 ObjectNameInfo,
1665 1024,
1666 &ReturnLength);
1667 if (!NT_SUCCESS(Status))
1668 {
1669 /* Failed, free memory */
1670 DPRINT1("Name query failed\n");
1671 ExFreePoolWithTag(ObjectNameInfo, TAG_MM);
1672 *ModuleName = NULL;
1673 return Status;
1674 }
1675
1676 /* Success */
1677 *ModuleName = ObjectNameInfo;
1678 return STATUS_SUCCESS;
1679}
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207

Referenced by MmGetFileNameForAddress(), and MmGetFileNameForSection().

◆ MmGetFileNameForSection()

NTSTATUS NTAPI MmGetFileNameForSection ( IN PVOID  Section,
OUT POBJECT_NAME_INFORMATION *  ModuleName 
)

Definition at line 1683 of file section.c.

1685{
1687 PSECTION SectionObject = Section;
1688
1689 /* Make sure it's an image section */
1690 if (SectionObject->u.Flags.Image == 0)
1691 {
1692 /* It's not, fail */
1693 DPRINT1("Not an image section\n");
1695 }
1696
1697 /* Get the file object */
1700}
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID SectionObject)
Definition: section.c:1553

Referenced by DbgkCreateThread(), and DbgkpSectionToFileHandle().

◆ MmGetFileObjectForSection()

PFILE_OBJECT NTAPI MmGetFileObjectForSection ( IN PVOID  SectionObject)

Definition at line 1553 of file section.c.

1554{
1555 PSECTION Section = SectionObject;
1558
1559 /* Check if it's an ARM3, or ReactOS section */
1561 {
1562 /* Return the file pointer stored in the control area */
1563 return Section->Segment->ControlArea->FilePointer;
1564 }
1565
1566 /* Return the file object */
1567 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1568}
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1105

Referenced by CcGetFileObjectFromBcb(), CcGetFileObjectFromSectionPtrs(), CcShutdownSystem(), MmGetFileNameForSection(), MmInitializeProcessAddressSpace(), and PsReferenceProcessFilePointer().

◆ MmGetImageInformation()

VOID NTAPI MmGetImageInformation ( OUT PSECTION_IMAGE_INFORMATION  ImageInformation)

Definition at line 1630 of file section.c.

1631{
1633
1634 /* Get the section object of this process*/
1635 SectionObject = PsGetCurrentProcess()->SectionObject;
1638
1639 if (SectionObject->u.Flags.Image == 0)
1640 {
1641 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1642 return;
1643 }
1644
1645 /* Return the image information */
1646 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1647}
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT

Referenced by NtQueryInformationProcess().

◆ MmMapViewInSessionSpace()

NTSTATUS NTAPI MmMapViewInSessionSpace ( IN PVOID  Section,
OUT PVOID *  MappedBase,
IN OUT PSIZE_T  ViewSize 
)

Definition at line 2710 of file section.c.

2713{
2714 PAGED_CODE();
2716
2717 // HACK
2718 if (MiIsRosSectionObject(Section))
2719 {
2720 return MmMapViewInSystemSpace(Section, MappedBase, ViewSize);
2721 }
2722
2723 /* Process must be in a session */
2724 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2725 {
2726 DPRINT1("Process is not in session\n");
2728 }
2729
2730 /* Use the system space API, but with the session view instead */
2732 SectionOffset.QuadPart = 0;
2733 return MiMapViewInSystemSpace(Section,
2735 MappedBase,
2736 ViewSize,
2737 &SectionOffset);
2738}
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:1048
NTSTATUS NTAPI MmMapViewInSystemSpace(IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:4504

Referenced by _Success_(), InitGdiHandleTable(), and UserCreateHeap().

◆ MmMapViewOfArm3Section()

NTSTATUS NTAPI MmMapViewOfArm3Section ( _In_ PVOID  SectionObject,
_In_ PEPROCESS  Process,
_Outptr_result_bytebuffer_ *ViewSize _When_ *!=0, _Pre_opt_valid_ _When_ *==0, _Pre_valid_ PVOID *  BaseAddress,
_In_ ULONG_PTR  ZeroBits,
_In_ SIZE_T  CommitSize,
_Inout_ PLARGE_INTEGER  SectionOffset,
_Inout_ PSIZE_T  ViewSize,
_In_range_(ViewShare, ViewUnmap) SECTION_INHERIT  InheritDisposition,
_In_ ULONG  AllocationType,
_In_ ULONG  Protect 
)

Definition at line 2544 of file section.c.

2558{
2561 PSECTION Section;
2562 PCONTROL_AREA ControlArea;
2563 ULONG ProtectionMask;
2565 ULONG64 CalculatedViewSize;
2566
2567 PAGED_CODE();
2568
2569 /* Check for invalid inherit disposition */
2570 // Let MiMapViewOfDataSection() check InheritDisposition value.
2571
2572 /* Get the segment and control area */
2573 Section = (PSECTION)SectionObject;
2574 ControlArea = Section->Segment->ControlArea;
2575
2576 /* These flags/states are not yet supported by ARM3 */
2577 ASSERT(Section->u.Flags.Image == 0);
2578 ASSERT(Section->u.Flags.NoCache == 0);
2579 ASSERT(Section->u.Flags.WriteCombined == 0);
2580 ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
2581
2582 /* FIXME */
2583 if ((AllocationType & MEM_RESERVE) != 0)
2584 {
2585 DPRINT1("MmMapViewOfArm3Section called with MEM_RESERVE, this is not implemented yet!!!\n");
2587 }
2588
2589 /* Check if the mapping protection is compatible with the create */
2591 {
2592 DPRINT1("Mapping protection is incompatible\n");
2594 }
2595
2596 /* Check if the offset and size would cause an overflow */
2597 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) <
2598 (ULONG64)SectionOffset->QuadPart)
2599 {
2600 DPRINT1("Section offset overflows\n");
2602 }
2603
2604 /* Check if the offset and size are bigger than the section itself */
2605 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) >
2606 (ULONG64)Section->SizeOfSection.QuadPart)
2607 {
2608 DPRINT1("Section offset is larger than section\n");
2610 }
2611
2612 /* Check if the caller did not specify a view size */
2613 if (!(*ViewSize))
2614 {
2615 /* Compute it for the caller */
2616 CalculatedViewSize = Section->SizeOfSection.QuadPart -
2617 SectionOffset->QuadPart;
2618
2619 /* Check if it's larger than 4GB or overflows into kernel-mode */
2620 if (!NT_SUCCESS(RtlULongLongToSIZET(CalculatedViewSize, ViewSize)) ||
2621 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < CalculatedViewSize))
2622 {
2623 DPRINT1("Section view won't fit\n");
2625 }
2626 }
2627
2628 /* Check if the commit size is larger than the view size */
2629 if (CommitSize > *ViewSize)
2630 {
2631 DPRINT1("Attempting to commit more than the view itself\n");
2633 }
2634
2635 /* Check if the view size is larger than the section */
2636 if (*ViewSize > (ULONG64)Section->SizeOfSection.QuadPart)
2637 {
2638 DPRINT1("The view is larger than the section\n");
2640 }
2641
2642 /* Compute and validate the protection mask */
2643 ProtectionMask = MiMakeProtectionMask(Protect);
2644 if (ProtectionMask == MM_INVALID_PROTECTION)
2645 {
2646 DPRINT1("The protection is invalid\n");
2648 }
2649
2650 /* We only handle pagefile-backed sections, which cannot be writecombined */
2652 {
2653 DPRINT1("Cannot write combine a pagefile-backed section\n");
2655 }
2656
2657 /* Start by attaching to the current process if needed */
2659 {
2661 Attached = TRUE;
2662 }
2663
2664 /* Do the actual mapping */
2665 Status = MiMapViewOfDataSection(ControlArea,
2666 Process,
2669 ViewSize,
2670 Section,
2671 InheritDisposition,
2672 ProtectionMask,
2673 CommitSize,
2674 ZeroBits,
2676
2677 /* Detach if needed, then return status */
2679 return Status;
2680}
static NTSTATUS MiMapViewOfDataSection(_In_ PCONTROL_AREA ControlArea, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _Inout_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_ PSECTION Section, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG ProtectionMask, _In_ SIZE_T CommitSize, _In_ ULONG_PTR ZeroBits, _In_ ULONG AllocationType)
Definition: section.c:1160
static BOOLEAN MiIsProtectionCompatible(IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
Definition: section.c:117
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:48
#define STATUS_SECTION_PROTECTION
Definition: ntstatus.h:408
#define STATUS_INVALID_PARAMETER_10
Definition: ntstatus.h:578
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:573
ULONG PhysicalMemory
Definition: mmtypes.h:473
ULONG WriteCombined
Definition: mmtypes.h:493

Referenced by MmMapViewOfSection().

◆ MmUnmapViewInSessionSpace()

NTSTATUS NTAPI MmUnmapViewInSessionSpace ( IN PVOID  MappedBase)

Definition at line 2745 of file section.c.

2746{
2747 PAGED_CODE();
2748
2749 // HACK
2751 {
2753 }
2754
2755 /* Process must be in a session */
2756 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2757 {
2758 DPRINT1("Proess is not in session\n");
2760 }
2761
2762 /* Use the system space API, but with the session view instead */
2765 MappedBase);
2766}
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:2784
static NTSTATUS MiUnmapViewInSystemSpace(IN PMMSESSION Session, IN PVOID MappedBase)
Definition: section.c:2081
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:185

Referenced by EngFreeSectionMem(), and IntFreeDesktopHeap().

◆ MmUnmapViewInSystemSpace()

NTSTATUS NTAPI MmUnmapViewInSystemSpace ( IN PVOID  MappedBase)

Definition at line 2784 of file section.c.

2785{
2787 PAGED_CODE();
2788
2789 /* Was this mapped by RosMm? */
2793 {
2796 return Status;
2797 }
2799
2800 /* It was not, call the ARM3 routine */
2802}
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:4614
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:61
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:94
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1712

Referenced by CcRosInternalFreeVacb(), EngFreeModule(), MmUnmapViewInSessionSpace(), and SharedMem_Release().

◆ MmUnmapViewOfSection()

NTSTATUS NTAPI MmUnmapViewOfSection ( IN PEPROCESS  Process,
IN PVOID  BaseAddress 
)

Definition at line 2773 of file section.c.

2775{
2777}
static NTSTATUS MiUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
Definition: section.c:813

Referenced by _Function_class_(), _Success_(), EngUnmapSectionView(), IntMapDesktopView(), IntUnmapDesktopView(), IntUserHeapCreate(), LpcpDeletePort(), MiLoadImageSection(), and UnmapGlobalUserHeap().

◆ NtAreMappedFilesTheSame()

NTSTATUS NTAPI NtAreMappedFilesTheSame ( IN PVOID  File1MappedAsAnImage,
IN PVOID  File2MappedAsFile 
)

Definition at line 3018 of file section.c.

3020{
3022 PMMVAD Vad1, Vad2;
3023 PFILE_OBJECT FileObject1, FileObject2;
3025
3026 /* Lock address space */
3029
3030 /* Get the VAD for Address 1 */
3031 Vad1 = MiLocateAddress(File1MappedAsAnImage);
3032 if (Vad1 == NULL)
3033 {
3034 /* Fail, the address does not exist */
3035 DPRINT1("No VAD at address 1 %p\n", File1MappedAsAnImage);
3037 goto Exit;
3038 }
3039
3040 /* Get the VAD for Address 2 */
3041 Vad2 = MiLocateAddress(File2MappedAsFile);
3042 if (Vad2 == NULL)
3043 {
3044 /* Fail, the address does not exist */
3045 DPRINT1("No VAD at address 2 %p\n", File2MappedAsFile);
3047 goto Exit;
3048 }
3049
3050 /* Get the file object pointer for VAD 1 */
3051 FileObject1 = MiGetFileObjectForVad(Vad1);
3052 if (FileObject1 == NULL)
3053 {
3054 DPRINT1("Failed to get file object for Address 1 %p\n", File1MappedAsAnImage);
3056 goto Exit;
3057 }
3058
3059 /* Get the file object pointer for VAD 2 */
3060 FileObject2 = MiGetFileObjectForVad(Vad2);
3061 if (FileObject2 == NULL)
3062 {
3063 DPRINT1("Failed to get file object for Address 2 %p\n", File2MappedAsFile);
3065 goto Exit;
3066 }
3067
3068 /* Make sure Vad1 is an image mapping */
3069 if (Vad1->u.VadFlags.VadType != VadImageMap)
3070 {
3071 DPRINT1("Address 1 (%p) is not an image mapping\n", File1MappedAsAnImage);
3073 goto Exit;
3074 }
3075
3076 /* SectionObjectPointer is equal if the files are equal */
3077 if (FileObject1->SectionObjectPointer == FileObject2->SectionObjectPointer)
3078 {
3080 }
3081 else
3082 {
3084 }
3085
3086Exit:
3087 /* Unlock address space */
3089 return Status;
3090}
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:354
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:542
static void Exit(void)
Definition: sock.c:1330

◆ NtCreateSection()

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 at line 3097 of file section.c.

3104{
3105 LARGE_INTEGER SafeMaximumSize;
3107 HANDLE Handle;
3110 PAGED_CODE();
3111
3112 /* Check for non-existing flags */
3115 SEC_NO_CHANGE)))
3116 {
3117 if (!(AllocationAttributes & 1))
3118 {
3119 DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
3121 }
3122 }
3123
3124 /* Check for no allocation type */
3126 {
3127 DPRINT1("Missing allocation type in allocation attributes\n");
3129 }
3130
3131 /* Check for image allocation with invalid attributes */
3135 {
3136 DPRINT1("Image allocation with invalid attributes\n");
3138 }
3139
3140 /* Check for allocation type is both commit and reserve */
3142 {
3143 DPRINT1("Commit and reserve in the same time\n");
3145 }
3146
3147 /* Now check for valid protection */
3152 {
3153 DPRINT1("Sections don't support these protections\n");
3155 }
3156
3157 /* Use a maximum size of zero, if none was specified */
3158 SafeMaximumSize.QuadPart = 0;
3159
3160 /* Check for user-mode caller */
3161 if (PreviousMode != KernelMode)
3162 {
3163 /* Enter SEH */
3164 _SEH2_TRY
3165 {
3166 /* Safely check user-mode parameters */
3167 if (MaximumSize) SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
3168 MaximumSize = &SafeMaximumSize;
3169 ProbeForWriteHandle(SectionHandle);
3170 }
3172 {
3173 /* Return the exception code */
3175 }
3176 _SEH2_END;
3177 }
3178 else if (!MaximumSize) MaximumSize = &SafeMaximumSize;
3179
3180 /* Check that MaximumSize is valid if backed by paging file */
3181 if ((!FileHandle) && (!MaximumSize->QuadPart))
3183
3184 /* Create the section */
3191 FileHandle,
3192 NULL);
3193 if (!NT_SUCCESS(Status)) return Status;
3194
3195 /* FIXME: Should zero last page for a file mapping */
3196
3197 /* Now insert the object */
3199 NULL,
3201 0,
3202 NULL,
3203 &Handle);
3204 if (NT_SUCCESS(Status))
3205 {
3206 /* Enter SEH */
3207 _SEH2_TRY
3208 {
3209 /* Return the handle safely */
3210 *SectionHandle = Handle;
3211 }
3213 {
3214 /* Nothing here */
3215 }
3216 _SEH2_END;
3217 }
3218
3219 /* Return the status */
3220 return Status;
3221}
ULONG Handle
Definition: gdb_input.c:15
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:2962
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
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:4677
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664

Referenced by BasepMapFile(), CabinetExtractFile(), CabinetOpen(), CON_API(), CreateFileMappingW(), CreateProcessInternalW(), CreateSection(), CSR_API(), CsrpConnectToServer(), CsrSrvCreateSharedSection(), get_binary_type(), get_manifest_in_manifest_file(), get_manifest_in_pe_file(), GRAPHICS_BUFFER_Initialize(), GuiConsoleShowConsoleProperties(), InitFunctionPtrs(), IntGetCodePageEntry(), LdrpCheckForLoadedDll(), LdrpCreateDllSection(), LdrVerifyImageMatchesChecksum(), MapFile(), SdbpOpenMemMappedFile(), SetupCopyFile(), SmpInitializeKnownDllsInternal(), START_TEST(), Test_BasedSection(), Test_EmptyFile(), Test_ImageSection(), Test_ImageSection2(), Test_PageFileSection(), Test_RawSize(), Test_SectionContents(), Test_Truncate(), and TH32CreateSnapshotSectionInitialize().

◆ NtExtendSection()

NTSTATUS NTAPI NtExtendSection ( IN HANDLE  SectionHandle,
IN OUT PLARGE_INTEGER  NewMaximumSize 
)

Definition at line 3538 of file section.c.

3540{
3541 LARGE_INTEGER SafeNewMaximumSize;
3542 PSECTION Section;
3545
3546 /* Check for user-mode parameters */
3547 if (PreviousMode != KernelMode)
3548 {
3549 /* Enter SEH */
3550 _SEH2_TRY
3551 {
3552 /* Probe and capture the maximum size, it's both read and write */
3553 ProbeForWriteLargeInteger(NewMaximumSize);
3554 SafeNewMaximumSize = *NewMaximumSize;
3555 }
3557 {
3558 /* Return the exception code */
3560 }
3561 _SEH2_END;
3562 }
3563 else
3564 {
3565 /* Just read the size directly */
3566 SafeNewMaximumSize = *NewMaximumSize;
3567 }
3568
3569 /* Reference the section */
3570 Status = ObReferenceObjectByHandle(SectionHandle,
3574 (PVOID*)&Section,
3575 NULL);
3576 if (!NT_SUCCESS(Status)) return Status;
3577
3578 Status = MmExtendSection(Section, &SafeNewMaximumSize);
3579
3580 /* Dereference the section */
3581 ObDereferenceObject(Section);
3582
3583 if (NT_SUCCESS(Status))
3584 {
3585 _SEH2_TRY
3586 {
3587 /* Write back the new size */
3588 *NewMaximumSize = SafeNewMaximumSize;
3589 }
3591 {
3593 }
3594 _SEH2_END;
3595 }
3596
3597 /* Return the status */
3599}
#define SECTION_EXTEND_SIZE
Definition: nt_native.h:1294
NTSTATUS NTAPI MmExtendSection(_In_ PVOID Section, _Inout_ PLARGE_INTEGER NewSize)
Definition: section.c:5451
#define ProbeForWriteLargeInteger(Ptr)
Definition: probe.h:46

◆ NtMapViewOfSection()

NTSTATUS NTAPI NtMapViewOfSection ( _In_ HANDLE  SectionHandle,
_In_ HANDLE  ProcessHandle,
_Outptr_result_bytebuffer_ *ViewSize _Pre_valid_ PVOID *  BaseAddress,
_In_ ULONG_PTR  ZeroBits,
_In_ SIZE_T  CommitSize,
_Inout_opt_ PLARGE_INTEGER  SectionOffset,
_Inout_ PSIZE_T  ViewSize,
_In_range_(ViewShare, ViewUnmap) SECTION_INHERIT  InheritDisposition,
_In_ ULONG  AllocationType,
_In_ ULONG  Win32Protect 
)

Definition at line 3278 of file section.c.

3289{
3290 PVOID SafeBaseAddress;
3291 LARGE_INTEGER SafeSectionOffset;
3292 SIZE_T SafeViewSize;
3293 PSECTION Section;
3297 ULONG ProtectionMask;
3299#if defined(_M_IX86) || defined(_M_AMD64)
3300 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3302#else
3303 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3305#endif
3306
3307 /* Check for invalid inherit disposition */
3308 if ((InheritDisposition < ViewShare) || (InheritDisposition > ViewUnmap))
3309 {
3310 DPRINT1("Invalid inherit disposition: %d\n", InheritDisposition);
3312 }
3313
3314 /* Allow only valid allocation types */
3315 if (AllocationType & ~ValidAllocationType)
3316 {
3317 DPRINT1("Invalid allocation type\n");
3319 }
3320
3321 /* Convert the protection mask, and validate it */
3322 ProtectionMask = MiMakeProtectionMask(Win32Protect);
3323 if (ProtectionMask == MM_INVALID_PROTECTION)
3324 {
3325 DPRINT1("Invalid page protection\n");
3327 }
3328
3329 /* Now convert the protection mask into desired section access mask */
3330 DesiredAccess = MmMakeSectionAccess[ProtectionMask & 0x7];
3331
3332 /* Assume no section offset */
3333 SafeSectionOffset.QuadPart = 0;
3334
3335 /* Enter SEH */
3336 _SEH2_TRY
3337 {
3338 /* Check for unsafe parameters */
3339 if (PreviousMode != KernelMode)
3340 {
3341 /* Probe the parameters */
3344 }
3345
3346 /* Check if a section offset was given */
3347 if (SectionOffset)
3348 {
3349 /* Check for unsafe parameters and capture section offset */
3351 SafeSectionOffset = *SectionOffset;
3352 }
3353
3354 /* Capture the other parameters */
3355 SafeBaseAddress = *BaseAddress;
3356 SafeViewSize = *ViewSize;
3357 }
3359 {
3360 /* Return the exception code */
3362 }
3363 _SEH2_END;
3364
3365 /* Check for kernel-mode address */
3366 if (SafeBaseAddress > MM_HIGHEST_VAD_ADDRESS)
3367 {
3368 DPRINT1("Kernel base not allowed\n");
3370 }
3371
3372 /* Check for range entering kernel-mode */
3373 if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)SafeBaseAddress) < SafeViewSize)
3374 {
3375 DPRINT1("Overflowing into kernel base not allowed\n");
3377 }
3378
3379 /* Check for invalid zero bits */
3380 if (ZeroBits)
3381 {
3383 {
3384 DPRINT1("Invalid zero bits\n");
3386 }
3387
3388 if ((((ULONG_PTR)SafeBaseAddress << ZeroBits) >> ZeroBits) != (ULONG_PTR)SafeBaseAddress)
3389 {
3390 DPRINT1("Invalid zero bits\n");
3392 }
3393
3394 if (((((ULONG_PTR)SafeBaseAddress + SafeViewSize) << ZeroBits) >> ZeroBits) != ((ULONG_PTR)SafeBaseAddress + SafeViewSize))
3395 {
3396 DPRINT1("Invalid zero bits\n");
3398 }
3399 }
3400
3401 /* Reference the process */
3406 (PVOID*)&Process,
3407 NULL);
3408 if (!NT_SUCCESS(Status)) return Status;
3409
3410 /* Reference the section */
3411 Status = ObReferenceObjectByHandle(SectionHandle,
3415 (PVOID*)&Section,
3416 NULL);
3417 if (!NT_SUCCESS(Status))
3418 {
3420 return Status;
3421 }
3422
3423 if (Section->u.Flags.PhysicalMemory)
3424 {
3425 if (PreviousMode == UserMode &&
3426 SafeSectionOffset.QuadPart + SafeViewSize > MmHighestPhysicalPage << PAGE_SHIFT)
3427 {
3428 DPRINT1("Denying map past highest physical page.\n");
3429 ObDereferenceObject(Section);
3432 }
3433 }
3434 else if (!(AllocationType & MEM_DOS_LIM))
3435 {
3436 /* Check for non-allocation-granularity-aligned BaseAddress */
3437 if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
3438 {
3439 DPRINT("BaseAddress is not at 64-kilobyte address boundary.\n");
3440 ObDereferenceObject(Section);
3443 }
3444
3445 /* Do the same for the section offset */
3446 if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
3447 {
3448 DPRINT("SectionOffset is not at 64-kilobyte address boundary.\n");
3449 ObDereferenceObject(Section);
3452 }
3453 }
3454
3455 /* Now do the actual mapping */
3456 Status = MmMapViewOfSection(Section,
3457 Process,
3458 &SafeBaseAddress,
3459 ZeroBits,
3460 CommitSize,
3461 &SafeSectionOffset,
3462 &SafeViewSize,
3463 InheritDisposition,
3465 Win32Protect);
3466
3467 /* Return data only on success */
3468 if (NT_SUCCESS(Status))
3469 {
3470 /* Check if this is an image for the current process */
3471 if ((Section->u.Flags.Image) &&
3474 {
3475 /* Notify the debugger */
3476 DbgkMapViewOfSection(Section,
3477 SafeBaseAddress,
3478 SafeSectionOffset.LowPart,
3479 SafeViewSize);
3480 }
3481
3482 /* Enter SEH */
3483 _SEH2_TRY
3484 {
3485 /* Return parameters to user */
3486 *BaseAddress = SafeBaseAddress;
3487 *ViewSize = SafeViewSize;
3488 if (SectionOffset) *SectionOffset = SafeSectionOffset;
3489 }
3491 {
3492 /* Nothing to do */
3493 }
3494 _SEH2_END;
3495 }
3496
3497 /* Dereference all objects and return status */
3498 ObDereferenceObject(Section);
3500 return Status;
3501}
ACCESS_MASK MmMakeSectionAccess[8]
Definition: section.c:20
VOID NTAPI DbgkMapViewOfSection(IN PVOID Section, IN PVOID BaseAddress, IN ULONG SectionOffset, IN ULONG_PTR ViewSize)
Definition: dbgkutil.c:380
#define PROCESS_VM_OPERATION
Definition: pstypes.h:156
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define UserMode
Definition: asm.h:39
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ ULONG _In_ ULONG Win32Protect
Definition: mmfuncs.h:416
#define MEM_TOP_DOWN
Definition: nt_native.h:1324
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define MEM_LARGE_PAGES
Definition: nt_native.h:1325
#define MI_MAX_ZERO_BITS
Definition: mm.h:85
POBJECT_TYPE PsProcessType
Definition: process.c:20
#define STATUS_MAPPED_ALIGNMENT
Definition: ntstatus.h:798
#define STATUS_INVALID_PARAMETER_8
Definition: ntstatus.h:576
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:571
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:192
#define ProbeForWritePointer(Ptr)
Definition: probe.h:42
#define ProbeForWriteSize_t(Ptr)
Definition: probe.h:45
NTSTATUS NTAPI MmMapViewOfSection(_In_ PVOID SectionObject, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Protect)
Definition: section.c:4031
#define ALIGN_DOWN_POINTER_BY(ptr, align)
Definition: umtypes.h:82

Referenced by BasepLoadLibraryAsDatafile(), CabinetExtractFile(), CabinetOpen(), CON_API(), CsrSrvAttachSharedSection(), CsrSrvCreateSharedSection(), get_manifest_in_manifest_file(), get_manifest_in_pe_file(), GRAPHICS_BUFFER_Initialize(), GuiApplyUserSettings(), GuiConsoleShowConsoleProperties(), Heap32ListFirst(), Heap32ListNext(), InitFunctionPtrs(), LdrpMapDll(), LdrVerifyImageMatchesChecksum(), MapFile(), MapViewOfFileEx(), Module32FirstW(), Module32NextW(), Process32FirstW(), Process32NextW(), SdbpOpenMemMappedFile(), SetupCopyFile(), START_TEST(), Test_BasedSection(), test_cross_process_notifications(), Test_ImageSection(), Test_ImageSection2(), test_notifications(), test_NtMapViewOfSection(), Test_PageFileSection(), test_query_image_information(), test_query_region_information(), Test_RawSize(), Test_SectionContents(), Test_Truncate(), TestPhysicalMemorySection(), TH32CreateSnapshotSectionInitialize(), Thread32First(), and Thread32Next().

◆ NtOpenSection()

NTSTATUS NTAPI NtOpenSection ( OUT PHANDLE  SectionHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes 
)

Definition at line 3225 of file section.c.

3228{
3229 HANDLE Handle;
3232 PAGED_CODE();
3233
3234 /* Check for user-mode caller */
3235 if (PreviousMode != KernelMode)
3236 {
3237 /* Enter SEH */
3238 _SEH2_TRY
3239 {
3240 /* Safely check user-mode parameters */
3241 ProbeForWriteHandle(SectionHandle);
3242 }
3244 {
3245 /* Return the exception code */
3247 }
3248 _SEH2_END;
3249 }
3250
3251 /* Try opening the object */
3255 NULL,
3257 NULL,
3258 &Handle);
3259
3260 /* Enter SEH */
3261 _SEH2_TRY
3262 {
3263 /* Return the handle safely */
3264 *SectionHandle = Handle;
3265 }
3267 {
3268 /* Nothing here */
3269 }
3270 _SEH2_END;
3271
3272 /* Return the status */
3273 return Status;
3274}
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:2559

Referenced by IntGetCodePageEntry(), LdrpCheckForKnownDll(), NtOpenObject(), OpenFileMappingFromApp(), and OpenFileMappingW().

◆ NtUnmapViewOfSection()

NTSTATUS NTAPI NtUnmapViewOfSection ( IN HANDLE  ProcessHandle,
IN PVOID  BaseAddress 
)

Definition at line 3505 of file section.c.

3507{
3511
3512 /* Don't allowing mapping kernel views */
3514 {
3515 DPRINT1("Trying to unmap a kernel view\n");
3517 }
3518
3519 /* Reference the process */
3524 (PVOID*)&Process,
3525 NULL);
3526 if (!NT_SUCCESS(Status)) return Status;
3527
3528 /* Unmap the view */
3530
3531 /* Dereference the process and return status */
3533 return Status;
3534}
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17

Referenced by BasepSxsCloseHandles(), CabinetExtractFile(), close_cross_process_connection(), CloseCabinet(), CON_API(), CsrSrvCreateSharedSection(), FreeLibrary(), FreeLibraryAndExitThread(), get_manifest_in_manifest_file(), get_manifest_in_pe_file(), GRAPHICS_BUFFER_Destroy(), GRAPHICS_BUFFER_Initialize(), GuiApplyUserSettings(), GuiConsoleShowConsoleProperties(), Heap32ListFirst(), Heap32ListNext(), InitFunctionPtrs(), LdrpCheckForLoadedDll(), LdrpMapDll(), LdrUnloadDll(), LdrVerifyImageMatchesChecksum(), Module32FirstW(), Module32NextW(), Process32FirstW(), Process32NextW(), SdbpCloseMemMappedFile(), SetupCopyFile(), START_TEST(), test_cross_process_notifications(), test_image_mappings(), Test_ImageSection(), test_locale_nls(), test_notifications(), test_NtMapViewOfSection(), test_NtMapViewOfSectionEx(), Test_PageFileSection(), test_query_image_information(), test_query_region_information(), Test_RawSize(), test_section_access(), Test_SectionContents(), Test_Truncate(), TH32CreateSnapshotSectionInitialize(), Thread32First(), Thread32Next(), UnMapFile(), and UnmapViewOfFile().

Variable Documentation

◆ MmCompatibleProtectionMask

◆ MmHighSectionBase

PVOID MmHighSectionBase

Definition at line 111 of file section.c.

Referenced by MmArmInitSystem(), and MmCreateArm3Section().

◆ MmMakeFileAccess

ACCESS_MASK MmMakeFileAccess[8]

◆ MmMakeSectionAccess

ACCESS_MASK MmMakeSectionAccess[8]

◆ MmSectionBasedMutex

KGUARDED_MUTEX MmSectionBasedMutex

Definition at line 110 of file section.c.

Referenced by MiDeleteARM3Section(), MmArmInitSystem(), and MmCreateArm3Section().

◆ MmSectionBasedRoot

◆ MmSectionCommitMutex

◆ MmSession

◆ MmUserProtectionToMask1

◆ MmUserProtectionToMask2