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

Go to the source code of this file.

Classes

struct  MM_SECTION_PAGEOUT_CONTEXT
 

Macros

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

Functions

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

Variables

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

Macro Definition Documentation

◆ DIE

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

◆ MmSetPageEntrySectionSegment

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

Definition at line 56 of file section.c.

◆ NDEBUG

#define NDEBUG

Definition at line 49 of file section.c.

Function Documentation

◆ _MmLockSectionSegment()

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

Definition at line 70 of file section.c.

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

◆ _MmUnlockSectionSegment()

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

Definition at line 79 of file section.c.

80{
81 ASSERT(Segment->Locked);
82 Segment->Locked = FALSE;
84 //DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment, file, line);
85}
#define FALSE
Definition: types.h:117
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define ASSERT(a)
Definition: mode.c:44

◆ _Requires_exclusive_lock_held_()

_Requires_exclusive_lock_held_ ( Segment->  Lock)

◆ _When_()

Definition at line 988 of file section.c.

998{
999 /* Lock the PFN lock because we mess around with SectionObjectPointers */
1000 if (OldIrql == MM_NOIRQL)
1001 {
1002 OldIrql = MiAcquirePfnLock();
1003 }
1004
1005 if (InterlockedDecrement64(Segment->ReferenceCount) > 0)
1006 {
1007 /* Nothing to do yet */
1008 MiReleasePfnLock(OldIrql);
1009 return;
1010 }
1011
1012 *Segment->Flags |= MM_SEGMENT_INDELETE;
1013
1014 /* Flush the segment */
1015 if (*Segment->Flags & MM_DATAFILE_SEGMENT)
1016 {
1017 MiReleasePfnLock(OldIrql);
1018 /* Free the page table. This will flush any remaining dirty data */
1020
1021 OldIrql = MiAcquirePfnLock();
1022 /* Delete the pointer on the file */
1023 ASSERT(Segment->FileObject->SectionObjectPointer->DataSectionObject == Segment);
1024 Segment->FileObject->SectionObjectPointer->DataSectionObject = NULL;
1025 MiReleasePfnLock(OldIrql);
1026 ObDereferenceObject(Segment->FileObject);
1027
1029 }
1030 else
1031 {
1032 /* Most grotesque thing ever */
1033 PMM_IMAGE_SECTION_OBJECT ImageSectionObject = CONTAINING_RECORD(Segment->ReferenceCount, MM_IMAGE_SECTION_OBJECT, RefCount);
1034 PMM_SECTION_SEGMENT SectionSegments;
1035 ULONG NrSegments;
1036 ULONG i;
1037
1038 /* Delete the pointer on the file */
1039 ASSERT(ImageSectionObject->FileObject->SectionObjectPointer->ImageSectionObject == ImageSectionObject);
1040 ImageSectionObject->FileObject->SectionObjectPointer->ImageSectionObject = NULL;
1041 MiReleasePfnLock(OldIrql);
1042
1043 ObDereferenceObject(ImageSectionObject->FileObject);
1044
1045 NrSegments = ImageSectionObject->NrSegments;
1046 SectionSegments = ImageSectionObject->Segments;
1047 for (i = 0; i < NrSegments; i++)
1048 {
1049 if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED)
1050 {
1051 MmpFreePageFileSegment(&SectionSegments[i]);
1052 }
1053
1054 MmFreePageTablesSectionSegment(&SectionSegments[i], NULL);
1055 }
1056
1058 ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
1059 }
1060}
#define NULL
Definition: types.h:112
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 InterlockedDecrement64
Definition: interlocked.h:144
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
VOID NTAPI MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment, FREE_SECTION_PAGE_FUN FreePage)
Definition: sptab.c:321
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define MM_NOIRQL
Definition: mm.h:70
#define MM_SEGMENT_INDELETE
Definition: mm.h:246
#define MM_DATAFILE_SEGMENT
Definition: mm.h:245
static VOID NTAPI FreeSegmentPage(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: section.c:960
VOID NTAPI MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:917
PMM_SECTION_SEGMENT Segments
Definition: mm.h:241
PFILE_OBJECT FileObject
Definition: mm.h:233
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:113
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ ASSERT() [1/2]

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

◆ ASSERT() [2/2]

ASSERT ( Segment->  Locked)

◆ C_ASSERT() [1/14]

C_ASSERT ( EXEFMT_LOAD_HEADER_SIZE >=  sizeofIMAGE_DOS_HEADER)

◆ C_ASSERT() [2/14]

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

◆ C_ASSERT() [3/14]

◆ C_ASSERT() [4/14]

◆ C_ASSERT() [5/14]

◆ C_ASSERT() [6/14]

C_ASSERT ( PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion)  )

◆ C_ASSERT() [7/14]

C_ASSERT ( PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion)  )

◆ C_ASSERT() [8/14]

◆ C_ASSERT() [9/14]

◆ C_ASSERT() [10/14]

◆ C_ASSERT() [11/14]

◆ C_ASSERT() [12/14]

◆ C_ASSERT() [13/14]

◆ C_ASSERT() [14/14]

◆ DPRINT()

DPRINT ( "Checking segment for file %wZ at offset 0x%I64X.\n"  ,
&Segment->FileObject->  FileName,
Offset->  QuadPart 
)

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

2596{
2597 SIZE_T SizeOfSegments;
2598 PMM_SECTION_SEGMENT Segments;
2599
2600 /* TODO: check for integer overflow */
2601 SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
2602
2604 SizeOfSegments,
2606
2607 if(Segments)
2608 RtlZeroMemory(Segments, SizeOfSegments);
2609
2610 return Segments;
2611}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
struct _MM_SECTION_SEGMENT MM_SECTION_SEGMENT
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#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 3029 of file section.c.

3031{
3033 PVOID FileHeader;
3034 PVOID FileHeaderBuffer;
3035 ULONG FileHeaderSize;
3036 ULONG Flags;
3037 ULONG OldNrSegments;
3039 ULONG i;
3040
3041 /*
3042 * Read the beginning of the file (2 pages). Should be enough to contain
3043 * all (or most) of the headers
3044 */
3045 Offset.QuadPart = 0;
3046
3048 &Offset,
3049 PAGE_SIZE * 2,
3050 &FileHeader,
3051 &FileHeaderBuffer,
3052 &FileHeaderSize);
3053
3054 if (!NT_SUCCESS(Status))
3055 return Status;
3056
3057 if (FileHeaderSize == 0)
3058 {
3059 ExFreePool(FileHeaderBuffer);
3060 return STATUS_UNSUCCESSFUL;
3061 }
3062
3063 /*
3064 * Look for a loader that can handle this executable
3065 */
3066 for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
3067 {
3068 Flags = 0;
3069
3070 Status = ExeFmtpLoaders[i](FileHeader,
3071 FileHeaderSize,
3072 FileObject,
3073 ImageSectionObject,
3074 &Flags,
3077
3078 if (!NT_SUCCESS(Status))
3079 {
3080 if (ImageSectionObject->Segments)
3081 {
3082 ExFreePool(ImageSectionObject->Segments);
3083 ImageSectionObject->Segments = NULL;
3084 }
3085 }
3086
3088 break;
3089 }
3090
3091 ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
3092
3093 /*
3094 * No loader handled the format
3095 */
3097 {
3100 }
3101
3102 if (!NT_SUCCESS(Status))
3103 return Status;
3104
3105 ASSERT(ImageSectionObject->Segments != NULL);
3106 ASSERT(ImageSectionObject->RefCount > 0);
3107
3108 /*
3109 * Some defaults
3110 */
3111 /* FIXME? are these values platform-dependent? */
3112 if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
3113 ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
3114
3115 if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
3116 ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
3117
3118 if(ImageSectionObject->BasedAddress == NULL)
3119 {
3120 if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3121 ImageSectionObject->BasedAddress = (PVOID)0x10000000;
3122 else
3123 ImageSectionObject->BasedAddress = (PVOID)0x00400000;
3124 }
3125
3126 /*
3127 * And now the fun part: fixing the segments
3128 */
3129
3130 /* Sort them by virtual address */
3131 MmspSortSegments(ImageSectionObject, Flags);
3132
3133 /* Ensure they don't overlap in memory */
3134 if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
3136
3137 /* Ensure they are aligned */
3138 OldNrSegments = ImageSectionObject->NrSegments;
3139
3140 if (!MmspPageAlignSegments(ImageSectionObject, Flags))
3142
3143 /* Trim them if the alignment phase merged some of them */
3144 if (ImageSectionObject->NrSegments < OldNrSegments)
3145 {
3146 PMM_SECTION_SEGMENT Segments;
3147 SIZE_T SizeOfSegments;
3148
3149 SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
3150
3152 SizeOfSegments,
3154
3155 if (Segments == NULL)
3157
3158 RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
3159 ExFreePool(ImageSectionObject->Segments);
3160 ImageSectionObject->Segments = Segments;
3161 }
3162
3163 /* And finish their initialization */
3164 for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
3165 {
3166 ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
3167 ImageSectionObject->Segments[i].ReferenceCount = &ImageSectionObject->RefCount;
3168 ImageSectionObject->Segments[i].Flags = &ImageSectionObject->SegFlags;
3169 MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
3170 ImageSectionObject->Segments[i].FileObject = FileObject;
3171 }
3172
3173 ASSERT(ImageSectionObject->RefCount > 0);
3174
3175 ImageSectionObject->FileObject = FileObject;
3176
3178 return Status;
3179}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
#define STATUS_ROS_EXEFMT_UNKNOWN_FORMAT
Definition: exeformat.h:72
Status
Definition: gdiplustypes.h:25
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:539
#define IMAGE_FILE_DLL
Definition: pedump.c:169
static PMM_SECTION_SEGMENT NTAPI ExeFmtpAllocateSegments(IN ULONG NrSegments)
Definition: section.c:2595
static BOOLEAN NTAPI MmspPageAlignSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2846
static BOOLEAN NTAPI MmspCheckSegmentBounds(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2795
static VOID NTAPI MmspSortSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2769
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:2615
static PEXEFMT_LOADER ExeFmtpLoaders[]
Definition: section.c:2584
PLARGE_INTEGER Offset
Definition: section.c:5134
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274

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

2621{
2624 ULONG AdjustOffset;
2625 ULONG OffsetAdjustment;
2627 ULONG UsedSize;
2628 PVOID Buffer;
2631
2633
2634 if(Length == 0)
2635 {
2636 KeBugCheck(MEMORY_MANAGEMENT);
2637 }
2638
2639 FileOffset = *Offset;
2640
2641 /* Negative/special offset: it cannot be used in this context */
2642 if(FileOffset.u.HighPart < 0)
2643 {
2644 KeBugCheck(MEMORY_MANAGEMENT);
2645 }
2646
2647 AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
2648 OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
2649 FileOffset.u.LowPart = AdjustOffset;
2650
2651 BufferSize = Length + OffsetAdjustment;
2653
2654 /*
2655 * It's ok to use paged pool, because this is a temporary buffer only used in
2656 * the loading of executables. The assumption is that MmCreateSection is
2657 * always called at low IRQLs and that these buffers don't survive a brief
2658 * initialization phase
2659 */
2661 if (!Buffer)
2662 {
2664 }
2665
2667
2668 UsedSize = (ULONG)Iosb.Information;
2669
2670 if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
2671 {
2674 }
2675
2676 if(NT_SUCCESS(Status))
2677 {
2678 *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
2679 *AllocBase = Buffer;
2680 *ReadSize = UsedSize - OffsetAdjustment;
2681 }
2682 else
2683 {
2684 ExFreePoolWithTag(Buffer, 'rXmM');
2685 }
2686
2687 return Status;
2688}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1434
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
Definition: bufpool.h:45
Definition: File.h:16
#define BufferSize
Definition: mmc.h:75
return Iosb
Definition: create.c:4403
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI MiSimpleRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PVOID Buffer, ULONG Length, BOOLEAN Paging, PIO_STATUS_BLOCK ReadStatus)
Definition: io.c:109
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
#define ASSERT_IRQL_LESS(x)
Definition: debug.h:253
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by ExeFmtpCreateImageSection().

◆ FreeSegmentPage()

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

Definition at line 960 of file section.c.

961{
964
966
968
970
971 /* This must be either a valid entry or nothing */
973
974 /* There should be no reference anymore */
976
978 /* If there is a page, this must be because it's still dirty */
979 ASSERT(Page != 0);
980
981 /* Write the page */
982 if (IS_DIRTY_SSE(Entry))
983 MiWritePage(Segment, Offset->QuadPart, Page);
984
986}
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1609
#define MmLockSectionSegment(x)
Definition: mm.h:1404
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1392
#define MC_USER
Definition: mm.h:114
#define MmUnlockSectionSegment(x)
Definition: mm.h:1412
#define IS_DIRTY_SSE(E)
Definition: mm.h:1384
#define PFN_FROM_SSE(E)
Definition: mm.h:1375
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1376
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:72
ULONG PFN_NUMBER
Definition: ke.h:9
PFN_NUMBER Page
Definition: section.c:5140
NTSTATUS NTAPI MiWritePage(PMM_SECTION_SEGMENT Segment, LONGLONG SegOffset, PFN_NUMBER Page)
Definition: section.c:238
base of all file and directory entries
Definition: entries.h:83

Referenced by _When_().

◆ if() [1/2]

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

Definition at line 5285 of file section.c.

5286 {
5287 ULONG_PTR NewEntry = 0;
5288 /* Restore the swap entry here */
5289 if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
5290 {
5292 if (SwapEntry)
5293 NewEntry = MAKE_SWAP_SSE(SwapEntry);
5294 }
5295
5296 /* Yes. Release it */
5299 /* Tell the caller we released the page */
5300 return TRUE;
5301 }
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define MAKE_SWAP_SSE(S)
Definition: mm.h:1381
ULONG_PTR SWAPENTRY
Definition: mm.h:57
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:500
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:56

◆ if() [2/2]

if ( Entry  = = 0)

Definition at line 5149 of file section.c.

5154 {
5155 BOOLEAN DirtyAgain;
5156
5157 /*
5158 * We got a dirty entry. This path is for the shared data,
5159 * be-it regular file maps or shared sections of DLLs
5160 */
5162 FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
5163
5164 /* Insert the cleaned entry back. Mark it as write in progress, and clear the dirty bit. */
5168
5170
5171 if (FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
5172 {
5174 KIRQL OldIrql;
5175
5176 /* We have to write it back to the file. Tell the FS driver who we are */
5177 if (PageOut)
5178 {
5179 LARGE_INTEGER EndOffset = *Offset;
5180
5182
5183 /* We need to disable all APCs */
5185
5186 EndOffset.QuadPart += PAGE_SIZE;
5188 &EndOffset,
5190 if (NT_SUCCESS(Status))
5191 {
5193 }
5194 else
5195 {
5196 /* Make sure we will not try to release anything */
5198 }
5199 }
5200 else
5201 {
5202 /* We don't have to lock. Say this is success */
5204 }
5205
5206 /* Go ahead and write the page, if previous locking succeeded */
5207 if (NT_SUCCESS(Status))
5208 {
5209 DPRINT("Writing page at offset %I64d for file %wZ, Pageout: %s\n",
5210 Offset->QuadPart, &Segment->FileObject->FileName, PageOut ? "TRUE" : "FALSE");
5211 Status = MiWritePage(Segment, Offset->QuadPart, Page);
5212 }
5213
5214 if (PageOut)
5215 {
5217 if (ResourceToRelease != NULL)
5218 {
5220 }
5222 }
5223 }
5224 else
5225 {
5226 /* This must only be called by the page-out path */
5227 ASSERT(PageOut);
5228
5229 /* And this must be for a shared section in a DLL */
5230 ASSERT(FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
5231
5233 if (!SwapEntry)
5234 {
5235 SwapEntry = MmAllocSwapPage();
5236 }
5237
5238 if (SwapEntry)
5239 {
5240 Status = MmWriteToSwapPage(SwapEntry, Page);
5241 if (NT_SUCCESS(Status))
5242 {
5243 MmSetSavedSwapEntryPage(Page, SwapEntry);
5244 }
5245 else
5246 {
5247 MmFreeSwapPage(SwapEntry);
5248 }
5249 }
5250 else
5251 {
5252 DPRINT1("Failed to allocate a swap page!\n");
5254 }
5255 }
5256
5258
5259 /* Get the entry again */
5262
5263 if (!NT_SUCCESS(Status))
5264 {
5265 /* Damn, this failed. Consider this page as still dirty */
5266 DPRINT1("MiWritePage FAILED: Status 0x%08x!\n", Status);
5267 DirtyAgain = TRUE;
5268 }
5269 else
5270 {
5271 /* Check if someone dirtified this page while we were not looking */
5272 DirtyAgain = IS_DIRTY_SSE(Entry);
5273 }
5274
5275 /* Drop the reference we got, deleting the write altogether. */
5277 if (DirtyAgain)
5278 {
5280 }
5282 }
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
_Check_return_ NTSTATUS NTAPI FsRtlAcquireFileForModWriteEx(_In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER EndingOffset, _Outptr_result_maybenull_ PERESOURCE *ResourceToRelease)
Lock a file object before flushing pages to disk. To be called by the Modified Page Writer (MPW)
Definition: fastio.c:1858
VOID NTAPI FsRtlReleaseFileForModWrite(_In_ PFILE_OBJECT FileObject, _In_ PERESOURCE ResourceToRelease)
Unlock a file object after flushing pages to disk. To be called by the Modified Page Writer (MPW) aft...
Definition: fastio.c:1965
#define DIRTY_SSE(E)
Definition: mm.h:1382
#define MAKE_SSE(P, C)
Definition: mm.h:1394
SWAPENTRY NTAPI MmAllocSwapPage(VOID)
Definition: pagefile.c:322
NTSTATUS NTAPI MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:147
#define PAGE_FROM_SSE(E)
Definition: mm.h:1390
VOID NTAPI MmFreeSwapPage(SWAPENTRY Entry)
Definition: pagefile.c:291
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:484
#define WRITE_SSE(E)
Definition: mm.h:1385
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
PLARGE_INTEGER BOOLEAN BOOLEAN PageOut
Definition: section.c:5137
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PLARGE_INTEGER _Out_ struct _ERESOURCE ** ResourceToRelease
Definition: iotypes.h:1598

◆ ImageSectionObjectFromSegment()

PMM_IMAGE_SECTION_OBJECT ImageSectionObjectFromSegment ( PMM_SECTION_SEGMENT  Segment)

Definition at line 120 of file section.c.

121{
122 ASSERT((Segment->SegFlags & MM_DATAFILE_SEGMENT) == 0);
123
124 return CONTAINING_RECORD(Segment->ReferenceCount, MM_IMAGE_SECTION_OBJECT, RefCount);
125}

Referenced by MiRosUnmapViewOfSection().

◆ MiCopyFromUserPage()

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

Definition at line 1170 of file section.c.

1171{
1173 KIRQL Irql;
1174 PVOID DestAddress;
1175
1177 DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
1178 if (DestAddress == NULL)
1179 {
1180 return STATUS_NO_MEMORY;
1181 }
1182 ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
1183 ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
1184 RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
1185 MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
1186 return STATUS_SUCCESS;
1187}
_Out_ PKIRQL Irql
Definition: csq.h:179
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:91
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:28
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by MmAccessFaultSectionView().

◆ MiGrabDataSection()

static PMM_SECTION_SEGMENT MiGrabDataSection ( PSECTION_OBJECT_POINTERS  SectionObjectPointer)
static

Definition at line 90 of file section.c.

91{
92 KIRQL OldIrql = MiAcquirePfnLock();
94
95 while (TRUE)
96 {
97 Segment = SectionObjectPointer->DataSectionObject;
98 if (!Segment)
99 break;
100
102 {
103 MiReleasePfnLock(OldIrql);
105 OldIrql = MiAcquirePfnLock();
106 continue;
107 }
108
111 break;
112 }
113
114 MiReleasePfnLock(OldIrql);
115
116 return Segment;
117}
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1369
#define KernelMode
Definition: asm.h:38
#define MM_SEGMENT_INCREATE
Definition: mm.h:247
static LARGE_INTEGER TinyTime
Definition: section.c:63

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

◆ MiMapViewInSystemSpace()

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

◆ MiPurgeImageSegment()

static BOOLEAN MiPurgeImageSegment ( PMM_SECTION_SEGMENT  Segment)
static

Definition at line 4315 of file section.c.

4316{
4318
4320
4321 /* Loop over all entries */
4322 for (PageTable = RtlEnumerateGenericTable(&Segment->PageTable, TRUE);
4323 PageTable != NULL;
4325 {
4326 for (ULONG i = 0; i < _countof(PageTable->PageEntries); i++)
4327 {
4328 ULONG_PTR Entry = PageTable->PageEntries[i];
4330
4331 if (!Entry)
4332 continue;
4333
4335 {
4336 /* I/O ongoing or swap entry. Someone mapped this file as we were not looking */
4338 return FALSE;
4339 }
4340
4341 /* Regular entry */
4344
4345 /* Properly remove using the used API */
4346 Offset.QuadPart = PageTable->FileOffset.QuadPart + (i << PAGE_SHIFT);
4349 }
4350 }
4351
4353
4354 return TRUE;
4355}
#define IS_WRITE_SSE(E)
Definition: mm.h:1386
#define _countof(array)
Definition: sndvol32.h:70
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ BOOLEAN Restart)

Referenced by MmFlushImageSection().

◆ MiRosUnmapViewInSystemSpace()

NTSTATUS NTAPI MiRosUnmapViewInSystemSpace ( IN PVOID  MappedBase)

Definition at line 4562 of file section.c.

4563{
4564 DPRINT("MmUnmapViewInSystemSpace() called\n");
4565
4567}
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1733
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:3530
_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 3594 of file section.c.

3597{
3601 PVOID ImageBaseAddress = 0;
3602
3603 DPRINT("Opening memory area Process %p BaseAddress %p\n",
3605
3606 ASSERT(Process);
3607
3608 AddressSpace = &Process->Vm;
3609
3611 BaseAddress);
3612 if (MemoryArea == NULL ||
3613#ifdef NEWCC
3614 ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) && (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
3615#else
3617#endif
3619
3620 {
3622
3623 DPRINT1("Unable to find memory area at address %p.\n", BaseAddress);
3625 }
3626
3628 {
3629 ULONG i;
3630 ULONG NrSegments;
3631 PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3632 PMM_SECTION_SEGMENT SectionSegments;
3634
3635 Segment = MemoryArea->SectionData.Segment;
3636 ImageSectionObject = ImageSectionObjectFromSegment(Segment);
3637 SectionSegments = ImageSectionObject->Segments;
3638 NrSegments = ImageSectionObject->NrSegments;
3639
3641
3642 /* Search for the current segment within the section segments
3643 * and calculate the image base address */
3644 for (i = 0; i < NrSegments; i++)
3645 {
3646 if (Segment == &SectionSegments[i])
3647 {
3648 ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
3649 break;
3650 }
3651 }
3652 if (i >= NrSegments)
3653 {
3654 KeBugCheck(MEMORY_MANAGEMENT);
3655 }
3656
3657 for (i = 0; i < NrSegments; i++)
3658 {
3659 PVOID SBaseAddress = (PVOID)
3660 ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
3661
3662 Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
3663 if (!NT_SUCCESS(Status))
3664 {
3665 DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3666 SBaseAddress, Process, Status);
3668 }
3669 }
3670 DPRINT("One mapping less for %p\n", ImageSectionObject->FileObject->SectionObjectPointer);
3671 InterlockedDecrement(&ImageSectionObject->MapCount);
3672 }
3673 else
3674 {
3676 PMMVAD Vad = &MemoryArea->VadNode;
3677 PCONTROL_AREA ControlArea = Vad->ControlArea;
3680 LARGE_INTEGER ViewOffset;
3681 ViewOffset.QuadPart = MemoryArea->SectionData.ViewOffset;
3682
3683 InterlockedIncrement64(Segment->ReferenceCount);
3684
3685 ViewSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
3686
3688 if (!NT_SUCCESS(Status))
3689 {
3690 DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3693 }
3694
3695 /* These might be deleted now */
3696 Vad = NULL;
3697 MemoryArea = NULL;
3698
3700 {
3701 /* Don't bother */
3702 MmDereferenceSegment(Segment);
3703 return STATUS_SUCCESS;
3704 }
3706
3707 FileObject = Segment->FileObject;
3709
3710 /* Don't bother for auto-delete closed file. */
3712 {
3714 MmDereferenceSegment(Segment);
3715 return STATUS_SUCCESS;
3716 }
3717
3718 /*
3719 * Flush only when last mapping is deleted.
3720 * FIXME: Why ControlArea == NULL? Or rather: is ControlArea ever not NULL here?
3721 */
3722 if (ControlArea == NULL || ControlArea->NumberOfMappedViews == 1)
3723 {
3724 while (ViewSize > 0)
3725 {
3726 ULONG FlushSize = min(ViewSize, PAGE_ROUND_DOWN(MAXULONG));
3727 MmFlushSegment(FileObject->SectionObjectPointer,
3728 &ViewOffset,
3729 FlushSize,
3730 NULL);
3731 ViewSize -= FlushSize;
3732 ViewOffset.QuadPart += FlushSize;
3733 }
3734 }
3735
3737 MmDereferenceSegment(Segment);
3738 }
3739
3740 /* Notify debugger */
3741 if (ImageBaseAddress && !SkipDebuggerNotify) DbgkUnMapViewOfSection(ImageBaseAddress);
3742
3743 return STATUS_SUCCESS;
3744}
#define InterlockedDecrement
Definition: armddk.h:52
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
#define ULONG_PTR
Definition: config.h:101
#define min(a, b)
Definition: monoChain.cc:55
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
@ VadImageMap
Definition: mmtypes.h:206
_In_ PMEMORY_AREA MemoryArea
Definition: newmm.h:207
VOID NTAPI FsRtlReleaseFile(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1665
VOID NTAPI FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1640
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:97
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
#define MM_PHYSICALMEMORY_SEGMENT
Definition: mm.h:244
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:262
PMM_IMAGE_SECTION_OBJECT ImageSectionObjectFromSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:120
NTSTATUS NTAPI MmFlushSegment(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _Out_opt_ PIO_STATUS_BLOCK Iosb)
Definition: section.c:5051
struct _MEMORY_AREA::@1805 SectionData
BOOLEAN DeleteInProgress
Definition: mm.h:260
ULONG Type
Definition: mm.h:258
MMVAD VadNode
Definition: mm.h:256
ULONG_PTR VadType
Definition: mmtypes.h:694
union _MMVAD::@2631 u
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
PCONTROL_AREA ControlArea
Definition: mmtypes.h:736
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
struct _MM_SECTION_SEGMENT::@1804 Image
else
Definition: tritemp.h:161
#define MAXULONG
Definition: typedefs.h:251
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
#define FO_DELETE_ON_CLOSE
Definition: iotypes.h:1792

Referenced by MiRosCleanupMemoryArea(), and MiUnmapViewOfSection().

◆ MiWritePage()

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

Definition at line 238 of file section.c.

248{
252 UCHAR MdlBase[sizeof(MDL) + sizeof(PFN_NUMBER)];
253 PMDL Mdl = (PMDL)MdlBase;
254 PFILE_OBJECT FileObject = Segment->FileObject;
256
257 FileOffset.QuadPart = Segment->Image.FileOffset + SegOffset;
258
259 RtlZeroMemory(MdlBase, sizeof(MdlBase));
262 Mdl->MdlFlags |= MDL_PAGES_LOCKED;
263
266 if (Status == STATUS_PENDING)
267 {
269 Status = IoStatus.Status;
270 }
271 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
272 {
273 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
274 }
275
276 return Status;
277}
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoSynchronousPageWrite(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1146
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
@ NotificationEvent
VOID NTAPI MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
Definition: pagefile.c:111
PVOID PMDL
Definition: usb.h:39
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
@ Executive
Definition: ketypes.h:415
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
MDL
Definition: mmtypes.h:117
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by FreeSegmentPage().

◆ MmAccessFaultSectionView()

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

Definition at line 1915 of file section.c.

1919{
1921 PFN_NUMBER OldPage;
1922 PFN_NUMBER NewPage;
1923 PFN_NUMBER UnmappedPage;
1924 PVOID PAddress;
1929 BOOLEAN Cow = FALSE;
1931 BOOLEAN Unmapped;
1933
1934 DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1935
1936 /* Get the region for this address */
1938 &MemoryArea->SectionData.RegionListHead,
1939 Address, NULL);
1940 ASSERT(Region != NULL);
1941 if (!(Region->Protect & PAGE_IS_WRITABLE))
1943
1944 /* Make sure we have a page mapping for this address. */
1946 {
1948 if (!NT_SUCCESS(Status))
1949 {
1950 /* This is invalid access ! */
1951 return Status;
1952 }
1953 }
1954
1955 /*
1956 * Check if the page has already been set readwrite
1957 */
1959 {
1960 DPRINT("Address 0x%p\n", Address);
1961 return STATUS_SUCCESS;
1962 }
1963
1964 /* Check if we are doing Copy-On-Write */
1965 Segment = MemoryArea->SectionData.Segment;
1966 Cow = Segment->WriteCopy || (Region->Protect & PAGE_IS_WRITECOPY);
1967
1968 if (!Cow)
1969 {
1970 /* Simply update page protection and we're done */
1972 return STATUS_SUCCESS;
1973 }
1974
1975 /* Calculate the new protection & check if we should update the region */
1976 NewProtect = Region->Protect;
1978 {
1979 NewProtect &= ~PAGE_IS_WRITECOPY;
1980 if (Region->Protect & PAGE_IS_EXECUTABLE)
1982 else
1985 &MemoryArea->SectionData.RegionListHead,
1988 }
1989
1990 /*
1991 * Find the offset of the page
1992 */
1993 PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1994 Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1995 + MemoryArea->SectionData.ViewOffset;
1996
1997 /* Get the page mapping this section offset. */
2000
2001 /* Get the current page mapping for the process */
2002 ASSERT(MmIsPagePresent(Process, PAddress));
2003 OldPage = MmGetPfnForProcess(Process, PAddress);
2004 ASSERT(OldPage != 0);
2005
2006 if (IS_SWAP_FROM_SSE(Entry) ||
2007 PFN_FROM_SSE(Entry) != OldPage)
2008 {
2010 /* This is a private page. We must only change the page protection. */
2012 return STATUS_SUCCESS;
2013 }
2014
2015 /*
2016 * Allocate a page
2017 */
2019 if (!NT_SUCCESS(Status))
2020 {
2022 return STATUS_NO_MEMORY;
2023 }
2024
2025 /*
2026 * Copy the old page
2027 */
2028 NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
2029
2030 /*
2031 * Unshare the old page.
2032 */
2033 DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
2034 Unmapped = MmDeleteVirtualMapping(Process, PAddress, NULL, &UnmappedPage);
2035 if (!Unmapped || (UnmappedPage != OldPage))
2036 {
2037 /* Uh , we had a page just before, but suddenly it changes. Someone corrupted us. */
2038 KeBugCheckEx(MEMORY_MANAGEMENT,
2040 (ULONG_PTR)PAddress,
2041 (ULONG_PTR)__FILE__,
2042 __LINE__);
2043 }
2044
2045 if (Process)
2046 MmDeleteRmap(OldPage, Process, PAddress);
2049
2050 /*
2051 * Set the PTE to point to the new page
2052 */
2053 if (!NT_SUCCESS(MmCreateVirtualMapping(Process, PAddress, NewProtect, NewPage)))
2054 {
2055 DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2056 KeBugCheck(MEMORY_MANAGEMENT);
2057 }
2058
2059 if (Process)
2060 MmInsertRmap(NewPage, Process, PAddress);
2061
2062 DPRINT("Address 0x%p\n", Address);
2063 return STATUS_SUCCESS;
2064}
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:251
#define PAGE_IS_WRITABLE
Definition: mm.h:160
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1718
BOOLEAN NTAPI MmIsPagePresent(struct _EPROCESS *Process, PVOID Address)
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_EXECUTABLE
Definition: mm.h:166
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:313
NTSTATUS NTAPI MmCreateVirtualMapping(struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PFN_NUMBER Page)
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:131
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define PAGE_IS_WRITECOPY
Definition: mm.h:172
VOID NTAPI MmDeleteVirtualMapping(IN PEPROCESS Process, IN PVOID Address, OUT PBOOLEAN WasDirty, OUT PPFN_NUMBER Page)
Definition: page.c:177
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
static WCHAR Address[46]
Definition: ping.c:68
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
NTSTATUS NTAPI MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
Definition: section.c:1537
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
Definition: section.c:1089
static NTSTATUS MiCopyFromUserPage(PFN_NUMBER DestPage, const VOID *SrcAddress)
Definition: section.c:1170
static VOID MmAlterViewAttributes(PMMSUPPORT AddressSpace, PVOID BaseAddress, SIZE_T RegionSize, ULONG OldType, ULONG OldProtect, ULONG NewType, ULONG NewProtect)
Definition: section.c:1446
Definition: mm.h:470
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3304

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

1453{
1456 BOOLEAN DoCOW = FALSE;
1457 ULONG i;
1459
1462 Segment = MemoryArea->SectionData.Segment;
1464
1465 if ((Segment->WriteCopy) &&
1467 {
1468 DoCOW = TRUE;
1469 }
1470
1471 if (OldProtect != NewProtect)
1472 {
1473 for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
1474 {
1475 SWAPENTRY SwapEntry;
1476 PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE);
1478
1479 /* Wait for a wait entry to disappear */
1480 do
1481 {
1482 MmGetPageFileMapping(Process, Address, &SwapEntry);
1483 if (SwapEntry != MM_WAIT_ENTRY)
1484 break;
1490 }
1491 while (TRUE);
1492
1493 /*
1494 * If we doing COW for this segment then check if the page is
1495 * already private.
1496 */
1498 {
1502
1504 + MemoryArea->SectionData.ViewOffset;
1506 /*
1507 * An MM_WAIT_ENTRY is ok in this case... It'll just count as
1508 * IS_SWAP_FROM_SSE and we'll do the right thing.
1509 */
1511
1512 /* Choose protection based on what was requested */
1515 else
1517
1519 {
1521 }
1522 }
1523
1525 {
1527 Protect);
1528 }
1529 }
1530 }
1531
1533}
#define PAGE_READONLY
Definition: compat.h:138
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1698
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
BOOLEAN NTAPI MmIsDisabledPage(struct _EPROCESS *Process, PVOID Address)
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1711
_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:221

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

◆ MmCanFileBeTruncated()

BOOLEAN NTAPI MmCanFileBeTruncated ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_opt_ PLARGE_INTEGER  NewFileSize 
)

Definition at line 4260 of file section.c.

4263{
4264 BOOLEAN Ret;
4266
4267 /* Check whether an ImageSectionObject exists */
4268 if (SectionObjectPointer->ImageSectionObject != NULL)
4269 {
4270 DPRINT1("ERROR: File can't be truncated because it has an image section\n");
4271 return FALSE;
4272 }
4273
4275 if (!Segment)
4276 {
4277 /* There is no data section. It's fine to do anything. */
4278 return TRUE;
4279 }
4280
4282 if ((Segment->SectionCount == 0) ||
4283 ((Segment->SectionCount == 1) && (SectionObjectPointer->SharedCacheMap != NULL)))
4284 {
4285 /* If the cache is the only one holding a reference to the segment, then it's fine to resize */
4286 Ret = TRUE;
4287 }
4288 else if (NewFileSize != NULL)
4289 {
4290 /* We can't shrink, but we can extend */
4291 Ret = NewFileSize->QuadPart >= Segment->RawLength.QuadPart;
4292#if DBG
4293 if (!Ret)
4294 {
4295 DPRINT1("Cannot truncate data: New Size %I64d, Segment Size %I64d\n", NewFileSize->QuadPart, Segment->RawLength.QuadPart);
4296 }
4297#endif
4298 }
4299 else
4300 {
4301 DPRINT1("ERROR: File can't be truncated because it has references held to its data section\n");
4302 Ret = FALSE;
4303 }
4304
4306 MmDereferenceSegment(Segment);
4307
4308 DPRINT("FIXME: didn't check for outstanding write probes\n");
4309
4310 return Ret;
4311}
static PMM_SECTION_SEGMENT MiGrabDataSection(PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: section.c:90
_In_opt_ PLARGE_INTEGER NewFileSize
Definition: mmfuncs.h:608

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

2108{
2109 SECTION Section;
2110 PSECTION NewSection;
2111 PSUBSECTION Subsection;
2112 PSEGMENT NewSegment, Segment;
2114 PCONTROL_AREA ControlArea;
2115 ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2117 BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2118 KIRQL OldIrql;
2120 BOOLEAN UserRefIncremented = FALSE;
2121 PVOID PreviousSectionPointer;
2122
2123 /* Make the same sanity checks that the Nt interface should've validated */
2126 SEC_NO_CHANGE)) == 0);
2136
2137 /* Convert section flag to page flag */
2140
2141 /* Check to make sure the protection is correct. Nt* does this already */
2143 if (ProtectionMask == MM_INVALID_PROTECTION)
2144 {
2145 DPRINT1("Invalid protection mask\n");
2147 }
2148
2149 /* Check if this is going to be a data or image backed file section */
2150 if ((FileHandle) || (FileObject))
2151 {
2152 /* These cannot be mapped with large pages */
2154
2155 /* For now, only support the mechanism through a file handle */
2157
2158 /* Reference the file handle to get the object */
2160 MmMakeFileAccess[ProtectionMask],
2163 (PVOID*)&File,
2164 NULL);
2165 if (!NT_SUCCESS(Status)) return Status;
2166
2167 /* Make sure Cc has been doing its job */
2168 if (!File->SectionObjectPointer)
2169 {
2170 /* This is not a valid file system-based file, fail */
2173 }
2174
2175 /* Image-file backed sections are not yet supported */
2177
2178 /* Compute the size of the control area, and allocate it */
2179 ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2180 ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2181 if (!ControlArea)
2182 {
2185 }
2186
2187 /* Zero it out */
2188 RtlZeroMemory(ControlArea, ControlAreaSize);
2189
2190 /* Did we get a handle, or an object? */
2191 if (FileHandle)
2192 {
2193 /* We got a file handle so we have to lock down the file */
2194#if 0
2196 if (!NT_SUCCESS(Status))
2197 {
2198 ExFreePool(ControlArea);
2200 return Status;
2201 }
2202#else
2203 /* ReactOS doesn't support this API yet, so do nothing */
2206#endif
2207 /* Update the top-level IRP so that drivers know what's happening */
2209 FileLock = TRUE;
2210 }
2211
2212 /* Lock the PFN database while we play with the section pointers */
2213 OldIrql = MiAcquirePfnLock();
2214
2215 /* Image-file backed sections are not yet supported */
2217
2218 /* There should not already be a control area for this file */
2219 ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2220 NewSegment = NULL;
2221
2222 /* Write down that this CA is being created, and set it */
2223 ControlArea->u.Flags.BeingCreated = TRUE;
2225 PreviousSectionPointer = File->SectionObjectPointer;
2226 File->SectionObjectPointer->DataSectionObject = ControlArea;
2227
2228 /* We can release the PFN lock now */
2229 MiReleasePfnLock(OldIrql);
2230
2231 /* We don't support previously-mapped file */
2232 ASSERT(NewSegment == NULL);
2233
2234 /* Image-file backed sections are not yet supported */
2236
2237 /* So we always create a data file map */
2239 &Segment,
2240 (PSIZE_T)InputMaximumSize,
2243 KernelCall);
2244 if (!NT_SUCCESS(Status))
2245 {
2246 /* Lock the PFN database while we play with the section pointers */
2247 OldIrql = MiAcquirePfnLock();
2248
2249 /* Reset the waiting-for-deletion event */
2250 ASSERT(ControlArea->WaitingForDeletion == NULL);
2251 ControlArea->WaitingForDeletion = NULL;
2252
2253 /* Set the file pointer NULL flag */
2254 ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2255 ControlArea->u.Flags.FilePointerNull = TRUE;
2256
2257 /* Delete the data section object */
2259 File->SectionObjectPointer->DataSectionObject = NULL;
2260
2261 /* No longer being created */
2262 ControlArea->u.Flags.BeingCreated = FALSE;
2263
2264 /* We can release the PFN lock now */
2265 MiReleasePfnLock(OldIrql);
2266
2267 /* Check if we locked and set the IRP */
2268 if (FileLock)
2269 {
2270 /* Undo */
2272 //FsRtlReleaseFile(File);
2273 }
2274
2275 /* Free the control area and de-ref the file object */
2276 ExFreePool(ControlArea);
2278
2279 /* All done */
2280 return Status;
2281 }
2282
2283 /* On success, we expect this */
2284 ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2285
2286 /* Check if a maximum size was specified */
2287 if (!InputMaximumSize->QuadPart)
2288 {
2289 /* Nope, use the segment size */
2290 Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2291 }
2292 else
2293 {
2294 /* Yep, use the entered size */
2295 Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2296 }
2297 }
2298 else
2299 {
2300 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2302
2303 /* Not yet supported */
2305
2306 /* So this must be a pagefile-backed section, create the mappings needed */
2307 Status = MiCreatePagingFileMap(&NewSegment,
2308 InputMaximumSize,
2309 ProtectionMask,
2311 if (!NT_SUCCESS(Status)) return Status;
2312
2313 /* Set the size here, and read the control area */
2314 Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2315 ControlArea = NewSegment->ControlArea;
2316
2317 /* MiCreatePagingFileMap increments user references */
2318 UserRefIncremented = TRUE;
2319 }
2320
2321 /* Did we already have a segment? */
2322 if (!NewSegment)
2323 {
2324 /* This must be the file path and we created a segment */
2325 NewSegment = Segment;
2326 ASSERT(File != NULL);
2327
2328 /* Acquire the PFN lock while we set control area flags */
2329 OldIrql = MiAcquirePfnLock();
2330
2331 /* We don't support this race condition yet, so assume no waiters */
2332 ASSERT(ControlArea->WaitingForDeletion == NULL);
2333 ControlArea->WaitingForDeletion = NULL;
2334
2335 /* Image-file backed sections are not yet supported, nor ROM images */
2337 ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2338
2339 /* Take off the being created flag, and then release the lock */
2340 ControlArea->u.Flags.BeingCreated = FALSE;
2341 MiReleasePfnLock(OldIrql);
2342 }
2343
2344 /* Check if we locked the file earlier */
2345 if (FileLock)
2346 {
2347 /* Reset the top-level IRP and release the lock */
2349 //FsRtlReleaseFile(File);
2350 FileLock = FALSE;
2351 }
2352
2353 /* Set the initial section object data */
2354 Section.InitialPageProtection = SectionPageProtection;
2355
2356 /* The mapping created a control area and segment, save the flags */
2357 Section.Segment = NewSegment;
2358 Section.u.LongFlags = ControlArea->u.LongFlags;
2359
2360 /* Check if this is a user-mode read-write non-image file mapping */
2361 if (!(FileObject) &&
2363 !(ControlArea->u.Flags.Image) &&
2364 (ControlArea->FilePointer))
2365 {
2366 /* Add a reference and set the flag */
2367 Section.u.Flags.UserWritable = TRUE;
2368 InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2369 }
2370
2371 /* Check for image mappings or page file mappings */
2372 if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2373 {
2374 /* Charge the segment size, and allocate a subsection */
2375 PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2376 Size = sizeof(SUBSECTION);
2377 }
2378 else
2379 {
2380 /* Charge nothing, and allocate a mapped subsection */
2381 PagedCharge = 0;
2382 Size = sizeof(MSUBSECTION);
2383 }
2384
2385 /* Check if this is a normal CA */
2386 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2387 ASSERT(ControlArea->u.Flags.Rom == 0);
2388
2389 /* Charge only a CA, and the subsection is right after */
2390 NonPagedCharge = sizeof(CONTROL_AREA);
2391 Subsection = (PSUBSECTION)(ControlArea + 1);
2392
2393 /* We only support single-subsection mappings */
2394 NonPagedCharge += Size;
2395 ASSERT(Subsection->NextSubsection == NULL);
2396
2397 /* Create the actual section object, with enough space for the prototype PTEs */
2402 NULL,
2403 sizeof(SECTION),
2404 PagedCharge,
2405 NonPagedCharge,
2406 (PVOID*)&NewSection);
2407 if (!NT_SUCCESS(Status))
2408 {
2409 /* Check if this is a user-mode read-write non-image file mapping */
2410 if (!(FileObject) &&
2412 !(ControlArea->u.Flags.Image) &&
2413 (ControlArea->FilePointer))
2414 {
2415 /* Remove a reference and check the flag */
2416 ASSERT(Section.u.Flags.UserWritable == 1);
2417 InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2418 }
2419
2420 /* Check if a user reference was added */
2421 if (UserRefIncremented)
2422 {
2423 /* Acquire the PFN lock while we change counters */
2424 OldIrql = MiAcquirePfnLock();
2425
2426 /* Decrement the accounting counters */
2427 ControlArea->NumberOfSectionReferences--;
2428 ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2429 ControlArea->NumberOfUserReferences--;
2430
2431 /* Check if we should destroy the CA and release the lock */
2432 MiCheckControlArea(ControlArea, OldIrql);
2433 }
2434
2435 /* Return the failure code */
2436 return Status;
2437 }
2438
2439 /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2440
2441 /* Now copy the local section object from the stack into this new object */
2442 RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2443 NewSection->Address.StartingVpn = 0;
2444
2445 /* For now, only user calls are supported */
2446 ASSERT(KernelCall == FALSE);
2447 NewSection->u.Flags.UserReference = TRUE;
2448
2449 /* Is this a "based" allocation, in which all mappings are identical? */
2451 {
2452 /* Lock the VAD tree during the search */
2454
2455 /* Is it a brand new ControArea ? */
2456 if (ControlArea->u.Flags.BeingCreated == 1)
2457 {
2458 ASSERT(ControlArea->u.Flags.Based == 1);
2459 /* Then we must find a global address, top-down */
2462 _64K,
2464 (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2465
2466 if (!NT_SUCCESS(Status))
2467 {
2468 /* No way to find a valid range. */
2470 ControlArea->u.Flags.Based = 0;
2471 NewSection->u.Flags.Based = 0;
2472 ObDereferenceObject(NewSection);
2473 return Status;
2474 }
2475
2476 /* Compute the ending address and insert it into the VAD tree */
2477 NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2478 NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2479 MiInsertBasedSection(NewSection);
2480 }
2481 else
2482 {
2483 /* 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 !*/
2484 ASSERT(FALSE);
2485 }
2486
2488 }
2489
2490 /* The control area is not being created anymore */
2491 if (ControlArea->u.Flags.BeingCreated == 1)
2492 {
2493 /* Acquire the PFN lock while we set control area flags */
2494 OldIrql = MiAcquirePfnLock();
2495
2496 /* Take off the being created flag, and then release the lock */
2497 ControlArea->u.Flags.BeingCreated = 0;
2498 NewSection->u.Flags.BeingCreated = 0;
2499
2500 MiReleasePfnLock(OldIrql);
2501 }
2502
2503 /* Migrate the attribute into a flag */
2505
2506 /* If R/W access is not requested, this might eventually become a CoW mapping */
2508 {
2509 NewSection->u.Flags.CopyOnWrite = TRUE;
2510 }
2511
2512 /* Write down if this was a kernel call */
2513 ControlArea->u.Flags.WasPurged |= KernelCall;
2514 ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2515
2516 /* Make sure the segment and the section are the same size, or the section is smaller */
2517 ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2518
2519 /* Return the object and the creation status */
2520 *SectionObject = (PVOID)NewSection;
2521 return Status;
2522}
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
static NTSTATUS MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1407
static NTSTATUS MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1422
PVOID MmHighSectionBase
Definition: section.c:111
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
static VOID MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:714
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:140
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
#define InterlockedIncrement
Definition: armddk.h:53
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define ExGetPreviousMode
Definition: ex.h:143
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:423
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:799
#define _64K
Definition: miarm.h:23
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
unsigned __int64 ULONG64
Definition: imports.h:198
#define SECTION
Definition: profile.c:31
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:363
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:364
struct _SUBSECTION * PSUBSECTION
struct _SUBSECTION SUBSECTION
#define SEC_NOCACHE
Definition: mmtypes.h:101
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SEC_IMAGE
Definition: mmtypes.h:97
struct _MSUBSECTION MSUBSECTION
#define SEC_LARGE_PAGES
Definition: mmtypes.h:103
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
struct _CONTROL_AREA CONTROL_AREA
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define SEC_RESERVE
Definition: nt_native.h:1323
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PAGE_GUARD
Definition: nt_native.h:1310
#define SEC_BASED
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1653
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:269
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:480
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
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:1039
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
long LONG
Definition: pedump.c:60
POBJECT_TYPE MmSectionObjectType
Definition: section.c:194
PSEGMENT Segment
Definition: mmtypes.h:521
ULONG NumberOfSectionReferences
Definition: mmtypes.h:523
PEVENT_COUNTER WaitingForDeletion
Definition: mmtypes.h:534
ULONG NumberOfUserReferences
Definition: mmtypes.h:527
ULONG LongFlags
Definition: mmtypes.h:530
ULONG WritableUserReferences
Definition: mmtypes.h:537
MMSECTION_FLAGS Flags
Definition: mmtypes.h:531
PFILE_OBJECT FilePointer
Definition: mmtypes.h:533
union _CONTROL_AREA::@2624 u
ULONG_PTR StartingVpn
Definition: mmtypes.h:653
ULONG_PTR EndingVpn
Definition: mmtypes.h:654
ULONG NoChange
Definition: mmtypes.h:486
ULONG UserReference
Definition: mmtypes.h:479
ULONG CopyOnWrite
Definition: mmtypes.h:474
ULONG FilePointerNull
Definition: mmtypes.h:482
ULONG BeingCreated
Definition: mmtypes.h:464
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:491
ULONG WasPurged
Definition: mmtypes.h:478
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
union _SECTION::@2640 u
PSEGMENT Segment
Definition: mmtypes.h:812
MMADDRESS_NODE Address
Definition: mmtypes.h:811
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:813
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:409
ULONG TotalNumberOfPtes
Definition: mmtypes.h:410
PVOID BasedAddress
Definition: mmtypes.h:418
ULONGLONG SizeOfSegment
Definition: mmtypes.h:413
struct _SUBSECTION * NextSubsection
Definition: mmtypes.h:584
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
int64_t LONGLONG
Definition: typedefs.h:68
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78

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

2343{
2344 PSECTION Section;
2348 KIRQL OldIrql;
2349
2350 /*
2351 * Create the section
2352 */
2357 NULL,
2358 sizeof(*Section),
2359 0,
2360 0,
2361 (PVOID*)&Section);
2362 if (!NT_SUCCESS(Status))
2363 {
2364 return Status;
2365 }
2366 /*
2367 * Initialize it
2368 */
2369 RtlZeroMemory(Section, sizeof(*Section));
2370
2371 /* Mark this as a "ROS" section */
2372 Section->u.Flags.filler = 1;
2374 Section->u.Flags.File = 1;
2375
2377 Section->u.Flags.NoChange = 1;
2379 Section->u.Flags.Reserve = 1;
2380
2381 if (!GotFileHandle)
2382 {
2383 ASSERT(UMaximumSize != NULL);
2384 // ASSERT(UMaximumSize->QuadPart != 0);
2385 MaximumSize = *UMaximumSize;
2386 }
2387 else
2388 {
2391 if (!NT_SUCCESS(Status))
2392 {
2393 ObDereferenceObject(Section);
2394 return Status;
2395 }
2396
2397 /*
2398 * FIXME: Revise this once a locking order for file size changes is
2399 * decided
2400 */
2401 if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
2402 {
2403 MaximumSize = *UMaximumSize;
2404 }
2405 else
2406 {
2408 /* Mapping zero-sized files isn't allowed. */
2409 if (MaximumSize.QuadPart == 0)
2410 {
2411 ObDereferenceObject(Section);
2413 }
2414 }
2415
2416 if (MaximumSize.QuadPart > FileSize.QuadPart)
2417 {
2420 sizeof(LARGE_INTEGER),
2421 &MaximumSize);
2422 if (!NT_SUCCESS(Status))
2423 {
2424 ObDereferenceObject(Section);
2426 }
2427 }
2428 }
2429
2430 if (FileObject->SectionObjectPointer == NULL)
2431 {
2432 ObDereferenceObject(Section);
2434 }
2435
2436 /*
2437 * Lock the file
2438 */
2440 if (Status != STATUS_SUCCESS)
2441 {
2442 ObDereferenceObject(Section);
2443 return Status;
2444 }
2445
2446 /* Lock the PFN lock while messing with Section Object pointers */
2447grab_segment:
2448 OldIrql = MiAcquirePfnLock();
2449 Segment = FileObject->SectionObjectPointer->DataSectionObject;
2450
2451 while (Segment && (Segment->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
2452 {
2453 MiReleasePfnLock(OldIrql);
2455 OldIrql = MiAcquirePfnLock();
2456 Segment = FileObject->SectionObjectPointer->DataSectionObject;
2457 }
2458
2459 /*
2460 * If this file hasn't been mapped as a data file before then allocate a
2461 * section segment to describe the data file mapping
2462 */
2463 if (Segment == NULL)
2464 {
2465 /* Release the lock. ExAllocatePoolWithTag might acquire it */
2466 MiReleasePfnLock(OldIrql);
2467
2470 if (Segment == NULL)
2471 {
2472 //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2473 ObDereferenceObject(Section);
2474 return STATUS_NO_MEMORY;
2475 }
2476
2477 /* We are creating it */
2478 RtlZeroMemory(Segment, sizeof(*Segment));
2480 Segment->RefCount = 1;
2481
2482 /* Acquire lock again */
2483 OldIrql = MiAcquirePfnLock();
2484
2485 if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
2486 {
2487 /* Well that's bad luck. Restart it all over */
2488 MiReleasePfnLock(OldIrql);
2490 goto grab_segment;
2491 }
2492
2493 FileObject->SectionObjectPointer->DataSectionObject = Segment;
2494
2495 /* We're safe to release the lock now */
2496 MiReleasePfnLock(OldIrql);
2497
2498 Section->Segment = (PSEGMENT)Segment;
2499
2500 /* Self-referencing segment */
2501 Segment->Flags = &Segment->SegFlags;
2502 Segment->ReferenceCount = &Segment->RefCount;
2503
2504 Segment->SectionCount = 1;
2505
2507 Segment->FileObject = FileObject;
2509
2510 Segment->Image.FileOffset = 0;
2511 Segment->Protection = SectionPageProtection;
2512
2513 Segment->Image.Characteristics = 0;
2516 {
2517 Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
2518 }
2519 else
2520 {
2521 Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2522 Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2523 }
2524 Segment->Image.VirtualAddress = 0;
2526
2527 /* We're good to use it now */
2528 OldIrql = MiAcquirePfnLock();
2529 Segment->SegFlags &= ~MM_SEGMENT_INCREATE;
2530 MiReleasePfnLock(OldIrql);
2531 }
2532 else
2533 {
2534 Section->Segment = (PSEGMENT)Segment;
2535 InterlockedIncrement64(&Segment->RefCount);
2536 InterlockedIncrementUL(&Segment->SectionCount);
2537
2538 MiReleasePfnLock(OldIrql);
2539
2541
2542 if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
2544 {
2545 Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2546 Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2547 }
2548
2550 }
2551 Section->SizeOfSection = MaximumSize;
2552
2553 //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2554 *SectionObject = Section;
2555 return STATUS_SUCCESS;
2556}
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1544
@ FileEndOfFileInformation
Definition: from_kernel.h:81
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
NTSTATUS NTAPI IoSetInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN PVOID FileInformation)
Definition: iofunc.c:1314
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
struct _SEGMENT * PSEGMENT
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
NTSTATUS NTAPI FsRtlGetFileSize(IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize)
Definition: fastio.c:815
#define STATUS_MAPPED_FILE_SIZE_ZERO
Definition: ntstatus.h:522
#define STATUS_SECTION_NOT_EXTENDED
Definition: ntstatus.h:371
NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File)
Definition: section.c:907
ULONG InitialPageProtection
Definition: mmtypes.h:819
#define ObReferenceObject
Definition: obfuncs.h:204

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

3189{
3190 PSECTION Section;
3192 PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3193 KIRQL OldIrql;
3194
3195
3196 if (FileObject == NULL)
3198
3199 if (FileObject->SectionObjectPointer == NULL)
3200 {
3201 DPRINT1("Denying section creation due to missing cache initialization\n");
3203 }
3204
3205 /*
3206 * Create the section
3207 */
3212 NULL,
3213 sizeof(*Section),
3214 0,
3215 0,
3216 (PVOID*)(PVOID)&Section);
3217 if (!NT_SUCCESS(Status))
3218 {
3219 return Status;
3220 }
3221
3222 /*
3223 * Initialize it
3224 */
3225 RtlZeroMemory(Section, sizeof(*Section));
3226
3227 /* Mark this as a "ROS" Section */
3228 Section->u.Flags.filler = 1;
3229
3231 Section->u.Flags.File = 1;
3232 Section->u.Flags.Image = 1;
3234 Section->u.Flags.NoChange = 1;
3235
3236grab_image_section_object:
3237 OldIrql = MiAcquirePfnLock();
3238
3239 /* Wait for it to be properly created or deleted */
3240 ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3241 while(ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
3242 {
3243 MiReleasePfnLock(OldIrql);
3244
3246
3247 OldIrql = MiAcquirePfnLock();
3248 ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3249 }
3250
3251 if (ImageSectionObject == NULL)
3252 {
3253 NTSTATUS StatusExeFmt;
3254
3255 /* Release the lock because ExAllocatePoolWithTag could need to acquire it */
3256 MiReleasePfnLock(OldIrql);
3257
3259 if (ImageSectionObject == NULL)
3260 {
3261 ObDereferenceObject(Section);
3262 return STATUS_NO_MEMORY;
3263 }
3264
3265 ImageSectionObject->SegFlags = MM_SEGMENT_INCREATE;
3266 ImageSectionObject->RefCount = 1;
3267 ImageSectionObject->SectionCount = 1;
3268
3269 OldIrql = MiAcquirePfnLock();
3270 if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
3271 {
3272 MiReleasePfnLock(OldIrql);
3273 /* Bad luck. Start over */
3274 ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3275 goto grab_image_section_object;
3276 }
3277
3278 FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
3279
3280 MiReleasePfnLock(OldIrql);
3281
3282 /* Purge the cache */
3283 CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
3284
3285 StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
3286
3287 if (!NT_SUCCESS(StatusExeFmt))
3288 {
3289 /* Unset */
3290 OldIrql = MiAcquirePfnLock();
3291 FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3292 MiReleasePfnLock(OldIrql);
3293
3294 if(ImageSectionObject->Segments != NULL)
3295 ExFreePool(ImageSectionObject->Segments);
3296
3297 /*
3298 * If image file is empty, then return that the file is invalid for section
3299 */
3300 Status = StatusExeFmt;
3301 if (StatusExeFmt == STATUS_END_OF_FILE)
3302 {
3304 }
3305
3306 ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3307 ObDereferenceObject(Section);
3308 return Status;
3309 }
3310
3311 Section->Segment = (PSEGMENT)ImageSectionObject;
3312 ASSERT(ImageSectionObject->Segments);
3313 ASSERT(ImageSectionObject->RefCount > 0);
3314
3315 /*
3316 * Lock the file
3317 */
3319 if (!NT_SUCCESS(Status))
3320 {
3321 /* Unset */
3322 OldIrql = MiAcquirePfnLock();
3323 FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3324 MiReleasePfnLock(OldIrql);
3325
3326 ExFreePool(ImageSectionObject->Segments);
3327 ExFreePool(ImageSectionObject);
3328 ObDereferenceObject(Section);
3329 return Status;
3330 }
3331
3332 OldIrql = MiAcquirePfnLock();
3333 ImageSectionObject->SegFlags &= ~MM_SEGMENT_INCREATE;
3334
3335 /* Take a ref on the file on behalf of the newly created structure */
3337
3338 MiReleasePfnLock(OldIrql);
3339
3340 Status = StatusExeFmt;
3341 }
3342 else
3343 {
3344 /* If FS driver called for delete, tell them it's not possible anymore. */
3345 ImageSectionObject->SegFlags &= ~MM_IMAGE_SECTION_FLUSH_DELETE;
3346
3347 /* Take one ref */
3348 InterlockedIncrement64(&ImageSectionObject->RefCount);
3349 ImageSectionObject->SectionCount++;
3350
3351 MiReleasePfnLock(OldIrql);
3352
3353 Section->Segment = (PSEGMENT)ImageSectionObject;
3354
3356 }
3357 //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
3358 *SectionObject = Section;
3359 ASSERT(ImageSectionObject->RefCount > 0);
3360
3361 return Status;
3362}
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
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
NTSTATUS ExeFmtpCreateImageSection(PFILE_OBJECT FileObject, PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
Definition: section.c:3029
#define STATUS_END_OF_FILE
Definition: shellext.h:67

Referenced by MmCreateSection().

◆ MmCreatePhysicalMemorySection()

NTSTATUS NTAPI MmCreatePhysicalMemorySection ( VOID  )

Definition at line 2208 of file section.c.

2209{
2210 PSECTION PhysSection;
2213 UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2214 LARGE_INTEGER SectionSize;
2215 HANDLE Handle;
2217
2218 /*
2219 * Create the section mapping physical memory
2220 */
2223 &Name,
2225 NULL,
2226 NULL);
2227 /*
2228 * Create the Object
2229 */
2232 &Obj,
2234 NULL,
2235 sizeof(*PhysSection),
2236 0,
2237 0,
2238 (PVOID*)&PhysSection);
2239 if (!NT_SUCCESS(Status))
2240 {
2241 DPRINT1("MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n", Status);
2242 return Status;
2243 }
2244
2245 /*
2246 * Initialize it
2247 */
2248 RtlZeroMemory(PhysSection, sizeof(*PhysSection));
2249
2250 /* Mark this as a "ROS Section" */
2251 PhysSection->u.Flags.filler = 1;
2253 PhysSection->u.Flags.PhysicalMemory = 1;
2254 PhysSection->SizeOfSection = SectionSize;
2257 if (Segment == NULL)
2258 {
2259 ObDereferenceObject(PhysSection);
2260 return STATUS_NO_MEMORY;
2261 }
2263 PhysSection->Segment = (PSEGMENT)Segment;
2264 Segment->RefCount = 1;
2265
2266 Segment->ReferenceCount = &Segment->RefCount;
2267 Segment->Flags = &Segment->SegFlags;
2268
2270 Segment->Image.FileOffset = 0;
2271 Segment->Protection = PAGE_EXECUTE_READWRITE;
2272 Segment->RawLength = SectionSize;
2273 Segment->Length = SectionSize;
2275 Segment->WriteCopy = FALSE;
2276 Segment->Image.VirtualAddress = 0;
2277 Segment->Image.Characteristics = 0;
2279
2280 Status = ObInsertObject(PhysSection,
2281 NULL,
2283 0,
2284 NULL,
2285 &Handle);
2286 if (!NT_SUCCESS(Status))
2287 {
2288 ObDereferenceObject(PhysSection);
2289 return Status;
2290 }
2292
2293 return STATUS_SUCCESS;
2294}
ULONG Handle
Definition: gdb_input.c:15
#define OBJ_PERMANENT
Definition: winternl.h:226
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:91
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
ULONG PhysicalMemory
Definition: mmtypes.h:473
#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 4625 of file section.c.

4633{
4635 ULONG Protection;
4636 PSECTION *SectionObject = (PSECTION *)Section;
4637 BOOLEAN FileLock = FALSE;
4638
4639 /* Check if an ARM3 section is being created instead */
4641 {
4642 if (!(FileObject) && !(FileHandle))
4643 {
4644 return MmCreateArm3Section(Section,
4650 FileHandle,
4651 FileObject);
4652 }
4653 }
4654
4655 /* Convert section flag to page flag */
4657
4658 /* Check to make sure the protection is correct. Nt* does this already */
4660 if (Protection == MM_INVALID_PROTECTION)
4661 {
4662 DPRINT1("Page protection is invalid\n");
4664 }
4665
4666 /* Check if this is going to be a data or image backed file section */
4667 if ((FileHandle) || (FileObject))
4668 {
4669 /* These cannot be mapped with large pages */
4671 {
4672 DPRINT1("Large pages cannot be used with an image mapping\n");
4674 }
4675
4676 /* Did the caller pass a file object ? */
4677 if (FileObject)
4678 {
4679 /* Reference the object directly */
4681
4682 /* We don't create image mappings with file objects */
4683 AllocationAttributes &= ~SEC_IMAGE;
4684 }
4685 else
4686 {
4687 /* Reference the file handle to get the object */
4689 MmMakeFileAccess[Protection],
4692 (PVOID*)&FileObject,
4693 NULL);
4694 if (!NT_SUCCESS(Status))
4695 {
4696 DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
4697 return Status;
4698 }
4699
4700 /* Lock the file */
4702 if (!NT_SUCCESS(Status))
4703 {
4705 return Status;
4706 }
4707
4708 FileLock = TRUE;
4709
4710 /* Deny access if there are writes on the file */
4711#if 0
4713 {
4714 DPRINT1("Cannot create image maps with writers open on the file!\n");
4716 goto Quit;
4717 }
4718#else
4720 DPRINT1("Creating image map with writers open on the file!\n");
4721#endif
4722 }
4723 }
4724 else
4725 {
4726 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
4728 }
4729
4731 {
4738 FileObject);
4739 }
4740#ifndef NEWCC
4741 else if (FileObject != NULL)
4742 {
4749 FileObject,
4750 FileHandle != NULL);
4751 }
4752#else
4753 else if (FileHandle != NULL || FileObject != NULL)
4754 {
4761 FileObject);
4762 }
4763#endif
4764 else
4765 {
4766 /* All cases should be handled above */
4768 }
4769
4770 if (FileLock)
4772 if (FileObject)
4774
4775 return Status;
4776}
NTSTATUS NTAPI MmCreateCacheSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
#define SEC_PHYSICALMEMORY
Definition: mm.h:112
#define STATUS_FILE_LOCKED_WITH_WRITERS
Definition: ntstatus.h:112
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:2332
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:2100
NTSTATUS MmCreateImageSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
Definition: section.c:3182
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658

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

5386{
5387 PSECTION Section = _Section;
5388
5389 /* It makes no sense to extend an image mapping */
5390 if (Section->u.Flags.Image)
5392
5393 /* Nor is it possible to extend a page file mapping */
5394 if (!Section->u.Flags.File)
5396
5397 if (!MiIsRosSectionObject(Section))
5399
5400 /* We just extend the sizes. Shrinking is a no-op ? */
5401 if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5402 {
5404 Section->SizeOfSection = *NewSize;
5405
5406 if (!Section->u.Flags.Reserve)
5407 {
5409 if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5410 {
5411 Segment->RawLength = *NewSize;
5412 Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5413 }
5415 }
5416 }
5417
5418 return STATUS_SUCCESS;
5419}
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
if(dx< 0)
Definition: linetemp.h:194
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1111
struct _MM_SECTION_SEGMENT * PMM_SECTION_SEGMENT

Referenced by CcSetFileSizes(), and NtExtendSection().

◆ MmFlushImageSection()

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

Definition at line 4361 of file section.c.

4363{
4364 switch(FlushType)
4365 {
4366 case MmFlushForDelete:
4367 {
4368 /*
4369 * FIXME: Check for outstanding write probes on Data section.
4370 * How do we do that ?
4371 */
4372 }
4373 /* Fall-through */
4374 case MmFlushForWrite:
4375 {
4376 KIRQL OldIrql = MiAcquirePfnLock();
4377 PMM_IMAGE_SECTION_OBJECT ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4378
4379 DPRINT("Deleting or modifying %p\n", SectionObjectPointer);
4380
4381 /* Wait for concurrent creation or deletion of image to be done */
4382 ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4383 while (ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INCREATE | MM_SEGMENT_INDELETE)))
4384 {
4385 MiReleasePfnLock(OldIrql);
4387 OldIrql = MiAcquirePfnLock();
4388 ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4389 }
4390
4391 if (!ImageSectionObject)
4392 {
4393 DPRINT("No image section object. Accepting\n");
4394 /* Nothing to do */
4395 MiReleasePfnLock(OldIrql);
4396 return TRUE;
4397 }
4398
4399 /* Do we have open sections or mappings on it ? */
4400 if ((ImageSectionObject->SectionCount) || (ImageSectionObject->MapCount))
4401 {
4402 /* We do. No way to delete it */
4403 MiReleasePfnLock(OldIrql);
4404 DPRINT("Denying. There are mappings open\n");
4405 return FALSE;
4406 }
4407
4408 /* There are no sections open on it, but we must still have pages around. Discard everything */
4409 ImageSectionObject->SegFlags |= MM_IMAGE_SECTION_FLUSH_DELETE;
4410 InterlockedIncrement64(&ImageSectionObject->RefCount);
4411 MiReleasePfnLock(OldIrql);
4412
4413 DPRINT("Purging\n");
4414
4415 for (ULONG i = 0; i < ImageSectionObject->NrSegments; i++)
4416 {
4417 if (!MiPurgeImageSegment(&ImageSectionObject->Segments[i]))
4418 break;
4419 }
4420
4421 /* Grab lock again */
4422 OldIrql = MiAcquirePfnLock();
4423
4424 if (!(ImageSectionObject->SegFlags & MM_IMAGE_SECTION_FLUSH_DELETE))
4425 {
4426 /*
4427 * Someone actually created a section while we were not looking.
4428 * Drop our ref and deny.
4429 * MmDereferenceSegmentWithLock releases Pfn lock
4430 */
4431 MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4432 return FALSE;
4433 }
4434
4435 /* We should be the last one holding a ref here. */
4436 ASSERT(ImageSectionObject->RefCount == 1);
4437 ASSERT(ImageSectionObject->SectionCount == 0);
4438
4439 /* Dereference the first segment, this will free everything & release the lock */
4440 MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4441 return TRUE;
4442 }
4443 }
4444 return FALSE;
4445}
IN PFCB IN FAT_FLUSH_TYPE FlushType
Definition: fatprocs.h:1083
#define MM_IMAGE_SECTION_FLUSH_DELETE
Definition: mm.h:248
static BOOLEAN MiPurgeImageSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:4315

Referenced by _Requires_lock_held_(), Ext2CreateFile(), Ext2IsFileRemovable(), Ext2PurgeFile(), Ext2PurgeVolume(), FatSetRenameInfo(), open_file3(), 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 5051 of file section.c.

5056{
5057 LARGE_INTEGER FlushStart, FlushEnd;
5059
5060 if (Offset)
5061 {
5062 FlushStart = *Offset;
5063 Status = RtlLongLongAdd(FlushStart.QuadPart, Length, &FlushEnd.QuadPart);
5064 if (!NT_SUCCESS(Status))
5065 return Status;
5066 }
5067
5068 if (Iosb)
5069 Iosb->Information = 0;
5070
5072 if (!Segment)
5073 {
5074 /* Nothing to flush */
5075 goto Quit;
5076 }
5077
5079
5081
5082 if (!Offset)
5083 {
5084 FlushStart.QuadPart = 0;
5085
5086 /* FIXME: All of this is suboptimal */
5087 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
5088 if (!ElemCount)
5089 {
5090 /* No page. Nothing to flush */
5092 MmDereferenceSegment(Segment);
5093 goto Quit;
5094 }
5095
5097 FlushEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
5098 }
5099
5100 /* Find byte offset of the page to start */
5101 FlushStart.QuadPart = PAGE_ROUND_DOWN_64(FlushStart.QuadPart);
5102
5103 while (FlushStart.QuadPart < FlushEnd.QuadPart)
5104 {
5106
5107 if (IS_DIRTY_SSE(Entry))
5108 {
5109 MmCheckDirtySegment(Segment, &FlushStart, FALSE, FALSE);
5110
5111 if (Iosb)
5112 Iosb->Information += PAGE_SIZE;
5113 }
5114
5115 FlushStart.QuadPart += PAGE_SIZE;
5116 }
5117
5119 MmDereferenceSegment(Segment);
5120
5121Quit:
5122 /* FIXME: Handle failures */
5123 if (Iosb)
5124 Iosb->Status = STATUS_SUCCESS;
5125
5126 return STATUS_SUCCESS;
5127}
BOOLEAN NTAPI MmCheckDirtySegment(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN ForceDirty, BOOLEAN PageOut)
#define PAGE_ROUND_DOWN_64(x)
Definition: mm.h:138
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlGetElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ ULONG I)
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElements(_In_ PRTL_GENERIC_TABLE Table)

Referenced by CcFlushCache(), CcRosDeleteFileCache(), CcRosFlushVacb(), and MiRosUnmapViewOfSection().

◆ MmFreeSectionPage()

static VOID MmFreeSectionPage ( PVOID  Context,
MEMORY_AREA MemoryArea,
PVOID  Address,
PFN_NUMBER  Page,
SWAPENTRY  SwapEntry,
BOOLEAN  Dirty 
)
static

Definition at line 3446 of file section.c.

3448{
3451 SWAPENTRY SavedSwapEntry;
3455
3458
3460
3462 MemoryArea->SectionData.ViewOffset;
3463
3464 Segment = MemoryArea->SectionData.Segment;
3465
3467 while (Entry && MM_IS_WAIT_PTE(Entry))
3468 {
3471
3473
3477 }
3478
3479 /*
3480 * For a dirty, datafile, non-private page, there shoulkd be no swap entry
3481 */
3482 if (*Segment->Flags & MM_DATAFILE_SEGMENT)
3483 {
3484 if (Page == PFN_FROM_SSE(Entry) && Dirty)
3485 {
3486 ASSERT(SwapEntry == 0);
3487 }
3488 }
3489
3490 if (SwapEntry != 0)
3491 {
3492 /*
3493 * Sanity check
3494 */
3495 MmFreeSwapPage(SwapEntry);
3496 }
3497 else if (Page != 0)
3498 {
3499 if (IS_SWAP_FROM_SSE(Entry) ||
3501 {
3502 ASSERT(Process != NULL);
3503
3504 /*
3505 * Just dereference private pages
3506 */
3507 SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
3508 if (SavedSwapEntry != 0)
3509 {
3510 MmFreeSwapPage(SavedSwapEntry);
3512 }
3515 }
3516 else
3517 {
3518 if (Process)
3519 {
3521 }
3522
3523 /* We don't dirtify for System Space Maps. We let Cc manage that */
3525 }
3526 }
3527}
struct _MMSUPPORT * PMMSUPPORT
#define MM_IS_WAIT_PTE(E)
Definition: mm.h:1377

Referenced by MmUnmapViewOfSegment().

◆ MmInitSectionImplementation()

NTSTATUS NTAPI MmInitSectionImplementation ( VOID  )

Definition at line 2299 of file section.c.

2300{
2301 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
2303
2304 DPRINT("Creating Section Object Type\n");
2305
2306 /* Initialize the section based root */
2309
2310 /* Initialize the Section object type */
2311 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
2312 RtlInitUnicodeString(&Name, L"Section");
2313 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
2314 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(SECTION);
2315 ObjectTypeInitializer.PoolType = PagedPool;
2316 ObjectTypeInitializer.UseDefaultObject = TRUE;
2317 ObjectTypeInitializer.GenericMapping = MmpSectionMapping;
2318 ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection;
2319 ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
2320 ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
2321 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
2322 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
2323
2325
2326 return STATUS_SUCCESS;
2327}
struct NameRec_ * Name
Definition: cdprocs.h:460
#define OBJ_OPENLINK
Definition: winternl.h:230
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
static GENERIC_MAPPING MmpSectionMapping
Definition: section.c:223
VOID NTAPI MmpDeleteSection(PVOID ObjectBody)
Definition: section.c:2143
VOID NTAPI MmpCloseSection(IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
Definition: section.c:2196
NTSTATUS NTAPI MmCreatePhysicalMemorySection(VOID)
Definition: section.c:2208
union _MMADDRESS_NODE::@2629 u1
struct _MMADDRESS_NODE * Parent
Definition: mmtypes.h:649
ULONG_PTR NumberGenericTableElements
Definition: mmtypes.h:668
MMADDRESS_NODE BalancedRoot
Definition: mmtypes.h:662
OB_CLOSE_METHOD CloseProcedure
Definition: obtypes.h:368
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369

Referenced by MmInitSystem().

◆ MmIsDataSectionResident()

BOOLEAN NTAPI MmIsDataSectionResident ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_ LONGLONG  Offset,
_In_ ULONG  Length 
)

Definition at line 4932 of file section.c.

4936{
4938 LARGE_INTEGER RangeStart, RangeEnd;
4939 BOOLEAN Ret = TRUE;
4940
4941 RangeStart.QuadPart = Offset;
4942 if (!NT_SUCCESS(RtlLongLongAdd(RangeStart.QuadPart, Length, &RangeEnd.QuadPart)))
4943 return FALSE;
4944
4946 if (!Segment)
4947 return FALSE;
4948
4949 /* Find byte offset of the page to start */
4950 RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart);
4951
4953
4954 while (RangeStart.QuadPart < RangeEnd.QuadPart)
4955 {
4957 if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4958 {
4959 Ret = FALSE;
4960 break;
4961 }
4962
4963 RangeStart.QuadPart += PAGE_SIZE;
4964 }
4965
4967 MmDereferenceSegment(Segment);
4968
4969 return Ret;
4970}

Referenced by CcRosEnsureVacbResident().

◆ MmMakeDataSectionResident()

NTSTATUS NTAPI MmMakeDataSectionResident ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_ LONGLONG  Offset,
_In_ ULONG  Length,
_In_ PLARGE_INTEGER  ValidDataLength 
)

Definition at line 4974 of file section.c.

4979{
4981
4982 /* There must be a segment for this call */
4983 ASSERT(Segment);
4984
4986
4987 MmDereferenceSegment(Segment);
4988
4989 return Status;
4990}
static NTSTATUS NTAPI MmMakeSegmentResident(_In_ PMM_SECTION_SEGMENT Segment, _In_ LONGLONG Offset, _In_ ULONG Length, _In_opt_ PLARGE_INTEGER ValidDataLength, _In_ BOOLEAN SetDirty)
Definition: section.c:1192

Referenced by CcRosEnsureVacbResident().

◆ MmMakeSegmentDirty()

NTSTATUS NTAPI MmMakeSegmentDirty ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_ LONGLONG  Offset,
_In_ ULONG  Length 
)

Definition at line 4994 of file section.c.

4998{
5000 LARGE_INTEGER RangeStart, RangeEnd;
5002
5003 RangeStart.QuadPart = Offset;
5004 Status = RtlLongLongAdd(RangeStart.QuadPart, Length, &RangeEnd.QuadPart);
5005 if (!NT_SUCCESS(Status))
5006 return Status;
5007
5009 if (!Segment)
5011
5012 /* Find byte offset of the page to start */
5013 RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart);
5014
5016
5017 while (RangeStart.QuadPart < RangeEnd.QuadPart)
5018 {
5020
5021 /* Let any pending read proceed */
5022 while (MM_IS_WAIT_PTE(Entry))
5023 {
5028 }
5029
5030 /* We are called from Cc, this can't be backed by the page files */
5032
5033 /* If there is no page there, there is nothing to make dirty */
5034 if (Entry != 0)
5035 {
5036 /* Dirtify the entry */
5038 }
5039
5040 RangeStart.QuadPart += PAGE_SIZE;
5041 }
5042
5044 MmDereferenceSegment(Segment);
5045
5046 return STATUS_SUCCESS;
5047}

Referenced by CcCopyWrite(), CcSetDirtyPinnedData(), and CcZeroData().

◆ MmMakeSegmentResident()

static NTSTATUS NTAPI MmMakeSegmentResident ( _In_ PMM_SECTION_SEGMENT  Segment,
_In_ LONGLONG  Offset,
_In_ ULONG  Length,
_In_opt_ PLARGE_INTEGER  ValidDataLength,
_In_ BOOLEAN  SetDirty 
)
static

Definition at line 1192 of file section.c.

1198{
1199 /* Let's use a 64K granularity. */
1200 LONGLONG RangeStart, RangeEnd;
1202 PFILE_OBJECT FileObject = Segment->FileObject;
1203
1204 /* Calculate our range, aligned on 64K if possible. */
1205 Status = RtlLongLongAdd(Offset, Length, &RangeEnd);
1207 if (!NT_SUCCESS(Status))
1208 return Status;
1209
1210 /* If the file is not random access and we are not the page out thread
1211 * read a 64K Chunk. */
1213 && !FlagOn(FileObject->Flags, FO_RANDOM_ACCESS))
1214 {
1215 RangeStart = Offset - (Offset % _64K);
1216 if (RangeEnd % _64K)
1217 RangeEnd += _64K - (RangeEnd % _64K);
1218 }
1219 else
1220 {
1221 RangeStart = Offset - (Offset % PAGE_SIZE);
1222 if (RangeEnd % PAGE_SIZE)
1223 RangeEnd += PAGE_SIZE - (RangeEnd % PAGE_SIZE);
1224 }
1225
1226 /* Clamp if needed */
1227 if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
1228 {
1229 if (RangeEnd > Segment->RawLength.QuadPart)
1230 RangeEnd = Segment->RawLength.QuadPart;
1231 }
1232
1233 /* Let's gooooooooo */
1234 for ( ; RangeStart < RangeEnd; RangeStart += _64K)
1235 {
1236 /* First take a look at where we miss pages */
1237 ULONG ToReadPageBits = 0;
1238 LONGLONG ChunkEnd = RangeStart + _64K;
1239
1240 if (ChunkEnd > RangeEnd)
1241 ChunkEnd = RangeEnd;
1242
1244 for (LONGLONG ChunkOffset = RangeStart; ChunkOffset < ChunkEnd; ChunkOffset += PAGE_SIZE)
1245 {
1246 LARGE_INTEGER CurrentOffset;
1247
1248 CurrentOffset.QuadPart = ChunkOffset;
1250
1251 /* Let any pending read proceed */
1252 while (MM_IS_WAIT_PTE(Entry))
1253 {
1255
1257
1259 Entry = MmGetPageEntrySectionSegment(Segment, &CurrentOffset);
1260 }
1261
1262 if (Entry != 0)
1263 {
1264 /* Dirtify it if it's a resident page and we're asked to */
1265 if (SetDirty && !IS_SWAP_FROM_SSE(Entry))
1267 continue;
1268 }
1269
1270 ToReadPageBits |= 1UL << ((ChunkOffset - RangeStart) >> PAGE_SHIFT);
1271
1272 /* Put a wait entry here */
1273 MmSetPageEntrySectionSegment(Segment, &CurrentOffset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
1274 }
1276
1277 if (ToReadPageBits == 0)
1278 {
1279 /* Nothing to do for this chunk */
1280 continue;
1281 }
1282
1283 /* Now perform the actual read */
1284 LONGLONG ChunkOffset = RangeStart;
1285 while (ChunkOffset < ChunkEnd)
1286 {
1287 /* Move forward if there is a hole */
1288 ULONG BitSet;
1289 if (!_BitScanForward(&BitSet, ToReadPageBits))
1290 {
1291 /* Nothing more to read */
1292 break;
1293 }
1294 ToReadPageBits >>= BitSet;
1295 ChunkOffset += BitSet * PAGE_SIZE;
1296 ASSERT(ChunkOffset < ChunkEnd);
1297
1298 /* Get the range we have to read */
1299 _BitScanForward(&BitSet, ~ToReadPageBits);
1300 ULONG ReadLength = BitSet * PAGE_SIZE;
1301
1303
1304 /* Clamp (This is for image mappings */
1305 if ((ChunkOffset + ReadLength) > ChunkEnd)
1306 ReadLength = ChunkEnd - ChunkOffset;
1307
1308 ASSERT(ReadLength != 0);
1309
1310 /* Allocate a MDL */
1312 if (!Mdl)
1313 {
1314 /* Damn. Roll-back. */
1316 while (ChunkOffset < ChunkEnd)
1317 {
1318 if (ToReadPageBits & 1)
1319 {
1320 LARGE_INTEGER CurrentOffset;
1321 CurrentOffset.QuadPart = ChunkOffset;
1323 MmSetPageEntrySectionSegment(Segment, &CurrentOffset, 0);
1324 }
1325 ToReadPageBits >>= 1;
1326 ChunkOffset += PAGE_SIZE;
1327 }
1330 }
1331
1332 /* Get our pages */
1335 for (UINT i = 0; i < BYTES_TO_PAGES(ReadLength); i++)
1336 {
1338 if (!NT_SUCCESS(Status))
1339 {
1340 /* Damn. Roll-back. */
1341 for (UINT j = 0; j < i; j++)
1343 goto Failed;
1344 }
1345 }
1346
1347 Mdl->MdlFlags |= MDL_PAGES_LOCKED | MDL_IO_PAGE_READ;
1348
1350 FileOffset.QuadPart = Segment->Image.FileOffset + ChunkOffset;
1351
1352 /* Clamp to VDL */
1353 if (ValidDataLength && ((FileOffset.QuadPart + ReadLength) > ValidDataLength->QuadPart))
1354 {
1355 if (FileOffset.QuadPart > ValidDataLength->QuadPart)
1356 {
1357 /* Great, nothing to read. */
1358 goto AssignPagesToSegment;
1359 }
1360
1361 Mdl->Size = (FileOffset.QuadPart + ReadLength) - ValidDataLength->QuadPart;
1362 }
1363
1364 KEVENT Event;
1366
1367 /* Disable APCs */
1368 KIRQL OldIrql;
1370
1373 if (Status == STATUS_PENDING)
1374 {
1376 Status = Iosb.Status;
1377 }
1378
1379 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
1380 {
1381 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
1382 }
1383
1385
1387 {
1388 DPRINT1("Got STATUS_END_OF_FILE at offset %I64d for file %wZ.\n", FileOffset.QuadPart, &FileObject->FileName);
1390 }
1391
1392 if (!NT_SUCCESS(Status))
1393 {
1394 /* Damn. Roll back. */
1395 for (UINT i = 0; i < BYTES_TO_PAGES(ReadLength); i++)
1397
1398Failed:
1400 while (ChunkOffset < ChunkEnd)
1401 {
1402 if (ToReadPageBits & 1)
1403 {
1404 LARGE_INTEGER CurrentOffset;
1405 CurrentOffset.QuadPart = ChunkOffset;
1407 MmSetPageEntrySectionSegment(Segment, &CurrentOffset, 0);
1408 }
1409 ToReadPageBits >>= 1;
1410 ChunkOffset += PAGE_SIZE;
1411 }
1413 IoFreeMdl(Mdl);;
1414 return Status;
1415 }
1416
1417AssignPagesToSegment:
1419
1420 for (UINT i = 0; i < BYTES_TO_PAGES(ReadLength); i++)
1421 {
1422 ULONG_PTR Entry = MAKE_SSE(Pages[i] << PAGE_SHIFT, 0);
1423 LARGE_INTEGER CurrentOffset;
1424 CurrentOffset.QuadPart = ChunkOffset + (i * PAGE_SIZE);
1425
1427
1428 if (SetDirty)
1430
1431 MmSetPageEntrySectionSegment(Segment, &CurrentOffset, Entry);
1432 }
1433
1435
1436 IoFreeMdl(Mdl);
1437 ToReadPageBits >>= BitSet;
1438 ChunkOffset += BitSet * PAGE_SIZE;
1439 }
1440 }
1441
1442 return STATUS_SUCCESS;
1443}
ULONG ReadLength
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
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 GLint GLint j
Definition: glfuncs.h:250
unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask)
Definition: intrin_arm.h:57
NTSTATUS NTAPI IoPageRead(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1201
unsigned int UINT
Definition: ndis.h:50
@ Failed
Definition: arc.h:79
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define FO_RANDOM_ACCESS
Definition: iotypes.h:1796
@ WrPageIn
Definition: ketypes.h:424
#define BYTES_TO_PAGES(Size)
#define MmGetMdlPfnArray(_Mdl)
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24

Referenced by MmMakeDataSectionResident(), and MmNotPresentFaultSectionView().

◆ MmMapViewInSystemSpace()

NTSTATUS NTAPI MmMapViewInSystemSpace ( IN PVOID  SectionObject,
OUT PVOID MappedBase,
IN OUT PSIZE_T  ViewSize 
)

Definition at line 4452 of file section.c.

4455{
4457
4458 SectionOffset.QuadPart = 0;
4459
4461}
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
NTSTATUS NTAPI MmMapViewInSystemSpaceEx(_In_ PVOID SectionObject, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset, _In_ ULONG_PTR Flags)
Definition: section.c:4465

Referenced by ExpInitNls(), IntGdiAddFontResourceEx(), and MmMapViewInSessionSpace().

◆ MmMapViewInSystemSpaceEx()

NTSTATUS NTAPI MmMapViewInSystemSpaceEx ( _In_ PVOID  SectionObject,
_Outptr_result_bytebuffer_ *ViewSize PVOID MappedBase,
_Inout_ PSIZE_T  ViewSize,
_Inout_ PLARGE_INTEGER  SectionOffset,
_In_ ULONG_PTR  Flags 
)

Definition at line 4465 of file section.c.

4472{
4473 PSECTION Section = SectionObject;
4477
4479
4480 PAGED_CODE();
4481
4483 {
4485 &MmSession,
4486 MappedBase,
4487 ViewSize,
4489 }
4490
4491 DPRINT("MmMapViewInSystemSpaceEx() called\n");
4492
4493 /* unsupported for now */
4494 ASSERT(Section->u.Flags.Image == 0);
4495
4496 Section = SectionObject;
4498
4499 if (*ViewSize == 0)
4500 {
4501 LONGLONG MapSizeLL;
4502
4503 /* Page-align the mapping */
4504 SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
4505
4506 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &MapSizeLL)))
4508
4509 if (!NT_SUCCESS(RtlLongLongToSIZET(MapSizeLL, ViewSize)))
4511 }
4512 else
4513 {
4514 LONGLONG HelperLL;
4515
4516 /* Get the map end */
4517 if (!NT_SUCCESS(RtlLongLongAdd(SectionOffset->QuadPart, *ViewSize, &HelperLL)))
4519
4520 /* Round it up, if needed */
4521 if (HelperLL % PAGE_SIZE)
4522 {
4523 if (!NT_SUCCESS(RtlLongLongAdd(HelperLL, PAGE_SIZE - (HelperLL % PAGE_SIZE), &HelperLL)))
4525 }
4526
4527 /* Now that we have the mapping end, we can align down its start */
4528 SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
4529
4530 /* Get the new size */
4531 if (!NT_SUCCESS(RtlLongLongSub(HelperLL, SectionOffset->QuadPart, &HelperLL)))
4533
4534 if (!NT_SUCCESS(RtlLongLongToSIZET(HelperLL, ViewSize)))
4536 }
4537
4539
4541
4543
4545 Section->u.Flags.Image,
4546 Segment,
4547 MappedBase,
4548 *ViewSize,
4550 SectionOffset->QuadPart,
4551 SEC_RESERVE);
4552
4555
4556 return Status;
4557}
NTSTATUS MiMapViewInSystemSpace(_In_ PVOID Section, _In_ PMMSESSION Session, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset)
Definition: section.c:1040
MMSESSION MmSession
Definition: section.c:107
#define PAGED_CODE()
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:268
static NTSTATUS MmMapViewOfSegment(PMMSUPPORT AddressSpace, BOOLEAN AsImage, PMM_SECTION_SEGMENT Segment, PVOID *BaseAddress, SIZE_T ViewSize, ULONG Protect, LONGLONG ViewOffset, ULONG AllocationType)
Definition: section.c:3367

Referenced by CcRosCreateVacb(), and MmMapViewInSystemSpace().

◆ MmMapViewOfArm3Section()

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 
)

Definition at line 2529 of file section.c.

2539{
2542 PSECTION Section;
2543 PCONTROL_AREA ControlArea;
2544 ULONG ProtectionMask;
2546 ULONG64 CalculatedViewSize;
2547 PAGED_CODE();
2548
2549 /* Get the segment and control area */
2550 Section = (PSECTION)SectionObject;
2551 ControlArea = Section->Segment->ControlArea;
2552
2553 /* These flags/states are not yet supported by ARM3 */
2554 ASSERT(Section->u.Flags.Image == 0);
2555 ASSERT(Section->u.Flags.NoCache == 0);
2556 ASSERT(Section->u.Flags.WriteCombined == 0);
2557 ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
2558
2559 /* FIXME */
2560 if ((AllocationType & MEM_RESERVE) != 0)
2561 {
2562 DPRINT1("MmMapViewOfArm3Section called with MEM_RESERVE, this is not implemented yet!!!\n");
2564 }
2565
2566 /* Check if the mapping protection is compatible with the create */
2568 {
2569 DPRINT1("Mapping protection is incompatible\n");
2571 }
2572
2573 /* Check if the offset and size would cause an overflow */
2574 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) <
2575 (ULONG64)SectionOffset->QuadPart)
2576 {
2577 DPRINT1("Section offset overflows\n");
2579 }
2580
2581 /* Check if the offset and size are bigger than the section itself */
2582 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) >
2583 (ULONG64)Section->SizeOfSection.QuadPart)
2584 {
2585 DPRINT1("Section offset is larger than section\n");
2587 }
2588
2589 /* Check if the caller did not specify a view size */
2590 if (!(*ViewSize))
2591 {
2592 /* Compute it for the caller */
2593 CalculatedViewSize = Section->SizeOfSection.QuadPart -
2594 SectionOffset->QuadPart;
2595
2596 /* Check if it's larger than 4GB or overflows into kernel-mode */
2597 if (!NT_SUCCESS(RtlULongLongToSIZET(CalculatedViewSize, ViewSize)) ||
2598 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < CalculatedViewSize))
2599 {
2600 DPRINT1("Section view won't fit\n");
2602 }
2603 }
2604
2605 /* Check if the commit size is larger than the view size */
2606 if (CommitSize > *ViewSize)
2607 {
2608 DPRINT1("Attempting to commit more than the view itself\n");
2610 }
2611
2612 /* Check if the view size is larger than the section */
2613 if (*ViewSize > (ULONG64)Section->SizeOfSection.QuadPart)
2614 {
2615 DPRINT1("The view is larger than the section\n");
2617 }
2618
2619 /* Compute and validate the protection mask */
2620 ProtectionMask = MiMakeProtectionMask(Protect);
2621 if (ProtectionMask == MM_INVALID_PROTECTION)
2622 {
2623 DPRINT1("The protection is invalid\n");
2625 }
2626
2627 /* We only handle pagefile-backed sections, which cannot be writecombined */
2629 {
2630 DPRINT1("Cannot write combine a pagefile-backed section\n");
2632 }
2633
2634 /* Start by attaching to the current process if needed */
2636 {
2638 Attached = TRUE;
2639 }
2640
2641 /* Do the actual mapping */
2642 Status = MiMapViewOfDataSection(ControlArea,
2643 Process,
2646 ViewSize,
2647 Section,
2649 ProtectionMask,
2650 CommitSize,
2651 ZeroBits,
2653
2654 /* Detach if needed, then return status */
2656 return Status;
2657}
static NTSTATUS MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *BaseAddress, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T ViewSize, IN PSECTION Section, IN SECTION_INHERIT InheritDisposition, IN ULONG ProtectionMask, IN SIZE_T CommitSize, IN ULONG_PTR ZeroBits, IN ULONG AllocationType)
Definition: section.c:1152
static BOOLEAN MiIsProtectionCompatible(IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
Definition: section.c:117
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT InheritDisposition
Definition: mmfuncs.h:409
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:405
_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 AllocationType
Definition: mmfuncs.h:410
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
struct _SECTION * PSECTION
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1772
#define STATUS_SECTION_PROTECTION
Definition: ntstatus.h:314
#define STATUS_INVALID_PARAMETER_10
Definition: ntstatus.h:484
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:479
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
ULONG WriteCombined
Definition: mmtypes.h:493
static BOOL Attached
Definition: vidbios.c:3905
KAPC_STATE
Definition: ketypes.h:1409

Referenced by MmMapViewOfSection().

◆ MmMapViewOfSection()

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 
)

Definition at line 4001 of file section.c.

4011{
4012 PSECTION Section;
4015 BOOLEAN NotAtBase = FALSE;
4016 BOOLEAN IsAttached = FALSE;
4018
4020 {
4021 DPRINT("Mapping ARM3 section into %s\n", Process->ImageFileName);
4023 Process,
4025 ZeroBits,
4026 CommitSize,
4028 ViewSize,
4031 Protect);
4032 }
4033
4034 ASSERT(Process);
4035
4037 {
4039 }
4040
4042 {
4044 IsAttached = TRUE;
4045 }
4046
4047 /* FIXME: We should keep this, but it would break code checking equality */
4048 Protect &= ~PAGE_NOCACHE;
4049
4050 Section = SectionObject;
4051 AddressSpace = &Process->Vm;
4052
4053 if (Section->u.Flags.NoChange)
4055
4057
4058 if (Section->u.Flags.Image)
4059 {
4060 ULONG i;
4061 ULONG NrSegments;
4062 ULONG_PTR ImageBase;
4063 SIZE_T ImageSize;
4064 PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
4065 PMM_SECTION_SEGMENT SectionSegments;
4066
4067 ImageSectionObject = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment);
4068 SectionSegments = ImageSectionObject->Segments;
4069 NrSegments = ImageSectionObject->NrSegments;
4070
4071 ASSERT(ImageSectionObject->RefCount > 0);
4072
4073 ImageBase = (ULONG_PTR)*BaseAddress;
4074 if (ImageBase == 0)
4075 {
4076 ImageBase = (ULONG_PTR)ImageSectionObject->BasedAddress;
4077 }
4078
4079 ImageSize = 0;
4080 for (i = 0; i < NrSegments; i++)
4081 {