ReactOS  0.4.11-dev-195-gef016bf
section.c File Reference
#include <ntoskrnl.h>
#include <ntintsafe.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

#define MODULE_INVOLVED_IN_ARM3

Definition at line 16 of file section.c.

#define NDEBUG

Definition at line 13 of file section.c.

Function Documentation

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

Definition at line 418 of file section.c.

Referenced by MiMapViewInSystemSpace().

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

Definition at line 141 of file section.c.

142 {
143  ULONG ProtectionMask;
144 
145  /* Calculate the protection mask and make sure it's valid */
147  if (ProtectionMask == MM_INVALID_PROTECTION)
148  {
149  DPRINT1("Invalid protection mask\n");
151  }
152 
153  /* Now convert it to the required file access */
154  return MmMakeFileAccess[ProtectionMask & 0x7];
155 }
#define MM_INVALID_PROTECTION
Definition: miarm.h:71
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:33
_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:159
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:291
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI MiCheckControlArea ( IN PCONTROL_AREA  ControlArea,
IN KIRQL  OldIrql 
)

Definition at line 729 of file section.c.

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

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

Definition at line 545 of file section.c.

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

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

Referenced by MmCreateArm3Section().

1502 {
1503  /* Not yet implemented */
1504  ASSERT(FALSE);
1505  *Segment = NULL;
1506  return STATUS_NOT_IMPLEMENTED;
1507 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PVOID Segment
Definition: exfuncs.h:893
NTSTATUS NTAPI MiCreatePagingFileMap ( OUT PSEGMENT Segment,
IN PSIZE_T  MaximumSize,
IN ULONG  ProtectionMask,
IN ULONG  AllocationAttributes 
)

Definition at line 1511 of file section.c.

Referenced by MmCreateArm3Section().

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

Definition at line 3247 of file section.c.

Referenced by MmpDeleteSection().

3248 {
3250  PCONTROL_AREA ControlArea;
3251  KIRQL OldIrql;
3252 
3253  SectionObject = (PSECTION)ObjectBody;
3254 
3255  if (SectionObject->u.Flags.Based == 1)
3256  {
3257  /* Remove the node from the global section address tree */
3259  MiRemoveNode(&SectionObject->Address, &MmSectionBasedRoot);
3261  }
3262 
3263  /* Lock the PFN database */
3264  OldIrql = MiAcquirePfnLock();
3265 
3266  ASSERT(SectionObject->Segment);
3267  ASSERT(SectionObject->Segment->ControlArea);
3268 
3269  ControlArea = SectionObject->Segment->ControlArea;
3270 
3271  /* Dereference */
3272  ControlArea->NumberOfSectionReferences--;
3273  ControlArea->NumberOfUserReferences--;
3274 
3275  ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
3276 
3277  /* Check it. It will delete it if there is no more reference to it */
3278  MiCheckControlArea(ControlArea, OldIrql);
3279 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
ULONG NumberOfSectionReferences
Definition: mmtypes.h:515
PSEGMENT Segment
Definition: mmtypes.h:813
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:111
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:110
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:401
union _SECTION::@2496 u
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _SECTION * PSECTION
MMSECTION_FLAGS Flags
Definition: mmtypes.h:818
_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:455
MMADDRESS_NODE Address
Definition: mmtypes.h:812
ULONG NumberOfUserReferences
Definition: mmtypes.h:519
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:729
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
union _CONTROL_AREA::@2480 u
MMSECTION_FLAGS Flags
Definition: mmtypes.h:523
VOID NTAPI MiDereferenceControlArea ( IN PCONTROL_AREA  ControlArea)

Definition at line 764 of file section.c.

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

765 {
766  KIRQL OldIrql;
767 
768  /* Lock the PFN database */
769  OldIrql = MiAcquirePfnLock();
770 
771  /* Drop reference counts */
772  ControlArea->NumberOfMappedViews--;
773  ControlArea->NumberOfUserReferences--;
774 
775  /* Check if it's time to delete the CA. This releases the lock */
776  MiCheckControlArea(ControlArea, OldIrql);
777 }
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
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:729
VOID NTAPI MiFillSystemPageDirectory ( IN PVOID  Base,
IN SIZE_T  NumberOfBytes 
)

Definition at line 477 of file section.c.

Referenced by MiMapViewInSystemSpace(), and MmGetPageTableForProcess().

479 {
480  PMMPDE PointerPde, LastPde, SystemMapPde;
481  MMPDE TempPde;
482  PFN_NUMBER PageFrameIndex, ParentPage;
483  KIRQL OldIrql;
484  PAGED_CODE();
485 
486  /* Find the PDEs needed for this mapping */
487  PointerPde = MiAddressToPde(Base);
488  LastPde = MiAddressToPde((PVOID)((ULONG_PTR)Base + NumberOfBytes - 1));
489 
490 #if (_MI_PAGING_LEVELS == 2)
491  /* Find the system double-mapped PDE that describes this mapping */
492  SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
493 #else
494  /* We don't have a double mapping */
495  SystemMapPde = PointerPde;
496 #endif
497 
498  /* Use the PDE template and loop the PDEs */
499  TempPde = ValidKernelPde;
500  while (PointerPde <= LastPde)
501  {
502  /* Lock the PFN database */
503  OldIrql = MiAcquirePfnLock();
504 
505  /* Check if we don't already have this PDE mapped */
506  if (SystemMapPde->u.Hard.Valid == 0)
507  {
508  /* Grab a page for it */
510  MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
511  PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
512  ASSERT(PageFrameIndex);
513  TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
514 
515 #if (_MI_PAGING_LEVELS == 2)
516  ParentPage = MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_COUNT];
517 #else
518  ParentPage = MiPdeToPpe(PointerPde)->u.Hard.PageFrameNumber;
519 #endif
520  /* Initialize its PFN entry, with the parent system page directory page table */
521  MiInitializePfnForOtherProcess(PageFrameIndex,
522  (PMMPTE)PointerPde,
523  ParentPage);
524 
525  /* Make the system PDE entry valid */
526  MI_WRITE_VALID_PDE(SystemMapPde, TempPde);
527 
528  /* The system PDE entry might be the PDE itself, so check for this */
529  if (PointerPde->u.Hard.Valid == 0)
530  {
531  /* It's different, so make the real PDE valid too */
532  MI_WRITE_VALID_PDE(PointerPde, TempPde);
533  }
534  }
535 
536  /* Release the lock and keep going with the next PDE */
537  MiReleasePfnLock(OldIrql);
538  SystemMapPde++;
539  PointerPde++;
540  }
541 }
DWORD *typedef PVOID
Definition: winlogon.h:61
#define MiAddressToPde(x)
Definition: mmx86.c:20
union _MMPTE::@2227 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:211
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:77
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
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:901
#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
#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:971
#define MI_SET_USAGE(x)
Definition: mm.h:253
PMMPDE MmSystemPagePtes
Definition: init.c:41
#define MiPdeToPpe(_Pde)
Definition: mm.h:233
ULONG64 Valid
Definition: mmtypes.h:150
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
IN SIZE_T NumberOfBytes
Definition: ndis.h:3915
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
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
VOID NTAPI MiFlushTbAndCapture ( IN PMMVAD  FoundVad,
IN PMMPTE  PointerPte,
IN ULONG  ProtectionMask,
IN PMMPFN  Pfn1,
IN BOOLEAN  UpdateDirty 
)

Definition at line 1958 of file section.c.

Referenced by MiProtectVirtualMemory(), and MiSetProtectionOnSection().

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

Definition at line 1619 of file section.c.

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

Definition at line 1702 of file section.c.

Referenced by MmGetFileNameForAddress(), and NtAreMappedFilesTheSame().

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

Definition at line 241 of file section.c.

Referenced by MiBuildPagedPool(), and MiSessionCreateInternal().

242 {
243  SIZE_T AllocSize, BitmapSize, Size;
244  PVOID ViewStart;
245  PMMSESSION Session;
246 
247  /* Check if this a session or system space */
248  if (InputSession)
249  {
250  /* Use the input session */
251  Session = InputSession;
252  ViewStart = MiSessionViewStart;
253  Size = MmSessionViewSize;
254  }
255  else
256  {
257  /* Use the system space "session" */
258  Session = &MmSession;
259  ViewStart = MiSystemViewStart;
260  Size = MmSystemViewSize;
261  }
262 
263  /* Initialize the system space lock */
264  Session->SystemSpaceViewLockPointer = &Session->SystemSpaceViewLock;
266 
267  /* Set the start address */
268  Session->SystemSpaceViewStart = ViewStart;
269 
270  /* Create a bitmap to describe system space */
271  BitmapSize = sizeof(RTL_BITMAP) + ((((Size / MI_SYSTEM_VIEW_BUCKET_SIZE) + 31) / 32) * sizeof(ULONG));
273  BitmapSize,
274  TAG_MM);
275  ASSERT(Session->SystemSpaceBitMap);
277  (PULONG)(Session->SystemSpaceBitMap + 1),
279 
280  /* Set system space fully empty to begin with */
282 
283  /* Set default hash flags */
284  Session->SystemSpaceHashSize = 31;
285  Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
286  Session->SystemSpaceHashEntries = 0;
287 
288  /* Calculate how much space for the hash views we'll need */
289  AllocSize = sizeof(MMVIEW) * Session->SystemSpaceHashSize;
290  ASSERT(AllocSize < PAGE_SIZE);
291 
292  /* Allocate and zero the view table */
293  Session->SystemSpaceViewTable = ExAllocatePoolWithTag(Session == &MmSession ?
294  NonPagedPool :
295  PagedPool,
296  AllocSize,
297  TAG_MM);
298  ASSERT(Session->SystemSpaceViewTable != NULL);
299  RtlZeroMemory(Session->SystemSpaceViewTable, AllocSize);
300 
301  /* Success */
302  return TRUE;
303 }
DWORD *typedef PVOID
Definition: winlogon.h:61
#define TRUE
Definition: types.h:120
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
struct _RTL_BITMAP RTL_BITMAP
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PCHAR SystemSpaceViewStart
Definition: miarm.h:431
ULONG SystemSpaceHashEntries
Definition: miarm.h:434
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:429
#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:432
ULONG SystemSpaceHashKey
Definition: miarm.h:435
UINTN Size
Definition: acefiex.h:555
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
struct _MMVIEW MMVIEW
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:430
#define PAGE_SIZE
Definition: env_spec_w32.h:49
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:437
PVOID MiSessionViewStart
Definition: init.c:30
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:240
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:433
MMSESSION MmSession
Definition: section.c:108
PVOID NTAPI MiInsertInSystemSpace ( IN PMMSESSION  Session,
IN ULONG  Buckets,
IN PCONTROL_AREA  ControlArea 
)

Definition at line 307 of file section.c.

Referenced by MiMapViewInSystemSpace().

310 {
311  PVOID Base;
312  ULONG Entry, Hash, i, HashSize;
313  PMMVIEW OldTable;
314  PAGED_CODE();
315 
316  /* Stay within 4GB */
318 
319  /* Lock system space */
320  KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
321 
322  /* Check if we're going to exhaust hash entries */
323  if ((Session->SystemSpaceHashEntries + 8) > Session->SystemSpaceHashSize)
324  {
325  /* Double the hash size */
326  HashSize = Session->SystemSpaceHashSize * 2;
327 
328  /* Save the old table and allocate a new one */
329  OldTable = Session->SystemSpaceViewTable;
330  Session->SystemSpaceViewTable = ExAllocatePoolWithTag(Session ==
331  &MmSession ?
332  NonPagedPool :
333  PagedPool,
334  HashSize *
335  sizeof(MMVIEW),
336  TAG_MM);
337  if (!Session->SystemSpaceViewTable)
338  {
339  /* Failed to allocate a new table, keep the old one for now */
340  Session->SystemSpaceViewTable = OldTable;
341  }
342  else
343  {
344  /* Clear the new table and set the new ahsh and key */
345  RtlZeroMemory(Session->SystemSpaceViewTable, HashSize * sizeof(MMVIEW));
346  Session->SystemSpaceHashSize = HashSize;
347  Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
348 
349  /* Loop the old table */
350  for (i = 0; i < Session->SystemSpaceHashSize / 2; i++)
351  {
352  /* Check if the entry was valid */
353  if (OldTable[i].Entry)
354  {
355  /* Re-hash the old entry and search for space in the new table */
356  Hash = (OldTable[i].Entry >> 16) % Session->SystemSpaceHashKey;
357  while (Session->SystemSpaceViewTable[Hash].Entry)
358  {
359  /* Loop back at the beginning if we had an overflow */
360  if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
361  }
362 
363  /* Write the old entry in the new table */
364  Session->SystemSpaceViewTable[Hash] = OldTable[i];
365  }
366  }
367 
368  /* Free the old table */
369  ExFreePool(OldTable);
370  }
371  }
372 
373  /* Check if we ran out */
374  if (Session->SystemSpaceHashEntries == Session->SystemSpaceHashSize)
375  {
376  DPRINT1("Ran out of system view hash entries\n");
377  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
378  return NULL;
379  }
380 
381  /* Find space where to map this view */
382  i = RtlFindClearBitsAndSet(Session->SystemSpaceBitMap, Buckets, 0);
383  if (i == 0xFFFFFFFF)
384  {
385  /* Out of space, fail */
386  Session->BitmapFailures++;
387  DPRINT1("Out of system view space\n");
388  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
389  return NULL;
390  }
391 
392  /* Compute the base address */
393  Base = (PVOID)((ULONG_PTR)Session->SystemSpaceViewStart + (i * MI_SYSTEM_VIEW_BUCKET_SIZE));
394 
395  /* Get the hash entry for this allocation */
396  Entry = ((ULONG_PTR)Base & ~(MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) + Buckets;
397  Hash = (Entry >> 16) % Session->SystemSpaceHashKey;
398 
399  /* Loop hash entries until a free one is found */
400  while (Session->SystemSpaceViewTable[Hash].Entry)
401  {
402  /* Unless we overflow, in which case loop back at hash o */
403  if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
404  }
405 
406  /* Add this entry into the hash table */
407  Session->SystemSpaceViewTable[Hash].Entry = Entry;
408  Session->SystemSpaceViewTable[Hash].ControlArea = ControlArea;
409 
410  /* Hash entry found, increment total and return the base address */
411  Session->SystemSpaceHashEntries++;
412  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
413  return Base;
414 }
DWORD *typedef PVOID
Definition: winlogon.h:61
static int Hash(const char *)
Definition: reader.c:2258
struct _Entry Entry
Definition: kefuncs.h:640
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
while(1)
Definition: macro.lex.yy.c:743
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define TAG_MM
Definition: tag.h:136
smooth NULL
Definition: ftsmooth.c:416
#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:240
Definition: miarm.h:421
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:423
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
MMSESSION MmSession
Definition: section.c:108
BOOLEAN NTAPI MiIsProtectionCompatible ( IN ULONG  SectionPageProtection,
IN ULONG  NewSectionPageProtection 
)

Definition at line 118 of file section.c.

Referenced by MmMapViewOfArm3Section().

120 {
121  ULONG ProtectionMask, CompatibleMask;
122 
123  /* Calculate the protection mask and make sure it's valid */
125  if (ProtectionMask == MM_INVALID_PROTECTION)
126  {
127  DPRINT1("Invalid protection mask\n");
128  return FALSE;
129  }
130 
131  /* Calculate the compatible mask */
132  CompatibleMask = MmCompatibleProtectionMask[ProtectionMask & 0x7] |
134 
135  /* See if the mapping protection is compatible with the create protection */
136  return ((CompatibleMask | NewSectionPageProtection) == CompatibleMask);
137 }
#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
#define FALSE
Definition: types.h:117
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:159
ULONG MmCompatibleProtectionMask[8]
Definition: section.c:85
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI MiLoadUserSymbols ( IN PCONTROL_AREA  ControlArea,
IN PVOID  BaseAddress,
IN PEPROCESS  Process 
)

Definition at line 1159 of file section.c.

1162 {
1163  NTSTATUS Status;
1165  PLIST_ENTRY NextEntry;
1167  PIMAGE_NT_HEADERS NtHeaders;
1168  PLDR_DATA_TABLE_ENTRY LdrEntry;
1169 
1170  FileName = &ControlArea->FilePointer->FileName;
1171  if (FileName->Length == 0)
1172  {
1173  return;
1174  }
1175 
1176  /* Acquire module list lock */
1179 
1180  /* Browse list to try to find current module */
1181  for (NextEntry = MmLoadedUserImageList.Flink;
1182  NextEntry != &MmLoadedUserImageList;
1183  NextEntry = NextEntry->Flink)
1184  {
1185  /* Get the entry */
1186  LdrEntry = CONTAINING_RECORD(NextEntry,
1188  InLoadOrderLinks);
1189 
1190  /* If already in the list, increase load count */
1191  if (LdrEntry->DllBase == BaseAddress)
1192  {
1193  ++LdrEntry->LoadCount;
1194  break;
1195  }
1196  }
1197 
1198  /* Not in the list, we'll add it */
1199  if (NextEntry == &MmLoadedUserImageList)
1200  {
1201  /* Allocate our element, taking to the name string and its null char */
1202  LdrEntry = ExAllocatePoolWithTag(NonPagedPool, FileName->Length + sizeof(UNICODE_NULL) + sizeof(*LdrEntry), 'bDmM');
1203  if (LdrEntry)
1204  {
1205  memset(LdrEntry, 0, FileName->Length + sizeof(UNICODE_NULL) + sizeof(*LdrEntry));
1206 
1207  _SEH2_TRY
1208  {
1209  /* Get image checksum and size */
1210  NtHeaders = RtlImageNtHeader(BaseAddress);
1211  if (NtHeaders)
1212  {
1213  LdrEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
1214  LdrEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
1215  }
1216  }
1218  {
1219  ExFreePoolWithTag(LdrEntry, 'bDmM');
1220  _SEH2_YIELD(return);
1221  }
1222  _SEH2_END;
1223 
1224  /* Fill all the details */
1225  LdrEntry->DllBase = BaseAddress;
1226  LdrEntry->FullDllName.Buffer = (PVOID)((ULONG_PTR)LdrEntry + sizeof(*LdrEntry));
1227  LdrEntry->FullDllName.Length = FileName->Length;
1228  LdrEntry->FullDllName.MaximumLength = FileName->Length + sizeof(UNICODE_NULL);
1229  memcpy(LdrEntry->FullDllName.Buffer, FileName->Buffer, FileName->Length);
1230  LdrEntry->FullDllName.Buffer[LdrEntry->FullDllName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1231  LdrEntry->LoadCount = 1;
1232 
1233  /* Insert! */
1235  }
1236  }
1237 
1238  /* Release locks */
1241 
1242  /* Load symbols */
1243  Status = RtlUnicodeStringToAnsiString(&FileNameA, FileName, TRUE);
1244  if (NT_SUCCESS(Status))
1245  {
1246  DbgLoadImageSymbols(&FileNameA, BaseAddress, (ULONG_PTR)Process->UniqueProcessId);
1247  RtlFreeAnsiString(&FileNameA);
1248  }
1249 }
DWORD *typedef PVOID
Definition: winlogon.h:61
#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
ULONG SizeOfImage
Definition: ldrtypes.h:141
#define WCHAR
Definition: msvc.h:43
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:1766
#define UNICODE_NULL
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
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
LONG NTSTATUS
Definition: precomp.h:26
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
ULONG CheckSum
Definition: btrfs_drv.h:1772
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:1762
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:136
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:1768
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:212
PSUBSECTION NTAPI MiLocateSubsection ( IN PMMVAD  Vad,
IN ULONG_PTR  Vpn 
)

Definition at line 571 of file section.c.

Referenced by MiDeleteVirtualAddresses().

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

Definition at line 159 of file section.c.

Referenced by MiArm3GetCorrectFileAccessMask(), MiIsProtectionCompatible(), MiProtectVirtualMemory(), MiSetProtectionOnSection(), MmCreateArm3Section(), MmCreateSection(), MmInsertMemoryArea(), MmMapViewOfArm3Section(), NtAllocateVirtualMemory(), and NtMapViewOfSection().

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

Definition at line 1053 of file section.c.

Referenced by MmMapViewInSessionSpace(), and MmMapViewInSystemSpace().

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

Referenced by MmMapViewOfArm3Section().

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

Definition at line 1893 of file section.c.

Referenced by NtQueryVirtualMemory().

1898 {
1900  NTSTATUS Status;
1901  WCHAR ModuleFileNameBuffer[MAX_PATH] = {0};
1903  PMEMORY_SECTION_NAME SectionName = NULL;
1905 
1908  NULL,
1909  PreviousMode,
1910  (PVOID*)(&Process),
1911  NULL);
1912 
1913  if (!NT_SUCCESS(Status))
1914  {
1915  DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1916  return Status;
1917  }
1918 
1919  RtlInitEmptyUnicodeString(&ModuleFileName, ModuleFileNameBuffer, sizeof(ModuleFileNameBuffer));
1920  Status = MmGetFileNameForAddress(BaseAddress, &ModuleFileName);
1921 
1922  if (NT_SUCCESS(Status))
1923  {
1924  SectionName = MemoryInformation;
1925  if (PreviousMode != KernelMode)
1926  {
1927  _SEH2_TRY
1928  {
1929  RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
1930  SectionName->SectionFileName.MaximumLength = (USHORT)MemoryInformationLength;
1931  RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
1932 
1933  if (ReturnLength) *ReturnLength = ModuleFileName.Length;
1934 
1935  }
1937  {
1938  Status = _SEH2_GetExceptionCode();
1939  }
1940  _SEH2_END;
1941  }
1942  else
1943  {
1944  RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
1945  SectionName->SectionFileName.MaximumLength = (USHORT)MemoryInformationLength;
1946  RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
1947 
1948  if (ReturnLength) *ReturnLength = ModuleFileName.Length;
1949 
1950  }
1951  }
1952  ObDereferenceObject(Process);
1953  return Status;
1954 }
DWORD *typedef PVOID
Definition: winlogon.h:61
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:1832
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
__wchar_t WCHAR
Definition: xmlstorage.h:180
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2927
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
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define MAX_PATH
Definition: compat.h:26
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
unsigned short USHORT
Definition: pedump.c:61
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
WCHAR NameBuffer[ANYSIZE_ARRAY]
Definition: mmtypes.h:318
ULONG NTAPI MiRemoveFromSystemSpace ( IN PMMSESSION  Session,
IN PVOID  Base,
OUT PCONTROL_AREA ControlArea 
)

Definition at line 2333 of file section.c.

Referenced by MiUnmapViewInSystemSpace().

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

Definition at line 2231 of file section.c.

Referenced by MiUnmapViewInSystemSpace().

2235 {
2236  PMMPTE PointerPte, ProtoPte;//, FirstPte;
2237  PMMPDE PointerPde, SystemMapPde;
2238  PMMPFN Pfn1, Pfn2;
2239  MMPTE PteContents;
2240  KIRQL OldIrql;
2241  DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
2242 
2243  ASSERT(Ws == NULL);
2244 
2245  /* Get the PTE and loop each one */
2246  PointerPte = MiAddressToPte(BaseAddress);
2247  //FirstPte = PointerPte;
2248  while (NumberOfPtes)
2249  {
2250  /* Check if the PTE is already valid */
2251  PteContents = *PointerPte;
2252  if (PteContents.u.Hard.Valid == 1)
2253  {
2254  /* Get the PFN entry */
2255  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
2256 
2257  /* Get the PTE */
2258  PointerPde = MiPteToPde(PointerPte);
2259 
2260  /* Lock the PFN database and make sure this isn't a mapped file */
2261  OldIrql = MiAcquirePfnLock();
2262  ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
2263 
2264  /* Mark the page as modified accordingly */
2265  if (MI_IS_PAGE_DIRTY(&PteContents))
2266  Pfn1->u3.e1.Modified = 1;
2267 
2268  /* Was the PDE invalid */
2269  if (PointerPde->u.Long == 0)
2270  {
2271 #if (_MI_PAGING_LEVELS == 2)
2272  /* Find the system double-mapped PDE that describes this mapping */
2273  SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
2274 
2275  /* Make it valid */
2276  ASSERT(SystemMapPde->u.Hard.Valid == 1);
2277  MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
2278 #else
2279  DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
2280  ASSERT(FALSE);
2281 #endif
2282  }
2283 
2284  /* Dereference the PDE and the PTE */
2285  Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
2286  MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
2288  MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
2289 
2290  /* Release the PFN lock */
2291  MiReleasePfnLock(OldIrql);
2292  }
2293  else
2294  {
2295  /* Windows ASSERT */
2296  ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
2297 
2298  /* Check if this is a prototype pointer PTE */
2299  if (PteContents.u.Soft.Prototype == 1)
2300  {
2301  /* Get the prototype PTE */
2302  ProtoPte = MiProtoPteToPte(&PteContents);
2303 
2304  /* We don't support anything else atm */
2305  ASSERT(ProtoPte->u.Long == 0);
2306  }
2307  }
2308 
2309  /* Make the PTE into a zero PTE */
2310  PointerPte->u.Long = 0;
2311 
2312  /* Move to the next PTE */
2313  PointerPte++;
2314  NumberOfPtes--;
2315  }
2316 
2317  /* Flush the TLB */
2318  KeFlushCurrentTb();
2319 
2320  /* Acquire the PFN lock */
2321  OldIrql = MiAcquirePfnLock();
2322 
2323  /* Decrement the accounting counters */
2324  ControlArea->NumberOfUserReferences--;
2325  ControlArea->NumberOfMappedViews--;
2326 
2327  /* Check if we should destroy the CA and release the lock */
2328  MiCheckControlArea(ControlArea, OldIrql);
2329 }
union _MMPTE::@2227 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
USHORT Modified
Definition: mm.h:292
union _MMPFN::@1721 u3
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:901
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
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
#define MiProtoPteToPte(x)
Definition: mm.h:246
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:971
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
_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:933
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:232
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:729
#define MI_IS_PAGE_DIRTY(x)
Definition: mm.h:108
#define ULONG_PTR
Definition: config.h:101
#define PFN_FROM_PTE(v)
Definition: mm.h:88
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:322
VOID NTAPI MiRemoveMappedView ( IN PEPROCESS  CurrentProcess,
IN PMMVAD  Vad 
)

Definition at line 781 of file section.c.

Referenced by MiUnmapViewOfSection(), and MmCleanProcessAddressSpace().

783 {
784  KIRQL OldIrql;
785  PCONTROL_AREA ControlArea;
786  PETHREAD CurrentThread = PsGetCurrentThread();
787 
788  /* Get the control area */
789  ControlArea = Vad->ControlArea;
790 
791  /* We only support non-extendable, non-image, pagefile-backed regular sections */
792  ASSERT(Vad->u.VadFlags.VadType == VadNone);
793  ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
794  ASSERT(ControlArea);
795  ASSERT(ControlArea->FilePointer == NULL);
796 
797  /* Delete the actual virtual memory pages */
798  MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
799  (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
800  Vad);
801 
802  /* Release the working set */
804 
805  /* Lock the PFN database */
806  OldIrql = MiAcquirePfnLock();
807 
808  /* Remove references */
809  ControlArea->NumberOfMappedViews--;
810  ControlArea->NumberOfUserReferences--;
811 
812  /* Check if it should be destroyed */
813  MiCheckControlArea(ControlArea, OldIrql);
814 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
PFILE_OBJECT FilePointer
Definition: mmtypes.h:525
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1179
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
ULONG CurrentProcess
Definition: shell.c:125
_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:517
VOID NTAPI MiDeleteVirtualAddresses(IN ULONG_PTR Va, IN ULONG_PTR EndingAddress, IN PMMVAD Vad)
Definition: virtual.c:540
ULONG NumberOfUserReferences
Definition: mmtypes.h:519
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:729
VOID NTAPI MiSegmentDelete ( IN PSEGMENT  Segment)

Definition at line 606 of file section.c.

Referenced by MiCheckControlArea().

607 {
608  PCONTROL_AREA ControlArea;
609  SEGMENT_FLAGS SegmentFlags;
610  PSUBSECTION Subsection;
611  PMMPTE PointerPte, LastPte, PteForProto;
612  PMMPFN Pfn1;
613  PFN_NUMBER PageFrameIndex;
614  MMPTE TempPte;
615  KIRQL OldIrql;
616 
617  /* Capture data */
618  SegmentFlags = Segment->SegmentFlags;
619  ControlArea = Segment->ControlArea;
620 
621  /* Make sure control area is on the right delete path */
622  ASSERT(ControlArea->u.Flags.BeingDeleted == 1);
623  ASSERT(ControlArea->WritableUserReferences == 0);
624 
625  /* These things are not supported yet */
626  ASSERT(ControlArea->DereferenceList.Flink == NULL);
627  ASSERT(!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File));
628  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
629  ASSERT(ControlArea->u.Flags.Rom == 0);
630 
631  /* Get the subsection and PTEs for this segment */
632  Subsection = (PSUBSECTION)(ControlArea + 1);
633  PointerPte = Subsection->SubsectionBase;
634  LastPte = PointerPte + Segment->NonExtendedPtes;
635 
636  /* Lock the PFN database */
637  OldIrql = MiAcquirePfnLock();
638 
639  /* Check if the master PTE is invalid */
640  PteForProto = MiAddressToPte(PointerPte);
641  if (!PteForProto->u.Hard.Valid)
642  {
643  /* Fault it in */
644  MiMakeSystemAddressValidPfn(PointerPte, OldIrql);
645  }
646 
647  /* Loop all the segment PTEs */
648  while (PointerPte < LastPte)
649  {
650  /* Check if it's time to switch master PTEs if we passed a PDE boundary */
651  if (!((ULONG_PTR)PointerPte & (PD_SIZE - 1)) &&
652  (PointerPte != Subsection->SubsectionBase))
653  {
654  /* Check if the master PTE is invalid */
655  PteForProto = MiAddressToPte(PointerPte);
656  if (!PteForProto->u.Hard.Valid)
657  {
658  /* Fault it in */
659  MiMakeSystemAddressValidPfn(PointerPte, OldIrql);
660  }
661  }
662 
663  /* This should be a prototype PTE */
664  TempPte = *PointerPte;
665  ASSERT(SegmentFlags.LargePages == 0);
666  ASSERT(TempPte.u.Hard.Valid == 0);
667 
668  /* See if we should clean things up */
669  if (!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File))
670  {
671  /*
672  * This is a section backed by the pagefile. Now that it doesn't exist anymore,
673  * we can give everything back to the system.
674  */
675  ASSERT(TempPte.u.Soft.Prototype == 0);
676 
677  if (TempPte.u.Soft.Transition == 1)
678  {
679  /* We can give the page back for other use */
680  DPRINT("Releasing page for transition PTE %p\n", PointerPte);
681  PageFrameIndex = PFN_FROM_PTE(&TempPte);
682  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
683 
684  /* As this is a paged-backed section, nobody should reference it anymore (no cache or whatever) */
685  ASSERT(Pfn1->u3.ReferenceCount == 0);
686 
687  /* And it should be in standby or modified list */
689 
690  /* Unlink it and put it back in free list */
691  MiUnlinkPageFromList(Pfn1);
692 
693  /* Temporarily mark this as active and make it free again */
695  MI_SET_PFN_DELETED(Pfn1);
696 
697  MiInsertPageInFreeList(PageFrameIndex);
698  }
699  else if (TempPte.u.Soft.PageFileHigh != 0)
700  {
701  /* Should not happen for now */
702  ASSERT(FALSE);
703  }
704  }
705  else
706  {
707  /* unsupported for now */
708  ASSERT(FALSE);
709 
710  /* File-backed section must have prototype PTEs */
711  ASSERT(TempPte.u.Soft.Prototype == 1);
712  }
713 
714  /* Zero the PTE and keep going */
715  PointerPte->u.Long = 0;
716  PointerPte++;
717  }
718 
719  /* Release the PFN lock */
720  MiReleasePfnLock(OldIrql);
721 
722  /* Free the structures */
723  ExFreePool(ControlArea);
725 }
ULONG NTAPI MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress, IN KIRQL OldIrql)
Definition: virtual.c:257
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:264
union _MMPTE::@2227 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ULONG LargePages
Definition: mmtypes.h:395
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
union _MMPFN::@1721 u3
USHORT ReferenceCount
Definition: mm.h:328
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:901
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
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_Inout_ PVOID Segment
Definition: exfuncs.h:893
LIST_ENTRY DereferenceList
Definition: mmtypes.h:514
#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:75
struct _SUBSECTION * PSUBSECTION
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1393
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
ULONG64 PageFileHigh
Definition: mmtypes.h:93
Definition: mm.h:305
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:483
ULONG64 Prototype
Definition: mmtypes.h:89
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:163
ULONG64 Transition
Definition: mmtypes.h:90
ULONG BeingDeleted
Definition: mmtypes.h:455
ULONG WritableUserReferences
Definition: mmtypes.h:529
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
union _CONTROL_AREA::@2480 u
MMSECTION_FLAGS Flags
Definition: mmtypes.h:523
#define PFN_FROM_PTE(v)
Definition: mm.h:88
PMMPTE SubsectionBase
Definition: mmtypes.h:571
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS NTAPI MiSessionCommitPageTables ( IN PVOID  StartVa,
IN PVOID  EndVa 
)

Definition at line 936 of file section.c.

Referenced by MiMapViewInSystemSpace().

938 {
939  KIRQL OldIrql;
940  ULONG Color, Index;
941  PMMPDE StartPde, EndPde;
943  PMMPFN Pfn1;
944  PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
945 
946  /* Windows sanity checks */
947  ASSERT(StartVa >= (PVOID)MmSessionBase);
948  ASSERT(EndVa < (PVOID)MiSessionSpaceEnd);
949  ASSERT(PAGE_ALIGN(EndVa) == EndVa);
950 
951  /* Get the start and end PDE, then loop each one */
952  StartPde = MiAddressToPde(StartVa);
953  EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
954  Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
955  while (StartPde <= EndPde)
956  {
957 #ifndef _M_AMD64
958  /* If we don't already have a page table for it, increment count */
959  if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
960 #endif
961  /* Move to the next one */
962  StartPde++;
963  Index++;
964  }
965 
966  /* If there's no page tables to create, bail out */
967  if (PageCount == 0) return STATUS_SUCCESS;
968 
969  /* Reset the start PDE and index */
970  StartPde = MiAddressToPde(StartVa);
971  Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
972 
973  /* Loop each PDE while holding the working set lock */
974 // MiLockWorkingSet(PsGetCurrentThread(),
975 // &MmSessionSpace->GlobalVirtualAddress->Vm);
976 #ifdef _M_AMD64
977 _WARN("MiSessionCommitPageTables halfplemented for amd64")
982  DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
983  ASSERT(FALSE);
984 #else
985  while (StartPde <= EndPde)
986  {
987  /* Check if we already have a page table */
988  if (MmSessionSpace->PageTables[Index].u.Long == 0)
989  {
990  /* We don't, so the PDE shouldn't be ready yet */
991  ASSERT(StartPde->u.Hard.Valid == 0);
992 
993  /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
994  ASSERT(MmAvailablePages >= 32);
995 
996  /* Acquire the PFN lock and grab a zero page */
997  OldIrql = MiAcquirePfnLock();
999  MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
1000  Color = (++MmSessionSpace->Color) & MmSecondaryColorMask;
1001  PageFrameNumber = MiRemoveZeroPage(Color);
1002  TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
1003  MI_WRITE_VALID_PDE(StartPde, TempPde);
1004 
1005  /* Write the page table in session space structure */
1006  ASSERT(MmSessionSpace->PageTables[Index].u.Long == 0);
1008 
1009  /* Initialize the PFN */
1010  MiInitializePfnForOtherProcess(PageFrameNumber,
1011  StartPde,
1013 
1014  /* And now release the lock */
1015  MiReleasePfnLock(OldIrql);
1016 
1017  /* Get the PFN entry and make sure there's no event for it */
1018  Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1019  ASSERT(Pfn1->u1.Event == NULL);
1020 
1021  /* Increment the number of pages */
1022  ActualPages++;
1023  }
1024 
1025  /* Move to the next PDE */
1026  StartPde++;
1027  Index++;
1028  }
1029 #endif
1030 
1031  /* Make sure we didn't do more pages than expected */
1032  ASSERT(ActualPages <= PageCount);
1033 
1034  /* Release the working set lock */
1035 // MiUnlockWorkingSet(PsGetCurrentThread(),
1036 // &MmSessionSpace->GlobalVirtualAddress->Vm);
1037 
1038 
1039  /* If we did at least one page... */
1040  if (ActualPages)
1041  {
1042  /* Update the performance counters! */
1045  }
1046 
1047  /* Return status */
1048  return STATUS_SUCCESS;
1049 }
DWORD *typedef PVOID
Definition: winlogon.h:61
SIZE_T NonPageablePages
Definition: miarm.h:460
#define MiAddressToPde(x)
Definition: mmx86.c:20
PMMPDE PageTables
Definition: miarm.h:486
union _MMPTE::@2227 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:77
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
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:901
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
#define FALSE
Definition: types.h:117
#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:971
#define MI_SET_USAGE(x)
Definition: mm.h:253
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:326
SIZE_T CommittedPages
Definition: miarm.h:461
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)
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1393
_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:2710
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:459
VOID NTAPI MiSetControlAreaSymbolsLoaded ( IN PCONTROL_AREA  ControlArea)

Definition at line 1143 of file section.c.

1144 {
1145  KIRQL OldIrql;
1146 
1148 
1149  OldIrql = MiAcquirePfnLock();
1150  ControlArea->u.Flags.DebugSymbolsLoaded |= 1;
1151 
1152  ASSERT(OldIrql <= APC_LEVEL);
1153  MiReleasePfnLock(OldIrql);
1155 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
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
#define APC_LEVEL
Definition: env_spec_w32.h:695
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 2062 of file section.c.

2070 {
2071  PMMPTE PointerPte, LastPte;
2072  MMPTE TempPte, PteContents;
2073  PMMPDE PointerPde;
2074  PMMPFN Pfn1;
2075  ULONG ProtectionMask, QuotaCharge = 0;
2077  PAGED_CODE();
2078 
2079  //
2080  // Tell caller nothing is being locked
2081  //
2082  *Locked = FALSE;
2083 
2084  //
2085  // This function should only be used for section VADs. Windows ASSERT */
2086  //
2087  ASSERT(FoundVad->u.VadFlags.PrivateMemory == 0);
2088 
2089  //
2090  // We don't support these features in ARM3
2091  //
2092  ASSERT(FoundVad->u.VadFlags.VadType != VadImageMap);
2093  ASSERT(FoundVad->u2.VadFlags2.CopyOnWrite == 0);
2094 
2095  //
2096  // Convert and validate the protection mask
2097  //
2098  ProtectionMask = MiMakeProtectionMask(NewProtect);
2099  if (ProtectionMask == MM_INVALID_PROTECTION)
2100  {
2101  DPRINT1("Invalid section protect\n");
2103  }
2104 
2105  //
2106  // Get the PTE and PDE for the address, as well as the final PTE
2107  //
2109  PointerPde = MiAddressToPde(StartingAddress);
2110  PointerPte = MiAddressToPte(StartingAddress);
2111  LastPte = MiAddressToPte(EndingAddress);
2112 
2113  //
2114  // Make the PDE valid, and check the status of the first PTE
2115  //
2117  if (PointerPte->u.Long)
2118  {
2119  //
2120  // Not supported in ARM3
2121  //
2122  ASSERT(FoundVad->u.VadFlags.VadType != VadRotatePhysical);
2123 
2124  //
2125  // Capture the page protection and make the PDE valid
2126  //
2127  *CapturedOldProtect = MiGetPageProtection(PointerPte);
2129  }
2130  else
2131  {
2132  //
2133  // Only pagefile-backed section VADs are supported for now
2134  //
2135  ASSERT(FoundVad->u.VadFlags.VadType != VadImageMap);
2136 
2137  //
2138  // Grab the old protection from the VAD itself
2139  //
2140  *CapturedOldProtect = MmProtectToValue[FoundVad->u.VadFlags.Protection];
2141  }
2142 
2143  //
2144  // Loop all the PTEs now
2145  //
2147  while (PointerPte <= LastPte)
2148  {
2149  //
2150  // Check if we've crossed a PDE boundary and make the new PDE valid too
2151  //
2152  if ((((ULONG_PTR)PointerPte) & (SYSTEM_PD_SIZE - 1)) == 0)
2153  {
2154  PointerPde = MiPteToPde(PointerPte);
2156  }
2157 
2158  //
2159  // Capture the PTE and see what we're dealing with
2160  //
2161  PteContents = *PointerPte;
2162  if (PteContents.u.Long == 0)
2163  {
2164  //
2165  // This used to be a zero PTE and it no longer is, so we must add a
2166  // reference to the pagetable.
2167  //
2169 
2170  //
2171  // Create the demand-zero prototype PTE
2172  //
2173  TempPte = PrototypePte;
2174  TempPte.u.Soft.Protection = ProtectionMask;
2175  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2176  }
2177  else if (PteContents.u.Hard.Valid == 1)
2178  {
2179  //
2180  // Get the PFN entry
2181  //
2182  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
2183 
2184  //
2185  // We don't support these yet
2186  //
2187  ASSERT((NewProtect & (PAGE_NOACCESS | PAGE_GUARD)) == 0);
2188  ASSERT(Pfn1->u3.e1.PrototypePte == 0);
2189 
2190  //
2191  // Write the protection mask and write it with a TLB flush
2192  //
2193  Pfn1->OriginalPte.u.Soft.Protection = ProtectionMask;
2194  MiFlushTbAndCapture(FoundVad,
2195  PointerPte,
2196  ProtectionMask,
2197  Pfn1,
2198  TRUE);
2199  }
2200  else
2201  {
2202  //
2203  // We don't support these cases yet
2204  //
2205  ASSERT(PteContents.u.Soft.Prototype == 0);
2206  ASSERT(PteContents.u.Soft.Transition == 0);
2207 
2208  //
2209  // The PTE is already demand-zero, just update the protection mask
2210  //
2211  PointerPte->u.Soft.Protection = ProtectionMask;
2212  }
2213 
2214  PointerPte++;
2215  }
2216 
2217  //
2218  // Unlock the working set and update quota charges if needed, then return
2219  //
2221  if ((QuotaCharge > 0) && (!DontCharge))
2222  {
2223  FoundVad->u.VadFlags.CommitCharge -= QuotaCharge;
2224  Process->CommitCharge -= QuotaCharge;
2225  }
2226  return STATUS_SUCCESS;
2227 }
#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:1179
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
union _MMPTE::@2227 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define PAGE_GUARD
Definition: nt_native.h:1310
union _MMPFN::@1721 u3
#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
#define FALSE
Definition: types.h:117
_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:197
ULONG64 Protection
Definition: mmtypes.h:88
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1109
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:159
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:75
#define MM_NOIRQL
Definition: miarm.h:205
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:933
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:232
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:945
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
FORCEINLINE VOID MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:1637
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:1958
return STATUS_SUCCESS
Definition: btrfs.c:2710
#define PFN_FROM_PTE(v)
Definition: mm.h:88
VOID NTAPI MiSubsectionConsistent ( IN PSUBSECTION  Subsection)

Definition at line 1479 of file section.c.

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

Definition at line 2377 of file section.c.

Referenced by MmUnmapViewInSessionSpace(), and MmUnmapViewInSystemSpace().

2379 {
2380  ULONG Size;
2381  PCONTROL_AREA ControlArea;
2382  PAGED_CODE();
2383 
2384  /* Remove this mapping */
2385  KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2386  Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2387 
2388  /* Clear the bits for this mapping */
2389  RtlClearBits(Session->SystemSpaceBitMap,
2390  (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2391  Size);
2392 
2393  /* Convert the size from a bit size into the actual size */
2394  Size = Size * (_64K >> PAGE_SHIFT);
2395 
2396  /* Remove the PTEs now */
2397  MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2398  KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2399 
2400  /* Return success */
2401  return STATUS_SUCCESS;
2402 }
#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:2231
#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:2333
smooth NULL
Definition: ftsmooth.c:416
UINTN Size
Definition: acefiex.h:555
#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:2710
NTSTATUS NTAPI MiUnmapViewOfSection ( IN PEPROCESS  Process,
IN PVOID  BaseAddress,
IN ULONG  Flags 
)

Definition at line 818 of file section.c.

Referenced by MmUnmapViewOfSection(), and NtUnmapViewOfSection().

821 {
825  PMMVAD Vad;
826  PVOID DbgBase = NULL;
829  PETHREAD CurrentThread = PsGetCurrentThread();
831  PAGED_CODE();
832 
833  /* Check for Mm Region */
834  MemoryArea = MmLocateMemoryAreaByAddress(&Process->Vm, BaseAddress);
835  if ((MemoryArea) && (MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3))
836  {
837  /* Call Mm API */
838  return MiRosUnmapViewOfSection(Process, BaseAddress, Process->ProcessExiting);
839  }
840 
841  /* Check if we should attach to the process */
842  if (CurrentProcess != Process)
843  {
844  /* The process is different, do an attach */
845  KeStackAttachProcess(&Process->Pcb, &ApcState);
846  Attached = TRUE;
847  }
848 
849  /* Check if we need to lock the address space */
850  if (!Flags) MmLockAddressSpace(&Process->Vm);
851 
852  /* Check if the process is already daed */
853  if (Process->VmDeleted)
854  {
855  /* Fail the call */
856  DPRINT1("Process died!\n");
857  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
859  goto Quickie;
860  }
861 
862  /* Find the VAD for the address and make sure it's a section VAD */
864  if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
865  {
866  /* Couldn't find it, or invalid VAD, fail */
867  DPRINT1("No VAD or invalid VAD\n");
868  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
869  Status = STATUS_NOT_MAPPED_VIEW;
870  goto Quickie;
871  }
872 
873  /* We should be attached */
875 
876  /* We need the base address for the debugger message on image-backed VADs */
877  if (Vad->u.VadFlags.VadType == VadImageMap)
878  {
879  DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
880  }
881 
882  /* Compute the size of the VAD region */
883  RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
884 
885  /* For SEC_NO_CHANGE sections, we need some extra checks */
886  if (Vad->u.VadFlags.NoChange == 1)
887  {
888  /* Are we allowed to mess with this VAD? */
889  Status = MiCheckSecuredVad(Vad,
890  (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
891  RegionSize,
893  if (!NT_SUCCESS(Status))
894  {
895  /* We failed */
896  DPRINT1("Trying to unmap protected VAD!\n");
897  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
898  goto Quickie;
899  }
900  }
901 
902  /* Not currently supported */
904 
905  /* FIXME: Remove VAD charges */
906 
907  /* Lock the working set */
908  MiLockProcessWorkingSetUnsafe(Process, CurrentThread);
909 
910  /* Remove the VAD */
911  ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
912  MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
913 
914  /* Remove the PTEs for this view, which also releases the working set lock */
916 
917  /* FIXME: Remove commitment */
918 
919  /* Update performance counter and release the lock */
920  Process->VirtualSize -= RegionSize;
921  if (!Flags) MmUnlockAddressSpace(&Process->Vm);
922 
923  /* Destroy the VAD and return success */
924  ExFreePool(Vad);
925  Status = STATUS_SUCCESS;
926 
927  /* Failure and success case -- send debugger message, detach, and return */
928 Quickie:
929  if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
930  if (Attached) KeUnstackDetachProcess(&ApcState);
931  return Status;
932 }
DWORD *typedef PVOID
Definition: winlogon.h:61
#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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1410
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:781
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
ULONG_PTR NoChange
Definition: mmtypes.h:694
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:735
#define PAGED_CODE()
Definition: video.h:57
#define MM_DELETE_CHECK
Definition: miarm.h:235
ULONG_PTR EndingVpn
Definition: mmtypes.h:731
_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
#define FALSE
Definition: types.h:117
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:4108
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:48
union _MMVAD::@2487 u
ULONG_PTR StartingVpn
Definition: mmtypes.h:730
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:1109
unsigned char BOOLEAN
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG CurrentProcess
Definition: shell.c:125
LONG NTSTATUS
Definition: precomp.h:26
ULONG_PTR PrivateMemory
Definition: mmtypes.h:699
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:488
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:1471
#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:2710
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:65
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1403
ULONG_PTR VadType
Definition: mmtypes.h:695
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS NTAPI MmCommitSessionMappedView ( IN PVOID  MappedBase,
IN SIZE_T  ViewSize 
)

Definition at line 3084 of file section.c.

3086 {
3087  ULONG_PTR StartAddress, EndingAddress, Base;
3088  ULONG Hash, Count = 0, Size, QuotaCharge;
3089  PMMSESSION Session;
3090  PMMPTE LastProtoPte, PointerPte, ProtoPte;
3091  PCONTROL_AREA ControlArea;
3092  PSEGMENT Segment;
3093  PSUBSECTION Subsection;
3094  MMPTE TempPte;
3095  PAGED_CODE();
3096 
3097  /* Make sure the base isn't past the session view range */
3098  if ((MappedBase < MiSessionViewStart) ||
3100  {
3101  DPRINT1("Base outside of valid range\n");
3103  }
3104 
3105  /* Make sure the size isn't past the session view range */
3108  {
3109  DPRINT1("Size outside of valid range\n");
3111  }
3112 
3113  /* Sanity check */
3114  ASSERT(ViewSize != 0);
3115 
3116  /* Process must be in a session */
3117  if (PsGetCurrentProcess()->ProcessInSession == FALSE)
3118  {
3119  DPRINT1("Process is not in session\n");
3120  return STATUS_NOT_MAPPED_VIEW;
3121  }
3122 
3123  /* Compute the correctly aligned base and end addresses */
3124  StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
3125  EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
3126 
3127  /* Sanity check and grab the session */
3129  Session = &MmSessionSpace->Session;
3130 
3131  /* Get the hash entry for this allocation */
3132  Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
3133 
3134  /* Lock system space */
3136 
3137  /* Loop twice so we can try rolling over if needed */
3138  while (TRUE)
3139  {
3140  /* Extract the size and base addresses from the entry */
3141  Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
3142  Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
3143 
3144  /* Convert the size to bucket chunks */
3146 
3147  /* Bail out if this entry fits in here */
3148  if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
3149 
3150  /* Check if we overflew past the end of the hash table */
3151  if (++Hash >= Session->SystemSpaceHashSize)
3152  {
3153  /* Reset the hash to zero and keep searching from the bottom */
3154  Hash = 0;
3155  if (++Count == 2)
3156  {
3157  /* But if we overflew twice, then this is not a real mapping */
3158  KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
3159  Base,
3160  2,
3161  0,
3162  0);
3163  }
3164  }
3165  }
3166 
3167  /* Make sure the view being mapped is not file-based */
3168  ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
3169  if (ControlArea->FilePointer != NULL)
3170  {
3171  /* It is, so we have to bail out */
3172  DPRINT1("Only page-filed backed sections can be commited\n");
3174  return STATUS_ALREADY_COMMITTED;
3175  }
3176 
3177  /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
3178  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
3179  ASSERT(ControlArea->u.Flags.Rom == 0);
3180  Subsection = (PSUBSECTION)(ControlArea + 1);
3181 
3182  /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
3183  ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
3184  QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
3185  LastProtoPte = ProtoPte + QuotaCharge;
3186  if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
3187  {
3188  DPRINT1("PTE is out of bounds\n");
3191  }
3192 
3193  /* Acquire the commit lock and count all the non-committed PTEs */
3195  PointerPte = ProtoPte;
3196  while (PointerPte < LastProtoPte)
3197  {
3198  if (PointerPte->u.Long) QuotaCharge--;
3199  PointerPte++;
3200  }
3201 
3202  /* Was everything committed already? */
3203  if (!QuotaCharge)
3204  {
3205  /* Nothing to do! */
3208  return STATUS_SUCCESS;
3209  }
3210 
3211  /* Pick the segment and template PTE */
3212  Segment = ControlArea->Segment;
3213  TempPte = Segment->SegmentPteTemplate;
3214  ASSERT(TempPte.u.Long != 0);
3215 
3216  /* Loop all prototype PTEs to be committed */
3217  PointerPte = ProtoPte;
3218  while (PointerPte < LastProtoPte)
3219  {
3220  /* Make sure the PTE is already invalid */
3221  if (PointerPte->u.Long == 0)
3222  {
3223  /* And write the invalid PTE */
3224  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
3225  }
3226 
3227  /* Move to the next PTE */
3228  PointerPte++;
3229  }
3230 
3231  /* Check if we had at least one page charged */
3232  if (QuotaCharge)
3233  {
3234  /* Update the accounting data */
3235  Segment->NumberOfCommittedPages += QuotaCharge;
3237  }
3238 
3239  /* Release all */
3242  return STATUS_SUCCESS;
3243 }
DWORD *typedef PVOID
Definition: winlogon.h:61
static int Hash(const char *)
Definition: reader.c:2258
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
ULONG NumberOfCommittedPages
Definition: mmtypes.h:407
#define TRUE
Definition: types.h:120
PFILE_OBJECT FilePointer
Definition: mmtypes.h:525
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
union _MMPTE::@2227 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
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
#define FALSE
Definition: types.h:117
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
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:432
ULONG SystemSpaceHashKey
Definition: miarm.h:435
_Inout_ PVOID Segment
Definition: exfuncs.h:893
UINTN Size
Definition: acefiex.h:555
MMSESSION Session
Definition: miarm.h:476
#define PAGE_ALIGN(Va)
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
struct _SUBSECTION * PSUBSECTION
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
VOID FASTCALL KeReleaseGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:75
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:430
PCONTROL_AREA ControlArea
Definition: miarm.h:424
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:483
#define PAGE_SIZE
Definition: env_spec_w32.h:49
KGUARDED_MUTEX MmSectionCommitMutex
Definition: section.c:109
ULONG_PTR Long
Definition: mmtypes.h:215
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:945
PVOID MiSessionViewStart
Definition: init.c:30
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:240
PSEGMENT Segment
Definition: mmtypes.h:513
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
union _CONTROL_AREA::@2480 u
MMPTE SegmentPteTemplate
Definition: mmtypes.h:406
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
VOID FASTCALL KeAcquireGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:64
MMSECTION_FLAGS Flags
Definition: mmtypes.h:523
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:423
ULONG SystemSpaceHashSize
Definition: miarm.h:433
return STATUS_SUCCESS
Definition: btrfs.c:2710
PMMPTE SubsectionBase
Definition: mmtypes.h:571
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:573
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 2411 of file section.c.

Referenced by MmCreateSection().

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