ReactOS 0.4.17-dev-116-ga4b6fe9
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)    _MmSetPageEntrySectionSegment((S),(O),(E),__FILE__,__LINE__)
 
#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, _Outptr_result_bytebuffer_(*ViewSize) _When_(*ViewSize !=0, _Pre_opt_valid_) _When_(*ViewSize==0, _Pre_valid_) PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) 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_ PMEMORY_AREA MemoryArea, _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, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) 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 
)     _MmSetPageEntrySectionSegment((S),(O),(E),__FILE__,__LINE__)

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

69{
70 //DPRINT("MmLockSectionSegment(%p,%s:%d)\n", Segment, file, line);
72 Segment->Locked = TRUE;
73}
#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 77 of file section.c.

78{
79 ASSERT(Segment->Locked);
80 Segment->Locked = FALSE;
82 //DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment, file, line);
83}
#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 990 of file section.c.

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

2625{
2626 SIZE_T SizeOfSegments;
2627 PMM_SECTION_SEGMENT Segments;
2628
2629 /* TODO: check for integer overflow */
2630 SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
2631
2633 SizeOfSegments,
2635
2636 if(Segments)
2637 RtlZeroMemory(Segments, SizeOfSegments);
2638
2639 return Segments;
2640}
#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 3058 of file section.c.

3060{
3062 PVOID FileHeader;
3063 PVOID FileHeaderBuffer;
3064 ULONG FileHeaderSize;
3065 ULONG Flags;
3066 ULONG OldNrSegments;
3068 ULONG i;
3069
3070 /*
3071 * Read the beginning of the file (2 pages). Should be enough to contain
3072 * all (or most) of the headers
3073 */
3074 Offset.QuadPart = 0;
3075
3077 &Offset,
3078 PAGE_SIZE * 2,
3079 &FileHeader,
3080 &FileHeaderBuffer,
3081 &FileHeaderSize);
3082
3083 if (!NT_SUCCESS(Status))
3084 return Status;
3085
3086 if (FileHeaderSize == 0)
3087 {
3088 ExFreePool(FileHeaderBuffer);
3089 return STATUS_UNSUCCESSFUL;
3090 }
3091
3092 /*
3093 * Look for a loader that can handle this executable
3094 */
3095 for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
3096 {
3097 Flags = 0;
3098
3099 Status = ExeFmtpLoaders[i](FileHeader,
3100 FileHeaderSize,
3101 FileObject,
3102 ImageSectionObject,
3103 &Flags,
3106
3107 if (!NT_SUCCESS(Status))
3108 {
3109 if (ImageSectionObject->Segments)
3110 {
3111 ExFreePool(ImageSectionObject->Segments);
3112 ImageSectionObject->Segments = NULL;
3113 }
3114 }
3115
3117 break;
3118 }
3119
3120 ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
3121
3122 /*
3123 * No loader handled the format
3124 */
3126 {
3129 }
3130
3131 if (!NT_SUCCESS(Status))
3132 return Status;
3133
3134 ASSERT(ImageSectionObject->Segments != NULL);
3135 ASSERT(ImageSectionObject->RefCount > 0);
3136
3137 /*
3138 * Some defaults
3139 */
3140 /* FIXME? are these values platform-dependent? */
3141 if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
3142 ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
3143
3144 if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
3145 ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
3146
3147 if(ImageSectionObject->BasedAddress == NULL)
3148 {
3149 if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3150 ImageSectionObject->BasedAddress = (PVOID)0x10000000;
3151 else
3152 ImageSectionObject->BasedAddress = (PVOID)0x00400000;
3153 }
3154
3155 /*
3156 * And now the fun part: fixing the segments
3157 */
3158
3159 /* Sort them by virtual address */
3160 MmspSortSegments(ImageSectionObject, Flags);
3161
3162 /* Ensure they don't overlap in memory */
3163 if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
3165
3166 /* Ensure they are aligned */
3167 OldNrSegments = ImageSectionObject->NrSegments;
3168
3169 if (!MmspPageAlignSegments(ImageSectionObject, Flags))
3171
3172 /* Trim them if the alignment phase merged some of them */
3173 if (ImageSectionObject->NrSegments < OldNrSegments)
3174 {
3175 PMM_SECTION_SEGMENT Segments;
3176 SIZE_T SizeOfSegments;
3177
3178 SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
3179
3181 SizeOfSegments,
3183
3184 if (Segments == NULL)
3186
3187 RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
3188 ExFreePool(ImageSectionObject->Segments);
3189 ImageSectionObject->Segments = Segments;
3190 }
3191
3192 /* And finish their initialization */
3193 for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
3194 {
3195 ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
3196 ImageSectionObject->Segments[i].ReferenceCount = &ImageSectionObject->RefCount;
3197 ImageSectionObject->Segments[i].Flags = &ImageSectionObject->SegFlags;
3198 MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
3199 ImageSectionObject->Segments[i].FileObject = FileObject;
3200 }
3201
3202 ASSERT(ImageSectionObject->RefCount > 0);
3203
3204 ImageSectionObject->FileObject = FileObject;
3205
3207 return Status;
3208}
#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:453
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:633
#define IMAGE_FILE_DLL
Definition: pedump.c:169
static PMM_SECTION_SEGMENT NTAPI ExeFmtpAllocateSegments(IN ULONG NrSegments)
Definition: section.c:2624
static BOOLEAN NTAPI MmspPageAlignSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2875
static BOOLEAN NTAPI MmspCheckSegmentBounds(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2824
static VOID NTAPI MmspSortSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:2798
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:2644
static PEXEFMT_LOADER ExeFmtpLoaders[]
Definition: section.c:2613
PLARGE_INTEGER Offset
Definition: section.c:5202
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 2644 of file section.c.

2650{
2653 ULONG AdjustOffset;
2654 ULONG OffsetAdjustment;
2656 ULONG UsedSize;
2657 PVOID Buffer;
2660
2662
2663 if(Length == 0)
2664 {
2665 KeBugCheck(MEMORY_MANAGEMENT);
2666 }
2667
2668 FileOffset = *Offset;
2669
2670 /* Negative/special offset: it cannot be used in this context */
2671 if(FileOffset.u.HighPart < 0)
2672 {
2673 KeBugCheck(MEMORY_MANAGEMENT);
2674 }
2675
2676 AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
2677 OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
2678 FileOffset.u.LowPart = AdjustOffset;
2679
2680 BufferSize = Length + OffsetAdjustment;
2682
2683 /*
2684 * It's ok to use paged pool, because this is a temporary buffer only used in
2685 * the loading of executables. The assumption is that MmCreateSection is
2686 * always called at low IRQLs and that these buffers don't survive a brief
2687 * initialization phase
2688 */
2690 if (!Buffer)
2691 {
2693 }
2694
2696
2697 UsedSize = (ULONG)Iosb.Information;
2698
2699 if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
2700 {
2703 }
2704
2705 if(NT_SUCCESS(Status))
2706 {
2707 *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
2708 *AllocBase = Buffer;
2709 *ReadSize = UsedSize - OffsetAdjustment;
2710 }
2711 else
2712 {
2713 ExFreePoolWithTag(Buffer, 'rXmM');
2714 }
2715
2716 return Status;
2717}
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:336
#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 962 of file section.c.

963{
966
968
970
972
973 /* This must be either a valid entry or nothing */
975
976 /* There should be no reference anymore */
978
980 /* If there is a page, this must be because it's still dirty */
981 ASSERT(Page != 0);
982
983 /* Write the page */
984 if (IS_DIRTY_SSE(Entry))
985 MiWritePage(Segment, Offset->QuadPart, Page);
986
988}
ULONG_PTR PFN_NUMBER
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1601
#define MmLockSectionSegment(x)
Definition: mm.h:1396
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1384
#define MC_USER
Definition: mm.h:112
#define MmUnlockSectionSegment(x)
Definition: mm.h:1404
#define IS_DIRTY_SSE(E)
Definition: mm.h:1376
#define PFN_FROM_SSE(E)
Definition: mm.h:1367
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1368
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:72
PFN_NUMBER Page
Definition: section.c:5208
Entry
Definition: section.c:5216
NTSTATUS NTAPI MiWritePage(PMM_SECTION_SEGMENT Segment, LONGLONG SegOffset, PFN_NUMBER Page)
Definition: section.c:240

Referenced by _When_().

◆ if() [1/2]

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

Definition at line 5353 of file section.c.

5354 {
5355 ULONG_PTR NewEntry = 0;
5356 /* Restore the swap entry here */
5357 if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
5358 {
5360 if (SwapEntry)
5361 NewEntry = MAKE_SWAP_SSE(SwapEntry);
5362 }
5363
5364 /* Yes. Release it */
5367 /* Tell the caller we released the page */
5368 return TRUE;
5369 }
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define MAKE_SWAP_SSE(S)
Definition: mm.h:1373
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 5217 of file section.c.

5222 {
5223 BOOLEAN DirtyAgain;
5224
5225 /*
5226 * We got a dirty entry. This path is for the shared data,
5227 * be-it regular file maps or shared sections of DLLs
5228 */
5230 FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
5231
5232 /* Insert the cleaned entry back. Mark it as write in progress, and clear the dirty bit. */
5236
5238
5239 if (FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
5240 {
5242 KIRQL OldIrql;
5243
5244 /* We have to write it back to the file. Tell the FS driver who we are */
5245 if (PageOut)
5246 {
5247 LARGE_INTEGER EndOffset = *Offset;
5248
5250
5251 /* We need to disable all APCs */
5253
5254 EndOffset.QuadPart += PAGE_SIZE;
5256 &EndOffset,
5258 if (NT_SUCCESS(Status))
5259 {
5261 }
5262 else
5263 {
5264 /* Make sure we will not try to release anything */
5266 }
5267 }
5268 else
5269 {
5270 /* We don't have to lock. Say this is success */
5272 }
5273
5274 /* Go ahead and write the page, if previous locking succeeded */
5275 if (NT_SUCCESS(Status))
5276 {
5277 DPRINT("Writing page at offset %I64d for file %wZ, Pageout: %s\n",
5278 Offset->QuadPart, &Segment->FileObject->FileName, PageOut ? "TRUE" : "FALSE");
5279 Status = MiWritePage(Segment, Offset->QuadPart, Page);
5280 }
5281
5282 if (PageOut)
5283 {
5285 if (ResourceToRelease != NULL)
5286 {
5288 }
5290 }
5291 }
5292 else
5293 {
5294 /* This must only be called by the page-out path */
5295 ASSERT(PageOut);
5296
5297 /* And this must be for a shared section in a DLL */
5298 ASSERT(FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED));
5299
5301 if (!SwapEntry)
5302 {
5303 SwapEntry = MmAllocSwapPage();
5304 }
5305
5306 if (SwapEntry)
5307 {
5308 Status = MmWriteToSwapPage(SwapEntry, Page);
5309 if (NT_SUCCESS(Status))
5310 {
5311 MmSetSavedSwapEntryPage(Page, SwapEntry);
5312 }
5313 else
5314 {
5315 MmFreeSwapPage(SwapEntry);
5316 }
5317 }
5318 else
5319 {
5320 DPRINT1("Failed to allocate a swap page!\n");
5322 }
5323 }
5324
5326
5327 /* Get the entry again */
5330
5331 if (!NT_SUCCESS(Status))
5332 {
5333 /* Damn, this failed. Consider this page as still dirty */
5334 DPRINT1("MiWritePage FAILED: Status 0x%08x!\n", Status);
5335 DirtyAgain = TRUE;
5336 }
5337 else
5338 {
5339 /* Check if someone dirtified this page while we were not looking */
5340 DirtyAgain = IS_DIRTY_SSE(Entry);
5341 }
5342
5343 /* Drop the reference we got, deleting the write altogether. */
5345 if (DirtyAgain)
5346 {
5348 }
5350 }
unsigned char BOOLEAN
Definition: actypes.h:127
#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:1374
#define MAKE_SSE(P, C)
Definition: mm.h:1386
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:1382
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:1377
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:5205
#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 118 of file section.c.

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

Referenced by MiRosUnmapViewOfSection().

◆ MiCopyFromUserPage()

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

Definition at line 1172 of file section.c.

1173{
1175 KIRQL Irql;
1176 PVOID DestAddress;
1177
1179 DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
1180 if (DestAddress == NULL)
1181 {
1182 return STATUS_NO_MEMORY;
1183 }
1184 ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
1185 ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
1186 RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
1187 MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
1188 return STATUS_SUCCESS;
1189}
_Out_ PKIRQL Irql
Definition: csq.h:179
#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 88 of file section.c.

89{
90 KIRQL OldIrql = MiAcquirePfnLock();
92
93 while (TRUE)
94 {
95 Segment = SectionObjectPointer->DataSectionObject;
96 if (!Segment)
97 break;
98
100 {
101 MiReleasePfnLock(OldIrql);
103 OldIrql = MiAcquirePfnLock();
104 continue;
105 }
106
109 break;
110 }
111
112 MiReleasePfnLock(OldIrql);
113
114 return Segment;
115}
#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:246
static LARGE_INTEGER TinyTime
Definition: section.c:61

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

4368{
4370
4372
4373 /* Loop over all entries */
4374 for (PageTable = RtlEnumerateGenericTable(&Segment->PageTable, TRUE);
4375 PageTable != NULL;
4377 {
4378 for (ULONG i = 0; i < _countof(PageTable->PageEntries); i++)
4379 {
4380 ULONG_PTR Entry = PageTable->PageEntries[i];
4382
4383 if (!Entry)
4384 continue;
4385
4387 {
4388 /* I/O ongoing or swap entry. Someone mapped this file as we were not looking */
4390 return FALSE;
4391 }
4392
4393 /* Regular entry */
4396
4397 /* Properly remove using the used API */
4398 Offset.QuadPart = PageTable->FileOffset.QuadPart + (i << PAGE_SHIFT);
4401 }
4402 }
4403
4405
4406 return TRUE;
4407}
#define IS_WRITE_SSE(E)
Definition: mm.h:1378
#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 4614 of file section.c.

4615{
4616 DPRINT("MmUnmapViewInSystemSpace() called\n");
4617
4619}
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1730
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:3566
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492

Referenced by MmUnmapViewInSystemSpace().

◆ MiRosUnmapViewOfSection()

NTSTATUS NTAPI MiRosUnmapViewOfSection ( _In_ PEPROCESS  Process,
_In_ PMEMORY_AREA  MemoryArea,
_In_ PVOID  BaseAddress,
_In_ BOOLEAN  SkipDebuggerNotify 
)

Definition at line 3630 of file section.c.

3635{
3638 PVOID ImageBaseAddress = 0;
3639
3640 DPRINT("Opening memory area Process %p BaseAddress %p\n",
3642
3643 ASSERT(Process);
3645
3646 AddressSpace = &Process->Vm;
3647
3648 if (MemoryArea == NULL ||
3649#ifdef NEWCC
3650 ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) && (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
3651#else
3653#endif
3655
3656 {
3658
3659 DPRINT1("Unable to find memory area at address %p.\n", BaseAddress);
3661 }
3662
3664 {
3665 ULONG i;
3666 ULONG NrSegments;
3667 PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3668 PMM_SECTION_SEGMENT SectionSegments;
3670 ULONG MapCount;
3671
3672 Segment = MemoryArea->SectionData.Segment;
3673 ImageSectionObject = ImageSectionObjectFromSegment(Segment);
3674 SectionSegments = ImageSectionObject->Segments;
3675 NrSegments = ImageSectionObject->NrSegments;
3676
3678
3679 /* Search for the current segment within the section segments
3680 * and calculate the image base address */
3681 for (i = 0; i < NrSegments; i++)
3682 {
3683 if (Segment == &SectionSegments[i])
3684 {
3685 ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
3686 break;
3687 }
3688 }
3689 if (i >= NrSegments)
3690 {
3691 KeBugCheck(MEMORY_MANAGEMENT);
3692 }
3693
3694 for (i = 0; i < NrSegments; i++)
3695 {
3696 PVOID SBaseAddress = (PVOID)
3697 ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
3698
3699 Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
3700 if (!NT_SUCCESS(Status))
3701 {
3702 DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3703 SBaseAddress, Process, Status);
3705 }
3706 }
3707 DPRINT("One mapping less for %p\n", ImageSectionObject->FileObject->SectionObjectPointer);
3708 MapCount = InterlockedDecrement(&ImageSectionObject->MapCount);
3709 if (MapCount != 0)
3710 ImageBaseAddress = NULL;
3711 }
3712 else
3713 {
3715 PMMVAD Vad = &MemoryArea->VadNode;
3716 PCONTROL_AREA ControlArea = Vad->ControlArea;
3719 LARGE_INTEGER ViewOffset;
3720 ViewOffset.QuadPart = MemoryArea->SectionData.ViewOffset;
3721
3722 InterlockedIncrement64(Segment->ReferenceCount);
3723
3724 ViewSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
3725
3727 if (!NT_SUCCESS(Status))
3728 {
3729 DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3732 }
3733
3734 /* These might be deleted now */
3735 Vad = NULL;
3736 MemoryArea = NULL;
3737
3739 {
3740 /* Don't bother */
3741 MmDereferenceSegment(Segment);
3742 return STATUS_SUCCESS;
3743 }
3745
3746 FileObject = Segment->FileObject;
3748
3749 /* Don't bother for auto-delete closed file. */
3751 {
3753 MmDereferenceSegment(Segment);
3754 return STATUS_SUCCESS;
3755 }
3756
3757 /*
3758 * Flush only when last mapping is deleted.
3759 * FIXME: Why ControlArea == NULL? Or rather: is ControlArea ever not NULL here?
3760 */
3761 if (ControlArea == NULL || ControlArea->NumberOfMappedViews == 1)
3762 {
3763 while (ViewSize > 0)
3764 {
3765 ULONG FlushSize = min(ViewSize, PAGE_ROUND_DOWN(MAXULONG));
3766 MmFlushSegment(FileObject->SectionObjectPointer,
3767 &ViewOffset,
3768 FlushSize,
3769 NULL);
3770 ViewSize -= FlushSize;
3771 ViewOffset.QuadPart += FlushSize;
3772 }
3773 }
3774
3776 MmDereferenceSegment(Segment);
3777 }
3778
3779 /* Notify debugger */
3780 if (ImageBaseAddress && !SkipDebuggerNotify) DbgkUnMapViewOfSection(ImageBaseAddress);
3781
3782 return STATUS_SUCCESS;
3783}
#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 _Pre_valid_ PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ 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
#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:243
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:355
PMM_IMAGE_SECTION_OBJECT ImageSectionObjectFromSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:118
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:5119
struct _MEMORY_AREA::@1949 SectionData
BOOLEAN DeleteInProgress
Definition: mm.h:259
ULONG Type
Definition: mm.h:257
MMVAD VadNode
Definition: mm.h:255
ULONG_PTR VadType
Definition: mmtypes.h:694
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
union _MMVAD::@2856 u
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::@1948 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 240 of file section.c.

250{
254 UCHAR MdlBase[sizeof(MDL) + sizeof(PFN_NUMBER)];
255 PMDL Mdl = (PMDL)MdlBase;
256 PFILE_OBJECT FileObject = Segment->FileObject;
258
259 FileOffset.QuadPart = Segment->Image.FileOffset + SegOffset;
260
261 RtlZeroMemory(MdlBase, sizeof(MdlBase));
264 Mdl->MdlFlags |= MDL_PAGES_LOCKED;
265
268 if (Status == STATUS_PENDING)
269 {
271 Status = IoStatus.Status;
272 }
273 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
274 {
275 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
276 }
277
278 return Status;
279}
#define 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
#define STATUS_PENDING
Definition: telnetd.h:14
unsigned char UCHAR
Definition: typedefs.h:53
PVOID PMDL
Definition: usb.h:39
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
@ Executive
Definition: ketypes.h:467
#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

Referenced by FreeSegmentPage().

◆ MmAccessFaultSectionView()

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

Definition at line 1938 of file section.c.

1942{
1944 PFN_NUMBER OldPage;
1945 PFN_NUMBER NewPage;
1946 PFN_NUMBER UnmappedPage;
1947 PVOID PAddress;
1952 BOOLEAN Cow = FALSE;
1954 BOOLEAN Unmapped;
1956
1957 DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1958
1959 /* Get the region for this address */
1961 &MemoryArea->SectionData.RegionListHead,
1962 Address, NULL);
1963 ASSERT(Region != NULL);
1964 if (!(Region->Protect & PAGE_IS_WRITABLE))
1966
1967 /* Make sure we have a page mapping for this address. */
1969 {
1971 if (!NT_SUCCESS(Status))
1972 {
1973 /* This is invalid access ! */
1974 return Status;
1975 }
1976 }
1977
1978 /*
1979 * Check if the page has already been set readwrite
1980 */
1982 {
1983 DPRINT("Address 0x%p\n", Address);
1984 return STATUS_SUCCESS;
1985 }
1986
1987 /* Check if we are doing Copy-On-Write */
1988 Segment = MemoryArea->SectionData.Segment;
1989 Cow = Segment->WriteCopy || (Region->Protect & PAGE_IS_WRITECOPY);
1990
1991 if (!Cow)
1992 {
1993 /* Simply update page protection and we're done */
1995 return STATUS_SUCCESS;
1996 }
1997
1998 /* Calculate the new protection & check if we should update the region */
1999 NewProtect = Region->Protect;
2001 {
2002 NewProtect &= ~PAGE_IS_WRITECOPY;
2003 if (Region->Protect & PAGE_IS_EXECUTABLE)
2005 else
2008 &MemoryArea->SectionData.RegionListHead,
2011 }
2012
2013 /*
2014 * Find the offset of the page
2015 */
2016 PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
2017 Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
2018 + MemoryArea->SectionData.ViewOffset;
2019
2020 /* Get the page mapping this section offset. */
2023
2024 /* Get the current page mapping for the process */
2025 ASSERT(MmIsPagePresent(Process, PAddress));
2026 OldPage = MmGetPfnForProcess(Process, PAddress);
2027 ASSERT(OldPage != 0);
2028
2029 if (IS_SWAP_FROM_SSE(Entry) ||
2030 PFN_FROM_SSE(Entry) != OldPage)
2031 {
2033 /* This is a private page. We must only change the page protection. */
2035 return STATUS_SUCCESS;
2036 }
2037
2038 /*
2039 * Allocate a page
2040 */
2042 if (!NT_SUCCESS(Status))
2043 {
2045 return STATUS_NO_MEMORY;
2046 }
2047
2048 /*
2049 * Copy the old page
2050 */
2051 NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
2052
2053 /*
2054 * Unshare the old page.
2055 */
2056 DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
2057 Unmapped = MmDeleteVirtualMapping(Process, PAddress, NULL, &UnmappedPage);
2058 if (!Unmapped || (UnmappedPage != OldPage))
2059 {
2060 /* Uh , we had a page just before, but suddenly it changes. Someone corrupted us. */
2061 KeBugCheckEx(MEMORY_MANAGEMENT,
2063 (ULONG_PTR)PAddress,
2064 (ULONG_PTR)__FILE__,
2065 __LINE__);
2066 }
2067
2068 if (Process)
2069 MmDeleteRmap(OldPage, Process, PAddress);
2072
2073 /*
2074 * Set the PTE to point to the new page
2075 */
2076 if (!NT_SUCCESS(MmCreateVirtualMapping(Process, PAddress, NewProtect, NewPage)))
2077 {
2078 DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2079 KeBugCheck(MEMORY_MANAGEMENT);
2080 }
2081
2082 if (Process)
2083 MmInsertRmap(NewPage, Process, PAddress);
2084
2085 DPRINT("Address 0x%p\n", Address);
2086 return STATUS_SUCCESS;
2087}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
#define STATUS_ACCESS_VIOLATION
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311
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:250
#define PAGE_IS_WRITABLE
Definition: mm.h:159
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1715
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:165
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:129
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define PAGE_IS_WRITECOPY
Definition: mm.h:171
VOID NTAPI MmDeleteVirtualMapping(IN PEPROCESS Process, IN PVOID Address, OUT PBOOLEAN WasDirty, OUT PPFN_NUMBER Page)
Definition: page.c:177
static WCHAR Address[46]
Definition: ping.c:68
NTSTATUS NTAPI MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
Definition: section.c:1560
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
Definition: section.c:1091
static NTSTATUS MiCopyFromUserPage(PFN_NUMBER DestPage, const VOID *SrcAddress)
Definition: section.c:1172
static VOID MmAlterViewAttributes(PMMSUPPORT AddressSpace, PVOID BaseAddress, SIZE_T RegionSize, ULONG OldType, ULONG OldProtect, ULONG NewType, ULONG NewProtect)
Definition: section.c:1469
Definition: mm.h:482
_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 1469 of file section.c.

1476{
1479 BOOLEAN DoCOW = FALSE;
1480 ULONG i;
1482
1485 Segment = MemoryArea->SectionData.Segment;
1487
1488 if ((Segment->WriteCopy) &&
1490 {
1491 DoCOW = TRUE;
1492 }
1493
1494 if (OldProtect != NewProtect)
1495 {
1496 for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
1497 {
1498 SWAPENTRY SwapEntry;
1499 PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE);
1501
1502 /* Wait for a wait entry to disappear */
1503 do
1504 {
1505 MmGetPageFileMapping(Process, Address, &SwapEntry);
1506 if (SwapEntry != MM_WAIT_ENTRY)
1507 break;
1513 }
1514 while (TRUE);
1515
1516 /*
1517 * If we doing COW for this segment then check if the page is
1518 * already private.
1519 */
1521 {
1525
1527 + MemoryArea->SectionData.ViewOffset;
1529 /*
1530 * An MM_WAIT_ENTRY is ok in this case... It'll just count as
1531 * IS_SWAP_FROM_SSE and we'll do the right thing.
1532 */
1534
1535 /* Choose protection based on what was requested */
1538 else
1540
1542 {
1544 }
1545 }
1546
1548 {
1550 Protect);
1551 }
1552 }
1553 }
1554
1556}
#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:1310
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1695
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
BOOLEAN NTAPI MmIsDisabledPage(struct _EPROCESS *Process, PVOID Address)
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:61
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1708
static int Protect(const char **args)
Definition: vfdcmd.c:2132

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

◆ MmCanFileBeTruncated()

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

Definition at line 4312 of file section.c.

4315{
4316 BOOLEAN Ret;
4318
4319 /* Check whether an ImageSectionObject exists */
4320 if (SectionObjectPointer->ImageSectionObject != NULL)
4321 {
4322 DPRINT1("ERROR: File can't be truncated because it has an image section\n");
4323 return FALSE;
4324 }
4325
4327 if (!Segment)
4328 {
4329 /* There is no data section. It's fine to do anything. */
4330 return TRUE;
4331 }
4332
4334 if ((Segment->SectionCount == 0) ||
4335 ((Segment->SectionCount == 1) && (SectionObjectPointer->SharedCacheMap != NULL)))
4336 {
4337 /* If the cache is the only one holding a reference to the segment, then it's fine to resize */
4338 Ret = TRUE;
4339 }
4340 else if (NewFileSize != NULL)
4341 {
4342 /* We can't shrink, but we can extend */
4343 Ret = NewFileSize->QuadPart >= Segment->RawLength.QuadPart;
4344#if DBG
4345 if (!Ret)
4346 {
4347 DPRINT1("Cannot truncate data: New Size %I64d, Segment Size %I64d\n", NewFileSize->QuadPart, Segment->RawLength.QuadPart);
4348 }
4349#endif
4350 }
4351 else
4352 {
4353 DPRINT1("ERROR: File can't be truncated because it has references held to its data section\n");
4354 Ret = FALSE;
4355 }
4356
4358 MmDereferenceSegment(Segment);
4359
4360 DPRINT("FIXME: didn't check for outstanding write probes\n");
4361
4362 return Ret;
4363}
static PMM_SECTION_SEGMENT MiGrabDataSection(PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: section.c:88
_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 2105 of file section.c.

2113{
2114 SECTION Section;
2115 PSECTION NewSection;
2116 PSUBSECTION Subsection;
2117 PSEGMENT NewSegment, Segment;
2119 PCONTROL_AREA ControlArea;
2120 ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2122 BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2123 KIRQL OldIrql;
2125 BOOLEAN UserRefIncremented = FALSE;
2126 PVOID PreviousSectionPointer;
2127
2128 /* Make the same sanity checks that the Nt interface should've validated */
2131 SEC_NO_CHANGE)) == 0);
2141
2142 /* Convert section flag to page flag */
2145
2146 /* Check to make sure the protection is correct. Nt* does this already */
2148 if (ProtectionMask == MM_INVALID_PROTECTION)
2149 {
2150 DPRINT1("Invalid protection mask\n");
2152 }
2153
2154 /* Check if this is going to be a data or image backed file section */
2155 if ((FileHandle) || (FileObject))
2156 {
2157 /* These cannot be mapped with large pages */
2159
2160 /* For now, only support the mechanism through a file handle */
2162
2163 /* Reference the file handle to get the object */
2165 MmMakeFileAccess[ProtectionMask],
2168 (PVOID*)&File,
2169 NULL);
2170 if (!NT_SUCCESS(Status)) return Status;
2171
2172 /* Make sure Cc has been doing its job */
2173 if (!File->SectionObjectPointer)
2174 {
2175 /* This is not a valid file system-based file, fail */
2178 }
2179
2180 /* Image-file backed sections are not yet supported */
2182
2183 /* Compute the size of the control area, and allocate it */
2184 ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2185 ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2186 if (!ControlArea)
2187 {
2190 }
2191
2192 /* Zero it out */
2193 RtlZeroMemory(ControlArea, ControlAreaSize);
2194
2195 /* Did we get a handle, or an object? */
2196 if (FileHandle)
2197 {
2198 /* We got a file handle so we have to lock down the file */
2199#if 0
2201 if (!NT_SUCCESS(Status))
2202 {
2203 ExFreePool(ControlArea);
2205 return Status;
2206 }
2207#else
2208 /* ReactOS doesn't support this API yet, so do nothing */
2211#endif
2212 /* Update the top-level IRP so that drivers know what's happening */
2214 FileLock = TRUE;
2215 }
2216
2217 /* Lock the PFN database while we play with the section pointers */
2218 OldIrql = MiAcquirePfnLock();
2219
2220 /* Image-file backed sections are not yet supported */
2222
2223 /* There should not already be a control area for this file */
2224 ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2225 NewSegment = NULL;
2226
2227 /* Write down that this CA is being created, and set it */
2228 ControlArea->u.Flags.BeingCreated = TRUE;
2230 PreviousSectionPointer = File->SectionObjectPointer;
2231 File->SectionObjectPointer->DataSectionObject = ControlArea;
2232
2233 /* We can release the PFN lock now */
2234 MiReleasePfnLock(OldIrql);
2235
2236 /* We don't support previously-mapped file */
2237 ASSERT(NewSegment == NULL);
2238
2239 /* Image-file backed sections are not yet supported */
2241
2242 /* So we always create a data file map */
2244 &Segment,
2245 InputMaximumSize,
2248 KernelCall);
2249 if (!NT_SUCCESS(Status))
2250 {
2251 /* Lock the PFN database while we play with the section pointers */
2252 OldIrql = MiAcquirePfnLock();
2253
2254 /* Reset the waiting-for-deletion event */
2255 ASSERT(ControlArea->WaitingForDeletion == NULL);
2256 ControlArea->WaitingForDeletion = NULL;
2257
2258 /* Set the file pointer NULL flag */
2259 ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2260 ControlArea->u.Flags.FilePointerNull = TRUE;
2261
2262 /* Delete the data section object */
2264 File->SectionObjectPointer->DataSectionObject = NULL;
2265
2266 /* No longer being created */
2267 ControlArea->u.Flags.BeingCreated = FALSE;
2268
2269 /* We can release the PFN lock now */
2270 MiReleasePfnLock(OldIrql);
2271
2272 /* Check if we locked and set the IRP */
2273 if (FileLock)
2274 {
2275 /* Undo */
2277 //FsRtlReleaseFile(File);
2278 }
2279
2280 /* Free the control area and de-ref the file object */
2281 ExFreePool(ControlArea);
2283
2284 /* All done */
2285 return Status;
2286 }
2287
2288 /* On success, we expect this */
2289 ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2290
2291 /* Check if a maximum size was specified */
2292 if (!InputMaximumSize->QuadPart)
2293 {
2294 /* Nope, use the segment size */
2295 Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2296 }
2297 else
2298 {
2299 /* Yep, use the entered size */
2300 Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2301 }
2302 }
2303 else
2304 {
2305 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2307
2308 /* Not yet supported */
2310
2311 /* So this must be a pagefile-backed section, create the mappings needed */
2312 Status = MiCreatePagingFileMap(&NewSegment,
2313 InputMaximumSize->QuadPart,
2314 ProtectionMask,
2316 if (!NT_SUCCESS(Status)) return Status;
2317
2318 /* Set the size here, and read the control area */
2319 Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2320 ControlArea = NewSegment->ControlArea;
2321
2322 /* MiCreatePagingFileMap increments user references */
2323 UserRefIncremented = TRUE;
2324 }
2325
2326 /* Did we already have a segment? */
2327 if (!NewSegment)
2328 {
2329 /* This must be the file path and we created a segment */
2330 NewSegment = Segment;
2331 ASSERT(File != NULL);
2332
2333 /* Acquire the PFN lock while we set control area flags */
2334 OldIrql = MiAcquirePfnLock();
2335
2336 /* We don't support this race condition yet, so assume no waiters */
2337 ASSERT(ControlArea->WaitingForDeletion == NULL);
2338 ControlArea->WaitingForDeletion = NULL;
2339
2340 /* Image-file backed sections are not yet supported, nor ROM images */
2342 ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2343
2344 /* Take off the being created flag, and then release the lock */
2345 ControlArea->u.Flags.BeingCreated = FALSE;
2346 MiReleasePfnLock(OldIrql);
2347 }
2348
2349 /* Check if we locked the file earlier */
2350 if (FileLock)
2351 {
2352 /* Reset the top-level IRP and release the lock */
2354 //FsRtlReleaseFile(File);
2355 FileLock = FALSE;
2356 }
2357
2358 /* Set the initial section object data */
2360
2361 /* The mapping created a control area and segment, save the flags */
2362 Section.Segment = NewSegment;
2363 Section.u.LongFlags = ControlArea->u.LongFlags;
2364
2365 /* Check if this is a user-mode read-write non-image file mapping */
2366 if (!(FileObject) &&
2368 !(ControlArea->u.Flags.Image) &&
2369 (ControlArea->FilePointer))
2370 {
2371 /* Add a reference and set the flag */
2372 Section.u.Flags.UserWritable = TRUE;
2373 InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2374 }
2375
2376 /* Check for image mappings or page file mappings */
2377 if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2378 {
2379 /* Charge the segment size, and allocate a subsection */
2380 PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2381 Size = sizeof(SUBSECTION);
2382 }
2383 else
2384 {
2385 /* Charge nothing, and allocate a mapped subsection */
2386 PagedCharge = 0;
2387 Size = sizeof(MSUBSECTION);
2388 }
2389
2390 /* Check if this is a normal CA */
2391 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2392 ASSERT(ControlArea->u.Flags.Rom == 0);
2393
2394 /* Charge only a CA, and the subsection is right after */
2395 NonPagedCharge = sizeof(CONTROL_AREA);
2396 Subsection = (PSUBSECTION)(ControlArea + 1);
2397
2398 /* We only support single-subsection mappings */
2399 NonPagedCharge += Size;
2400 ASSERT(Subsection->NextSubsection == NULL);
2401
2402 /* Create the actual section object, with enough space for the prototype PTEs */
2407 NULL,
2408 sizeof(SECTION),
2409 PagedCharge,
2410 NonPagedCharge,
2411 (PVOID*)&NewSection);
2412 if (!NT_SUCCESS(Status))
2413 {
2414 /* Check if this is a user-mode read-write non-image file mapping */
2415 if (!(FileObject) &&
2417 !(ControlArea->u.Flags.Image) &&
2418 (ControlArea->FilePointer))
2419 {
2420 /* Remove a reference and check the flag */
2421 ASSERT(Section.u.Flags.UserWritable == 1);
2422 InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2423 }
2424
2425 /* Check if a user reference was added */
2426 if (UserRefIncremented)
2427 {
2428 /* Acquire the PFN lock while we change counters */
2429 OldIrql = MiAcquirePfnLock();
2430
2431 /* Decrement the accounting counters */
2432 ControlArea->NumberOfSectionReferences--;
2433 ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2434 ControlArea->NumberOfUserReferences--;
2435
2436 /* Check if we should destroy the CA and release the lock */
2437 MiCheckControlArea(ControlArea, OldIrql);
2438 }
2439
2440 /* Return the failure code */
2441 return Status;
2442 }
2443
2444 /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2445
2446 /* Now copy the local section object from the stack into this new object */
2447 RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2448 NewSection->Address.StartingVpn = 0;
2449
2450 /* For now, only user calls are supported */
2451 ASSERT(KernelCall == FALSE);
2452 NewSection->u.Flags.UserReference = TRUE;
2453
2454 /* Is this a "based" allocation, in which all mappings are identical? */
2456 {
2457 /* Lock the VAD tree during the search */
2459
2460 /* Is it a brand new ControArea ? */
2461 if (ControlArea->u.Flags.BeingCreated == 1)
2462 {
2463 ASSERT(ControlArea->u.Flags.Based == 1);
2464 /* Then we must find a global address, top-down */
2467 _64K,
2469 (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2470
2471 if (!NT_SUCCESS(Status))
2472 {
2473 /* No way to find a valid range. */
2475 ControlArea->u.Flags.Based = 0;
2476 NewSection->u.Flags.Based = 0;
2477 ObDereferenceObject(NewSection);
2478 return Status;
2479 }
2480
2481 /* Compute the ending address and insert it into the VAD tree */
2482 NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2483 NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2484 MiInsertBasedSection(NewSection);
2485 }
2486 else
2487 {
2488 /* 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 !*/
2489 ASSERT(FALSE);
2490 }
2491
2493 }
2494
2495 /* The control area is not being created anymore */
2496 if (ControlArea->u.Flags.BeingCreated == 1)
2497 {
2498 /* Acquire the PFN lock while we set control area flags */
2499 OldIrql = MiAcquirePfnLock();
2500
2501 /* Take off the being created flag, and then release the lock */
2502 ControlArea->u.Flags.BeingCreated = 0;
2503 NewSection->u.Flags.BeingCreated = 0;
2504
2505 MiReleasePfnLock(OldIrql);
2506 }
2507
2508 /* Migrate the attribute into a flag */
2510
2511 /* If R/W access is not requested, this might eventually become a CoW mapping */
2513 {
2514 NewSection->u.Flags.CopyOnWrite = TRUE;
2515 }
2516
2517 /* Write down if this was a kernel call */
2518 ControlArea->u.Flags.WasPurged |= KernelCall;
2519 ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2520
2521 /* Make sure the segment and the section are the same size, or the section is smaller */
2522 ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2523
2524 /* Return the object and the creation status */
2525 *SectionObject = (PVOID)NewSection;
2526 return Status;
2527}
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
static NTSTATUS MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1409
static NTSTATUS MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN ULONG64 MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1424
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:716
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:386
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:711
#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:1314
#define SEC_RESERVE
Definition: nt_native.h:1326
#define PAGE_NOACCESS
Definition: nt_native.h:1305
#define PAGE_GUARD
Definition: nt_native.h:1313
#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:362
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:574
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:399
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:196
PSEGMENT Segment
Definition: mmtypes.h:521
ULONG NumberOfSectionReferences
Definition: mmtypes.h:523
union _CONTROL_AREA::@2849 u
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
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
ULONG UserWritable
Definition: mmtypes.h:489
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
union _SECTION::@2865 u
ULONG LongFlags
Definition: mmtypes.h:816
PSEGMENT Segment
Definition: mmtypes.h:812
ULONG InitialPageProtection
Definition: mmtypes.h:819
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
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:4539
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 2363 of file section.c.

2374{
2375 PSECTION Section;
2379 KIRQL OldIrql;
2380
2381 /*
2382 * Create the section
2383 */
2388 NULL,
2389 sizeof(*Section),
2390 0,
2391 0,
2392 (PVOID*)&Section);
2393 if (!NT_SUCCESS(Status))
2394 {
2395 return Status;
2396 }
2397 /*
2398 * Initialize it
2399 */
2400 RtlZeroMemory(Section, sizeof(*Section));
2401
2402 /* Mark this as a "ROS" section */
2403 Section->u.Flags.filler = 1;
2405 Section->u.Flags.File = 1;
2406
2408 Section->u.Flags.NoChange = 1;
2409
2410 if (!GotFileHandle)
2411 {
2412 ASSERT(UMaximumSize != NULL);
2413 // ASSERT(UMaximumSize->QuadPart != 0);
2414 MaximumSize = *UMaximumSize;
2415 }
2416 else
2417 {
2420 if (!NT_SUCCESS(Status))
2421 {
2422 ObDereferenceObject(Section);
2423 return Status;
2424 }
2425
2426 /*
2427 * FIXME: Revise this once a locking order for file size changes is
2428 * decided
2429 */
2430 if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
2431 {
2432 MaximumSize = *UMaximumSize;
2433 }
2434 else
2435 {
2437 /* Mapping zero-sized files isn't allowed. */
2438 if (MaximumSize.QuadPart == 0)
2439 {
2440 ObDereferenceObject(Section);
2442 }
2443 }
2444
2445 if (MaximumSize.QuadPart > FileSize.QuadPart)
2446 {
2449 sizeof(LARGE_INTEGER),
2450 &MaximumSize);
2451 if (!NT_SUCCESS(Status))
2452 {
2453 ObDereferenceObject(Section);
2455 }
2456 }
2457 }
2458
2459 if (FileObject->SectionObjectPointer == NULL)
2460 {
2461 ObDereferenceObject(Section);
2463 }
2464
2465 /*
2466 * Lock the file
2467 */
2469 if (Status != STATUS_SUCCESS)
2470 {
2471 ObDereferenceObject(Section);
2472 return Status;
2473 }
2474
2475 /* Lock the PFN lock while messing with Section Object pointers */
2476grab_segment:
2477 OldIrql = MiAcquirePfnLock();
2478 Segment = FileObject->SectionObjectPointer->DataSectionObject;
2479
2480 while (Segment && (Segment->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
2481 {
2482 MiReleasePfnLock(OldIrql);
2484 OldIrql = MiAcquirePfnLock();
2485 Segment = FileObject->SectionObjectPointer->DataSectionObject;
2486 }
2487
2488 /*
2489 * If this file hasn't been mapped as a data file before then allocate a
2490 * section segment to describe the data file mapping
2491 */
2492 if (Segment == NULL)
2493 {
2494 /* Release the lock. ExAllocatePoolWithTag might acquire it */
2495 MiReleasePfnLock(OldIrql);
2496
2499 if (Segment == NULL)
2500 {
2501 //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2502 ObDereferenceObject(Section);
2503 return STATUS_NO_MEMORY;
2504 }
2505
2506 /* We are creating it */
2507 RtlZeroMemory(Segment, sizeof(*Segment));
2509 Segment->RefCount = 1;
2510
2511 /* Acquire lock again */
2512 OldIrql = MiAcquirePfnLock();
2513
2514 if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
2515 {
2516 /* Well that's bad luck. Restart it all over */
2517 MiReleasePfnLock(OldIrql);
2519 goto grab_segment;
2520 }
2521
2522 FileObject->SectionObjectPointer->DataSectionObject = Segment;
2523
2524 /* We're safe to release the lock now */
2525 MiReleasePfnLock(OldIrql);
2526
2527 Section->Segment = (PSEGMENT)Segment;
2528
2529 /* Self-referencing segment */
2530 Segment->Flags = &Segment->SegFlags;
2531 Segment->ReferenceCount = &Segment->RefCount;
2532
2533 Segment->SectionCount = 1;
2534
2536 Segment->FileObject = FileObject;
2538
2539 Segment->Image.FileOffset = 0;
2540 Segment->Protection = SectionPageProtection;
2541
2542 Segment->Image.Characteristics = 0;
2545 {
2546 Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
2547 }
2548 else
2549 {
2550 Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2551 Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2552 }
2553 Segment->Image.VirtualAddress = 0;
2555
2556 /* We're good to use it now */
2557 OldIrql = MiAcquirePfnLock();
2558 Segment->SegFlags &= ~MM_SEGMENT_INCREATE;
2559 MiReleasePfnLock(OldIrql);
2560 }
2561 else
2562 {
2563 Section->Segment = (PSEGMENT)Segment;
2564 InterlockedIncrement64(&Segment->RefCount);
2565 InterlockedIncrementUL(&Segment->SectionCount);
2566
2567 MiReleasePfnLock(OldIrql);
2568
2570
2571 if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
2573 {
2574 Segment->RawLength.QuadPart = MaximumSize.QuadPart;
2575 Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
2576 }
2577
2579 }
2580 Section->SizeOfSection = MaximumSize;
2581
2582 //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2583 *SectionObject = Section;
2584 return STATUS_SUCCESS;
2585}
#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:1308
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1312
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:616
#define STATUS_SECTION_NOT_EXTENDED
Definition: ntstatus.h:465
NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File)
Definition: section.c:909
#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 3211 of file section.c.

3218{
3219 PSECTION Section;
3221 PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3222 KIRQL OldIrql;
3223
3224
3225 if (FileObject == NULL)
3227
3228 if (FileObject->SectionObjectPointer == NULL)
3229 {
3230 DPRINT1("Denying section creation due to missing cache initialization\n");
3232 }
3233
3234 /*
3235 * Create the section
3236 */
3241 NULL,
3242 sizeof(*Section),
3243 0,
3244 0,
3245 (PVOID*)(PVOID)&Section);
3246 if (!NT_SUCCESS(Status))
3247 {
3248 return Status;
3249 }
3250
3251 /*
3252 * Initialize it
3253 */
3254 RtlZeroMemory(Section, sizeof(*Section));
3255
3256 /* Mark this as a "ROS" Section */
3257 Section->u.Flags.filler = 1;
3258
3260 Section->SizeOfSection = *UMaximumSize;
3261 Section->u.Flags.File = 1;
3262 Section->u.Flags.Image = 1;
3264 Section->u.Flags.NoChange = 1;
3265
3266grab_image_section_object:
3267 OldIrql = MiAcquirePfnLock();
3268
3269 /* Wait for it to be properly created or deleted */
3270 ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3271 while(ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
3272 {
3273 MiReleasePfnLock(OldIrql);
3274
3276
3277 OldIrql = MiAcquirePfnLock();
3278 ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3279 }
3280
3281 if (ImageSectionObject == NULL)
3282 {
3283 NTSTATUS StatusExeFmt;
3284
3285 /* Release the lock because ExAllocatePoolWithTag could need to acquire it */
3286 MiReleasePfnLock(OldIrql);
3287
3289 if (ImageSectionObject == NULL)
3290 {
3291 ObDereferenceObject(Section);
3292 return STATUS_NO_MEMORY;
3293 }
3294
3295 ImageSectionObject->SegFlags = MM_SEGMENT_INCREATE;
3296 ImageSectionObject->RefCount = 1;
3297 ImageSectionObject->SectionCount = 1;
3298
3299 OldIrql = MiAcquirePfnLock();
3300 if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
3301 {
3302 MiReleasePfnLock(OldIrql);
3303 /* Bad luck. Start over */
3304 ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3305 goto grab_image_section_object;
3306 }
3307
3308 FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
3309
3310 MiReleasePfnLock(OldIrql);
3311
3312 /* Purge the cache */
3313 CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
3314
3315 StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
3316
3317 if (!NT_SUCCESS(StatusExeFmt))
3318 {
3319 /* Unset */
3320 OldIrql = MiAcquirePfnLock();
3321 FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3322 MiReleasePfnLock(OldIrql);
3323
3324 if(ImageSectionObject->Segments != NULL)
3325 ExFreePool(ImageSectionObject->Segments);
3326
3327 /*
3328 * If image file is empty, then return that the file is invalid for section
3329 */
3330 Status = StatusExeFmt;
3331 if (StatusExeFmt == STATUS_END_OF_FILE)
3332 {
3334 }
3335
3336 ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3337 ObDereferenceObject(Section);
3338 return Status;
3339 }
3340
3341 Section->Segment = (PSEGMENT)ImageSectionObject;
3342 ASSERT(ImageSectionObject->Segments);
3343 ASSERT(ImageSectionObject->RefCount > 0);
3344
3345 /*
3346 * Lock the file
3347 */
3349 if (!NT_SUCCESS(Status))
3350 {
3351 /* Unset */
3352 OldIrql = MiAcquirePfnLock();
3353 FileObject->SectionObjectPointer->ImageSectionObject = NULL;
3354 MiReleasePfnLock(OldIrql);
3355
3356 ExFreePool(ImageSectionObject->Segments);
3357 ExFreePool(ImageSectionObject);
3358 ObDereferenceObject(Section);
3359 return Status;
3360 }
3361
3362 OldIrql = MiAcquirePfnLock();
3363 ImageSectionObject->SegFlags &= ~MM_SEGMENT_INCREATE;
3364
3365 /* Take a ref on the file on behalf of the newly created structure */
3367
3368 MiReleasePfnLock(OldIrql);
3369
3370 Status = StatusExeFmt;
3371 }
3372 else
3373 {
3374 /* If FS driver called for delete, tell them it's not possible anymore. */
3375 ImageSectionObject->SegFlags &= ~MM_IMAGE_SECTION_FLUSH_DELETE;
3376
3377 /* Take one ref */
3378 InterlockedIncrement64(&ImageSectionObject->RefCount);
3379 ImageSectionObject->SectionCount++;
3380
3381 MiReleasePfnLock(OldIrql);
3382
3383 Section->Segment = (PSEGMENT)ImageSectionObject;
3384
3386 }
3387
3388 if (Section->SizeOfSection.QuadPart == 0)
3389 {
3390 Section->SizeOfSection.QuadPart = ImageSectionObject->ImageInformation.ImageFileSize;
3391 }
3392
3393 //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
3394 *SectionObject = Section;
3395 ASSERT(ImageSectionObject->RefCount > 0);
3396
3397 return Status;
3398}
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
static 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:3058
#define STATUS_END_OF_FILE
Definition: shellext.h:67
SECTION_IMAGE_INFORMATION ImageInformation
Definition: mm.h:237

Referenced by MmCreateSection().

◆ MmCreatePhysicalMemorySection()

NTSTATUS NTAPI MmCreatePhysicalMemorySection ( VOID  )

Definition at line 2239 of file section.c.

2240{
2241 PSECTION PhysSection;
2244 UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2245 LARGE_INTEGER SectionSize;
2246 HANDLE Handle;
2248
2249 /*
2250 * Create the section mapping physical memory
2251 */
2254 &Name,
2256 NULL,
2257 NULL);
2258 /*
2259 * Create the Object
2260 */
2263 &Obj,
2265 NULL,
2266 sizeof(*PhysSection),
2267 0,
2268 0,
2269 (PVOID*)&PhysSection);
2270 if (!NT_SUCCESS(Status))
2271 {
2272 DPRINT1("MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n", Status);
2273 return Status;
2274 }
2275
2276 /*
2277 * Initialize it
2278 */
2279 RtlZeroMemory(PhysSection, sizeof(*PhysSection));
2280
2281 /* Mark this as a "ROS Section" */
2282 PhysSection->u.Flags.filler = 1;
2284 PhysSection->u.Flags.PhysicalMemory = 1;
2285 PhysSection->SizeOfSection = SectionSize;
2288 if (Segment == NULL)
2289 {
2290 ObDereferenceObject(PhysSection);
2291 return STATUS_NO_MEMORY;
2292 }
2294 PhysSection->Segment = (PSEGMENT)Segment;
2295 Segment->RefCount = 1;
2296
2297 Segment->ReferenceCount = &Segment->RefCount;
2298 Segment->Flags = &Segment->SegFlags;
2299
2301 Segment->Image.FileOffset = 0;
2302 Segment->Protection = PAGE_EXECUTE_READWRITE;
2303 Segment->RawLength = SectionSize;
2304 Segment->Length = SectionSize;
2306 Segment->WriteCopy = FALSE;
2307 Segment->Image.VirtualAddress = 0;
2308 Segment->Image.Characteristics = 0;
2310
2311 Status = ObInsertObject(PhysSection,
2312 NULL,
2314 0,
2315 NULL,
2316 &Handle);
2317 if (!NT_SUCCESS(Status))
2318 {
2319 /* Note: ObInsertObject dereferences PhysSection on failure */
2320 return Status;
2321 }
2323
2324 return STATUS_SUCCESS;
2325}
LPWSTR Name
Definition: desk.c:124
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define L(x)
Definition: resources.c:13
ULONG Handle
Definition: gdb_input.c:15
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:91
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1296
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
#define OBJ_PERMANENT
Definition: winternl.h:226
ULONG PhysicalMemory
Definition: mmtypes.h:473

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

4685{
4687 ULONG Protection;
4688 PSECTION *SectionObject = (PSECTION *)Section;
4689 BOOLEAN FileLock = FALSE;
4690 BOOLEAN HaveFileObject = FALSE;
4691
4692 // FIXME: Implement support for large pages
4694 {
4695 DPRINT1("SEC_LARGE_PAGES is not supported\n");
4697 }
4698
4699 /* Check if an ARM3 section is being created instead */
4701 {
4702 if (!(FileObject) && !(FileHandle))
4703 {
4704 return MmCreateArm3Section(Section,
4710 FileHandle,
4711 FileObject);
4712 }
4713 }
4714
4715 /* Convert section flag to page flag */
4717
4718 /* Check to make sure the protection is correct. Nt* does this already */
4720 if (Protection == MM_INVALID_PROTECTION)
4721 {
4722 DPRINT1("Page protection is invalid\n");
4724 }
4725
4726 /* Check if this is going to be a data or image backed file section */
4727 if ((FileHandle) || (FileObject))
4728 {
4729 /* These cannot be mapped with large pages */
4731 {
4732 DPRINT1("Large pages cannot be used with an image mapping\n");
4734 }
4735
4736 /* Did the caller pass a file object ? */
4737 if (FileObject)
4738 {
4739 /* Reference the object directly */
4741 HaveFileObject = TRUE;
4742 }
4743 else
4744 {
4745 /* Reference the file handle to get the object */
4747 MmMakeFileAccess[Protection],
4750 (PVOID*)&FileObject,
4751 NULL);
4752 if (!NT_SUCCESS(Status))
4753 {
4754 DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
4755 return Status;
4756 }
4757
4758 /* Lock the file */
4760 if (!NT_SUCCESS(Status))
4761 {
4763 return Status;
4764 }
4765
4766 FileLock = TRUE;
4767
4768 /* Deny access if there are writes on the file */
4769#if 0
4771 {
4772 DPRINT1("Cannot create image maps with writers open on the file!\n");
4774 goto Quit;
4775 }
4776#else
4778 DPRINT1("Creating image map with writers open on the file!\n");
4779#endif
4780 }
4781 }
4782 else
4783 {
4784 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
4786 }
4787
4788 if (FileObject == NULL)
4789 {
4791 goto Exit;
4792 }
4793
4795 {
4802 FileObject);
4803
4804 /* If the file was ivalid, and we got a FileObject passed, fall back to data section */
4805 if (!NT_SUCCESS(Status) && HaveFileObject)
4806 {
4807 AllocationAttributes &= ~SEC_IMAGE;
4808 }
4809 }
4810
4811#ifndef NEWCC
4813 {
4820 FileObject,
4821 FileHandle != NULL);
4822 }
4823#else
4824 else
4825 {
4832 FileObject);
4833 }
4834#endif
4835
4836Exit:
4837
4838 if (FileLock)
4840 if (FileObject)
4842
4843 return Status;
4844}
NTSTATUS NTAPI MmCreateCacheSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
#define STATUS_FILE_LOCKED_WITH_WRITERS
Definition: ntstatus.h:168
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:2363
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:2105
NTSTATUS MmCreateImageSection(PSECTION *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
Definition: section.c:3211
static void Exit(void)
Definition: sock.c:1330
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664

Referenced by CcpAllocateSection(), CcRosInitializeFileCache(), EngCreateSection(), EngCreateSectionHack(), EngLoadModuleEx(), InitGdiHandleTable(), IntGdiAddFontResourceSingle(), NtCreateSection(), TestCreateSection(), TestPhysicalMemorySection(), and UserCreateHeap().

◆ MmExtendSection()

NTSTATUS NTAPI MmExtendSection ( _In_ PVOID  _Section,
_Inout_ PLARGE_INTEGER  NewSize 
)

Definition at line 5451 of file section.c.

5454{
5455 PSECTION Section = _Section;
5456
5457 /* It makes no sense to extend an image mapping */
5458 if (Section->u.Flags.Image)
5460
5461 /* Nor is it possible to extend a page file mapping */
5462 if (!Section->u.Flags.File)
5464
5465 if (!MiIsRosSectionObject(Section))
5467
5468 /* We just extend the sizes. Shrinking is a no-op ? */
5469 if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5470 {
5472 Section->SizeOfSection = *NewSize;
5473
5474 if (!Section->u.Flags.Reserve)
5475 {
5477 if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5478 {
5479 Segment->RawLength = *NewSize;
5480 Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5481 }
5483 }
5484 }
5485
5486 return STATUS_SUCCESS;
5487}
#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:1105
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 4413 of file section.c.

4415{
4416 switch(FlushType)
4417 {
4418 case MmFlushForDelete:
4419 {
4420 /*
4421 * FIXME: Check for outstanding write probes on Data section.
4422 * How do we do that ?
4423 */
4424 }
4425 /* Fall-through */
4426 case MmFlushForWrite:
4427 {
4428 KIRQL OldIrql = MiAcquirePfnLock();
4429 PMM_IMAGE_SECTION_OBJECT ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4430
4431 DPRINT("Deleting or modifying %p\n", SectionObjectPointer);
4432
4433 /* Wait for concurrent creation or deletion of image to be done */
4434 ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4435 while (ImageSectionObject && (ImageSectionObject->SegFlags & (MM_SEGMENT_INCREATE | MM_SEGMENT_INDELETE)))
4436 {
4437 MiReleasePfnLock(OldIrql);
4439 OldIrql = MiAcquirePfnLock();
4440 ImageSectionObject = SectionObjectPointer->ImageSectionObject;
4441 }
4442
4443 if (!ImageSectionObject)
4444 {
4445 DPRINT("No image section object. Accepting\n");
4446 /* Nothing to do */
4447 MiReleasePfnLock(OldIrql);
4448 return TRUE;
4449 }
4450
4451 /* Do we have open sections or mappings on it ? */
4452 if ((ImageSectionObject->SectionCount) || (ImageSectionObject->MapCount))
4453 {
4454 /* We do. No way to delete it */
4455 MiReleasePfnLock(OldIrql);
4456 DPRINT("Denying. There are mappings open\n");
4457 return FALSE;
4458 }
4459
4460 /* There are no sections open on it, but we must still have pages around. Discard everything */
4461 ImageSectionObject->SegFlags |= MM_IMAGE_SECTION_FLUSH_DELETE;
4462 InterlockedIncrement64(&ImageSectionObject->RefCount);
4463 MiReleasePfnLock(OldIrql);
4464
4465 DPRINT("Purging\n");
4466
4467 for (ULONG i = 0; i < ImageSectionObject->NrSegments; i++)
4468 {
4469 if (!MiPurgeImageSegment(&ImageSectionObject->Segments[i]))
4470 break;
4471 }
4472
4473 /* Grab lock again */
4474 OldIrql = MiAcquirePfnLock();
4475
4476 if (!(ImageSectionObject->SegFlags & MM_IMAGE_SECTION_FLUSH_DELETE))
4477 {
4478 /*
4479 * Someone actually created a section while we were not looking.
4480 * Drop our ref and deny.
4481 * MmDereferenceSegmentWithLock releases Pfn lock
4482 */
4483 MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4484 return FALSE;
4485 }
4486
4487 /* We should be the last one holding a ref here. */
4488 ASSERT(ImageSectionObject->RefCount == 1);
4489 ASSERT(ImageSectionObject->SectionCount == 0);
4490
4491 /* Dereference the first segment, this will free everything & release the lock */
4492 MmDereferenceSegmentWithLock(&ImageSectionObject->Segments[0], OldIrql);
4493 return TRUE;
4494 }
4495 }
4496 return FALSE;
4497}
IN PFCB IN FAT_FLUSH_TYPE FlushType
Definition: fatprocs.h:1083
#define MM_IMAGE_SECTION_FLUSH_DELETE
Definition: mm.h:247
static BOOLEAN MiPurgeImageSegment(PMM_SECTION_SEGMENT Segment)
Definition: section.c:4367

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

5124{
5125 LARGE_INTEGER FlushStart, FlushEnd;
5127
5128 if (Offset)
5129 {
5130 FlushStart = *Offset;
5131 Status = RtlLongLongAdd(FlushStart.QuadPart, Length, &FlushEnd.QuadPart);
5132 if (!NT_SUCCESS(Status))
5133 return Status;
5134 }
5135
5136 if (Iosb)
5137 Iosb->Information = 0;
5138
5140 if (!Segment)
5141 {
5142 /* Nothing to flush */
5143 goto Quit;
5144 }
5145
5147
5149
5150 if (!Offset)
5151 {
5152 FlushStart.QuadPart = 0;
5153
5154 /* FIXME: All of this is suboptimal */
5155 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
5156 if (!ElemCount)
5157 {
5158 /* No page. Nothing to flush */
5160 MmDereferenceSegment(Segment);
5161 goto Quit;
5162 }
5163
5165 FlushEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
5166 }
5167
5168 /* Find byte offset of the page to start */
5169 FlushStart.QuadPart = PAGE_ROUND_DOWN_64(FlushStart.QuadPart);
5170
5171 while (FlushStart.QuadPart < FlushEnd.QuadPart)
5172 {
5174
5175 if (IS_DIRTY_SSE(Entry))
5176 {
5177 MmCheckDirtySegment(Segment, &FlushStart, FALSE, FALSE);
5178
5179 if (Iosb)
5180 Iosb->Information += PAGE_SIZE;
5181 }
5182
5183 FlushStart.QuadPart += PAGE_SIZE;
5184 }
5185
5187 MmDereferenceSegment(Segment);
5188
5189Quit:
5190 /* FIXME: Handle failures */
5191 if (Iosb)
5192 Iosb->Status = STATUS_SUCCESS;
5193
5194 return STATUS_SUCCESS;
5195}
BOOLEAN NTAPI MmCheckDirtySegment(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN ForceDirty, BOOLEAN PageOut)
#define PAGE_ROUND_DOWN_64(x)
Definition: mm.h:136
_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 3482 of file section.c.

3484{
3487 SWAPENTRY SavedSwapEntry;
3491
3494
3496
3498 MemoryArea->SectionData.ViewOffset;
3499
3500 Segment = MemoryArea->SectionData.Segment;
3501
3503 while (Entry && MM_IS_WAIT_PTE(Entry))
3504 {
3507
3509
3513 }
3514
3515 /*
3516 * For a dirty, datafile, non-private page, there shoulkd be no swap entry
3517 */
3518 if (*Segment->Flags & MM_DATAFILE_SEGMENT)
3519 {
3520 if (Page == PFN_FROM_SSE(Entry) && Dirty)
3521 {
3522 ASSERT(SwapEntry == 0);
3523 }
3524 }
3525
3526 if (SwapEntry != 0)
3527 {
3528 /*
3529 * Sanity check
3530 */
3531 MmFreeSwapPage(SwapEntry);
3532 }
3533 else if (Page != 0)
3534 {
3535 if (IS_SWAP_FROM_SSE(Entry) ||
3537 {
3538 ASSERT(Process != NULL);
3539
3540 /*
3541 * Just dereference private pages
3542 */
3543 SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
3544 if (SavedSwapEntry != 0)
3545 {
3546 MmFreeSwapPage(SavedSwapEntry);
3548 }
3551 }
3552 else
3553 {
3554 if (Process)
3555 {
3557 }
3558
3559 /* We don't dirtify for System Space Maps. We let Cc manage that */
3561 }
3562 }
3563}
struct _MMSUPPORT * PMMSUPPORT
#define MM_IS_WAIT_PTE(E)
Definition: mm.h:1369
_In_ PVOID Context
Definition: storport.h:2269

Referenced by MmUnmapViewOfSegment().

◆ MmInitSectionImplementation()

NTSTATUS NTAPI MmInitSectionImplementation ( VOID  )

Definition at line 2330 of file section.c.

2331{
2332 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
2334
2335 DPRINT("Creating Section Object Type\n");
2336
2337 /* Initialize the section based root */
2340
2341 /* Initialize the Section object type */
2342 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
2343 RtlInitUnicodeString(&Name, L"Section");
2344 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
2345 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(SECTION);
2346 ObjectTypeInitializer.PoolType = PagedPool;
2347 ObjectTypeInitializer.UseDefaultObject = TRUE;
2348 ObjectTypeInitializer.GenericMapping = MmpSectionMapping;
2349 ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection;
2350 ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
2351 ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
2352 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
2353 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
2354
2356
2357 return STATUS_SUCCESS;
2358}
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
#define OBJ_OPENLINK
Definition: winternl.h:230
static GENERIC_MAPPING MmpSectionMapping
Definition: section.c:225
VOID NTAPI MmpDeleteSection(PVOID ObjectBody)
Definition: section.c:2174
VOID NTAPI MmpCloseSection(IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
Definition: section.c:2227
NTSTATUS NTAPI MmCreatePhysicalMemorySection(VOID)
Definition: section.c:2239
union _MMADDRESS_NODE::@2854 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 5000 of file section.c.

5004{
5006 LARGE_INTEGER RangeStart, RangeEnd;
5007 BOOLEAN Ret = TRUE;
5008
5009 RangeStart.QuadPart = Offset;
5010 if (!NT_SUCCESS(RtlLongLongAdd(RangeStart.QuadPart, Length, &RangeEnd.QuadPart)))
5011 return FALSE;
5012
5014 if (!Segment)
5015 return FALSE;
5016
5017 /* Find byte offset of the page to start */
5018 RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart);
5019
5021
5022 while (RangeStart.QuadPart < RangeEnd.QuadPart)
5023 {
5025 if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
5026 {
5027 Ret = FALSE;
5028 break;
5029 }
5030
5031 RangeStart.QuadPart += PAGE_SIZE;
5032 }
5033
5035 MmDereferenceSegment(Segment);
5036
5037 return Ret;
5038}

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

5047{
5049
5050 /* There must be a segment for this call */
5051 ASSERT(Segment);
5052
5054
5055 MmDereferenceSegment(Segment);
5056
5057 return Status;
5058}
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:1194

Referenced by CcRosEnsureVacbResident().

◆ MmMakeSegmentDirty()

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

Definition at line 5062 of file section.c.

5066{
5068 LARGE_INTEGER RangeStart, RangeEnd;
5070
5071 RangeStart.QuadPart = Offset;
5072 Status = RtlLongLongAdd(RangeStart.QuadPart, Length, &RangeEnd.QuadPart);
5073 if (!NT_SUCCESS(Status))
5074 return Status;
5075
5077 if (!Segment)
5079
5080 /* Find byte offset of the page to start */
5081 RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart);
5082
5084
5085 while (RangeStart.QuadPart < RangeEnd.QuadPart)
5086 {
5088
5089 /* Let any pending read proceed */
5090 while (MM_IS_WAIT_PTE(Entry))
5091 {
5096 }
5097
5098 /* We are called from Cc, this can't be backed by the page files */
5100
5101 /* If there is no page there, there is nothing to make dirty */
5102 if (Entry != 0)
5103 {
5104 /* Dirtify the entry */
5106 }
5107
5108 RangeStart.QuadPart += PAGE_SIZE;
5109 }
5110
5112 MmDereferenceSegment(Segment);
5113
5114 return STATUS_SUCCESS;
5115}

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

1200{
1201 /* Let's use a 64K granularity. */
1202 LONGLONG RangeStart, RangeEnd;
1204 PFILE_OBJECT FileObject = Segment->FileObject;
1205
1206 /* Calculate our range, aligned on 64K if possible. */
1207 Status = RtlLongLongAdd(Offset, Length, &RangeEnd);
1209 if (!NT_SUCCESS(Status))
1210 return Status;
1211
1212 /* If the file is not random access and we are not the page out thread
1213 * read a 64K Chunk. */
1215 && !FlagOn(FileObject->Flags, FO_RANDOM_ACCESS))
1216 {
1217 RangeStart = Offset - (Offset % _64K);
1218 if (RangeEnd % _64K)
1219 RangeEnd += _64K - (RangeEnd % _64K);
1220 }
1221 else
1222 {
1223 RangeStart = Offset - (Offset % PAGE_SIZE);
1224 if (RangeEnd % PAGE_SIZE)
1225 RangeEnd += PAGE_SIZE - (RangeEnd % PAGE_SIZE);
1226 }
1227
1228 /* Clamp if needed */
1229 if (!FlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT))
1230 {
1231 if (RangeEnd > Segment->RawLength.QuadPart)
1232 RangeEnd = Segment->RawLength.QuadPart;
1233 }
1234
1235 /* Let's gooooooooo */
1236 for ( ; RangeStart < RangeEnd; RangeStart += _64K)
1237 {
1238 /* First take a look at where we miss pages */
1239 ULONG ToReadPageBits = 0;
1240 LONGLONG ChunkEnd = RangeStart + _64K;
1241
1242 if (ChunkEnd > RangeEnd)
1243 ChunkEnd = RangeEnd;
1244
1246 for (LONGLONG ChunkOffset = RangeStart; ChunkOffset < ChunkEnd; ChunkOffset += PAGE_SIZE)
1247 {
1248 LARGE_INTEGER CurrentOffset;
1249
1250 CurrentOffset.QuadPart = ChunkOffset;
1252
1253 /* Let any pending read proceed */
1254 while (MM_IS_WAIT_PTE(Entry))
1255 {
1257
1259
1261 Entry = MmGetPageEntrySectionSegment(Segment, &CurrentOffset);
1262 }
1263
1264 if (Entry != 0)
1265 {
1266 /* Dirtify it if it's a resident page and we're asked to */
1267 if (SetDirty && !IS_SWAP_FROM_SSE(Entry))
1268 {
1270 }
1271 continue;
1272 }
1273
1274 ToReadPageBits |= 1UL << ((ChunkOffset - RangeStart) >> PAGE_SHIFT);
1275
1276 /* Put a wait entry here */
1277 Status = MmSetPageEntrySectionSegment(Segment, &CurrentOffset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
1278 if (!NT_SUCCESS(Status))
1279 {
1280 /* Failed, roll back! */
1281 DPRINT1("Failed to set wait entry for segment %p at offset %I64d\n", Segment, ChunkOffset);
1282 LARGE_INTEGER RollbackOffset;
1283 RollbackOffset.QuadPart = ChunkOffset;
1284 while (RollbackOffset.QuadPart > RangeStart)
1285 {
1286 RollbackOffset.QuadPart -= PAGE_SIZE;
1288 {
1290 }
1291 }
1292
1294 return Status;
1295 }
1297 }
1299
1300 if (ToReadPageBits == 0)
1301 {
1302 /* Nothing to do for this chunk */
1303 continue;
1304 }
1305
1306 /* Now perform the actual read */
1307 LONGLONG ChunkOffset = RangeStart;
1308 while (ChunkOffset < ChunkEnd)
1309 {
1310 /* Move forward if there is a hole */
1311 ULONG BitSet;
1312 if (!_BitScanForward(&BitSet, ToReadPageBits))
1313 {
1314 /* Nothing more to read */
1315 break;
1316 }
1317 ToReadPageBits >>= BitSet;
1318 ChunkOffset += BitSet * PAGE_SIZE;
1319 ASSERT(ChunkOffset < ChunkEnd);
1320
1321 /* Get the range we have to read */
1322 _BitScanForward(&BitSet, ~ToReadPageBits);
1323 ULONG ReadLength = BitSet * PAGE_SIZE;
1324
1326
1327 /* Clamp (This is for image mappings */
1328 if ((ChunkOffset + ReadLength) > ChunkEnd)
1329 ReadLength = ChunkEnd - ChunkOffset;
1330
1331 ASSERT(ReadLength != 0);
1332
1333 /* Allocate a MDL */
1335 if (!Mdl)
1336 {
1337 /* Damn. Roll-back. */
1339 while (ChunkOffset < ChunkEnd)
1340 {
1341 if (ToReadPageBits & 1)
1342 {
1343 LARGE_INTEGER CurrentOffset;
1344 CurrentOffset.QuadPart = ChunkOffset;
1346 MmSetPageEntrySectionSegment(Segment, &CurrentOffset, 0);
1347 }
1348 ToReadPageBits >>= 1;
1349 ChunkOffset += PAGE_SIZE;
1350 }
1353 }
1354
1355 /* Get our pages */
1358 for (UINT i = 0; i < BYTES_TO_PAGES(ReadLength); i++)
1359 {
1361 if (!NT_SUCCESS(Status))
1362 {
1363 /* Damn. Roll-back. */
1364 for (UINT j = 0; j < i; j++)
1366 goto Failed;
1367 }
1368 }
1369
1370 Mdl->MdlFlags |= MDL_PAGES_LOCKED | MDL_IO_PAGE_READ;
1371
1373 FileOffset.QuadPart = Segment->Image.FileOffset + ChunkOffset;
1374
1375 /* Clamp to VDL */
1376 if (ValidDataLength && ((FileOffset.QuadPart + ReadLength) > ValidDataLength->QuadPart))
1377 {
1378 if (FileOffset.QuadPart > ValidDataLength->QuadPart)
1379 {
1380 /* Great, nothing to read. */
1381 goto AssignPagesToSegment;
1382 }
1383
1384 Mdl->Size = (FileOffset.QuadPart + ReadLength) - ValidDataLength->QuadPart;
1385 }
1386
1387 KEVENT Event;
1389
1390 /* Disable APCs */
1391 KIRQL OldIrql;
1393
1396 if (Status == STATUS_PENDING)
1397 {
1399 Status = Iosb.Status;
1400 }
1401
1402 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
1403 {
1404 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
1405 }
1406
1408
1410 {
1411 DPRINT1("Got STATUS_END_OF_FILE at offset %I64d for file %wZ.\n", FileOffset.QuadPart, &FileObject->FileName);
1413 }
1414
1415 if (!NT_SUCCESS(Status))
1416 {
1417 /* Damn. Roll back. */
1418 for (UINT i = 0; i < BYTES_TO_PAGES(ReadLength); i++)
1420
1421Failed:
1423 while (ChunkOffset < ChunkEnd)
1424 {
1425 if (ToReadPageBits & 1)
1426 {
1427 LARGE_INTEGER CurrentOffset;
1428 CurrentOffset.QuadPart = ChunkOffset;
1430 MmSetPageEntrySectionSegment(Segment, &CurrentOffset, 0);
1431 }
1432 ToReadPageBits >>= 1;
1433 ChunkOffset += PAGE_SIZE;
1434 }
1436 IoFreeMdl(Mdl);;
1437 return Status;
1438 }
1439
1440AssignPagesToSegment:
1442
1443 for (UINT i = 0; i < BYTES_TO_PAGES(ReadLength); i++)
1444 {
1445 ULONG_PTR Entry = MAKE_SSE(Pages[i] << PAGE_SHIFT, 0);
1446 LARGE_INTEGER CurrentOffset;
1447 CurrentOffset.QuadPart = ChunkOffset + (i * PAGE_SIZE);
1448
1450
1451 if (SetDirty)
1453
1454 MmSetPageEntrySectionSegment(Segment, &CurrentOffset, Entry);
1455 }
1456
1458
1459 IoFreeMdl(Mdl);
1460 ToReadPageBits >>= BitSet;
1461 ChunkOffset += BitSet * PAGE_SIZE;
1462 }
1463 }
1464
1465 return STATUS_SUCCESS;
1466}
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
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:88
unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask)
Definition: intrin_arm.h:57
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define FO_RANDOM_ACCESS
Definition: iotypes.h:1796
@ WrPageIn
Definition: ketypes.h:476
#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 4504 of file section.c.

4507{
4509
4510 SectionOffset.QuadPart = 0;
4511
4513}
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ 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:4517

Referenced by ExpInitNls(), IntGdiAddFontResourceSingle(), 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 4517 of file section.c.

4524{
4525 PSECTION Section = SectionObject;
4529
4531
4532 PAGED_CODE();
4533
4535 {
4537 &MmSession,
4538 MappedBase,
4539 ViewSize,
4541 }
4542
4543 DPRINT("MmMapViewInSystemSpaceEx() called\n");
4544
4545 /* unsupported for now */
4546 ASSERT(Section->u.Flags.Image == 0);
4547
4548 Section = SectionObject;
4550
4551 if (*ViewSize == 0)
4552 {
4553 LONGLONG MapSizeLL;
4554
4555 /* Page-align the mapping */
4556 SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
4557
4558 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &MapSizeLL)))
4560
4561 if (!NT_SUCCESS(RtlLongLongToSIZET(MapSizeLL, ViewSize)))
4563 }
4564 else
4565 {
4566 LONGLONG HelperLL;
4567
4568 /* Get the map end */
4569 if (!NT_SUCCESS(RtlLongLongAdd(SectionOffset->QuadPart, *ViewSize, &HelperLL)))
4571
4572 /* Round it up, if needed */
4573 if (HelperLL % PAGE_SIZE)
4574 {
4575 if (!NT_SUCCESS(RtlLongLongAdd(HelperLL, PAGE_SIZE - (HelperLL % PAGE_SIZE), &HelperLL)))
4577 }
4578
4579 /* Now that we have the mapping end, we can align down its start */
4580 SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
4581
4582 /* Get the new size */
4583 if (!NT_SUCCESS(RtlLongLongSub(HelperLL, SectionOffset->QuadPart, &HelperLL)))
4585
4586 if (!NT_SUCCESS(RtlLongLongToSIZET(HelperLL, ViewSize)))
4588 }
4589
4591
4593
4595
4597 Section->u.Flags.Image,
4598 Segment,
4599 MappedBase,
4600 *ViewSize,
4602 SectionOffset->QuadPart,
4603 SEC_RESERVE);
4604
4607
4608 return Status;
4609}
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:1041
MMSESSION MmSession
Definition: section.c:107
#define PAGED_CODE()
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:361
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:3403

Referenced by CcRosCreateVacb(), and MmMapViewInSystemSpace().

◆ MmMapViewOfArm3Section()

NTSTATUS NTAPI MmMapViewOfArm3Section ( _In_ PVOID  SectionObject,
_In_ PEPROCESS  Process,
_Outptr_result_bytebuffer_ *ViewSize _When_ *!=0, _Pre_opt_valid_ _When_ *==0, _Pre_valid_ PVOID BaseAddress,
_In_ ULONG_PTR  ZeroBits,
_In_ SIZE_T  CommitSize,
_Inout_ PLARGE_INTEGER  SectionOffset,
_Inout_ PSIZE_T  ViewSize,
_In_range_(ViewShare, ViewUnmap) SECTION_INHERIT  InheritDisposition,
_In_ ULONG  AllocationType,
_In_ ULONG  Protect 
)

Definition at line 2534 of file section.c.

2548{
2551 PSECTION Section;
2552 PCONTROL_AREA ControlArea;
2553 ULONG ProtectionMask;
2555 ULONG64 CalculatedViewSize;
2556 PAGED_CODE();
2557
2558 /* Get the segment and control area */
2559 Section = (PSECTION)SectionObject;
2560 ControlArea = Section->Segment->ControlArea;
2561
2562 /* These flags/states are not yet supported by ARM3 */
2563 ASSERT(Section->u.Flags.Image == 0);
2564 ASSERT(Section->u.Flags.NoCache == 0);
2565 ASSERT(Section->u.Flags.WriteCombined == 0);
2566 ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
2567
2568 /* FIXME */
2569 if ((AllocationType & MEM_RESERVE) != 0)
2570 {
2571 DPRINT1("MmMapViewOfArm3Section called with MEM_RESERVE, this is not implemented yet!!!\n");
2573 }
2574
2575 /* Check if the mapping protection is compatible with the create */
2577 {
2578 DPRINT1("Mapping protection is incompatible\n");
2580 }
2581
2582 /* Check if the offset and size would cause an overflow */
2583 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) <
2584 (ULONG64)SectionOffset->QuadPart)
2585 {
2586 DPRINT1("Section offset overflows\n");
2588 }
2589
2590 /* Check if the offset and size are bigger than the section itself */
2591 if (((ULONG64)SectionOffset->QuadPart + *ViewSize) >
2592 (ULONG64)Section->SizeOfSection.QuadPart)
2593 {
2594 DPRINT1("Section offset is larger than section\n");
2596 }
2597
2598 /* Check if the caller did not specify a view size */
2599 if (!(*ViewSize))
2600 {
2601 /* Compute it for the caller */
2602 CalculatedViewSize = Section->SizeOfSection.QuadPart -
2603 SectionOffset->QuadPart;
2604
2605 /* Check if it's larger than 4GB or overflows into kernel-mode */
2606 if (!NT_SUCCESS(RtlULongLongToSIZET(CalculatedViewSize, ViewSize)) ||
2607 (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < CalculatedViewSize))
2608 {
2609 DPRINT1("Section view won't fit\n");
2611 }
2612 }
2613
2614 /* Check if the commit size is larger than the view size */
2615 if (CommitSize > *ViewSize)
2616 {
2617 DPRINT1("Attempting to commit more than the view itself\n");
2619 }
2620
2621 /* Check if the view size is larger than the section */
2622 if (*ViewSize > (ULONG64)Section->SizeOfSection.QuadPart)
2623 {
2624 DPRINT1("The view is larger than the section\n");
2626 }
2627
2628 /* Compute and validate the protection mask */
2629 ProtectionMask = MiMakeProtectionMask(Protect);
2630 if (ProtectionMask == MM_INVALID_PROTECTION)
2631 {
2632 DPRINT1("The protection is invalid\n");
2634 }
2635
2636 /* We only handle pagefile-backed sections, which cannot be writecombined */
2638 {
2639 DPRINT1("Cannot write combine a pagefile-backed section\n");
2641 }
2642
2643 /* Start by attaching to the current process if needed */
2645 {
2647 Attached = TRUE;
2648 }
2649
2650 /* Do the actual mapping */
2651 Status = MiMapViewOfDataSection(ControlArea,
2652 Process,
2655 ViewSize,
2656 Section,
2657 InheritDisposition,
2658 ProtectionMask,
2659 CommitSize,
2660 ZeroBits,
2662
2663 /* Detach if needed, then return status */
2665 return Status;
2666}
static NTSTATUS MiMapViewOfDataSection(_In_ PCONTROL_AREA ControlArea, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _Inout_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_ PSECTION Section, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG ProtectionMask, _In_ SIZE_T CommitSize, _In_ ULONG_PTR ZeroBits, _In_ ULONG AllocationType)
Definition: section.c:1153
static BOOLEAN MiIsProtectionCompatible(IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
Definition: section.c:117
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:405
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ ULONG AllocationType
Definition: mmfuncs.h:410
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
struct _SECTION * PSECTION
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
#define STATUS_SECTION_PROTECTION
Definition: ntstatus.h:408
#define STATUS_INVALID_PARAMETER_10
Definition: ntstatus.h:578
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:573
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:1711

Referenced by MmMapViewOfSection().

◆ MmMapViewOfSection()

NTSTATUS NTAPI MmMapViewOfSection ( _In_ PVOID  SectionObject,
_In_ PEPROCESS  Process,
_Outptr_result_bytebuffer_ *ViewSize _Pre_opt_valid_ PVOID BaseAddress,
_In_ ULONG_PTR  ZeroBits,
_In_ SIZE_T  CommitSize,
_Inout_opt_ PLARGE_INTEGER  SectionOffset,
_Inout_ PSIZE_T  ViewSize,
_In_range_(ViewShare, ViewUnmap) SECTION_INHERIT  InheritDisposition,
_In_ ULONG  AllocationType,
_In_ ULONG  Protect 
)

Definition at line 4031 of file section.c.

4042{
4043 PSECTION Section;
4046 BOOLEAN NotAtBase = FALSE;
4047 BOOLEAN IsAttached = FALSE;
4049
4051 {
4052 DPRINT("Mapping ARM3 section into %s\n", Process->ImageFileName);
4055 Process,
4057 ZeroBits,
4058 CommitSize,
4060 ViewSize,
4061 InheritDisposition,
4063 Protect);
4064 }
4065
4066 ASSERT(Process);
4067
4069 {
4071 }
4072
4074 {
4076 IsAttached = TRUE;
4077 }
4078
4079 Section = SectionObject;
4080 AddressSpace = &Process->Vm;
4081
4082 if (Section->u.Flags.NoChange)
4084
4086
4087 if (Section->u.Flags.Image)
4088 {
4089 ULONG i;
4090 ULONG NrSegments;
4091 ULONG_PTR ImageBase;
4092 SIZE_T ImageSize;
4093 PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
4094 PMM_SECTION_SEGMENT SectionSegments;
4095
4096 ImageSectionObject = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment);
4097 SectionSegments = ImageSectionObject->Segments;
4098 NrSegments = ImageSectionObject->NrSegments;
4099
4100 ASSERT(ImageSectionObject->RefCount > 0);
4101
4102 ImageBase = (ULONG_PTR)*BaseAddress;
4103 if (ImageBase == 0)
4104 {
4105 ImageBase = (ULONG_PTR)ImageSectionObject->BasedAddress;
4106 }
4107
4108 ImageSize = 0;
4109 for (i = 0; i < NrSegments; i++)
4110 {
4111 ULONG_PTR MaxExtent;
4112 MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
4113 SectionSegments[i].Length.QuadPart);
4114 ImageSize = max(ImageSize, MaxExtent);
4115 }
4116
4117 ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize;
4118
4119 /* Check for an illegal base address */
4120 if (((ImageBase + ImageSize) > (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS) ||
4121 ((ImageBase + ImageSize) < ImageSize))
4122 {
4123 ASSERT(*BaseAddress == NULL);
4124 ImageBase = ALIGN_DOWN_BY((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - ImageSize,
4126 NotAtBase = TRUE;
4127 }
4128 else if (ImageBase != ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY))
4129 {
4130 ASSERT(*BaseAddress == NULL);
4131 ImageBase = ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY);
4132 NotAtBase = TRUE;
4133 }
4134
4135 /* Check there is enough space to map the section at that point. */
4136 if (!MmIsAddressRangeFree(AddressSpace, (PVOID)ImageBase, PAGE_ROUND_UP(ImageSize)))
4137 {
4138 /* Fail if the user requested a fixed base address. */
4139 if ((*BaseAddress) != NULL)
4140 {
4142 goto Exit;
4143 }
4144 /* Otherwise find a gap to map the image. */
4146 if (ImageBase == 0)
4147 {
4149 goto Exit;
4150 }
4151 /* Remember that we loaded image at a different base address */
4152 NotAtBase = TRUE;
4153 }
4154
4155 for (i = 0; i < NrSegments; i++)
4156 {
4157 PVOID SBaseAddress = (PVOID)
4158 ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
4159 MmLockSectionSegment(&SectionSegments[i]);
4161 TRUE,
4162 &SectionSegments[i],
4163 &SBaseAddress,
4164 SectionSegments[i].Length.QuadPart,
4165 SectionSegments[i].Protection,
4166 0,
4167 0);
4168 MmUnlockSectionSegment(&SectionSegments[i]);
4169 if (!NT_SUCCESS(Status))
4170 {
4171 /* roll-back */
4172 while (i--)
4173 {
4174 SBaseAddress = ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
4175 MmLockSectionSegment(&SectionSegments[i]);
4176 MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
4177 MmUnlockSectionSegment(&SectionSegments[i]);
4178 }
4179
4180 goto Exit;
4181 }
4182 }
4183
4184 *BaseAddress = (PVOID)ImageBase;
4185 *ViewSize = ImageSize;
4186
4187 DPRINT("Mapped %p for section pointer %p\n", ImageSectionObject, ImageSectionObject->FileObject->SectionObjectPointer);
4188
4189 /* One more map */
4190 InterlockedIncrement(&ImageSectionObject->MapCount);
4191 }
4192 else
4193 {
4195 LONGLONG ViewOffset;
4196
4197 ASSERT(Segment->RefCount > 0);
4198
4199 /* check for write access */
4202 {
4204 goto Exit;
4205 }
4206 /* check for read access */
4209 {
4211 goto Exit;
4212 }
4213 /* check for execute access */
4216 {
4218 goto Exit;
4219 }
4220
4221 if (SectionOffset == NULL)
4222 {
4223 ViewOffset = 0;
4224 }
4225 else
4226 {
4227 SectionOffset->QuadPart &= ~(PAGE_SIZE - 1);
4228 ViewOffset = SectionOffset->QuadPart;
4229 }
4230
4231 /* Check if the offset and size would cause an overflow */
4232 if (((ULONG64)ViewOffset + *ViewSize) < (ULONG64)ViewOffset)
4233 {
4234 DPRINT1("Section offset overflows\n");
4236 goto Exit;
4237 }
4238
4239 /* Check if the offset and size are bigger than the section itself */
4240 if (((ULONG64)ViewOffset + *ViewSize) > (ULONG64)Section->SizeOfSection.QuadPart)
4241 {
4242 /* This is allowed for physical memory sections and kernel mode callers */
4243 if (!Section->u.Flags.PhysicalMemory || (ExGetPreviousMode() == UserMode))
4244 {
4245 DPRINT1("Section offset and size are larger than section\n");
4247 goto Exit;
4248 }
4249 }
4250
4251 if ((*ViewSize) == 0)
4252 {
4253 /* Calculate a view size and make sure it doesn't overflow a SIZE_T */
4254 ULONG64 CalculatedSize = Section->SizeOfSection.QuadPart - ViewOffset;
4255 if (CalculatedSize > SIZE_T_MAX)
4256 {
4257 DPRINT1("ViewSize is larger than SIZE_T_MAX\n");
4259 goto Exit;
4260 }
4261
4262 *ViewSize = (SIZE_T)CalculatedSize;
4263 }
4264 else if ((ExGetPreviousMode() == UserMode) &&
4265 (((*ViewSize)+ViewOffset) > Section->SizeOfSection.QuadPart) &&
4266 (!Section->u.Flags.Reserve))
4267 {
4268 /* Dubious */
4269 (*ViewSize) = MIN(Section->SizeOfSection.QuadPart - ViewOffset, SIZE_T_MAX - PAGE_SIZE);
4270 }
4271
4273
4276 FALSE,
4277 Segment,
4279 *ViewSize,
4280 Protect,
4281 ViewOffset,
4284 if (!NT_SUCCESS(Status))
4285 {
4286 goto Exit;
4287 }
4288 }
4289
4290 if (NotAtBase)
4292 else
4294
4295Exit:
4296
4298
4299 if (IsAttached)
4300 {
4302 }
4303
4304 return Status;
4305}
#define ALIGN_DOWN_BY(size, align)
#define MIN(x, y)
Definition: rdesktop.h:171
#define SIZE_T_MAX
Definition: dhcpd.h:91
#define UserMode
Definition: asm.h:39
#define MEM_TOP_DOWN
Definition: nt_native.h:1324
#define PAGE_EXECUTE
Definition: nt_native.h:1309
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT
#define PAGE_FLAGS_VALID_FOR_SECTION
Definition: mm.h:139
BOOLEAN NTAPI MmIsAddressRangeFree(_In_ PMMSUPPORT AddressSpace, _In_ PVOID Address, _In_ ULONG_PTR Length)
Definition: marea.c:111
PVOID NTAPI MmFindGap(PMMSUPPORT AddressSpace, SIZE_T Length, ULONG_PTR Granularity, BOOLEAN TopDown)
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:354
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:192
NTSTATUS NTAPI MmMapViewOfArm3Section(_In_ PVOID SectionObject, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _When_(*ViewSize !=0, _Pre_opt_valid_) _When_(*ViewSize==0, _Pre_valid_) PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Protect)
Definition: section.c:2534
#define max(a, b)
Definition: svc.c:63

Referenced by _Function_class_(), _Success_(), ExpInitNls(), GDI_MapHandleTable(), IntMapDesktopView(), IntUserHeapCreate(), MapGlobalUserHeap(), MiLoadImageSection(), MmCreatePeb(), MmInitializeProcessAddressSpace(), NtMapViewOfSection(), NtSecureConnectPort(), and PspMapSystemDll().

◆ MmMapViewOfSegment()

static NTSTATUS MmMapViewOfSegment ( PMMSUPPORT  AddressSpace,
BOOLEAN  AsImage,
PMM_SECTION_SEGMENT  Segment,
PVOID BaseAddress,
SIZE_T  ViewSize,
ULONG  Protect,
LONGLONG  ViewOffset,
ULONG  AllocationType 
)
static

Definition at line 3403 of file section.c.

3412{
3413 PMEMORY_AREA MArea;
3415 ULONG Granularity;
3416
3417 ASSERT(ViewSize != 0);
3418
3419 if (Segment->WriteCopy)
3420 {
3421 /* We have to do this because the not present fault
3422 * and access fault handlers depend on the protection
3423 * that should be granted AFTER the COW fault takes
3424 * place to be in Region->Protect. The not present fault
3425 * handler changes this to the correct protection for COW when
3426 * mapping the pages into the process's address space. If a COW
3427 * fault takes place, the access fault handler sets the page protection
3428 * to these values for the newly copied pages
3429 */
3430 if (Protect == PAGE_WRITECOPY)
3432 else if (Protect == PAGE_EXECUTE_WRITECOPY)
3434 }
3435
3436 if (*BaseAddress == NULL)
3437 Granularity = MM_ALLOCATION_GRANULARITY;
3438 else
3439 Granularity = PAGE_SIZE;
3440
3441#ifdef NEWCC
3442 if (Segment->Flags & MM_DATAFILE_SEGMENT)
3443 {
3445 FileOffset.QuadPart = ViewOffset;
3446 ObReferenceObject(Section);
3448 }
3449#endif
3453 ViewSize,
3454 Protect,
3455 &MArea,
3457 Granularity);
3458 if (!NT_SUCCESS(Status))
3459 {
3460 DPRINT1("Mapping between 0x%p and 0x%p failed (%X).\n",
3461 (*BaseAddress), (char*)(*BaseAddress) + ViewSize, Status);
3462 return Status;
3463 }
3464
3465 InterlockedIncrement64(Segment->ReferenceCount);
3466
3467 MArea->SectionData.Segment = Segment;
3468 MArea->SectionData.ViewOffset = ViewOffset;
3469 if (AsImage)
3470 {
3472 }
3473
3474 MmInitializeRegion(&MArea->SectionData.RegionListHead,
3475 ViewSize, 0, Protect);
3476
3477 return STATUS_SUCCESS;
3478}
#define MM_ALLOCATION_GRANULARITY
Definition: mmtypes.h:36
NTSTATUS NTAPI _MiMapViewOfSegment(PMMSUPPORT AddressSpace, PMM_SECTION_SEGMENT Segment, PVOID *BaseAddress, SIZE_T ViewSize, ULONG Protect, PLARGE_INTEGER ViewOffset, ULONG AllocationType, const char *file, int line)
NTSTATUS NTAPI MmCreateMemoryArea(PMMSUPPORT AddressSpace, ULONG Type, PVOID *BaseAddress, SIZE_T Length, ULONG Protection, PMEMORY_AREA *Result, ULONG AllocationFlags, ULONG AllocationGranularity)
VOID NTAPI MmInitializeRegion(PLIST_ENTRY RegionListHead, SIZE_T Length, ULONG Type, ULONG Protect)
Definition: region.c:239

Referenced by MmMapViewInSystemSpaceEx(), and MmMapViewOfSection().

◆ MmNotPresentFaultSectionView()

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

Definition at line 1560 of file section.c.

1564{
1570 ULONG_PTR Entry1;
1573 BOOLEAN HasSwapEntry;
1574 PVOID PAddress;
1576 SWAPENTRY SwapEntry;
1577
1578 ASSERT(Locked);
1579
1580 /*
1581 * There is a window between taking the page fault and locking the
1582 * address space when another thread could load the page so we check
1583 * that.
1584 */
1586 {
1587 return STATUS_SUCCESS;
1588 }
1589
1591 {
1593 }
1594
1595 /*
1596 * Check for the virtual memory area being deleted.
1597 */
1599 {
1600 return STATUS_UNSUCCESSFUL;
1601 }
1602
1603 PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1604 Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1605 + MemoryArea->SectionData.ViewOffset;
1606
1607 Segment = MemoryArea->SectionData.Segment;
1609 &MemoryArea->SectionData.RegionListHead,
1610 Address, NULL);
1611 ASSERT(Region != NULL);
1612
1613 /* Check for a NOACCESS mapping */
1614 if (Region->Protect & PAGE_NOACCESS)
1615 {
1617 }
1618
1619 if (Region->Protect & PAGE_GUARD)
1620 {
1621 /* Remove it */
1623 &MemoryArea->SectionData.RegionListHead,
1624 Address, PAGE_SIZE, Region->Type, Region->Protect & ~PAGE_GUARD,
1626
1627 if (!NT_SUCCESS(Status))
1628 {
1629 DPRINT1("Removing PAGE_GUARD protection failed : 0x%08x.\n", Status);
1630 }
1631
1633 }
1634
1635 HasSwapEntry = MmIsPageSwapEntry(Process, Address);
1636
1637 /* See if we should use a private page */
1638 if (HasSwapEntry)
1639 {
1640 SWAPENTRY DummyEntry;
1641
1642 MmGetPageFileMapping(Process, Address, &SwapEntry);
1643 if (SwapEntry == MM_WAIT_ENTRY)
1644 {
1649 }
1650
1652 if (Process) MI_SET_PROCESS2(Process->ImageFileName);
1653 if (!Process) MI_SET_PROCESS2("Kernel Section");
1655 if (!NT_SUCCESS(Status))
1656 {
1657 return STATUS_NO_MEMORY;
1658 }
1659
1660 /*
1661 * Must be private page we have swapped out.
1662 */
1663
1664 /*
1665 * Sanity check
1666 */
1668 ASSERT(DummyEntry == SwapEntry);
1669
1670 /* Tell everyone else we are serving the fault. */
1671 MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
1672
1674
1675 Status = MmReadFromSwapPage(SwapEntry, Page);
1676 if (!NT_SUCCESS(Status))
1677 {
1678 DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
1679 KeBugCheck(MEMORY_MANAGEMENT);
1680 }
1681
1683 MmDeletePageFileMapping(Process, PAddress, &DummyEntry);
1684 ASSERT(DummyEntry == MM_WAIT_ENTRY);
1685
1687 PAddress,
1688 Region->Protect,
1689 Page);
1690 if (!NT_SUCCESS(Status))
1691 {
1692 DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
1693 KeBugCheck(MEMORY_MANAGEMENT);
1694 return Status;
1695 }
1696
1697 /*
1698 * Store the swap entry for later use.
1699 */
1700 MmSetSavedSwapEntryPage(Page, SwapEntry);
1701
1702 /*
1703 * Add the page to the process's working set
1704 */
1706 /*
1707 * Finish the operation
1708 */
1709 DPRINT("Address 0x%p\n", Address);
1710 return STATUS_SUCCESS;
1711 }
1712
1713 /*
1714 * Lock the segment
1715 */
1717
1718 /*
1719 * Satisfying a page fault on a map of /Device/PhysicalMemory is easy
1720 */
1721 if ((*Segment->Flags) & MM_PHYSICALMEMORY_SEGMENT)
1722 {
1724 /*
1725 * Just map the desired physical page
1726 */
1727 Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT);
1729 PAddress,
1730 Region->Protect,
1731 Page);
1732 if (!NT_SUCCESS(Status))
1733 {
1734 DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");
1735 KeBugCheck(MEMORY_MANAGEMENT);
1736 return Status;
1737 }
1738
1739 /*
1740 * Cleanup and release locks
1741 */
1742 DPRINT("Address 0x%p\n", Address);
1743 return STATUS_SUCCESS;
1744 }
1745
1746 /*
1747 * Check if this page needs to be mapped COW
1748 */
1749 if ((Segment->WriteCopy) &&
1750 (Region->Protect == PAGE_READWRITE || Region->Protect == PAGE_EXECUTE_READWRITE))
1751 {
1753 }
1754 else
1755 {
1756 Attributes = Region->Protect;
1757 }
1758
1759
1760 /*
1761 * Get the entry corresponding to the offset within the section
1762 */
1764 if (Entry == 0)
1765 {
1766 /*
1767 * If the entry is zero, then we need to load the page.
1768 */
1769 if ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart)) && (MemoryArea->VadNode.u.VadFlags.VadType == VadImageMap))
1770 {
1771 /* We are beyond the data which is on file. Just get a new page. */
1773 if (Process) MI_SET_PROCESS2(Process->ImageFileName);
1774 if (!Process) MI_SET_PROCESS2("Kernel Section");
1776 if (!NT_SUCCESS(Status))
1777 {
1779 return STATUS_NO_MEMORY;
1780 }
1783
1785 if (!NT_SUCCESS(Status))
1786 {
1787 DPRINT1("Unable to create virtual mapping\n");
1788 KeBugCheck(MEMORY_MANAGEMENT);
1789 }
1790 ASSERT(MmIsPagePresent(Process, PAddress));
1791 if (Process)
1793
1794 DPRINT("Address 0x%p\n", Address);
1795 return STATUS_SUCCESS;
1796 }
1797
1800
1801 /* The data must be paged in. Lock the file, so that the VDL doesn't get updated behind us. */
1803
1804 PFSRTL_COMMON_FCB_HEADER FcbHeader = Segment->FileObject->FsContext;
1805
1807
1808 FsRtlReleaseFile(Segment->FileObject);
1809
1810 /* Lock address space again */
1812 if (!NT_SUCCESS(Status))
1813 {
1814 if (Status == STATUS_NO_MEMORY)
1815 {
1816 return Status;
1817 }
1818 /* Damn */
1819 DPRINT1("Failed to page data in!\n");
1820 return STATUS_IN_PAGE_ERROR;
1821 }
1822
1823 /* Everything went fine. Restart the operation */
1825 }
1826 else if (IS_SWAP_FROM_SSE(Entry))
1827 {
1828 SWAPENTRY SwapEntry;
1829
1830 SwapEntry = SWAPENTRY_FROM_SSE(Entry);
1831
1832 /* See if a page op is running on this segment. */
1833 if (SwapEntry == MM_WAIT_ENTRY)
1834 {
1840 }
1841
1843 if (!NT_SUCCESS(Status))
1844 {
1846 return STATUS_NO_MEMORY;
1847 }
1848
1849 /*
1850 * Release all our locks and read in the page from disk
1851 */
1854
1856
1857 Status = MmReadFromSwapPage(SwapEntry, Page);
1858 if (!NT_SUCCESS(Status))
1859 {
1860 KeBugCheck(MEMORY_MANAGEMENT);
1861 }
1862
1863 /*
1864 * Relock the address space and segment
1865 */
1868
1869 /*
1870 * Check the entry. No one should change the status of a page
1871 * that has a pending page-in.
1872 */
1874 if (Entry1 != MAKE_SWAP_SSE(MM_WAIT_ENTRY))
1875 {
1876 DPRINT1("Someone changed ppte entry while we slept (%x vs %x)\n", Entry, Entry1);
1877 KeBugCheck(MEMORY_MANAGEMENT);
1878 }
1879
1880 /*
1881 * Save the swap entry.
1882 */
1883 MmSetSavedSwapEntryPage(Page, SwapEntry);
1884
1885 /* Map the page into the process address space */
1887 PAddress,
1888 Attributes,
1889 Page);
1890 if (!NT_SUCCESS(Status))
1891 {
1892 DPRINT1("Unable to create virtual mapping\n");
1893 KeBugCheck(MEMORY_MANAGEMENT);
1894 }
1895 if (Process)
1897
1898 /*
1899 * Mark the offset within the section as having valid, in-memory
1900 * data
1901 */
1902 Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
1905
1906 DPRINT("Address 0x%p\n", Address);
1907 return STATUS_SUCCESS;
1908 }
1909 else
1910 {
1911 /* We already have a page on this section offset. Map it into the process address space. */
1913
1915 PAddress,
1916 Attributes,
1917 Page);
1918 if (!NT_SUCCESS(Status))
1919 {
1920 DPRINT1("Unable to create virtual mapping\n");
1921 KeBugCheck(MEMORY_MANAGEMENT);
1922 }
1923
1924 if (Process)
1926
1927 /* Take a reference on it */
1930
1931 DPRINT("Address 0x%p\n", Address);
1932 return STATUS_SUCCESS;
1933 }
1934}
#define MI_SET_PROCESS2(x)
Definition: mm.h:329
@ MI_USAGE_SECTION
Definition: mm.h:343
BOOLEAN NTAPI MmIsPageSwapEntry(struct _EPROCESS *Process, PVOID Address)
#define SWAPENTRY_FROM_SSE(E)
Definition: mm.h:1372
NTSTATUS NTAPI MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:204
VOID NTAPI MmDeletePageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
#define MI_SET_USAGE(x)
Definition: mm.h:327
NTSTATUS NTAPI MmCreatePhysicalMapping(_Inout_opt_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG flProtect, _In_ PFN_NUMBER Page)
Definition: page.c:735
NTSTATUS NTAPI MmCreatePageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY SwapEntry)
#define STATUS_MM_RESTART_OPERATION
Definition: mm.h:104
#define STATUS_GUARD_PAGE_VIOLATION
Definition: ntstatus.h:262
VOID NTAPI MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: section.c:1066
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

Referenced by MmAccessFaultSectionView(), and MmNotPresentFault().

◆ MmpCloseSection()

VOID NTAPI MmpCloseSection ( IN PEPROCESS Process  OPTIONAL,
IN PVOID  Object,
IN ACCESS_MASK  GrantedAccess,
IN ULONG  ProcessHandleCount,
IN ULONG  SystemHandleCount 
)

Definition at line 2227 of file section.c.

2232{
2233 DPRINT("MmpCloseSection(OB %p, HC %lu)\n", Object, ProcessHandleCount);
2234}
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
@ ProcessHandleCount
Definition: winternl.h:1902

Referenced by MmInitSectionImplementation().

◆ MmpDeleteSection()

VOID NTAPI MmpDeleteSection ( PVOID  ObjectBody)

Definition at line 2174 of file section.c.

2175{
2176 PSECTION Section = ObjectBody;
2177
2178 /* Check if it's an ARM3, or ReactOS section */
2179 if (!MiIsRosSectionObject(Section))
2180 {
2181 MiDeleteARM3Section(ObjectBody);
2182 return;
2183 }
2184
2185 DPRINT("MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
2186 if (Section->u.Flags.Image)
2187 {
2188 PMM_IMAGE_SECTION_OBJECT ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)Section->Segment;
2189
2190 /*
2191 * NOTE: Section->ImageSection can be NULL for short time
2192 * during the section creating. If we fail for some reason
2193 * until the image section is properly initialized we shouldn't
2194 * process further here.
2195 */
2196 if (Section->Segment == NULL)
2197 return;
2198
2199 KIRQL OldIrql = MiAcquirePfnLock();
2200 ImageSectionObject->SectionCount--;
2201
2202 /* We just dereference the first segment */
2203 ASSERT(ImageSectionObject->RefCount > 0);
2204 /* MmDereferenceSegmentWithLock releases PFN lock */
2205 MmDereferenceSegmentWithLock(ImageSectionObject->Segments, OldIrql);
2206 }
2207 else
2208 {
2210
2211 /*
2212 * NOTE: Section->Segment can be NULL for short time
2213 * during the section creating.
2214 */
2215 if (Segment == NULL)
2216 return;
2217
2218 KIRQL OldIrql = MiAcquirePfnLock();
2219 Segment->SectionCount--;
2220
2221 /* MmDereferenceSegmentWithLock releases PFN lock */
2222 MmDereferenceSegmentWithLock(Segment, OldIrql);
2223 }
2224}
VOID NTAPI MiDeleteARM3Section(PVOID ObjectBody)
Definition: section.c:2958

Referenced by MmInitSectionImplementation().

◆ MmpFreePageFileSegment()

VOID NTAPI MmpFreePageFileSegment ( PMM_SECTION_SEGMENT  Segment)

Definition at line 919 of file section.c.

920{
924 SWAPENTRY SavedSwapEntry;
926
927 Page = 0;
928
930
931 Length = PAGE_ROUND_UP(Segment->Length.QuadPart);
932 for (Offset.QuadPart = 0; Offset.QuadPart < Length; Offset.QuadPart += PAGE_SIZE)
933 {
935 if (Entry)
936 {
939 {
941 }
942 else
943 {
945 SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
946 if (SavedSwapEntry != 0)
947 {
949 MmFreeSwapPage(SavedSwapEntry);
950 }
952 }
953 }
954 }
955
957}

Referenced by _When_().

◆ MmProtectSectionView()

NTSTATUS NTAPI MmProtectSectionView ( PMMSUPPORT  AddressSpace,
PMEMORY_AREA  MemoryArea,
PVOID  BaseAddress,
SIZE_T  Length,
ULONG  Protect,
PULONG  OldProtect 
)

Definition at line 2091 of file section.c.

2097{
2100 ULONG_PTR MaxLength;
2101
2103
2105 {
2106 return STATUS_UNSUCCESSFUL;
2107 }
2108
2110 if (Length > MaxLength)
2111 Length = (ULONG)MaxLength;
2112
2114 &MemoryArea->SectionData.RegionListHead,
2115 BaseAddress, NULL);
2116 ASSERT(Region != NULL);
2117
2118 if ((MemoryArea->Flags & SEC_NO_CHANGE) &&
2119 Region->Protect != Protect)
2120 {
2122 }
2123
2124 if (OldProtect != NULL)
2125 *OldProtect = Region->Protect;
2127 &MemoryArea->SectionData.RegionListHead,
2130
2131 return Status;
2132}
#define MA_GetEndingAddress(_MemoryArea)
Definition: mm.h:251
ULONG Flags
Definition: mm.h:258

Referenced by MiProtectVirtualMemory().

◆ MmPurgeSegment()

BOOLEAN NTAPI MmPurgeSegment ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_opt_ PLARGE_INTEGER  Offset,
_In_ ULONG  Length 
)

Definition at line 4905 of file section.c.

4909{
4910 LARGE_INTEGER PurgeStart, PurgeEnd;
4912
4913 PurgeStart.QuadPart = Offset ? Offset->QuadPart : 0LL;
4914 if (Length && Offset)
4915 {
4916 if (!NT_SUCCESS(RtlLongLongAdd(PurgeStart.QuadPart, Length, &PurgeEnd.QuadPart)))
4917 return FALSE;
4918 }
4919
4921 if (!Segment)
4922 {
4923 /* Nothing to purge */
4924 return TRUE;
4925 }
4926
4928
4929 if (!Length || !Offset)
4930 {
4931 /* We must calculate the length for ourselves */
4932 /* FIXME: All of this is suboptimal */
4933 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
4934 if (!ElemCount)
4935 {
4936 /* No page. Nothing to purge */
4938 MmDereferenceSegment(Segment);
4939 return TRUE;
4940 }
4941
4943 PurgeEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
4944 }
4945
4946 /* Find byte offset of the page to start */
4947 PurgeStart.QuadPart = PAGE_ROUND_DOWN_64(PurgeStart.QuadPart);
4948
4949 while (PurgeStart.QuadPart < PurgeEnd.QuadPart)
4950 {
4952
4953 if (Entry == 0)
4954 {
4955 PurgeStart.QuadPart += PAGE_SIZE;
4956 continue;
4957 }
4958
4960 {
4961 ASSERT(SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY);
4962 /* The page is currently being read. Meaning someone will need it soon. Bad luck */
4964 MmDereferenceSegment(Segment);
4965 return FALSE;
4966 }
4967
4968 if (IS_WRITE_SSE(Entry))
4969 {
4970 /* We're trying to purge an entry which is being written. Restart this loop iteration */
4974 continue;
4975 }
4976
4977 if (SHARE_COUNT_FROM_SSE(Entry) > 0)
4978 {
4979 /* This page is currently in use. Bad luck */
4981 MmDereferenceSegment(Segment);
4982 return FALSE;
4983 }
4984
4985 /* We can let this page go */
4986 MmSetPageEntrySectionSegment(Segment, &PurgeStart, 0);
4988
4989 PurgeStart.QuadPart += PAGE_SIZE;
4990 }
4991
4992 /* This page is currently in use. Bad luck */
4994 MmDereferenceSegment(Segment);
4995 return TRUE;
4996}
#define LL
Definition: tui.h:166

Referenced by CcPurgeCacheSection().

◆ MmQuerySectionView()

NTSTATUS NTAPI MmQuerySectionView ( PMEMORY_AREA  MemoryArea,
PVOID  Address,
PMEMORY_BASIC_INFORMATION  Info,
PSIZE_T  ResultLength 
)

Definition at line 2135 of file section.c.

2139{
2141 PVOID RegionBaseAddress;
2143
2145 &MemoryArea->SectionData.RegionListHead,
2146 Address, &RegionBaseAddress);
2147 if (Region == NULL)
2148 {
2149 return STATUS_UNSUCCESSFUL;
2150 }
2151
2153 {
2154 Segment = MemoryArea->SectionData.Segment;
2155 Info->AllocationBase = (PUCHAR)MA_GetStartingAddress(MemoryArea) - Segment->Image.VirtualAddress;
2156 Info->Type = MEM_IMAGE;
2157 }
2158 else
2159 {
2160 Info->AllocationBase = (PVOID)MA_GetStartingAddress(MemoryArea);
2161 Info->Type = MEM_MAPPED;
2162 }
2163 Info->BaseAddress = RegionBaseAddress;
2165 Info->RegionSize = Region->Length;
2166 Info->State = MEM_COMMIT;
2167 Info->Protect = Region->Protect;
2168
2170 return STATUS_SUCCESS;
2171}
#define MEM_IMAGE
Definition: mmtypes.h:89
struct _MEMORY_BASIC_INFORMATION MEMORY_BASIC_INFORMATION
#define MEM_MAPPED
Definition: nt_native.h:1322
#define MEM_COMMIT
Definition: nt_native.h:1316
const ULONG MmProtectToValue[32]
Definition: page.c:71
ULONG_PTR Protection
Definition: mmtypes.h:696
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782

Referenced by MiQueryMemoryBasicInformation().

◆ MmSharePageEntrySectionSegment()

VOID NTAPI MmSharePageEntrySectionSegment ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset 
)

Definition at line 1066 of file section.c.

1068{
1070
1072 if (Entry == 0)
1073 {
1074 DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n");
1075 KeBugCheck(MEMORY_MANAGEMENT);
1076 }
1078 {
1079 DPRINT1("Maximum share count reached\n");
1080 KeBugCheck(MEMORY_MANAGEMENT);
1081 }
1083 {
1084 KeBugCheck(MEMORY_MANAGEMENT);
1085 }
1087}
#define MAX_SHARE_COUNT
Definition: mm.h:1385
#define BUMPREF_SSE(E)
Definition: mm.h:1387

Referenced by MmNotPresentFaultSectionView().

◆ MmspAssertSegmentsNoOverlap()

static VOID NTAPI MmspAssertSegmentsNoOverlap ( IN PMM_IMAGE_SECTION_OBJECT  ImageSectionObject)
static

Definition at line 2741 of file section.c.

2742{
2743 ULONG i;
2744
2745 MmspAssertSegmentsSorted(ImageSectionObject);
2746
2747 for( i = 0; i < ImageSectionObject->NrSegments; ++ i )
2748 {
2749 ASSERT(ImageSectionObject->Segments[i].Length.QuadPart > 0);
2750
2751 if(i > 0)
2752 {
2753 ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >=
2754 (ImageSectionObject->Segments[i - 1].Image.VirtualAddress +
2755 ImageSectionObject->Segments[i - 1].Length.QuadPart));
2756 }
2757 }
2758}
static VOID NTAPI MmspAssertSegmentsSorted(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
Definition: section.c:2727

Referenced by MmspCheckSegmentBounds().

◆ MmspAssertSegmentsPageAligned()

static VOID NTAPI MmspAssertSegmentsPageAligned ( IN PMM_IMAGE_SECTION_OBJECT  ImageSectionObject)
static

Definition at line 2763 of file section.c.

2764{
2765 ULONG i;
2766
2767 for( i = 0; i < ImageSectionObject->NrSegments; ++ i )
2768 {
2769 ASSERT((ImageSectionObject->Segments[i].Image.VirtualAddress % PAGE_SIZE) == 0);
2770 ASSERT((ImageSectionObject->Segments[i].Length.QuadPart % PAGE_SIZE) == 0);
2771 }
2772}

Referenced by MmspPageAlignSegments().

◆ MmspAssertSegmentsSorted()

static VOID NTAPI MmspAssertSegmentsSorted ( IN PMM_IMAGE_SECTION_OBJECT  ImageSectionObject)
static

Definition at line 2727 of file section.c.

2728{
2729 ULONG i;
2730
2731 for( i = 1; i < ImageSectionObject->NrSegments; ++ i )
2732 {
2733 ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >=
2734 ImageSectionObject->Segments[i - 1].Image.VirtualAddress);
2735 }
2736}

Referenced by MmspAssertSegmentsNoOverlap(), and MmspSortSegments().

◆ MmspCheckSegmentBounds()

static BOOLEAN NTAPI MmspCheckSegmentBounds ( IN OUT PMM_IMAGE_SECTION_OBJECT  ImageSectionObject,
IN ULONG  Flags 
)
static

Definition at line 2823 of file section.c.

2828{
2829 ULONG i;
2830
2832 {
2833 MmspAssertSegmentsNoOverlap(ImageSectionObject);
2834 return TRUE;
2835 }
2836
2837 ASSERT(ImageSectionObject->NrSegments >= 1);
2838
2839 for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
2840 {
2841 if(ImageSectionObject->Segments[i].Length.QuadPart == 0)
2842 {
2843 return FALSE;
2844 }
2845
2846 if(i > 0)
2847 {
2848 /*
2849 * TODO: relax the limitation on gaps. For example, gaps smaller than a
2850 * page could be OK (Windows seems to be OK with them), and larger gaps
2851 * could lead to image sections spanning several discontiguous regions
2852 * (NtMapViewOfSection could then refuse to map them, and they could
2853 * e.g. only be allowed as parameters to NtCreateProcess, like on UNIX)
2854 */
2855 if ((ImageSectionObject->Segments[i - 1].Image.VirtualAddress +
2856 ImageSectionObject->Segments[i - 1].Length.QuadPart) !=
2857 ImageSectionObject->Segments[i].Image.VirtualAddress)
2858 {
2859 return FALSE;
2860 }
2861 }
2862 }
2863
2864 return TRUE;
2865}
#define EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP
Definition: exeformat.h:9
static VOID NTAPI MmspAssertSegmentsNoOverlap(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
Definition: section.c:2741

Referenced by ExeFmtpCreateImageSection().

◆ MmspCompareSegments()

static int __cdecl MmspCompareSegments ( const void x,
const void y 
)
static

Definition at line 2778 of file section.c.

2780{
2781 const MM_SECTION_SEGMENT *Segment1 = (const MM_SECTION_SEGMENT *)x;
2782 const MM_SECTION_SEGMENT *Segment2 = (const MM_SECTION_SEGMENT *)y;
2783
2784 if (Segment1->Image.VirtualAddress > Segment2->Image.VirtualAddress)
2785 return 1;
2786 else if (Segment1->Image.VirtualAddress < Segment2->Image.VirtualAddress)
2787 return -1;
2788 else
2789 return 0;
2790}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548

Referenced by MmspSortSegments().

◆ MmspPageAlignSegments()

static BOOLEAN NTAPI MmspPageAlignSegments ( IN OUT PMM_IMAGE_SECTION_OBJECT  ImageSectionObject,
IN ULONG  Flags 
)
static

Definition at line 2874 of file section.c.

2879{
2880 ULONG i;
2881 ULONG LastSegment;
2882 PMM_SECTION_SEGMENT EffectiveSegment;
2883
2885 {
2886 MmspAssertSegmentsPageAligned(ImageSectionObject);
2887 return TRUE;
2888 }
2889
2890 LastSegment = 0;
2891 EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
2892
2893 for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
2894 {
2895 /*
2896 * The first segment requires special handling
2897 */
2898 if (i == 0)
2899 {
2901 ULONG_PTR VirtualOffset;
2902
2903 VirtualAddress = EffectiveSegment->Image.VirtualAddress;
2904
2905 /* Round down the virtual address to the nearest page */
2906 EffectiveSegment->Image.VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress);
2907
2908 /* Round up the virtual size to the nearest page */
2909 EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length.QuadPart) -
2910 EffectiveSegment->Image.VirtualAddress;
2911
2912 /* Adjust the raw address and size */
2913 VirtualOffset = VirtualAddress - EffectiveSegment->Image.VirtualAddress;
2914
2915 if (EffectiveSegment->Image.FileOffset < VirtualOffset)
2916 {
2917 return FALSE;
2918 }
2919
2920 /*
2921 * Garbage in, garbage out: unaligned base addresses make the file
2922 * offset point in curious and odd places, but that's what we were
2923 * asked for
2924 */
2925 EffectiveSegment->Image.FileOffset -= VirtualOffset;
2926 EffectiveSegment->RawLength.QuadPart += VirtualOffset;
2927 }
2928 else
2929 {
2930 PMM_SECTION_SEGMENT Segment = &ImageSectionObject->Segments[i];
2931 ULONG_PTR EndOfEffectiveSegment;
2932
2933 EndOfEffectiveSegment = (ULONG_PTR)(EffectiveSegment->Image.VirtualAddress + EffectiveSegment->Length.QuadPart);
2934 ASSERT((EndOfEffectiveSegment % PAGE_SIZE) == 0);
2935
2936 /*
2937 * The current segment begins exactly where the current effective
2938 * segment ended, therefore beginning a new effective segment
2939 */
2940 if (EndOfEffectiveSegment == Segment->Image.VirtualAddress)
2941 {
2942 LastSegment ++;
2943 ASSERT(LastSegment <= i);
2944 ASSERT(LastSegment < ImageSectionObject->NrSegments);
2945
2946 EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
2947
2948 if (LastSegment != i)
2949 {
2950 /*
2951 * Copy the current segment. If necessary, the effective segment
2952 * will be expanded later
2953 */
2954 *EffectiveSegment = *Segment;
2955 }
2956
2957 /*
2958 * Page-align the virtual size. We know for sure the virtual address
2959 * already is
2960 */
2961 ASSERT((EffectiveSegment->Image.VirtualAddress % PAGE_SIZE) == 0);
2962 EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(EffectiveSegment->Length.QuadPart);
2963 }
2964 /*
2965 * The current segment is still part of the current effective segment:
2966 * extend the effective segment to reflect this
2967 */
2968 else if (EndOfEffectiveSegment > Segment->Image.VirtualAddress)
2969 {
2970 static const ULONG FlagsToProtection[16] =
2971 {
2988 };
2989
2990 unsigned ProtectionFlags;
2991
2992 /*
2993 * Extend the file size
2994 */
2995
2996 /* Unaligned segments must be contiguous within the file */
2997 if (Segment->Image.FileOffset != (EffectiveSegment->Image.FileOffset +
2998 EffectiveSegment->RawLength.QuadPart))
2999 {
3000 return FALSE;
3001 }
3002
3003 EffectiveSegment->RawLength.QuadPart += Segment->RawLength.QuadPart;
3004
3005 /*
3006 * Extend the virtual size
3007 */
3008 ASSERT(PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) >= EndOfEffectiveSegment);
3009
3010 EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) -
3011 EffectiveSegment->Image.VirtualAddress;
3012
3013 /*
3014 * Merge the protection
3015 */
3016 EffectiveSegment->Protection |= Segment->Protection;
3017
3018 /* Clean up redundance */
3019 ProtectionFlags = 0;
3020
3021 if(EffectiveSegment->Protection & PAGE_IS_READABLE)
3022 ProtectionFlags |= 1 << 0;
3023
3024 if(EffectiveSegment->Protection & PAGE_IS_WRITABLE)
3025 ProtectionFlags |= 1 << 1;
3026
3027 if(EffectiveSegment->Protection & PAGE_IS_EXECUTABLE)
3028 ProtectionFlags |= 1 << 2;
3029
3030 if(EffectiveSegment->Protection & PAGE_IS_WRITECOPY)
3031 ProtectionFlags |= 1 << 3;
3032
3033 ASSERT(ProtectionFlags < 16);
3034 EffectiveSegment->Protection = FlagsToProtection[ProtectionFlags];
3035
3036 /* If a segment was required to be shared and cannot, fail */
3037 if(!(Segment->Protection & PAGE_IS_WRITECOPY) &&
3038 EffectiveSegment->Protection & PAGE_IS_WRITECOPY)
3039 {
3040 return FALSE;
3041 }
3042 }
3043 /*
3044 * We assume no holes between segments at this point
3045 */
3046 else
3047 {
3048 KeBugCheck(MEMORY_MANAGEMENT);
3049 }
3050 }
3051 }
3052 ImageSectionObject->NrSegments = LastSegment + 1;
3053
3054 return TRUE;
3055}
#define EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED
Definition: exeformat.h:10
#define PAGE_IS_READABLE
Definition: mm.h:151
static VOID NTAPI MmspAssertSegmentsPageAligned(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
Definition: section.c:2763
LARGE_INTEGER RawLength
Definition: mm.h:206
ULONG Protection
Definition: mm.h:210
LARGE_INTEGER Length
Definition: mm.h:207
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress

Referenced by ExeFmtpCreateImageSection().

◆ MmspSortSegments()

static VOID NTAPI MmspSortSegments ( IN OUT PMM_IMAGE_SECTION_OBJECT  ImageSectionObject,
IN ULONG  Flags 
)
static

Definition at line 2798 of file section.c.

2800{
2802 {
2803 MmspAssertSegmentsSorted(ImageSectionObject);
2804 }
2805 else
2806 {
2807 qsort(ImageSectionObject->Segments,
2808 ImageSectionObject->NrSegments,
2809 sizeof(ImageSectionObject->Segments[0]),
2811 }
2812}
_ACRTIMP void __cdecl qsort(void *, size_t, size_t, int(__cdecl *)(const void *, const void *))
#define EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED
Definition: exeformat.h:8
static int __cdecl MmspCompareSegments(const void *x, const void *y)
Definition: section.c:2778

Referenced by ExeFmtpCreateImageSection().

◆ MmspWaitForFileLock()

NTSTATUS MmspWaitForFileLock ( PFILE_OBJECT  File)

Definition at line 909 of file section.c.

910{
911 return STATUS_SUCCESS;
912 //return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL);
913}

Referenced by MmCreateDataFileSection(), and MmCreateImageSection().

◆ MmUnmapViewOfSegment()

static NTSTATUS MmUnmapViewOfSegment ( PMMSUPPORT  AddressSpace,
PVOID  BaseAddress 
)
static

Definition at line 3566 of file section.c.

3568{
3572 PLIST_ENTRY CurrentEntry;
3573 PMM_REGION CurrentRegion;
3574 PLIST_ENTRY RegionListHead;
3575
3577 BaseAddress);
3578 if (MemoryArea == NULL)
3579 {
3580 return STATUS_UNSUCCESSFUL;
3581 }
3582
3583 Segment = MemoryArea->SectionData.Segment;
3584
3585#ifdef NEWCC
3586 if (Segment->Flags & MM_DATAFILE_SEGMENT)
3587 {
3591
3592 return Status;
3593 }
3594#endif
3595
3597
3599
3600 RegionListHead = &MemoryArea->SectionData.RegionListHead;
3601 while (!IsListEmpty(RegionListHead))
3602 {
3603 CurrentEntry = RemoveHeadList(RegionListHead);
3604 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry);
3605 ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
3606 }
3607
3608 if ((*Segment->Flags) & MM_PHYSICALMEMORY_SEGMENT)
3609 {
3611 MemoryArea,
3612 NULL,
3613 NULL);
3614 }
3615 else
3616 {
3618 MemoryArea,
3620 AddressSpace);
3621 }
3623 MmDereferenceSegment(Segment);
3624 return Status;
3625}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
NTSTATUS NTAPI MmUnmapViewOfCacheSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
NTSTATUS NTAPI MmFreeMemoryArea(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_FREE_PAGE_FUNC FreePage, PVOID FreePageContext)
Definition: marea.c:258
static VOID MmFreeSectionPage(PVOID Context, MEMORY_AREA *MemoryArea, PVOID Address, PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
Definition: section.c:3482
Definition: typedefs.h:120
#define TAG_MM_REGION
Definition: tag.h:110

Referenced by MiRosUnmapViewInSystemSpace(), MiRosUnmapViewOfSection(), and MmMapViewOfSection().

◆ MmUnsharePageEntrySectionSegment()

BOOLEAN NTAPI MmUnsharePageEntrySectionSegment ( PMEMORY_AREA  MemoryArea,
PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset,
BOOLEAN  Dirty,
BOOLEAN  PageOut,
ULONG_PTR InEntry 
)

Definition at line 1091 of file section.c.

1097{
1100 BOOLEAN IsDataMap = BooleanFlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT);
1101 SWAPENTRY SwapEntry;
1102
1103 if (Entry == 0)
1104 {
1105 DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n");
1106 KeBugCheck(MEMORY_MANAGEMENT);
1107 }
1108 if (SHARE_COUNT_FROM_SSE(Entry) == 0)
1109 {
1110 DPRINT1("Zero share count for unshare (Seg %p Offset %x Page %x)\n", Segment, Offset->LowPart, PFN_FROM_SSE(Entry));
1111 KeBugCheck(MEMORY_MANAGEMENT);
1112 }
1114 {
1115 KeBugCheck(MEMORY_MANAGEMENT);
1116 }
1118 if (Dirty) Entry = DIRTY_SSE(Entry);
1119
1120 /* If we are paging-out, pruning the page for real will be taken care of in MmCheckDirtySegment */
1121 if ((SHARE_COUNT_FROM_SSE(Entry) > 0) || PageOut)
1122 {
1123 /* Update the page mapping in the segment and we're done */
1125 return FALSE;
1126 }
1127
1128 /* We are pruning the last mapping on this page. See if we can keep it a bit more. */
1129 ASSERT(!PageOut);
1130
1131 if (IsDataMap)
1132 {
1133 /* We can always keep memory in for data maps */
1135 return FALSE;
1136 }
1137
1138 if (!FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED))
1139 {
1140 ASSERT(Segment->WriteCopy);
1143 /* So this must have been a read-only page. Keep it ! */
1145 return FALSE;
1146 }
1147
1148 /*
1149 * So this is a page for a shared section of a DLL.
1150 * We can keep it if it is not dirty.
1151 */
1152 SwapEntry = MmGetSavedSwapEntryPage(Page);
1153 if ((SwapEntry == 0) && !IS_DIRTY_SSE(Entry))
1154 {
1156 return FALSE;
1157 }
1158
1159 /* No more processes are referencing this shared dirty page. Ditch it. */
1160 if (SwapEntry)
1161 {
1163 MmFreeSwapPage(SwapEntry);
1164 }
1167 return TRUE;
1168}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define DECREF_SSE(E)
Definition: mm.h:1388

Referenced by MmAccessFaultSectionView(), MmFreeSectionPage(), and MmPageOutPhysicalAddress().

◆ NtQuerySection()

NTSTATUS NTAPI NtQuerySection ( _In_ HANDLE  SectionHandle,
_In_ SECTION_INFORMATION_CLASS  SectionInformationClass,
_Out_ PVOID  SectionInformation,
_In_ SIZE_T  SectionInformationLength,
_Out_opt_ PSIZE_T  ResultLength 
)

Queries the information of a section object.

Parameters
SectionHandleHandle to the section object. It must be opened with SECTION_QUERY access.
SectionInformationClassIndex to a certain information structure. Can be either SectionBasicInformation or SectionImageInformation. The latter is valid only for sections that were created with the SEC_IMAGE flag.
SectionInformationCaller supplies storage for resulting information.
LengthSize of the supplied storage.
ResultLengthData written.
Returns
Status.

@implemented

Definition at line 3812 of file section.c.

3818{
3819 PSECTION Section;
3822 PAGED_CODE();
3823
3825 if (PreviousMode != KernelMode)
3826 {
3827 _SEH2_TRY
3828 {
3829 ProbeForWrite(SectionInformation,
3830 SectionInformationLength,
3831 __alignof(ULONG));
3832 if (ResultLength != NULL)
3833 {
3835 sizeof(*ResultLength),
3836 __alignof(SIZE_T));
3837 }
3838 }
3840 {
3842 }
3843 _SEH2_END;
3844 }
3845
3846 if (SectionInformationClass == SectionBasicInformation)
3847 {
3848 if (SectionInformationLength < sizeof(SECTION_BASIC_INFORMATION))
3849 {
3851 }
3852 }
3853 else if (SectionInformationClass == SectionImageInformation)
3854 {
3855 if (SectionInformationLength < sizeof(SECTION_IMAGE_INFORMATION))
3856 {
3858 }
3859 }
3860 else
3861 {
3863 }
3864
3865 Status = ObReferenceObjectByHandle(SectionHandle,
3869 (PVOID*)(PVOID)&Section,
3870 NULL);
3871 if (!NT_SUCCESS(Status))
3872 {
3873 DPRINT1("Failed to reference section: 0x%lx\n", Status);
3874 return Status;
3875 }
3876
3877 switch(SectionInformationClass)
3878 {
3880 {
3881 SECTION_BASIC_INFORMATION Sbi = { 0 };
3882
3883 Sbi.Size = Section->SizeOfSection;
3884 Sbi.BaseAddress = NULL;
3885
3886 if (Section->u.Flags.File)
3887 Sbi.Attributes |= SEC_FILE;
3888 if (Section->u.Flags.Image)
3889 Sbi.Attributes |= SEC_IMAGE;
3890 if (Section->u.Flags.Commit)
3891 Sbi.Attributes |= SEC_COMMIT;
3892 if (Section->u.Flags.Reserve)
3893 Sbi.Attributes |= SEC_RESERVE;
3894 if (Section->u.Flags.Based)
3895 Sbi.Attributes |= SEC_BASED;
3896
3897 if (Section->u.Flags.Image)
3898 {
3899 if (!MiIsRosSectionObject(Section))
3900 {
3901 /* Not supported yet */
3902 ASSERT(FALSE);
3903 }
3904 }
3905 else if (MiIsRosSectionObject(Section))
3906 {
3907 Sbi.BaseAddress = (PVOID)((PMM_SECTION_SEGMENT)Section->Segment)->Image.VirtualAddress;
3908 }
3909 else
3910 {
3911 Sbi.BaseAddress = Section->Segment->BasedAddress;
3912 }
3913
3914 _SEH2_TRY
3915 {
3916 *((SECTION_BASIC_INFORMATION*)SectionInformation) = Sbi;
3917 if (ResultLength != NULL)
3918 {
3919 *ResultLength = sizeof(Sbi);
3920 }
3921 }
3923 {
3925 }
3926 _SEH2_END;
3927 break;
3928 }
3930 {
3931 if (!Section->u.Flags.Image)
3932 {
3934 }
3935 else if (MiIsRosSectionObject(Section))
3936 {
3937 PMM_IMAGE_SECTION_OBJECT ImageSectionObject = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment);
3938
3939 _SEH2_TRY
3940 {
3942 *Sii = ImageSectionObject->ImageInformation;
3943 if (ResultLength != NULL)
3944 {
3945 *ResultLength = sizeof(*Sii);
3946 }
3947 }
3949 {
3951 }
3952 _SEH2_END;
3953 }
3954 else
3955 {
3956 _SEH2_TRY
3957 {
3959 *Sii = *Section->Segment->u2.ImageInformation;
3960 if (ResultLength != NULL)
3961 *ResultLength = sizeof(*Sii);
3962 }
3964 {
3966 }
3967 _SEH2_END;
3968 }
3969 break;
3970 }
3971 default:
3972 DPRINT1("Unknown SectionInformationClass: %d\n", SectionInformationClass);
3974 }
3975
3976 ObDereferenceObject(Section);
3977
3978 return Status;
3979}
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
struct _SECTION_IMAGE_INFORMATION * PSECTION_IMAGE_INFORMATION
#define SEC_FILE
Definition: mmtypes.h:96
@ SectionBasicInformation
Definition: mmtypes.h:195
@ SectionImageInformation
Definition: mmtypes.h:196
#define SECTION_QUERY
Definition: nt_native.h:1290
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:403
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
LARGE_INTEGER Size
Definition: mmtypes.h:336
PSECTION_IMAGE_INFORMATION ImageInformation
Definition: mmtypes.h:426
union _SEGMENT::@2848 u2
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

Referenced by CreateProcessInternalW(), get_binary_type(), QuerySbi(), and Test_SectionBasicInformation().

◆ PeFmtCreateSection()

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 
)

Definition at line 287 of file section.c.

294{
295 NTSTATUS nStatus;
296 ULONG cbFileHeaderOffsetSize = 0;
297 ULONG cbSectionHeadersOffset = 0;
298 ULONG cbSectionHeadersSize;
299 ULONG cbSectionHeadersOffsetSize = 0;
300 ULONG cbOptHeaderSize;
301 ULONG cbHeadersSize = 0;
302 ULONG nSectionAlignment;
303 ULONG nFileAlignment;
304 ULONG_PTR ImageBase = 0;
305 const IMAGE_DOS_HEADER * pidhDosHeader;
306 const IMAGE_NT_HEADERS32 * pinhNtHeader;
307 const IMAGE_OPTIONAL_HEADER32 * piohOptHeader;
308 const IMAGE_SECTION_HEADER * pishSectionHeaders;
309 PMM_SECTION_SEGMENT pssSegments;
310 LARGE_INTEGER lnOffset;
312 SIZE_T nPrevVirtualEndOfSegment = 0;
313 ULONG nFileSizeOfHeaders = 0;
314 ULONG i;
315 ULONG AlignedLength;
316
317 ASSERT(FileHeader);
318 ASSERT(FileHeaderSize > 0);
319 ASSERT(File);
320 ASSERT(ImageSectionObject);
321 ASSERT(ReadFileCb);
322 ASSERT(AllocateSegmentsCb);
323
324 ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize));
325
326 ASSERT(((UINT_PTR)FileHeader % TYPE_ALIGNMENT(IMAGE_DOS_HEADER)) == 0);
327
328#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; }
329
330 pBuffer = NULL;
331 pidhDosHeader = FileHeader;
332
333 /* DOS HEADER */
335
336 /* image too small to be an MZ executable */
337 if(FileHeaderSize < sizeof(IMAGE_DOS_HEADER))
338 DIE(("Too small to be an MZ executable, size is %lu\n", FileHeaderSize));
339
340 /* no MZ signature */
341 if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
342 DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
343
344 /* NT HEADER */
346
347 /* not a Windows executable */
348 if(pidhDosHeader->e_lfanew <= 0)
349 DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
350
351 if(!Intsafe_AddULong32(&cbFileHeaderOffsetSize, pidhDosHeader->e_lfanew, RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)))
352 DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
353
354 if(FileHeaderSize < cbFileHeaderOffsetSize)
355 pinhNtHeader = NULL;
356 else
357 {
358 /*
359 * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
360 * and FileHeaderSize >= cbFileHeaderOffsetSize, so this holds true too
361 */
362 ASSERT(Intsafe_CanOffsetPointer(FileHeader, pidhDosHeader->e_lfanew));
363 pinhNtHeader = (PVOID)((UINT_PTR)FileHeader + pidhDosHeader->e_lfanew);
364 }
365
366 /*
367 * the buffer doesn't contain the NT file header, or the alignment is wrong: we
368 * need to read the header from the file
369 */
370 if(FileHeaderSize < cbFileHeaderOffsetSize ||
371 (UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
372 {
373 ULONG cbNtHeaderSize;
374 ULONG cbReadSize;
375 PVOID pData;
376
377l_ReadHeaderFromFile:
378 cbNtHeaderSize = 0;
379 lnOffset.QuadPart = pidhDosHeader->e_lfanew;
380
381 /* read the header from the file */
382 nStatus = ReadFileCb(File, &lnOffset, sizeof(IMAGE_NT_HEADERS64), &pData, &pBuffer, &cbReadSize);
383
384 if(!NT_SUCCESS(nStatus))
385 {
386 NTSTATUS ReturnedStatus = nStatus;
387
388 /* If it attempted to read past the end of the file, it means e_lfanew is invalid */
389 if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_INVALID_IMAGE_PROTECT;
390
391 DIE(("ReadFile failed, status %08X\n", ReturnedStatus));
392 }
393
394 ASSERT(pData);
396 ASSERT(cbReadSize > 0);
397
399
400 /* the buffer doesn't contain the file header */
401 if(cbReadSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader))
402 DIE(("The file doesn't contain the PE file header\n"));
403
404 pinhNtHeader = pData;
405
406 /* object still not aligned: copy it to the beginning of the buffer */
407 if((UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
408 {
410 RtlMoveMemory(pBuffer, pData, cbReadSize);
411 pinhNtHeader = pBuffer;
412 }
413
414 /* invalid NT header */
416
417 if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
418 DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
419
421
422 if(!Intsafe_AddULong32(&cbNtHeaderSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
423 DIE(("The full NT header is too large\n"));
424
425 /* the buffer doesn't contain the whole NT header */
426 if(cbReadSize < cbNtHeaderSize)
427 DIE(("The file doesn't contain the full NT header\n"));
428 }
429 else
430 {
431 ULONG cbOptHeaderOffsetSize = 0;
432
434
435 /* don't trust an invalid NT header */
436 if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
437 DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
438
439 if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
440 DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
441
443
444 if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
445 DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
446
447 /* the buffer doesn't contain the whole NT header: read it from the file */
448 if(cbOptHeaderOffsetSize > FileHeaderSize)
449 goto l_ReadHeaderFromFile;
450 }
451
452 /* read information from the NT header */
453 piohOptHeader = &pinhNtHeader->OptionalHeader;
454 cbOptHeaderSize = pinhNtHeader->FileHeader.SizeOfOptionalHeader;
455
457
458 if(!RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Magic))
459 DIE(("The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
460
461 /* ASSUME: RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject)); */
462
463 switch(piohOptHeader->Magic)
464 {
466#ifndef _WIN64
468 DIE(("Win64 optional header, unsupported\n"));
469#else
470 // Fall through.
471#endif
473 break;
474 default:
475 DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
476 }
477
478 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SectionAlignment) &&
479 RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, FileAlignment))
480 {
481 /* See [1], section 3.4.2 */
482 if(piohOptHeader->SectionAlignment < PAGE_SIZE)
483 {
484 if(piohOptHeader->FileAlignment != piohOptHeader->SectionAlignment)
485 DIE(("Sections aren't page-aligned and the file alignment isn't the same\n"));
486 }
487 else if(piohOptHeader->SectionAlignment < piohOptHeader->FileAlignment)
488 DIE(("The section alignment is smaller than the file alignment\n"));
489
490 nSectionAlignment = piohOptHeader->SectionAlignment;
491 nFileAlignment = piohOptHeader->FileAlignment;
492
493 if(!IsPowerOf2(nSectionAlignment) || !IsPowerOf2(nFileAlignment))
494 DIE(("The section alignment (%u) and file alignment (%u) aren't both powers of 2\n", nSectionAlignment, nFileAlignment));
495 }
496 else
497 {
498 nSectionAlignment = PAGE_SIZE;
499 nFileAlignment = PAGE_SIZE;
500 }
501
502 ASSERT(IsPowerOf2(nSectionAlignment));
503 ASSERT(IsPowerOf2(nFileAlignment));
504
505 switch(piohOptHeader->Magic)
506 {
507 /* PE32 */
509 {
510 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase))
511 ImageBase = piohOptHeader->ImageBase;
512
513 if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage))
514 ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->SizeOfImage;
515
516 if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve))
517 ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->SizeOfStackReserve;
518
519 if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit))
520 ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->SizeOfStackCommit;
521
522 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem))
523 {
524 ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->Subsystem;
525
526 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
527 RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MajorSubsystemVersion))
528 {
529 ImageSectionObject->ImageInformation.SubSystemMinorVersion = piohOptHeader->MinorSubsystemVersion;
530 ImageSectionObject->ImageInformation.SubSystemMajorVersion = piohOptHeader->MajorSubsystemVersion;
531 }
532 }
533
534 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
535 {
536 ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase +
537 piohOptHeader->AddressOfEntryPoint);
538 }
539
540 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode))
541 ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->SizeOfCode != 0;
542 else
543 ImageSectionObject->ImageInformation.ImageContainsCode = TRUE;
544
545 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
546 {
547 if (piohOptHeader->AddressOfEntryPoint == 0)
548 {
549 ImageSectionObject->ImageInformation.ImageContainsCode = FALSE;
550 }
551 }
552
553 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, LoaderFlags))
554 ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->LoaderFlags;
555
556 if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, DllCharacteristics))
557 {
558 ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->DllCharacteristics;
559
560 /*
561 * Since we don't really implement SxS yet and LD doesn't supoprt /ALLOWISOLATION:NO, hard-code
562 * this flag here, which will prevent the loader and other code from doing any .manifest or SxS
563 * magic to any binary.
564 *
565 * This will break applications that depend on SxS when running with real Windows Kernel32/SxS/etc
566 * but honestly that's not tested. It will also break them when running no ReactOS once we implement
567 * the SxS support -- at which point, duh, this should be removed.
568 *
569 * But right now, any app depending on SxS is already broken anyway, so this flag only helps.
570 */
571 ImageSectionObject->ImageInformation.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
572 }
573
574 break;
575 }
576#ifdef _WIN64
577 /* PE64 */
579 {
580 const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader;
581
582 pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader;
583
584 if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, ImageBase))
585 {
586 ImageBase = pioh64OptHeader->ImageBase;
587 if(pioh64OptHeader->ImageBase > MAXULONG_PTR)
588 DIE(("ImageBase exceeds the address space\n"));
589 }
590
591 if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfImage))
592 {
593 if(pioh64OptHeader->SizeOfImage > MAXULONG_PTR)
594 DIE(("SizeOfImage exceeds the address space\n"));
595
596 ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->SizeOfImage;
597 }
598
599 if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackReserve))
600 {
601 if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR)
602 DIE(("SizeOfStackReserve exceeds the address space\n"));
603
604 ImageSectionObject->ImageInformation.MaximumStackSize = (ULONG_PTR) pioh64OptHeader->SizeOfStackReserve;
605 }
606
607 if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackCommit))
608 {
609 if(pioh64OptHeader->SizeOfStackCommit > MAXULONG_PTR)
610 DIE(("SizeOfStackCommit exceeds the address space\n"));
611
612 ImageSectionObject->ImageInformation.CommittedStackSize = (ULONG_PTR) pioh64OptHeader->SizeOfStackCommit;
613 }
614
615 if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, Subsystem))
616 {
617 ImageSectionObject->ImageInformation.SubSystemType = pioh64OptHeader->Subsystem;
618
619 if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
620 RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MajorSubsystemVersion))
621 {
622 ImageSectionObject->ImageInformation.SubSystemMinorVersion = pioh64OptHeader->MinorSubsystemVersion;
623 ImageSectionObject->ImageInformation.SubSystemMajorVersion = pioh64OptHeader->MajorSubsystemVersion;
624 }
625 }
626
627 if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint))
628 {
629 ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase +
630 pioh64OptHeader->AddressOfEntryPoint);
631 }
632
633 if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfCode))
634 ImageSectionObject->ImageInformation.ImageContainsCode = pioh64OptHeader->SizeOfCode != 0;
635 else
636 ImageSectionObject->ImageInformation.ImageContainsCode = TRUE;
637
638 if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint))
639 {
640 if (pioh64OptHeader->AddressOfEntryPoint == 0)
641 {
642 ImageSectionObject->ImageInformation.ImageContainsCode = FALSE;
643 }
644 }
645
646 if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, LoaderFlags))
647 ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->LoaderFlags;
648
649 if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, DllCharacteristics))
650 ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->DllCharacteristics;
651
652 break;
653 }
654#endif // _WIN64
655 }
656
657 /* [1], section 3.4.2 */
658 if((ULONG_PTR)ImageBase % 0x10000)
659 DIE(("ImageBase is not aligned on a 64KB boundary"));
660
661 ImageSectionObject->ImageInformation.ImageCharacteristics = pinhNtHeader->FileHeader.Characteristics;
662 ImageSectionObject->ImageInformation.Machine = pinhNtHeader->FileHeader.Machine;
663 ImageSectionObject->ImageInformation.GpValue = 0;
664 ImageSectionObject->ImageInformation.ZeroBits = 0;
665 ImageSectionObject->BasedAddress = (PVOID)ImageBase;
666
667 /* SECTION HEADERS */
669
670 /* see [1], section 3.3 */
671 if(pinhNtHeader->FileHeader.NumberOfSections > 96)
672 DIE(("Too many sections, NumberOfSections is %u\n", pinhNtHeader->FileHeader.NumberOfSections));
673
674 /*
675 * the additional segment is for the file's headers. They need to be present for
676 * the benefit of the dynamic loader (to locate exports, defaults for thread
677 * parameters, resources, etc.)
678 */
679 ImageSectionObject->NrSegments = pinhNtHeader->FileHeader.NumberOfSections + 1;
680
681 /* file offset for the section headers */
682 if(!Intsafe_AddULong32(&cbSectionHeadersOffset, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
683 DIE(("Offset overflow\n"));
684
685 if(!Intsafe_AddULong32(&cbSectionHeadersOffset, cbSectionHeadersOffset, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
686 DIE(("Offset overflow\n"));
687
688 /* size of the section headers */
690 cbSectionHeadersSize = pinhNtHeader->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
691
692 if(!Intsafe_AddULong32(&cbSectionHeadersOffsetSize, cbSectionHeadersOffset, cbSectionHeadersSize))
693 DIE(("Section headers too large\n"));
694
695 /* size of the executable's headers */
696 if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfHeaders))
697 {
698// if(!IsAligned(piohOptHeader->SizeOfHeaders, nFileAlignment))
699// DIE(("SizeOfHeaders is not aligned\n"));
700
701 if(cbSectionHeadersSize > piohOptHeader->SizeOfHeaders)
702 DIE(("The section headers overflow SizeOfHeaders\n"));
703
704 cbHeadersSize = piohOptHeader->SizeOfHeaders;
705 }
706 else if(!AlignUp(&cbHeadersSize, cbSectionHeadersOffsetSize, nFileAlignment))
707 DIE(("Overflow aligning the size of headers\n"));
708
709 if(pBuffer)
710 {
712 pBuffer = NULL;
713 }
714 /* WARNING: pinhNtHeader IS NO LONGER USABLE */
715 /* WARNING: piohOptHeader IS NO LONGER USABLE */
716 /* WARNING: pioh64OptHeader IS NO LONGER USABLE */
717
718 if(FileHeaderSize < cbSectionHeadersOffsetSize)
719 pishSectionHeaders = NULL;
720 else
721 {
722 /*
723 * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
724 * and FileHeaderSize >= cbSectionHeadersOffsetSize, so this holds true too
725 */
726 ASSERT(Intsafe_CanOffsetPointer(FileHeader, cbSectionHeadersOffset));
727 pishSectionHeaders = (PVOID)((UINT_PTR)FileHeader + cbSectionHeadersOffset);
728 }
729
730 /*
731 * the buffer doesn't contain the section headers, or the alignment is wrong:
732 * read the headers from the file
733 */
734 if(FileHeaderSize < cbSectionHeadersOffsetSize ||
735 (UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
736 {
737 PVOID pData;
738 ULONG cbReadSize;
739
740 lnOffset.QuadPart = cbSectionHeadersOffset;
741
742 /* read the header from the file */
743 nStatus = ReadFileCb(File, &lnOffset, cbSectionHeadersSize, &pData, &pBuffer, &cbReadSize);
744
745 if(!NT_SUCCESS(nStatus))
746 DIE(("ReadFile failed with status %08X\n", nStatus));
747
748 ASSERT(pData);
750 ASSERT(cbReadSize > 0);
751
753
754 /* the buffer doesn't contain all the section headers */
755 if(cbReadSize < cbSectionHeadersSize)
756 DIE(("The file doesn't contain all of the section headers\n"));
757
758 pishSectionHeaders = pData;
759
760 /* object still not aligned: copy it to the beginning of the buffer */
761 if((UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
762 {
764 RtlMoveMemory(pBuffer, pData, cbReadSize);
765 pishSectionHeaders = pBuffer;
766 }
767 }
768
769 /* SEGMENTS */
770 /* allocate the segments */
772 ImageSectionObject->Segments = AllocateSegmentsCb(ImageSectionObject->NrSegments);
773
774 if(ImageSectionObject->Segments == NULL)
775 DIE(("AllocateSegments failed\n"));
776
777 /* initialize the headers segment */
778 pssSegments = ImageSectionObject->Segments;
779
780// ASSERT(IsAligned(cbHeadersSize, nFileAlignment));
781
782 if(!AlignUp(&nFileSizeOfHeaders, cbHeadersSize, nFileAlignment))
783 DIE(("Cannot align the size of the section headers\n"));
784
785 nPrevVirtualEndOfSegment = ALIGN_UP_BY(cbHeadersSize, nSectionAlignment);
786 if (nPrevVirtualEndOfSegment < cbHeadersSize)
787 DIE(("Cannot align the size of the section headers\n"));
788
789 pssSegments[0].Image.FileOffset = 0;
790 pssSegments[0].Protection = PAGE_READONLY;
791 pssSegments[0].Length.QuadPart = nPrevVirtualEndOfSegment;
792 pssSegments[0].RawLength.QuadPart = nFileSizeOfHeaders;
793 pssSegments[0].Image.VirtualAddress = 0;
794 pssSegments[0].Image.Characteristics = 0;
795 pssSegments[0].WriteCopy = TRUE;
796
797 /* skip the headers segment */
798 ++ pssSegments;
799
801
802 ASSERT(ImageSectionObject->RefCount > 0);
803
804 /* convert the executable sections into segments. See also [1], section 4 */
805 for(i = 0; i < ImageSectionObject->NrSegments - 1; ++ i)
806 {
807 ULONG nCharacteristics;
808
809 /* validate the alignment */
810 if(!IsAligned(pishSectionHeaders[i].VirtualAddress, nSectionAlignment))
811 DIE(("Image.VirtualAddress[%u] is not aligned\n", i));
812
813 /* sections must be contiguous, ordered by base address and non-overlapping */
814 if(pishSectionHeaders[i].VirtualAddress != nPrevVirtualEndOfSegment)
815 DIE(("Memory gap between section %u and the previous\n", i));
816
817 /* ignore explicit BSS sections */
818 if(pishSectionHeaders[i].PointerToRawData != 0 && pishSectionHeaders[i].SizeOfRawData != 0)
819 {
820 /* validate the alignment */
821#if 0
822 /* Yes, this should be a multiple of FileAlignment, but there's
823 * stuff out there that isn't. We can cope with that
824 */
825 if(!IsAligned(pishSectionHeaders[i].SizeOfRawData, nFileAlignment))
826 DIE(("SizeOfRawData[%u] is not aligned\n", i));
827#endif
828
829// if(!IsAligned(pishSectionHeaders[i].PointerToRawData, nFileAlignment))
830// DIE(("PointerToRawData[%u] is not aligned\n", i));
831
832 if(!Intsafe_CanAddULong32(pishSectionHeaders[i].PointerToRawData, pishSectionHeaders[i].SizeOfRawData))
833 DIE(("SizeOfRawData[%u] too large\n", i));
834
835 /* conversion */
836 pssSegments[i].Image.FileOffset = pishSectionHeaders[i].PointerToRawData;
837 pssSegments[i].RawLength.QuadPart = pishSectionHeaders[i].SizeOfRawData;
838 }
839 else
840 {
841 /* FIXME: Should reset PointerToRawData to 0 in the image mapping */
842 ASSERT(pssSegments[i].Image.FileOffset == 0);
843 ASSERT(pssSegments[i].RawLength.QuadPart == 0);
844 }
845
846 ASSERT(Intsafe_CanAddLong64(pssSegments[i].Image.FileOffset, pssSegments[i].RawLength.QuadPart));
847
848 nCharacteristics = pishSectionHeaders[i].Characteristics;
849
850 /* no explicit protection */
851 if((nCharacteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == 0)
852 {
853 if(nCharacteristics & IMAGE_SCN_CNT_CODE)
854 nCharacteristics |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
855
856 if(nCharacteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
857 nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
858
859 if(nCharacteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
860 nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
861 }
862
863 /* see table above */
864 pssSegments[i].Protection = SectionCharacteristicsToProtect[nCharacteristics >> 28];
865 pssSegments[i].WriteCopy = !(nCharacteristics & IMAGE_SCN_MEM_SHARED);
866
867 if(pishSectionHeaders[i].Misc.VirtualSize == 0)
868 pssSegments[i].Length.QuadPart = pishSectionHeaders[i].SizeOfRawData;
869 else
870 pssSegments[i].Length.QuadPart = pishSectionHeaders[i].Misc.VirtualSize;
871
872 AlignedLength = ALIGN_UP_BY(pssSegments[i].Length.LowPart, nSectionAlignment);
873 if(AlignedLength < pssSegments[i].Length.LowPart)
874 DIE(("Cannot align the virtual size of section %u\n", i));
875
876 pssSegments[i].Length.LowPart = AlignedLength;
877
878 if(pssSegments[i].Length.QuadPart == 0)
879 DIE(("Virtual size of section %u is null\n", i));
880
881 pssSegments[i].Image.VirtualAddress = pishSectionHeaders[i].VirtualAddress;
882 pssSegments[i].Image.Characteristics = pishSectionHeaders[i].Characteristics;
883
884 /* ensure the memory image is no larger than 4GB */
885 nPrevVirtualEndOfSegment = (ULONG_PTR)(pssSegments[i].Image.VirtualAddress + pssSegments[i].Length.QuadPart);
886 if (nPrevVirtualEndOfSegment < pssSegments[i].Image.VirtualAddress)
887 DIE(("The image is too large\n"));
888 }
889
890 if(nSectionAlignment >= PAGE_SIZE)
892
893 /* Success */
894 nStatus = STATUS_SUCCESS;// STATUS_ROS_EXEFMT_LOADED_FORMAT | EXEFMT_LOADED_PE32;
895
896l_Return:
897 if(pBuffer)
899
900 return nStatus;
901}
#define ALIGN_UP_BY(size, align)
#define MAXULONG_PTR
Definition: basetsd.h:97
static __inline BOOLEAN IsPowerOf2(IN ULONG Number)
Definition: exeformat.h:134
static __inline BOOLEAN Intsafe_CanAddLong64(IN LONG64 Addend1, IN LONG64 Addend2)
Definition: exeformat.h:104
static __inline BOOLEAN Intsafe_CanMulULong32(IN ULONG Factor1, IN ULONG Factor2)
Definition: exeformat.h:123
static __inline BOOLEAN Intsafe_CanAddULong32(IN ULONG Addend1, IN ULONG Addend2)
Definition: exeformat.h:109
static __inline BOOLEAN IsAligned(IN ULONG Address, IN ULONG Alignment)
Definition: exeformat.h:147
static __inline BOOLEAN Intsafe_CanOffsetPointer(IN CONST VOID *Pointer, IN SIZE_T Offset)
Definition: exeformat.h:128
static __inline BOOLEAN Intsafe_AddULong32(OUT PULONG Result, IN ULONG Addend1, IN ULONG Addend2)
Definition: exeformat.h:114
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define TYPE_ALIGNMENT(t)
Definition: ntbasedef.h:117
#define RTL_CONTAINS_FIELD(Struct, Size, Field)
Definition: ntbasedef.h:687
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:684
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: ntimage.h:376
#define IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: ntimage.h:231
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
#define IMAGE_SCN_CNT_CODE
Definition: ntimage.h:230
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239
#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION
Definition: ntimage.h:458
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA
Definition: ntimage.h:232
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:1029
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:634
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
struct _IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER
PVOID pBuffer
static ULONG SectionCharacteristicsToProtect[16]
Definition: section.c:200
#define DIE(ARGS_)
ULONGLONG AlignUp(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:81
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
USHORT MajorSubsystemVersion
Definition: ntimage.h:356
ULONGLONG SizeOfStackReserve
Definition: ntimage.h:364
USHORT MinorSubsystemVersion
Definition: ntimage.h:357
ULONGLONG SizeOfStackCommit
Definition: ntimage.h:365
union _IMAGE_SECTION_HEADER::@1688 Misc
DWORD PointerToRawData
Definition: pedump.c:290
BOOLEAN WriteCopy
Definition: mm.h:212
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Variable Documentation

◆ Entry

Definition at line 5216 of file section.c.

Referenced by _FindPort(), FxObject::_FromDisposeEntry(), FxRequestBase::_FromDrainEntry(), FxChildList::_FromEntry(), FxIoTarget::_FromEntry(), FxTransactionedEntry::_FromEntry(), FxDeviceInterface::_FromEntry(), FxDeviceText::_FromEntry(), FxQueryInterface::_FromEntry(), FxIoQueue::_FromIoPkgListEntry(), FxIoQueueNode::_FromListEntry(), FxRequestBase::_FromListEntry(), FxIoQueue::_FromPowerSListEntry(), _HandleDeletePort(), _MmSetPageEntrySectionSegment(), _Requires_lock_held_(), FxTransactionedList::Add(), FxRelatedDeviceList::Add(), AddMonitorW(), AddNTOSInstallationItem(), AddPortExW(), AddPortW(), AddPrinterDriverExW(), AddPrinterExW(), AddPrinterW(), AddRemoteDatabaseEntry(), AfdEventReceiveDatagramHandler(), AllocateDictionaryEntry(), AllocRoutine(), Amd64SetupGdt(), AppendGenericListEntry(), ApphelpCacheDump(), ApphelpCacheLookupEntry(), ApphelpCacheParse(), ApphelpCacheQueryInfo(), ApphelpCacheRemoveEntry(), ApphelpCacheRemoveEntryNolock(), ApphelpCacheUpdateEntry(), ApphelpCacheWrite(), AtaDeviceFlushPowerIrpQueue(), AtaFdoDeviceListInsert(), AtaFdoFindDeviceByPath(), AtaFdoFindNextDeviceByPath(), AtaPortDeviceProcessPowerChange(), AtaPortFindDeviceForAction(), AtaReqDeviceQueueDispatchNextRequest(), AtaReqDeviceQueueInsertSrb(), AtaReqFlushDeviceQueue(), AtaReqRemovePortRequest(), AVrfDllLoadNotification(), AVrfDllUnloadNotification(), AVrfInitializeVerifier(), AVrfInternalHeapFreeNotification(), AVrfpChainDuplicateThunks(), AvrfpFindDuplicateThunk(), AVrfpIsVerifierProviderDll(), AvrfpResolveThunks(), AVrfpSnapDllImports(), BasepIsProcessAllowed(), BasepLocateExeLdrEntry(), BasepProbeForDllManifest(), BaseSrvCleanupVDMResources(), BaseSrvGetConsoleRecord(), BroadcastOpen(), FxSystemThread::CancelWorkItem(), CcFlushImageSection(), CcIsThereDirtyData(), CcpCountCacheSections(), CcpFindMatchingMap(), CcpFindOtherStreamFileObject(), CdFspDispatch(), CdRemoveClose(), CenterCurrentListItem(), ChangeRemoteDatabaseUniqueId(), ClassDeviceControl(), ClasspInsertCScanList(), clean_main(), FxCollectionInternal::CleanupEntry(), CleanupNamespaceProviders(), CleanupProtocolProviders(), FxCmResList::ClearRegisterResourceEntryLocked(), ClearTTFontCache(), ClockUpdate(), FxChildList::CloneEntryLocked(), CloseAllDialogWindows(), CmpAddToDelayedClose(), CmpAllocateDelayItem(), CmpDelayDerefKeyControlBlock(), CmpEnumerateOpenSubKeys(), CmpFreeDelayItem(), CmpFreeDriverList(), CmpInsertKeyHash(), CmpRemoveFromDelayedClose(), co_MsqDispatchOneSentMessage(), co_MsqSendMessage(), FxRelatedDeviceList::Compare(), FxTransactionedList::Compare(), CompareSettings(), ComputeCompatibleFormat(), CON_API(), ConfigurePortW(), ConSrvGetObject(), ConvertNtPathToWin32Path(), ATL::CAtlPlex::Create(), FxChildList::CreateDevice(), CreateNTOSInstallationsList(), CreateRedirectedFile(), CSR_API(), DateTimePageDlgProc(), DcCancelSendPackets(), DcCreateRxRing(), DcFlushTransmitQueue(), DcFreeAdapter(), DcHandleTx(), DcProcessPendingPackets(), DECLARE_INTERFACE_(), DeleteMbrPartition(), DeleteMonitorW(), DeletePartition(), DeletePortW(), DeletePrinterDriverExW(), DeleteRemoteDatabaseEntry(), DestroyGenericList(), DestroyPartitionList(), DestroyTimeZoneList(), DestroyVolumeList(), DetailDisk(), DetailPartition(), DetailVolume(), DeviceInterruptBop(), DisconnectWorker(), DnsIntCacheAddEntry(), DnsIntCacheFlush(), DnsIntFlushCacheEntry(), DoEntry(), DoLAYOUT(), DosGetDriverNode(), DrawListEntries(), DrawPartitionList(), DriverIoControl(), DrvTestResources(), EmsFree(), FxTransactionedList::EntryAdded(), FxRelatedDeviceList::EntryRemoved(), FxTransactionedList::EntryRemoved(), EnumMonitorsW(), EnumPortsW(), EnumPrinterDriversW(), EnumPrintersW(), EnumPrintProcessorDatatypesW(), EnumPrintProcessorsW(), EventCallback(), ExAllocatePoolWithQuotaTag(), ExAllocatePoolWithTag(), ExDeleteNPagedLookasideList(), ExDeletePagedLookasideList(), ExExtendZone(), ExFreePoolWithTag(), ExiAllocateFromPagedLookasideList(), ExiFreeToPagedLookasideList(), ExInitializeZone(), ExInitPoolLookasidePointers(), ExitThreadCallback(), ExpAddTagForBigPages(), ExpAllocateHandleTableEntry(), ExpCheckPoolAllocation(), ExpCheckPoolBlocks(), ExpCheckPoolHeader(), ExpCheckPoolIrqlLevel(), ExpFindAndRemoveTagBigPages(), ExpInsertPoolHeadList(), ExpInsertPoolTailList(), ExpLookupHandleTableEntry(), ExpRemovePoolEntryList(), ExpRemovePoolHeadList(), ExpRemovePoolTailList(), ExReturnPoolQuota(), FAT12CountAvailableClusters(), FAT12FindAndMarkAvailableCluster(), FAT12GetNextCluster(), FatBufferDirectory(), FatFspDispatch(), FatInterpretClusterType(), FatRemoveOverflowEntry(), FDO_HandleResetCyclePort(), FileTypesDlg_InsertToLV(), fill_in_hard_link_full_id_information(), fill_in_hard_link_information(), FindBestFontFromList(), FindBootDisplayFromLoaderARCTree(), FindCachedTTFont(), FindComSpecInfoByPsp(), FindExistingNTOSInstall(), FindMatchingCreateItem(), FindPort(), FindPrintMonitor(), FindPrintProcessor(), FindRemoveEventMsg(), FlsFree(), FlushConnectQueue(), FlushListenQueue(), FlushReceiveQueue(), FlushSendQueue(), FlushShutdownQueue(), FontLink_Chain_Dump(), FontLink_Chain_FindGlyph(), FontLink_Chain_FindLink(), FontLink_DeleteEntries(), FontLink_FindEntry(), FreeDictionaryEntry(), FreeFilterInstance(), FreeLogFilterList(), FreeLogicalDevice(), FreeLogList(), FreeNtToWin32PathMappingList(), FreeRoutine(), FreeSegmentPage(), FsdSetFsLabelInformation(), FsRtlDeleteTunnelCache(), FsRtlFastUnlockAll(), FsRtlFastUnlockAllByKey(), FsRtlFastUnlockSingle(), FsRtlGetNextFileLock(), FsRtlpRebuildSharedLockRange(), FsRtlPruneTunnelCache(), FsRtlUninitializeFileLock(), FsRtlWorkerThread(), FstubCopyEntryEFI(), FstubWritePartitionTableEFI(), FsVolCommitOpsQueue(), FxAllocateFromNPagedLookasideList(), FxAllocateFromNPagedLookasideListNoTracking(), FxAllocateFromPagedLookasideList(), FxFreeToNPagedLookasideList(), FxFreeToNPagedLookasideListNoTracking(), FxFreeToPagedLookasideList(), GdiFixUpHandle(), GdiGetHandleUserData(), GdiValidateHandle(), CPortPinWaveCyclic::GeneratePositionEvents(), FxChildList::GetAddressDescriptionFromEntry(), GetAppName(), GetConsoleRecordBySessionId(), GetDialogListEntry(), GetDiskByBiosNumber(), GetDiskByNumber(), GetDiskBySCSI(), GetDiskBySignature(), GetDiskForVolume(), GetFileTypeIconsByKey(), GetFileTypeIconsEx(), GetFilterInstanceEntry(), GetFirstListEntry(), GetFontFamilyInfoForList(), GetFreeDiskSize(), GetLargerTimeZoneEntry(), CIconWatcher::GetListEntry(), GetListEntry(), GetListEntryData(), GetListEntryUiData(), GetLogicalPage(), GetModuleFileNameW(), GetNextDosSesId(), FxRelatedDeviceList::GetNextEntry(), FxTransactionedList::GetNextEntry(), FxTransactionedList::GetNextEntryLocked(), GetNextFreeVDDEntry(), GetNextListEntry(), GetNextUnformattedVolume(), GetNTOSInstallationName(), GetPartition(), GetPartitionCount(), GetPinInstanceCount(), GetPrimaryPartitionCount(), GetPrinterDriverDirectoryW(), GetPrintProcessorDirectoryW(), GetProgramPath(), GetProtoGetNextEnt(), GetRemoteDatabaseEntry(), GetSelectedTimeZoneEntry(), GetSettingDescription(), getShellClassInfo(), GetSystemDisk(), GetTimeZoneEntryByIndex(), GetTypeName(), GetVolumeFromPartition(), GetXmsHandleRecord(), HaliReadMPConfigTable(), HalpBuildPartialFromIdt(), HalpIsValidPartitionEntry(), HalpStoreAndClearIopm(), HandlePhysicalConnection(), HandleSysAudioFilterPinProperties(), HasDaylightSaving(), HasDaylightSavingTime(), HfontCreate(), HidClass_Close(), HistoryAddEntry(), HistoryCurrentBuffer(), HistoryFindBuffer(), HistoryFindEntryByPrefix(), HistoryGetCurrentEntry(), HistoryRecallHistory(), HistoryReshapeAllBuffers(), IniCacheDestroy(), IniCacheFindKey(), IniCacheFindSection(), IniCacheFreeSection(), IniFindFirstValue(), IniFindNextValue(), IniGetSettingByNumber(), IniModifySettingValue(), IniOpenSection(), IniReadSettingByName(), InitGenericComboList(), InitGenericListView(), InitializeMemoryManagement(), InitializePortList(), InitPaletteWithTable(), InsertAfterEntry(), InsertDiskRegion(), InsertHeadList(), InsertTailList(), IntCreateAliasEntry(), IntCreateAliasHeader(), IntDeleteAliasEntry(), IntDeleteAllAliases(), IntDeleteAllContexts(), InternalGetListRemovalHandledFlag(), InternalWake(), IntGdiCleanupMemEntry(), IntGdiCleanupPrivateFontsForProcess(), IntGdiLoadFontsFromMemory(), IntGdiReleaseRaoRgn(), IntGdiRemoveFontMemResource(), IntGetAliasEntry(), IntGetLoadedCodePageEntry(), IntGetNextPowerCallout(), IntNeedRequestFontSize(), IntRebaseList(), IntRegisterShellHookWindow(), IntSendSyncPaint(), IntVideoPortMapMemory(), IntVideoPortResetDisplayParametersEx(), IntVideoPortUnmapMemory(), IOAPICClearPin(), IOAPICMaskIrq(), IOAPICUnmaskIrq(), IopReinitializeBootDrivers(), IopReinitializeDrivers(), IopStartNextPacket(), IopStartNextPacketByKey(), IoRegisterFsRegistrationChange(), IoRegisterLastChanceShutdownNotification(), IoRegisterPlugPlayNotification(), IoRegisterShutdownNotification(), IoUnregisterPlugPlayNotification(), IsaFdoRemoveDevice(), IsaPdoQueryId(), IsaPnpRemoveLogicalDeviceDO(), IsaReadPortRemoveDevice(), IsBlockFromHeap(), IsThereAChildOpened(), kbd_c(), KdbpAttachToProcess(), KdbpCmdProc(), KdbpCmdThread(), KeInsertHeadQueue(), KeInsertQueue(), KeQueryInterruptHandler(), KeRegisterInterruptHandler(), KeSetBaseGdtSelector(), KeSetGdtSelector(), KeTerminateThread(), KiDoBugCheckCallbacks(), KiGetGdtDescriptorBase(), KiGetVectorDispatch(), KiInitGdtEntry(), KiInitializeKernel(), KiInitModuleList(), KiInitSystem(), KiInsertQueue(), KiPcToFileHeader(), KiRosPcToUserFileHeader(), KiSetGdtDescriptorBase(), KiSetGdtDescriptorLimit(), KiSetGdtEntry(), KiSetGdtEntryEx(), KmtCleanUsermodeCallbacks(), KsCancelIo(), KsCopyObjectBagItems(), KsCreateBusEnumObject(), KsFilterFactoryGetSymbolicLink(), KsFilterFactoryUpdateCacheData(), KsFreeObjectBag(), KspAddCreateItemToList(), KspAddObjectCreateItemToList(), KspBusWorkerRoutine(), KspCompletePendingIrps(), KspCreateDeviceAssociation(), KspCreateDeviceReference(), KspDisableEvent(), KspEnableBusDeviceInterface(), KspFindObjectBagItem(), KspFreeCreateItems(), KspFreeDeviceInterfaces(), KspFreeEventList(), KspGetObjectItemReferenceCount(), KspInstallBusEnumInterface(), KspQueryBusRelations(), KspRemoveDeviceAssociations(), KspSetDeviceInterfacesState(), KspSetFilterFactoriesState(), KsServiceBusEnumCreateRequest(), LdrpClearLoadInProgress(), LdrpCompareResourceNames_U(), LdrpFinalizeAndDeallocateDataTableEntry(), LdrpGetProcedureAddress(), LdrpSendDllNotifications(), LdrpUpdateLoadCount3(), LdrQueryProcessModuleInformationEx(), LdrUnregisterDllNotification(), LibTCPDequeuePacket(), LibTCPEmptyQueue(), LineInputKeyDown(), LineInputRecallHistory(), ListDisk(), ListPartition(), ListVolume(), LlbAllocateMemoryEntry(), LocalEnumMonitors(), LocalEnumPorts(), LocalmonEnumPorts(), LocalmonShutdown(), LpcpDeletePort(), LpcpDestroyPortQueue(), LpcpFindDataInfoMessage(), LpcpFreeDataInfoMessage(), LsapEnumLogonSessions(), LsapGetAuthenticationPackage(), LsapGetLogonSession(), LsapGetNotificationEntry(), LsapLookupAuthenticationPackage(), LsapNotifyPolicyChange(), LsapTerminateLogon(), MemCleanup(), MemInstallFastMemoryHook(), MempAllocatePTE(), MempSetupPaging(), MempUnmapPage(), MiCacheEvictPages(), MiFreeSegmentPage(), MiInsertInSystemSpace(), MiniportHandleInterrupt(), MiProtectedPoolInsertList(), MiProtectedPoolRemoveEntryList(), MiPurgeImageSegment(), MiRemoveFromSystemSpace(), MiRosTrimCache(), MiShutdownSystem(), MiUnlinkFreeOrZeroedPage(), MmAccessFaultSectionView(), MmAllocateSpecialPool(), MmAlterViewAttributes(), MmFlushSegment(), MmFreeCacheSectionPage(), MmFreeLoaderBlock(), MmFreePageTablesSectionSegment(), MmFreeSectionPage(), MmFreeSwapPage(), MmGetPageProtect(), MmGetPageTableForProcess(), MmGetPageTableForProcessForPAE(), MmGetPfnForProcess(), MmGetPhysicalMemoryRanges(), MmIsDataSectionResident(), MmIsPageSwapEntry(), MMixerGetDataByDeviceId(), MMixerGetDataByDeviceName(), MMixerGetLineControls(), MMixerGetMidiInfoByIndexAndType(), MMixerGetMixerByName(), MMixerGetMixerControlById(), MMixerGetMixerDataByDeviceHandle(), MMixerGetMixerInfoByIndex(), MMixerGetMixerLineContainingNodeId(), MMixerGetSourceMixerLineByComponentType(), MMixerGetSourceMixerLineByLineId(), MMixerGetWaveInfoByIndexAndType(), MMixerInitialize(), MMixerNotifyControlChange(), MMixerPrintMixerLineControls(), MMixerRemoveEvent(), MmMakeSegmentDirty(), MmMakeSegmentResident(), MmNotPresentFaultSectionView(), MmPageOutCacheSection(), MmPageOutPhysicalAddress(), MmpFreePageFileSegment(), MmPurgeSegment(), MmSharePageEntrySectionSegment(), MmTrimUserMemory(), MmUnsharePageEntrySectionSegment(), MmWithdrawSectionPage(), MountMgrQueryDosVolumePaths(), MountMgrQueryVolumePaths(), MountMgrVolumeMountPointDeleted(), MsfsRead(), MupCheckForUnregisteredProvider(), MupCleanupFcb(), MupForwardIoRequest(), MupInvalidatePrefixTable(), nfs41_DevFcbXXXControlFile(), NlsUninit(), Normalize(), NpFindPrefix(), NSProviderInfoFromContext(), NSProvidersEnumerationProc(), NtGetPlugPlayEvent(), NtLdrDetectBootVid(), NtQueryDirectoryObject(), NtReplyWaitReceivePortEx(), ObpDeferObjectDeletion(), OpenPrinterW(), Pc98VidSetColorRegisters(), PcCreateItemDispatch(), PcCreatePinDispatch(), PciBuildHackTable(), PciGetDescriptionMessage(), PciInsertEntryAtHead(), PcIoTimerRoutine(), PcNewRegistryKey(), PcRegisterIoTimeout(), PcUnregisterIoTimeout(), PeLdrFreeDataTableEntry(), PiDereferencePnpNotifyEntry(), PiReferencePnpNotifyEntry(), PopCircularBufferEntry(), PortDeleteDriverInitData(), PortGetDriverInitData(), PrepareCopyInfFile(), FxTransactionedList::ProcessAdd(), ProtocolEnumerationProc(), ProviderEnumerationProc(), PsGetNextProcess(), PsGetNextProcessThread(), PushCircularBufferEntry(), PushEntryList(), PushEntryListWrapper(), ReadVolumeLabel(), ReconcileThisDatabaseWithMasterWorker(), FxChildList::ReenumerateEntry(), FxChildList::ReenumerateEntryLocked(), RegisterConnection(), RegisterUncProvider(), RegShutdownRegistry(), FxTransactionedList::Remove(), RemoveCachedEntry(), FxCollectionInternal::RemoveEntry(), RemoveEntryList(), RemoveEntryListUnsafe(), RemoveHeadList(), FxTransactionedList::RemoveLocked(), RemoveTailList(), RetrieveTimeZone(), rsym_parse(), RtlAddAtomToAtomTable(), RtlAddRange(), RtlCopyRangeList(), RtlDeleteAtomFromAtomTable(), RtlDeleteOwnersRanges(), RtlDeleteRange(), RtlDestroyHeap(), RtlFindRange(), RtlFindUnicodePrefix(), RtlFreeRangeList(), RtlInsertUnicodePrefix(), RtlInvertRangeList(), RtlIsRangeAvailable(), RtlLookupAtomInAtomTable(), RtlNextUnicodePrefix(), RtlpAllocAtomTableEntry(), RtlpCheckListEntry(), RtlpCreateAtomHandle(), RtlpCreateUnCommittedRange(), RtlPcToFileHeader(), RtlpFreeAtomHandle(), RtlpFreeAtomTableEntry(), RtlpGetAtomEntry(), RtlPinAtomInAtomTable(), RtlpIsLastCommittedEntry(), RtlpValidateHeap(), RtlQueryAtomInAtomTable(), RtlRemoveUnicodePrefix(), RxCancelNotifyChangeDirectoryRequestsForFobx(), RxCancelNotifyChangeDirectoryRequestsForVNetRoot(), RxCancelRoutine(), RxFinalizeConnection(), RxFinalizeNetFcb(), RxGatherRequestsForSrvOpen(), RxIsOkToPurgeFcb(), RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpScavengeFobxs(), RxPurgeRelatedFobxs(), RxRemoveOverflowEntry(), RxRemovePrefixTableEntry(), RxScavengeFobxsForNetRoot(), RxTableLookupName(), RxTableLookupName_ExactLengthMatch(), ScanForUnpartitionedDiskSpace(), ScanForUnpartitionedGptDiskSpace(), ScanForUnpartitionedMbrDiskSpace(), ScrollDownGenericList(), ScrollToPositionGenericList(), ScrollUpGenericList(), ScsiPortDispatchScsi(), SeiResetEntryProcessed(), SeiSetEntryProcessed(), SelectDisk(), SelectPartition(), SelectVolume(), SetCurrentListEntry(), SetLocalTimeZone(), SetMountedDeviceValues(), SetPortW(), SetupCloseFileQueue(), SetupCommitFileQueueW(), SetupDeleteQueueEntry(), SetupQueueCopyWithCab(), SetupQueueDeleteW(), SetupQueueRenameW(), ShimLib_NotifyShims(), ShowTimeZoneList(), SmpCheckDuplicateMuSessionId(), SmpCreatePagingFileDescriptor(), SmpCreatePagingFileOnAnyDrive(), SmpCreatePagingFiles(), SmpFindRegistryValue(), SmpInitializeDosDevices(), SmpInitializeKnownDlls(), SmpInitializeKnownDllsInternal(), SmpLoadDataFromRegistry(), SmpLoadDeferedSubsystem(), SmpLoadSubSystemsForMuSession(), SmpLocateKnownSubSysByCid(), SmpLocateKnownSubSysByType(), SmpProcessFileRenames(), SmpSaveRegistryValue(), SmpSearchVolumeDescriptor(), SmpSessionIdToSession(), SpiGetNextRequestFromLun(), START_TEST(), StreamClassReleaseResources(), sys_arch_mbox_fetch(), SysAudio_Shutdown(), SysAudioHandleProperty(), SysAudioOpenVirtualDevice(), TCPAbortListenForSocket(), TCPAcceptEventHandler(), TCPConnectEventHandler(), TCPRecvEventHandler(), TCPRemoveIRP(), TCPSendEventHandler(), Test_FontSelectionEntry(), Test_GetFiles(), Test_GetFontResourceInfoW_case0(), Test_GetFontResourceInfoW_case1(), Test_GetFontResourceInfoW_case2(), test_table(), ThirdPartyVDDBop(), TrimWsList(), UDFCloseAllDelayed(), UDFCommonDispatch(), UDFDelayedClose(), UmaDescReallocate(), UmaDescRelease(), UmaDescReserve(), UmaMgrCleanup(), FxChildList::UpdateAddressDescriptionFromEntry(), UpdateAutoDaylightCheckbox(), UpdateDiskSignatures(), UpdateDstCheckbox(), FxCmResList::UpdateRegisterResourceEntryLocked(), UpdateRegistry(), USB2_Rebalance(), USB2_RebalanceEndpoint(), USBCCGP_PDOSelectConfiguration(), USBH_FdoQueryBusRelations(), USBH_FlushPortPwrList(), USBPORT_CancelActiveTransferIrp(), USBPORT_DmaEndpointActive(), USBPORT_DmaEndpointPaused(), USBPORT_DpcHandler(), USBPORT_EndpointHasQueuedTransfers(), USBPORT_FindCompanionControllers(), USBPORT_FlushAbortList(), USBPORT_FlushAllEndpoints(), USBPORT_FlushController(), USBPORT_GetTt(), USBPORT_InvalidateEndpointHandler(), USBPORT_MiniportCompleteTransfer(), USBPORT_RH_SetFeatureUSB2PortPower(), USBPORT_RootHubPowerAndChirpAllCcPorts(), USBPORT_SynchronizeRootHubCallback(), USBSTOR_RemoveIrp(), UserDerefObjectCo(), UserDestroyObjectsForOwner(), UserpGetClientFileName(), VBESetColorRegisters(), VDDBlockUserHook(), VDDCreateUserHook(), VDDDeInstallUserHook(), VDDInstallMemoryHook(), VDDResumeUserHook(), VDDTerminateUserHook(), verify_mru_(), FxChildList::VerifyDescriptionEntry(), FxChildList::VerifyModificationEntry(), VfatCloseWorker(), VfatRenameChildFCB(), VgaWriteAc(), VgaWriteDac(), VideoPortFreeCommonBuffer(), VideoPortGetCommonBuffer(), WdmAudGetMixerEvent(), WdmAudOpenSysAudioDeviceInterfaces(), WdmAudOpenSysAudioDevices(), WhoamiSetTable(), WhoamiSetTableDyn(), WorkerThread(), WorkItemRoutine(), WPUModifyIFSHandle(), WPUQueryBlockingCallback(), WritePartitionsToDisk(), WriteRemoteDatabaseEntry(), WsAsyncCancelRequest(), WsAsyncThread(), WsNcDelete(), WsNcEntrySetProvider(), WsNcEnumerateCatalogItems(), WsNcGetCatalogFromProviderId(), WsNcRefreshFromRegistry(), WsNcRemoveCatalogItem(), WsNcUpdateNamespaceList(), WsNqBeginEnumerationProc(), WsNqDelete(), WsNqLookupServiceBegin(), WsNqLookupServiceEnd(), WsNqLookupServiceNext(), WsNqNextProvider(), WsNqPreviousProvider(), WsTcDelete(), WsTcEntrySetProvider(), WsTcEnumerateCatalogItems(), WsTcFindIfsProviderForSocket(), WsTcFindProvider(), WsTcGetEntryFromAf(), WsTcGetEntryFromCatalogEntryId(), WsTcGetEntryFromTriplet(), WsTcRefreshFromRegistry(), WsTcRemoveCatalogItem(), WsTcUpdateProtocolList(), xHalIoReadPartitionTable(), xHalIoSetPartitionInformation(), and xHalIoWritePartitionTable().

◆ ExeFmtpLoaders

PEXEFMT_LOADER ExeFmtpLoaders[]
static
Initial value:
=
{
}
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)
Definition: section.c:287

Definition at line 2613 of file section.c.

Referenced by ExeFmtpCreateImageSection().

◆ FALSE

return FALSE

Definition at line 5371 of file section.c.

◆ ForceDirty

PLARGE_INTEGER BOOLEAN ForceDirty

Definition at line 5203 of file section.c.

◆ MmMakeFileAccess

ACCESS_MASK MmMakeFileAccess[8]
extern

Definition at line 32 of file section.c.

Referenced by MmCreateArm3Section(), and MmCreateSection().

◆ MmpSectionMapping

GENERIC_MAPPING MmpSectionMapping
static
Initial value:
=
{
}
#define SECTION_MAP_READ
Definition: compat.h:139
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1293
#define SECTION_MAP_WRITE
Definition: nt_native.h:1291
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67

Definition at line 225 of file section.c.

Referenced by MmInitSectionImplementation().

◆ MmSectionObjectType

◆ MmSession

◆ MmSubsectionBase

ULONG_PTR MmSubsectionBase

Definition at line 198 of file section.c.

Referenced by MI_MAKE_SUBSECTION_PTE(), and MiInitMachineDependent().

◆ MmWaitPageEvent

KEVENT MmWaitPageEvent

Definition at line 64 of file section.c.

Referenced by MmInitSystem().

◆ Offset

◆ Page

◆ PageOut

Initial value:

Definition at line 5204 of file section.c.

Referenced by MmUnsharePageEntrySectionSegment().

◆ SectionCharacteristicsToProtect

◆ Status

Definition at line 5207 of file section.c.

◆ TinyTime