ReactOS  0.4.15-dev-3326-ga91f5e8
section.c File Reference
#include <ntoskrnl.h>
#include <cache/newcc.h>
#include <cache/section/newmm.h>
#include <debug.h>
#include <reactos/exeformat.h>
#include "ARM3/miarm.h"
Include dependency graph for section.c:

Go to the source code of this file.

Classes

struct  MM_SECTION_PAGEOUT_CONTEXT
 

Macros

#define NDEBUG
 
#define MmSetPageEntrySectionSegment(S, O, E)
 
#define DIE(ARGS_)   { DPRINT ARGS_; goto l_Return; }
 

Functions

VOID NTAPI _MmLockSectionSegment (PMM_SECTION_SEGMENT Segment, const char *file, int line)
 
VOID NTAPI _MmUnlockSectionSegment (PMM_SECTION_SEGMENT Segment, const char *file, int line)
 
static PMM_SECTION_SEGMENT MiGrabDataSection (PSECTION_OBJECT_POINTERS SectionObjectPointer)
 
PMM_IMAGE_SECTION_OBJECT ImageSectionObjectFromSegment (PMM_SECTION_SEGMENT Segment)
 
NTSTATUS MiMapViewInSystemSpace (IN PVOID Section, IN PVOID Session, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize, IN PLARGE_INTEGER SectionOffset)
 
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)
 
 C_ASSERT (EXEFMT_LOAD_HEADER_SIZE >=sizeof(IMAGE_DOS_HEADER))
 
 C_ASSERT (sizeof(IMAGE_NT_HEADERS32)<=sizeof(IMAGE_NT_HEADERS64))
 
 C_ASSERT (TYPE_ALIGNMENT(IMAGE_NT_HEADERS32)==TYPE_ALIGNMENT(IMAGE_NT_HEADERS64))
 
 C_ASSERT (RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)==RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS64, FileHeader))
 
 C_ASSERT (FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)==FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Magic))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SectionAlignment))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, FileAlignment))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Subsystem))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, AddressOfEntryPoint))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfCode))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfHeaders))
 
ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask (IN ACCESS_MASK SectionPageProtection)
 
NTSTATUS NTAPI MiWritePage (PMM_SECTION_SEGMENT Segment, LONGLONG SegOffset, PFN_NUMBER Page)
 
NTSTATUS NTAPI PeFmtCreateSection (IN CONST VOID *FileHeader, IN SIZE_T FileHeaderSize, IN PVOID File, OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, OUT PULONG Flags, IN PEXEFMT_CB_READ_FILE ReadFileCb, IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb)
 
NTSTATUS MmspWaitForFileLock (PFILE_OBJECT File)
 
VOID NTAPI MmpFreePageFileSegment (PMM_SECTION_SEGMENT Segment)
 
static VOID NTAPI FreeSegmentPage (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
 
 _When_ (OldIrql==MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL))
 
VOID NTAPI MmSharePageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
 
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment (PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
 
static NTSTATUS MiCopyFromUserPage (PFN_NUMBER DestPage, const VOID *SrcAddress)
 
static NTSTATUS NTAPI MmMakeSegmentResident (_In_ PMM_SECTION_SEGMENT Segment, _In_ LONGLONG Offset, _In_ ULONG Length, _In_opt_ PLARGE_INTEGER ValidDataLength, _In_ BOOLEAN SetDirty)
 
static VOID MmAlterViewAttributes (PMMSUPPORT AddressSpace, PVOID BaseAddress, SIZE_T RegionSize, ULONG OldType, ULONG OldProtect, ULONG NewType, ULONG NewProtect)
 
NTSTATUS NTAPI MmNotPresentFaultSectionView (PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
 
NTSTATUS NTAPI MmAccessFaultSectionView (PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
 
NTSTATUS NTAPI MmProtectSectionView (PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PVOID BaseAddress, SIZE_T Length, ULONG Protect, PULONG OldProtect)
 
NTSTATUS NTAPI MmQuerySectionView (PMEMORY_AREA MemoryArea, PVOID Address, PMEMORY_BASIC_INFORMATION Info, PSIZE_T ResultLength)
 
VOID NTAPI MmpDeleteSection (PVOID ObjectBody)
 
VOID NTAPI MmpCloseSection (IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
 
NTSTATUS NTAPI MmCreatePhysicalMemorySection (VOID)
 
NTSTATUS NTAPI MmInitSectionImplementation (VOID)
 
static NTSTATUS NTAPI MmCreateDataFileSection (PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject, BOOLEAN GotFileHandle)
 
NTSTATUS NTAPI ElfFmtCreateSection (IN CONST VOID *FileHeader, IN SIZE_T FileHeaderSize, IN PVOID File, OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, OUT PULONG Flags, IN PEXEFMT_CB_READ_FILE ReadFileCb, IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb)
 
static PMM_SECTION_SEGMENT NTAPI ExeFmtpAllocateSegments (IN ULONG NrSegments)
 
static NTSTATUS NTAPI ExeFmtpReadFile (IN PVOID File, IN PLARGE_INTEGER Offset, IN ULONG Length, OUT PVOID *Data, OUT PVOID *AllocBase, OUT PULONG ReadSize)
 
static VOID NTAPI MmspAssertSegmentsSorted (IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 
static VOID NTAPI MmspAssertSegmentsNoOverlap (IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 
static VOID NTAPI MmspAssertSegmentsPageAligned (IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 
static int __cdecl MmspCompareSegments (const void *x, const void *y)
 
static VOID NTAPI MmspSortSegments (IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
 
static BOOLEAN NTAPI MmspCheckSegmentBounds (IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
 
static BOOLEAN NTAPI MmspPageAlignSegments (IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
 
NTSTATUS ExeFmtpCreateImageSection (PFILE_OBJECT FileObject, PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 
NTSTATUS MmCreateImageSection (PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
 
static NTSTATUS MmMapViewOfSegment (PMMSUPPORT AddressSpace, BOOLEAN AsImage, PMM_SECTION_SEGMENT Segment, PVOID *BaseAddress, SIZE_T ViewSize, ULONG Protect, LONGLONG ViewOffset, ULONG AllocationType)
 
static VOID MmFreeSectionPage (PVOID Context, MEMORY_AREA *MemoryArea, PVOID Address, PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
 
static NTSTATUS MmUnmapViewOfSegment (PMMSUPPORT AddressSpace, PVOID BaseAddress)
 
NTSTATUS NTAPI MiRosUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
 
NTSTATUS NTAPI NtQuerySection (_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T SectionInformationLength, _Out_opt_ PSIZE_T ResultLength)
 
NTSTATUS NTAPI MmMapViewOfSection (IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
 
BOOLEAN NTAPI MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN PLARGE_INTEGER NewFileSize)
 
static BOOLEAN MiPurgeImageSegment (PMM_SECTION_SEGMENT Segment)
 
BOOLEAN NTAPI MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
 
NTSTATUS NTAPI MmMapViewInSystemSpace (IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
 
NTSTATUS NTAPI MmMapViewInSystemSpaceEx (_In_ PVOID SectionObject, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset, _In_ ULONG_PTR Flags)
 
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace (IN PVOID MappedBase)
 
NTSTATUS NTAPI MmCreateSection (OUT PVOID *Section, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
 
BOOLEAN NTAPI MmArePagesResident (_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
 
BOOLEAN NTAPI MmPurgeSegment (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length)
 
NTSTATUS NTAPI MmMakeDataSectionResident (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _In_ ULONG Length, _In_ PLARGE_INTEGER ValidDataLength)
 
NTSTATUS NTAPI MmFlushSegment (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _Out_opt_ PIO_STATUS_BLOCK Iosb)
 
 _Requires_exclusive_lock_held_ (Segment->Lock) BOOLEAN NTAPI MmCheckDirtySegment(PMM_SECTION_SEGMENT Segment
 
 ASSERT (Segment->Locked)
 
 ASSERT ((Offset->QuadPart % PAGE_SIZE)==0)
 
 DPRINT ("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
 
 if (Entry==0)
 
 if (!IS_DIRTY_SSE(Entry) &&(SHARE_COUNT_FROM_SSE(Entry)==0) &&PageOut)
 
NTSTATUS NTAPI MmMakePagesDirty (_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
 
NTSTATUS NTAPI MmExtendSection (_In_ PVOID _Section, _Inout_ PLARGE_INTEGER NewSize)
 

Variables

MMSESSION MmSession
 
static LARGE_INTEGER TinyTime = {{-1L, -1L}}
 
KEVENT MmWaitPageEvent
 
POBJECT_TYPE MmSectionObjectType = NULL
 
ULONG_PTR MmSubsectionBase
 
static ULONG SectionCharacteristicsToProtect [16]
 
ULONG MmMakeFileAccess []
 
static GENERIC_MAPPING MmpSectionMapping
 
static PEXEFMT_LOADER ExeFmtpLoaders []
 
PLARGE_INTEGER Offset
 
PLARGE_INTEGER BOOLEAN ForceDirty
 
PLARGE_INTEGER BOOLEAN BOOLEAN PageOut
 
NTSTATUS Status
 
PFN_NUMBER Page
 
 Entry = MmGetPageEntrySectionSegment(Segment, Offset)
 
return FALSE
 

Macro Definition Documentation

◆ DIE

#define DIE (   ARGS_)    { DPRINT ARGS_; goto l_Return; }

◆ MmSetPageEntrySectionSegment

#define MmSetPageEntrySectionSegment (   S,
  O,
  E 
)
Value:
do { \
DPRINT("SetPageEntrySectionSegment(old,%p,%x,%x)\n",(S),(O)->LowPart,E); \
_MmSetPageEntrySectionSegment((S),(O),(E),__FILE__,__LINE__); \
} while (0)
static const WCHAR O[]
Definition: oid.c:1251
Definition: movable.cpp:7
static const WCHAR E[]
Definition: oid.c:1253

Definition at line 57 of file section.c.

◆ NDEBUG

#define NDEBUG

Definition at line 50 of file section.c.

Function Documentation

◆ _MmLockSectionSegment()

VOID NTAPI _MmLockSectionSegment ( PMM_SECTION_SEGMENT  Segment,
const char file,
int  line 
)

Definition at line 71 of file section.c.

72 {
73  //DPRINT("MmLockSectionSegment(%p,%s:%d)\n", Segment, file, line);
75  Segment->Locked = TRUE;
76 }
#define TRUE
Definition: types.h:120
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23

◆ _MmUnlockSectionSegment()

VOID NTAPI _MmUnlockSectionSegment ( PMM_SECTION_SEGMENT  Segment,
const char file,
int  line 
)

Definition at line 80 of file section.c.

81 {
82  ASSERT(Segment->Locked);
83  Segment->Locked = FALSE;
85  //DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment, file, line);
86 }
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
ASSERT(Segment->Locked)
return FALSE
Definition: section.c:5047
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

◆ _Requires_exclusive_lock_held_()

_Requires_exclusive_lock_held_ ( Segment->  Lock)

◆ _When_()

Definition at line 990 of file section.c.

999 {
1000  /* Lock the PFN lock because we mess around with SectionObjectPointers */
1001  if (OldIrql == MM_NOIRQL)
1002  {
1003  OldIrql = MiAcquirePfnLock();
1004  }
1005 
1006  if (InterlockedDecrement64(Segment->ReferenceCount) > 0)
1007  {
1008  /* Nothing to do yet */
1009  MiReleasePfnLock(OldIrql);
1010  return;
1011  }
1012 
1013  *Segment->Flags |= MM_SEGMENT_INDELETE;
1014 
1015  /* Flush the segment */
1016  if (*Segment->Flags & MM_DATAFILE_SEGMENT)
1017  {
1018  MiReleasePfnLock(OldIrql);
1019  /* Free the page table. This will flush any remaining dirty data */
1021 
1022  OldIrql = MiAcquirePfnLock();
1023  /* Delete the pointer on the file */
1024  ASSERT(Segment->FileObject->SectionObjectPointer->DataSectionObject == Segment);
1025  Segment->FileObject->SectionObjectPointer->DataSectionObject = NULL;
1026  MiReleasePfnLock(OldIrql);
1027  ObDereferenceObject(Segment->FileObject);
1028 
1030  }
1031  else
1032  {
1033  /* Most grotesque thing ever */
1034  PMM_IMAGE_SECTION_OBJECT ImageSectionObject = CONTAINING_RECORD(Segment->ReferenceCount, MM_IMAGE_SECTION_OBJECT, RefCount);
1035  PMM_SECTION_SEGMENT SectionSegments;
1036  ULONG NrSegments;
1037  ULONG i;
1038 
1039  /* Delete the pointer on the file */
1040  ASSERT(ImageSectionObject->FileObject->SectionObjectPointer->ImageSectionObject == ImageSectionObject);
1041  ImageSectionObject->FileObject->SectionObjectPointer->ImageSectionObject = NULL;
1042  MiReleasePfnLock(OldIrql);
1043 
1044  ObDereferenceObject(ImageSectionObject->FileObject);
1045 
1046  NrSegments = ImageSectionObject->NrSegments;
1047  SectionSegments = ImageSectionObject->Segments;
1048  for (i = 0; i < NrSegments; i++)
1049  {
1050  if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
1051  {
1052  MmpFreePageFileSegment(&SectionSegments[i]);
1053  }
1054 
1055  MmFreePageTablesSectionSegment(&SectionSegments[i], NULL);
1056  }
1057 
1058  ExFreePoolWithTag(ImageSectionObject->Segments, TAG_MM_SECTION_SEGMENT);
1059  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
1060  }
1061 }
static VOID NTAPI FreeSegmentPage(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: section.c:962
ASSERT(Segment->Locked)
#define MM_NOIRQL
Definition: mm.h:59
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
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
KIRQL OldIrql
Definition: mm.h:1502
VOID NTAPI MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:919
PMM_SECTION_SEGMENT Segments
Definition: mm.h:223
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID NTAPI MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment, FREE_SECTION_PAGE_FUN FreePage)
Definition: sptab.c:307
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define InterlockedDecrement64
Definition: interlocked.h:144
PFILE_OBJECT FileObject
Definition: mm.h:215
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define MM_SEGMENT_INDELETE
Definition: mm.h:228
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

◆ ASSERT() [1/2]

ASSERT ( Segment->  Locked)

Referenced by _MmUnlockSectionSegment(), _When_(), ExeFmtpCreateImageSection(), ExeFmtpReadFile(), FreeSegmentPage(), ImageSectionObjectFromSegment(), MiAddMappedPtes(), MiCheckControlArea(), MiCheckPurgeAndUpMapCount(), MiCopyFromUserPage(), MiCreateDataFileMap(), MiCreatePagingFileMap(), MiDeleteARM3Section(), MiFillSystemPageDirectory(), MiFlushTbAndCapture(), MiGetFileObjectForSectionAddress(), MiGetFileObjectForVad(), MiGrabDataSection(), MiInitializeSystemSpaceMap(), MiInsertInSystemSpace(), MiLocateSubsection(), MiMakeProtectionMask(), MiMapViewInSystemSpace(), MiMapViewOfDataSection(), MiPurgeImageSegment(), MiRemoveMappedPtes(), MiRemoveMappedView(), MiRosUnmapViewOfSection(), MiSegmentDelete(), MiSessionCommitPageTables(), MiSetControlAreaSymbolsLoaded(), MiSetProtectionOnSection(), MiSubsectionConsistent(), MiUnmapViewOfSection(), MmAccessFaultSectionView(), MmAlterViewAttributes(), MmArePagesResident(), MmCommitSessionMappedView(), MmCreateArm3Section(), MmCreateDataFileSection(), MmCreateImageSection(), MmFlushImageSection(), MmFlushSegment(), MmFreeSectionPage(), MmGetFileObjectForSection(), MmGetImageInformation(), MmInitSectionImplementation(), MmMakeDataSectionResident(), MmMakePagesDirty(), MmMakeSegmentResident(), MmMapViewInSessionSpace(), MmMapViewInSystemSpaceEx(), MmMapViewOfArm3Section(), MmMapViewOfSection(), MmMapViewOfSegment(), MmNotPresentFaultSectionView(), MmpDeleteSection(), MmProtectSectionView(), MmPurgeSegment(), MmspAssertSegmentsNoOverlap(), MmspAssertSegmentsPageAligned(), MmspAssertSegmentsSorted(), MmspCheckSegmentBounds(), MmspPageAlignSegments(), MmUnmapViewInSessionSpace(), MmUnsharePageEntrySectionSegment(), NtQuerySection(), and PeFmtCreateSection().

◆ ASSERT() [2/2]

ASSERT ( (Offset->QuadPart % PAGE_SIZE = =0)

◆ C_ASSERT() [1/14]

C_ASSERT ( EXEFMT_LOAD_HEADER_SIZE >=  sizeofIMAGE_DOS_HEADER)

◆ C_ASSERT() [2/14]

◆ C_ASSERT() [3/14]

◆ C_ASSERT() [4/14]

◆ C_ASSERT() [5/14]

C_ASSERT ( FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)  = =FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader))

◆ C_ASSERT() [6/14]

◆ C_ASSERT() [7/14]

◆ C_ASSERT() [8/14]

◆ C_ASSERT() [9/14]

◆ C_ASSERT() [10/14]

C_ASSERT ( PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion)  )

◆ C_ASSERT() [11/14]

C_ASSERT ( PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion)  )

◆ C_ASSERT() [12/14]

◆ C_ASSERT() [13/14]

◆ C_ASSERT() [14/14]

◆ DPRINT()

◆ ElfFmtCreateSection()

NTSTATUS NTAPI ElfFmtCreateSection ( IN CONST VOID FileHeader,
IN SIZE_T  FileHeaderSize,
IN PVOID  File,
OUT PMM_IMAGE_SECTION_OBJECT  ImageSectionObject,
OUT PULONG  Flags,
IN PEXEFMT_CB_READ_FILE  ReadFileCb,
IN PEXEFMT_CB_ALLOCATE_SEGMENTS  AllocateSegmentsCb 
)

◆ ExeFmtpAllocateSegments()

static PMM_SECTION_SEGMENT NTAPI ExeFmtpAllocateSegments ( IN ULONG  NrSegments)
static

Definition at line 2556 of file section.c.

2557 {
2558  SIZE_T SizeOfSegments;
2559  PMM_SECTION_SEGMENT Segments;
2560 
2561  /* TODO: check for integer overflow */
2562  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
2563 
2565  SizeOfSegments,
2567 
2568  if(Segments)
2569  RtlZeroMemory(Segments, SizeOfSegments);
2570 
2571  return Segments;
2572 }
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
struct _MM_SECTION_SEGMENT MM_SECTION_SEGMENT
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by ExeFmtpCreateImageSection().

◆ ExeFmtpCreateImageSection()

NTSTATUS ExeFmtpCreateImageSection ( PFILE_OBJECT  FileObject,
PMM_IMAGE_SECTION_OBJECT  ImageSectionObject 
)

Definition at line 2990 of file section.c.

2992 {
2994  PVOID FileHeader;
2995  PVOID FileHeaderBuffer;
2996  ULONG FileHeaderSize;
2997  ULONG Flags;
2998  ULONG OldNrSegments;
2999  NTSTATUS Status;
3000  ULONG i;
3001 
3002  /*
3003  * Read the beginning of the file (2 pages). Should be enough to contain
3004  * all (or most) of the headers
3005  */
3006  Offset.QuadPart = 0;
3007 
3009  &Offset,
3010  PAGE_SIZE * 2,
3011  &FileHeader,
3012  &FileHeaderBuffer,
3013  &FileHeaderSize);
3014 
3015  if (!NT_SUCCESS(Status))
3016  return Status;
3017 
3018  if (FileHeaderSize == 0)
3019  {
3020  ExFreePool(FileHeaderBuffer);
3021  return STATUS_UNSUCCESSFUL;
3022  }
3023 
3024  /*
3025  * Look for a loader that can handle this executable
3026  */
3027  for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
3028  {
3029  Flags = 0;
3030 
3031  Status = ExeFmtpLoaders[i](FileHeader,
3032  FileHeaderSize,
3033  FileObject,
3034  ImageSectionObject,
3035  &Flags,
3038 
3039  if (!NT_SUCCESS(Status))
3040  {
3041  if (ImageSectionObject->Segments)
3042  {
3043  ExFreePool(ImageSectionObject->Segments);
3044  ImageSectionObject->Segments = NULL;
3045  }
3046  }
3047 
3049  break;
3050  }
3051 
3052  ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
3053 
3054  /*
3055  * No loader handled the format
3056  */
3058  {
3061  }
3062 
3063  if (!NT_SUCCESS(Status))
3064  return Status;
3065 
3066  ASSERT(ImageSectionObject->Segments != NULL);
3067  ASSERT(ImageSectionObject->RefCount > 0);
3068 
3069  /*
3070  * Some defaults
3071  */
3072  /* FIXME? are these values platform-dependent? */
3073  if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
3074  ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
3075 
3076  if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
3077  ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
3078 
3079  if(ImageSectionObject->BasedAddress == NULL)
3080  {
3081  if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3082  ImageSectionObject->BasedAddress = (PVOID)0x10000000;
3083  else
3084  ImageSectionObject->BasedAddress = (PVOID)0x00400000;
3085  }
3086 
3087  /*
3088  * And now the fun part: fixing the segments
3089  */
3090 
3091  /* Sort them by virtual address */
3092  MmspSortSegments(ImageSectionObject, Flags);
3093 
3094  /* Ensure they don't overlap in memory */
3095  if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
3097 
3098  /* Ensure they are aligned */
3099  OldNrSegments = ImageSectionObject->NrSegments;
3100 
3101  if (!MmspPageAlignSegments(ImageSectionObject, Flags))
3103 
3104  /* Trim them if the alignment phase merged some of them */
3105  if (ImageSectionObject->NrSegments < OldNrSegments)
3106  {
3107  PMM_SECTION_SEGMENT Segments;
3108  SIZE_T SizeOfSegments;
3109 
3110  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
3111 
3112  Segments = ExAllocatePoolWithTag(PagedPool,
3113  SizeOfSegments,
3115 
3116  if (Segments == NULL)
3118 
3119  RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
3120  ExFreePool(ImageSectionObject->Segments);
3121  ImageSectionObject->Segments = Segments;
3122  }
3123 
3124  /* And finish their initialization */
3125  for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
3126  {
3127  ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
3128  ImageSectionObject->Segments[i].ReferenceCount = &ImageSectionObject->RefCount;
3129  ImageSectionObject->Segments[i].Flags = &ImageSectionObject->SegFlags;
3130  MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
3131  ImageSectionObject->Segments[i].FileObject = FileObject;
3132  }
3133 
3134  ASSERT(ImageSectionObject->RefCount > 0);
3135 
3136  ImageSectionObject->FileObject = FileObject;
3137 
3139  return Status;
3140 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
#define IMAGE_FILE_DLL
Definition: pedump.c:169
static BOOLEAN NTAPI MmspPageAlignSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2807
static VOID NTAPI MmspSortSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2730
ASSERT(Segment->Locked)
NTSTATUS Status
Definition: section.c:4922
void * PVOID
Definition: retypes.h:9
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
static PMM_SECTION_SEGMENT NTAPI ExeFmtpAllocateSegments(IN ULONG NrSegments)
Definition: section.c:2556
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:539
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static PEXEFMT_LOADER ExeFmtpLoaders[]
Definition: section.c:2545
static NTSTATUS NTAPI ExeFmtpReadFile(IN PVOID File, IN PLARGE_INTEGER Offset, IN ULONG Length, OUT PVOID *Data, OUT PVOID *AllocBase, OUT PULONG ReadSize)
Definition: section.c:2576
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SIZE_T
Definition: typedefs.h:80
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
PLARGE_INTEGER Offset
Definition: section.c:4917
#define NULL
Definition: types.h:112
struct _MM_SECTION_SEGMENT MM_SECTION_SEGMENT
#define STATUS_ROS_EXEFMT_UNKNOWN_FORMAT
Definition: exeformat.h:72
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
static BOOLEAN NTAPI MmspCheckSegmentBounds(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2756

Referenced by MmCreateImageSection().

◆ ExeFmtpReadFile()

static NTSTATUS NTAPI ExeFmtpReadFile ( IN PVOID  File,
IN PLARGE_INTEGER  Offset,
IN ULONG  Length,
OUT PVOID Data,
OUT PVOID AllocBase,
OUT PULONG  ReadSize 
)
static

Definition at line 2576 of file section.c.

2582 {
2583  NTSTATUS Status;
2585  ULONG AdjustOffset;
2586  ULONG OffsetAdjustment;
2587  ULONG BufferSize;
2588  ULONG UsedSize;
2589  PVOID Buffer;
2592 
2594 
2595  if(Length == 0)
2596  {
2597  KeBugCheck(MEMORY_MANAGEMENT);
2598  }
2599 
2600  FileOffset = *Offset;
2601 
2602  /* Negative/special offset: it cannot be used in this context */
2603  if(FileOffset.u.HighPart < 0)
2604  {
2605  KeBugCheck(MEMORY_MANAGEMENT);
2606  }
2607 
2608  AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
2609  OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
2610  FileOffset.u.LowPart = AdjustOffset;
2611 
2612  BufferSize = Length + OffsetAdjustment;
2614 
2615  /*
2616  * It's ok to use paged pool, because this is a temporary buffer only used in
2617  * the loading of executables. The assumption is that MmCreateSection is
2618  * always called at low IRQLs and that these buffers don't survive a brief
2619  * initialization phase
2620  */
2622  if (!Buffer)
2623  {
2625  }
2626 
2628 
2629  UsedSize = (ULONG)Iosb.Information;
2630 
2631  if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
2632  {
2635  }
2636 
2637  if(NT_SUCCESS(Status))
2638  {
2639  *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
2640  *AllocBase = Buffer;
2641  *ReadSize = UsedSize - OffsetAdjustment;
2642  }
2643  else
2644  {
2645  ExFreePoolWithTag(Buffer, 'rXmM');
2646  }
2647 
2648  return Status;
2649 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
ASSERT(Segment->Locked)
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
NTSTATUS Status
Definition: section.c:4922
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ASSERT_IRQL_LESS(x)
Definition: debug.h:253
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
PLARGE_INTEGER Offset
Definition: section.c:4917
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID _In_ LONG _In_z_ PCHAR File
Definition: wdfdevice.h:4061
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define BufferSize
Definition: mmc.h:75
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
NTSTATUS NTAPI MiSimpleRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PVOID Buffer, ULONG Length, BOOLEAN Paging, PIO_STATUS_BLOCK ReadStatus)
Definition: io.c:109

Referenced by ExeFmtpCreateImageSection().

◆ FreeSegmentPage()

static VOID NTAPI FreeSegmentPage ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset 
)
static

Definition at line 962 of file section.c.

963 {
966 
968 
970 
972 
973  /* This must be either a valid entry or nothing */
975 
976  /* There should be no reference anymore */
978 
980  /* If there is a page, this must be because it's still dirty */
981  ASSERT(Page != 0);
982 
983  /* Write the page */
984  if (IS_DIRTY_SSE(Entry))
985  MiWritePage(Segment, Offset->QuadPart, Page);
986 
988 }
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1538
#define MC_USER
Definition: mm.h:103
#define PFN_FROM_SSE(E)
Definition: mm.h:1304
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:73
#define MmLockSectionSegment(x)
Definition: mm.h:1333
uint32_t ULONG_PTR
Definition: typedefs.h:65
ASSERT(Segment->Locked)
ULONG PFN_NUMBER
Definition: ke.h:9
#define IS_DIRTY_SSE(E)
Definition: mm.h:1313
Entry
Definition: section.c:4931
PFN_NUMBER Page
Definition: section.c:4923
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
NTSTATUS NTAPI MiWritePage(PMM_SECTION_SEGMENT Segment, LONGLONG SegOffset, PFN_NUMBER Page)
Definition: section.c:240
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1305
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1321
base of all file and directory entries
Definition: entries.h:82

Referenced by _When_().

◆ if() [1/2]

if ( Entry  = = 0)

Definition at line 4932 of file section.c.

4937  {
4938  BOOLEAN DirtyAgain;
4939 
4940  /*
4941  * We got a dirty entry. This path is for the shared data,
4942  * be-it regular file maps or shared sections of DLLs
4943  */
4945  FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
4946 
4947  /* Insert the cleaned entry back. Mark it as write in progress, and clear the dirty bit. */
4949  Entry = WRITE_SSE(Entry);
4951 
4953 
4954  if (FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
4955  {
4956  /* We have to write it back to the file. Tell the FS driver who we are */
4957  if (PageOut)
4959 
4960  /* Go ahead and write the page */
4961  DPRINT("Writing page at offset %I64d for file %wZ, Pageout: %s\n",
4962  Offset->QuadPart, &Segment->FileObject->FileName, PageOut ? "TRUE" : "FALSE");
4963  Status = MiWritePage(Segment, Offset->QuadPart, Page);
4964 
4965  if (PageOut)
4967  }
4968  else
4969  {
4970  /* This must only be called by the page-out path */
4971  ASSERT(PageOut);
4972 
4973  /* And this must be for a shared section in a DLL */
4974  ASSERT(FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
4975 
4976  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
4977  if (!SwapEntry)
4978  {
4979  SwapEntry = MmAllocSwapPage();
4980  }
4981 
4982  if (SwapEntry)
4983  {
4984  Status = MmWriteToSwapPage(SwapEntry, Page);
4985  if (NT_SUCCESS(Status))
4986  {
4987  MmSetSavedSwapEntryPage(Page, SwapEntry);
4988  }
4989  else
4990  {
4991  MmFreeSwapPage(SwapEntry);
4992  }
4993  }
4994  else
4995  {
4996  DPRINT1("Failed to allocate a swap page!\n");
4998  }
4999  }
5000 
5002 
5003  /* Get the entry again */
5006 
5007  if (!NT_SUCCESS(Status))
5008  {
5009  /* Damn, this failed. Consider this page as still dirty */
5010  DPRINT1("MiWritePage FAILED: Status 0x%08x!\n", Status);
5011  DirtyAgain = TRUE;
5012  }
5013  else
5014  {
5015  /* Check if someone dirtified this page while we were not looking */
5016  DirtyAgain = IS_DIRTY_SSE(Entry);
5017  }
5018 
5019  /* Drop the reference we got, deleting the write altogether. */
5021  if (DirtyAgain)
5022  {
5023  Entry = DIRTY_SSE(Entry);
5024  }
5026  }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1538
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WRITE_SSE(E)
Definition: mm.h:1314
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:57
#define TRUE
Definition: types.h:120
#define PFN_FROM_SSE(E)
Definition: mm.h:1304
#define MmLockSectionSegment(x)
Definition: mm.h:1333
#define DIRTY_SSE(E)
Definition: mm.h:1311
ASSERT(Segment->Locked)
#define IS_DIRTY_SSE(E)
Definition: mm.h:1313
#define MAKE_SSE(P, C)
Definition: mm.h:1323
unsigned char BOOLEAN
PFN_NUMBER Page
Definition: section.c:4923
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
SWAPENTRY NTAPI MmAllocSwapPage(VOID)
Definition: pagefile.c:304
PLARGE_INTEGER BOOLEAN BOOLEAN PageOut
Definition: section.c:4920
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define PAGE_FROM_SSE(E)
Definition: mm.h:1319
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
NTSTATUS NTAPI MiWritePage(PMM_SECTION_SEGMENT Segment, LONGLONG SegOffset, PFN_NUMBER Page)
Definition: section.c:240
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SWAPENTRY
Definition: mm.h:53
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1321
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:483
NTSTATUS NTAPI MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:130
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI MmFreeSwapPage(SWAPENTRY Entry)
Definition: pagefile.c:274
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:499

Referenced by MmExtendSection(), MmMapViewInSystemSpaceEx(), MmpDeleteSection(), NtQuerySection(), and PeFmtCreateSection().

◆ if() [2/2]

if ( !IS_DIRTY_SSE(Entry) &&(SHARE_COUNT_FROM_SSE(Entry)==0) &&  PageOut)

Definition at line 5029 of file section.c.

5030  {
5031  ULONG_PTR NewEntry = 0;
5032  /* Restore the swap entry here */
5033  if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
5034  {
5035  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
5036  if (SwapEntry)
5037  NewEntry = MAKE_SWAP_SSE(SwapEntry);
5038  }
5039 
5040  /* Yes. Release it */
5043  /* Tell the caller we released the page */
5044  return TRUE;
5045  }
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:57
#define TRUE
Definition: types.h:120
#define MC_USER
Definition: mm.h:103
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:73
uint32_t ULONG_PTR
Definition: typedefs.h:65
PFN_NUMBER Page
Definition: section.c:4923
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SWAPENTRY
Definition: mm.h:53
#define MAKE_SWAP_SSE(S)
Definition: mm.h:1310
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:499

◆ ImageSectionObjectFromSegment()

PMM_IMAGE_SECTION_OBJECT ImageSectionObjectFromSegment ( PMM_SECTION_SEGMENT  Segment)

Definition at line 121 of file section.c.

122 {
123  ASSERT((Segment->SegFlags & MM_DATAFILE_SEGMENT) == 0);
124 
125  return CONTAINING_RECORD(Segment->ReferenceCount, MM_IMAGE_SECTION_OBJECT, RefCount);
126 }
ASSERT(Segment->Locked)
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
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227

Referenced by MiRosUnmapViewOfSection().

◆ MiArm3GetCorrectFileAccessMask()

ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask ( IN ACCESS_MASK  SectionPageProtection)

Definition at line 140 of file section.c.

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

◆ MiCopyFromUserPage()

static NTSTATUS MiCopyFromUserPage ( PFN_NUMBER  DestPage,
const VOID SrcAddress 
)
static

Definition at line 1171 of file section.c.

1172 {
1174  KIRQL Irql;
1175  PVOID DestAddress;
1176 
1178  DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
1179  if (DestAddress == NULL)
1180  {
1181  return STATUS_NO_MEMORY;
1182  }
1183  ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
1184  ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
1185  RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
1186  MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
1187  return STATUS_SUCCESS;
1188 }
_Out_ PKIRQL Irql
Definition: csq.h:179
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:28
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:91
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by MmAccessFaultSectionView().

◆ MiGrabDataSection()

static PMM_SECTION_SEGMENT MiGrabDataSection ( PSECTION_OBJECT_POINTERS  SectionObjectPointer)
static

Definition at line 91 of file section.c.

92 {
93  KIRQL OldIrql = MiAcquirePfnLock();
95 
96  while (TRUE)
97  {
98  Segment = SectionObjectPointer->DataSectionObject;
99  if (!Segment)
100  break;
101 
102  if (Segment->SegFlags & (MM_SEGMENT_INCREATE | MM_SEGMENT_INDELETE))
103  {
104  MiReleasePfnLock(OldIrql);
106  OldIrql = MiAcquirePfnLock();
107  continue;
108  }
109 
110  ASSERT(Segment->SegFlags & MM_DATAFILE_SEGMENT);
111  InterlockedIncrement64(&Segment->RefCount);
112  break;
113  }
114 
115  MiReleasePfnLock(OldIrql);
116 
117  return Segment;
118 }
static LARGE_INTEGER TinyTime
Definition: section.c:64
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
#define MM_SEGMENT_INCREATE
Definition: mm.h:229
return FALSE
Definition: section.c:5047
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
KIRQL OldIrql
Definition: mm.h:1502
#define InterlockedIncrement64
Definition: interlocked.h:211
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227
#define MM_SEGMENT_INDELETE
Definition: mm.h:228
#define NULL
Definition: types.h:112

Referenced by MmCanFileBeTruncated(), MmFlushSegment(), MmMakeDataSectionResident(), and MmPurgeSegment().

◆ MiMapViewInSystemSpace()

NTSTATUS MiMapViewInSystemSpace ( IN PVOID  Section,
IN PVOID  Session,
OUT PVOID MappedBase,
IN OUT PSIZE_T  ViewSize,
IN PLARGE_INTEGER  SectionOffset 
)

◆ MiPurgeImageSegment()

static BOOLEAN MiPurgeImageSegment ( PMM_SECTION_SEGMENT  Segment)
static

Definition at line 4199 of file section.c.

4200 {
4202 
4204 
4205  /* Loop over all entries */
4206  for (PageTable = RtlEnumerateGenericTable(&Segment->PageTable, TRUE);
4207  PageTable != NULL;
4209  {
4210  for (ULONG i = 0; i < _countof(PageTable->PageEntries); i++)
4211  {
4212  ULONG_PTR Entry = PageTable->PageEntries[i];
4214 
4215  if (!Entry)
4216  continue;
4217 
4219  {
4220  /* I/O ongoing or swap entry. Someone mapped this file as we were not looking */
4222  return FALSE;
4223  }
4224 
4225  /* Regular entry */
4228 
4229  /* Properly remove using the used API */
4230  Offset.QuadPart = PageTable->FileOffset.QuadPart + (i << PAGE_SHIFT);
4233  }
4234  }
4235 
4237 
4238  return TRUE;
4239 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:40
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:57
#define TRUE
Definition: types.h:120
#define MC_USER
Definition: mm.h:103
#define PFN_FROM_SSE(E)
Definition: mm.h:1304
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ BOOLEAN Restart)
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:73
#define MmLockSectionSegment(x)
Definition: mm.h:1333
uint32_t ULONG_PTR
Definition: typedefs.h:65
ASSERT(Segment->Locked)
return FALSE
Definition: section.c:5047
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define _countof(array)
Definition: sndvol32.h:68
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1305
PLARGE_INTEGER Offset
Definition: section.c:4917
#define NULL
Definition: types.h:112
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1321
#define IS_WRITE_SSE(E)
Definition: mm.h:1315
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:499

Referenced by MmFlushImageSection().

◆ MiRosUnmapViewInSystemSpace()

NTSTATUS NTAPI MiRosUnmapViewInSystemSpace ( IN PVOID  MappedBase)

Definition at line 4446 of file section.c.

4447 {
4448  DPRINT("MmUnmapViewInSystemSpace() called\n");
4449 
4451 }
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:3491
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1640
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492

Referenced by MmUnmapViewInSystemSpace().

◆ MiRosUnmapViewOfSection()

NTSTATUS NTAPI MiRosUnmapViewOfSection ( IN PEPROCESS  Process,
IN PVOID  BaseAddress,
IN BOOLEAN  SkipDebuggerNotify 
)

Definition at line 3555 of file section.c.

3558 {
3559  NTSTATUS Status;
3562  PVOID ImageBaseAddress = 0;
3563 
3564  DPRINT("Opening memory area Process %p BaseAddress %p\n",
3565  Process, BaseAddress);
3566 
3567  ASSERT(Process);
3568 
3570 
3572  BaseAddress);
3573  if (MemoryArea == NULL ||
3574 #ifdef NEWCC
3575  ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) && (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
3576 #else
3578 #endif
3580 
3581  {
3583 
3584  DPRINT1("Unable to find memory area at address %p.\n", BaseAddress);
3585  return STATUS_NOT_MAPPED_VIEW;
3586  }
3587 
3589  {
3590  ULONG i;
3591  ULONG NrSegments;
3592  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3593  PMM_SECTION_SEGMENT SectionSegments;
3595 
3596  Segment = MemoryArea->SectionData.Segment;
3597  ImageSectionObject = ImageSectionObjectFromSegment(Segment);
3598  SectionSegments = ImageSectionObject->Segments;
3599  NrSegments = ImageSectionObject->NrSegments;
3600 
3602 
3603  /* Search for the current segment within the section segments
3604  * and calculate the image base address */
3605  for (i = 0; i < NrSegments; i++)
3606  {
3607  if (Segment == &SectionSegments[i])
3608  {
3609  ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
3610  break;
3611  }
3612  }
3613  if (i >= NrSegments)
3614  {
3615  KeBugCheck(MEMORY_MANAGEMENT);
3616  }
3617 
3618  for (i = 0; i < NrSegments; i++)
3619  {
3620  PVOID SBaseAddress = (PVOID)
3621  ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
3622 
3623  Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
3624  if (!NT_SUCCESS(Status))
3625  {
3626  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3627  SBaseAddress, Process, Status);
3629  }
3630  }
3631  DPRINT("One mapping less for %p\n", ImageSectionObject->FileObject->SectionObjectPointer);
3632  InterlockedDecrement(&ImageSectionObject->MapCount);
3633  }
3634  else
3635  {
3637  if (!NT_SUCCESS(Status))
3638  {
3639  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3642  }
3643  }
3644 
3645  /* Notify debugger */
3646  if (ImageBaseAddress && !SkipDebuggerNotify) DbgkUnMapViewOfSection(ImageBaseAddress);
3647 
3648  return STATUS_SUCCESS;
3649 }
union _MMVAD::@2535 u
ULONG Type
Definition: mm.h:240
#define TRUE
Definition: types.h:120
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
LONG NTSTATUS
Definition: precomp.h:26
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:731
uint32_t ULONG_PTR
Definition: typedefs.h:65
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:3491
else
Definition: tritemp.h:161
ASSERT(Segment->Locked)
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:86
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
NTSTATUS Status
Definition: section.c:4922
struct _MM_SECTION_SEGMENT::@1745 Image
void * PVOID
Definition: retypes.h:9
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:82
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
Status
Definition: gdiplustypes.h:24
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PMM_SECTION_SEGMENT Segments
Definition: mm.h:223
BOOLEAN DeleteInProgress
Definition: mm.h:242
MMVAD VadNode
Definition: mm.h:238
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
#define InterlockedDecrement
Definition: armddk.h:52
PFILE_OBJECT FileObject
Definition: mm.h:215
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1640
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PMM_IMAGE_SECTION_OBJECT ImageSectionObjectFromSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:121
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
struct _MEMORY_AREA::@1746 SectionData
#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
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:262
#define ULONG_PTR
Definition: config.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:37
ULONG_PTR VadType
Definition: mmtypes.h:691

Referenced by MiRosCleanupMemoryArea(), and MiUnmapViewOfSection().

◆ MiWritePage()

NTSTATUS NTAPI MiWritePage ( PMM_SECTION_SEGMENT  Segment,
LONGLONG  SegOffset,
PFN_NUMBER  Page 
)

Definition at line 240 of file section.c.

250 {
253  KEVENT Event;
254  UCHAR MdlBase[sizeof(MDL) + sizeof(PFN_NUMBER)];
255  PMDL Mdl = (PMDL)MdlBase;
256  PFILE_OBJECT FileObject = Segment->FileObject;
258 
259  FileOffset.QuadPart = Segment->Image.FileOffset + SegOffset;
260 
261  RtlZeroMemory(MdlBase, sizeof(MdlBase));
264  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
265 
268  if (Status == STATUS_PENDING)
269  {
271  Status = IoStatus.Status;
272  }
273  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
274  {
275  MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
276  }
277 
278  return Status;
279 }
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
LONG NTSTATUS
Definition: precomp.h:26
PVOID PMDL
Definition: usb.h:39
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
ULONG PFN_NUMBER
Definition: ke.h:9
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:828
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
NTSTATUS Status
Definition: section.c:4922
return FALSE
Definition: section.c:5047
PFN_NUMBER Page
Definition: section.c:4923
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
Status
Definition: gdiplustypes.h:24
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
Definition: pagefile.c:94
* PFILE_OBJECT
Definition: iotypes.h:1998
unsigned char UCHAR
Definition: xmlstorage.h:181
MDL
Definition: mmtypes.h:117
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
NTSTATUS NTAPI IoSynchronousPageWrite(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1144
#define NULL
Definition: types.h:112
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by FreeSegmentPage().

◆ MmAccessFaultSectionView()

NTSTATUS NTAPI MmAccessFaultSectionView ( PMMSUPPORT  AddressSpace,
MEMORY_AREA MemoryArea,
PVOID  Address,
BOOLEAN  Locked 
)

Definition at line 1891 of file section.c.

1895 {
1897  PFN_NUMBER OldPage;
1898  PFN_NUMBER NewPage;
1899  PVOID PAddress;
1902  ULONG_PTR Entry;
1904  BOOLEAN Cow = FALSE;
1905  ULONG NewProtect;
1906 
1907  DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1908 
1909  /* Get the region for this address */
1911  &MemoryArea->SectionData.RegionListHead,
1912  Address, NULL);
1913  ASSERT(Region != NULL);
1914  if (!(Region->Protect & PAGE_IS_WRITABLE))
1915  return STATUS_ACCESS_VIOLATION;
1916 
1917  /* Make sure we have a page mapping for this address. */
1919  {
1921  if (!NT_SUCCESS(Status))
1922  {
1923  /* This is invalid access ! */
1924  return Status;
1925  }
1926  }
1927 
1928  /*
1929  * Check if the page has already been set readwrite
1930  */
1932  {
1933  DPRINT("Address 0x%p\n", Address);
1934  return STATUS_SUCCESS;
1935  }
1936 
1937  /* Check if we are doing Copy-On-Write */
1938  Segment = MemoryArea->SectionData.Segment;
1939  Cow = Segment->WriteCopy || (Region->Protect & PAGE_IS_WRITECOPY);
1940 
1941  if (!Cow)
1942  {
1943  /* Simply update page protection and we're done */
1944  MmSetPageProtect(Process, Address, Region->Protect);
1945  return STATUS_SUCCESS;
1946  }
1947 
1948  /* Calculate the new protection & check if we should update the region */
1949  NewProtect = Region->Protect;
1951  {
1953  if (Region->Protect & PAGE_IS_EXECUTABLE)
1955  else
1958  &MemoryArea->SectionData.RegionListHead,
1961  }
1962 
1963  /*
1964  * Find the offset of the page
1965  */
1966  PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1967  Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1968  + MemoryArea->SectionData.ViewOffset;
1969 
1970  /* Get the page mapping this section offset. */
1973 
1974  /* Get the current page mapping for the process */
1975  ASSERT(MmIsPagePresent(Process, PAddress));
1976  OldPage = MmGetPfnForProcess(Process, PAddress);
1977  ASSERT(OldPage != 0);
1978 
1979  if (IS_SWAP_FROM_SSE(Entry) ||
1980  PFN_FROM_SSE(Entry) != OldPage)
1981  {
1983  /* This is a private page. We must only change the page protection. */
1984  MmSetPageProtect(Process, PAddress, NewProtect);
1985  return STATUS_SUCCESS;
1986  }
1987 
1988  /*
1989  * Allocate a page
1990  */
1992  {
1993  KeBugCheck(MEMORY_MANAGEMENT);
1994  }
1995 
1996  /*
1997  * Copy the old page
1998  */
1999  NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
2000 
2001  /*
2002  * Unshare the old page.
2003  */
2004  DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
2005  MmDeleteVirtualMapping(Process, PAddress, NULL, NULL);
2006  if (Process)
2007  MmDeleteRmap(OldPage, Process, PAddress);
2010 
2011  /*
2012  * Set the PTE to point to the new page
2013  */
2014  if (!NT_SUCCESS(MmCreateVirtualMapping(Process, PAddress, NewProtect, NewPage)))
2015  {
2016  DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2017  KeBugCheck(MEMORY_MANAGEMENT);
2018  }
2019 
2020  if (Process)
2021  MmInsertRmap(NewPage, Process, PAddress);
2022 
2023  DPRINT("Address 0x%p\n", Address);
2024  return STATUS_SUCCESS;
2025 }
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1538
static VOID MmAlterViewAttributes(PMMSUPPORT AddressSpace, PVOID BaseAddress, SIZE_T RegionSize, ULONG OldType, ULONG OldProtect, ULONG NewType, ULONG NewProtect)
Definition: section.c:1439
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define PAGE_IS_EXECUTABLE
Definition: mm.h:148
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
#define TRUE
Definition: types.h:120
#define MC_USER
Definition: mm.h:103
#define PFN_FROM_SSE(E)
Definition: mm.h:1304
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
Definition: mm.h:451
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
Definition: section.c:1090
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:280
NTSTATUS NTAPI MmCreateVirtualMapping(struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PFN_NUMBER Page)
#define PAGE_IS_WRITECOPY
Definition: mm.h:154
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
#define MmLockSectionSegment(x)
Definition: mm.h:1333
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN NTAPI MmIsPagePresent(struct _EPROCESS *Process, PVOID Address)
ASSERT(Segment->Locked)
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS NTAPI MmAlterRegion(PMMSUPPORT AddressSpace, PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc)
Definition: region.c:108
#define PAGE_IS_WRITABLE
Definition: mm.h:142
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:207
NTSTATUS NTAPI MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
Definition: section.c:1525
NTSTATUS Status
Definition: section.c:4922
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
Entry
Definition: section.c:4931
VOID NTAPI MmDeleteVirtualMapping(struct _EPROCESS *Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
return FALSE
Definition: section.c:5047
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:120
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:233
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1305
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1625
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
PLARGE_INTEGER Offset
Definition: section.c:4917
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
struct _MEMORY_AREA::@1746 SectionData
#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
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
static NTSTATUS MiCopyFromUserPage(PFN_NUMBER DestPage, const VOID *SrcAddress)
Definition: section.c:1171
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:82
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by MmpAccessFault().

◆ MmAlterViewAttributes()

static VOID MmAlterViewAttributes ( PMMSUPPORT  AddressSpace,
PVOID  BaseAddress,
SIZE_T  RegionSize,
ULONG  OldType,
ULONG  OldProtect,
ULONG  NewType,
ULONG  NewProtect 
)
static

Definition at line 1439 of file section.c.

1446 {
1449  BOOLEAN DoCOW = FALSE;
1450  ULONG i;
1452 
1454  ASSERT(MemoryArea != NULL);
1455  Segment = MemoryArea->SectionData.Segment;
1457 
1458  if ((Segment->WriteCopy) &&
1460  {
1461  DoCOW = TRUE;
1462  }
1463 
1464  if (OldProtect != NewProtect)
1465  {
1466  for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
1467  {
1468  SWAPENTRY SwapEntry;
1469  PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE);
1471 
1472  /* Wait for a wait entry to disappear */
1473  do
1474  {
1475  MmGetPageFileMapping(Process, Address, &SwapEntry);
1476  if (SwapEntry != MM_WAIT_ENTRY)
1477  break;
1480  YieldProcessor();
1483  }
1484  while (TRUE);
1485 
1486  /*
1487  * If we doing COW for this segment then check if the page is
1488  * already private.
1489  */
1491  {
1493  ULONG_PTR Entry;
1494  PFN_NUMBER Page;
1495 
1497  + MemoryArea->SectionData.ViewOffset;
1499  /*
1500  * An MM_WAIT_ENTRY is ok in this case... It'll just count as
1501  * IS_SWAP_FROM_SSE and we'll do the right thing.
1502  */
1504 
1507  {
1508  Protect = NewProtect;
1509  }
1510  }
1511 
1513  {
1515  Protect);
1516  }
1517  }
1518  }
1519 
1521 }
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1538
_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
#define TRUE
Definition: types.h:120
#define PFN_FROM_SSE(E)
Definition: mm.h:1304
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1618
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MmLockSectionSegment(x)
Definition: mm.h:1333
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
BOOLEAN NTAPI MmIsPagePresent(struct _EPROCESS *Process, PVOID Address)
ASSERT(Segment->Locked)
ULONG PFN_NUMBER
Definition: ke.h:9
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
Entry
Definition: section.c:4931
return FALSE
Definition: section.c:5047
PFN_NUMBER Page
Definition: section.c:4923
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
BOOLEAN NTAPI MmIsDisabledPage(struct _EPROCESS *Process, PVOID Address)
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:233
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1305
ULONG_PTR SWAPENTRY
Definition: mm.h:53
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1625
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
PLARGE_INTEGER Offset
Definition: section.c:4917
#define NULL
Definition: types.h:112
#define PAGE_READONLY
Definition: compat.h:138
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
struct _MEMORY_AREA::@1746 SectionData
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:37
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1611
base of all file and directory entries
Definition: entries.h:82
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by MmAccessFaultSectionView(), MmNotPresentFaultSectionView(), and MmProtectSectionView().

◆ MmArePagesResident()

BOOLEAN NTAPI MmArePagesResident ( _In_ PEPROCESS  Process,
_In_ PVOID  Address,
_In_ ULONG  Length 
)

Definition at line 4664 of file section.c.

4668 {
4670  BOOLEAN Ret = TRUE;
4672  LARGE_INTEGER SegmentOffset, RangeEnd;
4674 
4676 
4678  if (MemoryArea == NULL)
4679  {
4681  return FALSE;
4682  }
4683 
4684  /* Only supported in old Mm for now */
4686  /* For file mappings */
4688 
4689  Segment = MemoryArea->SectionData.Segment;
4691 
4693  + MemoryArea->SectionData.ViewOffset;
4695  + MemoryArea->SectionData.ViewOffset;
4696 
4697  while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
4698  {
4700  if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4701  {
4702  Ret = FALSE;
4703  break;
4704  }
4705  SegmentOffset.QuadPart += PAGE_SIZE;
4706  }
4707 
4709 
4711  return Ret;
4712 }
union _MMVAD::@2535 u
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1538
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ULONG Type
Definition: mm.h:240
#define TRUE
Definition: types.h:120
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1618
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MmLockSectionSegment(x)
Definition: mm.h:1333
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:731
uint32_t ULONG_PTR
Definition: typedefs.h:65
ASSERT(Segment->Locked)
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
return FALSE
Definition: section.c:5047
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:82
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
MMVAD VadNode
Definition: mm.h:238
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:233
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1640
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1305
#define NULL
Definition: types.h:112
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
struct _MEMORY_AREA::@1746 SectionData
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:37
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1611
ULONG_PTR VadType
Definition: mmtypes.h:691
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CcRosEnsureVacbResident().

◆ MmCanFileBeTruncated()

BOOLEAN NTAPI MmCanFileBeTruncated ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointer,
IN PLARGE_INTEGER  NewFileSize 
)

Definition at line 4151 of file section.c.

4153 {
4154  BOOLEAN Ret;
4156 
4157  /* Check whether an ImageSectionObject exists */
4158  if (SectionObjectPointer->ImageSectionObject != NULL)
4159  {
4160  DPRINT1("ERROR: File can't be truncated because it has an image section\n");
4161  return FALSE;
4162  }
4163 
4165  if (!Segment)
4166  {
4167  /* There is no data section. It's fine to do anything. */
4168  return TRUE;
4169  }
4170 
4172  if ((Segment->SectionCount == 0) ||
4173  ((Segment->SectionCount == 1) && (SectionObjectPointer->SharedCacheMap != NULL)))
4174  {
4175  /* If the cache is the only one holding a reference to the segment, then it's fine to resize */
4176  Ret = TRUE;
4177  }
4178  else
4179  {
4180  /* We can't shrink, but we can extend */
4181  Ret = NewFileSize->QuadPart >= Segment->RawLength.QuadPart;
4182 #if DBG
4183  if (!Ret)
4184  {
4185  DPRINT1("Cannot truncate data: New Size %I64d, Segment Size %I64d\n", NewFileSize->QuadPart, Segment->RawLength.QuadPart);
4186  }
4187 #endif
4188  }
4190  MmDereferenceSegment(Segment);
4191 
4192  DPRINT("FIXME: didn't check for outstanding write probes\n");
4193 
4194  return Ret;
4195 }
#define TRUE
Definition: types.h:120
#define MmLockSectionSegment(x)
Definition: mm.h:1333
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
unsigned char BOOLEAN
return FALSE
Definition: section.c:5047
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_In_opt_ PLARGE_INTEGER NewFileSize
Definition: mmfuncs.h:608
static PMM_SECTION_SEGMENT MiGrabDataSection(PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: section.c:91
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by Ext2SetFileInformation(), Ext2SupersedeOrOverWriteFile(), NtfsSetEndOfFile(), open_file2(), RxCommonSetInformation(), set_end_of_file_information(), SetAttributeDataLength(), UDFCommonCreate(), UDFSetAllocationInformation(), UDFSetEOF(), VfatSetAllocationSizeInformation(), and VfatSetInformation().

◆ MmCreateArm3Section()

NTSTATUS NTAPI MmCreateArm3Section ( OUT PVOID SectionObject,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN PLARGE_INTEGER  InputMaximumSize,
IN ULONG  SectionPageProtection,
IN ULONG  AllocationAttributes,
IN HANDLE FileHandle  OPTIONAL,
IN PFILE_OBJECT FileObject  OPTIONAL 
)

Definition at line 2465 of file section.c.

2473 {
2474  SECTION Section;
2475  PSECTION NewSection;
2476  PSUBSECTION Subsection;
2477  PSEGMENT NewSegment, Segment;
2478  NTSTATUS Status;
2479  PCONTROL_AREA ControlArea;
2480  ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2482  BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2483  KIRQL OldIrql;
2485  BOOLEAN UserRefIncremented = FALSE;
2486  PVOID PreviousSectionPointer;
2487 
2488  /* Make the same sanity checks that the Nt interface should've validated */
2491  SEC_NO_CHANGE)) == 0);
2495  SEC_NOCACHE | SEC_NO_CHANGE))));
2501 
2502  /* Convert section flag to page flag */
2504 
2505  /* Check to make sure the protection is correct. Nt* does this already */
2506  ProtectionMask = MiMakeProtectionMask(SectionPageProtection);
2507  if (ProtectionMask == MM_INVALID_PROTECTION) return STATUS_INVALID_PAGE_PROTECTION;
2508 
2509  /* Check if this is going to be a data or image backed file section */
2510  if ((FileHandle) || (FileObject))
2511  {
2512  /* These cannot be mapped with large pages */
2514 
2515  /* For now, only support the mechanism through a file handle */
2516  ASSERT(FileObject == NULL);
2517 
2518  /* Reference the file handle to get the object */
2520  MmMakeFileAccess[ProtectionMask],
2522  PreviousMode,
2523  (PVOID*)&File,
2524  NULL);
2525  if (!NT_SUCCESS(Status)) return Status;
2526 
2527  /* Make sure Cc has been doing its job */
2528  if (!File->SectionObjectPointer)
2529  {
2530  /* This is not a valid file system-based file, fail */
2533  }
2534 
2535  /* Image-file backed sections are not yet supported */
2537 
2538  /* Compute the size of the control area, and allocate it */
2539  ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2540  ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2541  if (!ControlArea)
2542  {
2545  }
2546 
2547  /* Zero it out */
2548  RtlZeroMemory(ControlArea, ControlAreaSize);
2549 
2550  /* Did we get a handle, or an object? */
2551  if (FileHandle)
2552  {
2553  /* We got a file handle so we have to lock down the file */
2554 #if 0
2556  if (!NT_SUCCESS(Status))
2557  {
2558  ExFreePool(ControlArea);
2560  return Status;
2561  }
2562 #else
2563  /* ReactOS doesn't support this API yet, so do nothing */
2565 #endif
2566  /* Update the top-level IRP so that drivers know what's happening */
2568  FileLock = TRUE;
2569  }
2570 
2571  /* Lock the PFN database while we play with the section pointers */
2572  OldIrql = MiAcquirePfnLock();
2573 
2574  /* Image-file backed sections are not yet supported */
2576 
2577  /* There should not already be a control area for this file */
2578  ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2579  NewSegment = NULL;
2580 
2581  /* Write down that this CA is being created, and set it */
2582  ControlArea->u.Flags.BeingCreated = TRUE;
2584  PreviousSectionPointer = File->SectionObjectPointer;
2585  File->SectionObjectPointer->DataSectionObject = ControlArea;
2586 
2587  /* We can release the PFN lock now */
2588  MiReleasePfnLock(OldIrql);
2589 
2590  /* We don't support previously-mapped file */
2591  ASSERT(NewSegment == NULL);
2592 
2593  /* Image-file backed sections are not yet supported */
2595 
2596  /* So we always create a data file map */
2598  &Segment,
2599  (PSIZE_T)InputMaximumSize,
2602  KernelCall);
2603  if (!NT_SUCCESS(Status))
2604  {
2605  /* Lock the PFN database while we play with the section pointers */
2606  OldIrql = MiAcquirePfnLock();
2607 
2608  /* Reset the waiting-for-deletion event */
2609  ASSERT(ControlArea->WaitingForDeletion == NULL);
2610  ControlArea->WaitingForDeletion = NULL;
2611 
2612  /* Set the file pointer NULL flag */
2613  ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2614  ControlArea->u.Flags.FilePointerNull = TRUE;
2615 
2616  /* Delete the data section object */
2618  File->SectionObjectPointer->DataSectionObject = NULL;
2619 
2620  /* No longer being created */
2621  ControlArea->u.Flags.BeingCreated = FALSE;
2622 
2623  /* We can release the PFN lock now */
2624  MiReleasePfnLock(OldIrql);
2625 
2626  /* Check if we locked and set the IRP */
2627  if (FileLock)
2628  {
2629  /* Undo */
2631  //FsRtlReleaseFile(File);
2632  }
2633 
2634  /* Free the control area and de-ref the file object */
2635  ExFreePool(ControlArea);
2637 
2638  /* All done */
2639  return Status;
2640  }
2641 
2642  /* On success, we expect this */
2643  ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2644 
2645  /* Check if a maximum size was specified */
2646  if (!InputMaximumSize->QuadPart)
2647  {
2648  /* Nope, use the segment size */
2649  Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2650  }
2651  else
2652  {
2653  /* Yep, use the entered size */
2654  Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2655  }
2656  }
2657  else
2658  {
2659  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2661 
2662  /* Not yet supported */
2664 
2665  /* So this must be a pagefile-backed section, create the mappings needed */
2666  Status = MiCreatePagingFileMap(&NewSegment,
2667  InputMaximumSize,
2668  ProtectionMask,
2670  if (!NT_SUCCESS(Status)) return Status;
2671 
2672  /* Set the size here, and read the control area */
2673  Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2674  ControlArea = NewSegment->ControlArea;
2675 
2676  /* MiCreatePagingFileMap increments user references */
2677  UserRefIncremented = TRUE;
2678  }
2679 
2680  /* Did we already have a segment? */
2681  if (!NewSegment)
2682  {
2683  /* This must be the file path and we created a segment */
2684  NewSegment = Segment;
2685  ASSERT(File != NULL);
2686 
2687  /* Acquire the PFN lock while we set control area flags */
2688  OldIrql = MiAcquirePfnLock();
2689 
2690  /* We don't support this race condition yet, so assume no waiters */
2691  ASSERT(ControlArea->WaitingForDeletion == NULL);
2692  ControlArea->WaitingForDeletion = NULL;
2693 
2694  /* Image-file backed sections are not yet supported, nor ROM images */
2696  ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2697 
2698  /* Take off the being created flag, and then release the lock */
2699  ControlArea->u.Flags.BeingCreated = FALSE;
2700  MiReleasePfnLock(OldIrql);
2701  }
2702 
2703  /* Check if we locked the file earlier */
2704  if (FileLock)
2705  {
2706  /* Reset the top-level IRP and release the lock */
2708  //FsRtlReleaseFile(File);
2709  FileLock = FALSE;
2710  }
2711 
2712  /* Set the initial section object data */
2713  Section.InitialPageProtection = SectionPageProtection;
2714 
2715  /* The mapping created a control area and segment, save the flags */
2716  Section.Segment = NewSegment;
2717  Section.u.LongFlags = ControlArea->u.LongFlags;
2718 
2719  /* Check if this is a user-mode read-write non-image file mapping */
2720  if (!(FileObject) &&
2722  !(ControlArea->u.Flags.Image) &&
2723  (ControlArea->FilePointer))
2724  {
2725  /* Add a reference and set the flag */
2726  Section.u.Flags.UserWritable = TRUE;
2727  InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2728  }
2729 
2730  /* Check for image mappings or page file mappings */
2731  if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2732  {
2733  /* Charge the segment size, and allocate a subsection */
2734  PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2735  Size = sizeof(SUBSECTION);
2736  }
2737  else
2738  {
2739  /* Charge nothing, and allocate a mapped subsection */
2740  PagedCharge = 0;
2741  Size = sizeof(MSUBSECTION);
2742  }
2743 
2744  /* Check if this is a normal CA */
2745  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2746  ASSERT(ControlArea->u.Flags.Rom == 0);
2747 
2748  /* Charge only a CA, and the subsection is right after */
2749  NonPagedCharge = sizeof(CONTROL_AREA);
2750  Subsection = (PSUBSECTION)(ControlArea + 1);
2751 
2752  /* We only support single-subsection mappings */
2753  NonPagedCharge += Size;
2754  ASSERT(Subsection->NextSubsection == NULL);
2755 
2756  /* Create the actual section object, with enough space for the prototype PTEs */
2760  PreviousMode,
2761  NULL,
2762  sizeof(SECTION),
2763  PagedCharge,
2764  NonPagedCharge,
2765  (PVOID*)&NewSection);
2766  if (!NT_SUCCESS(Status))
2767  {
2768  /* Check if this is a user-mode read-write non-image file mapping */
2769  if (!(FileObject) &&
2771  !(ControlArea->u.Flags.Image) &&
2772  (ControlArea->FilePointer))
2773  {
2774  /* Remove a reference and check the flag */
2775  ASSERT(Section.u.Flags.UserWritable == 1);
2776  InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2777  }
2778 
2779  /* Check if a user reference was added */
2780  if (UserRefIncremented)
2781  {
2782  /* Acquire the PFN lock while we change counters */
2783  OldIrql = MiAcquirePfnLock();
2784 
2785  /* Decrement the accounting counters */
2786  ControlArea->NumberOfSectionReferences--;
2787  ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2788  ControlArea->NumberOfUserReferences--;
2789 
2790  /* Check if we should destroy the CA and release the lock */
2791  MiCheckControlArea(ControlArea, OldIrql);
2792  }
2793 
2794  /* Return the failure code */
2795  return Status;
2796  }
2797 
2798  /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2799 
2800  /* Now copy the local section object from the stack into this new object */
2801  RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2802  NewSection->Address.StartingVpn = 0;
2803 
2804  /* For now, only user calls are supported */
2805  ASSERT(KernelCall == FALSE);
2806  NewSection->u.Flags.UserReference = TRUE;
2807 
2808  /* Is this a "based" allocation, in which all mappings are identical? */
2810  {
2811  /* Lock the VAD tree during the search */
2813 
2814  /* Is it a brand new ControArea ? */
2815  if (ControlArea->u.Flags.BeingCreated == 1)
2816  {
2817  ASSERT(ControlArea->u.Flags.Based == 1);
2818  /* Then we must find a global address, top-down */
2821  _64K,
2823  (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2824 
2825  if (!NT_SUCCESS(Status))
2826  {
2827  /* No way to find a valid range. */
2829  ControlArea->u.Flags.Based = 0;
2830  NewSection->u.Flags.Based = 0;
2831  ObDereferenceObject(NewSection);
2832  return Status;
2833  }
2834 
2835  /* Compute the ending address and insert it into the VAD tree */
2836  NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2837  NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2838  MiInsertBasedSection(NewSection);
2839  }
2840  else
2841  {
2842  /* 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 !*/
2843  ASSERT(FALSE);
2844  }
2845 
2847  }
2848 
2849  /* The control area is not being created anymore */
2850  if (ControlArea->u.Flags.BeingCreated == 1)
2851  {
2852  /* Acquire the PFN lock while we set control area flags */
2853  OldIrql = MiAcquirePfnLock();
2854 
2855  /* Take off the being created flag, and then release the lock */
2856  ControlArea->u.Flags.BeingCreated = 0;
2857  NewSection->u.Flags.BeingCreated = 0;
2858 
2859  MiReleasePfnLock(OldIrql);
2860  }
2861 
2862  /* Migrate the attribute into a flag */
2863  if (AllocationAttributes & SEC_NO_CHANGE) NewSection->u.Flags.NoChange = TRUE;
2864 
2865  /* If R/W access is not requested, this might eventually become a CoW mapping */
2867  {
2868  NewSection->u.Flags.CopyOnWrite = TRUE;
2869  }
2870 
2871  /* Write down if this was a kernel call */
2872  ControlArea->u.Flags.WasPurged |= KernelCall;
2873  ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2874 
2875  /* Make sure the segment and the section are the same size, or the section is smaller */
2876  ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2877 
2878  /* Return the object and the creation status */
2879  *SectionObject = (PVOID)NewSection;
2880  return Status;
2881 }
ULONG NoChange
Definition: mmtypes.h:483
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define PAGE_NOCACHE
Definition: nt_native.h:1311
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
PEVENT_COUNTER WaitingForDeletion
Definition: mmtypes.h:531
PFILE_OBJECT FilePointer
Definition: mmtypes.h:530
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
ULONGLONG SizeOfSegment
Definition: mmtypes.h:410
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
ULONG UserReference
Definition: mmtypes.h:476
ULONG NumberOfSectionReferences
Definition: mmtypes.h:520
union _SECTION::@2544 u
PSEGMENT Segment
Definition: mmtypes.h:809
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:1533
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define TRUE
Definition: types.h:120
#define PAGE_GUARD
Definition: nt_native.h:1310
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
LONG NTSTATUS
Definition: precomp.h:26
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
#define SEC_NOCACHE
Definition: mmtypes.h:100
static NTSTATUS NTAPI MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1549
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:407
struct _SUBSECTION SUBSECTION
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:345
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:406
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SEC_BASED
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
UCHAR KIRQL
Definition: env_spec_w32.h:591
HANDLE FileHandle
Definition: stats.c:38
ASSERT(Segment->Locked)
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define SEC_COMMIT
Definition: mmtypes.h:99
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
struct _SUBSECTION * NextSubsection
Definition: mmtypes.h:581
long LONG
Definition: pedump.c:60
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:810
#define SEC_RESERVE
Definition: nt_native.h:1323
struct _MSUBSECTION MSUBSECTION
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1647
NTSTATUS Status
Definition: section.c:4922
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
return FALSE
Definition: section.c:5047
ULONG LongFlags
Definition: mmtypes.h:527
struct _SECTION SECTION
void * PVOID
Definition: retypes.h:9
ULONG_PTR StartingVpn
Definition: mmtypes.h:650
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
union _CONTROL_AREA::@2528 u
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
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:952
KIRQL OldIrql
Definition: mm.h:1502
ULONG_PTR EndingVpn
Definition: mmtypes.h:651
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:158
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
POBJECT_TYPE MmSectionObjectType
Definition: section.c:195
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _CONTROL_AREA CONTROL_AREA
struct _SUBSECTION * PSUBSECTION
unsigned __int64 ULONG64
Definition: imports.h:198
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
MMSECTION_FLAGS Flags
Definition: mmtypes.h:814
#define InterlockedDecrement
Definition: armddk.h:52
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:488
ULONG LowPart
Definition: typedefs.h:106
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
ULONG CopyOnWrite
Definition: mmtypes.h:471
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define _64K
Definition: miarm.h:23
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
#define InterlockedIncrement
Definition: armddk.h:53
ULONG FilePointerNull
Definition: mmtypes.h:479
ULONG WritableUserReferences
Definition: mmtypes.h:534
PSEGMENT Segment
Definition: mmtypes.h:518
MMADDRESS_NODE Address
Definition: mmtypes.h:808
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:480
ULONG NumberOfUserReferences
Definition: mmtypes.h:524
#define NULL
Definition: types.h:112
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:732
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
PVOID BasedAddress
Definition: mmtypes.h:415
PVOID MmHighSectionBase
Definition: section.c:111
ULONG WasPurged
Definition: mmtypes.h:475
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define SEC_IMAGE
Definition: mmtypes.h:96
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
Definition: File.h:15
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID _In_ LONG _In_z_ PCHAR File
Definition: wdfdevice.h:4061
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
ULONG BeingCreated
Definition: mmtypes.h:461
LONGLONG QuadPart
Definition: typedefs.h:114
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by MmCreateSection().

◆ MmCreateDataFileSection()

static NTSTATUS NTAPI MmCreateDataFileSection ( PSECTION SectionObject,
ACCESS_MASK  DesiredAccess,
POBJECT_ATTRIBUTES  ObjectAttributes,
PLARGE_INTEGER  UMaximumSize,
ULONG  SectionPageProtection,
ULONG  AllocationAttributes,
PFILE_OBJECT  FileObject,
BOOLEAN  GotFileHandle 
)
static

Definition at line 2293 of file section.c.

2304 {
2305  PSECTION Section;
2306  NTSTATUS Status;
2309  KIRQL OldIrql;
2310 
2311  /*
2312  * Create the section
2313  */
2318  NULL,
2319  sizeof(*Section),
2320  0,
2321  0,
2322  (PVOID*)&Section);
2323  if (!NT_SUCCESS(Status))
2324  {
2325  return Status;
2326  }
2327  /*
2328  * Initialize it
2329  */
2330  RtlZeroMemory(Section, sizeof(*Section));
2331 
2332  /* Mark this as a "ROS" section */
2333  Section->u.Flags.filler = 1;
2335  Section->u.Flags.File = 1;
2336 
2338  Section->u.Flags.NoChange = 1;
2340  Section->u.Flags.Reserve = 1;
2341 
2342  if (!GotFileHandle)
2343  {
2344  ASSERT(UMaximumSize != NULL);
2345  // ASSERT(UMaximumSize->QuadPart != 0);
2346  MaximumSize = *UMaximumSize;
2347  }
2348  else
2349  {
2352  if (!NT_SUCCESS(Status))
2353  {
2354  ObDereferenceObject(Section);
2355  return Status;
2356  }
2357 
2358  /*
2359  * FIXME: Revise this once a locking order for file size changes is
2360  * decided
2361  */
2362  if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
2363  {
2364  MaximumSize = *UMaximumSize;
2365  }
2366  else
2367  {
2369  /* Mapping zero-sized files isn't allowed. */
2370  if (MaximumSize.QuadPart == 0)
2371  {
2372  ObDereferenceObject(Section);
2374  }
2375  }
2376 
2377  if (MaximumSize.QuadPart > FileSize.QuadPart)
2378  {
2381  sizeof(LARGE_INTEGER),
2382  &MaximumSize);
2383  if (!NT_SUCCESS(Status))
2384  {
2385  ObDereferenceObject(Section);
2387  }
2388  }
2389  }
2390 
2391  if (FileObject->SectionObjectPointer == NULL)
2392  {
2393  ObDereferenceObject(Section);
2395  }
2396 
2397  /*
2398  * Lock the file
2399  */
2401  if (Status != STATUS_SUCCESS)
2402  {
2403  ObDereferenceObject(Section);
2404  return Status;
2405  }
2406 
2407  /* Lock the PFN lock while messing with Section Object pointers */
2408 grab_segment:
2409  OldIrql = MiAcquirePfnLock();
2410  Segment = FileObject->SectionObjectPointer->DataSectionObject;
2411 
2412  while (Segment && (Segment->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
2413  {
2414  MiReleasePfnLock(OldIrql);
2416  OldIrql = MiAcquirePfnLock();
2417  Segment = FileObject->SectionObjectPointer->DataSectionObject;
2418  }
2419 
2420  /*
2421  * If this file hasn't been mapped as a data file before then allocate a
2422  * section segment to describe the data file mapping
2423  */
2424  if (Segment == NULL)
2425  {
2426  /* Release the lock. ExAllocatePoolWithTag might acquire it */
2427  MiReleasePfnLock(OldIrql);
2428 
2431  if (Segment == NULL)
2432  {
2433  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2434  ObDereferenceObject(Section);
2435  return STATUS_NO_MEMORY;
2436  }
2437 
2438  /* We are creating it */
2439  RtlZeroMemory(Segment, sizeof(*Segment));
2441  Segment->RefCount = 1;
2442 
2443  /* Acquire lock again */
2444  OldIrql = MiAcquirePfnLock();
2445 
2446  if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
2447  {
2448  /* Well that's bad luck. Restart it all over */
2449  MiReleasePfnLock(OldIrql);
2451  goto grab_segment;
2452  }
2453 
2454  FileObject->SectionObjectPointer->DataSectionObject = Segment;
2455 
2456  /* We're safe to release the lock now */
2457  MiReleasePfnLock(OldIrql);
2458 
2459  Section->Segment = (PSEGMENT)Segment;
2460 
2461  /* Self-referencing segment */
2462  Segment->Flags = &Segment->SegFlags;
2463  Segment->ReferenceCount = &Segment->RefCount;
2464 
2465  Segment->SectionCount = 1;
2466 
2468  Segment->FileObject = FileObject;
2470 
2471  Segment->Image.FileOffset = 0;
2472  Segment->Protection = SectionPageProtection;
2473 
2474  Segment->Image.Characteristics = 0;
2477  {
2478  Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
2479  }
2480  else
2481  {
2482  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2483  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2484  }
2485  Segment->Image.VirtualAddress = 0;
2487 
2488  /* We're good to use it now */
2489  OldIrql = MiAcquirePfnLock();
2490  Segment->SegFlags &= ~MM_SEGMENT_INCREATE;
2491  MiReleasePfnLock(OldIrql);
2492  }
2493  else
2494  {
2495  Section->Segment = (PSEGMENT)Segment;
2496  InterlockedIncrement64(&Segment->RefCount);
2497  InterlockedIncrementUL(&Segment->SectionCount);
2498 
2499  MiReleasePfnLock(OldIrql);
2500 
2502 
2503  if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
2505  {
2506  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2507  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2508  }
2509 
2511  }
2512  Section->SizeOfSection = MaximumSize;
2513 
2514  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2515  *SectionObject = Section;
2516  return STATUS_SUCCESS;
2517 }
ULONG NoChange
Definition: mmtypes.h:483
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static LARGE_INTEGER TinyTime
Definition: section.c:64
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
union _SECTION::@2544 u
PSEGMENT Segment
Definition: mmtypes.h:809
ULONG InitialPageProtection
Definition: mmtypes.h:816
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
NTSTATUS NTAPI IoSetInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN PVOID FileInformation)
Definition: iofunc.c:1312
NTSTATUS NTAPI FsRtlGetFileSize(IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize)
Definition: fastio.c:815
#define MmLockSectionSegment(x)
Definition: mm.h:1333
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:810
#define SEC_RESERVE
Definition: nt_native.h:1323
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
NTSTATUS Status
Definition: section.c:4922
#define MM_SEGMENT_INCREATE
Definition: mm.h:229
return FALSE
Definition: section.c:5047
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
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:952
KIRQL OldIrql
Definition: mm.h:1502
Status
Definition: gdiplustypes.h:24
#define InterlockedIncrement64
Definition: interlocked.h:211
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227
POBJECT_TYPE MmSectionObjectType
Definition: section.c:195
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
MMSECTION_FLAGS Flags
Definition: mmtypes.h:814
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File)
Definition: section.c:909
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
struct _SEGMENT * PSEGMENT
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1525
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define MM_SEGMENT_INDELETE
Definition: mm.h:228
#define NULL
Definition: types.h:112
#define STATUS_SECTION_NOT_EXTENDED
Definition: ntstatus.h:371
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
#define ObReferenceObject
Definition: obfuncs.h:204
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_MAPPED_FILE_SIZE_ZERO
Definition: ntstatus.h:522
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by MmCreateSection().

◆ MmCreateImageSection()

NTSTATUS MmCreateImageSection ( PSECTION SectionObject,
ACCESS_MASK  DesiredAccess,
POBJECT_ATTRIBUTES  ObjectAttributes,
PLARGE_INTEGER  UMaximumSize,
ULONG  SectionPageProtection,
ULONG  AllocationAttributes,
PFILE_OBJECT  FileObject 
)

Definition at line 3143 of file section.c.

3150 {
3151  PSECTION Section;
3152  NTSTATUS Status;
3153  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3154  KIRQL OldIrql;
3155 
3156 
3157  if (FileObject == NULL)
3159 
3160  if (FileObject->SectionObjectPointer == NULL)
3161  {
3162  DPRINT1("Denying section creation due to missing cache initialization\n");
3164  }
3165 
3166  /*
3167  * Create the section
3168  */
3173  NULL,
3174  sizeof(*Section),
3175  0,
3176  0,
3177  (PVOID*)(PVOID)&Section);
3178  if (!NT_SUCCESS(Status))
3179  {
3180  return Status;
3181  }
3182 
3183  /*
3184  * Initialize it
3185  */
3186  RtlZeroMemory(Section, sizeof(*Section));
3187 
3188  /* Mark this as a "ROS" Section */
3189  Section->u.Flags.filler = 1;
3190 
3192  Section->u.Flags.File = 1;
3193  Section->u.Flags.Image = 1;
3195  Section->u.Flags.NoChange = 1;
3196 
3197 grab_image_section_object:
3198  OldIrql = MiAcquirePfnLock();
3199 
3200  /* Wait for it to be properly created or deleted */
3201  ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3202  while(ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
3203  {
3204  MiReleasePfnLock(OldIrql);
3205 
3207 
3208  OldIrql = MiAcquirePfnLock();
3209  ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3210  }
3211 
3212  if (ImageSectionObject == NULL)
3213  {
3214  NTSTATUS StatusExeFmt;
3215 
3216  /* Release the lock because ExAllocatePoolWithTag could need to acquire it */
3217  MiReleasePfnLock(OldIrql);
3218 
3219  ImageSectionObject = ExAllocatePoolZero(NonPagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT);
3220  if (ImageSectionObject == NULL)
3221  {
3222  ObDereferenceObject(Section);
3223  return STATUS_NO_MEMORY;
3224  }
3225 
3226  ImageSectionObject->SegFlags = MM_SEGMENT_INCREATE;
3227  ImageSectionObject->RefCount = 1;
3228  ImageSectionObject->SectionCount = 1;
3229 
3230  OldIrql = MiAcquirePfnLock();
3231  if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
3232  {
3233  MiReleasePfnLock(OldIrql);
3234  /* Bad luck. Start over */
3235  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3236  goto grab_image_section_object;
3237  }
3238 
3239  FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
3240 
3241  MiReleasePfnLock(OldIrql);
3242 
3243  /* Purge the cache */
3244  CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
3245 
3246  StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
3247 
3248  if (!NT_SUCCESS(StatusExeFmt))
3249  {
3250  /* Unset */
3251  OldIrql = MiAcquirePfnLock();
3252  FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3253  MiReleasePfnLock(OldIrql);
3254 
3255  if(ImageSectionObject->Segments != NULL)
3256  ExFreePool(ImageSectionObject->Segments);
3257 
3258  /*
3259  * If image file is empty, then return that the file is invalid for section
3260  */
3261  Status = StatusExeFmt;
3262  if (StatusExeFmt == STATUS_END_OF_FILE)
3263  {
3265  }
3266 
3267  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3268  ObDereferenceObject(Section);
3269  return Status;
3270  }
3271 
3272  Section->Segment = (PSEGMENT)ImageSectionObject;
3273  ASSERT(ImageSectionObject->Segments);
3274  ASSERT(ImageSectionObject->RefCount > 0);
3275 
3276  /*
3277  * Lock the file
3278  */
3280  if (!NT_SUCCESS(Status))
3281  {
3282  /* Unset */
3283  OldIrql = MiAcquirePfnLock();
3284  FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3285  MiReleasePfnLock(OldIrql);
3286 
3287  ExFreePool(ImageSectionObject->Segments);
3288  ExFreePool(ImageSectionObject);
3289  ObDereferenceObject(Section);
3290  return Status;
3291  }
3292 
3293  OldIrql = MiAcquirePfnLock();
3294  ImageSectionObject->SegFlags &= ~MM_SEGMENT_INCREATE;
3295 
3296  /* Take a ref on the file on behalf of the newly created structure */
3298 
3299  MiReleasePfnLock(OldIrql);
3300 
3301  Status = StatusExeFmt;
3302  }
3303  else
3304  {
3305  /* If FS driver called for delete, tell them it's not possible anymore. */
3306  ImageSectionObject->SegFlags &= ~MM_IMAGE_SECTION_FLUSH_DELETE;
3307 
3308  /* Take one ref */
3309  InterlockedIncrement64(&ImageSectionObject->RefCount);
3310  ImageSectionObject->SectionCount++;
3311 
3312  MiReleasePfnLock(OldIrql);
3313 
3314  Section->Segment = (PSEGMENT)ImageSectionObject;
3315 
3317  }
3318  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
3319  *SectionObject = Section;
3320  ASSERT(ImageSectionObject->RefCount > 0);
3321 
3322  return Status;
3323 }
ULONG NoChange
Definition: mmtypes.h:483
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static LARGE_INTEGER TinyTime
Definition: section.c:64
NTSTATUS ExeFmtpCreateImageSection(PFILE_OBJECT FileObject, PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
Definition: section.c:2990
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
union _SECTION::@2544 u
#define MM_IMAGE_SECTION_FLUSH_DELETE
Definition: mm.h:230
PSEGMENT Segment
Definition: mmtypes.h:809
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
ULONG InitialPageProtection
Definition: mmtypes.h:816
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
#define STATUS_END_OF_FILE
Definition: shellext.h:67
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
NTSTATUS Status
Definition: section.c:4922
#define MM_SEGMENT_INCREATE
Definition: mm.h:229
return FALSE
Definition: section.c:5047
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
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:952
KIRQL OldIrql
Definition: mm.h:1502
Status
Definition: gdiplustypes.h:24
#define InterlockedIncrement64
Definition: interlocked.h:211
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PMM_SECTION_SEGMENT Segments
Definition: mm.h:223
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
POBJECT_TYPE MmSectionObjectType
Definition: section.c:195
MMSECTION_FLAGS Flags
Definition: mmtypes.h:814
NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File)
Definition: section.c:909
struct _SEGMENT * PSEGMENT
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define MM_SEGMENT_INDELETE
Definition: mm.h:228
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define ObReferenceObject
Definition: obfuncs.h:204
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by MmCreateSection().

◆ MmCreatePhysicalMemorySection()

NTSTATUS NTAPI MmCreatePhysicalMemorySection ( VOID  )

Definition at line 2169 of file section.c.

2170 {
2171  PSECTION PhysSection;
2172  NTSTATUS Status;
2174  UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2175  LARGE_INTEGER SectionSize;
2176  HANDLE Handle;
2178 
2179  /*
2180  * Create the section mapping physical memory
2181  */
2182  SectionSize.QuadPart = MmHighestPhysicalPage * PAGE_SIZE;
2184  &Name,
2186  NULL,
2187  NULL);
2188  /*
2189  * Create the Object
2190  */
2193  &Obj,
2195  NULL,
2196  sizeof(*PhysSection),
2197  0,
2198  0,
2199  (PVOID*)&PhysSection);
2200  if (!NT_SUCCESS(Status))
2201  {
2202  DPRINT1("MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n", Status);
2203  return Status;
2204  }
2205 
2206  /*
2207  * Initialize it
2208  */
2209  RtlZeroMemory(PhysSection, sizeof(*PhysSection));
2210 
2211  /* Mark this as a "ROS Section" */
2212  PhysSection->u.Flags.filler = 1;
2214  PhysSection->u.Flags.PhysicalMemory = 1;
2215  PhysSection->SizeOfSection = SectionSize;
2218  if (Segment == NULL)
2219  {
2220  ObDereferenceObject(PhysSection);
2221  return STATUS_NO_MEMORY;
2222  }
2224  PhysSection->Segment = (PSEGMENT)Segment;
2225  Segment->RefCount = 1;
2226 
2227  Segment->ReferenceCount = &Segment->RefCount;
2228  Segment->Flags = &Segment->SegFlags;
2229 
2231  Segment->Image.FileOffset = 0;
2232  Segment->Protection = PAGE_EXECUTE_READWRITE;
2233  Segment->RawLength = SectionSize;
2234  Segment->Length = SectionSize;
2235  Segment->SegFlags = MM_PHYSICALMEMORY_SEGMENT;
2236  Segment->WriteCopy = FALSE;
2237  Segment->Image.VirtualAddress = 0;
2238  Segment->Image.Characteristics = 0;
2240 
2241  Status = ObInsertObject(PhysSection,
2242  NULL,
2244  0,
2245  NULL,
2246  &Handle);
2247  if (!NT_SUCCESS(Status))
2248  {
2249  ObDereferenceObject(PhysSection);
2250  return Status;
2251  }
2253 
2254  return STATUS_SUCCESS;
2255 }
union _SECTION::@2544 u
PSEGMENT Segment
Definition: mmtypes.h:809
ULONG PhysicalMemory
Definition: mmtypes.h:470
ULONG InitialPageProtection
Definition: mmtypes.h:816
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:810
NTSTATUS Status
Definition: section.c:4922
return FALSE
Definition: section.c:5047
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
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:952
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define ObDereferenceObject
Definition: obfuncs.h:203
POBJECT_TYPE MmSectionObjectType
Definition: section.c:195
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
MMSECTION_FLAGS Flags
Definition: mmtypes.h:814
static const WCHAR L[]
Definition: oid.c:1250
#define OBJ_PERMANENT
Definition: winternl.h:226
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
struct _SEGMENT * PSEGMENT
#define MM_PHYSICALMEMORY_SEGMENT
Definition: mm.h:226
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2931
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:91
#define DPRINT1
Definition: precomp.h:8
_In_ HANDLE Handle
Definition: extypes.h:390
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define STATUS_SUCCESS
Definition: shellext.h:65
LONGLONG QuadPart
Definition: typedefs.h:114
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by MmInitSectionImplementation().

◆ MmCreateSection()

NTSTATUS NTAPI MmCreateSection ( OUT PVOID Section,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN PLARGE_INTEGER  MaximumSize,
IN ULONG  SectionPageProtection,
IN ULONG  AllocationAttributes,
IN HANDLE FileHandle  OPTIONAL,
IN PFILE_OBJECT FileObject  OPTIONAL 
)

Definition at line 4509 of file section.c.

4517 {
4518  NTSTATUS Status;
4519  ULONG Protection;
4520  PSECTION *SectionObject = (PSECTION *)Section;
4521  BOOLEAN FileLock = FALSE;
4522 
4523  /* Check if an ARM3 section is being created instead */
4525  {
4526  if (!(FileObject) && !(FileHandle))
4527  {
4528  return MmCreateArm3Section(Section,
4529  DesiredAccess,
4531  MaximumSize,
4533  AllocationAttributes &~ 1,
4534  FileHandle,
4535  FileObject);
4536  }
4537  }
4538 
4539  /* Convert section flag to page flag */
4541 
4542  /* Check to make sure the protection is correct. Nt* does this already */
4544  if (Protection == MM_INVALID_PROTECTION)
4545  {
4546  DPRINT1("Page protection is invalid\n");
4548  }
4549 
4550  /* Check if this is going to be a data or image backed file section */
4551  if ((FileHandle) || (FileObject))
4552  {
4553  /* These cannot be mapped with large pages */
4555  {
4556  DPRINT1("Large pages cannot be used with an image mapping\n");
4558  }
4559 
4560  /* Did the caller pass a file object ? */
4561  if (FileObject)
4562  {
4563  /* Reference the object directly */
4565 
4566  /* We don't create image mappings with file objects */
4568  }
4569  else
4570  {
4571  /* Reference the file handle to get the object */
4573  MmMakeFileAccess[Protection],
4576  (PVOID*)&FileObject,
4577  NULL);
4578  if (!NT_SUCCESS(Status))
4579  {
4580  DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
4581  return Status;
4582  }
4583 
4584  /* Lock the file */
4586  if (!NT_SUCCESS(Status))
4587  {
4589  return Status;
4590  }
4591 
4592  FileLock = TRUE;
4593 
4594  /* Deny access if there are writes on the file */
4595 #if 0
4597  {
4598  DPRINT1("Cannot create image maps with writers open on the file!\n");
4600  goto Quit;
4601  }
4602 #else
4604  DPRINT1("Creating image map with writers open on the file!\n");
4605 #endif
4606  }
4607  }
4608  else
4609  {
4610  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
4612  }
4613 
4615  {
4617  DesiredAccess,
4619  MaximumSize,
4622  FileObject);
4623  }
4624 #ifndef NEWCC
4625  else if (FileObject != NULL)
4626  {
4628  DesiredAccess,
4630  MaximumSize,
4633  FileObject,
4634  FileHandle != NULL);
4635  }
4636 #else
4637  else if (FileHandle != NULL || FileObject != NULL)
4638  {
4640  DesiredAccess,
4642  MaximumSize,
4645  FileObject);
4646  }
4647 #endif
4648  else
4649  {
4650  /* All cases should be handled above */
4652  }
4653 
4654  if (FileLock)
4656  if (FileObject)
4658 
4659  return Status;
4660 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define PAGE_NOCACHE
Definition: nt_native.h:1311
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
#define SEC_NOCACHE
Definition: mmtypes.h:100
VOID NTAPI FsRtlReleaseFile(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1659
NTSTATUS NTAPI MmCreateArm3Section(OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER InputMaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: section.c:2465
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1647
NTSTATUS Status
Definition: section.c:4922
unsigned char BOOLEAN
return FALSE
Definition: section.c:5047
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:158
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
NTSTATUS MmCreateImageSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
Definition: section.c:3143
#define SEC_PHYSICALMEMORY
Definition: mm.h:101
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
static NTSTATUS NTAPI MmCreateDataFileSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject, BOOLEAN GotFileHandle)
Definition: section.c:2293
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:480
#define NULL
Definition: types.h:112
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
#define DPRINT1
Definition: precomp.h:8
#define ObReferenceObject
Definition: obfuncs.h:204
#define STATUS_FILE_LOCKED_WITH_WRITERS
Definition: ntstatus.h:112
unsigned int ULONG
Definition: retypes.h:1
#define SEC_IMAGE
Definition: mmtypes.h:96
NTSTATUS NTAPI MmCreateCacheSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)

Referenced by CcpAllocateSection(), CcRosInitializeFileCache(), EngCreateSection(), EngCreateSectionHack(), EngLoadModuleEx(), InitGdiHandleTable(), IntGdiAddFontResourceEx(), NtCreateSection(), TestCreateSection(), TestPhysicalMemorySection(), and UserCreateHeap().

◆ MmExtendSection()

NTSTATUS NTAPI MmExtendSection ( _In_ PVOID  _Section,
_Inout_ PLARGE_INTEGER  NewSize 
)

Definition at line 5123 of file section.c.

5126 {
5127  PSECTION Section = _Section;
5128 
5129  /* It makes no sense to extend an image mapping */
5130  if (Section->u.Flags.Image)
5132 
5133  /* Nor is it possible to extend a page file mapping */
5134  if (!Section->u.Flags.File)
5136 
5137  if (!MiIsRosSectionObject(Section))
5138  return STATUS_NOT_IMPLEMENTED;
5139 
5140  /* We just extend the sizes. Shrinking is a no-op ? */
5141  if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5142  {
5144  Section->SizeOfSection = *NewSize;
5145 
5146  if (!Section->u.Flags.Reserve)
5147  {
5149  if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5150  {
5151  Segment->RawLength = *NewSize;
5152  Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5153  }
5155  }
5156  }
5157 
5158  return STATUS_SUCCESS;
5159 }
union _SECTION::@2544 u
if(Entry==0)
Definition: section.c:4932
PSEGMENT Segment
Definition: mmtypes.h:809
#define MmLockSectionSegment(x)
Definition: mm.h:1333
return STATUS_NOT_IMPLEMENTED
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:810
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1103
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
int64_t LONGLONG
Definition: typedefs.h:68
struct _MM_SECTION_SEGMENT * PMM_SECTION_SEGMENT
MMSECTION_FLAGS Flags
Definition: mmtypes.h:814
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define STATUS_SECTION_NOT_EXTENDED
Definition: ntstatus.h:371
#define STATUS_SUCCESS
Definition: shellext.h:65
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CcSetFileSizes(), and NtExtendSection().

◆ MmFlushImageSection()

BOOLEAN NTAPI MmFlushImageSection ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointer,
IN MMFLUSH_TYPE  FlushType 
)

Definition at line 4245 of file section.c.

4247 {
4248  switch(FlushType)
4249  {
4250  case MmFlushForDelete:
4251  {
4252  /*
4253  * FIXME: Check for outstanding write probes on Data section.
4254  * How do we do that ?
4255  */
4256  }
4257  /* Fall-through */
4258  case MmFlushForWrite:
4259  {
4260  KIRQL OldIrql = MiAcquirePfnLock();
4261  PMM_IMAGE_SECTION_OBJECT ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4262 
4263  DPRINT("Deleting or modifying %p\n", SectionObjectPointer);
4264 
4265  /* Wait for concurrent creation or deletion of image to be done */
4266  ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4267  while (ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INCREATE | MM_SEGMENT_INDELETE)))
4268  {
4269  MiReleasePfnLock(OldIrql);
4271  OldIrql = MiAcquirePfnLock();
4272  ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4273  }
4274 
4275  if (!ImageSectionObject)
4276  {
4277  DPRINT("No image section object. Accepting\n");
4278  /* Nothing to do */
4279  MiReleasePfnLock(OldIrql);
4280  return TRUE;
4281  }
4282 
4283  /* Do we have open sections or mappings on it ? */
4284  if ((ImageSectionObject->SectionCount) || (ImageSectionObject->MapCount))
4285  {
4286  /* We do. No way to delete it */
4287  MiReleasePfnLock(OldIrql);
4288  DPRINT("Denying. There are mappings open\n");
4289  return FALSE;
4290  }
4291 
4292  /* There are no sections open on it, but we must still have pages around. Discard everything */
4293  ImageSectionObject->SegFlags |= MM_IMAGE_SECTION_FLUSH_DELETE;
4294  InterlockedIncrement64(&ImageSectionObject->RefCount);
4295  MiReleasePfnLock(OldIrql);
4296 
4297  DPRINT("Purging\n");
4298 
4299  for (ULONG i = 0; i < ImageSectionObject->NrSegments; i++)
4300  {
4301  if (!MiPurgeImageSegment(&ImageSectionObject->Segments[i]))
4302  break;
4303  }
4304 
4305  /* Grab lock again */
4306  OldIrql = MiAcquirePfnLock();
4307 
4308  if (!(ImageSectionObject->SegFlags & MM_IMAGE_SECTION_FLUSH_DELETE))
4309  {
4310  /*
4311  * Someone actually created a section while we were not looking.
4312  * Drop our ref and deny.
4313  * MmDereferenceSegmentWithLock releases Pfn lock
4314  */
4315  MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4316  return FALSE;
4317  }
4318 
4319  /* We should be the last one holding a ref here. */
4320  ASSERT(ImageSectionObject->RefCount == 1);
4321  ASSERT(ImageSectionObject->SectionCount == 0);
4322 
4323  /* Dereference the first segment, this will free everything & release the lock */
4324  MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4325  return TRUE;
4326  }
4327  }
4328  return FALSE;
4329 }
static LARGE_INTEGER TinyTime
Definition: section.c:64
#define MM_IMAGE_SECTION_FLUSH_DELETE
Definition: mm.h:230
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
UCHAR KIRQL
Definition: env_spec_w32.h:591
static BOOLEAN MiPurgeImageSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:4199
ASSERT(Segment->Locked)
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
#define MM_SEGMENT_INCREATE
Definition: mm.h:229
return FALSE
Definition: section.c:5047
IN PFCB IN FAT_FLUSH_TYPE FlushType
Definition: fatprocs.h:1080
KIRQL OldIrql
Definition: mm.h:1502
#define InterlockedIncrement64
Definition: interlocked.h:211
PMM_SECTION_SEGMENT Segments
Definition: mm.h:223
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MM_SEGMENT_INDELETE
Definition: mm.h:228
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
unsigned int ULONG
Definition: retypes.h:1