ReactOS  0.4.15-dev-5608-gafb953a
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))
 
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]
 
ACCESS_MASK MmMakeFileAccess [8]
 
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:5098
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

◆ _Requires_exclusive_lock_held_()

_Requires_exclusive_lock_held_ ( Segment->  Lock)

◆ _When_()

Definition at line 989 of file section.c.

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

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

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

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

2594 {
2595  NTSTATUS Status;
2597  ULONG AdjustOffset;
2598  ULONG OffsetAdjustment;
2599  ULONG BufferSize;
2600  ULONG UsedSize;
2601  PVOID Buffer;
2604 
2606 
2607  if(Length == 0)
2608  {
2609  KeBugCheck(MEMORY_MANAGEMENT);
2610  }
2611 
2612  FileOffset = *Offset;
2613 
2614  /* Negative/special offset: it cannot be used in this context */
2615  if(FileOffset.u.HighPart < 0)
2616  {
2617  KeBugCheck(MEMORY_MANAGEMENT);
2618  }
2619 
2620  AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
2621  OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
2622  FileOffset.u.LowPart = AdjustOffset;
2623 
2624  BufferSize = Length + OffsetAdjustment;
2626 
2627  /*
2628  * It's ok to use paged pool, because this is a temporary buffer only used in
2629  * the loading of executables. The assumption is that MmCreateSection is
2630  * always called at low IRQLs and that these buffers don't survive a brief
2631  * initialization phase
2632  */
2634  if (!Buffer)
2635  {
2637  }
2638 
2640 
2641  UsedSize = (ULONG)Iosb.Information;
2642 
2643  if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
2644  {
2647  }
2648 
2649  if(NT_SUCCESS(Status))
2650  {
2651  *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
2652  *AllocBase = Buffer;
2653  *ReadSize = UsedSize - OffsetAdjustment;
2654  }
2655  else
2656  {
2657  ExFreePoolWithTag(Buffer, 'rXmM');
2658  }
2659 
2660  return Status;
2661 }
#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:4934
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:4929
#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 961 of file section.c.

962 {
965 
967 
969 
971 
972  /* This must be either a valid entry or nothing */
974 
975  /* There should be no reference anymore */
977 
979  /* If there is a page, this must be because it's still dirty */
980  ASSERT(Page != 0);
981 
982  /* Write the page */
983  if (IS_DIRTY_SSE(Entry))
984  MiWritePage(Segment, Offset->QuadPart, Page);
985 
987 }
#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:4943
PFN_NUMBER Page
Definition: section.c:4935
#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:239
_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 4944 of file section.c.

4949  {
4950  BOOLEAN DirtyAgain;
4951 
4952  /*
4953  * We got a dirty entry. This path is for the shared data,
4954  * be-it regular file maps or shared sections of DLLs
4955  */
4957  FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
4958 
4959  /* Insert the cleaned entry back. Mark it as write in progress, and clear the dirty bit. */
4961  Entry = WRITE_SSE(Entry);
4963 
4965 
4966  if (FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
4967  {
4969  KIRQL OldIrql;
4970 
4971  /* We have to write it back to the file. Tell the FS driver who we are */
4972  if (PageOut)
4973  {
4974  LARGE_INTEGER EndOffset = *Offset;
4975 
4977 
4978  /* We need to disable all APCs */
4980 
4981  EndOffset.QuadPart += PAGE_SIZE;
4983  &EndOffset,
4985  if (NT_SUCCESS(Status))
4986  {
4988  }
4989  else
4990  {
4991  /* Make sure we will not try to release anything */
4993  }
4994  }
4995  else
4996  {
4997  /* We don't have to lock. Say this is success */
4999  }
5000 
5001  /* Go ahead and write the page, if previous locking succeeded */
5002  if (NT_SUCCESS(Status))
5003  {
5004  DPRINT("Writing page at offset %I64d for file %wZ, Pageout: %s\n",
5005  Offset->QuadPart, &Segment->FileObject->FileName, PageOut ? "TRUE" : "FALSE");
5006  Status = MiWritePage(Segment, Offset->QuadPart, Page);
5007  }
5008 
5009  if (PageOut)
5010  {
5012  if (ResourceToRelease != NULL)
5013  {
5015  }
5017  }
5018  }
5019  else
5020  {
5021  /* This must only be called by the page-out path */
5022  ASSERT(PageOut);
5023 
5024  /* And this must be for a shared section in a DLL */
5025  ASSERT(FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
5026 
5027  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
5028  if (!SwapEntry)
5029  {
5030  SwapEntry = MmAllocSwapPage();
5031  }
5032 
5033  if (SwapEntry)
5034  {
5035  Status = MmWriteToSwapPage(SwapEntry, Page);
5036  if (NT_SUCCESS(Status))
5037  {
5038  MmSetSavedSwapEntryPage(Page, SwapEntry);
5039  }
5040  else
5041  {
5042  MmFreeSwapPage(SwapEntry);
5043  }
5044  }
5045  else
5046  {
5047  DPRINT1("Failed to allocate a swap page!\n");
5049  }
5050  }
5051 
5053 
5054  /* Get the entry again */
5057 
5058  if (!NT_SUCCESS(Status))
5059  {
5060  /* Damn, this failed. Consider this page as still dirty */
5061  DPRINT1("MiWritePage FAILED: Status 0x%08x!\n", Status);
5062  DirtyAgain = TRUE;
5063  }
5064  else
5065  {
5066  /* Check if someone dirtified this page while we were not looking */
5067  DirtyAgain = IS_DIRTY_SSE(Entry);
5068  }
5069 
5070  /* Drop the reference we got, deleting the write altogether. */
5072  if (DirtyAgain)
5073  {
5074  Entry = DIRTY_SSE(Entry);
5075  }
5077  }
VOID NTAPI FsRtlReleaseFileForModWrite(_In_ PFILE_OBJECT FileObject, _In_ PERESOURCE ResourceToRelease)
Unlock a file object after flushing pages to disk. To be called by the Modified Page Writer (MPW) aft...
Definition: fastio.c:1959
#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
_In_ PLARGE_INTEGER _Out_ struct _ERESOURCE ** ResourceToRelease
Definition: iotypes.h:1598
#define PFN_FROM_SSE(E)
Definition: mm.h:1351
#define MmLockSectionSegment(x)
Definition: mm.h:1380
#define DIRTY_SSE(E)
Definition: mm.h:1358
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#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:4935
#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:322
PLARGE_INTEGER BOOLEAN BOOLEAN PageOut
Definition: section.c:4932
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define MM_DATAFILE_SEGMENT
Definition: mm.h:238
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define PAGE_FROM_SSE(E)
Definition: mm.h:1366
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
NTSTATUS NTAPI MiWritePage(PMM_SECTION_SEGMENT Segment, LONGLONG SegOffset, PFN_NUMBER Page)
Definition: section.c:239
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SWAPENTRY
Definition: mm.h:56
PLARGE_INTEGER Offset
Definition: section.c:4929
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
VOID NTAPI KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql)
Definition: spinlock.c:27
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1368
_Check_return_ NTSTATUS NTAPI FsRtlAcquireFileForModWriteEx(_In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER EndingOffset, _Outptr_result_maybenull_ PERESOURCE *ResourceToRelease)
Lock a file object before flushing pages to disk. To be called by the Modified Page Writer (MPW)
Definition: fastio.c:1852
#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:147
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39
#define APC_LEVEL
Definition: env_spec_w32.h:695
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI MmFreeSwapPage(SWAPENTRY Entry)
Definition: pagefile.c:291
LONGLONG QuadPart
Definition: typedefs.h:114
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 5080 of file section.c.

5081  {
5082  ULONG_PTR NewEntry = 0;
5083  /* Restore the swap entry here */
5084  if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
5085  {
5086  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
5087  if (SwapEntry)
5088  NewEntry = MAKE_SWAP_SSE(SwapEntry);
5089  }
5090 
5091  /* Yes. Release it */
5094  /* Tell the caller we released the page */
5095  return TRUE;
5096  }
#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:4935
_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().

◆ MiCopyFromUserPage()

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

Definition at line 1171 of file section.c.

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

Referenced by MmAccessFaultSectionView().

◆ MiGrabDataSection()

static PMM_SECTION_SEGMENT MiGrabDataSection ( PSECTION_OBJECT_POINTERS  SectionObjectPointer)
static

Definition at line 91 of file section.c.

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

4212 {
4214 
4216 
4217  /* Loop over all entries */
4218  for (PageTable = RtlEnumerateGenericTable(&Segment->PageTable, TRUE);
4219  PageTable != NULL;
4221  {
4222  for (ULONG i = 0; i < _countof(PageTable->PageEntries); i++)
4223  {
4224  ULONG_PTR Entry = PageTable->PageEntries[i];
4226 
4227  if (!Entry)
4228  continue;
4229 
4231  {
4232  /* I/O ongoing or swap entry. Someone mapped this file as we were not looking */
4234  return FALSE;
4235  }
4236 
4237  /* Regular entry */
4240 
4241  /* Properly remove using the used API */
4242  Offset.QuadPart = PageTable->FileOffset.QuadPart + (i << PAGE_SHIFT);
4245  }
4246  }
4247 
4249 
4250  return TRUE;
4251 }
#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:5098
#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:4929
#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 4458 of file section.c.

4459 {
4460  DPRINT("MmUnmapViewInSystemSpace() called\n");
4461 
4463 }
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:3503
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 3567 of file section.c.

3570 {
3571  NTSTATUS Status;
3574  PVOID ImageBaseAddress = 0;
3575 
3576  DPRINT("Opening memory area Process %p BaseAddress %p\n",
3577  Process, BaseAddress);
3578 
3579  ASSERT(Process);
3580 
3582 
3584  BaseAddress);
3585  if (MemoryArea == NULL ||
3586 #ifdef NEWCC
3587  ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) && (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
3588 #else
3590 #endif
3592 
3593  {
3595 
3596  DPRINT1("Unable to find memory area at address %p.\n", BaseAddress);
3597  return STATUS_NOT_MAPPED_VIEW;
3598  }
3599 
3601  {
3602  ULONG i;
3603  ULONG NrSegments;
3604  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3605  PMM_SECTION_SEGMENT SectionSegments;
3607 
3608  Segment = MemoryArea->SectionData.Segment;
3609  ImageSectionObject = ImageSectionObjectFromSegment(Segment);
3610  SectionSegments = ImageSectionObject->Segments;
3611  NrSegments = ImageSectionObject->NrSegments;
3612 
3614 
3615  /* Search for the current segment within the section segments
3616  * and calculate the image base address */
3617  for (i = 0; i < NrSegments; i++)
3618  {
3619  if (Segment == &SectionSegments[i])
3620  {
3621  ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
3622  break;
3623  }
3624  }
3625  if (i >= NrSegments)
3626  {
3627  KeBugCheck(MEMORY_MANAGEMENT);
3628  }
3629 
3630  for (i = 0; i < NrSegments; i++)
3631  {
3632  PVOID SBaseAddress = (PVOID)
3633  ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
3634 
3635  Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
3636  if (!NT_SUCCESS(Status))
3637  {
3638  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3639  SBaseAddress, Process, Status);
3641  }
3642  }
3643  DPRINT("One mapping less for %p\n", ImageSectionObject->FileObject->SectionObjectPointer);
3644  InterlockedDecrement(&ImageSectionObject->MapCount);
3645  }
3646  else
3647  {
3649  if (!NT_SUCCESS(Status))
3650  {
3651  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3654  }
3655  }
3656 
3657  /* Notify debugger */
3658  if (ImageBaseAddress && !SkipDebuggerNotify) DbgkUnMapViewOfSection(ImageBaseAddress);
3659 
3660  return STATUS_SUCCESS;
3661 }
struct _MM_SECTION_SEGMENT::@1753 Image
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:3503
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:4934
void * PVOID
Definition: retypes.h:9
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
union _MMVAD::@2569 u
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
struct _MEMORY_AREA::@1754 SectionData
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
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:262
#define ULONG_PTR
Definition: config.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:37
ULONG_PTR VadType
Definition: mmtypes.h:691

Referenced by MiRosCleanupMemoryArea(), and MiUnmapViewOfSection().

◆ MiWritePage()

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

Definition at line 239 of file section.c.

249 {
252  KEVENT Event;
253  UCHAR MdlBase[sizeof(MDL) + sizeof(PFN_NUMBER)];
254  PMDL Mdl = (PMDL)MdlBase;
255  PFILE_OBJECT FileObject = Segment->FileObject;
257 
258  FileOffset.QuadPart = Segment->Image.FileOffset + SegOffset;
259 
260  RtlZeroMemory(MdlBase, sizeof(MdlBase));
263  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
264 
267  if (Status == STATUS_PENDING)
268  {
270  Status = IoStatus.Status;
271  }
272  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
273  {
274  MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
275  }
276 
277  return Status;
278 }
#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:4934
return FALSE
Definition: section.c:5098
PFN_NUMBER Page
Definition: section.c:4935
_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:111
* 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 1891 of file section.c.

1895 {
1897  PFN_NUMBER OldPage;
1898  PFN_NUMBER NewPage;
1899  PFN_NUMBER UnmappedPage;
1900  PVOID PAddress;
1903  ULONG_PTR Entry;
1905  BOOLEAN Cow = FALSE;
1906  ULONG NewProtect;
1907  BOOLEAN Unmapped;
1908 
1909  DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1910 
1911  /* Get the region for this address */
1913  &MemoryArea->SectionData.RegionListHead,
1914  Address, NULL);
1915  ASSERT(Region != NULL);
1916  if (!(Region->Protect & PAGE_IS_WRITABLE))
1917  return STATUS_ACCESS_VIOLATION;
1918 
1919  /* Make sure we have a page mapping for this address. */
1921  {
1923  if (!NT_SUCCESS(Status))
1924  {
1925  /* This is invalid access ! */
1926  return Status;
1927  }
1928  }
1929 
1930  /*
1931  * Check if the page has already been set readwrite
1932  */
1934  {
1935  DPRINT("Address 0x%p\n", Address);
1936  return STATUS_SUCCESS;
1937  }
1938 
1939  /* Check if we are doing Copy-On-Write */
1940  Segment = MemoryArea->SectionData.Segment;
1941  Cow = Segment->WriteCopy || (Region->Protect & PAGE_IS_WRITECOPY);
1942 
1943  if (!Cow)
1944  {
1945  /* Simply update page protection and we're done */
1946  MmSetPageProtect(Process, Address, Region->Protect);
1947  return STATUS_SUCCESS;
1948  }
1949 
1950  /* Calculate the new protection & check if we should update the region */
1951  NewProtect = Region->Protect;
1953  {
1955  if (Region->Protect & PAGE_IS_EXECUTABLE)
1957  else
1960  &MemoryArea->SectionData.RegionListHead,
1963  }
1964 
1965  /*
1966  * Find the offset of the page
1967  */
1968  PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1969  Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1970  + MemoryArea->SectionData.ViewOffset;
1971 
1972  /* Get the page mapping this section offset. */
1975 
1976  /* Get the current page mapping for the process */
1977  ASSERT(MmIsPagePresent(Process, PAddress));
1978  OldPage = MmGetPfnForProcess(Process, PAddress);
1979  ASSERT(OldPage != 0);
1980 
1981  if (IS_SWAP_FROM_SSE(Entry) ||
1982  PFN_FROM_SSE(Entry) != OldPage)
1983  {
1985  /* This is a private page. We must only change the page protection. */
1986  MmSetPageProtect(Process, PAddress, NewProtect);
1987  return STATUS_SUCCESS;
1988  }
1989 
1990  /*
1991  * Allocate a page
1992  */
1994  {
1995  KeBugCheck(MEMORY_MANAGEMENT);
1996  }
1997 
1998  /*
1999  * Copy the old page
2000  */
2001  NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
2002 
2003  /*
2004  * Unshare the old page.
2005  */
2006  DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
2007  Unmapped = MmDeleteVirtualMapping(Process, PAddress, NULL, &UnmappedPage);
2008  if (!Unmapped || (UnmappedPage != OldPage))
2009  {
2010  /* Uh , we had a page just before, but suddenly it changes. Someone corrupted us. */
2011  KeBugCheckEx(MEMORY_MANAGEMENT,
2012  (ULONG_PTR)Process,
2013  (ULONG_PTR)PAddress,
2014  (ULONG_PTR)__FILE__,
2015  __LINE__);
2016  }
2017 
2018  if (Process)
2019  MmDeleteRmap(OldPage, Process, PAddress);
2022 
2023  /*
2024  * Set the PTE to point to the new page
2025  */
2026  if (!NT_SUCCESS(MmCreateVirtualMapping(Process, PAddress, NewProtect, NewPage)))
2027  {
2028  DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2029  KeBugCheck(MEMORY_MANAGEMENT);
2030  }
2031 
2032  if (Process)
2033  MmInsertRmap(NewPage, Process, PAddress);
2034 
2035  DPRINT("Address 0x%p\n", Address);
2036  return STATUS_SUCCESS;
2037 }
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:1439
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:1090
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:1525
NTSTATUS Status
Definition: section.c:4934
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
Entry
Definition: section.c:4943
return FALSE
Definition: section.c:5098
#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
struct _MEMORY_AREA::@1754 SectionData
#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:4929
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:1171
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:82
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 1439 of file section.c.

1446 {
1449  BOOLEAN DoCOW = FALSE;
1450  ULONG i;
1452 
1454  ASSERT(MemoryArea != NULL);
1455  Segment = MemoryArea->SectionData.Segment;
1457 
1458  if ((Segment->WriteCopy) &&
1460  {
1461  DoCOW = TRUE;
1462  }
1463 
1464  if (OldProtect != NewProtect)
1465  {
1466  for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
1467  {
1468  SWAPENTRY SwapEntry;
1469  PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE);
1471 
1472  /* Wait for a wait entry to disappear */
1473  do
1474  {
1475  MmGetPageFileMapping(Process, Address, &SwapEntry);
1476  if (SwapEntry != MM_WAIT_ENTRY)
1477  break;
1480  YieldProcessor();
1483  }
1484  while (TRUE);
1485 
1486  /*
1487  * If we doing COW for this segment then check if the page is
1488  * already private.
1489  */
1491  {
1493  ULONG_PTR Entry;
1494  PFN_NUMBER Page;
1495 
1497  + MemoryArea->SectionData.ViewOffset;
1499  /*
1500  * An MM_WAIT_ENTRY is ok in this case... It'll just count as
1501  * IS_SWAP_FROM_SSE and we'll do the right thing.
1502  */
1504 
1507  {
1508  Protect = NewProtect;
1509  }
1510  }
1511 
1513  {
1515  Protect);
1516  }
1517  }
1518  }
1519 
1521 }
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h: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:4943
return FALSE
Definition: section.c:5098
PFN_NUMBER Page
Definition: section.c:4935
#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)
struct _MEMORY_AREA::@1754 SectionData
#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:4929
#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 * 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 4676 of file section.c.

4680 {
4682  BOOLEAN Ret = TRUE;
4684  LARGE_INTEGER SegmentOffset, RangeEnd;
4686 
4688 
4690  if (MemoryArea == NULL)
4691  {
4693  return FALSE;
4694  }
4695 
4696  /* Only supported in old Mm for now */
4698  /* For file mappings */
4700 
4701  Segment = MemoryArea->SectionData.Segment;
4703 
4705  + MemoryArea->SectionData.ViewOffset;
4707  + MemoryArea->SectionData.ViewOffset;
4708 
4709  while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
4710  {
4712  if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4713  {
4714  Ret = FALSE;
4715  break;
4716  }
4717  SegmentOffset.QuadPart += PAGE_SIZE;
4718  }
4719 
4721 
4723  return Ret;
4724 }
#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:5098
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
#define MmUnlockSectionSegment(x)
Definition: mm.h:1388
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
union _MMVAD::@2569 u
MMVAD VadNode
Definition: mm.h:249
struct _MEMORY_AREA::@1754 SectionData
#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
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:37
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h: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 4163 of file section.c.

4165 {
4166  BOOLEAN Ret;
4168 
4169  /* Check whether an ImageSectionObject exists */
4170  if (SectionObjectPointer->ImageSectionObject != NULL)
4171  {
4172  DPRINT1("ERROR: File can't be truncated because it has an image section\n");
4173  return FALSE;
4174  }
4175 
4177  if (!Segment)
4178  {
4179  /* There is no data section. It's fine to do anything. */
4180  return TRUE;
4181  }
4182 
4184  if ((Segment->SectionCount == 0) ||
4185  ((Segment->SectionCount == 1) && (SectionObjectPointer->SharedCacheMap != NULL)))
4186  {
4187  /* If the cache is the only one holding a reference to the segment, then it's fine to resize */
4188  Ret = TRUE;
4189  }
4190  else
4191  {
4192  /* We can't shrink, but we can extend */
4193  Ret = NewFileSize->QuadPart >= Segment->RawLength.QuadPart;
4194 #if DBG
4195  if (!Ret)
4196  {
4197  DPRINT1("Cannot truncate data: New Size %I64d, Segment Size %I64d\n", NewFileSize->QuadPart, Segment->RawLength.QuadPart);
4198  }
4199 #endif
4200  }
4202  MmDereferenceSegment(Segment);
4203 
4204  DPRINT("FIXME: didn't check for outstanding write probes\n");
4205 
4206  return Ret;
4207 }
#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:5098
#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 2468 of file section.c.

2476 {
2477  SECTION Section;
2478  PSECTION NewSection;
2479  PSUBSECTION Subsection;
2480  PSEGMENT NewSegment, Segment;
2481  NTSTATUS Status;
2482  PCONTROL_AREA ControlArea;
2483  ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2485  BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2486  KIRQL OldIrql;
2488  BOOLEAN UserRefIncremented = FALSE;
2489  PVOID PreviousSectionPointer;
2490 
2491  /* Make the same sanity checks that the Nt interface should've validated */
2494  SEC_NO_CHANGE)) == 0);
2498  SEC_NOCACHE | SEC_NO_CHANGE))));
2504 
2505  /* Convert section flag to page flag */
2508 
2509  /* Check to make sure the protection is correct. Nt* does this already */
2510  ProtectionMask = MiMakeProtectionMask(SectionPageProtection);
2511  if (ProtectionMask == MM_INVALID_PROTECTION)
2512  {
2513  DPRINT1("Invalid protection mask\n");
2515  }
2516 
2517  /* Check if this is going to be a data or image backed file section */
2518  if ((FileHandle) || (FileObject))
2519  {
2520  /* These cannot be mapped with large pages */
2522 
2523  /* For now, only support the mechanism through a file handle */
2524  ASSERT(FileObject == NULL);
2525 
2526  /* Reference the file handle to get the object */
2528  MmMakeFileAccess[ProtectionMask],
2530  PreviousMode,
2531  (PVOID*)&File,
2532  NULL);
2533  if (!NT_SUCCESS(Status)) return Status;
2534 
2535  /* Make sure Cc has been doing its job */
2536  if (!File->SectionObjectPointer)
2537  {
2538  /* This is not a valid file system-based file, fail */
2541  }
2542 
2543  /* Image-file backed sections are not yet supported */
2545 
2546  /* Compute the size of the control area, and allocate it */
2547  ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2548  ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2549  if (!ControlArea)
2550  {
2553  }
2554 
2555  /* Zero it out */
2556  RtlZeroMemory(ControlArea, ControlAreaSize);
2557 
2558  /* Did we get a handle, or an object? */
2559  if (FileHandle)
2560  {
2561  /* We got a file handle so we have to lock down the file */
2562 #if 0
2564  if (!NT_SUCCESS(Status))
2565  {
2566  ExFreePool(ControlArea);
2568  return Status;
2569  }
2570 #else
2571  /* ReactOS doesn't support this API yet, so do nothing */
2573 #endif
2574  /* Update the top-level IRP so that drivers know what's happening */
2576  FileLock = TRUE;
2577  }
2578 
2579  /* Lock the PFN database while we play with the section pointers */
2580  OldIrql = MiAcquirePfnLock();
2581 
2582  /* Image-file backed sections are not yet supported */
2584 
2585  /* There should not already be a control area for this file */
2586  ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2587  NewSegment = NULL;
2588 
2589  /* Write down that this CA is being created, and set it */
2590  ControlArea->u.Flags.BeingCreated = TRUE;
2592  PreviousSectionPointer = File->SectionObjectPointer;
2593  File->SectionObjectPointer->DataSectionObject = ControlArea;
2594 
2595  /* We can release the PFN lock now */
2596  MiReleasePfnLock(OldIrql);
2597 
2598  /* We don't support previously-mapped file */
2599  ASSERT(NewSegment == NULL);
2600 
2601  /* Image-file backed sections are not yet supported */
2603 
2604  /* So we always create a data file map */
2606  &Segment,
2607  (PSIZE_T)InputMaximumSize,
2610  KernelCall);
2611  if (!NT_SUCCESS(Status))
2612  {
2613  /* Lock the PFN database while we play with the section pointers */
2614  OldIrql = MiAcquirePfnLock();
2615 
2616  /* Reset the waiting-for-deletion event */
2617  ASSERT(ControlArea->WaitingForDeletion == NULL);
2618  ControlArea->WaitingForDeletion = NULL;
2619 
2620  /* Set the file pointer NULL flag */
2621  ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2622  ControlArea->u.Flags.FilePointerNull = TRUE;
2623 
2624  /* Delete the data section object */
2626  File->SectionObjectPointer->DataSectionObject = NULL;
2627 
2628  /* No longer being created */
2629  ControlArea->u.Flags.BeingCreated = FALSE;
2630 
2631  /* We can release the PFN lock now */
2632  MiReleasePfnLock(OldIrql);
2633 
2634  /* Check if we locked and set the IRP */
2635  if (FileLock)
2636  {
2637  /* Undo */
2639  //FsRtlReleaseFile(File);
2640  }
2641 
2642  /* Free the control area and de-ref the file object */
2643  ExFreePool(ControlArea);
2645 
2646  /* All done */
2647  return Status;
2648  }
2649 
2650  /* On success, we expect this */
2651  ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2652 
2653  /* Check if a maximum size was specified */
2654  if (!InputMaximumSize->QuadPart)
2655  {
2656  /* Nope, use the segment size */
2657  Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2658  }
2659  else
2660  {
2661  /* Yep, use the entered size */
2662  Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2663  }
2664  }
2665  else
2666  {
2667  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2669 
2670  /* Not yet supported */
2672 
2673  /* So this must be a pagefile-backed section, create the mappings needed */
2674  Status = MiCreatePagingFileMap(&NewSegment,
2675  InputMaximumSize,
2676  ProtectionMask,
2678  if (!NT_SUCCESS(Status)) return Status;
2679 
2680  /* Set the size here, and read the control area */
2681  Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2682  ControlArea = NewSegment->ControlArea;
2683 
2684  /* MiCreatePagingFileMap increments user references */
2685  UserRefIncremented = TRUE;
2686  }
2687 
2688  /* Did we already have a segment? */
2689  if (!NewSegment)
2690  {
2691  /* This must be the file path and we created a segment */
2692  NewSegment = Segment;
2693  ASSERT(File != NULL);
2694 
2695  /* Acquire the PFN lock while we set control area flags */
2696  OldIrql = MiAcquirePfnLock();
2697 
2698  /* We don't support this race condition yet, so assume no waiters */
2699  ASSERT(ControlArea->WaitingForDeletion == NULL);
2700  ControlArea->WaitingForDeletion = NULL;
2701 
2702  /* Image-file backed sections are not yet supported, nor ROM images */
2704  ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2705 
2706  /* Take off the being created flag, and then release the lock */
2707  ControlArea->u.Flags.BeingCreated = FALSE;
2708  MiReleasePfnLock(OldIrql);
2709  }
2710 
2711  /* Check if we locked the file earlier */
2712  if (FileLock)
2713  {
2714  /* Reset the top-level IRP and release the lock */
2716  //FsRtlReleaseFile(File);
2717  FileLock = FALSE;
2718  }
2719 
2720  /* Set the initial section object data */
2721  Section.InitialPageProtection = SectionPageProtection;
2722 
2723  /* The mapping created a control area and segment, save the flags */
2724  Section.Segment = NewSegment;
2725  Section.u.LongFlags = ControlArea->u.LongFlags;
2726 
2727  /* Check if this is a user-mode read-write non-image file mapping */
2728  if (!(FileObject) &&
2730  !(ControlArea->u.Flags.Image) &&
2731  (ControlArea->FilePointer))
2732  {
2733  /* Add a reference and set the flag */
2734  Section.u.Flags.UserWritable = TRUE;
2735  InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2736  }
2737 
2738  /* Check for image mappings or page file mappings */
2739  if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2740  {
2741  /* Charge the segment size, and allocate a subsection */
2742  PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2743  Size = sizeof(SUBSECTION);
2744  }
2745  else
2746  {
2747  /* Charge nothing, and allocate a mapped subsection */
2748  PagedCharge = 0;
2749  Size = sizeof(MSUBSECTION);
2750  }
2751 
2752  /* Check if this is a normal CA */
2753  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2754  ASSERT(ControlArea->u.Flags.Rom == 0);
2755 
2756  /* Charge only a CA, and the subsection is right after */
2757  NonPagedCharge = sizeof(CONTROL_AREA);
2758  Subsection = (PSUBSECTION)(ControlArea + 1);
2759 
2760  /* We only support single-subsection mappings */
2761  NonPagedCharge += Size;
2762  ASSERT(Subsection->NextSubsection == NULL);
2763 
2764  /* Create the actual section object, with enough space for the prototype PTEs */
2768  PreviousMode,
2769  NULL,
2770  sizeof(SECTION),
2771  PagedCharge,
2772  NonPagedCharge,
2773  (PVOID*)&NewSection);
2774  if (!NT_SUCCESS(Status))
2775  {
2776  /* Check if this is a user-mode read-write non-image file mapping */
2777  if (!(FileObject) &&
2779  !(ControlArea->u.Flags.Image) &&
2780  (ControlArea->FilePointer))
2781  {
2782  /* Remove a reference and check the flag */
2783  ASSERT(Section.u.Flags.UserWritable == 1);
2784  InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2785  }
2786 
2787  /* Check if a user reference was added */
2788  if (UserRefIncremented)
2789  {
2790  /* Acquire the PFN lock while we change counters */
2791  OldIrql = MiAcquirePfnLock();
2792 
2793  /* Decrement the accounting counters */
2794  ControlArea->NumberOfSectionReferences--;
2795  ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2796  ControlArea->NumberOfUserReferences--;
2797 
2798  /* Check if we should destroy the CA and release the lock */
2799  MiCheckControlArea(ControlArea, OldIrql);
2800  }
2801 
2802  /* Return the failure code */
2803  return Status;
2804  }
2805 
2806  /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2807 
2808  /* Now copy the local section object from the stack into this new object */
2809  RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2810  NewSection->Address.StartingVpn = 0;
2811 
2812  /* For now, only user calls are supported */
2813  ASSERT(KernelCall == FALSE);
2814  NewSection->u.Flags.UserReference = TRUE;
2815 
2816  /* Is this a "based" allocation, in which all mappings are identical? */
2818  {
2819  /* Lock the VAD tree during the search */
2821 
2822  /* Is it a brand new ControArea ? */
2823  if (ControlArea->u.Flags.BeingCreated == 1)
2824  {
2825  ASSERT(ControlArea->u.Flags.Based == 1);
2826  /* Then we must find a global address, top-down */
2829  _64K,
2831  (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2832 
2833  if (!NT_SUCCESS(Status))
2834  {
2835  /* No way to find a valid range. */
2837  ControlArea->u.Flags.Based = 0;
2838  NewSection->u.Flags.Based = 0;
2839  ObDereferenceObject(NewSection);
2840  return Status;
2841  }
2842 
2843  /* Compute the ending address and insert it into the VAD tree */
2844  NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2845  NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2846  MiInsertBasedSection(NewSection);
2847  }
2848  else
2849  {
2850  /* 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 !*/
2851  ASSERT(FALSE);
2852  }
2853 
2855  }
2856 
2857  /* The control area is not being created anymore */
2858  if (ControlArea->u.Flags.BeingCreated == 1)
2859  {
2860  /* Acquire the PFN lock while we set control area flags */
2861  OldIrql = MiAcquirePfnLock();
2862 
2863  /* Take off the being created flag, and then release the lock */
2864  ControlArea->u.Flags.BeingCreated = 0;
2865  NewSection->u.Flags.BeingCreated = 0;
2866 
2867  MiReleasePfnLock(OldIrql);
2868  }
2869 
2870  /* Migrate the attribute into a flag */
2871  if (AllocationAttributes & SEC_NO_CHANGE) NewSection->u.Flags.NoChange = TRUE;
2872 
2873  /* If R/W access is not requested, this might eventually become a CoW mapping */
2875  {
2876  NewSection->u.Flags.CopyOnWrite = TRUE;
2877  }
2878 
2879  /* Write down if this was a kernel call */
2880  ControlArea->u.Flags.WasPurged |= KernelCall;
2881  ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2882 
2883  /* Make sure the segment and the section are the same size, or the section is smaller */
2884  ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2885 
2886  /* Return the object and the creation status */
2887  *SectionObject = (PVOID)NewSection;
2888  return Status;
2889 }
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
union _SECTION::@2578 u
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
ULONGLONG SizeOfSegment
Definition: mmtypes.h:410
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
ULONG UserReference
Definition: mmtypes.h:476
ULONG NumberOfSectionReferences
Definition: mmtypes.h:520
PSEGMENT Segment
Definition: mmtypes.h:809
NTSTATUS NTAPI MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1536
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:1552
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:4934
union _CONTROL_AREA::@2562 u
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
return FALSE
Definition: section.c:5098
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:140
#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:714
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
PVOID BasedAddress
Definition: mmtypes.h:415
PVOID MmHighSectionBase
Definition: section.c:111
ULONG WasPurged
Definition: mmtypes.h:475
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define SEC_IMAGE
Definition: mmtypes.h:96
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
Definition: File.h:15
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID _In_ LONG _In_z_ PCHAR File
Definition: wdfdevice.h:4061
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
ULONG BeingCreated
Definition: mmtypes.h:461
LONGLONG QuadPart
Definition: typedefs.h:114
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by MmCreateSection().

◆ MmCreateDataFileSection()

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

Definition at line 2305 of file section.c.

2316 {
2317  PSECTION Section;
2318  NTSTATUS Status;
2321  KIRQL OldIrql;
2322 
2323  /*
2324  * Create the section
2325  */
2330  NULL,
2331  sizeof(*Section),
2332  0,
2333  0,
2334  (PVOID*)&Section);
2335  if (!NT_SUCCESS(Status))
2336  {
2337  return Status;
2338  }
2339  /*
2340  * Initialize it
2341  */
2342  RtlZeroMemory(Section, sizeof(*Section));
2343 
2344  /* Mark this as a "ROS" section */
2345  Section->u.Flags.filler = 1;
2347  Section->u.Flags.File = 1;
2348 
2350  Section->u.Flags.NoChange = 1;
2352  Section->u.Flags.Reserve = 1;
2353 
2354  if (!GotFileHandle)
2355  {
2356  ASSERT(UMaximumSize != NULL);
2357  // ASSERT(UMaximumSize->QuadPart != 0);
2358  MaximumSize = *UMaximumSize;
2359  }
2360  else
2361  {
2364  if (!NT_SUCCESS(Status))
2365  {
2366  ObDereferenceObject(Section);
2367  return Status;
2368  }
2369 
2370  /*
2371  * FIXME: Revise this once a locking order for file size changes is
2372  * decided
2373  */
2374  if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
2375  {
2376  MaximumSize = *UMaximumSize;
2377  }
2378  else
2379  {
2381  /* Mapping zero-sized files isn't allowed. */
2382  if (MaximumSize.QuadPart == 0)
2383  {
2384  ObDereferenceObject(Section);
2386  }
2387  }
2388 
2389  if (MaximumSize.QuadPart > FileSize.QuadPart)
2390  {
2393  sizeof(LARGE_INTEGER),
2394  &MaximumSize);
2395  if (!NT_SUCCESS(Status))
2396  {
2397  ObDereferenceObject(Section);
2399  }
2400  }
2401  }
2402 
2403  if (FileObject->SectionObjectPointer == NULL)
2404  {
2405  ObDereferenceObject(Section);
2407  }
2408 
2409  /*
2410  * Lock the file
2411  */
2413  if (Status != STATUS_SUCCESS)
2414  {
2415  ObDereferenceObject(Section);
2416  return Status;
2417  }
2418 
2419  /* Lock the PFN lock while messing with Section Object pointers */
2420 grab_segment:
2421  OldIrql = MiAcquirePfnLock();
2422  Segment = FileObject->SectionObjectPointer->DataSectionObject;
2423 
2424  while (Segment && (Segment->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
2425  {
2426  MiReleasePfnLock(OldIrql);
2428  OldIrql = MiAcquirePfnLock();
2429  Segment = FileObject->SectionObjectPointer->DataSectionObject;
2430  }
2431 
2432  /*
2433  * If this file hasn't been mapped as a data file before then allocate a
2434  * section segment to describe the data file mapping
2435  */
2436  if (Segment == NULL)
2437  {
2438  /* Release the lock. ExAllocatePoolWithTag might acquire it */
2439  MiReleasePfnLock(OldIrql);
2440 
2443  if (Segment == NULL)
2444  {
2445  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2446  ObDereferenceObject(Section);
2447  return STATUS_NO_MEMORY;
2448  }
2449 
2450  /* We are creating it */
2451  RtlZeroMemory(Segment, sizeof(*Segment));
2453  Segment->RefCount = 1;
2454 
2455  /* Acquire lock again */
2456  OldIrql = MiAcquirePfnLock();
2457 
2458  if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
2459  {
2460  /* Well that's bad luck. Restart it all over */
2461  MiReleasePfnLock(OldIrql);
2463  goto grab_segment;
2464  }
2465 
2466  FileObject->SectionObjectPointer->DataSectionObject = Segment;
2467 
2468  /* We're safe to release the lock now */
2469  MiReleasePfnLock(OldIrql);
2470 
2471  Section->Segment = (PSEGMENT)Segment;
2472 
2473  /* Self-referencing segment */
2474  Segment->Flags = &Segment->SegFlags;
2475  Segment->ReferenceCount = &Segment->RefCount;
2476 
2477  Segment->SectionCount = 1;
2478 
2480  Segment->FileObject = FileObject;
2482 
2483  Segment->Image.FileOffset = 0;
2484  Segment->Protection = SectionPageProtection;
2485 
2486  Segment->Image.Characteristics = 0;
2489  {
2490  Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
2491  }
2492  else
2493  {
2494  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2495  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2496  }
2497  Segment->Image.VirtualAddress = 0;
2499 
2500  /* We're good to use it now */
2501  OldIrql = MiAcquirePfnLock();
2502  Segment->SegFlags &= ~MM_SEGMENT_INCREATE;
2503  MiReleasePfnLock(OldIrql);
2504  }
2505  else
2506  {
2507  Section->Segment = (PSEGMENT)Segment;
2508  InterlockedIncrement64(&Segment->RefCount);
2509  InterlockedIncrementUL(&Segment->SectionCount);
2510 
2511  MiReleasePfnLock(OldIrql);
2512 
2514 
2515  if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
2517  {
2518  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2519  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2520  }
2521 
2523  }
2524  Section->SizeOfSection = MaximumSize;
2525 
2526  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2527  *SectionObject = Section;
2528  return STATUS_SUCCESS;
2529 }
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
union _SECTION::@2578 u
_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:4934
#define MM_SEGMENT_INCREATE
Definition: mm.h:240
return FALSE
Definition: section.c:5098
#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:908
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
struct _SEGMENT * PSEGMENT
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:114
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1526
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define MM_SEGMENT_INDELETE
Definition: mm.h:239
#define NULL
Definition: types.h:112
#define STATUS_SECTION_NOT_EXTENDED
Definition: ntstatus.h:371
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
#define ObReferenceObject
Definition: obfuncs.h:204
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_MAPPED_FILE_SIZE_ZERO
Definition: ntstatus.h:522
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by MmCreateSection().

◆ MmCreateImageSection()

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

Definition at line 3155 of file section.c.

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

Referenced by MmCreateSection().

◆ MmCreatePhysicalMemorySection()

NTSTATUS NTAPI MmCreatePhysicalMemorySection ( VOID  )

Definition at line 2181 of file section.c.

2182 {
2183  PSECTION PhysSection;
2184  NTSTATUS Status;
2186  UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2187  LARGE_INTEGER SectionSize;
2188  HANDLE Handle;
2190 
2191  /*
2192  * Create the section mapping physical memory
2193  */
2194  SectionSize.QuadPart = MmHighestPhysicalPage * PAGE_SIZE;
2196  &Name,
2198  NULL,
2199  NULL);
2200  /*
2201  * Create the Object
2202  */
2205  &Obj,
2207  NULL,
2208  sizeof(*PhysSection),
2209  0,
2210  0,
2211  (PVOID*)&PhysSection);
2212  if (!NT_SUCCESS(Status))
2213  {
2214  DPRINT1("MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n", Status);
2215  return Status;
2216  }
2217 
2218  /*
2219  * Initialize it
2220  */
2221  RtlZeroMemory(PhysSection, sizeof(*PhysSection));
2222 
2223  /* Mark this as a "ROS Section" */
2224  PhysSection->u.Flags.filler = 1;
2226  PhysSection->u.Flags.PhysicalMemory = 1;
2227  PhysSection->SizeOfSection = SectionSize;
2230  if (Segment == NULL)
2231  {
2232  ObDereferenceObject(PhysSection);
2233  return STATUS_NO_MEMORY;
2234  }
2236  PhysSection->Segment = (PSEGMENT)Segment;
2237  Segment->RefCount = 1;
2238 
2239  Segment->ReferenceCount = &Segment->RefCount;
2240  Segment->Flags = &Segment->SegFlags;
2241 
2243  Segment->Image.FileOffset = 0;
2244  Segment->Protection = PAGE_EXECUTE_READWRITE;
2245  Segment->RawLength = SectionSize;
2246  Segment->Length = SectionSize;
2247  Segment->SegFlags = MM_PHYSICALMEMORY_SEGMENT;
2248  Segment->WriteCopy = FALSE;
2249  Segment->Image.VirtualAddress = 0;
2250  Segment->Image.Characteristics = 0;
2252 
2253  Status = ObInsertObject(PhysSection,
2254  NULL,
2256  0,
2257  NULL,
2258  &Handle);
2259  if (!NT_SUCCESS(Status))
2260  {
2261  ObDereferenceObject(PhysSection);
2262  return Status;
2263  }
2265 
2266  return STATUS_SUCCESS;
2267 }
union _SECTION::@2578 u
PSEGMENT Segment
Definition: mmtypes.h:809
ULONG PhysicalMemory
Definition: mmtypes.h:470
ULONG InitialPageProtection
Definition: mmtypes.h:816
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c: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:4934
return FALSE
Definition: section.c:5098
_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:114
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:91
#define DPRINT1
Definition: precomp.h:8
_In_ HANDLE Handle
Definition: extypes.h:390
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define STATUS_SUCCESS
Definition: shellext.h:65
LONGLONG QuadPart
Definition: typedefs.h:114
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by MmInitSectionImplementation().

◆ MmCreateSection()

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

Definition at line 4521 of file section.c.

4529 {
4530  NTSTATUS Status;
4531  ULONG Protection;
4532  PSECTION *SectionObject = (PSECTION *)Section;
4533  BOOLEAN FileLock = FALSE;
4534 
4535  /* Check if an ARM3 section is being created instead */
4537  {
4538  if (!(FileObject) && !(FileHandle))
4539  {
4540  return MmCreateArm3Section(Section,
4541  DesiredAccess,
4543  MaximumSize,
4545  AllocationAttributes &~ 1,
4546  FileHandle,
4547  FileObject);
4548  }
4549  }
4550 
4551  /* Convert section flag to page flag */
4553 
4554  /* Check to make sure the protection is correct. Nt* does this already */
4556  if (Protection == MM_INVALID_PROTECTION)
4557  {
4558  DPRINT1("Page protection is invalid\n");
4560  }
4561 
4562  /* Check if this is going to be a data or image backed file section */
4563  if ((FileHandle) || (FileObject))
4564  {
4565  /* These cannot be mapped with large pages */
4567  {
4568  DPRINT1("Large pages cannot be used with an image mapping\n");
4570  }
4571 
4572  /* Did the caller pass a file object ? */
4573  if (FileObject)
4574  {
4575  /* Reference the object directly */
4577 
4578  /* We don't create image mappings with file objects */
4580  }
4581  else
4582  {
4583  /* Reference the file handle to get the object */
4585  MmMakeFileAccess[Protection],
4588  (PVOID*)&FileObject,
4589  NULL);
4590  if (!NT_SUCCESS(Status))
4591  {
4592  DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
4593  return Status;
4594  }
4595 
4596  /* Lock the file */
4598  if (!NT_SUCCESS(Status))
4599  {
4601  return Status;
4602  }
4603 
4604  FileLock = TRUE;
4605 
4606  /* Deny access if there are writes on the file */
4607 #if 0
4609  {
4610  DPRINT1("Cannot create image maps with writers open on the file!\n");
4612  goto Quit;
4613  }
4614 #else
4616  DPRINT1("Creating image map with writers open on the file!\n");
4617 #endif
4618  }
4619  }
4620  else
4621  {
4622  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
4624  }
4625 
4627  {
4629  DesiredAccess,
4631  MaximumSize,
4634  FileObject);
4635  }
4636 #ifndef NEWCC
4637  else if (FileObject != NULL)
4638  {
4640  DesiredAccess,
4642  MaximumSize,
4645  FileObject,
4646  FileHandle != NULL);
4647  }
4648 #else
4649  else if (FileHandle != NULL || FileObject != NULL)
4650  {
4652  DesiredAccess,
4654  MaximumSize,
4657  FileObject);
4658  }
4659 #endif
4660  else
4661  {
4662  /* All cases should be handled above */
4664  }
4665 
4666  if (FileLock)
4668  if (FileObject)
4670 
4671  return Status;
4672 }
_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:2468
_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:4934
unsigned char BOOLEAN
return FALSE
Definition: section.c:5098
_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:140
#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:3155
#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:2305
#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 5174 of file section.c.

5177 {
5178  PSECTION Section = _Section;
5179 
5180  /* It makes no sense to extend an image mapping */
5181  if (Section->u.Flags.Image)
5183 
5184  /* Nor is it possible to extend a page file mapping */
5185  if (!Section->u.Flags.File)
5187 
5188  if (!MiIsRosSectionObject(Section))
5189  return STATUS_NOT_IMPLEMENTED;
5190 
5191  /* We just extend the sizes. Shrinking is a no-op ? */
5192  if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5193  {
5195  Section->SizeOfSection = *NewSize;
5196 
5197  if (!Section->u.Flags.Reserve)
5198  {
5200  if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5201  {
5202  Segment->RawLength = *NewSize;
5203  Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5204  }
5206  }
5207  }
5208 
5209  return STATUS_SUCCESS;
5210 }
union _SECTION::@2578 u
if(Entry==0)
Definition: section.c:4944
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
#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 4257 of file section.c.

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