ReactOS  0.4.14-dev-41-g31d7680
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)
 
NTSTATUS NTAPI MiAddMappedPtes (IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea)
 
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 NTAPI MiMapViewInSystemSpace (IN PVOID Section, IN PMMSESSION Session, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
 
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)
 
NTSTATUS NTAPI MiCreatePagingFileMap (OUT PSEGMENT *Segment, IN PSIZE_T 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()

NTSTATUS NTAPI MiAddMappedPtes ( IN PMMPTE  FirstPte,
IN PFN_NUMBER  PteCount,
IN PCONTROL_AREA  ControlArea 
)

Definition at line 417 of file section.c.

420 {
421  MMPTE TempPte;
422  PMMPTE PointerPte, ProtoPte, LastProtoPte, LastPte;
423  PSUBSECTION Subsection;
424 
425  /* ARM3 doesn't support this yet */
426  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
427  ASSERT(ControlArea->u.Flags.Rom == 0);
428  ASSERT(ControlArea->FilePointer == NULL);
429 
430  /* Sanity checks */
431  ASSERT(PteCount != 0);
432  ASSERT(ControlArea->NumberOfMappedViews >= 1);
433  ASSERT(ControlArea->NumberOfUserReferences >= 1);
434  ASSERT(ControlArea->NumberOfSectionReferences != 0);
435  ASSERT(ControlArea->u.Flags.BeingCreated == 0);
436  ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
437  ASSERT(ControlArea->u.Flags.BeingPurged == 0);
438 
439  /* Get the PTEs for the actual mapping */
440  PointerPte = FirstPte;
441  LastPte = FirstPte + PteCount;
442 
443  /* Get the prototype PTEs that desribe the section mapping in the subsection */
444  Subsection = (PSUBSECTION)(ControlArea + 1);
445  ProtoPte = Subsection->SubsectionBase;
446  LastProtoPte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
447 
448  /* Loop the PTEs for the mapping */
449  while (PointerPte < LastPte)
450  {
451  /* We may have run out of prototype PTEs in this subsection */
452  if (ProtoPte >= LastProtoPte)
453  {
454  /* But we don't handle this yet */
455  ASSERT(FALSE);
456  }
457 
458  /* The PTE should be completely clear */
459  ASSERT(PointerPte->u.Long == 0);
460 
461  /* Build the prototype PTE and write it */
462  MI_MAKE_PROTOTYPE_PTE(&TempPte, ProtoPte);
463  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
464 
465  /* Keep going */
466  PointerPte++;
467  ProtoPte++;
468  }
469 
470  /* No failure path */
471  return STATUS_SUCCESS;
472 }
union _MMPTE::@2236 u
smooth NULL
Definition: ftsmooth.c:416
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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:980
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, IN PMMPTE PointerPte)
Definition: mm.h:272
return STATUS_SUCCESS
Definition: btrfs.c:2966
PMMPTE SubsectionBase
Definition: mmtypes.h:570
ULONG PtesInSubsection
Definition: mmtypes.h:572

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:71
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:291
#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 728 of file section.c.

730 {
731  BOOLEAN DeleteSegment = FALSE;
733 
734  /* Check if this is the last reference or view */
735  if (!(ControlArea->NumberOfMappedViews) &&
736  !(ControlArea->NumberOfSectionReferences))
737  {
738  /* There should be no more user references either */
739  ASSERT(ControlArea->NumberOfUserReferences == 0);
740 
741  /* Not yet supported */
742  ASSERT(ControlArea->FilePointer == NULL);
743 
744  /* The control area is being destroyed */
745  ControlArea->u.Flags.BeingDeleted = TRUE;
746  DeleteSegment = TRUE;
747  }
748 
749  /* Release the PFN lock */
751 
752  /* Delete the segment if needed */
753  if (DeleteSegment)
754  {
755  /* No more user write references at all */
756  ASSERT(ControlArea->WritableUserReferences == 0);
757  MiSegmentDelete(ControlArea->Segment);
758  }
759 }
#define TRUE
Definition: types.h:120
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI MiSegmentDelete(IN PSEGMENT Segment)
Definition: section.c:605
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803

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

◆ MiCheckPurgeAndUpMapCount()

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

Definition at line 544 of file section.c.

546 {
547  KIRQL OldIrql;
548 
549  /* Flag not yet supported */
550  ASSERT(FailIfSystemViews == FALSE);
551 
552  /* Lock the PFN database */
554 
555  /* State not yet supported */
556  ASSERT(ControlArea->u.Flags.BeingPurged == 0);
557 
558  /* Increase the reference counts */
559  ControlArea->NumberOfMappedViews++;
560  ControlArea->NumberOfUserReferences++;
561  ASSERT(ControlArea->NumberOfSectionReferences != 0);
562 
563  /* Release the PFN lock and return success */
565  return STATUS_SUCCESS;
566 }
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
return STATUS_SUCCESS
Definition: btrfs.c:2966

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

1501 {
1502  /* Not yet implemented */
1503  ASSERT(FALSE);
1504  *Segment = NULL;
1505  return STATUS_NOT_IMPLEMENTED;
1506 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PVOID Segment
Definition: exfuncs.h:893
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by MmCreateArm3Section().

◆ MiCreatePagingFileMap()

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

Definition at line 1510 of file section.c.

1514 {
1515  SIZE_T SizeLimit;
1516  PFN_COUNT PteCount;
1517  PMMPTE PointerPte;
1518  MMPTE TempPte;
1519  PCONTROL_AREA ControlArea;
1520  PSEGMENT NewSegment;
1521  PSUBSECTION Subsection;
1522  PAGED_CODE();
1523 
1524  /* No large pages in ARM3 yet */
1526 
1527  /* Pagefile-backed sections need a known size */
1528  if (!(*MaximumSize)) return STATUS_INVALID_PARAMETER_4;
1529 
1530  /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1531  SizeLimit = MAXULONG_PTR - sizeof(SEGMENT);
1532  SizeLimit /= sizeof(MMPTE);
1533  SizeLimit <<= PAGE_SHIFT;
1534 
1535  /* Fail if this size is too big */
1536  if (*MaximumSize > SizeLimit) return STATUS_SECTION_TOO_BIG;
1537 
1538  /* Calculate how many Prototype PTEs will be needed */
1539  PteCount = (PFN_COUNT)((*MaximumSize + PAGE_SIZE - 1) >> PAGE_SHIFT);
1540 
1541  /* For commited memory, we must have a valid protection mask */
1542  if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1543 
1544  /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1545  NewSegment = ExAllocatePoolWithTag(PagedPool,
1546  sizeof(SEGMENT) +
1547  sizeof(MMPTE) * (PteCount - 1),
1548  'tSmM');
1549  ASSERT(NewSegment);
1550  *Segment = NewSegment;
1551 
1552  /* Now allocate the control area, which has the subsection structure */
1553  ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1554  sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1555  'tCmM');
1556  ASSERT(ControlArea);
1557 
1558  /* And zero it out, filling the basic segmnet pointer and reference fields */
1559  RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1560  ControlArea->Segment = NewSegment;
1561  ControlArea->NumberOfSectionReferences = 1;
1562  ControlArea->NumberOfUserReferences = 1;
1563 
1564  /* Convert allocation attributes to control area flags */
1565  if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1566  if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1567  if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1568 
1569  /* We just allocated it */
1570  ControlArea->u.Flags.BeingCreated = 1;
1571 
1572  /* The subsection follows, write the mask, PTE count and point back to the CA */
1573  Subsection = (PSUBSECTION)(ControlArea + 1);
1574  Subsection->ControlArea = ControlArea;
1575  Subsection->PtesInSubsection = PteCount;
1576  Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1577 
1578  /* Zero out the segment's prototype PTEs, and link it with the control area */
1579  PointerPte = &NewSegment->ThePtes[0];
1580  RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1581  NewSegment->PrototypePte = PointerPte;
1582  NewSegment->ControlArea = ControlArea;
1583 
1584  /* Save some extra accounting data for the segment as well */
1585  NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1586  NewSegment->SizeOfSegment = PteCount * PAGE_SIZE;
1587  NewSegment->TotalNumberOfPtes = PteCount;
1588  NewSegment->NonExtendedPtes = PteCount;
1589 
1590  /* The subsection's base address is the first Prototype PTE in the segment */
1591  Subsection->SubsectionBase = PointerPte;
1592 
1593  /* Start with an empty PTE, unless this is a commit operation */
1594  TempPte.u.Long = 0;
1596  {
1597  /* In which case, write down the protection mask in the Prototype PTEs */
1598  TempPte.u.Soft.Protection = ProtectionMask;
1599 
1600  /* For accounting, also mark these pages as being committed */
1601  NewSegment->NumberOfCommittedPages = PteCount;
1602  }
1603 
1604  /* The template PTE itself for the segment should also have the mask set */
1605  NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1606 
1607  /* Write out the prototype PTEs, for now they're simply demand zero */
1608 #ifdef _WIN64
1609  RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1610 #else
1611  RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1612 #endif
1613  return STATUS_SUCCESS;
1614 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
ULONG NumberOfCommittedPages
Definition: mmtypes.h:406
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
ULONGLONG SizeOfSegment
Definition: mmtypes.h:404
_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:514
ULONG NonExtendedPtes
Definition: mmtypes.h:402
ULONG PFN_COUNT
Definition: mmtypes.h:102
PCONTROL_AREA ControlArea
Definition: mmtypes.h:562
MMPTE ThePtes[1]
Definition: mmtypes.h:421
#define MAXULONG_PTR
Definition: basetsd.h:103
ULONG TotalNumberOfPtes
Definition: mmtypes.h:401
union _SUBSECTION::@2491 u
#define PAGED_CODE()
Definition: video.h:57
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:400
#define SEC_BASED
PEPROCESS CreatingProcess
Definition: mmtypes.h:413
#define SEC_COMMIT
Definition: mmtypes.h:99
union _MMPTE::@2236 u
#define SEC_RESERVE
Definition: nt_native.h:1323
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:286
ULONG64 Protection
Definition: mmtypes.h:88
union _CONTROL_AREA::@2489 u
_Inout_ PVOID Segment
Definition: exfuncs.h:893
union _SEGMENT::@2487 u1
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _SUBSECTION * PSUBSECTION
struct _SEGMENT SEGMENT
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ULONG_PTR SIZE_T
Definition: typedefs.h:78
MMSUBSECTION_FLAGS SubsectionFlags
Definition: mmtypes.h:566
PSEGMENT Segment
Definition: mmtypes.h:512
ULONG NumberOfUserReferences
Definition: mmtypes.h:518
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:405
MMSECTION_FLAGS Flags
Definition: mmtypes.h:522
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:464
return STATUS_SUCCESS
Definition: btrfs.c:2966
PMMPTE PrototypePte
Definition: mmtypes.h:420
PMMPTE SubsectionBase
Definition: mmtypes.h:570
ULONG BeingCreated
Definition: mmtypes.h:455
NTSYSAPI VOID NTAPI RtlFillMemoryUlonglong(_Out_writes_bytes_all_(Length) PVOID Destination, _In_ SIZE_T Length, _In_ ULONGLONG Pattern)
ULONG PtesInSubsection
Definition: mmtypes.h:572

Referenced by MmCreateArm3Section().

◆ MiDeleteARM3Section()

VOID NTAPI MiDeleteARM3Section ( PVOID  ObjectBody)

Definition at line 3248 of file section.c.

3249 {
3251  PCONTROL_AREA ControlArea;
3252  KIRQL OldIrql;
3253 
3254  SectionObject = (PSECTION)ObjectBody;
3255 
3256  if (SectionObject->u.Flags.Based == 1)
3257  {
3258  /* Remove the node from the global section address tree */
3262  }
3263 
3264  /* Lock the PFN database */
3266 
3267  ASSERT(SectionObject->Segment);
3268  ASSERT(SectionObject->Segment->ControlArea);
3269 
3270  ControlArea = SectionObject->Segment->ControlArea;
3271 
3272  /* Dereference */
3273  ControlArea->NumberOfSectionReferences--;
3274  ControlArea->NumberOfUserReferences--;
3275 
3276  ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
3277 
3278  /* Check it. It will delete it if there is no more reference to it */
3279  MiCheckControlArea(ControlArea, OldIrql);
3280 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
ULONG NumberOfSectionReferences
Definition: mmtypes.h:514
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:901
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _SECTION * PSECTION
union _CONTROL_AREA::@2489 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:360
ULONG BeingDeleted
Definition: mmtypes.h:454
ULONG NumberOfUserReferences
Definition: mmtypes.h:518
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:728
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
MMSECTION_FLAGS Flags
Definition: mmtypes.h:522

Referenced by MmpDeleteSection().

◆ MiDereferenceControlArea()

VOID NTAPI MiDereferenceControlArea ( IN PCONTROL_AREA  ControlArea)

Definition at line 763 of file section.c.

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

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

◆ MiFillSystemPageDirectory()

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

Definition at line 476 of file section.c.

478 {
479  PMMPDE PointerPde, LastPde, SystemMapPde;
480  MMPDE TempPde;
481  PFN_NUMBER PageFrameIndex, ParentPage;
482  KIRQL OldIrql;
483  PAGED_CODE();
484 
485  /* Find the PDEs needed for this mapping */
486  PointerPde = MiAddressToPde(Base);
487  LastPde = MiAddressToPde((PVOID)((ULONG_PTR)Base + NumberOfBytes - 1));
488 
489 #if (_MI_PAGING_LEVELS == 2)
490  /* Find the system double-mapped PDE that describes this mapping */
491  SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
492 #else
493  /* We don't have a double mapping */
494  SystemMapPde = PointerPde;
495 #endif
496 
497  /* Use the PDE template and loop the PDEs */
499  while (PointerPde <= LastPde)
500  {
501  /* Lock the PFN database */
503 
504  /* Check if we don't already have this PDE mapped */
505  if (SystemMapPde->u.Hard.Valid == 0)
506  {
507  /* Grab a page for it */
509  MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
510  PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
511  ASSERT(PageFrameIndex);
512  TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
513 
514 #if (_MI_PAGING_LEVELS == 2)
515  ParentPage = MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_COUNT];
516 #else
517  ParentPage = MiPdeToPpe(PointerPde)->u.Hard.PageFrameNumber;
518 #endif
519  /* Initialize its PFN entry, with the parent system page directory page table */
520  MiInitializePfnForOtherProcess(PageFrameIndex,
521  (PMMPTE)PointerPde,
522  ParentPage);
523 
524  /* Make the system PDE entry valid */
525  MI_WRITE_VALID_PDE(SystemMapPde, TempPde);
526 
527  /* The system PDE entry might be the PDE itself, so check for this */
528  if (PointerPde->u.Hard.Valid == 0)
529  {
530  /* It's different, so make the real PDE valid too */
531  MI_WRITE_VALID_PDE(PointerPde, TempPde);
532  }
533  }
534 
535  /* Release the lock and keep going with the next PDE */
537  SystemMapPde++;
538  PointerPde++;
539  }
540 }
#define MiAddressToPde(x)
Definition: mmx86.c:20
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:246
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
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:908
#define PAGED_CODE()
Definition: video.h:57
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PDE_COUNT
Definition: miarm.h:32
ULONG PFN_NUMBER
Definition: ke.h:8
union _MMPTE::@2236 u
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1006
#define MI_SET_USAGE(x)
Definition: mm.h:253
PMMPDE MmSystemPagePtes
Definition: init.c:41
ULONG PageFrameNumber
Definition: mmtypes.h:74
#define MiPdeToPpe(_Pde)
Definition: mm.h:234
ULONG64 Valid
Definition: mmtypes.h:150
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
PFN_NUMBER MmSystemPageDirectory[PD_COUNT]
Definition: init.c:40
MMPTE ValidKernelPde
Definition: init.c:30
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define SYSTEM_PD_SIZE
Definition: miarm.h:36
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:998
#define ULONG_PTR
Definition: config.h:101

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

1964 {
1965  MMPTE TempPte, PreviousPte;
1966  KIRQL OldIrql;
1967  BOOLEAN RebuildPte = FALSE;
1968 
1969  //
1970  // User for sanity checking later on
1971  //
1972  PreviousPte = *PointerPte;
1973 
1974  //
1975  // Build the PTE and acquire the PFN lock
1976  //
1978  PointerPte,
1979  ProtectionMask,
1980  PreviousPte.u.Hard.PageFrameNumber);
1982 
1983  //
1984  // We don't support I/O mappings in this path yet
1985  //
1986  ASSERT(Pfn1 != NULL);
1987  ASSERT(Pfn1->u3.e1.CacheAttribute != MiWriteCombined);
1988 
1989  //
1990  // Make sure new protection mask doesn't get in conflict and fix it if it does
1991  //
1992  if (Pfn1->u3.e1.CacheAttribute == MiCached)
1993  {
1994  //
1995  // This is a cached PFN
1996  //
1997  if (ProtectionMask & (MM_NOCACHE | MM_NOACCESS))
1998  {
1999  RebuildPte = TRUE;
2000  ProtectionMask &= ~(MM_NOCACHE | MM_NOACCESS);
2001  }
2002  }
2003  else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
2004  {
2005  //
2006  // This is a non-cached PFN
2007  //
2008  if ((ProtectionMask & (MM_NOCACHE | MM_NOACCESS)) != MM_NOCACHE)
2009  {
2010  RebuildPte = TRUE;
2011  ProtectionMask &= ~MM_NOACCESS;
2012  ProtectionMask |= MM_NOCACHE;
2013  }
2014  }
2015 
2016  if (RebuildPte)
2017  {
2019  PointerPte,
2020  ProtectionMask,
2021  PreviousPte.u.Hard.PageFrameNumber);
2022  }
2023 
2024  //
2025  // Write the new PTE, making sure we are only changing the bits
2026  //
2027  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2028 
2029  //
2030  // Flush the TLB
2031  //
2032  ASSERT(PreviousPte.u.Hard.Valid == 1);
2033  KeFlushCurrentTb();
2034  ASSERT(PreviousPte.u.Hard.Valid == 1);
2035 
2036  //
2037  // Windows updates the relevant PFN1 information, we currently don't.
2038  //
2039  if (UpdateDirty && PreviousPte.u.Hard.Dirty)
2040  {
2041  if (!Pfn1->u3.e1.Modified)
2042  {
2043  DPRINT1("FIXME: Mark PFN as dirty\n");
2044  }
2045  }
2046 
2047  //
2048  // Not supported in ARM3
2049  //
2050  ASSERT(FoundVad->u.VadFlags.VadType != VadWriteWatch);
2051 
2052  //
2053  // Release the PFN lock, we are done
2054  //
2056 }
#define TRUE
Definition: types.h:120
#define MM_NOACCESS
Definition: miarm.h:69
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define MM_NOCACHE
Definition: miarm.h:60
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
ULONG64 Dirty
Definition: mmtypes.h:164
UCHAR KIRQL
Definition: env_spec_w32.h:591
union _MMPTE::@2236 u
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:822
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#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:965
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:322

Referenced by MiProtectVirtualMemory(), and MiSetProtectionOnSection().

◆ MiGetFileObjectForSectionAddress()

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

Definition at line 1618 of file section.c.

1621 {
1622  PMMVAD Vad;
1623  PCONTROL_AREA ControlArea;
1624 
1625  /* Get the VAD */
1626  Vad = MiLocateAddress(Address);
1627  if (Vad == NULL)
1628  {
1629  /* Fail, the address does not exist */
1630  DPRINT1("Invalid address\n");
1631  return STATUS_INVALID_ADDRESS;
1632  }
1633 
1634  /* Check if this is a RosMm memory area */
1635  if (Vad->u.VadFlags.Spare != 0)
1636  {
1638  PROS_SECTION_OBJECT Section;
1639 
1640  /* Check if it's a section view (RosMm section) */
1642  {
1643  /* Get the section pointer to the SECTION_OBJECT */
1644  Section = MemoryArea->Data.SectionData.Section;
1645  *FileObject = Section->FileObject;
1646  }
1647  else
1648  {
1650  DPRINT1("Address is a cache section!\n");
1651  return STATUS_SECTION_NOT_IMAGE;
1652  }
1653  }
1654  else
1655  {
1656  /* Make sure it's not a VM VAD */
1657  if (Vad->u.VadFlags.PrivateMemory == 1)
1658  {
1659  DPRINT1("Address is not a section\n");
1660  return STATUS_SECTION_NOT_IMAGE;
1661  }
1662 
1663  /* Get the control area */
1664  ControlArea = Vad->ControlArea;
1665  if (!(ControlArea) || !(ControlArea->u.Flags.Image))
1666  {
1667  DPRINT1("Address is not a section\n");
1668  return STATUS_SECTION_NOT_IMAGE;
1669  }
1670 
1671  /* Get the file object */
1672  *FileObject = ControlArea->FilePointer;
1673  }
1674 
1675  /* Return success */
1676  return STATUS_SUCCESS;
1677 }
PFILE_OBJECT FilePointer
Definition: mmtypes.h:524
ULONG Type
Definition: mm.h:214
struct _MEMORY_AREA * PMEMORY_AREA
union _MEMORY_AREA::@1725 Data
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
#define MEMORY_AREA_CACHE
Definition: mm.h:72
PCONTROL_AREA ControlArea
Definition: mmtypes.h:736
smooth NULL
Definition: ftsmooth.c:416
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:48
static WCHAR Address[46]
Definition: ping.c:68
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:71
union _CONTROL_AREA::@2489 u
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
PFILE_OBJECT FileObject
Definition: mm.h:199
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:295
struct _MEMORY_AREA::@1725::@1726 SectionData
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:543
union _MMVAD::@2496 u
#define DPRINT1
Definition: precomp.h:8
ULONG_PTR Spare
Definition: mmtypes.h:697
MMSECTION_FLAGS Flags
Definition: mmtypes.h:522
return STATUS_SUCCESS
Definition: btrfs.c:2966

◆ MiGetFileObjectForVad()

static PFILE_OBJECT MiGetFileObjectForVad ( _In_ PMMVAD  Vad)
static

Definition at line 1701 of file section.c.

1703 {
1704  PCONTROL_AREA ControlArea;
1706 
1707  /* Check if this is a RosMm memory area */
1708  if (Vad->u.VadFlags.Spare != 0)
1709  {
1711  PROS_SECTION_OBJECT Section;
1712 
1713  /* Check if it's a section view (RosMm section) */
1715  {
1716  /* Get the section pointer to the SECTION_OBJECT */
1717  Section = MemoryArea->Data.SectionData.Section;
1718  FileObject = Section->FileObject;
1719  }
1720  else
1721  {
1723  DPRINT1("VAD is a cache section!\n");
1724  return NULL;
1725  }
1726  }
1727  else
1728  {
1729  /* Make sure it's not a VM VAD */
1730  if (Vad->u.VadFlags.PrivateMemory == 1)
1731  {
1732  DPRINT1("VAD is not a section\n");
1733  return NULL;
1734  }
1735 
1736  /* Get the control area */
1737  ControlArea = Vad->ControlArea;
1738  if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1739  {
1740  DPRINT1("Address is not a section\n");
1741  return NULL;
1742  }
1743 
1744  /* Get the file object */
1745  FileObject = ControlArea->FilePointer;
1746  }
1747 
1748  /* Return the file object */
1749  return FileObject;
1750 }
PFILE_OBJECT FilePointer
Definition: mmtypes.h:524
ULONG Type
Definition: mm.h:214
struct _MEMORY_AREA * PMEMORY_AREA
union _MEMORY_AREA::@1725 Data
#define MEMORY_AREA_CACHE
Definition: mm.h:72
smooth NULL
Definition: ftsmooth.c:416
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:71
union _CONTROL_AREA::@2489 u
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFILE_OBJECT FileObject
Definition: mm.h:199
* PFILE_OBJECT
Definition: iotypes.h:1955
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _MEMORY_AREA::@1725::@1726 SectionData
#define DPRINT1
Definition: precomp.h:8
MMSECTION_FLAGS Flags
Definition: mmtypes.h:522

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 }
#define TRUE
Definition: types.h:120
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
struct _RTL_BITMAP RTL_BITMAP
PCHAR SystemSpaceViewStart
Definition: miarm.h:466
ULONG SystemSpaceHashEntries
Definition: miarm.h:469
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:464
#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
smooth NULL
Definition: ftsmooth.c:416
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:467
ULONG SystemSpaceHashKey
Definition: miarm.h:470
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
struct _MMVIEW MMVIEW
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:465
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG_PTR SIZE_T
Definition: typedefs.h:78
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
PRTL_BITMAP SystemSpaceBitMap
Definition: miarm.h:472
PVOID MiSessionViewStart
Definition: init.c:30
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:275
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ULONG SystemSpaceHashSize
Definition: miarm.h:468
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
struct _Entry Entry
Definition: kefuncs.h:640
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
while(1)
Definition: macro.lex.yy.c:740
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 TAG_MM
Definition: tag.h:136
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:275
Definition: miarm.h:456
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:261
#define ULONG_PTR
Definition: config.h:101
ULONG_PTR Entry
Definition: miarm.h:458
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
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:71
#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
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 1158 of file section.c.

1161 {
1162  NTSTATUS Status;
1164  PLIST_ENTRY NextEntry;
1166  PIMAGE_NT_HEADERS NtHeaders;
1167  PLDR_DATA_TABLE_ENTRY LdrEntry;
1168 
1169  FileName = &ControlArea->FilePointer->FileName;
1170  if (FileName->Length == 0)
1171  {
1172  return;
1173  }
1174 
1175  /* Acquire module list lock */
1178 
1179  /* Browse list to try to find current module */
1180  for (NextEntry = MmLoadedUserImageList.Flink;
1181  NextEntry != &MmLoadedUserImageList;
1182  NextEntry = NextEntry->Flink)
1183  {
1184  /* Get the entry */
1185  LdrEntry = CONTAINING_RECORD(NextEntry,
1187  InLoadOrderLinks);
1188 
1189  /* If already in the list, increase load count */
1190  if (LdrEntry->DllBase == BaseAddress)
1191  {
1192  ++LdrEntry->LoadCount;
1193  break;
1194  }
1195  }
1196 
1197  /* Not in the list, we'll add it */
1198  if (NextEntry == &MmLoadedUserImageList)
1199  {
1200  /* Allocate our element, taking to the name string and its null char */
1201  LdrEntry = ExAllocatePoolWithTag(NonPagedPool, FileName->Length + sizeof(UNICODE_NULL) + sizeof(*LdrEntry), 'bDmM');
1202  if (LdrEntry)
1203  {
1204  memset(LdrEntry, 0, FileName->Length + sizeof(UNICODE_NULL) + sizeof(*LdrEntry));
1205 
1206  _SEH2_TRY
1207  {
1208  /* Get image checksum and size */
1209  NtHeaders = RtlImageNtHeader(BaseAddress);
1210  if (NtHeaders)
1211  {
1212  LdrEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
1213  LdrEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
1214  }
1215  }
1217  {
1218  ExFreePoolWithTag(LdrEntry, 'bDmM');
1219  _SEH2_YIELD(return);
1220  }
1221  _SEH2_END;
1222 
1223  /* Fill all the details */
1224  LdrEntry->DllBase = BaseAddress;
1225  LdrEntry->FullDllName.Buffer = (PVOID)((ULONG_PTR)LdrEntry + sizeof(*LdrEntry));
1226  LdrEntry->FullDllName.Length = FileName->Length;
1227  LdrEntry->FullDllName.MaximumLength = FileName->Length + sizeof(UNICODE_NULL);
1228  memcpy(LdrEntry->FullDllName.Buffer, FileName->Buffer, FileName->Length);
1229  LdrEntry->FullDllName.Buffer[LdrEntry->FullDllName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1230  LdrEntry->LoadCount = 1;
1231 
1232  /* Insert! */
1234  }
1235  }
1236 
1237  /* Release locks */
1240 
1241  /* Load symbols */
1243  if (NT_SUCCESS(Status))
1244  {
1247  }
1248 }
#define TRUE
Definition: types.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370
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:142
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
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:1784
#define UNICODE_NULL
#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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_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:1790
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:1780
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:137
struct _FileName FileName
Definition: fatprocs.h:884
_SEH2_END
Definition: create.c:4424
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1786
VOID NTAPI DbgLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
#define RtlImageNtHeader
Definition: compat.h:457
_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 570 of file section.c.

572 {
573  PSUBSECTION Subsection;
574  PCONTROL_AREA ControlArea;
575  ULONG_PTR PteOffset;
576 
577  /* Get the control area */
578  ControlArea = Vad->ControlArea;
579  ASSERT(ControlArea->u.Flags.Rom == 0);
580  ASSERT(ControlArea->u.Flags.Image == 0);
581  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
582 
583  /* Get the subsection */
584  Subsection = (PSUBSECTION)(ControlArea + 1);
585 
586  /* We only support single-subsection segments */
587  ASSERT(Subsection->SubsectionBase != NULL);
588  ASSERT(Vad->FirstPrototypePte >= Subsection->SubsectionBase);
589  ASSERT(Vad->FirstPrototypePte < &Subsection->SubsectionBase[Subsection->PtesInSubsection]);
590 
591  /* Compute the PTE offset */
592  PteOffset = Vpn - Vad->StartingVpn;
593  PteOffset += Vad->FirstPrototypePte - Subsection->SubsectionBase;
594 
595  /* Again, we only support single-subsection segments */
596  ASSERT(PteOffset < 0xF0000000);
597  ASSERT(PteOffset < Subsection->PtesInSubsection);
598 
599  /* Return the subsection */
600  return Subsection;
601 }
uint32_t ULONG_PTR
Definition: typedefs.h:63
smooth NULL
Definition: ftsmooth.c:416
union _CONTROL_AREA::@2489 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _SUBSECTION * PSUBSECTION
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:482
MMSECTION_FLAGS Flags
Definition: mmtypes.h:522
PMMPTE SubsectionBase
Definition: mmtypes.h:570
ULONG PtesInSubsection
Definition: mmtypes.h:572

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:71
_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:69
#define MM_NOCACHE
Definition: miarm.h:60
#define PAGE_NOACCESS
Definition: nt_native.h:1302
CHAR MmUserProtectionToMask2[16]
Definition: section.c:64
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MM_GUARDPAGE
Definition: miarm.h:61
#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 NTAPI MiMapViewInSystemSpace ( IN PVOID  Section,
IN PMMSESSION  Session,
OUT PVOID MappedBase,
IN OUT PSIZE_T  ViewSize 
)

Definition at line 1052 of file section.c.

1056 {
1057  PVOID Base;
1058  PCONTROL_AREA ControlArea;
1059  ULONG Buckets, SectionSize;
1060  NTSTATUS Status;
1061  PAGED_CODE();
1062 
1063  /* Get the control area, check for any flags ARM3 doesn't yet support */
1064  ControlArea = ((PSECTION)Section)->Segment->ControlArea;
1065  ASSERT(ControlArea->u.Flags.Image == 0);
1066  ASSERT(ControlArea->FilePointer == NULL);
1067  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1068  ASSERT(ControlArea->u.Flags.Rom == 0);
1069  ASSERT(ControlArea->u.Flags.WasPurged == 0);
1070 
1071  /* Increase the reference and map count on the control area, no purges yet */
1072  Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1074 
1075  /* Get the section size at creation time */
1076  SectionSize = ((PSECTION)Section)->SizeOfSection.LowPart;
1077 
1078  /* If the caller didn't specify a view size, assume the whole section */
1079  if (!(*ViewSize)) *ViewSize = SectionSize;
1080 
1081  /* Check if the caller wanted a larger section than the view */
1082  if (*ViewSize > SectionSize)
1083  {
1084  /* Fail */
1085  DPRINT1("View is too large\n");
1086  MiDereferenceControlArea(ControlArea);
1087  return STATUS_INVALID_VIEW_SIZE;
1088  }
1089 
1090  /* Get the number of 64K buckets required for this mapping */
1091  Buckets = (ULONG)(*ViewSize / MI_SYSTEM_VIEW_BUCKET_SIZE);
1092  if (*ViewSize & (MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) Buckets++;
1093 
1094  /* Check if the view is more than 4GB large */
1095  if (Buckets >= MI_SYSTEM_VIEW_BUCKET_SIZE)
1096  {
1097  /* Fail */
1098  DPRINT1("View is too large\n");
1099  MiDereferenceControlArea(ControlArea);
1100  return STATUS_INVALID_VIEW_SIZE;
1101  }
1102 
1103  /* Insert this view into system space and get a base address for it */
1104  Base = MiInsertInSystemSpace(Session, Buckets, ControlArea);
1105  if (!Base)
1106  {
1107  /* Fail */
1108  DPRINT1("Out of system space\n");
1109  MiDereferenceControlArea(ControlArea);
1110  return STATUS_NO_MEMORY;
1111  }
1112 
1113  /* What's the underlying session? */
1114  if (Session == &MmSession)
1115  {
1116  /* Create the PDEs needed for this mapping, and double-map them if needed */
1119  }
1120  else
1121  {
1122  /* Create the PDEs needed for this mapping */
1124  (PVOID)((ULONG_PTR)Base +
1125  Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
1127  }
1128 
1129  /* Create the actual prototype PTEs for this mapping */
1132  ControlArea);
1134 
1135  /* Return the base adress of the mapping and success */
1136  *MappedBase = Base;
1137  return STATUS_SUCCESS;
1138 }
PFILE_OBJECT FilePointer
Definition: mmtypes.h:524
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
NTSTATUS NTAPI MiSessionCommitPageTables(IN PVOID StartVa, IN PVOID EndVa)
Definition: section.c:935
#define PAGED_CODE()
Definition: video.h:57
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:400
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS NTAPI MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:544
VOID NTAPI MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:763
NTSTATUS NTAPI MiAddMappedPtes(IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea)
Definition: section.c:417
#define MiAddressToPte(x)
Definition: mmx86.c:19
smooth NULL
Definition: ftsmooth.c:416
struct _SECTION * PSECTION
union _CONTROL_AREA::@2489 u
PVOID NTAPI MiInsertInSystemSpace(IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
Definition: section.c:306
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:476
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define BYTES_TO_PAGES(Size)
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:482
Status
Definition: gdiplustypes.h:24
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:254
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:275
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
PSEGMENT Segment
Definition: mmtypes.h:512
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:493
_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:469
MMSECTION_FLAGS Flags
Definition: mmtypes.h:522
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966
MMSESSION MmSession
Definition: section.c:107

Referenced by MmMapViewInSessionSpace(), and MmMapViewInSystemSpace().

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

1263 {
1264  PMMVAD_LONG Vad;
1265  ULONG_PTR StartAddress;
1266  ULONG_PTR ViewSizeInPages;
1267  PSUBSECTION Subsection;
1268  PSEGMENT Segment;
1269  PFN_NUMBER PteOffset;
1270  NTSTATUS Status;
1271  ULONG QuotaCharge = 0, QuotaExcess = 0;
1272  PMMPTE PointerPte, LastPte;
1273  MMPTE TempPte;
1274  ULONG Granularity = MM_VIRTMEM_GRANULARITY;
1275 
1276  DPRINT("Mapping ARM3 data section\n");
1277 
1278  /* Get the segment for this section */
1279  Segment = ControlArea->Segment;
1280 
1281 #ifdef _M_IX86
1282  /* ALlow being less restrictive on x86. */
1284  Granularity = PAGE_SIZE;
1285 #endif
1286 
1287  /* One can only reserve a file-based mapping, not shared memory! */
1288  if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1289  {
1291  }
1292 
1293  /* First, increase the map count. No purging is supported yet */
1294  Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1295  if (!NT_SUCCESS(Status)) return Status;
1296 
1297  /* Check if the caller specified the view size */
1298  if (!(*ViewSize))
1299  {
1300  /* The caller did not, so pick a 64K aligned view size based on the offset */
1301  SectionOffset->LowPart &= ~(_64K - 1);
1302  *ViewSize = (SIZE_T)(Section->SizeOfSection.QuadPart - SectionOffset->QuadPart);
1303  }
1304  else
1305  {
1306  /* A size was specified, align it to a 64K boundary */
1307  *ViewSize += SectionOffset->LowPart & (_64K - 1);
1308 
1309  /* Align the offset as well to make this an aligned map */
1310  SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1311  }
1312 
1313  /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1314  ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1315 
1316  /* It's illegal to try to map more than overflows a LONG_PTR */
1317  if (*ViewSize >= MAXLONG_PTR)
1318  {
1319  MiDereferenceControlArea(ControlArea);
1320  return STATUS_INVALID_VIEW_SIZE;
1321  }
1322 
1323  /* Windows ASSERTs for this flag */
1324  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1325 
1326  /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1327  ASSERT(ControlArea->u.Flags.Rom == 0);
1328  Subsection = (PSUBSECTION)(ControlArea + 1);
1329 
1330  /* Sections with extended segments are not supported in ARM3 */
1331  ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1332 
1333  /* Within this section, figure out which PTEs will describe the view */
1334  PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1335 
1336  /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1337  ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1338  ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1339 
1340  /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1341  ASSERT(PteOffset < Subsection->PtesInSubsection);
1342 
1343  /* In ARM3, only page-file backed sections (shared memory) are supported now */
1344  ASSERT(ControlArea->FilePointer == NULL);
1345 
1346  /* Windows ASSERTs for this too -- there must be a subsection base address */
1347  ASSERT(Subsection->SubsectionBase != NULL);
1348 
1349  /* Compute how much commit space the segment will take */
1350  if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1351  {
1352  /* Charge for the maximum pages */
1353  QuotaCharge = BYTES_TO_PAGES(CommitSize);
1354  }
1355 
1356  /* ARM3 does not currently support large pages */
1357  ASSERT(Segment->SegmentFlags.LargePages == 0);
1358 
1359  /* Calculate how many pages the region spans */
1360  ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1361 
1362  /* A VAD can now be allocated. Do so and zero it out */
1363  /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1364  ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1365  Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1366  if (!Vad)
1367  {
1368  MiDereferenceControlArea(ControlArea);
1370  }
1371 
1372  RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1373  Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1374 
1375  /* Write all the data required in the VAD for handling a fault */
1376  Vad->ControlArea = ControlArea;
1377  Vad->u.VadFlags.CommitCharge = 0;
1378  Vad->u.VadFlags.Protection = ProtectionMask;
1379  Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1381  if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1382  {
1383  /* This isn't really implemented yet, but handle setting the flag */
1384  Vad->u.VadFlags.NoChange = 1;
1385  Vad->u2.VadFlags2.SecNoChange = 1;
1386  }
1387 
1388  /* Finally, write down the first and last prototype PTE */
1389  Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1390  PteOffset += ViewSizeInPages - 1;
1391  ASSERT(PteOffset < Subsection->PtesInSubsection);
1392  Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1393 
1394  /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1396 
1397  /* FIXME: Should setup VAD bitmap */
1399 
1400  /* Check if anything was committed */
1401  if (QuotaCharge)
1402  {
1403  /* Set the start and end PTE addresses, and pick the template PTE */
1404  PointerPte = Vad->FirstPrototypePte;
1405  LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1406  TempPte = Segment->SegmentPteTemplate;
1407 
1408  /* Acquire the commit lock and loop all prototype PTEs to be committed */
1410  while (PointerPte < LastPte)
1411  {
1412  /* Make sure the PTE is already invalid */
1413  if (PointerPte->u.Long == 0)
1414  {
1415  /* And write the invalid PTE */
1416  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1417  }
1418  else
1419  {
1420  /* The PTE is valid, so skip it */
1421  QuotaExcess++;
1422  }
1423 
1424  /* Move to the next PTE */
1425  PointerPte++;
1426  }
1427 
1428  /* Now check how many pages exactly we committed, and update accounting */
1429  ASSERT(QuotaCharge >= QuotaExcess);
1430  QuotaCharge -= QuotaExcess;
1431  Segment->NumberOfCommittedPages += QuotaCharge;
1432  ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1433 
1434  /* Now that we're done, release the lock */
1436  }
1437 
1438  /* Is it SEC_BASED, or did the caller manually specify an address? */
1439  if (*BaseAddress != NULL)
1440  {
1441  /* Just align what the caller gave us */
1442  StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1443  }
1444  else if (Section->Address.StartingVpn != 0)
1445  {
1446  /* It is a SEC_BASED mapping, use the address that was generated */
1447  StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1448  }
1449  else
1450  {
1451  StartAddress = 0;
1452  }
1453 
1454  /* Insert the VAD */
1455  Status = MiInsertVadEx((PMMVAD)Vad,
1456  &StartAddress,
1457  ViewSizeInPages * PAGE_SIZE,
1459  Granularity,
1460  AllocationType);
1461  if (!NT_SUCCESS(Status))
1462  {
1463  return Status;
1464  }
1465 
1466  /* Windows stores this for accounting purposes, do so as well */
1467  if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1468 
1469  /* Finally, let the caller know where, and for what size, the view was mapped */
1470  *ViewSize = ViewSizeInPages * PAGE_SIZE;
1471  *BaseAddress = (PVOID)StartAddress;
1472  DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1473  return STATUS_SUCCESS;
1474 }
_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:78
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
union _MMVAD_LONG::@2499 u
PMMPTE LastContiguousPte
Definition: mmtypes.h:767
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
ULONG_PTR CommitCharge
Definition: mmtypes.h:691
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:469
#define MAXULONG_PTR
Definition: basetsd.h:103
ULONG SecNoChange
Definition: mmtypes.h:707
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
ULONG_PTR Protection
Definition: mmtypes.h:696
ULONG_PTR NoChange
Definition: mmtypes.h:693
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS NTAPI MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:544
VOID NTAPI MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:763
ULONG PFN_NUMBER
Definition: ke.h:8
union _MMPTE::@2236 u
#define MEM_RESERVE
Definition: nt_native.h:1314
smooth NULL
Definition: ftsmooth.c:416
PVOID Banked
Definition: mmtypes.h:780
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
#define ULL(a, b)
Definition: format_msg.c:27
_Inout_ PVOID Segment
Definition: exfuncs.h:893
_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:706
#define MEM_DOS_LIM
Definition: mmtypes.h:89
_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:771
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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
union _MMVAD_LONG::@2500 u2
KGUARDED_MUTEX MmSectionCommitMutex
Definition: section.c:108
ULONG Inherit
Definition: mmtypes.h:713
Status
Definition: gdiplustypes.h:24
ULONG_PTR Long
Definition: mmtypes.h:215
#define ALIGN_DOWN_BY(size, align)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:980
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:254
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
_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:766
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
union _MMVAD_LONG::@2502 u4
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
PMMPTE SubsectionBase
Definition: mmtypes.h:570
#define MAXLONG_PTR
Definition: basetsd.h:104

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

1897 {
1899  NTSTATUS Status;
1901  PMEMORY_SECTION_NAME SectionName = NULL;
1903 
1906  NULL,
1907  PreviousMode,
1908  (PVOID*)(&Process),
1909  NULL);
1910 
1911  if (!NT_SUCCESS(Status))
1912  {
1913  DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1914  return Status;
1915  }
1916 
1918 
1919  if (NT_SUCCESS(Status))
1920  {
1921  SectionName = MemoryInformation;
1922  if (PreviousMode != KernelMode)
1923  {
1924  _SEH2_TRY
1925  {
1926  RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1927  (PWSTR)(SectionName + 1),
1928  MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1930 
1932 
1933  }
1935  {
1937  }
1938  _SEH2_END;
1939  }
1940  else
1941  {
1942  RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1943  (PWSTR)(SectionName + 1),
1944  MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1946 
1948 
1949  }
1950 
1952  }
1954  return Status;
1955 }
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:1831
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:158
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_SEH2_TRY
Definition: create.c:4250
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
TCHAR ModuleFileName[MAX_PATH+1]
Definition: rundll32.c:55
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_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
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
UNICODE_STRING SectionFileName
Definition: mmtypes.h:317
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
_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
struct _MEMORY_SECTION_NAME MEMORY_SECTION_NAME

Referenced by NtQueryVirtualMemory().

◆ MiRemoveFromSystemSpace()

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

Definition at line 2334 of file section.c.

2337 {
2338  ULONG Hash, Size, Count = 0;
2339  ULONG_PTR Entry;
2340  PAGED_CODE();
2341 
2342  /* Compute the hash for this entry and loop trying to find it */
2343  Entry = (ULONG_PTR)Base >> 16;
2344  Hash = Entry % Session->SystemSpaceHashKey;
2345  while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2346  {
2347  /* Check if we overflew past the end of the hash table */
2348  if (++Hash >= Session->SystemSpaceHashSize)
2349  {
2350  /* Reset the hash to zero and keep searching from the bottom */
2351  Hash = 0;
2352  if (++Count == 2)
2353  {
2354  /* But if we overflew twice, then this is not a real mapping */
2355  KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2356  (ULONG_PTR)Base,
2357  1,
2358  0,
2359  0);
2360  }
2361  }
2362  }
2363 
2364  /* One less entry */
2365  Session->SystemSpaceHashEntries--;
2366 
2367  /* Extract the size and clear the entry */
2368  Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2369  Session->SystemSpaceViewTable[Hash].Entry = 0;
2370 
2371  /* Return the control area and the size */
2372  *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2373  return Size;
2374 }
static int Hash(const char *)
Definition: reader.c:2257
struct _Entry Entry
Definition: kefuncs.h:640
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
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:107

Referenced by MiUnmapViewInSystemSpace().

◆ MiRemoveMappedPtes()

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

Definition at line 2232 of file section.c.

2236 {
2237  PMMPTE PointerPte, ProtoPte;//, FirstPte;
2238  PMMPDE PointerPde, SystemMapPde;
2239  PMMPFN Pfn1, Pfn2;
2240  MMPTE PteContents;
2241  KIRQL OldIrql;
2242  DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
2243 
2244  ASSERT(Ws == NULL);
2245 
2246  /* Get the PTE and loop each one */
2247  PointerPte = MiAddressToPte(BaseAddress);
2248  //FirstPte = PointerPte;
2249  while (NumberOfPtes)
2250  {
2251  /* Check if the PTE is already valid */
2252  PteContents = *PointerPte;
2253  if (PteContents.u.Hard.Valid == 1)
2254  {
2255  /* Get the PFN entry */
2256  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
2257 
2258  /* Get the PTE */
2259  PointerPde = MiPteToPde(PointerPte);
2260 
2261  /* Lock the PFN database and make sure this isn't a mapped file */
2263  ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
2264 
2265  /* Mark the page as modified accordingly */
2266  if (MI_IS_PAGE_DIRTY(&PteContents))
2267  Pfn1->u3.e1.Modified = 1;
2268 
2269  /* Was the PDE invalid */
2270  if (PointerPde->u.Long == 0)
2271  {
2272 #if (_MI_PAGING_LEVELS == 2)
2273  /* Find the system double-mapped PDE that describes this mapping */
2274  SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
2275 
2276  /* Make it valid */
2277  ASSERT(SystemMapPde->u.Hard.Valid == 1);
2278  MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
2279 #else
2280  DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
2281  ASSERT(FALSE);
2282 #endif
2283  }
2284 
2285  /* Dereference the PDE and the PTE */
2286  Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
2287  MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
2289  MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
2290 
2291  /* Release the PFN lock */
2293  }
2294  else
2295  {
2296  /* Windows ASSERT */
2297  ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
2298 
2299  /* Check if this is a prototype pointer PTE */
2300  if (PteContents.u.Soft.Prototype == 1)
2301  {
2302  /* Get the prototype PTE */
2303  ProtoPte = MiProtoPteToPte(&PteContents);
2304 
2305  /* We don't support anything else atm */
2306  ASSERT(ProtoPte->u.Long == 0);
2307  }
2308  }
2309 
2310  /* Make the PTE into a zero PTE */
2311  PointerPte->u.Long = 0;
2312 
2313  /* Move to the next PTE */
2314  PointerPte++;
2315  NumberOfPtes--;
2316  }
2317 
2318  /* Flush the TLB */
2319  KeFlushCurrentTb();
2320 
2321  /* Acquire the PFN lock */
2323 
2324  /* Decrement the accounting counters */
2325  ControlArea->NumberOfUserReferences--;
2326  ControlArea->NumberOfMappedViews--;
2327 
2328  /* Check if we should destroy the CA and release the lock */
2329  MiCheckControlArea(ControlArea, OldIrql);
2330 }
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
USHORT Modified
Definition: mm.h:292
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
USHORT PrototypePte
Definition: mm.h:295
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
#define MiAddressToPte(x)
Definition: mmx86.c:19
union _MMPTE::@2236 u
smooth NULL
Definition: ftsmooth.c:416
#define MiProtoPteToPte(x)
Definition: mm.h:247
void DPRINT(...)
Definition: polytest.cpp:61
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:1006
PMMPDE MmSystemPagePtes
Definition: init.c:41
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:326
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG64 Valid
Definition: mmtypes.h:150
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: mm.h:305
ULONG64 Prototype
Definition: mmtypes.h:89
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define SYSTEM_PD_SIZE
Definition: miarm.h:36
#define MiPteToPde(_Pte)
Definition: mm.h:233
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE OriginalPte
Definition: mm.h:339
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:728
#define MI_IS_PAGE_DIRTY(x)
Definition: mm.h:109
union _MMPFN::@1730 u3
#define ULONG_PTR
Definition: config.h:101
#define PFN_FROM_PTE(v)
Definition: mm.h:89
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:322

Referenced by MiUnmapViewInSystemSpace().

◆ MiRemoveMappedView()

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

Definition at line 780 of file section.c.

782 {
783  KIRQL OldIrql;
784  PCONTROL_AREA ControlArea;
785  PETHREAD CurrentThread = PsGetCurrentThread();
786 
787  /* Get the control area */
788  ControlArea = Vad->ControlArea;
789 
790  /* We only support non-extendable, non-image, pagefile-backed regular sections */
791  ASSERT(Vad->u.VadFlags.VadType == VadNone);
792  ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
793  ASSERT(ControlArea);
794  ASSERT(ControlArea->FilePointer == NULL);
795 
796  /* Delete the actual virtual memory pages */
797  MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
798  (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
799  Vad);
800 
801  /* Release the working set */
803 
804  /* Lock the PFN database */
806 
807  /* Remove references */
808  ControlArea->NumberOfMappedViews--;
809  ControlArea->NumberOfUserReferences--;
810 
811  /* Check if it should be destroyed */
812  MiCheckControlArea(ControlArea, OldIrql);
813 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
PFILE_OBJECT FilePointer
Definition: mmtypes.h:524
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:901
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
ULONG CurrentProcess
Definition: shell.c:125
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ULONG NumberOfMappedViews
Definition: mmtypes.h:516
VOID NTAPI MiDeleteVirtualAddresses(IN ULONG_PTR Va, IN ULONG_PTR EndingAddress, IN PMMVAD Vad)
Definition: virtual.c:540
ULONG NumberOfUserReferences
Definition: mmtypes.h:518
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:728

Referenced by MiUnmapViewOfSection(), and MmCleanProcessAddressSpace().

◆ MiSegmentDelete()

VOID NTAPI MiSegmentDelete ( IN PSEGMENT  Segment)

Definition at line 605 of file section.c.

606 {
607  PCONTROL_AREA ControlArea;
608  SEGMENT_FLAGS SegmentFlags;
609  PSUBSECTION Subsection;
610  PMMPTE PointerPte, LastPte, PteForProto;
611  PMMPFN Pfn1;
612  PFN_NUMBER PageFrameIndex;
613  MMPTE TempPte;
614  KIRQL OldIrql;
615 
616  /* Capture data */
617  SegmentFlags = Segment->SegmentFlags;
618  ControlArea = Segment->ControlArea;
619 
620  /* Make sure control area is on the right delete path */
621  ASSERT(ControlArea->u.Flags.BeingDeleted == 1);
622  ASSERT(ControlArea->WritableUserReferences == 0);
623 
624  /* These things are not supported yet */
625  ASSERT(ControlArea->DereferenceList.Flink == NULL);
626  ASSERT(!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File));
627  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
628  ASSERT(ControlArea->u.Flags.Rom == 0);
629 
630  /* Get the subsection and PTEs for this segment */
631  Subsection = (PSUBSECTION)(ControlArea + 1);
632  PointerPte = Subsection->SubsectionBase;
633  LastPte = PointerPte + Segment->NonExtendedPtes;
634 
635  /* Lock the PFN database */
637 
638  /* Check if the master PTE is invalid */
639  PteForProto = MiAddressToPte(PointerPte);
640  if (!PteForProto->u.Hard.Valid)
641  {
642  /* Fault it in */
644  }
645 
646  /* Loop all the segment PTEs */
647  while (PointerPte < LastPte)
648  {
649  /* Check if it's time to switch master PTEs if we passed a PDE boundary */
650  if (!((ULONG_PTR)PointerPte & (PD_SIZE - 1)) &&
651  (PointerPte != Subsection->SubsectionBase))
652  {
653  /* Check if the master PTE is invalid */
654  PteForProto = MiAddressToPte(PointerPte);
655  if (!PteForProto->u.Hard.Valid)
656  {
657  /* Fault it in */
659  }
660  }
661 
662  /* This should be a prototype PTE */
663  TempPte = *PointerPte;
664  ASSERT(SegmentFlags.LargePages == 0);
665  ASSERT(TempPte.u.Hard.Valid == 0);
666 
667  /* See if we should clean things up */
668  if (!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File))
669  {
670  /*
671  * This is a section backed by the pagefile. Now that it doesn't exist anymore,
672  * we can give everything back to the system.
673  */
674  ASSERT(TempPte.u.Soft.Prototype == 0);
675 
676  if (TempPte.u.Soft.Transition == 1)
677  {
678  /* We can give the page back for other use */
679  DPRINT("Releasing page for transition PTE %p\n", PointerPte);
680  PageFrameIndex = PFN_FROM_PTE(&TempPte);
681  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
682 
683  /* As this is a paged-backed section, nobody should reference it anymore (no cache or whatever) */
684  ASSERT(Pfn1->u3.ReferenceCount == 0);
685 
686  /* And it should be in standby or modified list */
688 
689  /* Unlink it and put it back in free list */
690  MiUnlinkPageFromList(Pfn1);
691 
692  /* Temporarily mark this as active and make it free again */
694  MI_SET_PFN_DELETED(Pfn1);
695 
696  MiInsertPageInFreeList(PageFrameIndex);
697  }
698  else if (TempPte.u.Soft.PageFileHigh != 0)
699  {
700  /* Should not happen for now */
701  ASSERT(FALSE);
702  }
703  }
704  else
705  {
706  /* unsupported for now */
707  ASSERT(FALSE);
708 
709  /* File-backed section must have prototype PTEs */
710  ASSERT(TempPte.u.Soft.Prototype == 1);
711  }
712 
713  /* Zero the PTE and keep going */
714  PointerPte->u.Long = 0;
715  PointerPte++;
716  }
717 
718  /* Release the PFN lock */
720 
721  /* Free the structures */
722  ExFreePool(ControlArea);
724 }
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
ULONG LargePages
Definition: mmtypes.h:394
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
USHORT ReferenceCount
Definition: mm.h:328
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
USHORT PageLocation
Definition: mm.h:297
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
union _MMPTE::@2236 u
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
union _CONTROL_AREA::@2489 u
_Inout_ PVOID Segment
Definition: exfuncs.h:893
LIST_ENTRY DereferenceList
Definition: mmtypes.h:513
#define PD_SIZE
Definition: miarm.h:28
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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:803
Definition: mm.h:305
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:482
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:198
ULONG BeingDeleted
Definition: mmtypes.h:454
ULONG WritableUserReferences
Definition: mmtypes.h:528
union _MMPFN::@1730 u3
MMSECTION_FLAGS Flags
Definition: mmtypes.h:522
#define PFN_FROM_PTE(v)
Definition: mm.h:89
PMMPTE SubsectionBase
Definition: mmtypes.h:570
#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 935 of file section.c.

937 {
938  KIRQL OldIrql;
939  ULONG Color, Index;
940  PMMPDE StartPde, EndPde;
942  PMMPFN Pfn1;
943  PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
944 
945  /* Windows sanity checks */
946  ASSERT(StartVa >= (PVOID)MmSessionBase);
947  ASSERT(EndVa < (PVOID)MiSessionSpaceEnd);
948  ASSERT(PAGE_ALIGN(EndVa) == EndVa);
949 
950  /* Get the start and end PDE, then loop each one */
951  StartPde = MiAddressToPde(StartVa);
952  EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
953  Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
954  while (StartPde <= EndPde)
955  {
956 #ifndef _M_AMD64
957  /* If we don't already have a page table for it, increment count */
958  if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
959 #endif
960  /* Move to the next one */
961  StartPde++;
962  Index++;
963  }
964 
965  /* If there's no page tables to create, bail out */
966  if (PageCount == 0) return STATUS_SUCCESS;
967 
968  /* Reset the start PDE and index */
969  StartPde = MiAddressToPde(StartVa);
970  Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
971 
972  /* Loop each PDE while holding the working set lock */
973 // MiLockWorkingSet(PsGetCurrentThread(),
974 // &MmSessionSpace->GlobalVirtualAddress->Vm);
975 #ifdef _M_AMD64
976 _WARN("MiSessionCommitPageTables halfplemented for amd64")
981  DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
982  ASSERT(FALSE);
983 #else
984  while (StartPde <= EndPde)
985  {
986  /* Check if we already have a page table */
987  if (MmSessionSpace->PageTables[Index].u.Long == 0)
988  {
989  /* We don't, so the PDE shouldn't be ready yet */
990  ASSERT(StartPde->u.Hard.Valid == 0);
991 
992  /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
993  ASSERT(MmAvailablePages >= 32);
994 
995  /* Acquire the PFN lock and grab a zero page */
998  MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
1000  PageFrameNumber = MiRemoveZeroPage(Color);
1001  TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
1002  MI_WRITE_VALID_PDE(StartPde, TempPde);
1003 
1004  /* Write the page table in session space structure */
1007 
1008  /* Initialize the PFN */
1009  MiInitializePfnForOtherProcess(PageFrameNumber,
1010  StartPde,
1012 
1013  /* And now release the lock */
1015 
1016  /* Get the PFN entry and make sure there's no event for it */
1017  Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1018  ASSERT(Pfn1->u1.Event == NULL);
1019 
1020  /* Increment the number of pages */
1021  ActualPages++;
1022  }
1023 
1024  /* Move to the next PDE */
1025  StartPde++;
1026  Index++;
1027  }
1028 #endif
1029 
1030  /* Make sure we didn't do more pages than expected */
1031  ASSERT(ActualPages <= PageCount);
1032 
1033  /* Release the working set lock */
1034 // MiUnlockWorkingSet(PsGetCurrentThread(),
1035 // &MmSessionSpace->GlobalVirtualAddress->Vm);
1036 
1037 
1038  /* If we did at least one page... */
1039  if (ActualPages)
1040  {
1041  /* Update the performance counters! */
1044  }
1045 
1046  /* Return status */
1047  return STATUS_SUCCESS;
1048 }
SIZE_T NonPageablePages
Definition: miarm.h:495
#define MiAddressToPde(x)
Definition: mmx86.c:20
PMMPDE PageTables
Definition: miarm.h:521
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
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:908
struct Color Color
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID MmSessionBase
Definition: init.c:33
ULONG PFN_NUMBER
Definition: ke.h:8
union _MMPTE::@2236 u
#define _WARN(msg)
Definition: debug.h:263
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
ULONG MmSecondaryColorMask
Definition: mminit.c:257
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1006
#define MI_SET_USAGE(x)
Definition: mm.h:253
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:326
ULONG PageFrameNumber
Definition: mmtypes.h:74
SIZE_T CommittedPages
Definition: miarm.h:496
ULONG64 Valid
Definition: mmtypes.h:150
static const UCHAR Index[8]
Definition: usbohci.c:18
PVOID MiSessionSpaceEnd
Definition: init.c:27
#define PAGE_ALIGN(Va)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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:803
Definition: mm.h:305
MMPTE ValidKernelPdeLocal
Definition: init.c:34
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
return STATUS_SUCCESS
Definition: btrfs.c:2966
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:494

Referenced by MiMapViewInSystemSpace().

◆ MiSetControlAreaSymbolsLoaded()

VOID NTAPI MiSetControlAreaSymbolsLoaded ( IN PCONTROL_AREA  ControlArea)

Definition at line 1142 of file section.c.

1143 {
1144  KIRQL OldIrql;
1145 
1147 
1149  ControlArea->u.Flags.DebugSymbolsLoaded |= 1;
1150 
1151  ASSERT(OldIrql <= APC_LEVEL);
1154 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#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 2063 of file section.c.

2071 {
2072  PMMPTE PointerPte, LastPte;
2073  MMPTE TempPte, PteContents;
2074  PMMPDE PointerPde;
2075  PMMPFN Pfn1;
2076  ULONG ProtectionMask, QuotaCharge = 0;
2078  PAGED_CODE();
2079 
2080  //
2081  // Tell caller nothing is being locked
2082  //
2083  *Locked = FALSE;
2084 
2085  //
2086  // This function should only be used for section VADs. Windows ASSERT */
2087  //
2088  ASSERT(FoundVad->u.VadFlags.PrivateMemory == 0);
2089 
2090  //
2091  // We don't support these features in ARM3
2092  //
2093  ASSERT(FoundVad->u.VadFlags.VadType != VadImageMap);
2094  ASSERT(FoundVad->u2.VadFlags2.CopyOnWrite == 0);
2095 
2096  //
2097  // Convert and validate the protection mask
2098  //
2099  ProtectionMask = MiMakeProtectionMask(NewProtect);
2100  if (ProtectionMask == MM_INVALID_PROTECTION)
2101  {
2102  DPRINT1("Invalid section protect\n");
2104  }
2105 
2106  //
2107  // Get the PTE and PDE for the address, as well as the final PTE
2108  //
2110  PointerPde = MiAddressToPde(StartingAddress);
2111  PointerPte = MiAddressToPte(StartingAddress);
2112  LastPte = MiAddressToPte(EndingAddress);
2113 
2114  //
2115  // Make the PDE valid, and check the status of the first PTE
2116  //
2118  if (PointerPte->u.Long)
2119  {
2120  //
2121  // Not supported in ARM3
2122  //
2123  ASSERT(FoundVad->u.VadFlags.VadType != VadRotatePhysical);
2124 
2125  //
2126  // Capture the page protection and make the PDE valid
2127  //
2128  *CapturedOldProtect = MiGetPageProtection(PointerPte);
2130  }
2131  else
2132  {
2133  //
2134  // Only pagefile-backed section VADs are supported for now
2135  //
2136  ASSERT(FoundVad->u.VadFlags.VadType != VadImageMap);
2137 
2138  //
2139  // Grab the old protection from the VAD itself
2140  //
2141  *CapturedOldProtect = MmProtectToValue[FoundVad->u.VadFlags.Protection];
2142  }
2143 
2144  //
2145  // Loop all the PTEs now
2146  //
2148  while (PointerPte <= LastPte)
2149  {
2150  //
2151  // Check if we've crossed a PDE boundary and make the new PDE valid too
2152  //
2153  if ((((ULONG_PTR)PointerPte) & (SYSTEM_PD_SIZE - 1)) == 0)
2154  {
2155  PointerPde = MiPteToPde(PointerPte);
2157  }
2158 
2159  //
2160  // Capture the PTE and see what we're dealing with
2161  //
2162  PteContents = *PointerPte;
2163  if (PteContents.u.Long == 0)
2164  {
2165  //
2166  // This used to be a zero PTE and it no longer is, so we must add a
2167  // reference to the pagetable.
2168  //
2170 
2171  //
2172  // Create the demand-zero prototype PTE
2173  //
2175  TempPte.u.Soft.Protection = ProtectionMask;
2176  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2177  }
2178  else if (PteContents.u.Hard.Valid == 1)
2179  {
2180  //
2181  // Get the PFN entry
2182  //
2183  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
2184 
2185  //
2186  // We don't support these yet
2187  //
2188  ASSERT((NewProtect & (PAGE_NOACCESS | PAGE_GUARD)) == 0);
2189  ASSERT(Pfn1->u3.e1.PrototypePte == 0);
2190 
2191  //
2192  // Write the protection mask and write it with a TLB flush
2193  //
2194  Pfn1->OriginalPte.u.Soft.Protection = ProtectionMask;
2195  MiFlushTbAndCapture(FoundVad,
2196  PointerPte,
2197  ProtectionMask,
2198  Pfn1,
2199  TRUE);
2200  }
2201  else
2202  {
2203  //
2204  // We don't support these cases yet
2205  //
2206  ASSERT(PteContents.u.Soft.Prototype == 0);
2207  ASSERT(PteContents.u.Soft.Transition == 0);
2208 
2209  //
2210  // The PTE is already demand-zero, just update the protection mask
2211  //
2212  PointerPte->u.Soft.Protection = ProtectionMask;
2213  }
2214 
2215  PointerPte++;
2216  }
2217 
2218  //
2219  // Unlock the working set and update quota charges if needed, then return
2220  //
2222  if ((QuotaCharge > 0) && (!DontCharge))
2223  {
2224  FoundVad->u.VadFlags.CommitCharge -= QuotaCharge;
2225  Process->CommitCharge -= QuotaCharge;
2226  }
2227  return STATUS_SUCCESS;
2228 }
#define MM_INVALID_PROTECTION
Definition: miarm.h:71
MMPTE PrototypePte
Definition: init.c:42
#define TRUE
Definition: types.h:120
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
#define PAGE_GUARD
Definition: nt_native.h:1310
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
USHORT PrototypePte
Definition: mm.h:295
MMPFNENTRY e1
Definition: mm.h:329
#define MiAddressToPte(x)
Definition: mmx86.c:19
union _MMPTE::@2236 u
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:260
#define PAGE_NOACCESS
Definition: nt_native.h:1302
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2371
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MM_NOIRQL
Definition: miarm.h:240
Definition: mm.h:305
ULONG64 Prototype
Definition: mmtypes.h:89
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:291
const ULONG MmProtectToValue[32]
Definition: page.c:81
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define SYSTEM_PD_SIZE
Definition: miarm.h:36
#define MiPteToPde(_Pte)
Definition: mm.h:233
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:980
ULONG64 Transition
Definition: mmtypes.h:90
ULONG NTAPI MiGetPageProtection(IN PMMPTE PointerPte)
Definition: virtual.c:1329
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:683
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE OriginalPte
Definition: mm.h:339
#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
union _MMPFN::@1730 u3
FORCEINLINE VOID MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:1672
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI MiFlushTbAndCapture(IN PMMVAD FoundVad, IN PMMPTE PointerPte, IN ULONG ProtectionMask, IN PMMPFN Pfn1, IN BOOLEAN UpdateDirty)
Definition: section.c:1959
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define PFN_FROM_PTE(v)
Definition: mm.h:89

◆ MiSubsectionConsistent()

VOID NTAPI MiSubsectionConsistent ( IN PSUBSECTION  Subsection)

Definition at line 1478 of file section.c.

1479 {
1480  /* ReactOS only supports systems with 4K pages and 4K sectors */
1481  ASSERT(Subsection->u.SubsectionFlags.SectorEndOffset == 0);
1482 
1483  /* Therefore, then number of PTEs should be equal to the number of sectors */
1484  if (Subsection->NumberOfFullSectors != Subsection->PtesInSubsection)
1485  {
1486  /* Break and warn if this is inconsistent */
1487  DPRINT1("Mm: Subsection inconsistent (%x vs %x)\n",
1488  Subsection->NumberOfFullSectors, Subsection->PtesInSubsection);
1489  DbgBreakPoint();
1490  }
1491 }
void DbgBreakPoint()
Definition: mach.c:553
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define DPRINT1
Definition: precomp.h:8

◆ MiUnmapViewInSystemSpace()

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

Definition at line 2378 of file section.c.

2380 {
2381  ULONG Size;
2382  PCONTROL_AREA ControlArea;
2383  PAGED_CODE();
2384 
2385  /* Remove this mapping */
2386  KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2387  Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2388 
2389  /* Clear the bits for this mapping */
2390  RtlClearBits(Session->SystemSpaceBitMap,
2391  (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2392  Size);
2393 
2394  /* Convert the size from a bit size into the actual size */
2395  Size = Size * (_64K >> PAGE_SHIFT);
2396 
2397  /* Remove the PTEs now */
2398  MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2399  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2400 
2401  /* Return success */
2402  return STATUS_SUCCESS;
2403 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
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:2232
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG NTAPI MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2334
smooth NULL
Definition: ftsmooth.c:416
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define _64K
Definition: miarm.h:19
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:493
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by MmUnmapViewInSessionSpace(), and MmUnmapViewInSystemSpace().

◆ MiUnmapViewOfSection()

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

Definition at line 817 of file section.c.

820 {
824  PMMVAD Vad;
825  PVOID DbgBase = NULL;
828  PETHREAD CurrentThread = PsGetCurrentThread();
830  PAGED_CODE();
831 
832  /* Check for Mm Region */
835  {
836  /* Call Mm API */
837  return MiRosUnmapViewOfSection(Process, BaseAddress, Process->ProcessExiting);
838  }
839 
840  /* Check if we should attach to the process */
841  if (CurrentProcess != Process)
842  {
843  /* The process is different, do an attach */
845  Attached = TRUE;
846  }
847 
848  /* Check if we need to lock the address space */
849  if (!Flags) MmLockAddressSpace(&Process->Vm);
850 
851  /* Check if the process is already daed */
852  if (Process->VmDeleted)
853  {
854  /* Fail the call */
855  DPRINT1("Process died!\n");
856  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
858  goto Quickie;
859  }
860 
861  /* Find the VAD for the address and make sure it's a section VAD */
863  if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
864  {
865  /* Couldn't find it, or invalid VAD, fail */
866  DPRINT1("No VAD or invalid VAD\n");
867  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
869  goto Quickie;
870  }
871 
872  /* We should be attached */
874 
875  /* We need the base address for the debugger message on image-backed VADs */
876  if (Vad->u.VadFlags.VadType == VadImageMap)
877  {
878  DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
879  }
880 
881  /* Compute the size of the VAD region */
882  RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
883 
884  /* For SEC_NO_CHANGE sections, we need some extra checks */
885  if (Vad->u.VadFlags.NoChange == 1)
886  {
887  /* Are we allowed to mess with this VAD? */
889  (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
890  RegionSize,
892  if (!NT_SUCCESS(Status))
893  {
894  /* We failed */
895  DPRINT1("Trying to unmap protected VAD!\n");
896  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
897  goto Quickie;
898  }
899  }
900 
901  /* Not currently supported */
903 
904  /* FIXME: Remove VAD charges */
905 
906  /* Lock the working set */
907  MiLockProcessWorkingSetUnsafe(Process, CurrentThread);
908 
909  /* Remove the VAD */
910  ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
911  MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
912 
913  /* Remove the PTEs for this view, which also releases the working set lock */
915 
916  /* FIXME: Remove commitment */
917 
918  /* Update performance counter and release the lock */
919  Process->VirtualSize -= RegionSize;
920  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
921 
922  /* Destroy the VAD and return success */
923  ExFreePool(Vad);
925 
926  /* Failure and success case -- send debugger message, detach, and return */
927 Quickie:
928  if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
930  return Status;
931 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
KAPC_STATE
Definition: ketypes.h:1273
ULONG Type
Definition: mm.h:214
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1431
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:780
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
ULONG_PTR NoChange
Definition: mmtypes.h:693
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
#define PAGED_CODE()
Definition: video.h:57
#define MM_DELETE_CHECK
Definition: miarm.h:270
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static BOOL Attached
Definition: vidbios.c:3905
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:73
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:4137
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:48
void * PVOID
Definition: retypes.h:9
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
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
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:488
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1492
union _MMVAD::@2496 u
#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:248
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:65
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1424
ULONG_PTR VadType
Definition: mmtypes.h:694
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by MmUnmapViewOfSection(), and NtUnmapViewOfSection().

◆ MmCommitSessionMappedView()

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

Definition at line 3085 of file section.c.

3087 {
3088  ULONG_PTR StartAddress, EndingAddress, Base;
3089  ULONG Hash, Count = 0, Size, QuotaCharge;
3090  PMMSESSION Session;
3091  PMMPTE LastProtoPte, PointerPte, ProtoPte;
3092  PCONTROL_AREA ControlArea;
3093  PSEGMENT Segment;
3094  PSUBSECTION Subsection;
3095  MMPTE TempPte;
3096  PAGED_CODE();
3097 
3098  /* Make sure the base isn't past the session view range */
3099  if ((MappedBase < MiSessionViewStart) ||
3101  {
3102  DPRINT1("Base outside of valid range\n");
3104  }
3105 
3106  /* Make sure the size isn't past the session view range */
3109  {
3110  DPRINT1("Size outside of valid range\n");
3112  }
3113 
3114  /* Sanity check */
3115  ASSERT(ViewSize != 0);
3116 
3117  /* Process must be in a session */
3118  if (PsGetCurrentProcess()->ProcessInSession == FALSE)
3119  {
3120  DPRINT1("Process is not in session\n");
3121  return STATUS_NOT_MAPPED_VIEW;
3122  }
3123 
3124  /* Compute the correctly aligned base and end addresses */
3125  StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
3126  EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
3127 
3128  /* Sanity check and grab the session */
3130  Session = &MmSessionSpace->Session;
3131 
3132  /* Get the hash entry for this allocation */
3133  Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
3134 
3135  /* Lock system space */
3137 
3138  /* Loop twice so we can try rolling over if needed */
3139  while (TRUE)
3140  {
3141  /* Extract the size and base addresses from the entry */
3142  Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
3143  Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
3144 
3145  /* Convert the size to bucket chunks */
3147 
3148  /* Bail out if this entry fits in here */
3149  if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
3150 
3151  /* Check if we overflew past the end of the hash table */
3152  if (++Hash >= Session->SystemSpaceHashSize)
3153  {
3154  /* Reset the hash to zero and keep searching from the bottom */
3155  Hash = 0;
3156  if (++Count == 2)
3157  {
3158  /* But if we overflew twice, then this is not a real mapping */
3159  KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
3160  Base,
3161  2,
3162  0,
3163  0);
3164  }
3165  }
3166  }
3167 
3168  /* Make sure the view being mapped is not file-based */
3169  ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
3170  if (ControlArea->FilePointer != NULL)
3171  {
3172  /* It is, so we have to bail out */
3173  DPRINT1("Only page-filed backed sections can be commited\n");
3175  return STATUS_ALREADY_COMMITTED;
3176  }
3177 
3178  /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
3179  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
3180  ASSERT(ControlArea->u.Flags.Rom == 0);
3181  Subsection = (PSUBSECTION)(ControlArea + 1);
3182 
3183  /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
3184  ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
3185  QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
3186  LastProtoPte = ProtoPte + QuotaCharge;
3187  if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
3188  {
3189  DPRINT1("PTE is out of bounds\n");
3192  }
3193 
3194  /* Acquire the commit lock and count all the non-committed PTEs */
3196  PointerPte = ProtoPte;
3197  while (PointerPte < LastProtoPte)
3198  {
3199  if (PointerPte->u.Long) QuotaCharge--;
3200  PointerPte++;
3201  }
3202 
3203  /* Was everything committed already? */
3204  if (!QuotaCharge)
3205  {
3206  /* Nothing to do! */
3209  return STATUS_SUCCESS;
3210  }
3211 
3212  /* Pick the segment and template PTE */
3213  Segment = ControlArea->Segment;
3214  TempPte = Segment->SegmentPteTemplate;
3215  ASSERT(TempPte.u.Long != 0);
3216 
3217  /* Loop all prototype PTEs to be committed */
3218  PointerPte = ProtoPte;
3219  while (PointerPte < LastProtoPte)
3220  {
3221  /* Make sure the PTE is already invalid */
3222  if (PointerPte->u.Long == 0)
3223  {
3224  /* And write the invalid PTE */
3225  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
3226  }
3227 
3228  /* Move to the next PTE */
3229  PointerPte++;
3230  }
3231 
3232  /* Check if we had at least one page charged */
3233  if (QuotaCharge)
3234  {
3235  /* Update the accounting data */
3236  Segment->NumberOfCommittedPages += QuotaCharge;
3238  }
3239 
3240  /* Release all */
3243  return STATUS_SUCCESS;
3244 }
static int Hash(const char *)
Definition: reader.c:2257
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
PFILE_OBJECT FilePointer
Definition: mmtypes.h:524
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
SIZE_T MmSharedCommit
Definition: freelist.c:31
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:256
#define MiAddressToPte(x)
Definition: mmx86.c:19
union _MMPTE::@2236 u
ULONG MmSessionViewSize
Definition: init.c:35
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
union _CONTROL_AREA::@2489 u
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:467
ULONG SystemSpaceHashKey
Definition: miarm.h:470
_Inout_ PVOID Segment
Definition: exfuncs.h:893
MMSESSION Session
Definition: miarm.h:511
#define PAGE_ALIGN(Va)
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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:465
PCONTROL_AREA ControlArea
Definition: miarm.h:459
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:482
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
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:980
PVOID MiSessionViewStart
Definition: init.c:30
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:275
PSEGMENT Segment
Definition: mmtypes.h:512
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:493
_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:522
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:248
#define ULONG_PTR
Definition: config.h:101
ULONG_PTR Entry
Definition: miarm.h:458
ULONG SystemSpaceHashSize
Definition: miarm.h:468
return STATUS_SUCCESS
Definition: btrfs.c:2966
PMMPTE SubsectionBase
Definition: mmtypes.h:570
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:107
ULONG PtesInSubsection
Definition: mmtypes.h:572

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

2420 {
2421  SECTION Section;
2422  PSECTION NewSection;
2423  PSUBSECTION Subsection;
2424  PSEGMENT NewSegment, Segment;
2425  NTSTATUS Status;
2426  PCONTROL_AREA ControlArea;
2427  ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2429  BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2430  KIRQL OldIrql;
2432  BOOLEAN UserRefIncremented = FALSE;
2433  PVOID PreviousSectionPointer;
2434 
2435  /* Make the same sanity checks that the Nt interface should've validated */
2438  SEC_NO_CHANGE)) == 0);
2442  SEC_NOCACHE | SEC_NO_CHANGE))));
2448 
2449  /* Convert section flag to page flag */
2451 
2452  /* Check to make sure the protection is correct. Nt* does this already */
2453  ProtectionMask = MiMakeProtectionMask(SectionPageProtection);
2454  if (ProtectionMask == MM_INVALID_PROTECTION) return STATUS_INVALID_PAGE_PROTECTION;
2455 
2456  /* Check if this is going to be a data or image backed file section */
2457  if ((FileHandle) || (FileObject))
2458  {
2459  /* These cannot be mapped with large pages */
2461 
2462  /* For now, only support the mechanism through a file handle */
2463  ASSERT(FileObject == NULL);
2464 
2465  /* Reference the file handle to get the object */
2467  MmMakeFileAccess[ProtectionMask],
2469  PreviousMode,
2470  (PVOID*)&File,
2471  NULL);
2472  if (!NT_SUCCESS(Status)) return Status;
2473 
2474  /* Make sure Cc has been doing its job */
2475  if (!File->SectionObjectPointer)
2476  {
2477  /* This is not a valid file system-based file, fail */
2480  }
2481 
2482  /* Image-file backed sections are not yet supported */
2484 
2485  /* Compute the size of the control area, and allocate it */
2486  ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2487  ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2488  if (!ControlArea)
2489  {
2492  }
2493 
2494  /* Zero it out */
2495  RtlZeroMemory(ControlArea, ControlAreaSize);
2496 
2497  /* Did we get a handle, or an object? */
2498  if (FileHandle)
2499  {
2500  /* We got a file handle so we have to lock down the file */
2501 #if 0
2502  Status = FsRtlAcquireToCreateMappedSection(File, SectionPageProtection);
2503  if (!NT_SUCCESS(Status))
2504  {
2505  ExFreePool(ControlArea);
2507  return Status;
2508  }
2509 #else
2510  /* ReactOS doesn't support this API yet, so do nothing */
2512 #endif
2513  /* Update the top-level IRP so that drivers know what's happening */
2515  FileLock = TRUE;
2516  }
2517 
2518  /* Lock the PFN database while we play with the section pointers */
2520 
2521  /* Image-file backed sections are not yet supported */
2523 
2524  /* There should not already be a control area for this file */
2525  ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2526  NewSegment = NULL;
2527 
2528  /* Write down that this CA is being created, and set it */
2529  ControlArea->u.Flags.BeingCreated = TRUE;
2531  PreviousSectionPointer = File->SectionObjectPointer;
2532  File->SectionObjectPointer->DataSectionObject = ControlArea;
2533 
2534  /* We can release the PFN lock now */
2536 
2537  /* We don't support previously-mapped file */
2538  ASSERT(NewSegment == NULL);
2539 
2540  /* Image-file backed sections are not yet supported */
2542 
2543  /* So we always create a data file map */
2545  &Segment,
2546  (PSIZE_T)InputMaximumSize,
2549  KernelCall);
2550  if (!NT_SUCCESS(Status))
2551  {
2552  /* Lock the PFN database while we play with the section pointers */
2554 
2555  /* Reset the waiting-for-deletion event */
2556  ASSERT(ControlArea->WaitingForDeletion == NULL);
2557  ControlArea->WaitingForDeletion = NULL;
2558 
2559  /* Set the file pointer NULL flag */
2560  ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2561  ControlArea->u.Flags.FilePointerNull = TRUE;
2562 
2563  /* Delete the data section object */
2565  File->SectionObjectPointer->DataSectionObject = NULL;
2566 
2567  /* No longer being created */
2568  ControlArea->u.Flags.BeingCreated = FALSE;
2569 
2570  /* We can release the PFN lock now */
2572 
2573  /* Check if we locked and set the IRP */
2574  if (FileLock)
2575  {
2576  /* Undo */
2578  //FsRtlReleaseFile(File);
2579  }
2580 
2581  /* Free the control area and de-ref the file object */
2582  ExFreePool(ControlArea);
2584 
2585  /* All done */
2586  return Status;
2587  }
2588 
2589  /* On success, we expect this */
2590  ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2591 
2592  /* Check if a maximum size was specified */
2593  if (!InputMaximumSize->QuadPart)
2594  {
2595  /* Nope, use the segment size */
2596  Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2597  }
2598  else
2599  {
2600  /* Yep, use the entered size */
2601  Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2602  }
2603  }
2604  else
2605  {
2606  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2608 
2609  /* Not yet supported */
2611 
2612  /* So this must be a pagefile-backed section, create the mappings needed */
2613  Status = MiCreatePagingFileMap(&NewSegment,
2614  (PSIZE_T)InputMaximumSize,
2615  ProtectionMask,
2617  if (!NT_SUCCESS(Status)) return Status;
2618 
2619  /* Set the size here, and read the control area */
2620  Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2621  ControlArea = NewSegment->ControlArea;
2622 
2623  /* MiCreatePagingFileMap increments user references */
2624  UserRefIncremented = TRUE;
2625  }
2626 
2627  /* Did we already have a segment? */
2628  if (!NewSegment)
2629  {
2630  /* This must be the file path and we created a segment */
2631  NewSegment = Segment;
2632  ASSERT(File != NULL);
2633 
2634  /* Acquire the PFN lock while we set control area flags */
2636 
2637  /* We don't support this race condition yet, so assume no waiters */
2638  ASSERT(ControlArea->WaitingForDeletion == NULL);
2639  ControlArea->WaitingForDeletion = NULL;
2640 
2641  /* Image-file backed sections are not yet supported, nor ROM images */
2643  ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2644 
2645  /* Take off the being created flag, and then release the lock */
2646  ControlArea->u.Flags.BeingCreated = FALSE;
2648  }
2649 
2650  /* Check if we locked the file earlier */
2651  if (FileLock)
2652  {
2653  /* Reset the top-level IRP and release the lock */
2655  //FsRtlReleaseFile(File);
2656  FileLock = FALSE;
2657  }
2658 
2659  /* Set the initial section object data */
2660  Section.InitialPageProtection = SectionPageProtection;
2661 
2662  /* The mapping created a control area and segment, save the flags */
2663  Section.Segment = NewSegment;
2664  Section.u.LongFlags = ControlArea->u.LongFlags;
2665 
2666  /* Check if this is a user-mode read-write non-image file mapping */
2667  if (!(FileObject) &&
2669  !(ControlArea->u.Flags.Image) &&
2670  (ControlArea->FilePointer))
2671  {
2672  /* Add a reference and set the flag */
2673  Section.u.Flags.UserWritable = TRUE;
2674  InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2675  }
2676 
2677  /* Check for image mappings or page file mappings */
2678  if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2679  {
2680  /* Charge the segment size, and allocate a subsection */
2681  PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2682  Size = sizeof(SUBSECTION);
2683  }
2684  else
2685  {
2686  /* Charge nothing, and allocate a mapped subsection */
2687  PagedCharge = 0;
2688  Size = sizeof(MSUBSECTION);
2689  }
2690 
2691  /* Check if this is a normal CA */
2692  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2693  ASSERT(ControlArea->u.Flags.Rom == 0);
2694 
2695  /* Charge only a CA, and the subsection is right after */
2696  NonPagedCharge = sizeof(CONTROL_AREA);
2697  Subsection = (PSUBSECTION)(ControlArea + 1);
2698 
2699  /* We only support single-subsection mappings */
2700  NonPagedCharge += Size;
2701  ASSERT(Subsection->NextSubsection == NULL);
2702 
2703  /* Create the actual section object, with enough space for the prototype PTEs */
2707  PreviousMode,
2708  NULL,
2709  sizeof(SECTION),
2710  PagedCharge,
2711  NonPagedCharge,
2712  (PVOID*)&NewSection);
2713  if (!NT_SUCCESS(Status))
2714  {
2715  /* Check if this is a user-mode read-write non-image file mapping */
2716  if (!(FileObject) &&
2718  !(ControlArea->u.Flags.Image) &&
2719  (ControlArea->FilePointer))
2720  {
2721  /* Remove a reference and check the flag */
2722  ASSERT(Section.u.Flags.UserWritable == 1);
2723  InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2724  }
2725 
2726  /* Check if a user reference was added */
2727  if (UserRefIncremented)
2728  {
2729  /* Acquire the PFN lock while we change counters */
2731 
2732  /* Decrement the accounting counters */
2733  ControlArea->NumberOfSectionReferences--;
2734  ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2735  ControlArea->NumberOfUserReferences--;
2736 
2737  /* Check if we should destroy the CA and release the lock */
2738  MiCheckControlArea(ControlArea, OldIrql);
2739  }
2740 
2741  /* Return the failure code */
2742  return Status;
2743  }
2744 
2745  /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2746 
2747  /* Now copy the local section object from the stack into this new object */
2748  RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2749  NewSection->Address.StartingVpn = 0;
2750 
2751  /* For now, only user calls are supported */
2752  ASSERT(KernelCall == FALSE);
2753  NewSection->u.Flags.UserReference = TRUE;
2754 
2755  /* Is this a "based" allocation, in which all mappings are identical? */
2757  {
2758  /* Lock the VAD tree during the search */
2760 
2761  /* Is it a brand new ControArea ? */
2762  if (ControlArea->u.Flags.BeingCreated == 1)
2763  {
2764  ASSERT(ControlArea->u.Flags.Based == 1);
2765  /* Then we must find a global address, top-down */
2768  _64K,
2770  (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2771 
2772  if (!NT_SUCCESS(Status))
2773  {
2774  /* No way to find a valid range. */
2776  ControlArea->u.Flags.Based = 0;
2777  NewSection->u.Flags.Based = 0;
2778  ObDereferenceObject(NewSection);
2779  return Status;
2780  }
2781 
2782  /* Compute the ending address and insert it into the VAD tree */
2783  NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2784  NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2785  MiInsertBasedSection(NewSection);
2786  }
2787  else
2788  {
2789  /* 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 !*/
2790  ASSERT(FALSE);
2791  }
2792 
2794  }
2795 
2796  /* The control area is not being created anymore */
2797  if (ControlArea->u.Flags.BeingCreated == 1)
2798  {
2799  /* Acquire the PFN lock while we set control area flags */
2801 
2802  /* Take off the being created flag, and then release the lock */
2803  ControlArea->u.Flags.BeingCreated = 0;
2804  NewSection->u.Flags.BeingCreated = 0;
2805 
2807  }
2808 
2809  /* Migrate the attribute into a flag */
2810  if (AllocationAttributes & SEC_NO_CHANGE) NewSection->u.Flags.NoChange = TRUE;
2811 
2812  /* If R/W access is not requested, this might eventually become a CoW mapping */
2814  {
2815  NewSection->u.Flags.CopyOnWrite = TRUE;
2816  }
2817 
2818  /* Write down if this was a kernel call */
2819  ControlArea->u.Flags.WasPurged |= KernelCall;
2820  ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2821 
2822  /* Make sure the segment and the section are the same size, or the section is smaller */
2823  ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2824 
2825  /* Return the object and the creation status */
2826  *SectionObject = (PVOID)NewSection;
2827  return Status;
2828 }
ULONG NoChange
Definition: mmtypes.h:477
_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:71
PEVENT_COUNTER WaitingForDeletion
Definition: mmtypes.h:525
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PFILE_OBJECT FilePointer
Definition: mmtypes.h:524
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
ULONGLONG SizeOfSegment
Definition: mmtypes.h:404
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
ULONG UserReference
Definition: mmtypes.h:470
ULONG NumberOfSectionReferences
Definition: mmtypes.h:514
PSEGMENT Segment
Definition: mmtypes.h:812
NTSTATUS NTAPI MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1495
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define PAGE_GUARD
Definition: nt_native.h:1310
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
LONG NTSTATUS
Definition: precomp.h:26
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define SEC_NOCACHE
Definition: mmtypes.h:100
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree(IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base)
Definition: vadnode.c:713
ULONG TotalNumberOfPtes
Definition: mmtypes.h:401
struct _SUBSECTION SUBSECTION
NTSTATUS NTAPI MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1510
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:345
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:400
uint32_t ULONG_PTR
Definition: typedefs.h:63