ReactOS  0.4.15-dev-2106-g6de3300
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

BOOLEAN NTAPI MiIsProtectionCompatible (IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
 
ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask (IN ACCESS_MASK SectionPageProtection)
 
ULONG NTAPI MiMakeProtectionMask (IN ULONG Protect)
 
BOOLEAN NTAPI MiInitializeSystemSpaceMap (IN PMMSESSION InputSession OPTIONAL)
 
PVOID NTAPI 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)
 
NTSTATUS NTAPI MiCheckPurgeAndUpMapCount (IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
 
PSUBSECTION NTAPI MiLocateSubsection (IN PMMVAD Vad, IN ULONG_PTR Vpn)
 
VOID NTAPI MiSegmentDelete (IN PSEGMENT Segment)
 
VOID NTAPI MiCheckControlArea (IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
 
VOID NTAPI MiDereferenceControlArea (IN PCONTROL_AREA ControlArea)
 
VOID NTAPI MiRemoveMappedView (IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
 
NTSTATUS NTAPI MiUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
 
NTSTATUS NTAPI 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)
 
VOID NTAPI MiSetControlAreaSymbolsLoaded (IN PCONTROL_AREA ControlArea)
 
VOID NTAPI MiLoadUserSymbols (IN PCONTROL_AREA ControlArea, IN PVOID BaseAddress, IN PEPROCESS Process)
 
NTSTATUS NTAPI MiMapViewOfDataSection (IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *BaseAddress, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T ViewSize, IN PSECTION Section, IN SECTION_INHERIT InheritDisposition, IN ULONG ProtectionMask, IN SIZE_T CommitSize, IN ULONG_PTR ZeroBits, IN ULONG AllocationType)
 
VOID NTAPI MiSubsectionConsistent (IN PSUBSECTION Subsection)
 
NTSTATUS NTAPI MiCreateDataFileMap (IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
 
static NTSTATUS NTAPI MiCreatePagingFileMap (OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
 
NTSTATUS NTAPI MiGetFileObjectForSectionAddress (IN PVOID Address, OUT PFILE_OBJECT *FileObject)
 
PFILE_OBJECT NTAPI MmGetFileObjectForSection (IN PVOID SectionObject)
 
static PFILE_OBJECT MiGetFileObjectForVad (_In_ PMMVAD Vad)
 
VOID NTAPI MmGetImageInformation (OUT PSECTION_IMAGE_INFORMATION ImageInformation)
 
NTSTATUS NTAPI 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)
 
NTSTATUS NTAPI MiSetProtectionOnSection (IN PEPROCESS Process, IN PMMVAD FoundVad, IN PVOID StartingAddress, IN PVOID EndingAddress, IN ULONG NewProtect, OUT PULONG CapturedOldProtect, IN ULONG DontCharge, OUT PULONG Locked)
 
VOID NTAPI MiRemoveMappedPtes (IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
 
ULONG NTAPI MiRemoveFromSystemSpace (IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
 
NTSTATUS NTAPI 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, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
 
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, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
 
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 417 of file section.c.

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

Referenced by MiMapViewInSystemSpace().

◆ MiArm3GetCorrectFileAccessMask()

ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask ( IN ACCESS_MASK  SectionPageProtection)

Definition at line 140 of file section.c.

141 {
142  ULONG ProtectionMask;
143 
144  /* Calculate the protection mask and make sure it's valid */
146  if (ProtectionMask == MM_INVALID_PROTECTION)
147  {
148  DPRINT1("Invalid protection mask\n");
150  }
151 
152  /* Now convert it to the required file access */
153  return MmMakeFileAccess[ProtectionMask & 0x7];
154 }
#define MM_INVALID_PROTECTION
Definition: miarm.h:63
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:158
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1

◆ MiCheckControlArea()

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

Definition at line 732 of file section.c.

734 {
735  BOOLEAN DeleteSegment = FALSE;
737 
738  /* Check if this is the last reference or view */
739  if (!(ControlArea->NumberOfMappedViews) &&
740  !(ControlArea->NumberOfSectionReferences))
741  {
742  /* There should be no more user references either */
743  ASSERT(ControlArea->NumberOfUserReferences == 0);
744 
745  /* Not yet supported */
746  ASSERT(ControlArea->FilePointer == NULL);
747 
748  /* The control area is being destroyed */
749  ControlArea->u.Flags.BeingDeleted = TRUE;
750  DeleteSegment = TRUE;
751  }
752 
753  /* Release the PFN lock */
755 
756  /* Delete the segment if needed */
757  if (DeleteSegment)
758  {
759  /* No more user write references at all */
760  ASSERT(ControlArea->WritableUserReferences == 0);
761  MiSegmentDelete(ControlArea->Segment);
762  }
763 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:921
#define TRUE
Definition: types.h:120
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:893
ASSERT(Segment->Locked)
unsigned char BOOLEAN
return FALSE
Definition: section.c:4970
VOID NTAPI MiSegmentDelete(IN PSEGMENT Segment)
Definition: section.c:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define NULL
Definition: types.h:112

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

◆ MiCheckPurgeAndUpMapCount()

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

Definition at line 548 of file section.c.

550 {
551  KIRQL OldIrql;
552 
553  /* Flag not yet supported */
554  ASSERT(FailIfSystemViews == FALSE);
555 
556  /* Lock the PFN database */
558 
559  /* State not yet supported */
560  ASSERT(ControlArea->u.Flags.BeingPurged == 0);
561 
562  /* Increase the reference counts */
563  ControlArea->NumberOfMappedViews++;
564  ControlArea->NumberOfUserReferences++;
565  ASSERT(ControlArea->NumberOfSectionReferences != 0);
566 
567  /* Release the PFN lock and return success */
569  return STATUS_SUCCESS;
570 }
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:893
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
return FALSE
Definition: section.c:4970
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

◆ MiCreateDataFileMap()

NTSTATUS NTAPI MiCreateDataFileMap ( IN PFILE_OBJECT  File,
OUT PSEGMENT Segment,
IN PSIZE_T  MaximumSize,
IN ULONG  SectionPageProtection,
IN ULONG  AllocationAttributes,
IN ULONG  IgnoreFileSizing 
)

Definition at line 1532 of file section.c.

1538 {
1539  /* Not yet implemented */
1540  ASSERT(FALSE);
1541  *Segment = NULL;
1542  return STATUS_NOT_IMPLEMENTED;
1543 }
return STATUS_NOT_IMPLEMENTED
ASSERT(Segment->Locked)
return FALSE
Definition: section.c:4970
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define NULL
Definition: types.h:112

Referenced by MmCreateArm3Section().

◆ MiCreatePagingFileMap()

static NTSTATUS NTAPI MiCreatePagingFileMap ( OUT PSEGMENT Segment,
IN PLARGE_INTEGER  MaximumSize,
IN ULONG  ProtectionMask,
IN ULONG  AllocationAttributes 
)
static

Definition at line 1548 of file section.c.

1552 {
1553  ULONGLONG SizeLimit;
1554  PFN_COUNT PteCount;
1555  PMMPTE PointerPte;
1556  MMPTE TempPte;
1557  PCONTROL_AREA ControlArea;
1558  PSEGMENT NewSegment;
1559  PSUBSECTION Subsection;
1560  PAGED_CODE();
1561 
1562  /* No large pages in ARM3 yet */
1564 
1565  /* Pagefile-backed sections need a known size */
1566  if (!MaximumSize || !MaximumSize->QuadPart || MaximumSize->QuadPart < 0)
1568 
1569  /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1570  SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
1571  SizeLimit /= sizeof(MMPTE);
1572  SizeLimit <<= PAGE_SHIFT;
1573 
1574  /* Fail if this size is too big */
1575  if (MaximumSize->QuadPart > SizeLimit)
1576  {
1577  return STATUS_SECTION_TOO_BIG;
1578  }
1579 
1580  /* Calculate how many Prototype PTEs will be needed */
1581  PteCount = (PFN_COUNT)((MaximumSize->QuadPart + PAGE_SIZE - 1) >> PAGE_SHIFT);
1582 
1583  /* For commited memory, we must have a valid protection mask */
1584  if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1585 
1586  /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1587  NewSegment = ExAllocatePoolWithTag(PagedPool,
1588  sizeof(SEGMENT) +
1589  sizeof(MMPTE) * (PteCount - 1),
1590  'tSmM');
1591  if (!NewSegment)
1592  {
1594  }
1595  *Segment = NewSegment;
1596 
1597  /* Now allocate the control area, which has the subsection structure */
1598  ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1599  sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1600  'tCmM');
1601  if (!ControlArea)
1602  {
1603  ExFreePoolWithTag(Segment, 'tSmM');
1605  }
1606 
1607  /* And zero it out, filling the basic segmnet pointer and reference fields */
1608  RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1609  ControlArea->Segment = NewSegment;
1610  ControlArea->NumberOfSectionReferences = 1;
1611  ControlArea->NumberOfUserReferences = 1;
1612 
1613  /* Convert allocation attributes to control area flags */
1614  if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1615  if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1616  if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1617 
1618  /* We just allocated it */
1619  ControlArea->u.Flags.BeingCreated = 1;
1620 
1621  /* The subsection follows, write the mask, PTE count and point back to the CA */
1622  Subsection = (PSUBSECTION)(ControlArea + 1);
1623  Subsection->ControlArea = ControlArea;
1624  Subsection->PtesInSubsection = PteCount;
1625  Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1626 
1627  /* Zero out the segment's prototype PTEs, and link it with the control area */
1628  PointerPte = &NewSegment->ThePtes[0];
1629  RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1630  NewSegment->PrototypePte = PointerPte;
1631  NewSegment->ControlArea = ControlArea;
1632 
1633  /* Save some extra accounting data for the segment as well */
1634  NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1635  NewSegment->SizeOfSegment = ((ULONGLONG)PteCount) * PAGE_SIZE;
1636  NewSegment->TotalNumberOfPtes = PteCount;
1637  NewSegment->NonExtendedPtes = PteCount;
1638 
1639  /* The subsection's base address is the first Prototype PTE in the segment */
1640  Subsection->SubsectionBase = PointerPte;
1641 
1642  /* Start with an empty PTE, unless this is a commit operation */
1643  TempPte.u.Long = 0;
1645  {
1646  /* In which case, write down the protection mask in the Prototype PTEs */
1647  TempPte.u.Soft.Protection = ProtectionMask;
1648 
1649  /* For accounting, also mark these pages as being committed */
1650  NewSegment->NumberOfCommittedPages = PteCount;
1651  }
1652 
1653  /* The template PTE itself for the segment should also have the mask set */
1654  NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1655 
1656  /* Write out the prototype PTEs, for now they're simply demand zero */
1657 #ifdef _WIN64
1658  RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1659 #else
1660  RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1661 #endif
1662  return STATUS_SUCCESS;
1663 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
ULONG NumberOfCommittedPages
Definition: mmtypes.h:412
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
ULONGLONG SizeOfSegment
Definition: mmtypes.h:410
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
ULONG NumberOfSectionReferences
Definition: mmtypes.h:520
union _MMPTE::@2304 u
ULONG NonExtendedPtes
Definition: mmtypes.h:408
ULONG PFN_COUNT
Definition: mmtypes.h:102
PCONTROL_AREA ControlArea
Definition: mmtypes.h:570
MMPTE ThePtes[1]
Definition: mmtypes.h:427
ULONG TotalNumberOfPtes
Definition: mmtypes.h:407
union _CONTROL_AREA::@2557 u
SIZE_T MmSizeOfPagedPoolInBytes
Definition: miarm.h:592
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:406
#define SEC_BASED
PEPROCESS CreatingProcess
Definition: mmtypes.h:419
ASSERT(Segment->Locked)
#define SEC_COMMIT
Definition: mmtypes.h:99
#define SEC_RESERVE
Definition: nt_native.h:1323
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:300
ULONG64 Protection
Definition: mmtypes.h:88
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
uint64_t ULONGLONG
Definition: typedefs.h:67
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _SUBSECTION * PSUBSECTION
struct _SEGMENT SEGMENT
union _SEGMENT::@2555 u1
#define PAGE_SIZE
Definition: env_spec_w32.h:49
MMSUBSECTION_FLAGS SubsectionFlags
Definition: mmtypes.h:574
PSEGMENT Segment
Definition: mmtypes.h:518
ULONG NumberOfUserReferences
Definition: mmtypes.h:524
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
struct _MMPTE MMPTE
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
MMPTE SegmentPteTemplate
Definition: mmtypes.h:411
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
union _SUBSECTION::@2559 u
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:478
PMMPTE PrototypePte
Definition: mmtypes.h:426
PMMPTE SubsectionBase
Definition: mmtypes.h:578
ULONG BeingCreated
Definition: mmtypes.h:461
NTSYSAPI VOID NTAPI RtlFillMemoryUlonglong(_Out_writes_bytes_all_(Length) PVOID Destination, _In_ SIZE_T Length, _In_ ULONGLONG Pattern)
#define PAGED_CODE()
ULONG PtesInSubsection
Definition: mmtypes.h:580

Referenced by MmCreateArm3Section().

◆ MiDeleteARM3Section()

VOID NTAPI MiDeleteARM3Section ( PVOID  ObjectBody)

Definition at line 3305 of file section.c.

3306 {
3308  PCONTROL_AREA ControlArea;
3309  KIRQL OldIrql;
3310 
3311  SectionObject = (PSECTION)ObjectBody;
3312 
3313  if (SectionObject->u.Flags.Based == 1)
3314  {
3315  /* Remove the node from the global section address tree */
3319  }
3320 
3321  /* Lock the PFN database */
3323 
3324  ASSERT(SectionObject->Segment);
3325  ASSERT(SectionObject->Segment->ControlArea);
3326 
3327  ControlArea = SectionObject->Segment->ControlArea;
3328 
3329  /* Dereference */
3330  ControlArea->NumberOfSectionReferences--;
3331  ControlArea->NumberOfUserReferences--;
3332 
3333  ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
3334 
3335  /* Check it. It will delete it if there is no more reference to it */
3336  MiCheckControlArea(ControlArea, OldIrql);
3337 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
ULONG NumberOfSectionReferences
Definition: mmtypes.h:520
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
union _CONTROL_AREA::@2557 u
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
struct _SECTION * PSECTION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:360
ULONG BeingDeleted
Definition: mmtypes.h:460
ULONG NumberOfUserReferences
Definition: mmtypes.h:524
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:732
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528

Referenced by MmpDeleteSection().

◆ MiDereferenceControlArea()

VOID NTAPI MiDereferenceControlArea ( IN PCONTROL_AREA  ControlArea)

Definition at line 767 of file section.c.

768 {
769  KIRQL OldIrql;
770 
771  /* Lock the PFN database */
773 
774  /* Drop reference counts */
775  ControlArea->NumberOfMappedViews--;
776  ControlArea->NumberOfUserReferences--;
777 
778  /* Check if it's time to delete the CA. This releases the lock */
779  MiCheckControlArea(ControlArea, OldIrql);
780 }
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:732

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

◆ MiFillSystemPageDirectory()

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

Definition at line 480 of file section.c.

482 {
483  PMMPDE PointerPde, LastPde, SystemMapPde;
484  MMPDE TempPde;
485  PFN_NUMBER PageFrameIndex, ParentPage;
486  KIRQL OldIrql;
487  PAGED_CODE();
488 
489  /* Find the PDEs needed for this mapping */
490  PointerPde = MiAddressToPde(Base);
491  LastPde = MiAddressToPde((PVOID)((ULONG_PTR)Base + NumberOfBytes - 1));
492 
493 #if (_MI_PAGING_LEVELS == 2)
494  /* Find the system double-mapped PDE that describes this mapping */
495  SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
496 #else
497  /* We don't have a double mapping */
498  SystemMapPde = PointerPde;
499 #endif
500 
501  /* Use the PDE template and loop the PDEs */
503  while (PointerPde <= LastPde)
504  {
505  /* Lock the PFN database */
507 
508  /* Check if we don't already have this PDE mapped */
509  if (SystemMapPde->u.Hard.Valid == 0)
510  {
511  /* Grab a page for it */
513  MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
514  PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
515  ASSERT(PageFrameIndex);
516  TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
517 
518 #if (_MI_PAGING_LEVELS == 2)
519  ParentPage = MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_PER_PAGE];
520 #else
521  ParentPage = MiPdeToPpe(PointerPde)->u.Hard.PageFrameNumber;
522 #endif
523  /* Initialize its PFN entry, with the parent system page directory page table */
524  MiInitializePfnForOtherProcess(PageFrameIndex,
525  (PMMPTE)PointerPde,
526  ParentPage);
527 
528  /* Make the system PDE entry valid */
529  MI_WRITE_VALID_PDE(SystemMapPde, TempPde);
530 
531  /* The system PDE entry might be the PDE itself, so check for this */
532  if (PointerPde->u.Hard.Valid == 0)
533  {
534  /* It's different, so make the real PDE valid too */
535  MI_WRITE_VALID_PDE(PointerPde, TempPde);
536  }
537  }
538 
539  /* Release the lock and keep going with the next PDE */
541  SystemMapPde++;
542  PointerPde++;
543  }
544 }
#define PDE_PER_PAGE
Definition: mm.h:21
#define MiAddressToPde(x)
Definition: mmx86.c:20
union _MMPTE::@2304 u
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2373
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:238
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1280
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:893
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
ULONG PFN_NUMBER
Definition: ke.h:9
#define MI_SET_PROCESS2(x)
Definition: mm.h:251
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1001
#define MI_SET_USAGE(x)
Definition: mm.h:250
PMMPDE MmSystemPagePtes
Definition: init.c:41
ULONG PageFrameNumber
Definition: mmtypes.h:74
#define MiPdeToPpe(_Pde)
Definition: mm.h:237
ULONG64 Valid
Definition: mmtypes.h:150
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
MMPTE ValidKernelPde
Definition: init.c:28
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define SYSTEM_PD_SIZE
Definition: miarm.h:28
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1035
#define NULL
Definition: types.h:112
#define ULONG_PTR
Definition: config.h:101
#define PAGED_CODE()

Referenced by MiMapViewInSystemSpace(), and MmGetPageTableForProcess().

◆ MiFlushTbAndCapture()

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

Definition at line 2009 of file section.c.

2014 {
2015  MMPTE TempPte, PreviousPte;
2016  KIRQL OldIrql;
2017  BOOLEAN RebuildPte = FALSE;
2018 
2019  //
2020  // User for sanity checking later on
2021  //
2022  PreviousPte = *PointerPte;
2023 
2024  //
2025  // Build the PTE and acquire the PFN lock
2026  //
2028  PointerPte,
2029  ProtectionMask,
2030  PreviousPte.u.Hard.PageFrameNumber);
2032 
2033  //
2034  // We don't support I/O mappings in this path yet
2035  //
2036  ASSERT(Pfn1 != NULL);
2037  ASSERT(Pfn1->u3.e1.CacheAttribute != MiWriteCombined);
2038 
2039  //
2040  // Make sure new protection mask doesn't get in conflict and fix it if it does
2041  //
2042  if (Pfn1->u3.e1.CacheAttribute == MiCached)
2043  {
2044  //
2045  // This is a cached PFN
2046  //
2047  if (ProtectionMask & (MM_NOCACHE | MM_NOACCESS))
2048  {
2049  RebuildPte = TRUE;
2050  ProtectionMask &= ~(MM_NOCACHE | MM_NOACCESS);
2051  }
2052  }
2053  else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
2054  {
2055  //
2056  // This is a non-cached PFN
2057  //
2058  if ((ProtectionMask & (MM_NOCACHE | MM_NOACCESS)) != MM_NOCACHE)
2059  {
2060  RebuildPte = TRUE;
2061  ProtectionMask &= ~MM_NOACCESS;
2062  ProtectionMask |= MM_NOCACHE;
2063  }
2064  }
2065 
2066  if (RebuildPte)
2067  {
2069  PointerPte,
2070  ProtectionMask,
2071  PreviousPte.u.Hard.PageFrameNumber);
2072  }
2073 
2074  //
2075  // Write the new PTE, making sure we are only changing the bits
2076  //
2077  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2078 
2079  //
2080  // Flush the TLB
2081  //
2082  ASSERT(PreviousPte.u.Hard.Valid == 1);
2083  KeFlushCurrentTb();
2084  ASSERT(PreviousPte.u.Hard.Valid == 1);
2085 
2086  //
2087  // Windows updates the relevant PFN1 information, we currently don't.
2088  //
2089  if (UpdateDirty && PreviousPte.u.Hard.Dirty)
2090  {
2091  if (!Pfn1->u3.e1.Modified)
2092  {
2093  DPRINT1("FIXME: Mark PFN as dirty\n");
2094  }
2095  }
2096 
2097  //
2098  // Not supported in ARM3
2099  //
2100  ASSERT(FoundVad->u.VadFlags.VadType != VadWriteWatch);
2101 
2102  //
2103  // Release the PFN lock, we are done
2104  //
2106 }
union _MMPTE::@2304 u
#define TRUE
Definition: types.h:120
#define MM_NOACCESS
Definition: miarm.h:61
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
#define MM_NOCACHE
Definition: miarm.h:52
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:893
ULONG64 Dirty
Definition: mmtypes.h:164
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
unsigned char BOOLEAN
return FALSE
Definition: section.c:4970
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:813
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:960
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:325

Referenced by MiProtectVirtualMemory(), and MiSetProtectionOnSection().

◆ MiGetFileObjectForSectionAddress()

NTSTATUS NTAPI MiGetFileObjectForSectionAddress ( IN PVOID  Address,
OUT PFILE_OBJECT FileObject 
)

Definition at line 1667 of file section.c.

1670 {
1671  PMMVAD Vad;
1672  PCONTROL_AREA ControlArea;
1673 
1674  /* Get the VAD */
1675  Vad = MiLocateAddress(Address);
1676  if (Vad == NULL)
1677  {
1678  /* Fail, the address does not exist */
1679  DPRINT1("Invalid address\n");
1680  return STATUS_INVALID_ADDRESS;
1681  }
1682 
1683  /* Check if this is a RosMm memory area */
1684  if (Vad->u.VadFlags.Spare != 0)
1685  {
1687 
1688  /* Check if it's a section view (RosMm section) */
1690  {
1691  /* Get the section pointer to the SECTION_OBJECT */
1692  *FileObject = MemoryArea->SectionData.Segment->FileObject;
1693  }
1694  else
1695  {
1696 #ifdef NEWCC
1697  ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1698  DPRINT1("Address is a cache section!\n");
1699  return STATUS_SECTION_NOT_IMAGE;
1700 #else
1701  ASSERT(FALSE);
1702  return STATUS_SECTION_NOT_IMAGE;
1703 #endif
1704  }
1705  }
1706  else
1707  {
1708  /* Make sure it's not a VM VAD */
1709  if (Vad->u.VadFlags.PrivateMemory == 1)
1710  {
1711  DPRINT1("Address is not a section\n");
1712  return STATUS_SECTION_NOT_IMAGE;
1713  }
1714 
1715  /* Get the control area */
1716  ControlArea = Vad->ControlArea;
1717  if (!(ControlArea) || !(ControlArea->u.Flags.Image))
1718  {
1719  DPRINT1("Address is not a section\n");
1720  return STATUS_SECTION_NOT_IMAGE;
1721  }
1722 
1723  /* Get the file object */
1724  *FileObject = ControlArea->FilePointer;
1725  }
1726 
1727  /* Return success */
1728  return STATUS_SUCCESS;
1729 }
PFILE_OBJECT FilePointer
Definition: mmtypes.h:530
ULONG Type
Definition: mm.h:219
struct _MEMORY_AREA * PMEMORY_AREA
union _CONTROL_AREA::@2557 u
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:731
ASSERT(Segment->Locked)
PCONTROL_AREA ControlArea
Definition: mmtypes.h:733
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:48
static WCHAR Address[46]
Definition: ping.c:68
return FALSE
Definition: section.c:4970
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:71
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
ULONG_PTR PrivateMemory
Definition: mmtypes.h:695
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:309
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:557
union _MMVAD::@2564 u
#define NULL
Definition: types.h:112
struct _MEMORY_AREA::@1775 SectionData
#define DPRINT1
Definition: precomp.h:8
ULONG_PTR Spare
Definition: mmtypes.h:694
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
#define STATUS_SUCCESS
Definition: shellext.h:65

◆ MiGetFileObjectForVad()

static PFILE_OBJECT MiGetFileObjectForVad ( _In_ PMMVAD  Vad)
static

Definition at line 1752 of file section.c.

1754 {
1755  PCONTROL_AREA ControlArea;
1757 
1758  /* Check if this is a RosMm memory area */
1759  if (Vad->u.VadFlags.Spare != 0)
1760  {
1762 
1763  /* Check if it's a section view (RosMm section) */
1765  {
1766  /* Get the section pointer to the SECTION_OBJECT */
1767  FileObject = MemoryArea->SectionData.Segment->FileObject;
1768  }
1769  else
1770  {
1771 #ifdef NEWCC
1772  ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1773  DPRINT1("VAD is a cache section!\n");
1774 #else
1775  ASSERT(FALSE);
1776 #endif
1777  return NULL;
1778  }
1779  }
1780  else
1781  {
1782  /* Make sure it's not a VM VAD */
1783  if (Vad->u.VadFlags.PrivateMemory == 1)
1784  {
1785  DPRINT1("VAD is not a section\n");
1786  return NULL;
1787  }
1788 
1789  /* Get the control area */
1790  ControlArea = Vad->ControlArea;
1791  if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1792  {
1793  DPRINT1("Address is not a section\n");
1794  return NULL;
1795  }
1796 
1797  /* Get the file object */
1798  FileObject = ControlArea->FilePointer;
1799  }
1800 
1801  /* Return the file object */
1802  return FileObject;
1803 }
PFILE_OBJECT FilePointer
Definition: mmtypes.h:530
ULONG Type
Definition: mm.h:219
struct _MEMORY_AREA * PMEMORY_AREA
union _CONTROL_AREA::@2557 u
ASSERT(Segment->Locked)
return FALSE
Definition: section.c:4970
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:71
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
* PFILE_OBJECT
Definition: iotypes.h:1995
#define NULL
Definition: types.h:112
struct _MEMORY_AREA::@1775 SectionData
#define DPRINT1
Definition: precomp.h:8
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528

Referenced by MmGetFileNameForAddress(), and NtAreMappedFilesTheSame().

◆ MiInitializeSystemSpaceMap()

BOOLEAN NTAPI MiInitializeSystemSpaceMap ( IN PMMSESSION InputSession  OPTIONAL)

Definition at line 240 of file section.c.

241 {
242  SIZE_T AllocSize, BitmapSize, Size;
243  PVOID ViewStart;
244  PMMSESSION Session;
245 
246  /* Check if this a session or system space */
247  if (InputSession)
248  {
249  /* Use the input session */
250  Session = InputSession;
251  ViewStart = MiSessionViewStart;
253  }
254  else
255  {
256  /* Use the system space "session" */
257  Session = &MmSession;
258  ViewStart = MiSystemViewStart;
260  }
261 
262  /* Initialize the system space lock */
263  Session->SystemSpaceViewLockPointer = &Session->SystemSpaceViewLock;
265 
266  /* Set the start address */
267  Session->SystemSpaceViewStart = ViewStart;
268 
269  /* Create a bitmap to describe system space */
270  BitmapSize = sizeof(RTL_BITMAP) + ((((Size / MI_SYSTEM_VIEW_BUCKET_SIZE) + 31) / 32) * sizeof(ULONG));
272  BitmapSize,
273  TAG_MM);
274  ASSERT(Session->SystemSpaceBitMap);
276  (PULONG)(Session->SystemSpaceBitMap + 1),
278 
279  /* Set system space fully empty to begin with */
281 
282  /* Set default hash flags */
283  Session->SystemSpaceHashSize = 31;
284  Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
285  Session->SystemSpaceHashEntries = 0;
286 
287  /* Calculate how much space for the hash views we'll need */
288  AllocSize = sizeof(MMVIEW) * Session->SystemSpaceHashSize;
289  ASSERT(AllocSize < PAGE_SIZE);
290 
291  /* Allocate and zero the view table */
292  Session->SystemSpaceViewTable = ExAllocatePoolWithTag(Session == &MmSession ?
293  NonPagedPool :
294  PagedPool,
295  AllocSize,
296  TAG_MM);
297  ASSERT(Session->SystemSpaceViewTable != NULL);
298  RtlZeroMemory(Session->SystemSpaceViewTable, AllocSize);
299 
300  /* Success */
301  return TRUE;
302 }
struct _RTL_BITMAP RTL_BITMAP
#define TRUE
Definition: types.h:120
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
PCHAR SystemSpaceViewStart
Definition: miarm.h:458
ULONG SystemSpaceHashEntries
Definition: miarm.h:461
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:456
ASSERT(Segment->Locked)
#define TAG_MM
Definition: tag.h:136
ULONG MmSystemViewSize
Definition: init.c:39
ULONG MmSessionViewSize
Definition: init.c:35
PVOID MiSystemViewStart
Definition: init.c:38
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:459
ULONG SystemSpaceHashKey
Definition: miarm.h:462
struct _MMVIEW MMVIEW
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:457
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ULONG_PTR SIZE_T
Definition: typedefs.h:80
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
PRTL_BITMAP SystemSpaceBitMap
Definition: miarm.h:464
PVOID MiSessionViewStart
Definition: init.c:30
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:267
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
ULONG SystemSpaceHashSize
Definition: miarm.h:460
MMSESSION MmSession
Definition: section.c:107

Referenced by MiBuildPagedPool(), and MiSessionCreateInternal().

◆ MiInsertInSystemSpace()

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

Definition at line 306 of file section.c.

309 {
310  PVOID Base;
311  ULONG Entry, Hash, i, HashSize;
312  PMMVIEW OldTable;
313  PAGED_CODE();
314 
315  /* Stay within 4GB */
317 
318  /* Lock system space */
319  KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
320 
321  /* Check if we're going to exhaust hash entries */
322  if ((Session->SystemSpaceHashEntries + 8) > Session->SystemSpaceHashSize)
323  {
324  /* Double the hash size */
325  HashSize = Session->SystemSpaceHashSize * 2;
326 
327  /* Save the old table and allocate a new one */
328  OldTable = Session->SystemSpaceViewTable;
329  Session->SystemSpaceViewTable = ExAllocatePoolWithTag(Session ==
330  &MmSession ?
331  NonPagedPool :
332  PagedPool,
333  HashSize *
334  sizeof(MMVIEW),
335  TAG_MM);
336  if (!Session->SystemSpaceViewTable)
337  {
338  /* Failed to allocate a new table, keep the old one for now */
339  Session->SystemSpaceViewTable = OldTable;
340  }
341  else
342  {
343  /* Clear the new table and set the new ahsh and key */
344  RtlZeroMemory(Session->SystemSpaceViewTable, HashSize * sizeof(MMVIEW));
345  Session->SystemSpaceHashSize = HashSize;
346  Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
347 
348  /* Loop the old table */
349  for (i = 0; i < Session->SystemSpaceHashSize / 2; i++)
350  {
351  /* Check if the entry was valid */
352  if (OldTable[i].Entry)
353  {
354  /* Re-hash the old entry and search for space in the new table */
355  Hash = (OldTable[i].Entry >> 16) % Session->SystemSpaceHashKey;
356  while (Session->SystemSpaceViewTable[Hash].Entry)
357  {
358  /* Loop back at the beginning if we had an overflow */
359  if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
360  }
361 
362  /* Write the old entry in the new table */
363  Session->SystemSpaceViewTable[Hash] = OldTable[i];
364  }
365  }
366 
367  /* Free the old table */
368  ExFreePool(OldTable);
369  }
370  }
371 
372  /* Check if we ran out */
373  if (Session->SystemSpaceHashEntries == Session->SystemSpaceHashSize)
374  {
375  DPRINT1("Ran out of system view hash entries\n");
376  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
377  return NULL;
378  }
379 
380  /* Find space where to map this view */
381  i = RtlFindClearBitsAndSet(Session->SystemSpaceBitMap, Buckets, 0);
382  if (i == 0xFFFFFFFF)
383  {
384  /* Out of space, fail */
385  Session->BitmapFailures++;
386  DPRINT1("Out of system view space\n");
387  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
388  return NULL;
389  }
390 
391  /* Compute the base address */
392  Base = (PVOID)((ULONG_PTR)Session->SystemSpaceViewStart + (i * MI_SYSTEM_VIEW_BUCKET_SIZE));
393 
394  /* Get the hash entry for this allocation */
395  Entry = ((ULONG_PTR)Base & ~(MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) + Buckets;
396  Hash = (Entry >> 16) % Session->SystemSpaceHashKey;
397 
398  /* Loop hash entries until a free one is found */
399  while (Session->SystemSpaceViewTable[Hash].Entry)
400  {
401  /* Unless we overflow, in which case loop back at hash o */
402  if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
403  }
404 
405  /* Add this entry into the hash table */
406  Session->SystemSpaceViewTable[Hash].Entry = Entry;
407  Session->SystemSpaceViewTable[Hash].ControlArea = ControlArea;
408 
409  /* Hash entry found, increment total and return the base address */
410  Session->SystemSpaceHashEntries++;
411  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
412  return Base;
413 }
static int Hash(const char *)
Definition: reader.c:2257
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2373
uint32_t ULONG_PTR
Definition: typedefs.h:65
while(1)
Definition: macro.lex.yy.c:740
ASSERT(Segment->Locked)
#define TAG_MM
Definition: tag.h:136
Entry
Definition: section.c:4851
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
void * PVOID
Definition: retypes.h:9
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
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
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:267
Definition: miarm.h:448
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
ULONG_PTR Entry
Definition: miarm.h:450
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PAGED_CODE()
MMSESSION MmSession
Definition: section.c:107

Referenced by MiMapViewInSystemSpace().

◆ MiIsProtectionCompatible()

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

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 }
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define MM_INVALID_PROTECTION
Definition: miarm.h:63
#define PAGE_GUARD
Definition: nt_native.h:1310
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
return FALSE
Definition: section.c:4970
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:158
ULONG MmCompatibleProtectionMask[8]
Definition: section.c:84
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1

Referenced by MmMapViewOfArm3Section().

◆ MiLoadUserSymbols()

VOID NTAPI MiLoadUserSymbols ( IN PCONTROL_AREA  ControlArea,
IN PVOID  BaseAddress,
IN PEPROCESS  Process 
)

Definition at line 1185 of file section.c.

1188 {
1189  NTSTATUS Status;
1191  PLIST_ENTRY NextEntry;
1193  PIMAGE_NT_HEADERS NtHeaders;
1194  PLDR_DATA_TABLE_ENTRY LdrEntry;
1195 
1196  FileName = &ControlArea->FilePointer->FileName;
1197  if (FileName->Length == 0)
1198  {
1199  return;
1200  }
1201 
1202  /* Acquire module list lock */
1205 
1206  /* Browse list to try to find current module */
1207  for (NextEntry = MmLoadedUserImageList.Flink;
1208  NextEntry != &MmLoadedUserImageList;
1209  NextEntry = NextEntry->Flink)
1210  {
1211  /* Get the entry */
1212  LdrEntry = CONTAINING_RECORD(NextEntry,
1214  InLoadOrderLinks);
1215 
1216  /* If already in the list, increase load count */
1217  if (LdrEntry->DllBase == BaseAddress)
1218  {
1219  ++LdrEntry->LoadCount;
1220  break;
1221  }
1222  }
1223 
1224  /* Not in the list, we'll add it */
1225  if (NextEntry == &MmLoadedUserImageList)
1226  {
1227  /* Allocate our element, taking to the name string and its null char */
1228  LdrEntry = ExAllocatePoolWithTag(NonPagedPool, FileName->Length + sizeof(UNICODE_NULL) + sizeof(*LdrEntry), 'bDmM');
1229  if (LdrEntry)
1230  {
1231  memset(LdrEntry, 0, FileName->Length + sizeof(UNICODE_NULL) + sizeof(*LdrEntry));
1232 
1233  _SEH2_TRY
1234  {
1235  /* Get image checksum and size */
1236  NtHeaders = RtlImageNtHeader(BaseAddress);
1237  if (NtHeaders)
1238  {
1239  LdrEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
1240  LdrEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
1241  }
1242  }
1244  {
1245  ExFreePoolWithTag(LdrEntry, 'bDmM');
1248  _SEH2_YIELD(return);
1249  }
1250  _SEH2_END;
1251 
1252  /* Fill all the details */
1253  LdrEntry->DllBase = BaseAddress;
1254  LdrEntry->FullDllName.Buffer = (PVOID)((ULONG_PTR)LdrEntry + sizeof(*LdrEntry));
1255  LdrEntry->FullDllName.Length = FileName->Length;
1256  LdrEntry->FullDllName.MaximumLength = FileName->Length + sizeof(UNICODE_NULL);
1257  memcpy(LdrEntry->FullDllName.Buffer, FileName->Buffer, FileName->Length);
1258  LdrEntry->FullDllName.Buffer[LdrEntry->FullDllName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1259  LdrEntry->LoadCount = 1;
1260 
1261  /* Insert! */
1263  }
1264  }
1265 
1266  /* Release locks */
1269 
1270  /* Load symbols */
1272  if (NT_SUCCESS(Status))
1273  {
1276  }
1277 }
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LONG NTSTATUS
Definition: precomp.h:26
ULONG SizeOfImage
Definition: ldrtypes.h:143
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
PVOID DllBase
Definition: btrfs_drv.h:1926
#define UNICODE_NULL
NTSTATUS Status
Definition: section.c:4842
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG CheckSum
Definition: btrfs_drv.h:1932
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
LIST_ENTRY MmLoadedUserImageList
Definition: sysldr.c:35
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1922
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: typedefs.h:119
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
struct _FileName FileName
Definition: fatprocs.h:893
_SEH2_END
Definition: create.c:4400
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1928
VOID NTAPI DbgLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
#define RtlImageNtHeader
Definition: compat.h:665
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define memset(x, y, z)
Definition: compat.h:39
static const CHAR FileNameA[]
USHORT LoadCount
Definition: ntddk_ex.h:208

◆ MiLocateSubsection()

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

Definition at line 574 of file section.c.

576 {
577  PSUBSECTION Subsection;
578  PCONTROL_AREA ControlArea;
579  ULONG_PTR PteOffset;
580 
581  /* Get the control area */
582  ControlArea = Vad->ControlArea;
583  ASSERT(ControlArea->u.Flags.Rom == 0);
584  ASSERT(ControlArea->u.Flags.Image == 0);
585  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
586 
587  /* Get the subsection */
588  Subsection = (PSUBSECTION)(ControlArea + 1);
589 
590  /* We only support single-subsection segments */
591  ASSERT(Subsection->SubsectionBase != NULL);
592  ASSERT(Vad->FirstPrototypePte >= Subsection->SubsectionBase);
593  ASSERT(Vad->FirstPrototypePte < &Subsection->SubsectionBase[Subsection->PtesInSubsection]);
594 
595  /* Compute the PTE offset */
596  PteOffset = Vpn - Vad->StartingVpn;
597  PteOffset += Vad->FirstPrototypePte - Subsection->SubsectionBase;
598 
599  /* Again, we only support single-subsection segments */
600  ASSERT(PteOffset < 0xF0000000);
601  ASSERT(PteOffset < Subsection->PtesInSubsection);
602 
603  /* Return the subsection */
604  return Subsection;
605 }
union _CONTROL_AREA::@2557 u
uint32_t ULONG_PTR
Definition: typedefs.h:65
ASSERT(Segment->Locked)
struct _SUBSECTION * PSUBSECTION
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:488
#define NULL
Definition: types.h:112
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
PMMPTE SubsectionBase
Definition: mmtypes.h:578
ULONG PtesInSubsection
Definition: mmtypes.h:580

Referenced by MiDeleteVirtualAddresses().

◆ MiMakeProtectionMask()

ULONG NTAPI MiMakeProtectionMask ( IN ULONG  Protect)

Definition at line 158 of file section.c.

159 {
160  ULONG Mask1, Mask2, ProtectMask;
161 
162  /* PAGE_EXECUTE_WRITECOMBINE is theoretically the maximum */
163  if (Protect >= (PAGE_WRITECOMBINE * 2)) return MM_INVALID_PROTECTION;
164 
165  /*
166  * Windows API protection mask can be understood as two bitfields, differing
167  * by whether or not execute rights are being requested
168  */
169  Mask1 = Protect & 0xF;
170  Mask2 = (Protect >> 4) & 0xF;
171 
172  /* Check which field is there */
173  if (!Mask1)
174  {
175  /* Mask2 must be there, use it to determine the PTE protection */
176  if (!Mask2) return MM_INVALID_PROTECTION;
177  ProtectMask = MmUserProtectionToMask2[Mask2];
178  }
179  else
180  {
181  /* Mask2 should not be there, use Mask1 to determine the PTE mask */
182  if (Mask2) return MM_INVALID_PROTECTION;
183  ProtectMask = MmUserProtectionToMask1[Mask1];
184  }
185 
186  /* Make sure the final mask is a valid one */
187  if (ProtectMask == MM_INVALID_PROTECTION) return MM_INVALID_PROTECTION;
188 
189  /* Check for PAGE_GUARD option */
190  if (Protect & PAGE_GUARD)
191  {
192  /* It's not valid on no-access, nocache, or writecombine pages */
193  if ((ProtectMask == MM_NOACCESS) ||
195  {
196  /* Fail such requests */
197  return MM_INVALID_PROTECTION;
198  }
199 
200  /* This actually turns on guard page in this scenario! */
201  ProtectMask |= MM_GUARDPAGE;
202  }
203 
204  /* Check for nocache option */
205  if (Protect & PAGE_NOCACHE)
206  {
207  /* The earlier check should've eliminated this possibility */
208  ASSERT((Protect & PAGE_GUARD) == 0);
209 
210  /* Check for no-access page or write combine page */
211  if ((ProtectMask == MM_NOACCESS) || (Protect & PAGE_WRITECOMBINE))
212  {
213  /* Such a request is invalid */
214  return MM_INVALID_PROTECTION;
215  }
216 
217  /* Add the PTE flag */
218  ProtectMask |= MM_NOCACHE;
219  }
220 
221  /* Check for write combine option */
223  {
224  /* The two earlier scenarios should've caught this */
225  ASSERT((Protect & (PAGE_GUARD | PAGE_NOACCESS)) == 0);
226 
227  /* Don't allow on no-access pages */
228  if (ProtectMask == MM_NOACCESS) return MM_INVALID_PROTECTION;
229 
230  /* This actually turns on write-combine in this scenario! */
231  ProtectMask |= MM_NOACCESS;
232  }
233 
234  /* Return the final MM PTE protection mask */
235  return ProtectMask;
236 }
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define MM_INVALID_PROTECTION
Definition: miarm.h:63
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:214
CHAR MmUserProtectionToMask1[16]
Definition: section.c:44
#define PAGE_GUARD
Definition: nt_native.h:1310
#define MM_NOACCESS
Definition: miarm.h:61
#define MM_NOCACHE
Definition: miarm.h:52
ASSERT(Segment->Locked)
#define PAGE_NOACCESS
Definition: nt_native.h:1302
CHAR MmUserProtectionToMask2[16]
Definition: section.c:64
#define MM_GUARDPAGE
Definition: miarm.h:53
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
unsigned int ULONG
Definition: retypes.h:1

Referenced by MiArm3GetCorrectFileAccessMask(), MiIsProtectionCompatible(), MiProtectVirtualMemory(), MiSetProtectionOnSection(), MmCreateArm3Section(), MmCreateSection(), MmInsertMemoryArea(), MmMapViewOfArm3Section(), 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 1057 of file section.c.

1063 {
1064  PVOID Base;
1065  PCONTROL_AREA ControlArea;
1066  ULONG Buckets;
1067  LONGLONG SectionSize;
1068  NTSTATUS Status;
1069  PAGED_CODE();
1070 
1071  /* Get the control area, check for any flags ARM3 doesn't yet support */
1072  ControlArea = ((PSECTION)Section)->Segment->ControlArea;
1073  ASSERT(ControlArea->u.Flags.Image == 0);
1074  ASSERT(ControlArea->FilePointer == NULL);
1075  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1076  ASSERT(ControlArea->u.Flags.Rom == 0);
1077  ASSERT(ControlArea->u.Flags.WasPurged == 0);
1078 
1079  /* Increase the reference and map count on the control area, no purges yet */
1080  Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1082 
1083  /* Get the section size at creation time */
1084  SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart;
1085 
1086  /* If the caller didn't specify a view size, assume until the end of the section */
1087  if (!(*ViewSize))
1088  {
1089  /* Check for overflow first */
1090  if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX)
1091  {
1092  DPRINT1("Section end is too far away from the specified offset.\n");
1093  MiDereferenceControlArea(ControlArea);
1094  return STATUS_INVALID_VIEW_SIZE;
1095  }
1096  *ViewSize = SectionSize - SectionOffset->QuadPart;
1097  }
1098 
1099  /* Check overflow */
1100  if ((SectionOffset->QuadPart + *ViewSize) < SectionOffset->QuadPart)
1101  {
1102  DPRINT1("Integer overflow between size & offset!\n");
1103  MiDereferenceControlArea(ControlArea);
1104  return STATUS_INVALID_VIEW_SIZE;
1105  }
1106 
1107  /* Check if the caller wanted a larger section than the view */
1108  if (SectionOffset->QuadPart + *ViewSize > SectionSize)
1109  {
1110  /* Fail */
1111  DPRINT1("View is too large\n");
1112  MiDereferenceControlArea(ControlArea);
1113  return STATUS_INVALID_VIEW_SIZE;
1114  }
1115 
1116  /* Get the number of 64K buckets required for this mapping */
1117  Buckets = (ULONG)(*ViewSize / MI_SYSTEM_VIEW_BUCKET_SIZE);
1118  if (*ViewSize & (MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) Buckets++;
1119 
1120  /* Check if the view is more than 4GB large */
1121  if (Buckets >= MI_SYSTEM_VIEW_BUCKET_SIZE)
1122  {
1123  /* Fail */
1124  DPRINT1("View is too large\n");
1125  MiDereferenceControlArea(ControlArea);
1126  return STATUS_INVALID_VIEW_SIZE;
1127  }
1128 
1129  /* Insert this view into system space and get a base address for it */
1130  Base = MiInsertInSystemSpace(Session, Buckets, ControlArea);
1131  if (!Base)
1132  {
1133  /* Fail */
1134  DPRINT1("Out of system space\n");
1135  MiDereferenceControlArea(ControlArea);
1136  return STATUS_NO_MEMORY;
1137  }
1138 
1139  /* What's the underlying session? */
1140  if (Session == &MmSession)
1141  {
1142  /* Create the PDEs needed for this mapping, and double-map them if needed */
1145  }
1146  else
1147  {
1148  /* Create the PDEs needed for this mapping */
1150  (PVOID)((ULONG_PTR)Base +
1151  Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
1153  }
1154 
1155  /* Create the actual prototype PTEs for this mapping */
1158  ControlArea,
1159  SectionOffset->QuadPart);
1161 
1162  /* Return the base adress of the mapping and success */
1163  *MappedBase = Base;
1164  return STATUS_SUCCESS;
1165 }
PFILE_OBJECT FilePointer
Definition: mmtypes.h:530
#define SIZE_T_MAX
Definition: dhcpd.h:91
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2373
union _CONTROL_AREA::@2557 u
NTSTATUS NTAPI MiSessionCommitPageTables(IN PVOID StartVa, IN PVOID EndVa)
Definition: section.c:941
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:406
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS NTAPI MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:548
VOID NTAPI MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:767
ASSERT(Segment->Locked)
#define MiAddressToPte(x)
Definition: mmx86.c:19
static NTSTATUS MiAddMappedPtes(IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea, IN LONGLONG SectionOffset)
Definition: section.c:417
NTSTATUS Status
Definition: section.c:4842
return FALSE
Definition: section.c:4970
struct _SECTION * PSECTION
PVOID NTAPI MiInsertInSystemSpace(IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
Definition: section.c:306
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:404
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:480
#define BYTES_TO_PAGES(Size)
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:488
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:268
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:267
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
PSEGMENT Segment
Definition: mmtypes.h:518
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
ULONG WasPurged
Definition: mmtypes.h:475
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define PAGED_CODE()
MMSESSION MmSession
Definition: section.c:107

Referenced by MmMapViewInSessionSpace(), and MmMapViewInSystemSpaceEx().

◆ MiMapViewOfDataSection()

NTSTATUS NTAPI MiMapViewOfDataSection ( IN PCONTROL_AREA  ControlArea,
IN PEPROCESS  Process,
IN PVOID BaseAddress,
IN PLARGE_INTEGER  SectionOffset,
IN PSIZE_T  ViewSize,
IN PSECTION  Section,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG  ProtectionMask,
IN SIZE_T  CommitSize,
IN ULONG_PTR  ZeroBits,
IN ULONG  AllocationType 
)

Definition at line 1281 of file section.c.

1292 {
1293  PMMVAD_LONG Vad;
1294  ULONG_PTR StartAddress;
1295  ULONG_PTR ViewSizeInPages;
1296  PSUBSECTION Subsection;
1297  PSEGMENT Segment;
1298  PFN_NUMBER PteOffset;
1299  NTSTATUS Status;
1300  ULONG QuotaCharge = 0, QuotaExcess = 0;
1301  PMMPTE PointerPte, LastPte;
1302  MMPTE TempPte;
1303  ULONG Granularity = MM_VIRTMEM_GRANULARITY;
1304 
1305  DPRINT("Mapping ARM3 data section\n");
1306 
1307  /* Get the segment for this section */
1308  Segment = ControlArea->Segment;
1309 
1310 #ifdef _M_IX86
1311  /* ALlow being less restrictive on x86. */
1313  Granularity = PAGE_SIZE;
1314 #endif
1315 
1316  /* One can only reserve a file-based mapping, not shared memory! */
1317  if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1318  {
1320  }
1321 
1322  /* First, increase the map count. No purging is supported yet */
1323  Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1324  if (!NT_SUCCESS(Status)) return Status;
1325 
1326  /* Check if the caller specified the view size */
1327  if (!(*ViewSize))
1328  {
1329  /* The caller did not, so pick a 64K aligned view size based on the offset */
1330  SectionOffset->LowPart &= ~(_64K - 1);
1331 
1332  /* Make sure that we will not overflow */
1333  if ((Section->SizeOfSection.QuadPart - SectionOffset->QuadPart) > MAXLONG_PTR)
1334  {
1335  MiDereferenceControlArea(ControlArea);
1336  return STATUS_INVALID_VIEW_SIZE;
1337  }
1338 
1339  *ViewSize = (SIZE_T)(Section->SizeOfSection.QuadPart - SectionOffset->QuadPart);
1340  }
1341  else
1342  {
1343  /* A size was specified, align it to a 64K boundary */
1344  *ViewSize += SectionOffset->LowPart & (_64K - 1);
1345 
1346  /* Check for overflow or huge value */
1347  if ((*ViewSize < (SectionOffset->LowPart & (_64K - 1))) || ((*ViewSize) > MAXLONG_PTR))
1348  {
1349  MiDereferenceControlArea(ControlArea);
1350  return STATUS_INVALID_VIEW_SIZE;
1351  }
1352 
1353  /* Align the offset as well to make this an aligned map */
1354  SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1355  }
1356 
1357  /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1358  ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1359 
1360  /* Windows ASSERTs for this flag */
1361  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1362 
1363  /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1364  ASSERT(ControlArea->u.Flags.Rom == 0);
1365  Subsection = (PSUBSECTION)(ControlArea + 1);
1366 
1367  /* Sections with extended segments are not supported in ARM3 */
1368  ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1369 
1370  /* Within this section, figure out which PTEs will describe the view */
1371  PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1372 
1373  /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1374  ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1375  ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1376 
1377  /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1378  ASSERT(PteOffset < Subsection->PtesInSubsection);
1379 
1380  /* In ARM3, only page-file backed sections (shared memory) are supported now */
1381  ASSERT(ControlArea->FilePointer == NULL);
1382 
1383  /* Windows ASSERTs for this too -- there must be a subsection base address */
1384  ASSERT(Subsection->SubsectionBase != NULL);
1385 
1386  /* Compute how much commit space the segment will take */
1387  if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1388  {
1389  /* Charge for the maximum pages */
1390  QuotaCharge = BYTES_TO_PAGES(CommitSize);
1391  }
1392 
1393  /* ARM3 does not currently support large pages */
1394  ASSERT(Segment->SegmentFlags.LargePages == 0);
1395 
1396  /* Calculate how many pages the region spans */
1397  ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1398 
1399  /* A VAD can now be allocated. Do so and zero it out */
1400  /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1401  ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1402  Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1403  if (!Vad)
1404  {
1405  MiDereferenceControlArea(ControlArea);
1407  }
1408 
1409  RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1410  Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1411 
1412  /* Write all the data required in the VAD for handling a fault */
1413  Vad->ControlArea = ControlArea;
1414  Vad->u.VadFlags.CommitCharge = 0;
1415  Vad->u.VadFlags.Protection = ProtectionMask;
1416  Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1418  if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1419  {
1420  /* This isn't really implemented yet, but handle setting the flag */
1421  Vad->u.VadFlags.NoChange = 1;
1422  Vad->u2.VadFlags2.SecNoChange = 1;
1423  }
1424 
1425  /* Finally, write down the first and last prototype PTE */
1426  Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1427  PteOffset += ViewSizeInPages - 1;
1428  ASSERT(PteOffset < Subsection->PtesInSubsection);
1429  Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1430 
1431  /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1433 
1434  /* FIXME: Should setup VAD bitmap */
1436 
1437  /* Check if anything was committed */
1438  if (QuotaCharge)
1439  {
1440  /* Set the start and end PTE addresses, and pick the template PTE */
1441  PointerPte = Vad->FirstPrototypePte;
1442  LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1443  TempPte = Segment->SegmentPteTemplate;
1444 
1445  /* Acquire the commit lock and loop all prototype PTEs to be committed */
1447  while (PointerPte < LastPte)
1448  {
1449  /* Make sure the PTE is already invalid */
1450  if (PointerPte->u.Long == 0)
1451  {
1452  /* And write the invalid PTE */
1453  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1454  }
1455  else
1456  {
1457  /* The PTE is valid, so skip it */
1458  QuotaExcess++;
1459  }
1460 
1461  /* Move to the next PTE */
1462  PointerPte++;
1463  }
1464 
1465  /* Now check how many pages exactly we committed, and update accounting */
1466  ASSERT(QuotaCharge >= QuotaExcess);
1467  QuotaCharge -= QuotaExcess;
1468  Segment->NumberOfCommittedPages += QuotaCharge;
1469  ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1470 
1471  /* Now that we're done, release the lock */
1473  }
1474 
1475  /* Is it SEC_BASED, or did the caller manually specify an address? */
1476  if (*BaseAddress != NULL)
1477  {
1478  /* Just align what the caller gave us */
1479  StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1480  }
1481  else if (Section->Address.StartingVpn != 0)
1482  {
1483  /* It is a SEC_BASED mapping, use the address that was generated */
1484  StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1485  }
1486  else
1487  {
1488  StartAddress = 0;
1489  }
1490 
1491  /* Insert the VAD */
1492  Status = MiInsertVadEx((PMMVAD)Vad,
1493  &StartAddress,
1494  ViewSizeInPages * PAGE_SIZE,
1496  Granularity,
1497  AllocationType);
1498  if (!NT_SUCCESS(Status))
1499  {
1500  return Status;
1501  }
1502 
1503  /* Windows stores this for accounting purposes, do so as well */
1504  if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1505 
1506  /* Finally, let the caller know where, and for what size, the view was mapped */
1507  *ViewSize = ViewSizeInPages * PAGE_SIZE;
1508  *BaseAddress = (PVOID)StartAddress;
1509  DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1510  return STATUS_SUCCESS;
1511 }
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT InheritDisposition
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:404
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:80
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
union _MMPTE::@2304 u
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
PMMPTE LastContiguousPte
Definition: mmtypes.h:764
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:760
ULONG_PTR CommitCharge
Definition: mmtypes.h:688
LONG NTSTATUS
Definition: precomp.h:26
union _MMVAD_LONG::@2567 u
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:483
#define MAXULONG_PTR
Definition: basetsd.h:103
ULONG SecNoChange
Definition: mmtypes.h:704
PCONTROL_AREA ControlArea
Definition: mmtypes.h:762
ULONG_PTR Protection
Definition: mmtypes.h:693
ULONG_PTR NoChange
Definition: mmtypes.h:690
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS NTAPI MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:548
VOID NTAPI MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:767
ASSERT(Segment->Locked)
ULONG PFN_NUMBER
Definition: ke.h:9
#define MEM_RESERVE
Definition: nt_native.h:1314
NTSTATUS Status
Definition: section.c:4842
PVOID Banked
Definition: mmtypes.h:777
return FALSE
Definition: section.c:4970
void * PVOID
Definition: retypes.h:9
#define ULL(a, b)
Definition: format_msg.c:27
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:404
ULONG FileOffset
Definition: mmtypes.h:703
#define MEM_DOS_LIM
Definition: mmtypes.h:89
Status
Definition: gdiplustypes.h:24
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
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:204
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:404
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:768
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _SUBSECTION * PSUBSECTION
#define BYTES_TO_PAGES(Size)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG AllocationType
Definition: mmfuncs.h:404
#define _64K
Definition: miarm.h:19
KGUARDED_MUTEX MmSectionCommitMutex
Definition: section.c:108
ULONG Inherit
Definition: mmtypes.h:710
ULONG_PTR Long
Definition: mmtypes.h:215
#define ALIGN_DOWN_BY(size, align)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:975
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:268
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
union _MMVAD_LONG::@2568 u2
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
unsigned int ULONG
Definition: retypes.h:1
PMMPTE FirstPrototypePte
Definition: mmtypes.h:763
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
PMMPTE SubsectionBase
Definition: mmtypes.h:578
#define MAXLONG_PTR
Definition: basetsd.h:104
union _MMVAD_LONG::@2570 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 1942 of file section.c.

1947 {
1949  NTSTATUS Status;
1951  PMEMORY_SECTION_NAME SectionName = NULL;
1953 
1956  NULL,
1957  PreviousMode,
1958  (PVOID*)(&Process),
1959  NULL);
1960 
1961  if (!NT_SUCCESS(Status))
1962  {
1963  DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1964  return Status;
1965  }
1966 
1968 
1969  if (NT_SUCCESS(Status))
1970  {
1971  SectionName = MemoryInformation;
1972  if (PreviousMode != KernelMode)
1973  {
1974  _SEH2_TRY
1975  {
1976  RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1977  (PWSTR)(SectionName + 1),
1978  MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1980 
1982 
1983  }
1985  {
1987  }
1988  _SEH2_END;
1989  }
1990  else
1991  {
1992  RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1993  (PWSTR)(SectionName + 1),
1994  MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1996 
1998 
1999  }
2000 
2002  }
2004  return Status;
2005 }
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
NTSTATUS NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName)
Definition: section.c:1881
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:158
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_SEH2_TRY
Definition: create.c:4226
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:496
NTSTATUS Status
Definition: section.c:4842
TCHAR ModuleFileName[MAX_PATH+1]
Definition: rundll32.c:55
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
UNICODE_STRING SectionFileName
Definition: mmtypes.h:323
_SEH2_END
Definition: create.c:4400
struct _MEMORY_SECTION_NAME MEMORY_SECTION_NAME
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403

Referenced by NtQueryVirtualMemory().

◆ MiRemoveFromSystemSpace()

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

Definition at line 2384 of file section.c.

2387 {
2388  ULONG Hash, Size, Count = 0;
2389  ULONG_PTR Entry;
2390  PAGED_CODE();
2391 
2392  /* Compute the hash for this entry and loop trying to find it */
2393  Entry = (ULONG_PTR)Base >> 16;
2394  Hash = Entry % Session->SystemSpaceHashKey;
2395  while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2396  {
2397  /* Check if we overflew past the end of the hash table */
2398  if (++Hash >= Session->SystemSpaceHashSize)
2399  {
2400  /* Reset the hash to zero and keep searching from the bottom */
2401  Hash = 0;
2402  if (++Count == 2)
2403  {
2404  /* But if we overflew twice, then this is not a real mapping */
2405  KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2406  (ULONG_PTR)Base,
2407  1,
2408  0,
2409  0);
2410  }
2411  }
2412  }
2413 
2414  /* One less entry */
2415  Session->SystemSpaceHashEntries--;
2416 
2417  /* Extract the size and clear the entry */
2418  Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2419  Session->SystemSpaceViewTable[Hash].Entry = 0;
2420 
2421  /* Return the control area and the size */
2422  *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2423  return Size;
2424 }
static int Hash(const char *)
Definition: reader.c:2257
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2373
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
Entry
Definition: section.c:4851
int Count
Definition: noreturn.cpp:7
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define PAGED_CODE()

Referenced by MiUnmapViewInSystemSpace().

◆ MiRemoveMappedPtes()

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

Definition at line 2282 of file section.c.

2286 {
2287  PMMPTE PointerPte, ProtoPte;//, FirstPte;
2288  PMMPDE PointerPde, SystemMapPde;
2289  PMMPFN Pfn1, Pfn2;
2290  MMPTE PteContents;
2291  KIRQL OldIrql;
2292  DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
2293 
2294  ASSERT(Ws == NULL);
2295 
2296  /* Get the PTE and loop each one */
2297  PointerPte = MiAddressToPte(BaseAddress);
2298  //FirstPte = PointerPte;
2299  while (NumberOfPtes)
2300  {
2301  /* Check if the PTE is already valid */
2302  PteContents = *PointerPte;
2303  if (PteContents.u.Hard.Valid == 1)
2304  {
2305  /* Get the PFN entry */
2306  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
2307 
2308  /* Get the PTE */
2309  PointerPde = MiPteToPde(PointerPte);
2310 
2311  /* Lock the PFN database and make sure this isn't a mapped file */
2313  ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
2314 
2315  /* Mark the page as modified accordingly */
2316  if (MI_IS_PAGE_DIRTY(&PteContents))
2317  Pfn1->u3.e1.Modified = 1;
2318 
2319  /* Was the PDE invalid */
2320  if (PointerPde->u.Long == 0)
2321  {
2322 #if (_MI_PAGING_LEVELS == 2)
2323  /* Find the system double-mapped PDE that describes this mapping */
2324  SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
2325 
2326  /* Make it valid */
2327  ASSERT(SystemMapPde->u.Hard.Valid == 1);
2328  MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
2329 #else
2330  DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
2331  ASSERT(FALSE);
2332 #endif
2333  }
2334 
2335  /* Dereference the PDE and the PTE */
2336  Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
2337  MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
2339  MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
2340 
2341  /* Release the PFN lock */
2343  }
2344  else
2345  {
2346  /* Windows ASSERT */
2347  ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
2348 
2349  /* Check if this is a prototype pointer PTE */
2350  if (PteContents.u.Soft.Prototype == 1)
2351  {
2352  /* Get the prototype PTE */
2353  ProtoPte = MiProtoPteToPte(&PteContents);
2354 
2355  /* We don't support anything else atm */
2356  ASSERT(ProtoPte->u.Long == 0);
2357  }
2358  }
2359 
2360  /* Make the PTE into a zero PTE */
2361  PointerPte->u.Long = 0;
2362 
2363  /* Move to the next PTE */
2364  PointerPte++;
2365  NumberOfPtes--;
2366  }
2367 
2368  /* Flush the TLB */
2369  KeFlushCurrentTb();
2370 
2371  /* Acquire the PFN lock */
2373 
2374  /* Decrement the accounting counters */
2375  ControlArea->NumberOfUserReferences--;
2376  ControlArea->NumberOfMappedViews--;
2377 
2378  /* Check if we should destroy the CA and release the lock */
2379  MiCheckControlArea(ControlArea, OldIrql);
2380 }
union _MMPTE::@2304 u
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
USHORT Modified
Definition: mm.h:289
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:893
union _MMPFN::@1778 u3
USHORT PrototypePte
Definition: mm.h:292
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:326
ASSERT(Segment->Locked)
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiProtoPteToPte(x)
Definition: mm.h:250
return FALSE
Definition: section.c:4970
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1001
PMMPDE MmSystemPagePtes
Definition: init.c:41
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG64 Valid
Definition: mmtypes.h:150
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:302
ULONG64 Prototype
Definition: mmtypes.h:89
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:925
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define SYSTEM_PD_SIZE
Definition: miarm.h:28
#define MiPteToPde(_Pte)
Definition: mm.h:236
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
#define NULL
Definition: types.h:112
MMPTE OriginalPte
Definition: mm.h:336
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:732
#define MI_IS_PAGE_DIRTY(x)
Definition: mm.h:112
#define ULONG_PTR
Definition: config.h:101
#define PFN_FROM_PTE(v)
Definition: mm.h:92
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:325

Referenced by MiUnmapViewInSystemSpace().

◆ MiRemoveMappedView()

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

Definition at line 784 of file section.c.

786 {
787  KIRQL OldIrql;
788  PCONTROL_AREA ControlArea;
789  PETHREAD CurrentThread = PsGetCurrentThread();
790 
791  /* Get the control area */
792  ControlArea = Vad->ControlArea;
793 
794  /* We only support non-extendable, non-image, pagefile-backed regular sections */
795  ASSERT(Vad->u.VadFlags.VadType == VadNone);
796  ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
797  ASSERT(ControlArea);
798  ASSERT(ControlArea->FilePointer == NULL);
799 
800  /* Delete the actual virtual memory pages */
801  MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
802  (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
803  Vad);
804 
805  /* Release the working set */
807 
808  /* Lock the PFN database */
810 
811  /* Remove references */
812  ControlArea->NumberOfMappedViews--;
813  ControlArea->NumberOfUserReferences--;
814 
815  /* Check if it should be destroyed */
816  MiCheckControlArea(ControlArea, OldIrql);
817 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
PFILE_OBJECT FilePointer
Definition: mmtypes.h:530
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1214
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
return FALSE
Definition: section.c:4970
ULONG CurrentProcess
Definition: shell.c:125
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ULONG NumberOfMappedViews
Definition: mmtypes.h:522
VOID NTAPI MiDeleteVirtualAddresses(IN ULONG_PTR Va, IN ULONG_PTR EndingAddress, IN PMMVAD Vad)
Definition: virtual.c:540
ULONG NumberOfUserReferences
Definition: mmtypes.h:524
#define NULL
Definition: types.h:112
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:732

Referenced by MiUnmapViewOfSection(), and MmCleanProcessAddressSpace().

◆ MiSegmentDelete()

VOID NTAPI MiSegmentDelete ( IN PSEGMENT  Segment)

Definition at line 609 of file section.c.

610 {
611  PCONTROL_AREA ControlArea;
612  SEGMENT_FLAGS SegmentFlags;
613  PSUBSECTION Subsection;
614  PMMPTE PointerPte, LastPte, PteForProto;
615  PMMPFN Pfn1;
616  PFN_NUMBER PageFrameIndex;
617  MMPTE TempPte;
618  KIRQL OldIrql;
619 
620  /* Capture data */
621  SegmentFlags = Segment->SegmentFlags;
622  ControlArea = Segment->ControlArea;
623 
624  /* Make sure control area is on the right delete path */
625  ASSERT(ControlArea->u.Flags.BeingDeleted == 1);
626  ASSERT(ControlArea->WritableUserReferences == 0);
627 
628  /* These things are not supported yet */
629  ASSERT(ControlArea->DereferenceList.Flink == NULL);
630  ASSERT(!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File));
631  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
632  ASSERT(ControlArea->u.Flags.Rom == 0);
633 
634  /* Get the subsection and PTEs for this segment */
635  Subsection = (PSUBSECTION)(ControlArea + 1);
636  PointerPte = Subsection->SubsectionBase;
637  LastPte = PointerPte + Segment->NonExtendedPtes;
638 
639  /* Lock the PFN database */
641 
642  /* Check if the master PTE is invalid */
643  PteForProto = MiAddressToPte(PointerPte);
644  if (!PteForProto->u.Hard.Valid)
645  {
646  /* Fault it in */
648  }
649 
650  /* Loop all the segment PTEs */
651  while (PointerPte < LastPte)
652  {
653  /* Check if it's time to switch master PTEs if we passed a PDE boundary */
654  if (MiIsPteOnPdeBoundary(PointerPte) &&
655  (PointerPte != Subsection->SubsectionBase))
656  {
657  /* Check if the master PTE is invalid */
658  PteForProto = MiAddressToPte(PointerPte);
659  if (!PteForProto->u.Hard.Valid)
660  {
661  /* Fault it in */
663  }
664  }
665 
666  /* This should be a prototype PTE */
667  TempPte = *PointerPte;
668  ASSERT(SegmentFlags.LargePages == 0);
669  ASSERT(TempPte.u.Hard.Valid == 0);
670 
671  /* See if we should clean things up */
672  if (!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File))
673  {
674  /*
675  * This is a section backed by the pagefile. Now that it doesn't exist anymore,
676  * we can give everything back to the system.
677  */
678  ASSERT(TempPte.u.Soft.Prototype == 0);
679 
680  if (TempPte.u.Soft.Transition == 1)
681  {
682  /* We can give the page back for other use */
683  DPRINT("Releasing page for transition PTE %p\n", PointerPte);
684  PageFrameIndex = PFN_FROM_PTE(&TempPte);
685  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
686 
687  /* As this is a paged-backed section, nobody should reference it anymore (no cache or whatever) */
688  ASSERT(Pfn1->u3.ReferenceCount == 0);
689 
690  /* And it should be in standby or modified list */
692 
693  /* Unlink it and put it back in free list */
694  MiUnlinkPageFromList(Pfn1);
695 
696  /* Temporarily mark this as active and make it free again */
698  MI_SET_PFN_DELETED(Pfn1);
699 
700  MiInsertPageInFreeList(PageFrameIndex);
701  }
702  else if (TempPte.u.Soft.PageFileHigh != 0)
703  {
704  /* Should not happen for now */
705  ASSERT(FALSE);
706  }
707  }
708  else
709  {
710  /* unsupported for now */
711  ASSERT(FALSE);
712 
713  /* File-backed section must have prototype PTEs */
714  ASSERT(TempPte.u.Soft.Prototype == 1);
715  }
716 
717  /* Zero the PTE and keep going */
718  PointerPte->u.Long = 0;
719  PointerPte++;
720  }
721 
722  /* Release the PFN lock */
724 
725  /* Free the structures */
726  ExFreePool(ControlArea);
728 }
ULONG NTAPI MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress, IN KIRQL OldIrql)
Definition: virtual.c:257
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:264
union _MMPTE::@2304 u
ULONG LargePages
Definition: mmtypes.h:400
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
USHORT ReferenceCount
Definition: mm.h:325
union _CONTROL_AREA::@2557 u
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:893
union _MMPFN::@1778 u3
USHORT PageLocation
Definition: mm.h:294
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:326
ASSERT(Segment->Locked)
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
return FALSE
Definition: section.c:4970
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
LIST_ENTRY DereferenceList
Definition: mmtypes.h:519
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
struct _SUBSECTION * PSUBSECTION
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1428
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:302
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:488
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:190
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:240
ULONG BeingDeleted
Definition: mmtypes.h:460
ULONG WritableUserReferences
Definition: mmtypes.h:534
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
#define PFN_FROM_PTE(v)
Definition: mm.h:92
PMMPTE SubsectionBase
Definition: mmtypes.h:578
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by MiCheckControlArea().

◆ MiSessionCommitPageTables()

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

Definition at line 941 of file section.c.

943 {
944  KIRQL OldIrql;
945  ULONG Color, Index;
946  PMMPDE StartPde, EndPde;
948  PMMPFN Pfn1;
949  PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
950 
951  /* Windows sanity checks */
952  ASSERT(StartVa >= (PVOID)MmSessionBase);
953  ASSERT(EndVa < (PVOID)MiSessionSpaceEnd);
954  ASSERT(PAGE_ALIGN(EndVa) == EndVa);
955 
956  /* Get the start and end PDE, then loop each one */
957  StartPde = MiAddressToPde(StartVa);
958  EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
959  Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
960  while (StartPde <= EndPde)
961  {
962 #ifndef _M_AMD64
963  /* If we don't already have a page table for it, increment count */
964  if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
965 #endif
966  /* Move to the next one */
967  StartPde++;
968  Index++;
969  }
970 
971  /* If there's no page tables to create, bail out */
972  if (PageCount == 0) return STATUS_SUCCESS;
973 
974  /* Reset the start PDE and index */
975  StartPde = MiAddressToPde(StartVa);
976  Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
977 
978  /* Loop each PDE while holding the working set lock */
979 // MiLockWorkingSet(PsGetCurrentThread(),
980 // &MmSessionSpace->GlobalVirtualAddress->Vm);
981 #ifdef _M_AMD64
982 _WARN("MiSessionCommitPageTables halfplemented for amd64")
987  DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
988  ASSERT(FALSE);
989 #else
990  while (StartPde <= EndPde)
991  {
992  /* Check if we already have a page table */
993  if (MmSessionSpace->PageTables[Index].u.Long == 0)
994  {
995  /* We don't, so the PDE shouldn't be ready yet */
996  ASSERT(StartPde->u.Hard.Valid == 0);
997 
998  /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
999  ASSERT(MmAvailablePages >= 32);
1000 
1001  /* Acquire the PFN lock and grab a zero page */
1004  MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
1006  PageFrameNumber = MiRemoveZeroPage(Color);
1007  TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
1008  MI_WRITE_VALID_PDE(StartPde, TempPde);
1009 
1010  /* Write the page table in session space structure */
1013 
1014  /* Initialize the PFN */
1015  MiInitializePfnForOtherProcess(PageFrameNumber,
1016  StartPde,
1018 
1019  /* And now release the lock */
1021 
1022  /* Get the PFN entry and make sure there's no event for it */
1023  Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1024  ASSERT(Pfn1->u1.Event == NULL);
1025 
1026  /* Increment the number of pages */
1027  ActualPages++;
1028  }
1029 
1030  /* Move to the next PDE */
1031  StartPde++;
1032  Index++;
1033  }
1034 #endif
1035 
1036  /* Make sure we didn't do more pages than expected */
1037  ASSERT(ActualPages <= PageCount);
1038 
1039  /* Release the working set lock */
1040 // MiUnlockWorkingSet(PsGetCurrentThread(),
1041 // &MmSessionSpace->GlobalVirtualAddress->Vm);
1042 
1043 
1044  /* If we did at least one page... */
1045  if (ActualPages)
1046  {
1047  /* Update the performance counters! */
1050  }
1051 
1052  /* Return status */
1053  return STATUS_SUCCESS;
1054 }
SIZE_T NonPageablePages
Definition: miarm.h:487
#define MiAddressToPde(x)
Definition: mmx86.c:20
union _MMPTE::@2304 u
PMMPDE PageTables
Definition: miarm.h:513
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1280
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:893
struct Color Color
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID MmSessionBase
Definition: init.c:33
ASSERT(Segment->Locked)
ULONG PFN_NUMBER
Definition: ke.h:9
#define _WARN(msg)
Definition: debug.h:263
#define MI_SET_PROCESS2(x)
Definition: mm.h:251
#define PsGetCurrentProcess
Definition: psfuncs.h:17
ULONG MmSecondaryColorMask
Definition: mminit.c:257
return FALSE
Definition: section.c:4970
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1001
#define MI_SET_USAGE(x)
Definition: mm.h:250
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
ULONG PageFrameNumber
Definition: mmtypes.h:74
SIZE_T CommittedPages
Definition: miarm.h:488
_In_ WDFCOLLECTION _In_ ULONG Index
ULONG64 Valid
Definition: mmtypes.h:150
PVOID MiSessionSpaceEnd
Definition: init.c:27
#define PAGE_ALIGN(Va)
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1428
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:302
MMPTE ValidKernelPdeLocal
Definition: init.c:32
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:486

Referenced by MiMapViewInSystemSpace().

◆ MiSetControlAreaSymbolsLoaded()

VOID NTAPI MiSetControlAreaSymbolsLoaded ( IN PCONTROL_AREA  ControlArea)

Definition at line 1169 of file section.c.

1170 {
1171  KIRQL OldIrql;
1172 
1174 
1176  ControlArea->u.Flags.DebugSymbolsLoaded |= 1;
1177 
1178  ASSERT(OldIrql <= APC_LEVEL);
1181 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:886
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:893
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define APC_LEVEL
Definition: env_spec_w32.h:695

◆ MiSetProtectionOnSection()

NTSTATUS NTAPI MiSetProtectionOnSection ( IN PEPROCESS  Process,
IN PMMVAD  FoundVad,
IN PVOID  StartingAddress,
IN PVOID  EndingAddress,
IN ULONG  NewProtect,
OUT PULONG  CapturedOldProtect,
IN ULONG  DontCharge,
OUT PULONG  Locked 
)

Definition at line 2113 of file section.c.

2121 {
2122  PMMPTE PointerPte, LastPte;
2123  MMPTE TempPte, PteContents;
2124  PMMPDE PointerPde;
2125  PMMPFN Pfn1;
2126  ULONG ProtectionMask, QuotaCharge = 0;
2128  PAGED_CODE();
2129 
2130  //
2131  // Tell caller nothing is being locked
2132  //
2133  *Locked = FALSE;
2134 
2135  //
2136  // This function should only be used for section VADs. Windows ASSERT */
2137  //
2138  ASSERT(FoundVad->u.VadFlags.PrivateMemory == 0);
2139 
2140  //
2141  // We don't support these features in ARM3
2142  //
2143  ASSERT(FoundVad->u.VadFlags.VadType != VadImageMap);
2144  ASSERT(FoundVad->u2.VadFlags2.CopyOnWrite == 0);
2145 
2146  //
2147  // Convert and validate the protection mask
2148  //
2149  ProtectionMask = MiMakeProtectionMask(NewProtect);
2150  if (ProtectionMask == MM_INVALID_PROTECTION)
2151  {
2152  DPRINT1("Invalid section protect\n");
2154  }
2155 
2156  //
2157  // Get the PTE and PDE for the address, as well as the final PTE
2158  //
2160  PointerPde = MiAddressToPde(StartingAddress);
2161  PointerPte = MiAddressToPte(StartingAddress);
2162  LastPte = MiAddressToPte(EndingAddress);
2163 
2164  //
2165  // Make the PDE valid, and check the status of the first PTE
2166  //
2168  if (PointerPte->u.Long)
2169  {
2170  //
2171  // Not supported in ARM3
2172  //
2173  ASSERT(FoundVad->u.VadFlags.VadType != VadRotatePhysical);
2174 
2175  //
2176  // Capture the page protection and make the PDE valid
2177  //
2178  *CapturedOldProtect = MiGetPageProtection(PointerPte);
2180  }
2181  else
2182  {
2183  //
2184  // Only pagefile-backed section VADs are supported for now
2185  //
2186  ASSERT(FoundVad->u.VadFlags.VadType != VadImageMap);
2187 
2188  //
2189  // Grab the old protection from the VAD itself
2190  //
2191  *CapturedOldProtect = MmProtectToValue[FoundVad->u.VadFlags.Protection];
2192  }
2193 
2194  //
2195  // Loop all the PTEs now
2196  //
2198  while (PointerPte <= LastPte)
2199  {
2200  //
2201  // Check if we've crossed a PDE boundary and make the new PDE valid too
2202  //
2203  if (MiIsPteOnPdeBoundary(PointerPte))
2204  {
2205  PointerPde = MiPteToPde(PointerPte);
2207  }
2208 
2209  //
2210  // Capture the PTE and see what we're dealing with
2211  //
2212  PteContents = *PointerPte;
2213  if (PteContents.u.Long == 0)
2214  {
2215  //
2216  // This used to be a zero PTE and it no longer is, so we must add a
2217  // reference to the pagetable.
2218  //
2220 
2221  //
2222  // Create the demand-zero prototype PTE
2223  //
2225  TempPte.u.Soft.Protection = ProtectionMask;
2226  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2227  }
2228  else if (PteContents.u.Hard.Valid == 1)
2229  {
2230  //
2231  // Get the PFN entry
2232  //
2233  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
2234 
2235  //
2236  // We don't support these yet
2237  //
2238  ASSERT((NewProtect & (PAGE_NOACCESS | PAGE_GUARD)) == 0);
2239  ASSERT(Pfn1->u3.e1.PrototypePte == 0);
2240 
2241  //
2242  // Write the protection mask and write it with a TLB flush
2243  //
2244  Pfn1->OriginalPte.u.Soft.Protection = ProtectionMask;
2245  MiFlushTbAndCapture(FoundVad,
2246  PointerPte,
2247  ProtectionMask,
2248  Pfn1,
2249  TRUE);
2250  }
2251  else
2252  {
2253  //
2254  // We don't support these cases yet
2255  //
2256  ASSERT(PteContents.u.Soft.Prototype == 0);
2257  ASSERT(PteContents.u.Soft.Transition == 0);
2258 
2259  //
2260  // The PTE is already demand-zero, just update the protection mask
2261  //
2262  PointerPte->u.Soft.Protection = ProtectionMask;
2263  }
2264 
2265  PointerPte++;
2266  }
2267 
2268  //
2269  // Unlock the working set and update quota charges if needed, then return
2270  //
2272  if ((QuotaCharge > 0) && (!DontCharge))
2273  {
2274  FoundVad->u.VadFlags.CommitCharge -= QuotaCharge;
2275  Process->CommitCharge -= QuotaCharge;
2276  }
2277  return STATUS_SUCCESS;
2278 }
#define MM_INVALID_PROTECTION
Definition: miarm.h:63
MMPTE PrototypePte
Definition: init.c:40
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1214
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
union _MMPTE::@2304 u
#define TRUE
Definition: types.h:120
#define PAGE_GUARD
Definition: nt_native.h:1310
union _MMPFN::@1778 u3
USHORT PrototypePte
Definition: mm.h:292
MMPFNENTRY e1
Definition: mm.h:326
ASSERT(Segment->Locked)
#define MiAddressToPte(x)
Definition: mmx86.c:19
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:217
#define PAGE_NOACCESS
Definition: nt_native.h:1302
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2407
return FALSE
Definition: section.c:4970
ULONG64 Protection
Definition: mmtypes.h:88
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1144
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:158
ULONG64 Valid
Definition: mmtypes.h:150
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define MM_NOIRQL
Definition: miarm.h:232
Definition: mm.h:302
ULONG64 Prototype
Definition: mmtypes.h:89
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
const ULONG MmProtectToValue[32]
Definition: page.c:81
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:925
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MiPteToPde(_Pte)
Definition: mm.h:236
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:975
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:240
ULONG64 Transition
Definition: mmtypes.h:90
ULONG NTAPI MiGetPageProtection(IN PMMPTE PointerPte)
Definition: virtual.c:1365
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE OriginalPte
Definition: mm.h:336
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
FORCEINLINE VOID MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:1672
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI MiFlushTbAndCapture(IN PMMVAD FoundVad, IN PMMPTE PointerPte, IN ULONG ProtectionMask, IN PMMPFN Pfn1, IN BOOLEAN UpdateDirty)
Definition: section.c:2009
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define PAGED_CODE()

◆ MiSubsectionConsistent()

VOID NTAPI MiSubsectionConsistent ( IN PSUBSECTION  Subsection)

Definition at line 1515 of file section.c.

1516 {
1517  /* ReactOS only supports systems with 4K pages and 4K sectors */
1518  ASSERT(Subsection->u.SubsectionFlags.SectorEndOffset == 0);
1519 
1520  /* Therefore, then number of PTEs should be equal to the number of sectors */
1521  if (Subsection->NumberOfFullSectors != Subsection->PtesInSubsection)
1522  {
1523  /* Break and warn if this is inconsistent */
1524  DPRINT1("Mm: Subsection inconsistent (%x vs %x)\n",
1525  Subsection->NumberOfFullSectors, Subsection->PtesInSubsection);
1526  DbgBreakPoint();
1527  }
1528 }
void DbgBreakPoint()
Definition: mach.c:553
ASSERT(Segment->Locked)
#define DPRINT1
Definition: precomp.h:8

◆ MiUnmapViewInSystemSpace()

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

Definition at line 2428 of file section.c.

2430 {
2431  ULONG Size;
2432  PCONTROL_AREA ControlArea;
2433  PAGED_CODE();
2434 
2435  /* Remove this mapping */
2436  KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2437  Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2438 
2439  /* Clear the bits for this mapping */
2440  RtlClearBits(Session->SystemSpaceBitMap,
2441  (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2442  Size);
2443 
2444  /* Convert the size from a bit size into the actual size */
2445  Size = Size * (_64K >> PAGE_SHIFT);
2446 
2447  /* Remove the PTEs now */
2448  MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2449  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2450 
2451  /* Return success */
2452  return STATUS_SUCCESS;
2453 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
VOID NTAPI MiRemoveMappedPtes(IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
Definition: section.c:2282
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG NTAPI MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2384
#define _64K
Definition: miarm.h:19
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define PAGED_CODE()

Referenced by MmUnmapViewInSessionSpace(), and MmUnmapViewInSystemSpace().

◆ MiUnmapViewOfSection()

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

Definition at line 821 of file section.c.

824 {
828  PMMVAD Vad;
829  PVOID DbgBase = NULL;
832  PETHREAD CurrentThread = PsGetCurrentThread();
834  PAGED_CODE();
835 
836  /* Check if we need to lock the address space */
837  if (!Flags) MmLockAddressSpace(&Process->Vm);
838 
839  /* Check for Mm Region */
842  {
843  /* Call Mm API */
845  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
846  return Status;
847  }
848 
849  /* Check if we should attach to the process */
850  if (CurrentProcess != Process)
851  {
852  /* The process is different, do an attach */
854  Attached = TRUE;
855  }
856 
857  /* Check if the process is already dead */
858  if (Process->VmDeleted)
859  {
860  /* Fail the call */
861  DPRINT1("Process died!\n");
862  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
864  goto Quickie;
865  }
866 
867  /* Find the VAD for the address and make sure it's a section VAD */
869  if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
870  {
871  /* Couldn't find it, or invalid VAD, fail */
872  DPRINT1("No VAD or invalid VAD\n");
873  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
875  goto Quickie;
876  }
877 
878  /* We should be attached */
880 
881  /* We need the base address for the debugger message on image-backed VADs */
882  if (Vad->u.VadFlags.VadType == VadImageMap)
883  {
884  DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
885  }
886 
887  /* Compute the size of the VAD region */
888  RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
889 
890  /* For SEC_NO_CHANGE sections, we need some extra checks */
891  if (Vad->u.VadFlags.NoChange == 1)
892  {
893  /* Are we allowed to mess with this VAD? */
895  (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
896  RegionSize,
898  if (!NT_SUCCESS(Status))
899  {
900  /* We failed */
901  DPRINT1("Trying to unmap protected VAD!\n");
902  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
903  goto Quickie;
904  }
905  }
906 
907  /* Not currently supported */
909 
910  /* FIXME: Remove VAD charges */
911 
912  /* Lock the working set */
913  MiLockProcessWorkingSetUnsafe(Process, CurrentThread);
914 
915  /* Remove the VAD */
916  ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
917  MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
918 
919  /* Remove the PTEs for this view, which also releases the working set lock */
921 
922  /* FIXME: Remove commitment */
923 
924  /* Update performance counter and release the lock */
925  Process->VirtualSize -= RegionSize;
926  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
927 
928  /* Destroy the VAD and return success */
929  ExFreePool(Vad);
931 
932  /* Failure and success case -- send debugger message, detach, and return */
933 Quickie:
934  if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
936  return Status;
937 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
KAPC_STATE
Definition: ketypes.h:1280
ULONG Type
Definition: mm.h:219
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define TRUE
Definition: types.h:120
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1526
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:784
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
ULONG_PTR NoChange
Definition: mmtypes.h:690
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:731
#define MM_DELETE_CHECK
Definition: miarm.h:262
ULONG_PTR EndingVpn
Definition: mmtypes.h:727
ASSERT(Segment->Locked)
static BOOL Attached
Definition: vidbios.c:3905
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:75
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
NTSTATUS NTAPI MiRosUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
Definition: section.c:3514
NTSTATUS Status
Definition: section.c:4842
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:48
return FALSE
Definition: section.c:4970
void * PVOID
Definition: retypes.h:9
ULONG_PTR StartingVpn
Definition: mmtypes.h:726
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI MiCheckSecuredVad(IN PMMVAD Vad, IN PVOID Base, IN SIZE_T Size, IN ULONG ProtectionMask)
Definition: vadnode.c:815
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1144
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG CurrentProcess
Definition: shell.c:125
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ULONG_PTR PrivateMemory
Definition: mmtypes.h:695
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:360
ULONG_PTR SIZE_T
Definition: typedefs.h:80
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
union _MMVAD::@2564 u
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1587
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:47
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1519
ULONG_PTR VadType
Definition: mmtypes.h:691
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PAGED_CODE()

Referenced by MmUnmapViewOfSection(), and NtUnmapViewOfSection().

◆ MmCommitSessionMappedView()

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

Definition at line 3142 of file section.c.

3144 {
3145  ULONG_PTR StartAddress, EndingAddress, Base;
3146  ULONG Hash, Count = 0, Size, QuotaCharge;
3147  PMMSESSION Session;
3148  PMMPTE LastProtoPte, PointerPte, ProtoPte;
3149  PCONTROL_AREA ControlArea;
3150  PSEGMENT Segment;
3151  PSUBSECTION Subsection;
3152  MMPTE TempPte;
3153  PAGED_CODE();
3154 
3155  /* Make sure the base isn't past the session view range */
3156  if ((MappedBase < MiSessionViewStart) ||
3158  {
3159  DPRINT1("Base outside of valid range\n");
3161  }
3162 
3163  /* Make sure the size isn't past the session view range */
3166  {
3167  DPRINT1("Size outside of valid range\n");
3169  }
3170 
3171  /* Sanity check */
3172  ASSERT(ViewSize != 0);
3173 
3174  /* Process must be in a session */
3175  if (PsGetCurrentProcess()->ProcessInSession == FALSE)
3176  {
3177  DPRINT1("Process is not in session\n");
3178  return STATUS_NOT_MAPPED_VIEW;
3179  }
3180 
3181  /* Compute the correctly aligned base and end addresses */
3182  StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
3183  EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
3184 
3185  /* Sanity check and grab the session */
3187  Session = &MmSessionSpace->Session;
3188 
3189  /* Get the hash entry for this allocation */
3190  Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
3191 
3192  /* Lock system space */
3194 
3195  /* Loop twice so we can try rolling over if needed */
3196  while (TRUE)
3197  {
3198  /* Extract the size and base addresses from the entry */
3199  Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
3200  Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
3201 
3202  /* Convert the size to bucket chunks */
3204 
3205  /* Bail out if this entry fits in here */
3206  if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
3207 
3208  /* Check if we overflew past the end of the hash table */
3209  if (++Hash >= Session->SystemSpaceHashSize)
3210  {
3211  /* Reset the hash to zero and keep searching from the bottom */
3212  Hash = 0;
3213  if (++Count == 2)
3214  {
3215  /* But if we overflew twice, then this is not a real mapping */
3216  KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
3217  Base,
3218  2,
3219  0,
3220  0);
3221  }
3222  }
3223  }
3224 
3225  /* Make sure the view being mapped is not file-based */
3226  ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
3227  if (ControlArea->FilePointer != NULL)
3228  {
3229  /* It is, so we have to bail out */
3230  DPRINT1("Only page-filed backed sections can be commited\n");
3232  return STATUS_ALREADY_COMMITTED;
3233  }
3234 
3235  /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
3236  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
3237  ASSERT(ControlArea->u.Flags.Rom == 0);
3238  Subsection = (PSUBSECTION)(ControlArea + 1);
3239 
3240  /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
3241  ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
3242  QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
3243  LastProtoPte = ProtoPte + QuotaCharge;
3244  if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
3245  {
3246  DPRINT1("PTE is out of bounds\n");
3249  }
3250 
3251  /* Acquire the commit lock and count all the non-committed PTEs */
3253  PointerPte = ProtoPte;
3254  while (PointerPte < LastProtoPte)
3255  {
3256  if (PointerPte->u.Long) QuotaCharge--;
3257  PointerPte++;
3258  }
3259 
3260  /* Was everything committed already? */
3261  if (!QuotaCharge)
3262  {
3263  /* Nothing to do! */
3266  return STATUS_SUCCESS;
3267  }
3268 
3269  /* Pick the segment and template PTE */
3270  Segment = ControlArea->Segment;
3271  TempPte = Segment->SegmentPteTemplate;
3272  ASSERT(TempPte.u.Long != 0);
3273 
3274  /* Loop all prototype PTEs to be committed */
3275  PointerPte = ProtoPte;
3276  while (PointerPte < LastProtoPte)
3277  {
3278  /* Make sure the PTE is already invalid */
3279  if (PointerPte->u.Long == 0)
3280  {
3281  /* And write the invalid PTE */
3282  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
3283  }
3284 
3285  /* Move to the next PTE */
3286  PointerPte++;
3287  }
3288 
3289  /* Check if we had at least one page charged */
3290  if (QuotaCharge)
3291  {
3292  /* Update the accounting data */
3293  Segment->NumberOfCommittedPages += QuotaCharge;
3295  }
3296 
3297  /* Release all */
3300  return STATUS_SUCCESS;
3301 }
static int Hash(const char *)
Definition: reader.c:2257
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
PFILE_OBJECT FilePointer
Definition: mmtypes.h:530
union _MMPTE::@2304 u
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define TRUE
Definition: types.h:120
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2373
SIZE_T MmSharedCommit
Definition: freelist.c:31
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
union _CONTROL_AREA::@2557 u
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:270
ASSERT(Segment->Locked)
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG MmSessionViewSize
Definition: init.c:35
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
return FALSE
Definition: section.c:4970
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:459
ULONG SystemSpaceHashKey
Definition: miarm.h:462
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
int Count
Definition: noreturn.cpp:7
MMSESSION Session
Definition: miarm.h:503
#define PAGE_ALIGN(Va)
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
struct _SUBSECTION * PSUBSECTION
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
VOID FASTCALL KeReleaseGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:75
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:457
PCONTROL_AREA ControlArea
Definition: miarm.h:451
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:488
#define PAGE_SIZE
Definition: env_spec_w32.h:49
KGUARDED_MUTEX MmSectionCommitMutex
Definition: section.c:108
ULONG_PTR Long
Definition: mmtypes.h:215
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:975
PVOID MiSessionViewStart
Definition: init.c:30
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:267
PSEGMENT Segment
Definition: mmtypes.h:518
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
VOID FASTCALL KeAcquireGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:64
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:262
#define ULONG_PTR
Definition: config.h:101
ULONG_PTR Entry
Definition: miarm.h:450
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG SystemSpaceHashSize
Definition: miarm.h:460
PMMPTE SubsectionBase
Definition: mmtypes.h:578
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define PAGED_CODE()
ULONG PtesInSubsection
Definition: mmtypes.h:580

◆ 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 2462 of file section.c.

2470 {
2471  SECTION Section;
2472  PSECTION NewSection;
2473  PSUBSECTION Subsection;
2474  PSEGMENT NewSegment, Segment;
2475  NTSTATUS Status;
2476  PCONTROL_AREA ControlArea;
2477  ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2479  BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2480  KIRQL OldIrql;
2482  BOOLEAN UserRefIncremented = FALSE;
2483  PVOID PreviousSectionPointer;
2484 
2485  /* Make the same sanity checks that the Nt interface should've validated */
2488  SEC_NO_CHANGE)) == 0);
2492  SEC_NOCACHE | SEC_NO_CHANGE))));
2498 
2499  /* Convert section flag to page flag */
2501 
2502  /* Check to make sure the protection is correct. Nt* does this already */
2503  ProtectionMask = MiMakeProtectionMask(SectionPageProtection);
2504  if (ProtectionMask == MM_INVALID_PROTECTION) return STATUS_INVALID_PAGE_PROTECTION;
2505 
2506  /* Check if this is going to be a data or image backed file section */
2507  if ((FileHandle) || (FileObject))
2508  {
2509  /* These cannot be mapped with large pages */
2511 
2512  /* For now, only support the mechanism through a file handle */
2513  ASSERT(FileObject == NULL);
2514 
2515  /* Reference the file handle to get the object */
2517  MmMakeFileAccess[ProtectionMask],
2519  PreviousMode,
2520  (PVOID*)&File,
2521  NULL);
2522  if (!NT_SUCCESS(Status)) return Status;
2523 
2524  /* Make sure Cc has been doing its job */
2525  if (!File->SectionObjectPointer)
2526  {
2527  /* This is not a valid file system-based file, fail */
2530  }
2531 
2532  /* Image-file backed sections are not yet supported */
2534 
2535  /* Compute the size of the control area, and allocate it */
2536  ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2537  ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2538  if (!ControlArea)
2539  {
2542  }
2543 
2544  /* Zero it out */
2545  RtlZeroMemory(ControlArea, ControlAreaSize);
2546 
2547  /* Did we get a handle, or an object? */
2548  if (FileHandle)
2549  {
2550  /* We got a file handle so we have to lock down the file */
2551 #if 0
2553  if (!NT_SUCCESS(Status))
2554  {
2555  ExFreePool(ControlArea);
2557  return Status;
2558  }
2559 #else
2560  /* ReactOS doesn't support this API yet, so do nothing */
2562 #endif
2563  /* Update the top-level IRP so that drivers know what's happening */
2565  FileLock = TRUE;
2566  }
2567 
2568  /* Lock the PFN database while we play with the section pointers */
2570 
2571  /* Image-file backed sections are not yet supported */
2573 
2574  /* There should not already be a control area for this file */
2575  ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2576  NewSegment = NULL;
2577 
2578  /* Write down that this CA is being created, and set it */
2579  ControlArea->u.Flags.BeingCreated = TRUE;
2581  PreviousSectionPointer = File->SectionObjectPointer;
2582  File->SectionObjectPointer->DataSectionObject = ControlArea;
2583 
2584  /* We can release the PFN lock now */
2586 
2587  /* We don't support previously-mapped file */
2588  ASSERT(NewSegment == NULL);
2589 
2590  /* Image-file backed sections are not yet supported */
2592 
2593  /* So we always create a data file map */
2595  &Segment,
2596  (PSIZE_T)InputMaximumSize,
2599  KernelCall);
2600  if (!NT_SUCCESS(Status))
2601  {
2602  /* Lock the PFN database while we play with the section pointers */
2604 
2605  /* Reset the waiting-for-deletion event */
2606  ASSERT(ControlArea->WaitingForDeletion == NULL);
2607  ControlArea->WaitingForDeletion = NULL;
2608 
2609  /* Set the file pointer NULL flag */
2610  ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2611  ControlArea->u.Flags.FilePointerNull = TRUE;
2612 
2613  /* Delete the data section object */
2615  File->SectionObjectPointer->DataSectionObject = NULL;
2616 
2617  /* No longer being created */
2618  ControlArea->u.Flags.BeingCreated = FALSE;
2619 
2620  /* We can release the PFN lock now */
2622 
2623  /* Check if we locked and set the IRP */
2624  if (FileLock)
2625  {
2626  /* Undo */
2628  //FsRtlReleaseFile(File);
2629  }
2630 
2631  /* Free the control area and de-ref the file object */
2632  ExFreePool(ControlArea);
2634 
2635  /* All done */
2636  return Status;
2637  }
2638 
2639  /* On success, we expect this */
2640  ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2641 
2642  /* Check if a maximum size was specified */
2643  if (!InputMaximumSize->QuadPart)
2644  {
2645  /* Nope, use the segment size */
2646  Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2647  }
2648  else
2649  {
2650  /* Yep, use the entered size */
2651  Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2652  }
2653  }
2654  else
2655  {
2656  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2658 
2659  /* Not yet supported */
2661 
2662  /* So this must be a pagefile-backed section, create the mappings needed */
2663  Status = MiCreatePagingFileMap(&NewSegment,
2664  InputMaximumSize,
2665  ProtectionMask,
2667  if (!NT_SUCCESS(Status)) return Status;
2668 
2669  /* Set the size here, and read the control area */
2670  Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2671  ControlArea = NewSegment->ControlArea;
2672 
2673  /* MiCreatePagingFileMap increments user references */
2674  UserRefIncremented = TRUE;
2675  }
2676 
2677  /* Did we already have a segment? */
2678  if (!NewSegment)
2679  {
2680  /* This must be the file path and we created a segment */
2681  NewSegment = Segment;
2682  ASSERT(File != NULL);
2683 
2684  /* Acquire the PFN lock while we set control area flags */
2686 
2687  /* We don't support this race condition yet, so assume no waiters */
2688  ASSERT(ControlArea->WaitingForDeletion == NULL);
2689  ControlArea->WaitingForDeletion = NULL;
2690 
2691  /* Image-file backed sections are not yet supported, nor ROM images */
2693  ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2694 
2695  /* Take off the being created flag, and then release the lock */
2696  ControlArea->u.Flags.BeingCreated = FALSE;
2698  }
2699 
2700  /* Check if we locked the file earlier */
2701  if (FileLock)
2702  {
2703  /* Reset the top-level IRP and release the lock */
2705  //FsRtlReleaseFile(File);
2706  FileLock = FALSE;
2707  }
2708 
2709  /* Set the initial section object data */
2710  Section.InitialPageProtection = SectionPageProtection;
2711 
2712  /* The mapping created a control area and segment, save the flags */
2713  Section.Segment = NewSegment;
2714  Section.u.LongFlags = ControlArea->u.LongFlags;
2715 
2716  /* Check if this is a user-mode read-write non-image file mapping */
2717  if (!(FileObject) &&
2719  !(ControlArea->u.Flags.Image) &&
2720  (ControlArea->FilePointer))
2721  {
2722  /* Add a reference and set the flag */
2723  Section.u.Flags.UserWritable = TRUE;
2724  InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2725  }
2726 
2727  /* Check for image mappings or page file mappings */
2728  if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2729  {
2730  /* Charge the segment size, and allocate a subsection */
2731  PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2732  Size = sizeof(SUBSECTION);
2733  }
2734  else
2735  {
2736  /* Charge nothing, and allocate a mapped subsection */
2737  PagedCharge = 0;
2738  Size = sizeof(MSUBSECTION);
2739  }
2740 
2741  /* Check if this is a normal CA */
2742  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2743  ASSERT(ControlArea->u.Flags.Rom == 0);
2744 
2745  /* Charge only a CA, and the subsection is right after */
2746  NonPagedCharge = sizeof(CONTROL_AREA);
2747  Subsection = (PSUBSECTION)(ControlArea + 1);
2748 
2749  /* We only support single-subsection mappings */
2750  NonPagedCharge += Size;
2751  ASSERT(Subsection->NextSubsection == NULL);
2752 
2753  /* Create the actual section object, with enough space for the prototype PTEs */
2757  PreviousMode,
2758  NULL,
2759  sizeof(SECTION),
2760  PagedCharge,
2761  NonPagedCharge,
2762  (PVOID*)&NewSection);
2763  if (!NT_SUCCESS(Status))
2764  {
2765  /* Check if this is a user-mode read-write non-image file mapping */
2766  if (!(FileObject) &&
2768  !(ControlArea->u.Flags.Image) &&
2769  (ControlArea->FilePointer))
2770  {
2771  /* Remove a reference and check the flag */
2772  ASSERT(Section.u.Flags.UserWritable == 1);
2773  InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2774  }
2775 
2776  /* Check if a user reference was added */
2777  if (UserRefIncremented)
2778  {
2779  /* Acquire the PFN lock while we change counters */
2781 
2782  /* Decrement the accounting counters */
2783  ControlArea->NumberOfSectionReferences--;
2784  ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2785  ControlArea->NumberOfUserReferences--;
2786 
2787  /* Check if we should destroy the CA and release the lock */
2788  MiCheckControlArea(ControlArea, OldIrql);
2789  }
2790 
2791  /* Return the failure code */
2792  return Status;
2793  }
2794 
2795  /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2796 
2797  /* Now copy the local section object from the stack into this new object */
2798  RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2799  NewSection->Address.StartingVpn = 0;
2800 
2801  /* For now, only user calls are supported */
2802  ASSERT(KernelCall == FALSE);
2803  NewSection->u.Flags.UserReference = TRUE;
2804 
2805  /* Is this a "based" allocation, in which all mappings are identical? */
2807  {
2808  /* Lock the VAD tree during the search */
2810 
2811  /* Is it a brand new ControArea ? */
2812  if (ControlArea->u.Flags.BeingCreated == 1)
2813  {
2814  ASSERT(ControlArea->u.Flags.Based == 1);
2815  /* Then we must find a global address, top-down */
2818  _64K,
2820  (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2821 
2822  if (!NT_SUCCESS(Status))
2823  {
2824  /* No way to find a valid range. */
2826  ControlArea->u.Flags.Based = 0;
2827  NewSection->u.Flags.Based = 0;
2828  ObDereferenceObject(NewSection);
2829  return Status;
2830  }
2831 
2832  /* Compute the ending address and insert it into the VAD tree */
2833  NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2834  NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2835  MiInsertBasedSection(NewSection);
2836  }
2837  else
2838  {
2839  /* 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 !*/
2840  ASSERT(FALSE);
2841  }
2842 
2844  }
2845 
2846  /* The control area is not being created anymore */
2847  if (ControlArea->u.Flags.BeingCreated == 1)
2848  {
2849  /* Acquire the PFN lock while we set control area flags */
2851 
2852  /* Take off the being created flag, and then release the lock */
2853  ControlArea->u.Flags.BeingCreated = 0;
2854  NewSection->u.Flags.BeingCreated = 0;
2855 
2857  }
2858 
2859  /* Migrate the attribute into a flag */
2860  if (AllocationAttributes & SEC_NO_CHANGE) NewSection->u.Flags.NoChange = TRUE;
2861 
2862  /* If R/W access is not requested, this might eventually become a CoW mapping */
2864  {
2865  NewSection->u.Flags.CopyOnWrite = TRUE;
2866  }
2867 
2868  /* Write down if this was a kernel call */
2869  ControlArea->u.Flags.WasPurged |= KernelCall;
2870  ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2871 
2872  /* Make sure the segment and the section are the same size, or the section is smaller */
2873  ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2874 
2875  /* Return the object and the creation status */
2876  *SectionObject = (PVOID)NewSection;
2877  return Status;
2878 }
ULONG NoChange
Definition: mmtypes.h:483
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define PAGE_NOCACHE
Definition: nt_native.h:1311
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define MM_INVALID_PROTECTION
Definition: miarm.h:63
PEVENT_COUNTER WaitingForDeletion
Definition: mmtypes.h:531
PFILE_OBJECT FilePointer
Definition: mmtypes.h:530