ReactOS  0.4.15-dev-4603-gb922b6d
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:5048
_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.

1000 {
1001  /* Lock the PFN lock because we mess around with SectionObjectPointers */
1002  if (OldIrql == MM_NOIRQL)
1003  {
1004  OldIrql = MiAcquirePfnLock();
1005  }
1006 
1007  if (InterlockedDecrement64(Segment->ReferenceCount) > 0)
1008  {
1009  /* Nothing to do yet */
1010  MiReleasePfnLock(OldIrql);
1011  return;
1012  }
1013 
1014  *Segment->Flags |= MM_SEGMENT_INDELETE;
1015 
1016  /* Flush the segment */
1017  if (*Segment->Flags & MM_DATAFILE_SEGMENT)
1018  {
1019  MiReleasePfnLock(OldIrql);
1020  /* Free the page table. This will flush any remaining dirty data */
1022 
1023  OldIrql = MiAcquirePfnLock();
1024  /* Delete the pointer on the file */
1025  ASSERT(Segment->FileObject->SectionObjectPointer->DataSectionObject == Segment);
1026  Segment->FileObject->SectionObjectPointer->DataSectionObject = NULL;
1027  MiReleasePfnLock(OldIrql);
1028  ObDereferenceObject(Segment->FileObject);
1029 
1031  }
1032  else
1033  {
1034  /* Most grotesque thing ever */
1035  PMM_IMAGE_SECTION_OBJECT ImageSectionObject = CONTAINING_RECORD(Segment->ReferenceCount, MM_IMAGE_SECTION_OBJECT, RefCount);
1036  PMM_SECTION_SEGMENT SectionSegments;
1037  ULONG NrSegments;
1038  ULONG i;
1039 
1040  /* Delete the pointer on the file */
1041  ASSERT(ImageSectionObject->FileObject->SectionObjectPointer->ImageSectionObject == ImageSectionObject);
1042  ImageSectionObject->FileObject->SectionObjectPointer->ImageSectionObject = NULL;
1043  MiReleasePfnLock(OldIrql);
1044 
1045  ObDereferenceObject(ImageSectionObject->FileObject);
1046 
1047  NrSegments = ImageSectionObject->NrSegments;
1048  SectionSegments = ImageSectionObject->Segments;
1049  for (i = 0; i < NrSegments; i++)
1050  {
1051  if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
1052  {
1053  MmpFreePageFileSegment(&SectionSegments[i]);
1054  }
1055 
1056  MmFreePageTablesSectionSegment(&SectionSegments[i], NULL);
1057  }
1058 
1059  ExFreePoolWithTag(ImageSectionObject->Segments, TAG_MM_SECTION_SEGMENT);
1060  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
1061  }
1062 }
static VOID NTAPI FreeSegmentPage(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: section.c:962
ASSERT(Segment->Locked)
#define MM_NOIRQL
Definition: mm.h:70
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
VOID NTAPI MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:919
PMM_SECTION_SEGMENT Segments
Definition: mm.h:234
#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:238
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define InterlockedDecrement64
Definition: interlocked.h:144
PFILE_OBJECT FileObject
Definition: mm.h:226
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:111
#define MM_SEGMENT_INDELETE
Definition: mm.h:239
#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 2557 of file section.c.

2558 {
2559  SIZE_T SizeOfSegments;
2560  PMM_SECTION_SEGMENT Segments;
2561 
2562  /* TODO: check for integer overflow */
2563  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
2564 
2566  SizeOfSegments,
2568 
2569  if(Segments)
2570  RtlZeroMemory(Segments, SizeOfSegments);
2571 
2572  return Segments;
2573 }
#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:111
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 2991 of file section.c.

2993 {
2995  PVOID FileHeader;
2996  PVOID FileHeaderBuffer;
2997  ULONG FileHeaderSize;
2998  ULONG Flags;
2999  ULONG OldNrSegments;
3000  NTSTATUS Status;
3001  ULONG i;
3002 
3003  /*
3004  * Read the beginning of the file (2 pages). Should be enough to contain
3005  * all (or most) of the headers
3006  */
3007  Offset.QuadPart = 0;
3008 
3010  &Offset,
3011  PAGE_SIZE * 2,
3012  &FileHeader,
3013  &FileHeaderBuffer,
3014  &FileHeaderSize);
3015 
3016  if (!NT_SUCCESS(Status))
3017  return Status;
3018 
3019  if (FileHeaderSize == 0)
3020  {
3021  ExFreePool(FileHeaderBuffer);
3022  return STATUS_UNSUCCESSFUL;
3023  }
3024 
3025  /*
3026  * Look for a loader that can handle this executable
3027  */
3028  for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
3029  {
3030  Flags = 0;
3031 
3032  Status = ExeFmtpLoaders[i](FileHeader,
3033  FileHeaderSize,
3034  FileObject,
3035  ImageSectionObject,
3036  &Flags,
3039 
3040  if (!NT_SUCCESS(Status))
3041  {
3042  if (ImageSectionObject->Segments)
3043  {
3044  ExFreePool(ImageSectionObject->Segments);
3045  ImageSectionObject->Segments = NULL;
3046  }
3047  }
3048 
3050  break;
3051  }
3052 
3053  ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
3054 
3055  /*
3056  * No loader handled the format
3057  */
3059  {
3062  }
3063 
3064  if (!NT_SUCCESS(Status))
3065  return Status;
3066 
3067  ASSERT(ImageSectionObject->Segments != NULL);
3068  ASSERT(ImageSectionObject->RefCount > 0);
3069 
3070  /*
3071  * Some defaults
3072  */
3073  /* FIXME? are these values platform-dependent? */
3074  if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
3075  ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
3076 
3077  if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
3078  ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
3079 
3080  if(ImageSectionObject->BasedAddress == NULL)
3081  {
3082  if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3083  ImageSectionObject->BasedAddress = (PVOID)0x10000000;
3084  else
3085  ImageSectionObject->BasedAddress = (PVOID)0x00400000;
3086  }
3087 
3088  /*
3089  * And now the fun part: fixing the segments
3090  */
3091 
3092  /* Sort them by virtual address */
3093  MmspSortSegments(ImageSectionObject, Flags);
3094 
3095  /* Ensure they don't overlap in memory */
3096  if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
3098 
3099  /* Ensure they are aligned */
3100  OldNrSegments = ImageSectionObject->NrSegments;
3101 
3102  if (!MmspPageAlignSegments(ImageSectionObject, Flags))
3104 
3105  /* Trim them if the alignment phase merged some of them */
3106  if (ImageSectionObject->NrSegments < OldNrSegments)
3107  {
3108  PMM_SECTION_SEGMENT Segments;
3109  SIZE_T SizeOfSegments;
3110 
3111  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
3112 
3113  Segments = ExAllocatePoolWithTag(PagedPool,
3114  SizeOfSegments,
3116 
3117  if (Segments == NULL)
3119 
3120  RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
3121  ExFreePool(ImageSectionObject->Segments);
3122  ImageSectionObject->Segments = Segments;
3123  }
3124 
3125  /* And finish their initialization */
3126  for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
3127  {
3128  ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
3129  ImageSectionObject->Segments[i].ReferenceCount = &ImageSectionObject->RefCount;
3130  ImageSectionObject->Segments[i].Flags = &ImageSectionObject->SegFlags;
3131  MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
3132  ImageSectionObject->Segments[i].FileObject = FileObject;
3133  }
3134 
3135  ASSERT(ImageSectionObject->RefCount > 0);
3136 
3137  ImageSectionObject->FileObject = FileObject;
3138 
3140  return Status;
3141 }
#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:2808
static VOID NTAPI MmspSortSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2731
ASSERT(Segment->Locked)
NTSTATUS Status
Definition: section.c:4923
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:2557
#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:2546
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:2577
#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:111
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
PLARGE_INTEGER Offset
Definition: section.c:4918
#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:2757

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

2583 {
2584  NTSTATUS Status;
2586  ULONG AdjustOffset;
2587  ULONG OffsetAdjustment;
2588  ULONG BufferSize;
2589  ULONG UsedSize;
2590  PVOID Buffer;
2593 
2595 
2596  if(Length == 0)
2597  {
2598  KeBugCheck(MEMORY_MANAGEMENT);
2599  }
2600 
2601  FileOffset = *Offset;
2602 
2603  /* Negative/special offset: it cannot be used in this context */
2604  if(FileOffset.u.HighPart < 0)
2605  {
2606  KeBugCheck(MEMORY_MANAGEMENT);
2607  }
2608 
2609  AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
2610  OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
2611  FileOffset.u.LowPart = AdjustOffset;
2612 
2613  BufferSize = Length + OffsetAdjustment;
2615 
2616  /*
2617  * It's ok to use paged pool, because this is a temporary buffer only used in
2618  * the loading of executables. The assumption is that MmCreateSection is
2619  * always called at low IRQLs and that these buffers don't survive a brief
2620  * initialization phase
2621  */
2623  if (!Buffer)
2624  {
2626  }
2627 
2629 
2630  UsedSize = (ULONG)Iosb.Information;
2631 
2632  if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
2633  {
2636  }
2637 
2638  if(NT_SUCCESS(Status))
2639  {
2640  *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
2641  *AllocBase = Buffer;
2642  *ReadSize = UsedSize - OffsetAdjustment;
2643  }
2644  else
2645  {
2646  ExFreePoolWithTag(Buffer, 'rXmM');
2647  }
2648 
2649  return Status;
2650 }
#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:4923
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:4918
#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:1559
#define MC_USER
Definition: mm.h:114
#define PFN_FROM_SSE(E)
Definition: mm.h:1324
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:73
#define MmLockSectionSegment(x)
Definition: mm.h:1353
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:1333
Entry
Definition: section.c:4932
PFN_NUMBER Page
Definition: section.c:4924
#define MmUnlockSectionSegment(x)
Definition: mm.h:1361
_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:1325
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1341
base of all file and directory entries
Definition: entries.h:82

Referenced by _When_().

◆ if() [1/2]

if ( Entry  = = 0)

Definition at line 4933 of file section.c.

4938  {
4939  BOOLEAN DirtyAgain;
4940 
4941  /*
4942  * We got a dirty entry. This path is for the shared data,
4943  * be-it regular file maps or shared sections of DLLs
4944  */
4946  FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
4947 
4948  /* Insert the cleaned entry back. Mark it as write in progress, and clear the dirty bit. */
4950  Entry = WRITE_SSE(Entry);
4952 
4954 
4955  if (FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
4956  {
4957  /* We have to write it back to the file. Tell the FS driver who we are */
4958  if (PageOut)
4960 
4961  /* Go ahead and write the page */
4962  DPRINT("Writing page at offset %I64d for file %wZ, Pageout: %s\n",
4963  Offset->QuadPart, &Segment->FileObject->FileName, PageOut ? "TRUE" : "FALSE");
4964  Status = MiWritePage(Segment, Offset->QuadPart, Page);
4965 
4966  if (PageOut)
4968  }
4969  else
4970  {
4971  /* This must only be called by the page-out path */
4972  ASSERT(PageOut);
4973 
4974  /* And this must be for a shared section in a DLL */
4975  ASSERT(FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
4976 
4977  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
4978  if (!SwapEntry)
4979  {
4980  SwapEntry = MmAllocSwapPage();
4981  }
4982 
4983  if (SwapEntry)
4984  {
4985  Status = MmWriteToSwapPage(SwapEntry, Page);
4986  if (NT_SUCCESS(Status))
4987  {
4988  MmSetSavedSwapEntryPage(Page, SwapEntry);
4989  }
4990  else
4991  {
4992  MmFreeSwapPage(SwapEntry);
4993  }
4994  }
4995  else
4996  {
4997  DPRINT1("Failed to allocate a swap page!\n");
4999  }
5000  }
5001 
5003 
5004  /* Get the entry again */
5007 
5008  if (!NT_SUCCESS(Status))
5009  {
5010  /* Damn, this failed. Consider this page as still dirty */
5011  DPRINT1("MiWritePage FAILED: Status 0x%08x!\n", Status);
5012  DirtyAgain = TRUE;
5013  }
5014  else
5015  {
5016  /* Check if someone dirtified this page while we were not looking */
5017  DirtyAgain = IS_DIRTY_SSE(Entry);
5018  }
5019 
5020  /* Drop the reference we got, deleting the write altogether. */
5022  if (DirtyAgain)
5023  {
5024  Entry = DIRTY_SSE(Entry);
5025  }
5027  }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1559
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WRITE_SSE(E)
Definition: mm.h:1334
#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:1324
#define MmLockSectionSegment(x)
Definition: mm.h:1353
#define DIRTY_SSE(E)
Definition: mm.h:1331
ASSERT(Segment->Locked)
#define IS_DIRTY_SSE(E)
Definition: mm.h:1333
#define MAKE_SSE(P, C)
Definition: mm.h:1343
unsigned char BOOLEAN
PFN_NUMBER Page
Definition: section.c:4924
#define MmUnlockSectionSegment(x)
Definition: mm.h:1361
_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:4921
#define MM_DATAFILE_SEGMENT
Definition: mm.h:238
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define PAGE_FROM_SSE(E)
Definition: mm.h:1339
#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:56
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:1341
#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 5030 of file section.c.

5031  {
5032  ULONG_PTR NewEntry = 0;
5033  /* Restore the swap entry here */
5034  if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
5035  {
5036  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
5037  if (SwapEntry)
5038  NewEntry = MAKE_SWAP_SSE(SwapEntry);
5039  }
5040 
5041  /* Yes. Release it */
5044  /* Tell the caller we released the page */
5045  return TRUE;
5046  }
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:57
#define TRUE
Definition: types.h:120
#define MC_USER
Definition: mm.h:114
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:4924
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define MM_DATAFILE_SEGMENT
Definition: mm.h:238
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SWAPENTRY
Definition: mm.h:56
#define MAKE_SWAP_SSE(S)
Definition: mm.h:1330
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:238

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

1173 {
1175  KIRQL Irql;
1176  PVOID DestAddress;
1177 
1179  DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
1180  if (DestAddress == NULL)
1181  {
1182  return STATUS_NO_MEMORY;
1183  }
1184  ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
1185  ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
1186  RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
1187  MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
1188  return STATUS_SUCCESS;
1189 }
_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:240
return FALSE
Definition: section.c:5048
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
#define MM_DATAFILE_SEGMENT
Definition: mm.h:238
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define MM_SEGMENT_INDELETE
Definition: mm.h:239
#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 4200 of file section.c.

4201 {
4203 
4205 
4206  /* Loop over all entries */
4207  for (PageTable = RtlEnumerateGenericTable(&Segment->PageTable, TRUE);
4208  PageTable != NULL;
4210  {
4211  for (ULONG i = 0; i < _countof(PageTable->PageEntries); i++)
4212  {
4213  ULONG_PTR Entry = PageTable->PageEntries[i];
4215 
4216  if (!Entry)
4217  continue;
4218 
4220  {
4221  /* I/O ongoing or swap entry. Someone mapped this file as we were not looking */
4223  return FALSE;
4224  }
4225 
4226  /* Regular entry */
4229 
4230  /* Properly remove using the used API */
4231  Offset.QuadPart = PageTable->FileOffset.QuadPart + (i << PAGE_SHIFT);
4234  }
4235  }
4236 
4238 
4239  return TRUE;
4240 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:57
#define TRUE
Definition: types.h:120
#define MC_USER
Definition: mm.h:114
#define PFN_FROM_SSE(E)
Definition: mm.h:1324
_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:1353
uint32_t ULONG_PTR
Definition: typedefs.h:65
ASSERT(Segment->Locked)
return FALSE
Definition: section.c:5048
#define MmUnlockSectionSegment(x)
Definition: mm.h:1361
_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:1325
PLARGE_INTEGER Offset
Definition: section.c:4918
#define NULL
Definition: types.h:112
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1341
#define IS_WRITE_SSE(E)
Definition: mm.h:1335
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 4447 of file section.c.

4448 {
4449  DPRINT("MmUnmapViewInSystemSpace() called\n");
4450 
4452 }
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:3492
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1661
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 3556 of file section.c.

3559 {
3560  NTSTATUS Status;
3563  PVOID ImageBaseAddress = 0;
3564 
3565  DPRINT("Opening memory area Process %p BaseAddress %p\n",
3566  Process, BaseAddress);
3567 
3568  ASSERT(Process);
3569 
3571 
3573  BaseAddress);
3574  if (MemoryArea == NULL ||
3575 #ifdef NEWCC
3576  ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) && (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
3577 #else
3579 #endif
3581 
3582  {
3584 
3585  DPRINT1("Unable to find memory area at address %p.\n", BaseAddress);
3586  return STATUS_NOT_MAPPED_VIEW;
3587  }
3588 
3590  {
3591  ULONG i;
3592  ULONG NrSegments;
3593  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3594  PMM_SECTION_SEGMENT SectionSegments;
3596 
3597  Segment = MemoryArea->SectionData.Segment;
3598  ImageSectionObject = ImageSectionObjectFromSegment(Segment);
3599  SectionSegments = ImageSectionObject->Segments;
3600  NrSegments = ImageSectionObject->NrSegments;
3601 
3603 
3604  /* Search for the current segment within the section segments
3605  * and calculate the image base address */
3606  for (i = 0; i < NrSegments; i++)
3607  {
3608  if (Segment == &SectionSegments[i])
3609  {
3610  ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
3611  break;
3612  }
3613  }
3614  if (i >= NrSegments)
3615  {
3616  KeBugCheck(MEMORY_MANAGEMENT);
3617  }
3618 
3619  for (i = 0; i < NrSegments; i++)
3620  {
3621  PVOID SBaseAddress = (PVOID)
3622  ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
3623 
3624  Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
3625  if (!NT_SUCCESS(Status))
3626  {
3627  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3628  SBaseAddress, Process, Status);
3630  }
3631  }
3632  DPRINT("One mapping less for %p\n", ImageSectionObject->FileObject->SectionObjectPointer);
3633  InterlockedDecrement(&ImageSectionObject->MapCount);
3634  }
3635  else
3636  {
3638  if (!NT_SUCCESS(Status))
3639  {
3640  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3643  }
3644  }
3645 
3646  /* Notify debugger */
3647  if (ImageBaseAddress && !SkipDebuggerNotify) DbgkUnMapViewOfSection(ImageBaseAddress);
3648 
3649  return STATUS_SUCCESS;
3650 }
ULONG Type
Definition: mm.h:251
#define TRUE
Definition: types.h:120
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
LONG NTSTATUS
Definition: precomp.h:26
union _MMVAD::@2544 u
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:3492
else
Definition: tritemp.h:161
ASSERT(Segment->Locked)
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:97
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
NTSTATUS Status
Definition: section.c:4923
struct _MM_SECTION_SEGMENT::@1749 Image
void * PVOID
Definition: retypes.h:9
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
_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:234
BOOLEAN DeleteInProgress
Definition: mm.h:253
MMVAD VadNode
Definition: mm.h:249
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
#define InterlockedDecrement
Definition: armddk.h:52
PFILE_OBJECT FileObject
Definition: mm.h:226
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1661
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
#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::@1750 SectionData
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:833
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
NTSTATUS Status
Definition: section.c:4923
return FALSE
Definition: section.c:5048
PFN_NUMBER Page
Definition: section.c:4924
_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:1146
#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 1892 of file section.c.

1896 {
1898  PFN_NUMBER OldPage;
1899  PFN_NUMBER NewPage;
1900  PVOID PAddress;
1903  ULONG_PTR Entry;
1905  BOOLEAN Cow = FALSE;
1906  ULONG NewProtect;
1907 
1908  DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1909 
1910  /* Get the region for this address */
1912  &MemoryArea->SectionData.RegionListHead,
1913  Address, NULL);
1914  ASSERT(Region != NULL);
1915  if (!(Region->Protect & PAGE_IS_WRITABLE))
1916  return STATUS_ACCESS_VIOLATION;
1917 
1918  /* Make sure we have a page mapping for this address. */
1920  {
1922  if (!NT_SUCCESS(Status))
1923  {
1924  /* This is invalid access ! */
1925  return Status;
1926  }
1927  }
1928 
1929  /*
1930  * Check if the page has already been set readwrite
1931  */
1933  {
1934  DPRINT("Address 0x%p\n", Address);
1935  return STATUS_SUCCESS;
1936  }
1937 
1938  /* Check if we are doing Copy-On-Write */
1939  Segment = MemoryArea->SectionData.Segment;
1940  Cow = Segment->WriteCopy || (Region->Protect & PAGE_IS_WRITECOPY);
1941 
1942  if (!Cow)
1943  {
1944  /* Simply update page protection and we're done */
1945  MmSetPageProtect(Process, Address, Region->Protect);
1946  return STATUS_SUCCESS;
1947  }
1948 
1949  /* Calculate the new protection & check if we should update the region */
1950  NewProtect = Region->Protect;
1952  {
1954  if (Region->Protect & PAGE_IS_EXECUTABLE)
1956  else
1959  &MemoryArea->SectionData.RegionListHead,
1962  }
1963 
1964  /*
1965  * Find the offset of the page
1966  */
1967  PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1968  Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1969  + MemoryArea->SectionData.ViewOffset;
1970 
1971  /* Get the page mapping this section offset. */
1974 
1975  /* Get the current page mapping for the process */
1976  ASSERT(MmIsPagePresent(Process, PAddress));
1977  OldPage = MmGetPfnForProcess(Process, PAddress);
1978  ASSERT(OldPage != 0);
1979 
1980  if (IS_SWAP_FROM_SSE(Entry) ||
1981  PFN_FROM_SSE(Entry) != OldPage)
1982  {
1984  /* This is a private page. We must only change the page protection. */
1985  MmSetPageProtect(Process, PAddress, NewProtect);
1986  return STATUS_SUCCESS;
1987  }
1988 
1989  /*
1990  * Allocate a page
1991  */
1993  {
1994  KeBugCheck(MEMORY_MANAGEMENT);
1995  }
1996 
1997  /*
1998  * Copy the old page
1999  */
2000  NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
2001 
2002  /*
2003  * Unshare the old page.
2004  */
2005  DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
2006  MmDeleteVirtualMapping(Process, PAddress, NULL, NULL);
2007  if (Process)
2008  MmDeleteRmap(OldPage, Process, PAddress);
2011 
2012  /*
2013  * Set the PTE to point to the new page
2014  */
2015  if (!NT_SUCCESS(MmCreateVirtualMapping(Process, PAddress, NewProtect, NewPage)))
2016  {
2017  DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2018  KeBugCheck(MEMORY_MANAGEMENT);
2019  }
2020 
2021  if (Process)
2022  MmInsertRmap(NewPage, Process, PAddress);
2023 
2024  DPRINT("Address 0x%p\n", Address);
2025  return STATUS_SUCCESS;
2026 }
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1559
static VOID MmAlterViewAttributes(PMMSUPPORT AddressSpace, PVOID BaseAddress, SIZE_T RegionSize, ULONG OldType, ULONG OldProtect, ULONG NewType, ULONG NewProtect)
Definition: section.c:1440
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define PAGE_IS_EXECUTABLE
Definition: mm.h:159
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
#define TRUE
Definition: types.h:120
#define MC_USER
Definition: mm.h:114
#define PFN_FROM_SSE(E)
Definition: mm.h:1324
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:462
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:1091
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:165
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
#define MmLockSectionSegment(x)
Definition: mm.h:1353
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:153
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:1526
NTSTATUS Status
Definition: section.c:4923
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
Entry
Definition: section.c:4932
VOID NTAPI MmDeleteVirtualMapping(struct _EPROCESS *Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
return FALSE
Definition: section.c:5048
#define MmUnlockSectionSegment(x)
Definition: mm.h:1361
_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:131
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:244
_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:1325
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1646
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
PLARGE_INTEGER Offset
Definition: section.c:4918
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
_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:1172
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _MEMORY_AREA::@1750 SectionData
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 1440 of file section.c.

1447 {
1450  BOOLEAN DoCOW = FALSE;
1451  ULONG i;
1453 
1455  ASSERT(MemoryArea != NULL);
1456  Segment = MemoryArea->SectionData.Segment;
1458 
1459  if ((Segment->WriteCopy) &&
1461  {
1462  DoCOW = TRUE;
1463  }
1464 
1465  if (OldProtect != NewProtect)
1466  {
1467  for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
1468  {
1469  SWAPENTRY SwapEntry;
1470  PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE);
1472 
1473  /* Wait for a wait entry to disappear */
1474  do
1475  {
1476  MmGetPageFileMapping(Process, Address, &SwapEntry);
1477  if (SwapEntry != MM_WAIT_ENTRY)
1478  break;
1481  YieldProcessor();
1484  }
1485  while (TRUE);
1486 
1487  /*
1488  * If we doing COW for this segment then check if the page is
1489  * already private.
1490  */
1492  {
1494  ULONG_PTR Entry;
1495  PFN_NUMBER Page;
1496 
1498  + MemoryArea->SectionData.ViewOffset;
1500  /*
1501  * An MM_WAIT_ENTRY is ok in this case... It'll just count as
1502  * IS_SWAP_FROM_SSE and we'll do the right thing.
1503  */
1505 
1508  {
1509  Protect = NewProtect;
1510  }
1511  }
1512 
1514  {
1516  Protect);
1517  }
1518  }
1519  }
1520 
1522 }
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1559
_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:1324
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1639
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MmLockSectionSegment(x)
Definition: mm.h:1353
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:4932
return FALSE
Definition: section.c:5048
PFN_NUMBER Page
Definition: section.c:4924
#define MmUnlockSectionSegment(x)
Definition: mm.h:1361
_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:244
_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:1325
ULONG_PTR SWAPENTRY
Definition: mm.h:56
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1646
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
PLARGE_INTEGER Offset
Definition: section.c:4918
#define NULL
Definition: types.h:112
#define PAGE_READONLY
Definition: compat.h:138
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
_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::@1750 SectionData
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:37
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1632
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 4665 of file section.c.

4669 {
4671  BOOLEAN Ret = TRUE;
4673  LARGE_INTEGER SegmentOffset, RangeEnd;
4675 
4677 
4679  if (MemoryArea == NULL)
4680  {
4682  return FALSE;
4683  }
4684 
4685  /* Only supported in old Mm for now */
4687  /* For file mappings */
4689 
4690  Segment = MemoryArea->SectionData.Segment;
4692 
4694  + MemoryArea->SectionData.ViewOffset;
4696  + MemoryArea->SectionData.ViewOffset;
4697 
4698  while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
4699  {
4701  if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4702  {
4703  Ret = FALSE;
4704  break;
4705  }
4706  SegmentOffset.QuadPart += PAGE_SIZE;
4707  }
4708 
4710 
4712  return Ret;
4713 }
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1559
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ULONG Type
Definition: mm.h:251
#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:1639
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
union _MMVAD::@2544 u
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MmLockSectionSegment(x)
Definition: mm.h:1353
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:5048
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
#define MmUnlockSectionSegment(x)
Definition: mm.h:1361
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
MMVAD VadNode
Definition: mm.h:249
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:244
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1661
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1325
#define NULL
Definition: types.h:112
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
struct _MEMORY_AREA::@1750 SectionData
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:37
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1632
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 4152 of file section.c.

4154 {
4155  BOOLEAN Ret;
4157 
4158  /* Check whether an ImageSectionObject exists */
4159  if (SectionObjectPointer->ImageSectionObject != NULL)
4160  {
4161  DPRINT1("ERROR: File can't be truncated because it has an image section\n");
4162  return FALSE;
4163  }
4164 
4166  if (!Segment)
4167  {
4168  /* There is no data section. It's fine to do anything. */
4169  return TRUE;
4170  }
4171 
4173  if ((Segment->SectionCount == 0) ||
4174  ((Segment->SectionCount == 1) && (SectionObjectPointer->SharedCacheMap != NULL)))
4175  {
4176  /* If the cache is the only one holding a reference to the segment, then it's fine to resize */
4177  Ret = TRUE;
4178  }
4179  else
4180  {
4181  /* We can't shrink, but we can extend */
4182  Ret = NewFileSize->QuadPart >= Segment->RawLength.QuadPart;
4183 #if DBG
4184  if (!Ret)
4185  {
4186  DPRINT1("Cannot truncate data: New Size %I64d, Segment Size %I64d\n", NewFileSize->QuadPart, Segment->RawLength.QuadPart);
4187  }
4188 #endif
4189  }
4191  MmDereferenceSegment(Segment);
4192 
4193  DPRINT("FIXME: didn't check for outstanding write probes\n");
4194 
4195  return Ret;
4196 }
#define TRUE
Definition: types.h:120
#define MmLockSectionSegment(x)
Definition: mm.h:1353
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
unsigned char BOOLEAN
return FALSE
Definition: section.c:5048
#define MmUnlockSectionSegment(x)
Definition: mm.h:1361
_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 2486 of file section.c.

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

2305 {
2306  PSECTION Section;
2307  NTSTATUS Status;
2310  KIRQL OldIrql;
2311 
2312  /*
2313  * Create the section
2314  */
2319  NULL,
2320  sizeof(*Section),
2321  0,
2322  0,
2323  (PVOID*)&Section);
2324  if (!NT_SUCCESS(Status))
2325  {
2326  return Status;
2327  }
2328  /*
2329  * Initialize it
2330  */
2331  RtlZeroMemory(Section, sizeof(*Section));
2332 
2333  /* Mark this as a "ROS" section */
2334  Section->u.Flags.filler = 1;
2336  Section->u.Flags.File = 1;
2337 
2339  Section->u.Flags.NoChange = 1;
2341  Section->u.Flags.Reserve = 1;
2342 
2343  if (!GotFileHandle)
2344  {
2345  ASSERT(UMaximumSize != NULL);
2346  // ASSERT(UMaximumSize->QuadPart != 0);
2347  MaximumSize = *UMaximumSize;
2348  }
2349  else
2350  {
2353  if (!NT_SUCCESS(Status))
2354  {
2355  ObDereferenceObject(Section);
2356  return Status;
2357  }
2358 
2359  /*
2360  * FIXME: Revise this once a locking order for file size changes is
2361  * decided
2362  */
2363  if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
2364  {
2365  MaximumSize = *UMaximumSize;
2366  }
2367  else
2368  {
2370  /* Mapping zero-sized files isn't allowed. */
2371  if (MaximumSize.QuadPart == 0)
2372  {
2373  ObDereferenceObject(Section);
2375  }
2376  }
2377 
2378  if (MaximumSize.QuadPart > FileSize.QuadPart)
2379  {
2382  sizeof(LARGE_INTEGER),
2383  &MaximumSize);
2384  if (!NT_SUCCESS(Status))
2385  {
2386  ObDereferenceObject(Section);
2388  }
2389  }
2390  }
2391 
2392  if (FileObject->SectionObjectPointer == NULL)
2393  {
2394  ObDereferenceObject(Section);
2396  }
2397 
2398  /*
2399  * Lock the file
2400  */
2402  if (Status != STATUS_SUCCESS)
2403  {
2404  ObDereferenceObject(Section);
2405  return Status;
2406  }
2407 
2408  /* Lock the PFN lock while messing with Section Object pointers */
2409 grab_segment:
2410  OldIrql = MiAcquirePfnLock();
2411  Segment = FileObject->SectionObjectPointer->DataSectionObject;
2412 
2413  while (Segment && (Segment->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
2414  {
2415  MiReleasePfnLock(OldIrql);
2417  OldIrql = MiAcquirePfnLock();
2418  Segment = FileObject->SectionObjectPointer->DataSectionObject;
2419  }
2420 
2421  /*
2422  * If this file hasn't been mapped as a data file before then allocate a
2423  * section segment to describe the data file mapping
2424  */
2425  if (Segment == NULL)
2426  {
2427  /* Release the lock. ExAllocatePoolWithTag might acquire it */
2428  MiReleasePfnLock(OldIrql);
2429 
2432  if (Segment == NULL)
2433  {
2434  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2435  ObDereferenceObject(Section);
2436  return STATUS_NO_MEMORY;
2437  }
2438 
2439  /* We are creating it */
2440  RtlZeroMemory(Segment, sizeof(*Segment));
2442  Segment->RefCount = 1;
2443 
2444  /* Acquire lock again */
2445  OldIrql = MiAcquirePfnLock();
2446 
2447  if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
2448  {
2449  /* Well that's bad luck. Restart it all over */
2450  MiReleasePfnLock(OldIrql);
2452  goto grab_segment;
2453  }
2454 
2455  FileObject->SectionObjectPointer->DataSectionObject = Segment;
2456 
2457  /* We're safe to release the lock now */
2458  MiReleasePfnLock(OldIrql);
2459 
2460  Section->Segment = (PSEGMENT)Segment;
2461 
2462  /* Self-referencing segment */
2463  Segment->Flags = &Segment->SegFlags;
2464  Segment->ReferenceCount = &Segment->RefCount;
2465 
2466  Segment->SectionCount = 1;
2467 
2469  Segment->FileObject = FileObject;
2471 
2472  Segment->Image.FileOffset = 0;
2473  Segment->Protection = SectionPageProtection;
2474 
2475  Segment->Image.Characteristics = 0;
2478  {
2479  Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
2480  }
2481  else
2482  {
2483  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2484  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2485  }
2486  Segment->Image.VirtualAddress = 0;
2488 
2489  /* We're good to use it now */
2490  OldIrql = MiAcquirePfnLock();
2491  Segment->SegFlags &= ~MM_SEGMENT_INCREATE;
2492  MiReleasePfnLock(OldIrql);
2493  }
2494  else
2495  {
2496  Section->Segment = (PSEGMENT)Segment;
2497  InterlockedIncrement64(&Segment->RefCount);
2498  InterlockedIncrementUL(&Segment->SectionCount);
2499 
2500  MiReleasePfnLock(OldIrql);
2501 
2503 
2504  if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
2506  {
2507  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2508  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2509  }
2510 
2512  }
2513  Section->SizeOfSection = MaximumSize;
2514 
2515  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2516  *SectionObject = Section;
2517  return STATUS_SUCCESS;
2518 }
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
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:3063
NTSTATUS NTAPI IoSetInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN PVOID FileInformation)
Definition: iofunc.c:1314
NTSTATUS NTAPI FsRtlGetFileSize(IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize)
Definition: fastio.c:815
#define MmLockSectionSegment(x)
Definition: mm.h:1353
union _SECTION::@2553 u
_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:4923
#define MM_SEGMENT_INCREATE
Definition: mm.h:240
return FALSE
Definition: section.c:5048
#define MmUnlockSectionSegment(x)
Definition: mm.h:1361
_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:951
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
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
#define MM_DATAFILE_SEGMENT
Definition: mm.h:238
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
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
_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:111
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1525
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define MM_SEGMENT_INDELETE
Definition: mm.h:239
#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 3144 of file section.c.

3151 {
3152  PSECTION Section;
3153  NTSTATUS Status;
3154  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3155  KIRQL OldIrql;
3156 
3157 
3158  if (FileObject == NULL)
3160 
3161  if (FileObject->SectionObjectPointer == NULL)
3162  {
3163  DPRINT1("Denying section creation due to missing cache initialization\n");
3165  }
3166 
3167  /*
3168  * Create the section
3169  */
3174  NULL,
3175  sizeof(*Section),
3176  0,
3177  0,
3178  (PVOID*)(PVOID)&Section);
3179  if (!NT_SUCCESS(Status))
3180  {
3181  return Status;
3182  }
3183 
3184  /*
3185  * Initialize it
3186  */
3187  RtlZeroMemory(Section, sizeof(*Section));
3188 
3189  /* Mark this as a "ROS" Section */
3190  Section->u.Flags.filler = 1;
3191 
3193  Section->u.Flags.File = 1;
3194  Section->u.Flags.Image = 1;
3196  Section->u.Flags.NoChange = 1;
3197 
3198 grab_image_section_object:
3199  OldIrql = MiAcquirePfnLock();
3200 
3201  /* Wait for it to be properly created or deleted */
3202  ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3203  while(ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
3204  {
3205  MiReleasePfnLock(OldIrql);
3206 
3208 
3209  OldIrql = MiAcquirePfnLock();
3210  ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3211  }
3212 
3213  if (ImageSectionObject == NULL)
3214  {
3215  NTSTATUS StatusExeFmt;
3216 
3217  /* Release the lock because ExAllocatePoolWithTag could need to acquire it */
3218  MiReleasePfnLock(OldIrql);
3219 
3220  ImageSectionObject = ExAllocatePoolZero(NonPagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT);
3221  if (ImageSectionObject == NULL)
3222  {
3223  ObDereferenceObject(Section);
3224  return STATUS_NO_MEMORY;
3225  }
3226 
3227  ImageSectionObject->SegFlags = MM_SEGMENT_INCREATE;
3228  ImageSectionObject->RefCount = 1;
3229  ImageSectionObject->SectionCount = 1;
3230 
3231  OldIrql = MiAcquirePfnLock();
3232  if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
3233  {
3234  MiReleasePfnLock(OldIrql);
3235  /* Bad luck. Start over */
3236  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3237  goto grab_image_section_object;
3238  }
3239 
3240  FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
3241 
3242  MiReleasePfnLock(OldIrql);
3243 
3244  /* Purge the cache */
3245  CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
3246 
3247  StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
3248 
3249  if (!NT_SUCCESS(StatusExeFmt))
3250  {
3251  /* Unset */
3252  OldIrql = MiAcquirePfnLock();
3253  FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3254  MiReleasePfnLock(OldIrql);
3255 
3256  if(ImageSectionObject->Segments != NULL)
3257  ExFreePool(ImageSectionObject->Segments);
3258 
3259  /*
3260  * If image file is empty, then return that the file is invalid for section
3261  */
3262  Status = StatusExeFmt;
3263  if (StatusExeFmt == STATUS_END_OF_FILE)
3264  {
3266  }
3267 
3268  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3269  ObDereferenceObject(Section);
3270  return Status;
3271  }
3272 
3273  Section->Segment = (PSEGMENT)ImageSectionObject;
3274  ASSERT(ImageSectionObject->Segments);
3275  ASSERT(ImageSectionObject->RefCount > 0);
3276 
3277  /*
3278  * Lock the file
3279  */
3281  if (!NT_SUCCESS(Status))
3282  {
3283  /* Unset */
3284  OldIrql = MiAcquirePfnLock();
3285  FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3286  MiReleasePfnLock(OldIrql);
3287 
3288  ExFreePool(ImageSectionObject->Segments);
3289  ExFreePool(ImageSectionObject);
3290  ObDereferenceObject(Section);
3291  return Status;
3292  }
3293 
3294  OldIrql = MiAcquirePfnLock();
3295  ImageSectionObject->SegFlags &= ~MM_SEGMENT_INCREATE;
3296 
3297  /* Take a ref on the file on behalf of the newly created structure */
3299 
3300  MiReleasePfnLock(OldIrql);
3301 
3302  Status = StatusExeFmt;
3303  }
3304  else
3305  {
3306  /* If FS driver called for delete, tell them it's not possible anymore. */
3307  ImageSectionObject->SegFlags &= ~MM_IMAGE_SECTION_FLUSH_DELETE;
3308 
3309  /* Take one ref */
3310  InterlockedIncrement64(&ImageSectionObject->RefCount);
3311  ImageSectionObject->SectionCount++;
3312 
3313  MiReleasePfnLock(OldIrql);
3314 
3315  Section->Segment = (PSEGMENT)ImageSectionObject;
3316 
3318  }
3319  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
3320  *SectionObject = Section;
3321  ASSERT(ImageSectionObject->RefCount > 0);
3322 
3323  return Status;
3324 }
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:2991
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
#define MM_IMAGE_SECTION_FLUSH_DELETE
Definition: mm.h:241
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:3063
union _SECTION::@2553 u
#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:4923
#define MM_SEGMENT_INCREATE
Definition: mm.h:240
return FALSE
Definition: section.c:5048
_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:951
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PMM_SECTION_SEGMENT Segments
Definition: mm.h:234
#define ObDereferenceObject
Definition: obfuncs.h:203
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
POBJECT_TYPE MmSectionObjectType
Definition: section.c:195
MMSECTION_FLAGS Flags
Definition: mmtypes.h:814
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File)
Definition: section.c:909
struct _SEGMENT * PSEGMENT
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:111
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define MM_SEGMENT_INDELETE
Definition: mm.h:239
#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 2170 of file section.c.

2171 {
2172  PSECTION PhysSection;
2173  NTSTATUS Status;
2175  UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2176  LARGE_INTEGER SectionSize;
2177  HANDLE Handle;
2179 
2180  /*
2181  * Create the section mapping physical memory
2182  */
2183  SectionSize.QuadPart = MmHighestPhysicalPage * PAGE_SIZE;
2185  &Name,
2187  NULL,
2188  NULL);
2189  /*
2190  * Create the Object
2191  */
2194  &Obj,
2196  NULL,
2197  sizeof(*PhysSection),
2198  0,
2199  0,
2200  (PVOID*)&PhysSection);
2201  if (!NT_SUCCESS(Status))
2202  {
2203  DPRINT1("MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n", Status);
2204  return Status;
2205  }
2206 
2207  /*
2208  * Initialize it
2209  */
2210  RtlZeroMemory(PhysSection, sizeof(*PhysSection));
2211 
2212  /* Mark this as a "ROS Section" */
2213  PhysSection->u.Flags.filler = 1;
2215  PhysSection->u.Flags.PhysicalMemory = 1;
2216  PhysSection->SizeOfSection = SectionSize;
2219  if (Segment == NULL)
2220  {
2221  ObDereferenceObject(PhysSection);
2222  return STATUS_NO_MEMORY;
2223  }
2225  PhysSection->Segment = (PSEGMENT)Segment;
2226  Segment->RefCount = 1;
2227 
2228  Segment->ReferenceCount = &Segment->RefCount;
2229  Segment->Flags = &Segment->SegFlags;
2230 
2232  Segment->Image.FileOffset = 0;
2233  Segment->Protection = PAGE_EXECUTE_READWRITE;
2234  Segment->RawLength = SectionSize;
2235  Segment->Length = SectionSize;
2236  Segment->SegFlags = MM_PHYSICALMEMORY_SEGMENT;
2237  Segment->WriteCopy = FALSE;
2238  Segment->Image.VirtualAddress = 0;
2239  Segment->Image.Characteristics = 0;
2241 
2242  Status = ObInsertObject(PhysSection,
2243  NULL,
2245  0,
2246  NULL,
2247  &Handle);
2248  if (!NT_SUCCESS(Status))
2249  {
2250  ObDereferenceObject(PhysSection);
2251  return Status;
2252  }
2254 
2255  return STATUS_SUCCESS;
2256 }
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:3063
union _SECTION::@2553 u
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define L(x)
Definition: ntvdm.h:50
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:810
NTSTATUS Status
Definition: section.c:4923
return FALSE
Definition: section.c:5048
_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:951
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:3378
MMSECTION_FLAGS Flags
Definition: mmtypes.h:814
#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:237
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:2934
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:111
#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 4510 of file section.c.

4518 {
4519  NTSTATUS Status;
4520  ULONG Protection;
4521  PSECTION *SectionObject = (PSECTION *)Section;
4522  BOOLEAN FileLock = FALSE;
4523 
4524  /* Check if an ARM3 section is being created instead */
4526  {
4527  if (!(FileObject) && !(FileHandle))
4528  {
4529  return MmCreateArm3Section(Section,
4530  DesiredAccess,
4532  MaximumSize,
4534  AllocationAttributes &~ 1,
4535  FileHandle,
4536  FileObject);
4537  }
4538  }
4539 
4540  /* Convert section flag to page flag */
4542 
4543  /* Check to make sure the protection is correct. Nt* does this already */
4545  if (Protection == MM_INVALID_PROTECTION)
4546  {
4547  DPRINT1("Page protection is invalid\n");
4549  }
4550 
4551  /* Check if this is going to be a data or image backed file section */
4552  if ((FileHandle) || (FileObject))
4553  {
4554  /* These cannot be mapped with large pages */
4556  {
4557  DPRINT1("Large pages cannot be used with an image mapping\n");
4559  }
4560 
4561  /* Did the caller pass a file object ? */
4562  if (FileObject)
4563  {
4564  /* Reference the object directly */
4566 
4567  /* We don't create image mappings with file objects */
4569  }
4570  else
4571  {
4572  /* Reference the file handle to get the object */
4574  MmMakeFileAccess[Protection],
4577  (PVOID*)&FileObject,
4578  NULL);
4579  if (!NT_SUCCESS(Status))
4580  {
4581  DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
4582  return Status;
4583  }
4584 
4585  /* Lock the file */
4587  if (!NT_SUCCESS(Status))
4588  {
4590  return Status;
4591  }
4592 
4593  FileLock = TRUE;
4594 
4595  /* Deny access if there are writes on the file */
4596 #if 0
4598  {
4599  DPRINT1("Cannot create image maps with writers open on the file!\n");
4601  goto Quit;
4602  }
4603 #else
4605  DPRINT1("Creating image map with writers open on the file!\n");
4606 #endif
4607  }
4608  }
4609  else
4610  {
4611  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
4613  }
4614 
4616  {
4618  DesiredAccess,
4620  MaximumSize,
4623  FileObject);
4624  }
4625 #ifndef NEWCC
4626  else if (FileObject != NULL)
4627  {
4629  DesiredAccess,
4631  MaximumSize,
4634  FileObject,
4635  FileHandle != NULL);
4636  }
4637 #else
4638  else if (FileHandle != NULL || FileObject != NULL)
4639  {
4641  DesiredAccess,
4643  MaximumSize,
4646  FileObject);
4647  }
4648 #endif
4649  else
4650  {
4651  /* All cases should be handled above */
4653  }
4654 
4655  if (FileLock)
4657  if (FileObject)
4659 
4660  return Status;
4661 }
_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:3063
#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:2486
_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:4923
unsigned char BOOLEAN
return FALSE
Definition: section.c:5048
_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:3144
#define SEC_PHYSICALMEMORY
Definition: mm.h:112
#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:2294
#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 5124 of file section.c.

5127 {
5128  PSECTION Section = _Section;
5129 
5130  /* It makes no sense to extend an image mapping */
5131  if (Section->u.Flags.Image)
5133 
5134  /* Nor is it possible to extend a page file mapping */
5135  if (!Section->u.Flags.File)
5137 
5138  if (!MiIsRosSectionObject(Section))
5139  return STATUS_NOT_IMPLEMENTED;
5140 
5141  /* We just extend the sizes. Shrinking is a no-op ? */
5142  if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5143  {
5145  Section->SizeOfSection = *NewSize;
5146 
5147  if (!Section->u.Flags.Reserve)
5148  {
5150  if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5151  {
5152  Segment->RawLength = *NewSize;
5153  Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5154  }
5156  }
5157  }
5158 
5159  return STATUS_SUCCESS;
5160 }
if(Entry==0)
Definition: section.c:4933
PSEGMENT Segment
Definition: mmtypes.h:809
#define MmLockSectionSegment(x)
Definition: mm.h:1353
union _SECTION::@2553 u
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:1361
_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 4246 of file section.c.

4248 {
4249  switch(FlushType)
4250  {
4251  case MmFlushForDelete:
4252  {
4253  /*
4254  * FIXME: Check for outstanding write probes on Data section.
4255  * How do we do that ?
4256  */
4257  }
4258  /* Fall-through */
4259  case MmFlushForWrite:
4260  {
4261  KIRQL OldIrql = MiAcquirePfnLock();
4262  PMM_IMAGE_SECTION_OBJECT ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4263 
4264  DPRINT("Deleting or modifying %p\n", SectionObjectPointer);
4265 
4266  /* Wait for concurrent creation or deletion of image to be done */
4267  ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4268  while (ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INCREATE | MM_SEGMENT_INDELETE)))
4269  {
4270  MiReleasePfnLock(OldIrql);
4272  OldIrql = MiAcquirePfnLock();
4273  ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4274  }
4275 
4276  if (!ImageSectionObject)
4277  {
4278  DPRINT("No image section object. Accepting\n");
4279  /* Nothing to do */
4280  MiReleasePfnLock(OldIrql);
4281  return TRUE;
4282  }
4283 
4284  /* Do we have open sections or mappings on it ? */
4285  if ((ImageSectionObject->SectionCount) || (ImageSectionObject->MapCount))
4286  {
4287  /* We do. No way to delete it */
4288  MiReleasePfnLock(OldIrql);
4289  DPRINT("Denying. There are mappings open\n");
4290  return FALSE;
4291  }
4292 
4293  /* There are no sections open on it, but we must still have pages around. Discard everything */
4294  ImageSectionObject->SegFlags |= MM_IMAGE_SECTION_FLUSH_DELETE;
4295  InterlockedIncrement64(&ImageSectionObject->RefCount);
4296  MiReleasePfnLock(OldIrql);
4297 
4298  DPRINT("Purging\n");
4299 
4300  for (ULONG i = 0; i < ImageSectionObject->NrSegments; i++)
4301  {
4302  if (!MiPurgeImageSegment(&ImageSectionObject->Segments[i]))
4303  break;
4304  }
4305 
4306  /* Grab lock again */
4307  OldIrql = MiAcquirePfnLock();
4308 
4309  if (!(ImageSectionObject->SegFlags & MM_IMAGE_SECTION_FLUSH_DELETE))
4310  {
4311  /*
4312  * Someone actually created a section while we were not looking.
4313  * Drop our ref and deny.
4314  * MmDereferenceSegmentWithLock releases Pfn lock
4315  */
4316  MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4317  return FALSE;
4318  }
4319 
4320  /* We should be the last one holding a ref here. */
4321  ASSERT(ImageSectionObject->RefCount == 1);
4322  ASSERT(ImageSectionObject->SectionCount == 0);
4323 
4324  /* Dereference the first segment, this will free everything & release the lock */
4325  MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4326  return TRUE;
4327  }
4328  }
4329  return FALSE;
4330 }
static LARGE_INTEGER TinyTime
Definition: section.c:64
#define MM_IMAGE_SECTION_FLUSH_DELETE
Definition: mm.h:241
#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:4200
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:240
return FALSE
Definition: section.c:5048
IN PFCB IN FAT_FLUSH_TYPE FlushType
Definition: fatprocs.h:1080
PMM_SECTION_SEGMENT Segments
Definition: mm.h:234
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
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:239
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
unsigned int ULONG
Definition: retypes.h:1

Referenced by _Requires_lock_held_(), Ext2CreateFile(),