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

Go to the source code of this file.

Classes

struct  MM_SECTION_PAGEOUT_CONTEXT
 

Macros

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

Functions

VOID NTAPI _MmLockSectionSegment (PMM_SECTION_SEGMENT Segment, const char *file, int line)
 
VOID NTAPI _MmUnlockSectionSegment (PMM_SECTION_SEGMENT Segment, const char *file, int line)
 
static PMM_SECTION_SEGMENT MiGrabDataSection (PSECTION_OBJECT_POINTERS SectionObjectPointer)
 
PMM_IMAGE_SECTION_OBJECT ImageSectionObjectFromSegment (PMM_SECTION_SEGMENT Segment)
 
NTSTATUS MiMapViewInSystemSpace (IN PVOID Section, IN PVOID Session, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize, IN PLARGE_INTEGER SectionOffset)
 
NTSTATUS NTAPI MmCreateArm3Section (OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER InputMaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
 
NTSTATUS NTAPI MmMapViewOfArm3Section (IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
 
 C_ASSERT (EXEFMT_LOAD_HEADER_SIZE >=sizeof(IMAGE_DOS_HEADER))
 
 C_ASSERT (sizeof(IMAGE_NT_HEADERS32)<=sizeof(IMAGE_NT_HEADERS64))
 
 C_ASSERT (TYPE_ALIGNMENT(IMAGE_NT_HEADERS32)==TYPE_ALIGNMENT(IMAGE_NT_HEADERS64))
 
 C_ASSERT (RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)==RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS64, FileHeader))
 
 C_ASSERT (FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)==FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Magic))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SectionAlignment))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, FileAlignment))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Subsystem))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, AddressOfEntryPoint))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfCode))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfHeaders))
 
ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask (IN ACCESS_MASK SectionPageProtection)
 
NTSTATUS NTAPI MiWritePage (PMM_SECTION_SEGMENT Segment, LONGLONG SegOffset, PFN_NUMBER Page)
 
NTSTATUS NTAPI PeFmtCreateSection (IN CONST VOID *FileHeader, IN SIZE_T FileHeaderSize, IN PVOID File, OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, OUT PULONG Flags, IN PEXEFMT_CB_READ_FILE ReadFileCb, IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb)
 
NTSTATUS MmspWaitForFileLock (PFILE_OBJECT File)
 
VOID NTAPI MmpFreePageFileSegment (PMM_SECTION_SEGMENT Segment)
 
static VOID NTAPI FreeSegmentPage (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
 
 _When_ (OldIrql==MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL))
 
VOID NTAPI MmSharePageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
 
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment (PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
 
static NTSTATUS MiCopyFromUserPage (PFN_NUMBER DestPage, const VOID *SrcAddress)
 
static NTSTATUS NTAPI MmMakeSegmentResident (_In_ PMM_SECTION_SEGMENT Segment, _In_ LONGLONG Offset, _In_ ULONG Length, _In_opt_ PLARGE_INTEGER ValidDataLength)
 
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)
 
BOOLEAN NTAPI MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
 
NTSTATUS NTAPI MmMapViewInSystemSpace (IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
 
NTSTATUS NTAPI MmMapViewInSystemSpaceEx (_In_ PVOID SectionObject, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset, _In_ ULONG_PTR Flags)
 
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace (IN PVOID MappedBase)
 
NTSTATUS NTAPI MmCreateSection (OUT PVOID *Section, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
 
BOOLEAN NTAPI MmArePagesResident (_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
 
BOOLEAN NTAPI MmPurgeSegment (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length)
 
NTSTATUS NTAPI MmMakeDataSectionResident (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _In_ ULONG Length, _In_ PLARGE_INTEGER ValidDataLength)
 
NTSTATUS NTAPI MmFlushSegment (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _Out_opt_ PIO_STATUS_BLOCK Iosb)
 
 _Requires_exclusive_lock_held_ (Segment->Lock) BOOLEAN NTAPI MmCheckDirtySegment(PMM_SECTION_SEGMENT Segment
 
 ASSERT (Segment->Locked)
 
 ASSERT ((Offset->QuadPart % PAGE_SIZE)==0)
 
 DPRINT ("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
 
 if (Entry==0)
 
 if (!IS_DIRTY_SSE(Entry) &&(SHARE_COUNT_FROM_SSE(Entry)==0) &&PageOut)
 
NTSTATUS NTAPI MmMakePagesDirty (_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
 
NTSTATUS NTAPI MmExtendSection (_In_ PVOID _Section, _Inout_ PLARGE_INTEGER NewSize)
 

Variables

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

Macro Definition Documentation

◆ DIE

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

◆ MmSetPageEntrySectionSegment

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

Definition at line 57 of file section.c.

◆ NDEBUG

#define NDEBUG

Definition at line 50 of file section.c.

Function Documentation

◆ _MmLockSectionSegment()

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

Definition at line 71 of file section.c.

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

◆ _MmUnlockSectionSegment()

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

Definition at line 80 of file section.c.

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

◆ _Requires_exclusive_lock_held_()

_Requires_exclusive_lock_held_ ( Segment->  Lock)

◆ _When_()

Definition at line 990 of file section.c.

999 {
1000  /* Lock the PFN lock because we mess around with SectionObjectPointers */
1001  if (OldIrql == MM_NOIRQL)
1002  {
1003  OldIrql = MiAcquirePfnLock();
1004  }
1005 
1006  if (InterlockedDecrement64(Segment->ReferenceCount) > 0)
1007  {
1008  /* Nothing to do yet */
1009  MiReleasePfnLock(OldIrql);
1010  return;
1011  }
1012 
1013  *Segment->Flags |= MM_SEGMENT_INDELETE;
1014  MiReleasePfnLock(OldIrql);
1015 
1016  /* Flush the segment */
1017  if (*Segment->Flags & MM_DATAFILE_SEGMENT)
1018  {
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  OldIrql = MiAcquirePfnLock();
1040  /* Delete the pointer on the file */
1041  ASSERT(ImageSectionObject->FileObject->SectionObjectPointer->ImageSectionObject == ImageSectionObject);
1042  ImageSectionObject->FileObject->SectionObjectPointer->ImageSectionObject = NULL;
1043  MiReleasePfnLock(OldIrql);
1044 
1045  ObDereferenceObject(ImageSectionObject->FileObject);
1046 
1047  NrSegments = ImageSectionObject->NrSegments;
1048  SectionSegments = ImageSectionObject->Segments;
1049  for (i = 0; i < NrSegments; i++)
1050  {
1051  if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
1052  {
1053  MmpFreePageFileSegment(&SectionSegments[i]);
1054  }
1055 
1056  MmFreePageTablesSectionSegment(&SectionSegments[i], NULL);
1057  }
1058 
1059  ExFreePoolWithTag(ImageSectionObject->Segments, TAG_MM_SECTION_SEGMENT);
1060  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
1061  }
1062 }
static VOID NTAPI FreeSegmentPage(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: section.c:962
ASSERT(Segment->Locked)
#define MM_NOIRQL
Definition: mm.h:59
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
KIRQL OldIrql
Definition: mm.h:1502
VOID NTAPI MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:919
PMM_SECTION_SEGMENT Segments
Definition: mm.h:223
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID NTAPI MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment, FREE_SECTION_PAGE_FUN FreePage)
Definition: sptab.c:307
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define InterlockedDecrement64
Definition: interlocked.h:144
PFILE_OBJECT FileObject
Definition: mm.h:215
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define MM_SEGMENT_INDELETE
Definition: mm.h:228
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

◆ ASSERT() [1/2]

ASSERT ( Segment->  Locked)

Referenced by _MmUnlockSectionSegment(), _When_(), ExeFmtpCreateImageSection(), ExeFmtpReadFile(), FreeSegmentPage(), ImageSectionObjectFromSegment(), MiAddMappedPtes(), MiCheckControlArea(), MiCheckPurgeAndUpMapCount(), MiCopyFromUserPage(), MiCreateDataFileMap(), MiCreatePagingFileMap(), MiDeleteARM3Section(), MiFillSystemPageDirectory(), MiFlushTbAndCapture(), MiGetFileObjectForSectionAddress(), MiGetFileObjectForVad(), MiGrabDataSection(), MiInitializeSystemSpaceMap(), MiInsertInSystemSpace(), MiLocateSubsection(), MiMakeProtectionMask(), MiMapViewInSystemSpace(), MiMapViewOfDataSection(), 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 2549 of file section.c.

2550 {
2551  SIZE_T SizeOfSegments;
2552  PMM_SECTION_SEGMENT Segments;
2553 
2554  /* TODO: check for integer overflow */
2555  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
2556 
2558  SizeOfSegments,
2560 
2561  if(Segments)
2562  RtlZeroMemory(Segments, SizeOfSegments);
2563 
2564  return Segments;
2565 }
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
struct _MM_SECTION_SEGMENT MM_SECTION_SEGMENT
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by ExeFmtpCreateImageSection().

◆ ExeFmtpCreateImageSection()

NTSTATUS ExeFmtpCreateImageSection ( PFILE_OBJECT  FileObject,
PMM_IMAGE_SECTION_OBJECT  ImageSectionObject 
)

Definition at line 2983 of file section.c.

2985 {
2987  PVOID FileHeader;
2988  PVOID FileHeaderBuffer;
2989  ULONG FileHeaderSize;
2990  ULONG Flags;
2991  ULONG OldNrSegments;
2992  NTSTATUS Status;
2993  ULONG i;
2994 
2995  /*
2996  * Read the beginning of the file (2 pages). Should be enough to contain
2997  * all (or most) of the headers
2998  */
2999  Offset.QuadPart = 0;
3000 
3002  &Offset,
3003  PAGE_SIZE * 2,
3004  &FileHeader,
3005  &FileHeaderBuffer,
3006  &FileHeaderSize);
3007 
3008  if (!NT_SUCCESS(Status))
3009  return Status;
3010 
3011  if (FileHeaderSize == 0)
3012  {
3013  ExFreePool(FileHeaderBuffer);
3014  return STATUS_UNSUCCESSFUL;
3015  }
3016 
3017  /*
3018  * Look for a loader that can handle this executable
3019  */
3020  for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
3021  {
3022  Flags = 0;
3023 
3024  Status = ExeFmtpLoaders[i](FileHeader,
3025  FileHeaderSize,
3026  FileObject,
3027  ImageSectionObject,
3028  &Flags,
3031 
3032  if (!NT_SUCCESS(Status))
3033  {
3034  if (ImageSectionObject->Segments)
3035  {
3036  ExFreePool(ImageSectionObject->Segments);
3037  ImageSectionObject->Segments = NULL;
3038  }
3039  }
3040 
3042  break;
3043  }
3044 
3045  ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
3046 
3047  /*
3048  * No loader handled the format
3049  */
3051  {
3054  }
3055 
3056  if (!NT_SUCCESS(Status))
3057  return Status;
3058 
3059  ASSERT(ImageSectionObject->Segments != NULL);
3060  ASSERT(ImageSectionObject->RefCount > 0);
3061 
3062  /*
3063  * Some defaults
3064  */
3065  /* FIXME? are these values platform-dependent? */
3066  if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
3067  ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
3068 
3069  if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
3070  ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
3071 
3072  if(ImageSectionObject->BasedAddress == NULL)
3073  {
3074  if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3075  ImageSectionObject->BasedAddress = (PVOID)0x10000000;
3076  else
3077  ImageSectionObject->BasedAddress = (PVOID)0x00400000;
3078  }
3079 
3080  /*
3081  * And now the fun part: fixing the segments
3082  */
3083 
3084  /* Sort them by virtual address */
3085  MmspSortSegments(ImageSectionObject, Flags);
3086 
3087  /* Ensure they don't overlap in memory */
3088  if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
3090 
3091  /* Ensure they are aligned */
3092  OldNrSegments = ImageSectionObject->NrSegments;
3093 
3094  if (!MmspPageAlignSegments(ImageSectionObject, Flags))
3096 
3097  /* Trim them if the alignment phase merged some of them */
3098  if (ImageSectionObject->NrSegments < OldNrSegments)
3099  {
3100  PMM_SECTION_SEGMENT Segments;
3101  SIZE_T SizeOfSegments;
3102 
3103  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
3104 
3105  Segments = ExAllocatePoolWithTag(PagedPool,
3106  SizeOfSegments,
3108 
3109  if (Segments == NULL)
3111 
3112  RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
3113  ExFreePool(ImageSectionObject->Segments);
3114  ImageSectionObject->Segments = Segments;
3115  }
3116 
3117  /* And finish their initialization */
3118  for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
3119  {
3120  ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
3121  ImageSectionObject->Segments[i].ReferenceCount = &ImageSectionObject->RefCount;
3122  ImageSectionObject->Segments[i].Flags = &ImageSectionObject->SegFlags;
3123  MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
3124  ImageSectionObject->Segments[i].FileObject = FileObject;
3125  }
3126 
3127  ASSERT(ImageSectionObject->RefCount > 0);
3128 
3129  ImageSectionObject->FileObject = FileObject;
3130 
3132  return Status;
3133 }
#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:2800
static VOID NTAPI MmspSortSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2723
ASSERT(Segment->Locked)
NTSTATUS Status
Definition: section.c:4887
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:2549
#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:2538
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:2569
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SIZE_T
Definition: typedefs.h:80
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
PLARGE_INTEGER Offset
Definition: section.c:4882
#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:2749

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

2575 {
2576  NTSTATUS Status;
2578  ULONG AdjustOffset;
2579  ULONG OffsetAdjustment;
2580  ULONG BufferSize;
2581  ULONG UsedSize;
2582  PVOID Buffer;
2585 
2587 
2588  if(Length == 0)
2589  {
2590  KeBugCheck(MEMORY_MANAGEMENT);
2591  }
2592 
2593  FileOffset = *Offset;
2594 
2595  /* Negative/special offset: it cannot be used in this context */
2596  if(FileOffset.u.HighPart < 0)
2597  {
2598  KeBugCheck(MEMORY_MANAGEMENT);
2599  }
2600 
2601  AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
2602  OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
2603  FileOffset.u.LowPart = AdjustOffset;
2604 
2605  BufferSize = Length + OffsetAdjustment;
2607 
2608  /*
2609  * It's ok to use paged pool, because this is a temporary buffer only used in
2610  * the loading of executables. The assumption is that MmCreateSection is
2611  * always called at low IRQLs and that these buffers don't survive a brief
2612  * initialization phase
2613  */
2615  if (!Buffer)
2616  {
2618  }
2619 
2621 
2622  UsedSize = (ULONG)Iosb.Information;
2623 
2624  if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
2625  {
2628  }
2629 
2630  if(NT_SUCCESS(Status))
2631  {
2632  *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
2633  *AllocBase = Buffer;
2634  *ReadSize = UsedSize - OffsetAdjustment;
2635  }
2636  else
2637  {
2638  ExFreePoolWithTag(Buffer, 'rXmM');
2639  }
2640 
2641  return Status;
2642 }
#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:4887
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ASSERT_IRQL_LESS(x)
Definition: debug.h:253
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
PLARGE_INTEGER Offset
Definition: section.c:4882
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID _In_ LONG _In_z_ PCHAR File
Definition: wdfdevice.h:4061
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define BufferSize
Definition: mmc.h:75
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
NTSTATUS NTAPI MiSimpleRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PVOID Buffer, ULONG Length, BOOLEAN Paging, PIO_STATUS_BLOCK ReadStatus)
Definition: io.c:109

Referenced by ExeFmtpCreateImageSection().

◆ FreeSegmentPage()

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

Definition at line 962 of file section.c.

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

Referenced by _When_().

◆ if() [1/2]

if ( Entry  = = 0)

Definition at line 4897 of file section.c.

4902  {
4903  BOOLEAN DirtyAgain;
4904 
4905  /*
4906  * We got a dirty entry. This path is for the shared data,
4907  * be-it regular file maps or shared sections of DLLs
4908  */
4909  ASSERT(!Segment->WriteCopy);
4910  ASSERT(FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT) || FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
4911 
4912  /* Insert the cleaned entry back. Mark it as write in progress, and clear the dirty bit. */
4914  Entry = WRITE_SSE(Entry);
4916 
4918 
4919  if (FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
4920  {
4921  /* We have to write it back to the file. Tell the FS driver who we are */
4922  if (PageOut)
4924 
4925  /* Go ahead and write the page */
4926  DPRINT("Writing page at offset %I64d for file %wZ, Pageout: %s\n",
4927  Offset->QuadPart, &Segment->FileObject->FileName, PageOut ? "TRUE" : "FALSE");
4928  Status = MiWritePage(Segment, Offset->QuadPart, Page);
4929 
4930  if (PageOut)
4932  }
4933  else
4934  {
4935  /* This must only be called by the page-out path */
4936  ASSERT(PageOut);
4937 
4938  /* And this must be for a shared section in a DLL */
4939  ASSERT(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED);
4940 
4941  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
4942  if (!SwapEntry)
4943  {
4944  SwapEntry = MmAllocSwapPage();
4945  }
4946 
4947  if (SwapEntry)
4948  {
4949  Status = MmWriteToSwapPage(SwapEntry, Page);
4950  if (NT_SUCCESS(Status))
4951  {
4952  MmSetSavedSwapEntryPage(Page, SwapEntry);
4953  }
4954  else
4955  {
4956  MmFreeSwapPage(SwapEntry);
4957  }
4958  }
4959  else
4960  {
4961  DPRINT1("Failed to allocate a swap page!\n");
4963  }
4964  }
4965 
4967 
4968  /* Get the entry again */
4971 
4972  if (!NT_SUCCESS(Status))
4973  {
4974  /* Damn, this failed. Consider this page as still dirty */
4975  DPRINT1("MiWritePage FAILED: Status 0x%08x!\n", Status);
4976  DirtyAgain = TRUE;
4977  }
4978  else
4979  {
4980  /* Check if someone dirtified this page while we were not looking */
4981  DirtyAgain = IS_DIRTY_SSE(Entry);
4982  }
4983 
4984  /* Drop the reference we got, deleting the write altogether. */
4986  if (DirtyAgain)
4987  {
4988  Entry = DIRTY_SSE(Entry);
4989  }
4991  }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1538
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WRITE_SSE(E)
Definition: mm.h:1314
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:57
#define TRUE
Definition: types.h:120
#define PFN_FROM_SSE(E)
Definition: mm.h:1304
#define MmLockSectionSegment(x)
Definition: mm.h:1333
#define DIRTY_SSE(E)
Definition: mm.h:1311
ASSERT(Segment->Locked)
#define IS_DIRTY_SSE(E)
Definition: mm.h:1313
#define MAKE_SSE(P, C)
Definition: mm.h:1323
unsigned char BOOLEAN
PFN_NUMBER Page
Definition: section.c:4888
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
SWAPENTRY NTAPI MmAllocSwapPage(VOID)
Definition: pagefile.c:304
PLARGE_INTEGER BOOLEAN BOOLEAN PageOut
Definition: section.c:4885
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define PAGE_FROM_SSE(E)
Definition: mm.h:1319
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
NTSTATUS NTAPI MiWritePage(PMM_SECTION_SEGMENT Segment, LONGLONG SegOffset, PFN_NUMBER Page)
Definition: section.c:240
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SWAPENTRY
Definition: mm.h:53
DPRINT("Checking segment for file %wZ at offset 0x%I64X.\n", &Segment->FileObject->FileName, Offset->QuadPart)
#define NULL
Definition: types.h:112
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1321
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:483
NTSTATUS NTAPI MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:130
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI MmFreeSwapPage(SWAPENTRY Entry)
Definition: pagefile.c:274
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:499

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

◆ if() [2/2]

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

Definition at line 4994 of file section.c.

4995  {
4996  ULONG_PTR NewEntry = 0;
4997  /* Restore the swap entry here */
4998  if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
4999  {
5000  SWAPENTRY SwapEntry = MmGetSavedSwapEntryPage(Page);
5001  if (SwapEntry)
5002  NewEntry = MAKE_SWAP_SSE(SwapEntry);
5003  }
5004 
5005  /* Yes. Release it */
5008  /* Tell the caller we released the page */
5009  return TRUE;
5010  }
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:57
#define TRUE
Definition: types.h:120
#define MC_USER
Definition: mm.h:103
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:78
uint32_t ULONG_PTR
Definition: typedefs.h:65
PFN_NUMBER Page
Definition: section.c:4888
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SWAPENTRY
Definition: mm.h:53
#define MAKE_SWAP_SSE(S)
Definition: mm.h:1310
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:499

◆ ImageSectionObjectFromSegment()

PMM_IMAGE_SECTION_OBJECT ImageSectionObjectFromSegment ( PMM_SECTION_SEGMENT  Segment)

Definition at line 121 of file section.c.

122 {
123  ASSERT((Segment->SegFlags & MM_DATAFILE_SEGMENT) == 0);
124 
125  return CONTAINING_RECORD(Segment->ReferenceCount, MM_IMAGE_SECTION_OBJECT, RefCount);
126 }
ASSERT(Segment->Locked)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define MM_DATAFILE_SEGMENT
Definition: mm.h:227

Referenced by MiRosUnmapViewOfSection().

◆ MiArm3GetCorrectFileAccessMask()

ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask ( IN ACCESS_MASK  SectionPageProtection)

Definition at line 140 of file section.c.

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

◆ MiCopyFromUserPage()

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

Definition at line 1171 of file section.c.

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

Referenced by MmAccessFaultSectionView().

◆ MiGrabDataSection()

static PMM_SECTION_SEGMENT MiGrabDataSection ( PSECTION_OBJECT_POINTERS  SectionObjectPointer)
static

Definition at line 91 of file section.c.

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

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

◆ MiMapViewInSystemSpace()

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

◆ MiRosUnmapViewInSystemSpace()

NTSTATUS NTAPI MiRosUnmapViewInSystemSpace ( IN PVOID  MappedBase)

Definition at line 4411 of file section.c.

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

Referenced by MmUnmapViewInSystemSpace().

◆ MiRosUnmapViewOfSection()

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

Definition at line 3548 of file section.c.

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

Referenced by MiRosCleanupMemoryArea(), and MiUnmapViewOfSection().

◆ MiWritePage()

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

Definition at line 240 of file section.c.

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

Referenced by FreeSegmentPage().

◆ MmAccessFaultSectionView()

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

Definition at line 1884 of file section.c.

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

Referenced by MmpAccessFault().

◆ MmAlterViewAttributes()

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

Definition at line 1432 of file section.c.

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

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

◆ MmArePagesResident()

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

Definition at line 4629 of file section.c.

4633 {
4635  BOOLEAN Ret = TRUE;
4637  LARGE_INTEGER SegmentOffset, RangeEnd;
4639 
4641 
4643  if (MemoryArea == NULL)
4644  {
4646  return FALSE;
4647  }
4648 
4649  /* Only supported in old Mm for now */
4651  /* For file mappings */
4653 
4654  Segment = MemoryArea->SectionData.Segment;
4656 
4658  + MemoryArea->SectionData.ViewOffset;
4660  + MemoryArea->SectionData.ViewOffset;
4661 
4662  while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
4663  {
4665  if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4666  {
4667  Ret = FALSE;
4668  break;
4669  }
4670  SegmentOffset.QuadPart += PAGE_SIZE;
4671  }
4672 
4674 
4676  return Ret;
4677 }
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1538
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ULONG Type
Definition: mm.h:240
#define TRUE
Definition: types.h:120
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1618
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MmLockSectionSegment(x)
Definition: mm.h:1333
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:731
uint32_t ULONG_PTR
Definition: typedefs.h:65
union _MMVAD::@2547 u
ASSERT(Segment->Locked)
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
return FALSE
Definition: section.c:5012
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:82
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
MMVAD VadNode
Definition: mm.h:238
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:233
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1640
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1305
#define NULL
Definition: types.h:112
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
struct _MEMORY_AREA::@1758 SectionData
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:37
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1611
ULONG_PTR VadType
Definition: mmtypes.h:691
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CcRosEnsureVacbResident().

◆ MmCanFileBeTruncated()

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

Definition at line 4141 of file section.c.

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

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

◆ MmCreateArm3Section()

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

Definition at line 2465 of file section.c.

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

Referenced by MmCreateSection().

◆ MmCreateDataFileSection()

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

Definition at line 2286 of file section.c.

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

Referenced by MmCreateSection().

◆ MmCreateImageSection()

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

Definition at line 3136 of file section.c.

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

Referenced by MmCreateSection().

◆ MmCreatePhysicalMemorySection()

NTSTATUS NTAPI MmCreatePhysicalMemorySection ( VOID  )

Definition at line 2162 of file section.c.

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

Referenced by MmInitSectionImplementation().

◆ MmCreateSection()

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

Definition at line 4474 of file section.c.

4482 {
4483  NTSTATUS Status;
4484  ULONG Protection;
4485  PSECTION *SectionObject = (PSECTION *)Section;
4486  BOOLEAN FileLock = FALSE;
4487 
4488  /* Check if an ARM3 section is being created instead */
4490  {
4491  if (!(FileObject) && !(FileHandle))
4492  {
4493  return MmCreateArm3Section(Section,
4494  DesiredAccess,
4496  MaximumSize,
4498  AllocationAttributes &~ 1,
4499  FileHandle,
4500  FileObject);
4501  }
4502  }
4503 
4504  /* Convert section flag to page flag */
4506 
4507  /* Check to make sure the protection is correct. Nt* does this already */
4509  if (Protection == MM_INVALID_PROTECTION)
4510  {
4511  DPRINT1("Page protection is invalid\n");
4513  }
4514 
4515  /* Check if this is going to be a data or image backed file section */
4516  if ((FileHandle) || (FileObject))
4517  {
4518  /* These cannot be mapped with large pages */
4520  {
4521  DPRINT1("Large pages cannot be used with an image mapping\n");
4523  }
4524 
4525  /* Did the caller pass a file object ? */
4526  if (FileObject)
4527  {
4528  /* Reference the object directly */
4530 
4531  /* We don't create image mappings with file objects */
4533  }
4534  else
4535  {
4536  /* Reference the file handle to get the object */
4538  MmMakeFileAccess[Protection],
4541  (PVOID*)&FileObject,
4542  NULL);
4543  if (!NT_SUCCESS(Status))
4544  {
4545  DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
4546  return Status;
4547  }
4548 
4549  /* Lock the file */
4551  if (!NT_SUCCESS(Status))
4552  {
4554  return Status;
4555  }
4556 
4557  FileLock = TRUE;
4558 
4559  /* Deny access if there are writes on the file */
4560 #if 0
4562  {
4563  DPRINT1("Cannot create image maps with writers open on the file!\n");
4565  goto Quit;
4566  }
4567 #else
4569  DPRINT1("Creating image map with writers open on the file!\n");
4570 #endif
4571  }
4572  }
4573  else
4574  {
4575  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
4577  }
4578 
4580  {
4582  DesiredAccess,
4584  MaximumSize,
4587  FileObject);
4588  }
4589 #ifndef NEWCC
4590  else if (FileObject != NULL)
4591  {
4593  DesiredAccess,
4595  MaximumSize,
4598  FileObject,
4599  FileHandle != NULL);
4600  }
4601 #else
4602  else if (FileHandle != NULL || FileObject != NULL)
4603  {
4605  DesiredAccess,
4607  MaximumSize,
4610  FileObject);
4611  }
4612 #endif
4613  else
4614  {
4615  /* All cases should be handled above */
4617  }
4618 
4619  if (FileLock)
4621  if (FileObject)
4623 
4624  return Status;
4625 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define PAGE_NOCACHE
Definition: nt_native.h:1311
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
#define SEC_NOCACHE
Definition: mmtypes.h:100
VOID NTAPI FsRtlReleaseFile(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1659
NTSTATUS NTAPI MmCreateArm3Section(OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER InputMaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: section.c:2465
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1647
NTSTATUS Status
Definition: section.c:4887
unsigned char BOOLEAN
return FALSE
Definition: section.c:5012
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:158
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
NTSTATUS MmCreateImageSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
Definition: section.c:3136
#define SEC_PHYSICALMEMORY
Definition: mm.h:101
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
static NTSTATUS NTAPI MmCreateDataFileSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject, BOOLEAN GotFileHandle)
Definition: section.c:2286
#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 5088 of file section.c.

5091 {
5092  PSECTION Section = _Section;
5093 
5094  /* It makes no sense to extend an image mapping */
5095  if (Section->u.Flags.Image)
5097 
5098  /* Nor is it possible to extend a page file mapping */
5099  if (!Section->u.Flags.File)
5101 
5102  if (!MiIsRosSectionObject(Section))
5103  return STATUS_NOT_IMPLEMENTED;
5104 
5105  /* We just extend the sizes. Shrinking is a no-op ? */
5106  if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5107  {
5109  Section->SizeOfSection = *NewSize;
5110 
5111  if (!Section->u.Flags.Reserve)
5112  {
5114  if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5115  {
5116  Segment->RawLength = *NewSize;
5117  Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5118  }
5120  }
5121  }
5122 
5123  return STATUS_SUCCESS;
5124 }
if(Entry==0)
Definition: section.c:4897
PSEGMENT Segment
Definition: mmtypes.h:809
#define MmLockSectionSegment(x)
Definition: mm.h:1333
return STATUS_NOT_IMPLEMENTED
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:810
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1103
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
int64_t LONGLONG
Definition: typedefs.h:68
struct _MM_SECTION_SEGMENT * PMM_SECTION_SEGMENT
union _SECTION::@2556 u
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 4191 of file section.c.

4193 {
4194  switch(FlushType)
4195  {
4196  case MmFlushForDelete:
4197  {
4198  KIRQL OldIrql = MiAcquirePfnLock();
4199  PMM_IMAGE_SECTION_OBJECT ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4200 
4201  if (!ImageSectionObject || (ImageSectionObject->SegFlags & MM_SEGMENT_INDELETE))
4202  {
4203  MiReleasePfnLock(OldIrql);
4204  return TRUE;
4205  }
4206 
4207  /* Do we have open sections or mappings on it ? */
4208  if ((ImageSectionObject->SectionCount) || (ImageSectionObject->MapCount))
4209  {
4210  /* We do. No way to delete it */
4211  MiReleasePfnLock(OldIrql);
4212  return FALSE;
4213  }
4214 
4215  /* There are no sections open on it, but we must still have pages around. Discard everything */
4216  ImageSectionObject->SegFlags |= MM_IMAGE_SECTION_FLUSH_DELETE;
4217  InterlockedIncrement64(&ImageSectionObject->RefCount);
4218  MiReleasePfnLock(OldIrql);
4219 
4220  for (ULONG i = 0; i < ImageSectionObject->NrSegments; i++)
4221  {
4222  PMM_SECTION_SEGMENT Segment = &ImageSectionObject->Segments[i];
4223  LONGLONG Length;
4224 
4226  /* Loop over all entries */
4228  Offset.QuadPart = 0;
4229 
4230  Length = Segment->Length.QuadPart;
4231  if (Length < Segment->RawLength.QuadPart)
4232  Length = Segment->RawLength.QuadPart;
4233 
4234  while (Offset.QuadPart < Length)
4235  {
4237 
4238  /* Shared data must already be discarded, and nobody should be reading it. */
4240  if (Entry != 0)
4241  {
4242  DPRINT1("Freeing page %lx for image section %p\n", PFN_FROM_SSE(Entry), ImageSectionObject);
4243  /* Release the page */
4249  }
4250  Offset.QuadPart += PAGE_SIZE;
4251  }
4253  }
4254 
4255  /* Grab lock again */
4256  OldIrql = MiAcquirePfnLock();
4257 
4258  if (!(ImageSectionObject->SegFlags & MM_IMAGE_SECTION_FLUSH_DELETE))
4259  {
4260  /*
4261  * Someone actually created a section while we were not looking.
4262  * Drop our ref and deny.
4263  * MmDereferenceSegmentWithLock releases Pfn lock
4264  */
4265  MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4266  return FALSE;
4267  }
4268 
4269  /* We should be the last one holding a ref here. */
4270  ASSERT(ImageSectionObject->RefCount == 1);
4271  ASSERT(ImageSectionObject->SectionCount == 0);
4272 
4273  /* Dereference the first segment, this will free everything & release the lock */
4274  MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4275  return TRUE;
4276  }
4277  case MmFlushForWrite:
4278  {
4279  BOOLEAN Ret = TRUE;
4280  KIRQL OldIrql = MiAcquirePfnLock();
4281 
4282  if (SectionObjectPointer->ImageSectionObject)
4283  {
4284  PMM_IMAGE_SECTION_OBJECT ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4285  if (!(ImageSectionObject->SegFlags & MM_SEGMENT_INDELETE))
4286  Ret = FALSE;
4287  }
4288 
4289  MiReleasePfnLock(OldIrql);
4290  return Ret;
4291  }
4292  }
4293  return FALSE;
4294 }
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1538
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define MM_IMAGE_SECTION_FLUSH_DELETE
Definition: mm.h:230
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:57
#define TRUE
Definition: types.h:120
#define MC_USER
Definition: mm.h:103
#define PFN_FROM_SSE(E)
Definition: mm.h:1304
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:78
#define MmLockSectionSegment(x)
Definition: mm.h:1333
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
unsigned char BOOLEAN
return FALSE
Definition: section.c:5012
#define MmUnlockSectionSegment(x)
Definition: mm.h:1341
IN PFCB IN FAT_FLUSH_TYPE FlushType
Definition: fatprocs.h:1080
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
KIRQL OldIrql
Definition: mm.h:1502
int64_t LONGLONG
Definition: typedefs.h:68
#define InterlockedIncrement64
Definition: interlocked.h:211
PMM_SECTION_SEGMENT Segments
Definition: mm.h:223
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1305
#define MM_SEGMENT_INDELETE
Definition: mm.h:228
PLARGE_INTEGER Offset
Definition: section.c:4882
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1321
#define DPRINT1
Definition: precomp.h:8
#define IS_WRITE_SSE(E)
Definition: mm.h:1315
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:114
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:499

Referenced by _Requires_lock_held_(), Ext2CreateFile(), Ext2IsFileRemovable(), Ext2PurgeFile(), Ext2PurgeVolume(), FatSetRenameInfo(), open_file2(), RxCommonSetInformation(), RxPurgeFcbInSystemCache(), RxPurgeFobx(), RxPurgeNetFcb(), set_disposition_information(), UDFCloseAllXXXDelayedInDir(), UDFCommonCreate(), UDFMarkStreamsForDeletion(), UDFSetDispositionInformation(), VfatCreateFile(), vfatPrepareTargetForRename(), and VfatSetDispositionInformation().

◆ MmFlushSegment()

NTSTATUS NTAPI MmFlushSegment ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_opt_ PLARGE_INTEGER  Offset,
_In_ ULONG  Length,
_Out_opt_ PIO_STATUS_BLOCK  Iosb 
)

Definition at line 4794 of file section.c.

4799 {
4800  LARGE_INTEGER FlushStart, FlushEnd;
4801  NTSTATUS Status;
4802 
4803  if (Offset)
4804  {
4805  FlushStart = *Offset;
4806  Status = RtlLongLongAdd(FlushStart.QuadPart, Length, &FlushEnd.QuadPart);
4807  if (!NT_SUCCESS(Status))
4808  return Status;
4809  }
4810 
4811  if (Iosb)
4812  Iosb->Information = 0;
4813 
4815  if (!Segment)
4816  {
4817  /* Nothing to flush */
4818  if (Iosb)
4819  Iosb->Status = STATUS_SUCCESS;
4820  return STATUS_SUCCESS;
4821  }
4822 
4823  ASSERT(*Segment->Flags & MM_DATAFILE_SEGMENT);
4824 
4826 
4827  if (!Offset)
4828  {
4829  FlushStart.QuadPart = 0;
4830 
4831  /* FIXME: All of this is suboptimal */
4832  ULONG ElemCo