ReactOS  0.4.15-dev-5126-g3bb451b
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:5060
_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 2569 of file section.c.

2570 {
2571  SIZE_T SizeOfSegments;
2572  PMM_SECTION_SEGMENT Segments;
2573 
2574  /* TODO: check for integer overflow */
2575  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
2576 
2578  SizeOfSegments,
2580 
2581  if(Segments)
2582  RtlZeroMemory(Segments, SizeOfSegments);
2583 
2584  return Segments;
2585 }
#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 3003 of file section.c.

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

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

2595 {
2596  NTSTATUS Status;
2598  ULONG AdjustOffset;
2599  ULONG OffsetAdjustment;
2600  ULONG BufferSize;
2601  ULONG UsedSize;
2602  PVOID Buffer;
2605 
2607 
2608  if(Length == 0)
2609  {
2610  KeBugCheck(MEMORY_MANAGEMENT);
2611  }
2612 
2613  FileOffset = *Offset;
2614 
2615  /* Negative/special offset: it cannot be used in this context */
2616  if(FileOffset.u.HighPart < 0)
2617  {
2618  KeBugCheck(MEMORY_MANAGEMENT);
2619  }
2620 
2621  AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
2622  OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
2623  FileOffset.u.LowPart = AdjustOffset;
2624 
2625  BufferSize = Length + OffsetAdjustment;
2627 
2628  /*
2629  * It's ok to use paged pool, because this is a temporary buffer only used in
2630  * the loading of executables. The assumption is that MmCreateSection is
2631  * always called at low IRQLs and that these buffers don't survive a brief
2632  * initialization phase
2633  */
2635  if (!Buffer)
2636  {
2638  }
2639 
2641 
2642  UsedSize = (ULONG)Iosb.Information;
2643 
2644  if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
2645  {
2648  }
2649 
2650  if(NT_SUCCESS(Status))
2651  {
2652  *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
2653  *AllocBase = Buffer;
2654  *ReadSize = UsedSize - OffsetAdjustment;
2655  }
2656  else
2657  {
2658  ExFreePoolWithTag(Buffer, 'rXmM');
2659  }
2660 
2661  return Status;
2662 }
#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:4935
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#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:4930
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
return Iosb
Definition: create.c:4402
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:1586
#define MC_USER
Definition: mm.h:114
#define PFN_FROM_SSE(E)
Definition: mm.h:1351
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:73
#define MmLockSectionSegment(x)
Definition: mm.h:1380
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:1360
Entry
Definition: section.c:4944
PFN_NUMBER Page
Definition: section.c:4936
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_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:1352
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1368
base of all file and directory entries
Definition: entries.h:82

Referenced by _When_().

◆ if() [1/2]

if ( Entry  = = 0)

Definition at line 4945 of file section.c.

4950  {
4951  BOOLEAN DirtyAgain;
4952 
4953  /*
4954  * We got a dirty entry. This path is for the shared data,
4955  * be-it regular file maps or shared sections of DLLs
4956  */
4958  FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
4959 
4960  /* Insert the cleaned entry back. Mark it as write in progress, and clear the dirty bit. */
4962  Entry = WRITE_SSE(Entry);
4964 
4966 
4967  if (FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
4968  {
4969  /* We have to write it back to the file. Tell the FS driver who we are */
4970  if (PageOut)
4972 
4973  /* Go ahead and write the page */
4974  DPRINT("Writing page at offset %I64d for file %wZ, Pageout: %s\n",
4975  Offset->QuadPart, &Segment->FileObject->FileName, PageOut ? "TRUE" : "FALSE");
4976  Status = MiWritePage(Segment, Offset->QuadPart, Page);
4977 
4978  if (PageOut)
4980  }
4981  else
4982  {
4983  /* This must only be called by the page-out path */
4984  ASSERT(PageOut);
4985 
4986  /* And this must be for a shared section in a DLL */
4987  ASSERT(FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
4988 
4989  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
4990  if (!SwapEntry)
4991  {
4992  SwapEntry = MmAllocSwapPage();
4993  }
4994 
4995  if (SwapEntry)
4996  {
4997  Status = MmWriteToSwapPage(SwapEntry, Page);
4998  if (NT_SUCCESS(Status))
4999  {
5000  MmSetSavedSwapEntryPage(Page, SwapEntry);
5001  }
5002  else
5003  {
5004  MmFreeSwapPage(SwapEntry);
5005  }
5006  }
5007  else
5008  {
5009  DPRINT1("Failed to allocate a swap page!\n");
5011  }
5012  }
5013 
5015 
5016  /* Get the entry again */
5019 
5020  if (!NT_SUCCESS(Status))
5021  {
5022  /* Damn, this failed. Consider this page as still dirty */
5023  DPRINT1("MiWritePage FAILED: Status 0x%08x!\n", Status);
5024  DirtyAgain = TRUE;
5025  }
5026  else
5027  {
5028  /* Check if someone dirtified this page while we were not looking */
5029  DirtyAgain = IS_DIRTY_SSE(Entry);
5030  }
5031 
5032  /* Drop the reference we got, deleting the write altogether. */
5034  if (DirtyAgain)
5035  {
5036  Entry = DIRTY_SSE(Entry);
5037  }
5039  }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1586
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WRITE_SSE(E)
Definition: mm.h:1361
#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:1351
#define MmLockSectionSegment(x)
Definition: mm.h:1380
#define DIRTY_SSE(E)
Definition: mm.h:1358
ASSERT(Segment->Locked)
#define IS_DIRTY_SSE(E)
Definition: mm.h:1360
#define MAKE_SSE(P, C)
Definition: mm.h:1370
unsigned char BOOLEAN
PFN_NUMBER Page
Definition: section.c:4936
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_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:305
PLARGE_INTEGER BOOLEAN BOOLEAN PageOut
Definition: section.c:4933
#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:1366
#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:1368
#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 5042 of file section.c.

5043  {
5044  ULONG_PTR NewEntry = 0;
5045  /* Restore the swap entry here */
5046  if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
5047  {
5048  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
5049  if (SwapEntry)
5050  NewEntry = MAKE_SWAP_SSE(SwapEntry);
5051  }
5052 
5053  /* Yes. Release it */
5056  /* Tell the caller we released the page */
5057  return TRUE;
5058  }
#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:4936
_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:1357
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:5060
_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 4212 of file section.c.

4213 {
4215 
4217 
4218  /* Loop over all entries */
4219  for (PageTable = RtlEnumerateGenericTable(&Segment->PageTable, TRUE);
4220  PageTable != NULL;
4222  {
4223  for (ULONG i = 0; i < _countof(PageTable->PageEntries); i++)
4224  {
4225  ULONG_PTR Entry = PageTable->PageEntries[i];
4227 
4228  if (!Entry)
4229  continue;
4230 
4232  {
4233  /* I/O ongoing or swap entry. Someone mapped this file as we were not looking */
4235  return FALSE;
4236  }
4237 
4238  /* Regular entry */
4241 
4242  /* Properly remove using the used API */
4243  Offset.QuadPart = PageTable->FileOffset.QuadPart + (i << PAGE_SHIFT);
4246  }
4247  }
4248 
4250 
4251  return TRUE;
4252 }
#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:1351
_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:1380
uint32_t ULONG_PTR
Definition: typedefs.h:65
ASSERT(Segment->Locked)
return FALSE
Definition: section.c:5060
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_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:1352
PLARGE_INTEGER Offset
Definition: section.c:4930
#define NULL
Definition: types.h:112
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1368
#define IS_WRITE_SSE(E)
Definition: mm.h:1362
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 4459 of file section.c.

4460 {
4461  DPRINT("MmUnmapViewInSystemSpace() called\n");
4462 
4464 }
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:3504
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1688
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 3568 of file section.c.

3571 {
3572  NTSTATUS Status;
3575  PVOID ImageBaseAddress = 0;
3576 
3577  DPRINT("Opening memory area Process %p BaseAddress %p\n",
3578  Process, BaseAddress);
3579 
3580  ASSERT(Process);
3581 
3583 
3585  BaseAddress);
3586  if (MemoryArea == NULL ||
3587 #ifdef NEWCC
3588  ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) && (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
3589 #else
3591 #endif
3593 
3594  {
3596 
3597  DPRINT1("Unable to find memory area at address %p.\n", BaseAddress);
3598  return STATUS_NOT_MAPPED_VIEW;
3599  }
3600 
3602  {
3603  ULONG i;
3604  ULONG NrSegments;
3605  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3606  PMM_SECTION_SEGMENT SectionSegments;
3608 
3609  Segment = MemoryArea->SectionData.Segment;
3610  ImageSectionObject = ImageSectionObjectFromSegment(Segment);
3611  SectionSegments = ImageSectionObject->Segments;
3612  NrSegments = ImageSectionObject->NrSegments;
3613 
3615 
3616  /* Search for the current segment within the section segments
3617  * and calculate the image base address */
3618  for (i = 0; i < NrSegments; i++)
3619  {
3620  if (Segment == &SectionSegments[i])
3621  {
3622  ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
3623  break;
3624  }
3625  }
3626  if (i >= NrSegments)
3627  {
3628  KeBugCheck(MEMORY_MANAGEMENT);
3629  }
3630 
3631  for (i = 0; i < NrSegments; i++)
3632  {
3633  PVOID SBaseAddress = (PVOID)
3634  ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
3635 
3636  Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
3637  if (!NT_SUCCESS(Status))
3638  {
3639  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3640  SBaseAddress, Process, Status);
3642  }
3643  }
3644  DPRINT("One mapping less for %p\n", ImageSectionObject->FileObject->SectionObjectPointer);
3645  InterlockedDecrement(&ImageSectionObject->MapCount);
3646  }
3647  else
3648  {
3650  if (!NT_SUCCESS(Status))
3651  {
3652  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3655  }
3656  }
3657 
3658  /* Notify debugger */
3659  if (ImageBaseAddress && !SkipDebuggerNotify) DbgkUnMapViewOfSection(ImageBaseAddress);
3660 
3661  return STATUS_SUCCESS;
3662 }
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
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:3504
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:4935
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:1688
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
union _MMVAD::@2565 u
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
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:837
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
NTSTATUS Status
Definition: section.c:4935
return FALSE
Definition: section.c:5060
PFN_NUMBER Page
Definition: section.c:4936
_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  PFN_NUMBER UnmappedPage;
1901  PVOID PAddress;
1904  ULONG_PTR Entry;
1906  BOOLEAN Cow = FALSE;
1907  ULONG NewProtect;
1908  BOOLEAN Unmapped;
1909 
1910  DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1911 
1912  /* Get the region for this address */
1914  &MemoryArea->SectionData.RegionListHead,
1915  Address, NULL);
1916  ASSERT(Region != NULL);
1917  if (!(Region->Protect & PAGE_IS_WRITABLE))
1918  return STATUS_ACCESS_VIOLATION;
1919 
1920  /* Make sure we have a page mapping for this address. */
1922  {
1924  if (!NT_SUCCESS(Status))
1925  {
1926  /* This is invalid access ! */
1927  return Status;
1928  }
1929  }
1930 
1931  /*
1932  * Check if the page has already been set readwrite
1933  */
1935  {
1936  DPRINT("Address 0x%p\n", Address);
1937  return STATUS_SUCCESS;
1938  }
1939 
1940  /* Check if we are doing Copy-On-Write */
1941  Segment = MemoryArea->SectionData.Segment;
1942  Cow = Segment->WriteCopy || (Region->Protect & PAGE_IS_WRITECOPY);
1943 
1944  if (!Cow)
1945  {
1946  /* Simply update page protection and we're done */
1947  MmSetPageProtect(Process, Address, Region->Protect);
1948  return STATUS_SUCCESS;
1949  }
1950 
1951  /* Calculate the new protection & check if we should update the region */
1952  NewProtect = Region->Protect;
1954  {
1956  if (Region->Protect & PAGE_IS_EXECUTABLE)
1958  else
1961  &MemoryArea->SectionData.RegionListHead,
1964  }
1965 
1966  /*
1967  * Find the offset of the page
1968  */
1969  PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1970  Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1971  + MemoryArea->SectionData.ViewOffset;
1972 
1973  /* Get the page mapping this section offset. */
1976 
1977  /* Get the current page mapping for the process */
1978  ASSERT(MmIsPagePresent(Process, PAddress));
1979  OldPage = MmGetPfnForProcess(Process, PAddress);
1980  ASSERT(OldPage != 0);
1981 
1982  if (IS_SWAP_FROM_SSE(Entry) ||
1983  PFN_FROM_SSE(Entry) != OldPage)
1984  {
1986  /* This is a private page. We must only change the page protection. */
1987  MmSetPageProtect(Process, PAddress, NewProtect);
1988  return STATUS_SUCCESS;
1989  }
1990 
1991  /*
1992  * Allocate a page
1993  */
1995  {
1996  KeBugCheck(MEMORY_MANAGEMENT);
1997  }
1998 
1999  /*
2000  * Copy the old page
2001  */
2002  NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
2003 
2004  /*
2005  * Unshare the old page.
2006  */
2007  DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
2008  Unmapped = MmDeleteVirtualMapping(Process, PAddress, NULL, &UnmappedPage);
2009  if (!Unmapped || (UnmappedPage != OldPage))
2010  {
2011  /* Uh , we had a page just before, but suddenly it changes. Someone corrupted us. */
2012  KeBugCheckEx(MEMORY_MANAGEMENT,
2013  (ULONG_PTR)Process,
2014  (ULONG_PTR)PAddress,
2015  (ULONG_PTR)__FILE__,
2016  __LINE__);
2017  }
2018 
2019  if (Process)
2020  MmDeleteRmap(OldPage, Process, PAddress);
2023 
2024  /*
2025  * Set the PTE to point to the new page
2026  */
2027  if (!NT_SUCCESS(MmCreateVirtualMapping(Process, PAddress, NewProtect, NewPage)))
2028  {
2029  DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2030  KeBugCheck(MEMORY_MANAGEMENT);
2031  }
2032 
2033  if (Process)
2034  MmInsertRmap(NewPage, Process, PAddress);
2035 
2036  DPRINT("Address 0x%p\n", Address);
2037  return STATUS_SUCCESS;
2038 }
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1586
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:1351
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:281
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:1380
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:4935
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
Entry
Definition: section.c:4944
return FALSE
Definition: section.c:5060
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
Status
Definition: gdiplustypes.h:24
VOID NTAPI MmDeleteVirtualMapping(IN PEPROCESS Process, IN PVOID Address, OUT PBOOLEAN WasDirty, OUT PPFN_NUMBER Page)
Definition: page.c:177
#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:1352
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1673
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
PLARGE_INTEGER Offset
Definition: section.c:4930
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
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define 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:1586
_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:1351
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1666
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MmLockSectionSegment(x)
Definition: mm.h:1380
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:4944
return FALSE
Definition: section.c:5060
PFN_NUMBER Page
Definition: section.c:4936
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_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:1352
ULONG_PTR SWAPENTRY
Definition: mm.h:56
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1673
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
PLARGE_INTEGER Offset
Definition: section.c:4930
#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:1659
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 4677 of file section.c.

4681 {
4683  BOOLEAN Ret = TRUE;
4685  LARGE_INTEGER SegmentOffset, RangeEnd;
4687 
4689 
4691  if (MemoryArea == NULL)
4692  {
4694  return FALSE;
4695  }
4696 
4697  /* Only supported in old Mm for now */
4699  /* For file mappings */
4701 
4702  Segment = MemoryArea->SectionData.Segment;
4704 
4706  + MemoryArea->SectionData.ViewOffset;
4708  + MemoryArea->SectionData.ViewOffset;
4709 
4710  while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
4711  {
4713  if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4714  {
4715  Ret = FALSE;
4716  break;
4717  }
4718  SegmentOffset.QuadPart += PAGE_SIZE;
4719  }
4720 
4722 
4724  return Ret;
4725 }
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1586
_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:1666
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MmLockSectionSegment(x)
Definition: mm.h:1380
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:5060
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_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:1688
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1352
#define NULL
Definition: types.h:112
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
union _MMVAD::@2565 u
_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:1659
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 4164 of file section.c.

4166 {
4167  BOOLEAN Ret;
4169 
4170  /* Check whether an ImageSectionObject exists */
4171  if (SectionObjectPointer->ImageSectionObject != NULL)
4172  {
4173  DPRINT1("ERROR: File can't be truncated because it has an image section\n");
4174  return FALSE;
4175  }
4176 
4178  if (!Segment)
4179  {
4180  /* There is no data section. It's fine to do anything. */
4181  return TRUE;
4182  }
4183 
4185  if ((Segment->SectionCount == 0) ||
4186  ((Segment->SectionCount == 1) && (SectionObjectPointer->SharedCacheMap != NULL)))
4187  {
4188  /* If the cache is the only one holding a reference to the segment, then it's fine to resize */
4189  Ret = TRUE;
4190  }
4191  else
4192  {
4193  /* We can't shrink, but we can extend */
4194  Ret = NewFileSize->QuadPart >= Segment->RawLength.QuadPart;
4195 #if DBG
4196  if (!Ret)
4197  {
4198  DPRINT1("Cannot truncate data: New Size %I64d, Segment Size %I64d\n", NewFileSize->QuadPart, Segment->RawLength.QuadPart);
4199  }
4200 #endif
4201  }
4203  MmDereferenceSegment(Segment);
4204 
4205  DPRINT("FIXME: didn't check for outstanding write probes\n");
4206 
4207  return Ret;
4208 }
#define TRUE
Definition: types.h:120
#define MmLockSectionSegment(x)
Definition: mm.h:1380
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
unsigned char BOOLEAN
return FALSE
Definition: section.c:5060
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_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
union _CONTROL_AREA::@2558 u
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:3062
#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
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
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:4935
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
return FALSE
Definition: section.c:5060
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
#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
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1230
#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
union _SECTION::@2574 u
#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 2306 of file section.c.

2317 {
2318  PSECTION Section;
2319  NTSTATUS Status;
2322  KIRQL OldIrql;
2323 
2324  /*
2325  * Create the section
2326  */
2331  NULL,
2332  sizeof(*Section),
2333  0,
2334  0,
2335  (PVOID*)&Section);
2336  if (!NT_SUCCESS(Status))
2337  {
2338  return Status;
2339  }
2340  /*
2341  * Initialize it
2342  */
2343  RtlZeroMemory(Section, sizeof(*Section));
2344 
2345  /* Mark this as a "ROS" section */
2346  Section->u.Flags.filler = 1;
2348  Section->u.Flags.File = 1;
2349 
2351  Section->u.Flags.NoChange = 1;
2353  Section->u.Flags.Reserve = 1;
2354 
2355  if (!GotFileHandle)
2356  {
2357  ASSERT(UMaximumSize != NULL);
2358  // ASSERT(UMaximumSize->QuadPart != 0);
2359  MaximumSize = *UMaximumSize;
2360  }
2361  else
2362  {
2365  if (!NT_SUCCESS(Status))
2366  {
2367  ObDereferenceObject(Section);
2368  return Status;
2369  }
2370 
2371  /*
2372  * FIXME: Revise this once a locking order for file size changes is
2373  * decided
2374  */
2375  if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
2376  {
2377  MaximumSize = *UMaximumSize;
2378  }
2379  else
2380  {
2382  /* Mapping zero-sized files isn't allowed. */
2383  if (MaximumSize.QuadPart == 0)
2384  {
2385  ObDereferenceObject(Section);
2387  }
2388  }
2389 
2390  if (MaximumSize.QuadPart > FileSize.QuadPart)
2391  {
2394  sizeof(LARGE_INTEGER),
2395  &MaximumSize);
2396  if (!NT_SUCCESS(Status))
2397  {
2398  ObDereferenceObject(Section);
2400  }
2401  }
2402  }
2403 
2404  if (FileObject->SectionObjectPointer == NULL)
2405  {
2406  ObDereferenceObject(Section);
2408  }
2409 
2410  /*
2411  * Lock the file
2412  */
2414  if (Status != STATUS_SUCCESS)
2415  {
2416  ObDereferenceObject(Section);
2417  return Status;
2418  }
2419 
2420  /* Lock the PFN lock while messing with Section Object pointers */
2421 grab_segment:
2422  OldIrql = MiAcquirePfnLock();
2423  Segment = FileObject->SectionObjectPointer->DataSectionObject;
2424 
2425  while (Segment && (Segment->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
2426  {
2427  MiReleasePfnLock(OldIrql);
2429  OldIrql = MiAcquirePfnLock();
2430  Segment = FileObject->SectionObjectPointer->DataSectionObject;
2431  }
2432 
2433  /*
2434  * If this file hasn't been mapped as a data file before then allocate a
2435  * section segment to describe the data file mapping
2436  */
2437  if (Segment == NULL)
2438  {
2439  /* Release the lock. ExAllocatePoolWithTag might acquire it */
2440  MiReleasePfnLock(OldIrql);
2441 
2444  if (Segment == NULL)
2445  {
2446  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2447  ObDereferenceObject(Section);
2448  return STATUS_NO_MEMORY;
2449  }
2450 
2451  /* We are creating it */
2452  RtlZeroMemory(Segment, sizeof(*Segment));
2454  Segment->RefCount = 1;
2455 
2456  /* Acquire lock again */
2457  OldIrql = MiAcquirePfnLock();
2458 
2459  if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
2460  {
2461  /* Well that's bad luck. Restart it all over */
2462  MiReleasePfnLock(OldIrql);
2464  goto grab_segment;
2465  }
2466 
2467  FileObject->SectionObjectPointer->DataSectionObject = Segment;
2468 
2469  /* We're safe to release the lock now */
2470  MiReleasePfnLock(OldIrql);
2471 
2472  Section->Segment = (PSEGMENT)Segment;
2473 
2474  /* Self-referencing segment */
2475  Segment->Flags = &Segment->SegFlags;
2476  Segment->ReferenceCount = &Segment->RefCount;
2477 
2478  Segment->SectionCount = 1;
2479 
2481  Segment->FileObject = FileObject;
2483 
2484  Segment->Image.FileOffset = 0;
2485  Segment->Protection = SectionPageProtection;
2486 
2487  Segment->Image.Characteristics = 0;
2490  {
2491  Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
2492  }
2493  else
2494  {
2495  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2496  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2497  }
2498  Segment->Image.VirtualAddress = 0;
2500 
2501  /* We're good to use it now */
2502  OldIrql = MiAcquirePfnLock();
2503  Segment->SegFlags &= ~MM_SEGMENT_INCREATE;
2504  MiReleasePfnLock(OldIrql);
2505  }
2506  else
2507  {
2508  Section->Segment = (PSEGMENT)Segment;
2509  InterlockedIncrement64(&Segment->RefCount);
2510  InterlockedIncrementUL(&Segment->SectionCount);
2511 
2512  MiReleasePfnLock(OldIrql);
2513 
2515 
2516  if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
2518  {
2519  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2520  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2521  }
2522 
2524  }
2525  Section->SizeOfSection = MaximumSize;
2526 
2527  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2528  *SectionObject = Section;
2529  return STATUS_SUCCESS;
2530 }
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:3062
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:1380
_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:4935
#define MM_SEGMENT_INCREATE
Definition: mm.h:240
return FALSE
Definition: section.c:5060
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_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
union _SECTION::@2574 u
#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 3156 of file section.c.

3163 {
3164  PSECTION Section;
3165  NTSTATUS Status;
3166  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3167  KIRQL OldIrql;
3168 
3169 
3170  if (FileObject == NULL)
3172 
3173  if (FileObject->SectionObjectPointer == NULL)
3174  {
3175  DPRINT1("Denying section creation due to missing cache initialization\n");
3177  }
3178 
3179  /*
3180  * Create the section
3181  */
3186  NULL,
3187  sizeof(*Section),
3188  0,
3189  0,
3190  (PVOID*)(PVOID)&Section);
3191  if (!NT_SUCCESS(Status))
3192  {
3193  return Status;
3194  }
3195 
3196  /*
3197  * Initialize it
3198  */
3199  RtlZeroMemory(Section, sizeof(*Section));
3200 
3201  /* Mark this as a "ROS" Section */
3202  Section->u.Flags.filler = 1;
3203 
3205  Section->u.Flags.File = 1;
3206  Section->u.Flags.Image = 1;
3208  Section->u.Flags.NoChange = 1;
3209 
3210 grab_image_section_object:
3211  OldIrql = MiAcquirePfnLock();
3212 
3213  /* Wait for it to be properly created or deleted */
3214  ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3215  while(ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
3216  {
3217  MiReleasePfnLock(OldIrql);
3218 
3220 
3221  OldIrql = MiAcquirePfnLock();
3222  ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3223  }
3224 
3225  if (ImageSectionObject == NULL)
3226  {
3227  NTSTATUS StatusExeFmt;
3228 
3229  /* Release the lock because ExAllocatePoolWithTag could need to acquire it */
3230  MiReleasePfnLock(OldIrql);
3231 
3232  ImageSectionObject = ExAllocatePoolZero(NonPagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT);
3233  if (ImageSectionObject == NULL)
3234  {
3235  ObDereferenceObject(Section);
3236  return STATUS_NO_MEMORY;
3237  }
3238 
3239  ImageSectionObject->SegFlags = MM_SEGMENT_INCREATE;
3240  ImageSectionObject->RefCount = 1;
3241  ImageSectionObject->SectionCount = 1;
3242 
3243  OldIrql = MiAcquirePfnLock();
3244  if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
3245  {
3246  MiReleasePfnLock(OldIrql);
3247  /* Bad luck. Start over */
3248  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3249  goto grab_image_section_object;
3250  }
3251 
3252  FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
3253 
3254  MiReleasePfnLock(OldIrql);
3255 
3256  /* Purge the cache */
3257  CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
3258 
3259  StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
3260 
3261  if (!NT_SUCCESS(StatusExeFmt))
3262  {
3263  /* Unset */
3264  OldIrql = MiAcquirePfnLock();
3265  FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3266  MiReleasePfnLock(OldIrql);
3267 
3268  if(ImageSectionObject->Segments != NULL)
3269  ExFreePool(ImageSectionObject->Segments);
3270 
3271  /*
3272  * If image file is empty, then return that the file is invalid for section
3273  */
3274  Status = StatusExeFmt;
3275  if (StatusExeFmt == STATUS_END_OF_FILE)
3276  {
3278  }
3279 
3280  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3281  ObDereferenceObject(Section);
3282  return Status;
3283  }
3284 
3285  Section->Segment = (PSEGMENT)ImageSectionObject;
3286  ASSERT(ImageSectionObject->Segments);
3287  ASSERT(ImageSectionObject->RefCount > 0);
3288 
3289  /*
3290  * Lock the file
3291  */
3293  if (!NT_SUCCESS(Status))
3294  {
3295  /* Unset */
3296  OldIrql = MiAcquirePfnLock();
3297  FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3298  MiReleasePfnLock(OldIrql);
3299 
3300  ExFreePool(ImageSectionObject->Segments);
3301  ExFreePool(ImageSectionObject);
3302  ObDereferenceObject(Section);
3303  return Status;
3304  }
3305 
3306  OldIrql = MiAcquirePfnLock();
3307  ImageSectionObject->SegFlags &= ~MM_SEGMENT_INCREATE;
3308 
3309  /* Take a ref on the file on behalf of the newly created structure */
3311 
3312  MiReleasePfnLock(OldIrql);
3313 
3314  Status = StatusExeFmt;
3315  }
3316  else
3317  {
3318  /* If FS driver called for delete, tell them it's not possible anymore. */
3319  ImageSectionObject->SegFlags &= ~MM_IMAGE_SECTION_FLUSH_DELETE;
3320 
3321  /* Take one ref */
3322  InterlockedIncrement64(&ImageSectionObject->RefCount);
3323  ImageSectionObject->SectionCount++;
3324 
3325  MiReleasePfnLock(OldIrql);
3326 
3327  Section->Segment = (PSEGMENT)ImageSectionObject;
3328 
3330  }
3331  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
3332  *SectionObject = Section;
3333  ASSERT(ImageSectionObject->RefCount > 0);
3334 
3335  return Status;
3336 }
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:3003
_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:3062
#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:4935
#define MM_SEGMENT_INCREATE
Definition: mm.h:240
return FALSE
Definition: section.c:5060
_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
union _SECTION::@2574 u
#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 2182 of file section.c.

2183 {
2184  PSECTION PhysSection;
2185  NTSTATUS Status;
2187  UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2188  LARGE_INTEGER SectionSize;
2189  HANDLE Handle;
2191 
2192  /*
2193  * Create the section mapping physical memory
2194  */
2195  SectionSize.QuadPart = MmHighestPhysicalPage * PAGE_SIZE;
2197  &Name,
2199  NULL,
2200  NULL);
2201  /*
2202  * Create the Object
2203  */
2206  &Obj,
2208  NULL,
2209  sizeof(*PhysSection),
2210  0,
2211  0,
2212  (PVOID*)&PhysSection);
2213  if (!NT_SUCCESS(Status))
2214  {
2215  DPRINT1("MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n", Status);
2216  return Status;
2217  }
2218 
2219  /*
2220  * Initialize it
2221  */
2222  RtlZeroMemory(PhysSection, sizeof(*PhysSection));
2223 
2224  /* Mark this as a "ROS Section" */
2225  PhysSection->u.Flags.filler = 1;
2227  PhysSection->u.Flags.PhysicalMemory = 1;
2228  PhysSection->SizeOfSection = SectionSize;
2231  if (Segment == NULL)
2232  {
2233  ObDereferenceObject(PhysSection);
2234  return STATUS_NO_MEMORY;
2235  }
2237  PhysSection->Segment = (PSEGMENT)Segment;
2238  Segment->RefCount = 1;
2239 
2240  Segment->ReferenceCount = &Segment->RefCount;
2241  Segment->Flags = &Segment->SegFlags;
2242 
2244  Segment->Image.FileOffset = 0;
2245  Segment->Protection = PAGE_EXECUTE_READWRITE;
2246  Segment->RawLength = SectionSize;
2247  Segment->Length = SectionSize;
2248  Segment->SegFlags = MM_PHYSICALMEMORY_SEGMENT;
2249  Segment->WriteCopy = FALSE;
2250  Segment->Image.VirtualAddress = 0;
2251  Segment->Image.Characteristics = 0;
2253 
2254  Status = ObInsertObject(PhysSection,
2255  NULL,
2257  0,
2258  NULL,
2259  &Handle);
2260  if (!NT_SUCCESS(Status))
2261  {
2262  ObDereferenceObject(PhysSection);
2263  return Status;
2264  }
2266 
2267  return STATUS_SUCCESS;
2268 }
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:3062
#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:4935
return FALSE
Definition: section.c:5060
_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:3379
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:2935
#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
union _SECTION::@2574 u
#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 4522 of file section.c.

4530 {
4531  NTSTATUS Status;
4532  ULONG Protection;
4533  PSECTION *SectionObject = (PSECTION *)Section;
4534  BOOLEAN FileLock = FALSE;
4535 
4536  /* Check if an ARM3 section is being created instead */
4538  {
4539  if (!(FileObject) && !(FileHandle))
4540  {
4541  return MmCreateArm3Section(Section,
4542  DesiredAccess,
4544  MaximumSize,
4546  AllocationAttributes &~ 1,
4547  FileHandle,
4548  FileObject);
4549  }
4550  }
4551 
4552  /* Convert section flag to page flag */
4554 
4555  /* Check to make sure the protection is correct. Nt* does this already */
4557  if (Protection == MM_INVALID_PROTECTION)
4558  {
4559  DPRINT1("Page protection is invalid\n");
4561  }
4562 
4563  /* Check if this is going to be a data or image backed file section */
4564  if ((FileHandle) || (FileObject))
4565  {
4566  /* These cannot be mapped with large pages */
4568  {
4569  DPRINT1("Large pages cannot be used with an image mapping\n");
4571  }
4572 
4573  /* Did the caller pass a file object ? */
4574  if (FileObject)
4575  {
4576  /* Reference the object directly */
4578 
4579  /* We don't create image mappings with file objects */
4581  }
4582  else
4583  {
4584  /* Reference the file handle to get the object */
4586  MmMakeFileAccess[Protection],
4589  (PVOID*)&FileObject,
4590  NULL);
4591  if (!NT_SUCCESS(Status))
4592  {
4593  DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
4594  return Status;
4595  }
4596 
4597  /* Lock the file */
4599  if (!NT_SUCCESS(Status))
4600  {
4602  return Status;
4603  }
4604 
4605  FileLock = TRUE;
4606 
4607  /* Deny access if there are writes on the file */
4608 #if 0
4610  {
4611  DPRINT1("Cannot create image maps with writers open on the file!\n");
4613  goto Quit;
4614  }
4615 #else
4617  DPRINT1("Creating image map with writers open on the file!\n");
4618 #endif
4619  }
4620  }
4621  else
4622  {
4623  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
4625  }
4626 
4628  {
4630  DesiredAccess,
4632  MaximumSize,
4635  FileObject);
4636  }
4637 #ifndef NEWCC
4638  else if (FileObject != NULL)
4639  {
4641  DesiredAccess,
4643  MaximumSize,
4646  FileObject,
4647  FileHandle != NULL);
4648  }
4649 #else
4650  else if (FileHandle != NULL || FileObject != NULL)
4651  {
4653  DesiredAccess,
4655  MaximumSize,
4658  FileObject);
4659  }
4660 #endif
4661  else
4662  {
4663  /* All cases should be handled above */
4665  }
4666 
4667  if (FileLock)
4669  if (FileObject)
4671 
4672  return Status;
4673 }
_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:3062
#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
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:4935
unsigned char BOOLEAN
return FALSE
Definition: section.c:5060
_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:3156
#define SEC_PHYSICALMEMORY
Definition: mm.h:112
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1230
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:2306
#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 5136 of file section.c.

5139 {
5140  PSECTION Section = _Section;
5141 
5142  /* It makes no sense to extend an image mapping */
5143  if (Section->u.Flags.Image)
5145 
5146  /* Nor is it possible to extend a page file mapping */
5147  if (!Section->u.Flags.File)
5149 
5150  if (!MiIsRosSectionObject(Section))
5151  return STATUS_NOT_IMPLEMENTED;
5152 
5153  /* We just extend the sizes. Shrinking is a no-op ? */
5154  if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5155  {
5157  Section->SizeOfSection = *NewSize;
5158 
5159  if (!Section->u.Flags.Reserve)
5160  {
5162  if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5163  {
5164  Segment->RawLength = *NewSize;
5165  Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5166  }
5168  }
5169  }
5170 
5171  return STATUS_SUCCESS;
5172 }
if(Entry==0)
Definition: section.c:4945
PSEGMENT Segment
Definition: mmtypes.h:809
#define MmLockSectionSegment(x)
Definition: mm.h:1380
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:1388
_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
union _SECTION::@2574 u
#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 4258 of file section.c.

4260 {
4261  switch(FlushType)
4262  {
4263  case MmFlushForDelete:
4264  {
4265  /*
4266  * FIXME: Check for outstanding write probes on Data section.
4267  * How do we do that ?
4268  */
4269  }
4270  /* Fall-through */
4271  case MmFlushForWrite:
4272  {
4273  KIRQL OldIrql = MiAcquirePfnLock();
4274  PMM_IMAGE_SECTION_OBJECT ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4275 
4276  DPRINT("Deleting or modifying %p\n", SectionObjectPointer);
4277 
4278  /* Wait for concurrent creation or deletion of image to be done */
4279  ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4280  while (ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INCREATE | MM_SEGMENT_INDELETE)))
4281  {
4282  MiReleasePfnLock(OldIrql);
4284  OldIrql = MiAcquirePfnLock();
4285  ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4286  }
4287 
4288  if (!ImageSectionObject)
4289  {
4290  DPRINT("No image section object. Accepting\n");
4291  /* Nothing to do */
4292  MiReleasePfnLock(OldIrql);
4293  return TRUE;
4294  }
4295 
4296  /* Do we have open sections or mappings on it ? */
4297  if ((ImageSectionObject->SectionCount) || (ImageSectionObject->MapCount))
4298  {
4299  /* We do. No way to delete it */
4300  MiReleasePfnLock(OldIrql);
4301  DPRINT("Denying. There are mappings open\n");
4302  return FALSE;
4303  }
4304 
4305  /* There are no sections open on it, but we must still have pages around. Discard everything */
4306  ImageSectionObject->SegFlags |= MM_IMAGE_SECTION_FLUSH_DELETE;
4307  InterlockedIncrement64(&ImageSectionObject->RefCount);
4308  MiReleasePfnLock(OldIrql);
4309 
4310  DPRINT("Purging\n");
4311 
4312  for (ULONG i = 0; i < ImageSectionObject->NrSegments; i++)
4313  {
4314  if (!MiPurgeImageSegment(&ImageSectionObject->Segments[i]))
4315  break;
4316  }
4317 
4318  /* Grab lock again */
4319  OldIrql = MiAcquirePfnLock();
4320 
4321  if (!(ImageSectionObject->SegFlags & MM_IMAGE_SECTION_FLUSH_DELETE))
4322  {
4323  /*
4324  * Someone actually created a section while we were not looking.
4325  * Drop our ref and deny.
4326  * MmDereferenceSegmentWithLock releases Pfn lock
4327  */
4328  MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4329  return FALSE;
4330  }
4331 
4332  /* We should be the last one holding a ref here. */
4333  ASSERT(ImageSectionObject->RefCount == 1);
4334  ASSERT(ImageSectionObject->SectionCount == 0);
4335 
4336  /* Dereference the first segment, this will free everything & release the lock */
4337  MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4338  return TRUE;
4339  }
4340  }
4341  return FALSE;
4342 }
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:4212
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:5060
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: