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

Go to the source code of this file.

Classes

struct  MM_SECTION_PAGEOUT_CONTEXT
 

Macros

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

Functions

NTSTATUS NTAPI MiMapViewInSystemSpace (IN PVOID Section, IN PVOID Session, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
 
NTSTATUS NTAPI MmCreateArm3Section (OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER InputMaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
 
NTSTATUS NTAPI MmMapViewOfArm3Section (IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
 
 C_ASSERT (EXEFMT_LOAD_HEADER_SIZE >=sizeof(IMAGE_DOS_HEADER))
 
 C_ASSERT (sizeof(IMAGE_NT_HEADERS32)<=sizeof(IMAGE_NT_HEADERS64))
 
 C_ASSERT (TYPE_ALIGNMENT(IMAGE_NT_HEADERS32)==TYPE_ALIGNMENT(IMAGE_NT_HEADERS64))
 
 C_ASSERT (RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)==RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS64, FileHeader))
 
 C_ASSERT (FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)==FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Magic))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SectionAlignment))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, FileAlignment))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Subsystem))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, AddressOfEntryPoint))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfCode))
 
 C_ASSERT (PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfHeaders))
 
ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask (IN ACCESS_MASK SectionPageProtection)
 
NTSTATUS NTAPI 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 MmFreeSectionSegments (PFILE_OBJECT FileObject)
 
VOID NTAPI MmSharePageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
 
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment (PROS_SECTION_OBJECT Section, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
 
BOOLEAN MiIsPageFromCache (PMEMORY_AREA MemoryArea, LONGLONG SegOffset)
 
NTSTATUS NTAPI MiCopyFromUserPage (PFN_NUMBER DestPage, const VOID *SrcAddress)
 
NTSTATUS NTAPI MiReadPage (PMEMORY_AREA MemoryArea, LONGLONG SegOffset, PPFN_NUMBER Page)
 
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)
 
VOID MmPageOutDeleteMapping (PVOID Context, PEPROCESS Process, PVOID Address)
 
NTSTATUS NTAPI MmPageOutSectionView (PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, ULONG_PTR Entry)
 
NTSTATUS NTAPI MmWritePageSectionView (PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PVOID Address, ULONG PageEntry)
 
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 MmpFreePageFileSegment (PMM_SECTION_SEGMENT Segment)
 
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 INIT_FUNCTION NTAPI MmCreatePhysicalMemorySection (VOID)
 
NTSTATUS INIT_FUNCTION NTAPI MmInitSectionImplementation (VOID)
 
NTSTATUS NTAPI MmCreatePageFileSection (PROS_SECTION_OBJECT *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes)
 
NTSTATUS NTAPI MmCreateDataFileSection (PROS_SECTION_OBJECT *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
 
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 (PROS_SECTION_OBJECT *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
 
static NTSTATUS MmMapViewOfSegment (PMMSUPPORT AddressSpace, PROS_SECTION_OBJECT Section, PMM_SECTION_SEGMENT Segment, PVOID *BaseAddress, SIZE_T ViewSize, ULONG Protect, ULONG ViewOffset, ULONG AllocationType)
 
static VOID MmFreeSectionPage (PVOID Context, MEMORY_AREA *MemoryArea, PVOID Address, PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
 
static NTSTATUS MmUnmapViewOfSegment (PMMSUPPORT AddressSpace, PVOID BaseAddress)
 
NTSTATUS NTAPI MiRosUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
 
NTSTATUS NTAPI NtQuerySection (_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T SectionInformationLength, _Out_opt_ PSIZE_T ResultLength)
 
NTSTATUS NTAPI MmMapViewOfSection (IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
 
BOOLEAN NTAPI MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN PLARGE_INTEGER NewFileSize)
 
BOOLEAN NTAPI MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
 
NTSTATUS NTAPI MmMapViewInSystemSpace (IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
 
NTSTATUS NTAPI 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)
 

Variables

MMSESSION MmSession
 
POBJECT_TYPE MmSectionObjectType = NULL
 
ULONG_PTR MmSubsectionBase
 
static ULONG SectionCharacteristicsToProtect [16]
 
ULONG MmMakeFileAccess []
 
static GENERIC_MAPPING MmpSectionMapping
 
static PEXEFMT_LOADER ExeFmtpLoaders []
 

Macro Definition Documentation

◆ DIE

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

Referenced by PeFmtCreateSection().

◆ MmSetPageEntrySectionSegment

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

Definition at line 62 of file section.c.

Referenced by MmNotPresentFaultSectionView(), MmPageOutSectionView(), MmpFreePageFileSegment(), MmSharePageEntrySectionSegment(), MmUnsharePageEntrySectionSegment(), and MmWritePageSectionView().

◆ NDEBUG

#define NDEBUG

Definition at line 50 of file section.c.

Function Documentation

◆ C_ASSERT() [1/14]

C_ASSERT ( EXEFMT_LOAD_HEADER_SIZE >=  sizeofIMAGE_DOS_HEADER)

◆ C_ASSERT() [2/14]

◆ C_ASSERT() [3/14]

◆ C_ASSERT() [4/14]

◆ C_ASSERT() [5/14]

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

◆ C_ASSERT() [6/14]

◆ C_ASSERT() [7/14]

◆ C_ASSERT() [8/14]

◆ C_ASSERT() [9/14]

◆ C_ASSERT() [10/14]

C_ASSERT ( PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion)  )

◆ C_ASSERT() [11/14]

C_ASSERT ( PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion)  )

◆ C_ASSERT() [12/14]

◆ C_ASSERT() [13/14]

◆ C_ASSERT() [14/14]

◆ 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 
)

Referenced by MmCreateDataFileSection().

◆ ExeFmtpAllocateSegments()

static PMM_SECTION_SEGMENT NTAPI ExeFmtpAllocateSegments ( IN ULONG  NrSegments)
static

Definition at line 3135 of file section.c.

Referenced by ExeFmtpCreateImageSection().

3136 {
3137  SIZE_T SizeOfSegments;
3138  PMM_SECTION_SEGMENT Segments;
3139 
3140  /* TODO: check for integer overflow */
3141  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments;
3142 
3144  SizeOfSegments,
3146 
3147  if(Segments)
3148  RtlZeroMemory(Segments, SizeOfSegments);
3149 
3150  return Segments;
3151 }
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
struct _MM_SECTION_SEGMENT MM_SECTION_SEGMENT
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261

◆ ExeFmtpCreateImageSection()

NTSTATUS ExeFmtpCreateImageSection ( PFILE_OBJECT  FileObject,
PMM_IMAGE_SECTION_OBJECT  ImageSectionObject 
)

Definition at line 3577 of file section.c.

Referenced by MmCreateImageSection().

3579 {
3581  PVOID FileHeader;
3582  PVOID FileHeaderBuffer;
3583  ULONG FileHeaderSize;
3584  ULONG Flags;
3585  ULONG OldNrSegments;
3586  NTSTATUS Status;
3587  ULONG i;
3588 
3589  /*
3590  * Read the beginning of the file (2 pages). Should be enough to contain
3591  * all (or most) of the headers
3592  */
3593  Offset.QuadPart = 0;
3594 
3595  Status = ExeFmtpReadFile (FileObject,
3596  &Offset,
3597  PAGE_SIZE * 2,
3598  &FileHeader,
3599  &FileHeaderBuffer,
3600  &FileHeaderSize);
3601 
3602  if (!NT_SUCCESS(Status))
3603  return Status;
3604 
3605  if (FileHeaderSize == 0)
3606  {
3607  ExFreePool(FileHeaderBuffer);
3608  return STATUS_UNSUCCESSFUL;
3609  }
3610 
3611  /*
3612  * Look for a loader that can handle this executable
3613  */
3614  for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
3615  {
3616  RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject));
3617  Flags = 0;
3618 
3619  Status = ExeFmtpLoaders[i](FileHeader,
3620  FileHeaderSize,
3621  FileObject,
3622  ImageSectionObject,
3623  &Flags,
3626 
3627  if (!NT_SUCCESS(Status))
3628  {
3629  if (ImageSectionObject->Segments)
3630  {
3631  ExFreePool(ImageSectionObject->Segments);
3632  ImageSectionObject->Segments = NULL;
3633  }
3634  }
3635 
3636  if (Status != STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
3637  break;
3638  }
3639 
3640  ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
3641 
3642  /*
3643  * No loader handled the format
3644  */
3645  if (Status == STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
3646  {
3647  Status = STATUS_INVALID_IMAGE_NOT_MZ;
3648  ASSERT(!NT_SUCCESS(Status));
3649  }
3650 
3651  if (!NT_SUCCESS(Status))
3652  return Status;
3653 
3654  ASSERT(ImageSectionObject->Segments != NULL);
3655 
3656  /*
3657  * Some defaults
3658  */
3659  /* FIXME? are these values platform-dependent? */
3660  if (ImageSectionObject->ImageInformation.MaximumStackSize == 0)
3661  ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000;
3662 
3663  if(ImageSectionObject->ImageInformation.CommittedStackSize == 0)
3664  ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000;
3665 
3666  if(ImageSectionObject->BasedAddress == NULL)
3667  {
3668  if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3669  ImageSectionObject->BasedAddress = (PVOID)0x10000000;
3670  else
3671  ImageSectionObject->BasedAddress = (PVOID)0x00400000;
3672  }
3673 
3674  /*
3675  * And now the fun part: fixing the segments
3676  */
3677 
3678  /* Sort them by virtual address */
3679  MmspSortSegments(ImageSectionObject, Flags);
3680 
3681  /* Ensure they don't overlap in memory */
3682  if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
3684 
3685  /* Ensure they are aligned */
3686  OldNrSegments = ImageSectionObject->NrSegments;
3687 
3688  if (!MmspPageAlignSegments(ImageSectionObject, Flags))
3690 
3691  /* Trim them if the alignment phase merged some of them */
3692  if (ImageSectionObject->NrSegments < OldNrSegments)
3693  {
3694  PMM_SECTION_SEGMENT Segments;
3695  SIZE_T SizeOfSegments;
3696 
3697  SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
3698 
3699  Segments = ExAllocatePoolWithTag(PagedPool,
3700  SizeOfSegments,
3702 
3703  if (Segments == NULL)
3705 
3706  RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
3707  ExFreePool(ImageSectionObject->Segments);
3708  ImageSectionObject->Segments = Segments;
3709  }
3710 
3711  /* And finish their initialization */
3712  for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
3713  {
3714  ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
3715  ImageSectionObject->Segments[i].ReferenceCount = 1;
3716  MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]);
3717  }
3718 
3719  ASSERT(NT_SUCCESS(Status));
3720  return Status;
3721 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
#define IMAGE_FILE_DLL
Definition: pedump.c:169
static BOOLEAN NTAPI MmspPageAlignSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:3394
static VOID NTAPI MmspSortSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:3317
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLenum GLclampf GLint i
Definition: glfuncs.h:14
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
static PMM_SECTION_SEGMENT NTAPI ExeFmtpAllocateSegments(IN ULONG NrSegments)
Definition: section.c:3135
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:525
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:345
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static PEXEFMT_LOADER ExeFmtpLoaders[]
Definition: section.c:3124
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:3156
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
struct _MM_SECTION_SEGMENT MM_SECTION_SEGMENT
#define STATUS_ROS_EXEFMT_UNKNOWN_FORMAT
Definition: exeformat.h:72
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
static BOOLEAN NTAPI MmspCheckSegmentBounds(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags)
Definition: section.c:3343
LONGLONG QuadPart
Definition: typedefs.h:112

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

Referenced by ExeFmtpCreateImageSection().

3162 {
3163  NTSTATUS Status;
3165  ULONG AdjustOffset;
3166  ULONG OffsetAdjustment;
3167  ULONG BufferSize;
3168  ULONG UsedSize;
3169  PVOID Buffer;
3172 
3174 
3175  if(Length == 0)
3176  {
3177  KeBugCheck(MEMORY_MANAGEMENT);
3178  }
3179 
3180  FileOffset = *Offset;
3181 
3182  /* Negative/special offset: it cannot be used in this context */
3183  if(FileOffset.u.HighPart < 0)
3184  {
3185  KeBugCheck(MEMORY_MANAGEMENT);
3186  }
3187 
3188  AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
3189  OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset;
3190  FileOffset.u.LowPart = AdjustOffset;
3191 
3192  BufferSize = Length + OffsetAdjustment;
3193  BufferSize = PAGE_ROUND_UP(BufferSize);
3194 
3195  /* Flush data since we're about to perform a non-cached read */
3196  CcFlushCache(FileObject->SectionObjectPointer,
3197  &FileOffset,
3198  BufferSize,
3199  &Iosb);
3200 
3201  /*
3202  * It's ok to use paged pool, because this is a temporary buffer only used in
3203  * the loading of executables. The assumption is that MmCreateSection is
3204  * always called at low IRQLs and that these buffers don't survive a brief
3205  * initialization phase
3206  */
3208  BufferSize,
3209  'rXmM');
3210  if (!Buffer)
3211  {
3213  }
3214 
3215  UsedSize = 0;
3216 
3217  Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb);
3218 
3219  UsedSize = (ULONG)Iosb.Information;
3220 
3221  if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
3222  {
3223  Status = STATUS_IN_PAGE_ERROR;
3224  ASSERT(!NT_SUCCESS(Status));
3225  }
3226 
3227  if(NT_SUCCESS(Status))
3228  {
3229  *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
3230  *AllocBase = Buffer;
3231  *ReadSize = UsedSize - OffsetAdjustment;
3232  }
3233  else
3234  {
3235  ExFreePoolWithTag(Buffer, 'rXmM');
3236  }
3237 
3238  return Status;
3239 }
struct _LARGE_INTEGER::@2193 u
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
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
LONG NTSTATUS
Definition: precomp.h:26
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
void * PVOID
Definition: retypes.h:9
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define BufferSize
Definition: classpnp.h:419
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1954
#define ASSERT_IRQL_LESS(x)
Definition: debug.h:258
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:229
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
NTSTATUS NTAPI MiSimpleRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PVOID Buffer, ULONG Length, BOOLEAN Paging, PIO_STATUS_BLOCK ReadStatus)
Definition: io.c:114

◆ MiArm3GetCorrectFileAccessMask()

ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask ( IN ACCESS_MASK  SectionPageProtection)

Definition at line 141 of file section.c.

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

◆ MiCopyFromUserPage()

NTSTATUS NTAPI MiCopyFromUserPage ( PFN_NUMBER  DestPage,
const VOID SrcAddress 
)

Definition at line 1043 of file section.c.

Referenced by MmAccessFaultSectionView().

1044 {
1046  KIRQL Irql;
1047  PVOID DestAddress;
1048 
1049  Process = PsGetCurrentProcess();
1050  DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
1051  if (DestAddress == NULL)
1052  {
1053  return(STATUS_NO_MEMORY);
1054  }
1055  ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
1056  ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
1057  RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
1058  MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
1059  return(STATUS_SUCCESS);
1060 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_Out_ PKIRQL Irql
Definition: csq.h:179
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:30
smooth NULL
Definition: ftsmooth.c:416
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:93
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
return STATUS_SUCCESS
Definition: btrfs.c:2710

◆ MiIsPageFromCache()

BOOLEAN MiIsPageFromCache ( PMEMORY_AREA  MemoryArea,
LONGLONG  SegOffset 
)

Definition at line 1021 of file section.c.

Referenced by MmPageOutSectionView().

1023 {
1024 #ifndef NEWCC
1025  if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
1026  {
1027  PROS_SHARED_CACHE_MAP SharedCacheMap;
1028  PROS_VACB Vacb;
1029  SharedCacheMap = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
1030  Vacb = CcRosLookupVacb(SharedCacheMap, SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset);
1031  if (Vacb)
1032  {
1033  CcRosReleaseVacb(SharedCacheMap, Vacb, Vacb->Valid, FALSE, TRUE);
1034  return TRUE;
1035  }
1036  }
1037 #endif
1038  return FALSE;
1039 }
#define TRUE
Definition: types.h:120
Definition: cc.h:202
union _MEMORY_AREA::@1717 Data
NTSTATUS NTAPI CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Valid, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:412
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
struct _MEMORY_AREA::@1717::@1718 SectionData
BOOLEAN Valid
Definition: cc.h:209
PROS_VACB NTAPI CcRosLookupVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset)
Definition: view.c:449

◆ MiMapViewInSystemSpace()

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

◆ MiReadPage()

NTSTATUS NTAPI MiReadPage ( PMEMORY_AREA  MemoryArea,
LONGLONG  SegOffset,
PPFN_NUMBER  Page 
)

Definition at line 1065 of file section.c.

Referenced by MmNotPresentFaultSectionView().

1075 {
1076  LONGLONG BaseOffset;
1079  BOOLEAN UptoDate;
1080  PROS_VACB Vacb;
1082  NTSTATUS Status;
1083  LONGLONG RawLength;
1084  PROS_SHARED_CACHE_MAP SharedCacheMap;
1085  BOOLEAN IsImageSection;
1086  LONGLONG Length;
1087 
1088  FileObject = MemoryArea->Data.SectionData.Section->FileObject;
1089  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
1090  RawLength = MemoryArea->Data.SectionData.Segment->RawLength.QuadPart;
1091  FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset;
1092  IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
1093 
1094  ASSERT(SharedCacheMap);
1095 
1096  DPRINT("%S %I64x\n", FileObject->FileName.Buffer, FileOffset);
1097 
1098  /*
1099  * If the file system is letting us go directly to the cache and the
1100  * memory area was mapped at an offset in the file which is page aligned
1101  * then get the related VACB.
1102  */
1103  if (((FileOffset % PAGE_SIZE) == 0) &&
1104  ((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) &&
1105  !(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
1106  {
1107 
1108  /*
1109  * Get the related VACB; we use a lower level interface than
1110  * filesystems do because it is safe for us to use an offset with an
1111  * alignment less than the file system block size.
1112  */
1113  Status = CcRosGetVacb(SharedCacheMap,
1114  FileOffset,
1115  &BaseOffset,
1116  &BaseAddress,
1117  &UptoDate,
1118  &Vacb);
1119  if (!NT_SUCCESS(Status))
1120  {
1121  return(Status);
1122  }
1123  if (!UptoDate)
1124  {
1125  /*
1126  * If the VACB isn't up to date then call the file
1127  * system to read in the data.
1128  */
1129  Status = CcReadVirtualAddress(Vacb);
1130  if (!NT_SUCCESS(Status))
1131  {
1132  CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
1133  return Status;
1134  }
1135  }
1136 
1137  /* Probe the page, since it's PDE might not be synced */
1138  (void)*((volatile char*)BaseAddress + FileOffset - BaseOffset);
1139 
1140  /*
1141  * Retrieve the page from the view that we actually want.
1142  */
1143  (*Page) = MmGetPhysicalAddress((char*)BaseAddress +
1144  FileOffset - BaseOffset).LowPart >> PAGE_SHIFT;
1145 
1146  CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, TRUE);
1147  }
1148  else
1149  {
1151  KIRQL Irql;
1152  PVOID PageAddr;
1153  LONGLONG VacbOffset;
1154 
1155  /*
1156  * Allocate a page, this is rather complicated by the possibility
1157  * we might have to move other things out of memory
1158  */
1160  MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
1161  Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page);
1162  if (!NT_SUCCESS(Status))
1163  {
1164  return(Status);
1165  }
1166  Status = CcRosGetVacb(SharedCacheMap,
1167  FileOffset,
1168  &BaseOffset,
1169  &BaseAddress,
1170  &UptoDate,
1171  &Vacb);
1172  if (!NT_SUCCESS(Status))
1173  {
1174  return(Status);
1175  }
1176  if (!UptoDate)
1177  {
1178  /*
1179  * If the VACB isn't up to date then call the file
1180  * system to read in the data.
1181  */
1182  Status = CcReadVirtualAddress(Vacb);
1183  if (!NT_SUCCESS(Status))
1184  {
1185  CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
1186  return Status;
1187  }
1188  }
1189 
1190  Process = PsGetCurrentProcess();
1191  PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
1192  VacbOffset = BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset;
1193  Length = RawLength - SegOffset;
1194  if (Length <= VacbOffset && Length <= PAGE_SIZE)
1195  {
1196  memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, Length);
1197  }
1198  else if (VacbOffset >= PAGE_SIZE)
1199  {
1200  memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, PAGE_SIZE);
1201  }
1202  else
1203  {
1204  memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, VacbOffset);
1205  MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
1206  CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
1207  Status = CcRosGetVacb(SharedCacheMap,
1208  FileOffset + VacbOffset,
1209  &BaseOffset,
1210  &BaseAddress,
1211  &UptoDate,
1212  &Vacb);
1213  if (!NT_SUCCESS(Status))
1214  {
1215  return(Status);
1216  }
1217  if (!UptoDate)
1218  {
1219  /*
1220  * If the VACB isn't up to date then call the file
1221  * system to read in the data.
1222  */
1223  Status = CcReadVirtualAddress(Vacb);
1224  if (!NT_SUCCESS(Status))
1225  {
1226  CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
1227  return Status;
1228  }
1229  }
1230  PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
1231  if (Length < PAGE_SIZE)
1232  {
1233  memcpy((char*)PageAddr + VacbOffset, BaseAddress, Length - VacbOffset);
1234  }
1235  else
1236  {
1237  memcpy((char*)PageAddr + VacbOffset, BaseAddress, PAGE_SIZE - VacbOffset);
1238  }
1239  }
1240  MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
1241  CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
1242  }
1243  return(STATUS_SUCCESS);
1244 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
Definition: cc.h:202
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
#define MC_USER
Definition: mm.h:94
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:229
_Out_ PKIRQL Irql
Definition: csq.h:179
NTSTATUS NTAPI CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PLONGLONG BaseOffset, PVOID *BaseAddress, PBOOLEAN UptoDate, PROS_VACB *Vacb)
Definition: view.c:930
UCHAR KIRQL
Definition: env_spec_w32.h:591
union _MEMORY_AREA::@1717 Data
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:30
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
#define MI_SET_USAGE(x)
Definition: mm.h:253
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
int64_t LONGLONG
Definition: typedefs.h:66
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSTATUS NTAPI CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Valid, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:412
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1954
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:93
ULONG LowPart
Definition: typedefs.h:104
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:24
struct _MEMORY_AREA::@1717::@1718 SectionData
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define VACB_MAPPING_GRANULARITY
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define SEC_IMAGE
Definition: mmtypes.h:96
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:682
return STATUS_SUCCESS
Definition: btrfs.c:2710
NTSTATUS NTAPI CcReadVirtualAddress(PROS_VACB Vacb)
Definition: copy.c:81

◆ MiRosUnmapViewInSystemSpace()

NTSTATUS NTAPI MiRosUnmapViewInSystemSpace ( IN PVOID  MappedBase)

Definition at line 4895 of file section.c.

Referenced by MiQueryPageTableReferences(), and MmUnmapViewInSystemSpace().

4896 {
4898  NTSTATUS Status;
4899 
4900  DPRINT("MmUnmapViewInSystemSpace() called\n");
4901 
4902  AddressSpace = MmGetKernelAddressSpace();
4903 
4904  MmLockAddressSpace(AddressSpace);
4905 
4906  Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
4907 
4908  MmUnlockAddressSpace(AddressSpace);
4909 
4910  return Status;
4911 }
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1410
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:4066
void DPRINT(...)
Definition: polytest.cpp:61
Status
Definition: gdiplustypes.h:24
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1432
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:493
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1403

◆ MiRosUnmapViewOfSection()

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

Definition at line 4131 of file section.c.

Referenced by MiQueryPageTableReferences(), MiRosCleanupMemoryArea(), and MiUnmapViewOfSection().

4134 {
4135  NTSTATUS Status;
4138  PROS_SECTION_OBJECT Section;
4139  PVOID ImageBaseAddress = 0;
4140 
4141  DPRINT("Opening memory area Process %p BaseAddress %p\n",
4142  Process, BaseAddress);
4143 
4144  ASSERT(Process);
4145 
4146  AddressSpace = Process ? &Process->Vm : MmGetKernelAddressSpace();
4147 
4148  MmLockAddressSpace(AddressSpace);
4149  MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
4150  BaseAddress);
4151  if (MemoryArea == NULL ||
4152  ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) &&
4153  (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
4154  MemoryArea->DeleteInProgress)
4155  {
4156  if (MemoryArea) ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
4157  MmUnlockAddressSpace(AddressSpace);
4158  return STATUS_NOT_MAPPED_VIEW;
4159  }
4160 
4161  Section = MemoryArea->Data.SectionData.Section;
4162 
4163  if ((Section != NULL) && (Section->AllocationAttributes & SEC_IMAGE))
4164  {
4165  ULONG i;
4166  ULONG NrSegments;
4167  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
4168  PMM_SECTION_SEGMENT SectionSegments;
4170 
4171  Segment = MemoryArea->Data.SectionData.Segment;
4172  ImageSectionObject = Section->ImageSection;
4173  SectionSegments = ImageSectionObject->Segments;
4174  NrSegments = ImageSectionObject->NrSegments;
4175 
4176  MemoryArea->DeleteInProgress = TRUE;
4177 
4178  /* Search for the current segment within the section segments
4179  * and calculate the image base address */
4180  for (i = 0; i < NrSegments; i++)
4181  {
4182  if (Segment == &SectionSegments[i])
4183  {
4184  ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
4185  break;
4186  }
4187  }
4188  if (i >= NrSegments)
4189  {
4190  KeBugCheck(MEMORY_MANAGEMENT);
4191  }
4192 
4193  for (i = 0; i < NrSegments; i++)
4194  {
4195  PVOID SBaseAddress = (PVOID)
4196  ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
4197 
4198  Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
4199  if (!NT_SUCCESS(Status))
4200  {
4201  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
4202  SBaseAddress, Process, Status);
4203  ASSERT(NT_SUCCESS(Status));
4204  }
4205  }
4206  }
4207  else
4208  {
4209  Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
4210  if (!NT_SUCCESS(Status))
4211  {
4212  DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
4213  BaseAddress, Process, Status);
4214  ASSERT(NT_SUCCESS(Status));
4215  }
4216  }
4217 
4218  MmUnlockAddressSpace(AddressSpace);
4219 
4220  /* Notify debugger */
4221  if (ImageBaseAddress && !SkipDebuggerNotify) DbgkUnMapViewOfSection(ImageBaseAddress);
4222 
4223  return(STATUS_SUCCESS);
4224 }
struct _MM_SECTION_SEGMENT::@1714 Image
#define TRUE
Definition: types.h:120
ULONG Type
Definition: mm.h:214
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1410
LONG NTSTATUS
Definition: precomp.h:26
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MEMORY_AREA_CACHE
Definition: mm.h:72
uint32_t ULONG_PTR
Definition: typedefs.h:63
static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: section.c:4066
PMM_IMAGE_SECTION_OBJECT ImageSection
Definition: mm.h:202
GLenum GLclampf GLint i
Definition: glfuncs.h:14
union _MEMORY_AREA::@1717 Data
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:73
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
void * PVOID
Definition: retypes.h:9
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:71
_Inout_ PVOID Segment
Definition: exfuncs.h:893
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
PMM_SECTION_SEGMENT Segments
Definition: mm.h:189
BOOLEAN DeleteInProgress
Definition: mm.h:217
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
Status
Definition: gdiplustypes.h:24
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1432
struct _MEMORY_AREA::@1717::@1718 SectionData
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:248
#define ULONG_PTR
Definition: config.h:101
#define SEC_IMAGE
Definition: mmtypes.h:96
ULONG AllocationAttributes
Definition: mm.h:198
return STATUS_SUCCESS
Definition: btrfs.c:2710
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:65
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1403

◆ MmAccessFaultSectionView()

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

Definition at line 1794 of file section.c.

Referenced by MmpAccessFault().

1797 {
1799  PROS_SECTION_OBJECT Section;
1800  PFN_NUMBER OldPage;
1801  PFN_NUMBER NewPage;
1802  NTSTATUS Status;
1803  PVOID PAddress;
1806  ULONG_PTR Entry;
1807  PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
1808 
1809  DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1810 
1811  /* Make sure we have a page mapping for this address. */
1812  Status = MmNotPresentFaultSectionView(AddressSpace, MemoryArea, Address, TRUE);
1813  if (!NT_SUCCESS(Status))
1814  {
1815  /* This is invalid access ! */
1816  return Status;
1817  }
1818 
1819  /*
1820  * Check if the page has already been set readwrite
1821  */
1822  if (MmGetPageProtect(Process, Address) & PAGE_READWRITE)
1823  {
1824  DPRINT("Address 0x%p\n", Address);
1825  return(STATUS_SUCCESS);
1826  }
1827 
1828  /*
1829  * Find the offset of the page
1830  */
1831  PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1832  Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1833  + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
1834 
1835  Segment = MemoryArea->Data.SectionData.Segment;
1836  Section = MemoryArea->Data.SectionData.Section;
1837  Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
1838  &MemoryArea->Data.SectionData.RegionListHead,
1839  Address, NULL);
1840  ASSERT(Region != NULL);
1841 
1842  /*
1843  * Check if we are doing COW
1844  */
1845  if (!((Segment->WriteCopy) &&
1846  (Region->Protect == PAGE_READWRITE ||
1847  Region->Protect == PAGE_EXECUTE_READWRITE)))
1848  {
1849  DPRINT("Address 0x%p\n", Address);
1850  return(STATUS_ACCESS_VIOLATION);
1851  }
1852 
1853  /* Get the page mapping this section offset. */
1854  MmLockSectionSegment(Segment);
1855  Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
1856 
1857  /* Get the current page mapping for the process */
1858  ASSERT(MmIsPagePresent(Process, PAddress));
1859  OldPage = MmGetPfnForProcess(Process, PAddress);
1860  ASSERT(OldPage != 0);
1861 
1862  if (IS_SWAP_FROM_SSE(Entry) ||
1863  PFN_FROM_SSE(Entry) != OldPage)
1864  {
1865  MmUnlockSectionSegment(Segment);
1866  /* This is a private page. We must only change the page protection. */
1867  MmSetPageProtect(Process, PAddress, Region->Protect);
1868  return(STATUS_SUCCESS);
1869  }
1870 
1871  /*
1872  * Allocate a page
1873  */
1875  if (Process) MI_SET_PROCESS2(Process->ImageFileName);
1876  if (!Process) MI_SET_PROCESS2("Kernel Section");
1877  Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage);
1878  if (!NT_SUCCESS(Status))
1879  {
1880  KeBugCheck(MEMORY_MANAGEMENT);
1881  }
1882 
1883  /*
1884  * Copy the old page
1885  */
1886  NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
1887 
1888  /*
1889  * Unshare the old page.
1890  */
1891  DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
1892  MmDeleteVirtualMapping(Process, PAddress, NULL, NULL);
1893  MmDeleteRmap(OldPage, Process, PAddress);
1894  MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL);
1895  MmUnlockSectionSegment(Segment);
1896 
1897  /*
1898  * Set the PTE to point to the new page
1899  */
1900  Status = MmCreateVirtualMapping(Process,
1901  PAddress,
1902  Region->Protect,
1903  &NewPage,
1904  1);
1905  if (!NT_SUCCESS(Status))
1906  {
1907  DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
1908  KeBugCheck(MEMORY_MANAGEMENT);
1909  return(Status);
1910  }
1911  MmInsertRmap(NewPage, Process, PAddress);
1912 
1913  MiSetPageEvent(Process, Address);
1914  DPRINT("Address 0x%p\n", Address);
1915  return(STATUS_SUCCESS);
1916 }
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
BOOLEAN WriteCopy
Definition: mm.h:170
#define TRUE
Definition: types.h:120
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define MiSetPageEvent(Process, Address)
Definition: newmm.h:43
struct _Entry Entry
Definition: kefuncs.h:640
#define PFN_FROM_SSE(E)
Definition: newmm.h:7
NTSTATUS NTAPI MmCreateVirtualMapping(struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
#define MC_USER
Definition: mm.h:94
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
Definition: mm.h:390
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:229
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3289
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI MmIsPagePresent(struct _EPROCESS *Process, PVOID Address)
union _MEMORY_AREA::@1717 Data
ULONG PFN_NUMBER
Definition: ke.h:8
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSTATUS NTAPI MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
Definition: section.c:1361
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
Definition: section.c:876
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI MmDeleteVirtualMapping(struct _EPROCESS *Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
#define MI_SET_USAGE(x)
Definition: mm.h:253
_Inout_ PVOID Segment
Definition: exfuncs.h:893
ULONG Protect
Definition: mm.h:393
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:111
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define IS_SWAP_FROM_SSE(E)
Definition: newmm.h:8
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
Status
Definition: gdiplustypes.h:24
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
struct _MEMORY_AREA::@1717::@1718 SectionData
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1417
#define DPRINT1
Definition: precomp.h:8
#define MmLockSectionSegment(x)
Definition: newmm.h:276
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
CHAR ImageFileName[16]
Definition: pstypes.h:1257
#define ULONG_PTR
Definition: config.h:101
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
return STATUS_SUCCESS
Definition: btrfs.c:2710
NTSTATUS NTAPI MiCopyFromUserPage(PFN_NUMBER DestPage, const VOID *SrcAddress)
Definition: section.c:1043
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143
LONGLONG QuadPart
Definition: typedefs.h:112
#define PAGE_READWRITE
Definition: nt_native.h:1304

◆ MmAlterViewAttributes()

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

Definition at line 1279 of file section.c.

Referenced by MmNotPresentFaultSectionView(), and MmProtectSectionView().

1286 {
1289  BOOLEAN DoCOW = FALSE;
1290  ULONG i;
1291  PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
1292 
1293  MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
1294  ASSERT(MemoryArea != NULL);
1295  Segment = MemoryArea->Data.SectionData.Segment;
1296  MmLockSectionSegment(Segment);
1297 
1298  if ((Segment->WriteCopy) &&
1300  {
1301  DoCOW = TRUE;
1302  }
1303 
1304  if (OldProtect != NewProtect)
1305  {
1306  for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
1307  {
1308  SWAPENTRY SwapEntry;
1309  PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE);
1311 
1312  /* Wait for a wait entry to disappear */
1313  do
1314  {
1315  MmGetPageFileMapping(Process, Address, &SwapEntry);
1316  if (SwapEntry != MM_WAIT_ENTRY)
1317  break;
1318  MiWaitForPageEvent(Process, Address);
1319  }
1320  while (TRUE);
1321 
1322  /*
1323  * If we doing COW for this segment then check if the page is
1324  * already private.
1325  */
1326  if (DoCOW && MmIsPagePresent(Process, Address))
1327  {
1329  ULONG_PTR Entry;
1330  PFN_NUMBER Page;
1331 
1332  Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
1333  + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
1334  Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
1335  /*
1336  * An MM_WAIT_ENTRY is ok in this case... It'll just count as
1337  * IS_SWAP_FROM_SSE and we'll do the right thing.
1338  */
1339  Page = MmGetPfnForProcess(Process, Address);
1340 
1341  Protect = PAGE_READONLY;
1342  if (IS_SWAP_FROM_SSE(Entry) || PFN_FROM_SSE(Entry) != Page)
1343  {
1344  Protect = NewProtect;
1345  }
1346  }
1347 
1348  if (MmIsPagePresent(Process, Address) || MmIsDisabledPage(Process, Address))
1349  {
1350  MmSetPageProtect(Process, Address,
1351  Protect);
1352  }
1353  }
1354  }
1355 
1356  MmUnlockSectionSegment(Segment);
1357 }
BOOLEAN WriteCopy
Definition: mm.h:170
#define TRUE
Definition: types.h:120
struct _Entry Entry
Definition: kefuncs.h:640
#define PFN_FROM_SSE(E)
Definition: newmm.h:7
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:214
#define MM_WAIT_ENTRY
Definition: mm.h:152
#define MiWaitForPageEvent(Process, Address)
Definition: newmm.h:38
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI MmIsPagePresent(struct _EPROCESS *Process, PVOID Address)
GLenum GLclampf GLint i
Definition: glfuncs.h:14
union _MEMORY_AREA::@1717 Data
ULONG PFN_NUMBER
Definition: ke.h:8
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
VOID NTAPI MmGetPageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
_Inout_ PVOID Segment
Definition: exfuncs.h:893
BOOLEAN NTAPI MmIsDisabledPage(struct _EPROCESS *Process, PVOID Address)
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define IS_SWAP_FROM_SSE(E)
Definition: newmm.h:8
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
struct _MEMORY_AREA::@1717::@1718 SectionData
ULONG_PTR SWAPENTRY
Definition: mm.h:47
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1417
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:683
#define PAGE_READONLY
Definition: compat.h:127
#define MmLockSectionSegment(x)
Definition: newmm.h:276
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:65
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143
LONGLONG QuadPart
Definition: typedefs.h:112
#define PAGE_READWRITE
Definition: nt_native.h:1304

◆ MmCanFileBeTruncated()

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

Definition at line 4718 of file section.c.

Referenced by Ext2SetFileInformation(), Ext2SupersedeOrOverWriteFile(), FatSetPositionInfo(), FFSSetInformation(), FFSSupersedeOrOverWriteFile(), NtfsSetEndOfFile(), open_file(), RfsdSetInformation(), RfsdSupersedeOrOverWriteFile(), RxCommonSetInformation(), set_end_of_file_information(), SetAttributeDataLength(), UDFCommonCreate(), UDFSetAllocationInformation(), UDFSetEOF(), VfatSetAllocationSizeInformation(), and VfatSetInformation().

4720 {
4721  /* Check whether an ImageSectionObject exists */
4722  if (SectionObjectPointer->ImageSectionObject != NULL)
4723  {
4724  DPRINT1("ERROR: File can't be truncated because it has an image section\n");
4725  return FALSE;
4726  }
4727 
4728  if (SectionObjectPointer->DataSectionObject != NULL)
4729  {
4731 
4733  DataSectionObject;
4734 
4735  if (Segment->ReferenceCount != 0)
4736  {
4737 #ifdef NEWCC
4739  CcpLock();
4740  if (SectionObjectPointer->SharedCacheMap && (Segment->ReferenceCount > CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap)))
4741  {
4742  CcpUnlock();
4743  /* Check size of file */
4744  if (SectionObjectPointer->SharedCacheMap)
4745  {
4746  if (!CcGetFileSizes(Segment->FileObject, &FileSizes))
4747  {
4748  return FALSE;
4749  }
4750 
4751  if (NewFileSize->QuadPart <= FileSizes.FileSize.QuadPart)
4752  {
4753  return FALSE;
4754  }
4755  }
4756  }
4757  else
4758  CcpUnlock();
4759 #else
4760  /* Check size of file */
4761  if (SectionObjectPointer->SharedCacheMap)
4762  {
4763  PROS_SHARED_CACHE_MAP SharedCacheMap = SectionObjectPointer->SharedCacheMap;
4764  if (NewFileSize->QuadPart <= SharedCacheMap->FileSize.QuadPart)
4765  {
4766  return FALSE;
4767  }
4768  }
4769 #endif
4770  }
4771  else
4772  {
4773  /* Something must gone wrong
4774  * how can we have a Section but no
4775  * reference? */
4776  DPRINT("ERROR: DataSectionObject without reference!\n");
4777  }
4778  }
4779 
4780  DPRINT("FIXME: didn't check for outstanding write probes\n");
4781 
4782  return TRUE;
4783 }
#define TRUE
Definition: types.h:120
#define CcpLock()
Definition: newcc.h:140
static CC_FILE_SIZES FileSizes
BOOLEAN NTAPI CcGetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:373
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
LARGE_INTEGER FileSize
Definition: cctypes.h:16
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PFILE_OBJECT FileObject
Definition: mm.h:163
_Inout_ PVOID Segment
Definition: exfuncs.h:893
if(!(yy_init))
Definition: macro.lex.yy.c:717
struct _MM_SECTION_SEGMENT * PMM_SECTION_SEGMENT
_In_opt_ PLARGE_INTEGER NewFileSize
Definition: mmfuncs.h:609
ULONG ReferenceCount
Definition: mm.h:166
ULONG NTAPI CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
Definition: fssup.c:270
#define DPRINT1
Definition: precomp.h:8
LARGE_INTEGER FileSize
Definition: cc.h:175
#define CcpUnlock()
Definition: newcc.h:141
LONGLONG QuadPart
Definition: typedefs.h:112

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

Referenced by MmCreateSection().

2419 {
2420  SECTION Section;
2421  PSECTION NewSection;
2422  PSUBSECTION Subsection;
2423  PSEGMENT NewSegment, Segment;
2424  NTSTATUS Status;
2425  PCONTROL_AREA ControlArea;
2426  ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2428  BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2429  KIRQL OldIrql;
2431  BOOLEAN UserRefIncremented = FALSE;
2432  PVOID PreviousSectionPointer;
2433 
2434  /* Make the same sanity checks that the Nt interface should've validated */
2437  SEC_NO_CHANGE)) == 0);
2441  SEC_NOCACHE | SEC_NO_CHANGE))));
2447 
2448  /* Convert section flag to page flag */
2450 
2451  /* Check to make sure the protection is correct. Nt* does this already */
2452  ProtectionMask = MiMakeProtectionMask(SectionPageProtection);
2453  if (ProtectionMask == MM_INVALID_PROTECTION) return STATUS_INVALID_PAGE_PROTECTION;
2454 
2455  /* Check if this is going to be a data or image backed file section */
2456  if ((FileHandle) || (FileObject))
2457  {
2458  /* These cannot be mapped with large pages */
2460 
2461  /* For now, only support the mechanism through a file handle */
2462  ASSERT(FileObject == NULL);
2463 
2464  /* Reference the file handle to get the object */
2466  MmMakeFileAccess[ProtectionMask],
2468  PreviousMode,
2469  (PVOID*)&File,
2470  NULL);
2471  if (!NT_SUCCESS(Status)) return Status;
2472 
2473  /* Make sure Cc has been doing its job */
2474  if (!File->SectionObjectPointer)
2475  {
2476  /* This is not a valid file system-based file, fail */
2477  ObDereferenceObject(File);
2479  }
2480 
2481  /* Image-file backed sections are not yet supported */
2482  ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
2483 
2484  /* Compute the size of the control area, and allocate it */
2485  ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2486  ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2487  if (!ControlArea)
2488  {
2489  ObDereferenceObject(File);
2491  }
2492 
2493  /* Zero it out */
2494  RtlZeroMemory(ControlArea, ControlAreaSize);
2495 
2496  /* Did we get a handle, or an object? */
2497  if (FileHandle)
2498  {
2499  /* We got a file handle so we have to lock down the file */
2500 #if 0
2501  Status = FsRtlAcquireToCreateMappedSection(File, SectionPageProtection);
2502  if (!NT_SUCCESS(Status))
2503  {
2504  ExFreePool(ControlArea);
2505  ObDereferenceObject(File);
2506  return Status;
2507  }
2508 #else
2509  /* ReactOS doesn't support this API yet, so do nothing */
2510  Status = STATUS_SUCCESS;
2511 #endif
2512  /* Update the top-level IRP so that drivers know what's happening */
2514  FileLock = TRUE;
2515  }
2516 
2517  /* Lock the PFN database while we play with the section pointers */
2518  OldIrql = MiAcquirePfnLock();
2519 
2520  /* Image-file backed sections are not yet supported */
2521  ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
2522 
2523  /* There should not already be a control area for this file */
2524  ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2525  NewSegment = NULL;
2526 
2527  /* Write down that this CA is being created, and set it */
2528  ControlArea->u.Flags.BeingCreated = TRUE;
2529  ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
2530  PreviousSectionPointer = File->SectionObjectPointer;
2531  File->SectionObjectPointer->DataSectionObject = ControlArea;
2532 
2533  /* We can release the PFN lock now */
2534  MiReleasePfnLock(OldIrql);
2535 
2536  /* We don't support previously-mapped file */
2537  ASSERT(NewSegment == NULL);
2538 
2539  /* Image-file backed sections are not yet supported */
2540  ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
2541 
2542  /* So we always create a data file map */
2543  Status = MiCreateDataFileMap(File,
2544  &Segment,
2545  (PSIZE_T)InputMaximumSize,
2548  KernelCall);
2549  if (!NT_SUCCESS(Status))
2550  {
2551  /* Lock the PFN database while we play with the section pointers */
2552  OldIrql = MiAcquirePfnLock();
2553 
2554  /* Reset the waiting-for-deletion event */
2555  ASSERT(ControlArea->WaitingForDeletion == NULL);
2556  ControlArea->WaitingForDeletion = NULL;
2557 
2558  /* Set the file pointer NULL flag */
2559  ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2560  ControlArea->u.Flags.FilePointerNull = TRUE;
2561 
2562  /* Delete the data section object */
2563  ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
2564  File->SectionObjectPointer->DataSectionObject = NULL;
2565 
2566  /* No longer being created */
2567  ControlArea->u.Flags.BeingCreated = FALSE;
2568 
2569  /* We can release the PFN lock now */
2570  MiReleasePfnLock(OldIrql);
2571 
2572  /* Check if we locked and set the IRP */
2573  if (FileLock)
2574  {
2575  /* Undo */
2577  //FsRtlReleaseFile(File);
2578  }
2579 
2580  /* Free the control area and de-ref the file object */
2581  ExFreePool(ControlArea);
2582  ObDereferenceObject(File);
2583 
2584  /* All done */
2585  return Status;
2586  }
2587 
2588  /* On success, we expect this */
2589  ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2590 
2591  /* Check if a maximum size was specified */
2592  if (!InputMaximumSize->QuadPart)
2593  {
2594  /* Nope, use the segment size */
2595  Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2596  }
2597  else
2598  {
2599  /* Yep, use the entered size */
2600  Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2601  }
2602  }
2603  else
2604  {
2605  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2606  if (AllocationAttributes & SEC_IMAGE) return STATUS_INVALID_FILE_FOR_SECTION;
2607 
2608  /* Not yet supported */
2609  ASSERT((AllocationAttributes & SEC_LARGE_PAGES) == 0);
2610 
2611  /* So this must be a pagefile-backed section, create the mappings needed */
2612  Status = MiCreatePagingFileMap(&NewSegment,
2613  (PSIZE_T)InputMaximumSize,
2614  ProtectionMask,
2616  if (!NT_SUCCESS(Status)) return Status;
2617 
2618  /* Set the size here, and read the control area */
2619  Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2620  ControlArea = NewSegment->ControlArea;
2621 
2622  /* MiCreatePagingFileMap increments user references */
2623  UserRefIncremented = TRUE;
2624  }
2625 
2626  /* Did we already have a segment? */
2627  if (!NewSegment)
2628  {
2629  /* This must be the file path and we created a segment */
2630  NewSegment = Segment;
2631  ASSERT(File != NULL);
2632 
2633  /* Acquire the PFN lock while we set control area flags */
2634  OldIrql = MiAcquirePfnLock();
2635 
2636  /* We don't support this race condition yet, so assume no waiters */
2637  ASSERT(ControlArea->WaitingForDeletion == NULL);
2638  ControlArea->WaitingForDeletion = NULL;
2639 
2640  /* Image-file backed sections are not yet supported, nor ROM images */
2641  ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
2642  ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2643 
2644  /* Take off the being created flag, and then release the lock */
2645  ControlArea->u.Flags.BeingCreated = FALSE;
2646  MiReleasePfnLock(OldIrql);
2647  }
2648 
2649  /* Check if we locked the file earlier */
2650  if (FileLock)
2651  {
2652  /* Reset the top-level IRP and release the lock */
2654  //FsRtlReleaseFile(File);
2655  FileLock = FALSE;
2656  }
2657 
2658  /* Set the initial section object data */
2659  Section.InitialPageProtection = SectionPageProtection;
2660 
2661  /* The mapping created a control area and segment, save the flags */
2662  Section.Segment = NewSegment;
2663  Section.u.LongFlags = ControlArea->u.LongFlags;
2664 
2665  /* Check if this is a user-mode read-write non-image file mapping */
2666  if (!(FileObject) &&
2668  !(ControlArea->u.Flags.Image) &&
2669  (ControlArea->FilePointer))
2670  {
2671  /* Add a reference and set the flag */
2672  Section.u.Flags.UserWritable = TRUE;
2673  InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2674  }
2675 
2676  /* Check for image mappings or page file mappings */
2677  if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2678  {
2679  /* Charge the segment size, and allocate a subsection */
2680  PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2681  Size = sizeof(SUBSECTION);
2682  }
2683  else
2684  {
2685  /* Charge nothing, and allocate a mapped subsection */
2686  PagedCharge = 0;
2687  Size = sizeof(MSUBSECTION);
2688  }
2689 
2690  /* Check if this is a normal CA */
2691  ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2692  ASSERT(ControlArea->u.Flags.Rom == 0);
2693 
2694  /* Charge only a CA, and the subsection is right after */
2695  NonPagedCharge = sizeof(CONTROL_AREA);
2696  Subsection = (PSUBSECTION)(ControlArea + 1);
2697 
2698  /* We only support single-subsection mappings */
2699  NonPagedCharge += Size;
2700  ASSERT(Subsection->NextSubsection == NULL);
2701 
2702  /* Create the actual section object, with enough space for the prototype PTEs */
2703  Status = ObCreateObject(PreviousMode,
2706  PreviousMode,
2707  NULL,
2708  sizeof(SECTION),
2709  PagedCharge,
2710  NonPagedCharge,
2711  (PVOID*)&NewSection);
2712  if (!NT_SUCCESS(Status))
2713  {
2714  /* Check if this is a user-mode read-write non-image file mapping */
2715  if (!(FileObject) &&
2717  !(ControlArea->u.Flags.Image) &&
2718  (ControlArea->FilePointer))
2719  {
2720  /* Remove a reference and check the flag */
2721  ASSERT(Section.u.Flags.UserWritable == 1);
2722  InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2723  }
2724 
2725  /* Check if a user reference was added */
2726  if (UserRefIncremented)
2727  {
2728  /* Acquire the PFN lock while we change counters */
2729  OldIrql = MiAcquirePfnLock();
2730 
2731  /* Decrement the accounting counters */
2732  ControlArea->NumberOfSectionReferences--;
2733  ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2734  ControlArea->NumberOfUserReferences--;
2735 
2736  /* Check if we should destroy the CA and release the lock */
2737  MiCheckControlArea(ControlArea, OldIrql);
2738  }
2739 
2740  /* Return the failure code */
2741  return Status;
2742  }
2743 
2744  /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2745 
2746  /* Now copy the local section object from the stack into this new object */
2747  RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2748  NewSection->Address.StartingVpn = 0;
2749 
2750  /* For now, only user calls are supported */
2751  ASSERT(KernelCall == FALSE);
2752  NewSection->u.Flags.UserReference = TRUE;
2753 
2754  /* Is this a "based" allocation, in which all mappings are identical? */
2756  {
2757  /* Lock the VAD tree during the search */
2759 
2760  /* Is it a brand new ControArea ? */
2761  if (ControlArea->u.Flags.BeingCreated == 1)
2762  {
2763  ASSERT(ControlArea->u.Flags.Based == 1);
2764  /* Then we must find a global address, top-down */
2767  _64K,
2769  (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2770 
2771  if (!NT_SUCCESS(Status))
2772  {
2773  /* No way to find a valid range. */
2775  ControlArea->u.Flags.Based = 0;
2776  NewSection->u.Flags.Based = 0;
2777  ObDereferenceObject(NewSection);
2778  return Status;
2779  }
2780 
2781  /* Compute the ending address and insert it into the VAD tree */
2782  NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2783  NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2784  MiInsertBasedSection(NewSection);
2785  }
2786  else
2787  {
2788  /* 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 !*/
2789  ASSERT(FALSE);
2790  }
2791 
2793  }
2794 
2795  /* The control area is not being created anymore */
2796  if (ControlArea->u.Flags.BeingCreated == 1)
2797  {
2798  /* Acquire the PFN lock while we set control area flags */
2799  OldIrql = MiAcquirePfnLock();
2800 
2801  /* Take off the being created flag, and then release the lock */
2802  ControlArea->u.Flags.BeingCreated = 0;
2803  NewSection->u.Flags.BeingCreated = 0;
2804 
2805  MiReleasePfnLock(OldIrql);
2806  }
2807 
2808  /* Migrate the attribute into a flag */
2809  if (AllocationAttributes & SEC_NO_CHANGE) NewSection->u.Flags.NoChange = TRUE;
2810 
2811  /* If R/W access is not requested, this might eventually become a CoW mapping */
2813  {
2814  NewSection->u.Flags.CopyOnWrite = TRUE;
2815  }
2816 
2817  /* Write down if this was a kernel call */
2818  ControlArea->u.Flags.WasPurged |= KernelCall;
2819  ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2820 
2821  /* Make sure the segment and the section are the same size, or the section is smaller */
2822  ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2823 
2824  /* Return the object and the creation status */
2825  *SectionObject = (PVOID)NewSection;
2826  return Status;
2827 }
ULONG NoChange
Definition: mmtypes.h:478
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define PAGE_NOCACHE
Definition: nt_native.h:1311
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define MM_INVALID_PROTECTION
Definition: miarm.h:71
PEVENT_COUNTER WaitingForDeletion
Definition: mmtypes.h:526
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PFILE_OBJECT FilePointer
Definition: mmtypes.h:525
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
ULONGLONG SizeOfSegment
Definition: mmtypes.h:405
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
ULONG UserReference
Definition: mmtypes.h:471
ULONG NumberOfSectionReferences
Definition: mmtypes.h:515
PSEGMENT Segment
Definition: mmtypes.h:813
NTSTATUS NTAPI MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1496
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define PAGE_GUARD
Definition: nt_native.h:1310
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:111
LONG NTSTATUS
Definition: precomp.h:26
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:110
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:894
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:33
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2964
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define SEC_NOCACHE
Definition: mmtypes.h:100
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree(IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base)
Definition: vadnode.c:713
ULONG TotalNumberOfPtes
Definition: mmtypes.h:402
struct _SUBSECTION SUBSECTION
union _SECTION::@2497 u
NTSTATUS NTAPI MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN PSIZE_T MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1511
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:345
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:901
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:401
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define SEC_BASED
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
UCHAR KIRQL
Definition: env_spec_w32.h:591
HANDLE FileHandle
Definition: stats.c:38
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:496
#define SEC_COMMIT
Definition: mmtypes.h:99
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
struct _SUBSECTION * NextSubsection
Definition: mmtypes.h:574
long LONG
Definition: pedump.c:60
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:814
#define SEC_RESERVE
Definition: nt_native.h:1323
struct _MSUBSECTION MSUBSECTION
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
ULONG LongFlags
Definition: mmtypes.h:522
struct _SECTION SECTION
void * PVOID
Definition: retypes.h:9
ULONG_PTR StartingVpn
Definition: mmtypes.h:654
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
_Inout_ PVOID Segment
Definition: exfuncs.h:893
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
ULONG_PTR EndingVpn
Definition: mmtypes.h:655
int64_t LONGLONG
Definition: typedefs.h:66
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:159
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:255
POBJECT_TYPE MmSectionObjectType
Definition: section.c:136
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
* PFILE_OBJECT
Definition: iotypes.h:1954
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _CONTROL_AREA CONTROL_AREA
struct _SUBSECTION * PSUBSECTION
unsigned __int64 ULONG64
Definition: imports.h:198
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
MMSECTION_FLAGS Flags
Definition: mmtypes.h:818
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:483
ULONG LowPart
Definition: typedefs.h:104
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:291
ULONG CopyOnWrite
Definition: mmtypes.h:466
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define _64K
Definition: miarm.h:19
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
#define InterlockedIncrement
Definition: armddk.h:53
ULONG FilePointerNull
Definition: mmtypes.h:474
ULONG WritableUserReferences
Definition: mmtypes.h:529
PSEGMENT Segment
Definition: mmtypes.h:513
MMADDRESS_NODE Address
Definition: mmtypes.h:812
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:466
ULONG NumberOfUserReferences
Definition: mmtypes.h:519
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:729
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
PVOID BasedAddress
Definition: mmtypes.h:410
PVOID MmHighSectionBase
Definition: section.c:112
ULONG WasPurged
Definition: mmtypes.h:470
MMSECTION_FLAGS Flags
Definition: mmtypes.h:523
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
#define SEC_IMAGE
Definition: mmtypes.h:96
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
union _CONTROL_AREA::@2481 u
return STATUS_SUCCESS
Definition: btrfs.c:2710
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
ULONG BeingCreated
Definition: mmtypes.h:456
LONGLONG QuadPart
Definition: typedefs.h:112
#define PAGE_READWRITE
Definition: nt_native.h:1304

◆ MmCreateDataFileSection()

NTSTATUS NTAPI MmCreateDataFileSection ( PROS_SECTION_OBJECT SectionObject,
ACCESS_MASK  DesiredAccess,
POBJECT_ATTRIBUTES  ObjectAttributes,
PLARGE_INTEGER  UMaximumSize,
ULONG  SectionPageProtection,
ULONG  AllocationAttributes,
PFILE_OBJECT  FileObject 
)

Definition at line 2910 of file section.c.

Referenced by MmCreateSection().

2920 {
2921  PROS_SECTION_OBJECT Section;
2922  NTSTATUS Status;
2926  ULONG Length;
2927 
2928  /*
2929  * Create the section
2930  */
2931  Status = ObCreateObject(ExGetPreviousMode(),
2933  ObjectAttributes,
2935  NULL,
2936  sizeof(ROS_SECTION_OBJECT),
2937  0,
2938  0,
2939  (PVOID*)&Section);
2940  if (!NT_SUCCESS(Status))
2941  {
2943  return(Status);
2944  }
2945  /*
2946  * Initialize it
2947  */
2948  RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
2949  Section->Type = 'SC';
2950  Section->Size = 'TN';
2953 
2954  /*
2955  * FIXME: This is propably not entirely correct. We can't look into
2956  * the standard FCB header because it might not be initialized yet
2957  * (as in case of the EXT2FS driver by Manoj Paul Joseph where the
2958  * standard file information is filled on first request).
2959  */
2962  sizeof(FILE_STANDARD_INFORMATION),
2963  &FileInfo,
2964  &Length);
2965  if (!NT_SUCCESS(Status))
2966  {
2967  ObDereferenceObject(Section);
2969  return Status;
2970  }
2971 
2972  /*
2973  * FIXME: Revise this once a locking order for file size changes is
2974  * decided
2975  */
2976  if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0))
2977  {
2978  MaximumSize = *UMaximumSize;
2979  }
2980  else
2981  {
2982  MaximumSize = FileInfo.EndOfFile;
2983  /* Mapping zero-sized files isn't allowed. */
2984  if (MaximumSize.QuadPart == 0)
2985  {
2986  ObDereferenceObject(Section);
2989  }
2990  }
2991 
2992  if (MaximumSize.QuadPart > FileInfo.EndOfFile.QuadPart)
2993  {
2994  Status = IoSetInformation(FileObject,
2996  sizeof(LARGE_INTEGER),
2997  &MaximumSize);
2998  if (!NT_SUCCESS(Status))
2999  {
3000  ObDereferenceObject(Section);
3003  }
3004  }
3005 
3006  if (FileObject->SectionObjectPointer == NULL ||
3007  FileObject->SectionObjectPointer->SharedCacheMap == NULL)
3008  {
3009  ObDereferenceObject(Section);
3012  }
3013 
3014  /*
3015  * Lock the file
3016  */
3017  Status = MmspWaitForFileLock(FileObject);
3018  if (Status != STATUS_SUCCESS)
3019  {
3020  ObDereferenceObject(Section);
3022  return(Status);
3023  }
3024 
3025  /*
3026  * If this file hasn't been mapped as a data file before then allocate a
3027  * section segment to describe the data file mapping
3028  */
3029  if (FileObject->SectionObjectPointer->DataSectionObject == NULL)
3030  {
3033  if (Segment == NULL)
3034  {
3035  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
3036  ObDereferenceObject(Section);
3038  return(STATUS_NO_MEMORY);
3039  }
3040  Section->Segment = Segment;
3041  Segment->ReferenceCount = 1;
3042  ExInitializeFastMutex(&Segment->Lock);
3043  /*
3044  * Set the lock before assigning the segment to the file object
3045  */
3046  ExAcquireFastMutex(&Segment->Lock);
3047  FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
3048 
3049  Segment->Image.FileOffset = 0;
3050  Segment->Protection = SectionPageProtection;
3051  Segment->Flags = MM_DATAFILE_SEGMENT;
3052  Segment->Image.Characteristics = 0;
3055  {
3056  Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
3057  }
3058  else
3059  {
3060  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
3061  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
3062  }
3063  Segment->Image.VirtualAddress = 0;
3064  Segment->Locked = TRUE;
3066  }
3067  else
3068  {
3069  /*
3070  * If the file is already mapped as a data file then we may need
3071  * to extend it
3072  */
3073  Segment =
3074  (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
3075  DataSectionObject;
3076  Section->Segment = Segment;
3077  (void)InterlockedIncrementUL(&Segment->ReferenceCount);
3078  MmLockSectionSegment(Segment);
3079 
3080  if (MaximumSize.QuadPart > Segment->RawLength.QuadPart &&
3082  {
3083  Segment->RawLength.QuadPart = MaximumSize.QuadPart;
3084  Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
3085  }
3086  }
3087  MmUnlockSectionSegment(Segment);
3088  Section->FileObject = FileObject;
3089  Section->MaximumSize = MaximumSize;
3090 #ifndef NEWCC
3092 #endif
3093  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
3094  *SectionObject = Section;
3095  return(STATUS_SUCCESS);
3096 }
BOOLEAN WriteCopy
Definition: mm.h:170
struct _MM_SECTION_SEGMENT::@1714 Image
#define TRUE
Definition: types.h:120
LARGE_INTEGER MaximumSize
Definition: mm.h:196
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2964
NTSTATUS NTAPI IoSetInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN PVOID FileInformation)
Definition: iofunc.c:1204
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
NTSTATUS NTAPI IoQueryFileInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, OUT PVOID FileInformation, OUT PULONG ReturnedLength)
Definition: iofunc.c:1164
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
ULONG Protection
Definition: mm.h:168
#define SEC_RESERVE
Definition: nt_native.h:1323
BOOLEAN Locked
Definition: mm.h:171
smooth NULL
Definition: ftsmooth.c:416
LARGE_INTEGER EndOfFile
Definition: nt_native.h:948
VOID NTAPI CcRosReferenceCache(PFILE_OBJECT FileObject)
Definition: view.c:1264
void * PVOID
Definition: retypes.h:9
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
_Inout_ PVOID Segment
Definition: exfuncs.h:893
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
LARGE_INTEGER Length
Definition: mm.h:165
PFILE_OBJECT FileObject
Definition: mm.h:199
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
CSHORT Type
Definition: mm.h:194
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
LARGE_INTEGER RawLength
Definition: mm.h:164
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:255
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define MM_DATAFILE_SEGMENT
Definition: mm.h:91
POBJECT_TYPE MmSectionObjectType
Definition: section.c:136
struct _MM_SECTION_SEGMENT * PMM_SECTION_SEGMENT
ULONG Flags
Definition: mm.h:169
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG ReferenceCount
Definition: mm.h:166
NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File)
Definition: section.c:796
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
Status
Definition: gdiplustypes.h:24
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1479
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
ULONG SectionPageProtection
Definition: mm.h:197
#define STATUS_SECTION_NOT_EXTENDED
Definition: ntstatus.h:357
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
#define MmLockSectionSegment(x)
Definition: newmm.h:276
FAST_MUTEX Lock
Definition: mm.h:162
struct FileInfo FileInfo
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
CSHORT Size
Definition: mm.h:195
ULONG AllocationAttributes
Definition: mm.h:198
#define STATUS_MAPPED_FILE_SIZE_ZERO
Definition: ntstatus.h:508
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
PMM_SECTION_SEGMENT Segment
Definition: mm.h:203
return STATUS_SUCCESS
Definition: btrfs.c:2710
LONGLONG QuadPart
Definition: typedefs.h:112

◆ MmCreateImageSection()

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

Definition at line 3724 of file section.c.

Referenced by MmCreateSection().

3731 {
3732  PROS_SECTION_OBJECT Section;
3733  NTSTATUS Status;
3734  PMM_SECTION_SEGMENT SectionSegments;
3735  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
3736  ULONG i;
3737 
3738  if (FileObject == NULL)
3740 
3741 #ifndef NEWCC
3742  if (FileObject->SectionObjectPointer->SharedCacheMap == NULL)
3743  {
3744  DPRINT1("Denying section creation due to missing cache initialization\n");
3746  }
3747 #endif
3748 
3749  /*
3750  * Create the section
3751  */
3752  Status = ObCreateObject (ExGetPreviousMode(),
3754  ObjectAttributes,
3756  NULL,
3757  sizeof(ROS_SECTION_OBJECT),
3758  0,
3759  0,
3760  (PVOID*)(PVOID)&Section);
3761  if (!NT_SUCCESS(Status))
3762  {
3764  return(Status);
3765  }
3766 
3767  /*
3768  * Initialize it
3769  */
3770  RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
3771  Section->Type = 'SC';
3772  Section->Size = 'TN';
3775 
3776  if (FileObject->SectionObjectPointer->ImageSectionObject == NULL)
3777  {
3778  NTSTATUS StatusExeFmt;
3779 
3781  if (ImageSectionObject == NULL)
3782  {
3784  ObDereferenceObject(Section);
3785  return(STATUS_NO_MEMORY);
3786  }
3787 
3788  RtlZeroMemory(ImageSectionObject, sizeof(MM_IMAGE_SECTION_OBJECT));
3789 
3790  StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
3791 
3792  if (!NT_SUCCESS(StatusExeFmt))
3793  {
3794  if(ImageSectionObject->Segments != NULL)
3795  ExFreePool(ImageSectionObject->Segments);
3796 
3797  /*
3798  * If image file is empty, then return that the file is invalid for section
3799  */
3800  Status = StatusExeFmt;
3801  if (StatusExeFmt == STATUS_END_OF_FILE)
3802  {
3804  }
3805 
3806  ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
3807  ObDereferenceObject(Section);
3809  return(Status);
3810  }
3811 
3812  Section->ImageSection = ImageSectionObject;
3813  ASSERT(ImageSectionObject->Segments);
3814 
3815  /*
3816  * Lock the file
3817  */
3818  Status = MmspWaitForFileLock(FileObject);
3819  if (!NT_SUCCESS(Status))
3820  {
3821  ExFreePool(ImageSectionObject->Segments);
3822  ExFreePool(ImageSectionObject);
3823  ObDereferenceObject(Section);
3825  return(Status);
3826  }
3827 
3828  if (NULL != InterlockedCompareExchangePointer(&FileObject->SectionObjectPointer->ImageSectionObject,
3829  ImageSectionObject, NULL))
3830  {
3831  /*
3832  * An other thread has initialized the same image in the background
3833  */
3834  ExFreePool(ImageSectionObject->Segments);
3835  ExFreePool(ImageSectionObject);
3836  ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3837  Section->ImageSection = ImageSectionObject;
3838  SectionSegments = ImageSectionObject->Segments;
3839 
3840  for (i = 0; i < ImageSectionObject->NrSegments; i++)
3841  {
3842  (void)InterlockedIncrementUL(&SectionSegments[i].ReferenceCount);
3843  }
3844  }
3845 
3846  Status = StatusExeFmt;
3847  }
3848  else
3849  {
3850  /*
3851  * Lock the file
3852  */
3853  Status = MmspWaitForFileLock(FileObject);
3854  if (Status != STATUS_SUCCESS)
3855  {
3856  ObDereferenceObject(Section);
3858  return(Status);
3859  }
3860 
3861  ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
3862  Section->ImageSection = ImageSectionObject;
3863  SectionSegments = ImageSectionObject->Segments;
3864 
3865  /*
3866  * Otherwise just reference all the section segments
3867  */
3868  for (i = 0; i < ImageSectionObject->NrSegments; i++)
3869  {
3870  (void)InterlockedIncrementUL(&SectionSegments[i].ReferenceCount);
3871  }
3872 
3873  Status = STATUS_SUCCESS;
3874  }
3875  Section->FileObject = FileObject;
3876 #ifndef NEWCC
3878 #endif
3879  //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
3880  *SectionObject = Section;
3881  return(Status);
3882 }
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
NTSTATUS ExeFmtpCreateImageSection(PFILE_OBJECT FileObject, PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
Definition: section.c:3577
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2964
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define STATUS_END_OF_FILE
Definition: shellext.h:50
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
PMM_IMAGE_SECTION_OBJECT ImageSection
Definition: mm.h:202
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI CcRosReferenceCache(PFILE_OBJECT FileObject)
Definition: view.c:1264
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
PFILE_OBJECT FileObject
Definition: mm.h:199
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
CSHORT Type
Definition: mm.h:194
PMM_SECTION_SEGMENT Segments
Definition: mm.h:189
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:255
POBJECT_TYPE MmSectionObjectType
Definition: section.c:136
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File)
Definition: section.c:796
Status
Definition: gdiplustypes.h:24
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1479
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
ULONG SectionPageProtection
Definition: mm.h:197
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
CSHORT Size
Definition: mm.h:195
ULONG AllocationAttributes
Definition: mm.h:198
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2710
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ MmCreatePageFileSection()

NTSTATUS NTAPI MmCreatePageFileSection ( PROS_SECTION_OBJECT SectionObject,
ACCESS_MASK  DesiredAccess,
POBJECT_ATTRIBUTES  ObjectAttributes,
PLARGE_INTEGER  UMaximumSize,
ULONG  SectionPageProtection,
ULONG  AllocationAttributes 
)

Definition at line 2835 of file section.c.

Referenced by MmCreateSection().

2844 {
2846  PROS_SECTION_OBJECT Section;
2848  NTSTATUS Status;
2849 
2850  if (UMaximumSize == NULL)
2851  {
2852  DPRINT1("MmCreatePageFileSection: (UMaximumSize == NULL)\n");
2853  return(STATUS_INVALID_PARAMETER);
2854  }
2855  MaximumSize = *UMaximumSize;
2856 
2857  /*
2858  * Create the section
2859  */
2860  Status = ObCreateObject(ExGetPreviousMode(),
2862  ObjectAttributes,
2864  NULL,
2865  sizeof(ROS_SECTION_OBJECT),
2866  0,
2867  0,
2868  (PVOID*)(PVOID)&Section);
2869  if (!NT_SUCCESS(Status))
2870  {
2871  DPRINT1("MmCreatePageFileSection: failed to create object (0x%lx)\n", Status);
2872  return(Status);
2873  }
2874 
2875  /*
2876  * Initialize it
2877  */
2878  RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
2879  Section->Type = 'SC';
2880  Section->Size = 'TN';
2883  Section->MaximumSize = MaximumSize;
2886  if (Segment == NULL)
2887  {
2888  ObDereferenceObject(Section);
2889  return(STATUS_NO_MEMORY);
2890  }
2891  RtlZeroMemory(Segment, sizeof(MM_SECTION_SEGMENT));
2892  Section->Segment = Segment;
2893  Segment->ReferenceCount = 1;
2894  ExInitializeFastMutex(&Segment->Lock);
2895  Segment->Image.FileOffset = 0;
2896  Segment->Protection = SectionPageProtection;
2897  Segment->RawLength.QuadPart = MaximumSize.u.LowPart;
2898  Segment->Length.QuadPart = PAGE_ROUND_UP(MaximumSize.u.LowPart);
2899  Segment->Flags = MM_PAGEFILE_SEGMENT;
2900  Segment->WriteCopy = FALSE;
2901  Segment->Image.VirtualAddress = 0;
2902  Segment->Image.Characteristics = 0;
2903  *SectionObject = Section;
2905  return(STATUS_SUCCESS);
2906 }
BOOLEAN WriteCopy
Definition: mm.h:170
struct _MM_SECTION_SEGMENT::@1714 Image
struct _LARGE_INTEGER::@2193 u
LARGE_INTEGER MaximumSize
Definition: mm.h:196
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2964
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
ULONG Protection
Definition: mm.h:168
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PVOID Segment
Definition: exfuncs.h:893
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
LARGE_INTEGER Length
Definition: mm.h:165
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
CSHORT Type
Definition: mm.h:194
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
LARGE_INTEGER RawLength
Definition: mm.h:164
POBJECT_TYPE MmSectionObjectType
Definition: section.c:136
ULONG Flags
Definition: mm.h:169
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define MM_PAGEFILE_SEGMENT
Definition: mm.h:90
ULONG ReferenceCount
Definition: mm.h:166
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
Status
Definition: gdiplustypes.h:24
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:139
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
ULONG SectionPageProtection
Definition: mm.h:197
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
#define DPRINT1
Definition: precomp.h:8
FAST_MUTEX Lock
Definition: mm.h:162
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
CSHORT Size
Definition: mm.h:195
ULONG AllocationAttributes
Definition: mm.h:198
PMM_SECTION_SEGMENT Segment
Definition: mm.h:203
return STATUS_SUCCESS
Definition: btrfs.c:2710
LONGLONG QuadPart
Definition: typedefs.h:112

◆ MmCreatePhysicalMemorySection()

NTSTATUS INIT_FUNCTION NTAPI MmCreatePhysicalMemorySection ( VOID  )

Definition at line 2752 of file section.c.

Referenced by MmInitSectionImplementation().

2753 {
2754  PROS_SECTION_OBJECT PhysSection;
2755  NTSTATUS Status;
2757  UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2758  LARGE_INTEGER SectionSize;
2759  HANDLE Handle;
2760 
2761  /*
2762  * Create the section mapping physical memory
2763  */
2764  SectionSize.QuadPart = 0xFFFFFFFF;
2766  &Name,
2768  NULL,
2769  NULL);
2770  Status = MmCreateSection((PVOID)&PhysSection,
2772  &Obj,
2773  &SectionSize,
2776  NULL,
2777  NULL);
2778  if (!NT_SUCCESS(Status))
2779  {
2780  DPRINT1("Failed to create PhysicalMemory section\n");
2781  KeBugCheck(MEMORY_MANAGEMENT);
2782  }
2783  Status = ObInsertObject(PhysSection,
2784  NULL,
2786  0,
2787  NULL,
2788  &Handle);
2789  if (!NT_SUCCESS(Status))
2790  {
2791  ObDereferenceObject(PhysSection);
2792  }
2793  ObCloseHandle(Handle, KernelMode);
2794  PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY;
2795  PhysSection->Segment->Flags &= ~MM_PAGEFILE_SEGMENT;
2796 
2797  return(STATUS_SUCCESS);
2798 }
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_PERMANENT
Definition: winternl.h:226
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
_In_ HANDLE Handle
Definition: extypes.h:390
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
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: section.c:4969
ULONG Flags
Definition: mm.h:169
#define MM_PAGEFILE_SEGMENT
Definition: mm.h:90
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3370
static const WCHAR L[]
Definition: oid.c:1087
#define SEC_PHYSICALMEMORY
Definition: mm.h:88
Status
Definition: gdiplustypes.h:24
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:2926
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:91
#define DPRINT1
Definition: precomp.h:8
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG AllocationAttributes
Definition: mm.h:198
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
PMM_SECTION_SEGMENT Segment
Definition: mm.h:203
return STATUS_SUCCESS
Definition: btrfs.c:2710
LONGLONG QuadPart
Definition: typedefs.h:112
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

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

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

4977 {
4978  NTSTATUS Status;
4979  ULONG Protection;
4981 
4982  /* Check if an ARM3 section is being created instead */
4984  {
4985  if (!(FileObject) && !(FileHandle))
4986  {
4987  return MmCreateArm3Section(Section,
4988  DesiredAccess,
4990  MaximumSize,
4992  AllocationAttributes &~ 1,
4993  FileHandle,
4994  FileObject);
4995  }
4996  }
4997 
4998  /* Convert section flag to page flag */
5000 
5001  /* Check to make sure the protection is correct. Nt* does this already */
5003  if (Protection == MM_INVALID_PROTECTION)
5004  {
5005  DPRINT1("Page protection is invalid\n");
5007  }
5008 
5009  /* Check if this is going to be a data or image backed file section */
5010  if ((FileHandle) || (FileObject))
5011  {
5012  /* These cannot be mapped with large pages */
5014  {
5015  DPRINT1("Large pages cannot be used with an image mapping\n");
5017  }
5018 
5019  /* Did the caller pass an object? */
5020  if (FileObject)
5021  {
5022  /* Reference the object directly */
5024  }
5025  else
5026  {
5027  /* Reference the file handle to get the object */
5029  MmMakeFileAccess[Protection],
5032  (PVOID*)&FileObject,
5033  NULL);
5034  if (!NT_SUCCESS(Status))
5035  {
5036  DPRINT1("Failed to get a handle to the FO: %lx\n", Status);
5037  return Status;
5038  }
5039  }
5040  }
5041  else
5042  {
5043  /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
5045  }
5046 
5047 #ifndef NEWCC // A hack for initializing caching.
5048  // This is needed only in the old case.
5049  if (FileHandle)
5050  {
5052  NTSTATUS Status;
5053  CHAR Buffer;
5055  ByteOffset.QuadPart = 0;
5056  Status = ZwReadFile(FileHandle,
5057  NULL,
5058  NULL,
5059  NULL,
5060  &Iosb,
5061  &Buffer,
5062  sizeof(Buffer),
5063  &ByteOffset,
5064  NULL);
5065  if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
5066  {
5067  DPRINT1("CC failure: %lx\n", Status);
5068  if (FileObject)
5070  return Status;
5071  }
5072  // Caching is initialized...
5073 
5074  // Hack of the hack: actually, it might not be initialized if FSD init on effective right and if file is null-size
5075  // In such case, force cache by initiating a write IRP
5076  if (Status == STATUS_END_OF_FILE && !(AllocationAttributes & SEC_IMAGE) && FileObject != NULL &&
5077  (FileObject->SectionObjectPointer == NULL || FileObject->SectionObjectPointer->SharedCacheMap == NULL))
5078  {
5079  Buffer = 0xdb;
5080  Status = ZwWriteFile(FileHandle,
5081  NULL,
5082  NULL,
5083  NULL,
5084  &Iosb,
5085  &Buffer,
5086  sizeof(Buffer),
5087  &ByteOffset,
5088  NULL);
5089  if (NT_SUCCESS(Status))
5090  {
5092  Zero.QuadPart = 0LL;
5093 
5094  Status = IoSetInformation(FileObject,
5096  sizeof(LARGE_INTEGER),
5097  &Zero);
5098  ASSERT(NT_SUCCESS(Status));
5099  }
5100  }
5101  }
5102 #endif
5103 
5104  if (AllocationAttributes & SEC_IMAGE)
5105  {
5106  Status = MmCreateImageSection(SectionObject,
5107  DesiredAccess,
5109  MaximumSize,
5112  FileObject);
5113  }
5114 #ifndef NEWCC
5115  else if (FileHandle != NULL)
5116  {
5117  Status = MmCreateDataFileSection(SectionObject,
5118  DesiredAccess,
5120  MaximumSize,
5123  FileObject);
5124  }
5125 #else
5126  else if (FileHandle != NULL || FileObject != NULL)
5127  {
5128  Status = MmCreateCacheSection(SectionObject,
5129  DesiredAccess,
5131  MaximumSize,
5134  FileObject);
5135  }
5136 #endif
5137  else
5138  {
5140  {
5141  DPRINT1("Invalid path: %lx %p %p\n", AllocationAttributes, FileObject, FileHandle);
5142  }
5143 // ASSERT(AllocationAttributes & SEC_PHYSICALMEMORY);
5144  Status = MmCreatePageFileSection(SectionObject,
5145  DesiredAccess,
5147  MaximumSize,
5150  if (FileObject)
5152  }
5153 
5154  return Status;
5155 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define PAGE_NOCACHE
Definition: nt_native.h:1311
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define MM_INVALID_PROTECTION
Definition: miarm.h:71
#define LL
Definition: tui.h:72
#define SEC_LARGE_PAGES
Definition: mmtypes.h:102
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:360
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:33
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2964
NTSTATUS NTAPI IoSetInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN PVOID FileInformation)
Definition: iofunc.c:1204
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define SEC_NOCACHE
Definition: mmtypes.h:100
#define STATUS_END_OF_FILE
Definition: shellext.h:50
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:2411
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:360
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI MmCreateCacheSection(PROS_SECTION_OBJECT *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
Definition: data.c:308
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSTATUS NTAPI MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes)
Definition: section.c:2835
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:159
NTSTATUS MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
Definition: section.c:3724
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:255
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SEC_PHYSICALMEMORY
Definition: mm.h:88
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:291
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER UMaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, PFILE_OBJECT FileObject)
Definition: section.c:2910
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:466
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:402
#define DPRINT1
Definition: precomp.h:8
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
#define SEC_IMAGE
Definition: mmtypes.h:96
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
LONGLONG QuadPart
Definition: typedefs.h:112
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716

◆ MmFlushImageSection()

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

Definition at line 4792 of file section.c.

Referenced by _Requires_lock_held_(), Ext2CreateFile(), Ext2IsFileRemovable(), Ext2PurgeFile(), Ext2PurgeVolume(), FatQueryShortNameInfo(), FatSetRenameInfo(), FFSCreateFile(), FFSPurgeFile(), FFSPurgeVolume(), FFSSetDispositionInfo(), open_file(), RfsdCreateFile(), RfsdPurgeFile(), RfsdPurgeVolume(), RfsdSetDispositionInfo(), RxCommonSetInformation(), RxPurgeFcbInSystemCache(), RxPurgeFobx(), RxPurgeNetFcb(), set_disposition_information(), UDFCloseAllXXXDelayedInDir(), UDFCommonCreate(), UDFMarkStreamsForDeletion(), UDFSetDispositionInformation(), VfatCreateFile(), vfatPrepareTargetForRename(), and VfatSetDispositionInformation().

4794 {
4795  BOOLEAN Result = TRUE;
4796 #ifdef NEWCC
4798 #endif
4799 
4800  switch(FlushType)
4801  {
4802  case MmFlushForDelete:
4803  if (SectionObjectPointer->ImageSectionObject ||
4804  SectionObjectPointer->DataSectionObject)
4805  {
4806  return FALSE;
4807  }
4808 #ifndef NEWCC
4810 #endif
4811  return TRUE;
4812  case MmFlushForWrite:
4813  {
4814  DPRINT("MmFlushImageSection(%d)\n", FlushType);
4815 #ifdef NEWCC
4816  Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer->DataSectionObject;
4817 #endif
4818 
4819  if (SectionObjectPointer->ImageSectionObject)
4820  {
4821  DPRINT1("SectionObject has ImageSection\n");
4822  return FALSE;
4823  }
4824 
4825 #ifdef NEWCC
4826  CcpLock();
4827  Result = !SectionObjectPointer->SharedCacheMap || (Segment->ReferenceCount == CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap));
4828  CcpUnlock();
4829  DPRINT("Result %d\n", Result);
4830 #endif
4831  return Result;
4832  }
4833  }
4834  return FALSE;
4835 }
#define TRUE
Definition: types.h:120
#define CcpLock()
Definition: newcc.h:140
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
void DPRINT(...)
Definition: polytest.cpp:61
IN PFCB IN FAT_FLUSH_TYPE FlushType
Definition: fatprocs.h:1071
_Inout_ PVOID Segment
Definition: exfuncs.h:893
if(!(yy_init))
Definition: macro.lex.yy.c:717
struct _MM_SECTION_SEGMENT * PMM_SECTION_SEGMENT
VOID NTAPI CcRosRemoveIfClosed(PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: view.c:1278
ULONG ReferenceCount
Definition: mm.h:166
ULONG NTAPI CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
Definition: fssup.c:270
#define DPRINT1
Definition: precomp.h:8
#define CcpUnlock()
Definition: newcc.h:141

◆ MmFreeSectionPage()

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

Definition at line 3964 of file section.c.

Referenced by MmUnmapViewOfSegment().

3966 {
3967  ULONG_PTR Entry;
3968 #ifndef NEWCC
3970  PROS_SHARED_CACHE_MAP SharedCacheMap;
3971 #endif
3973  SWAPENTRY SavedSwapEntry;
3974  PROS_SECTION_OBJECT Section;
3978 
3979  AddressSpace = (PMMSUPPORT)Context;
3980  Process = MmGetAddressSpaceOwner(AddressSpace);
3981 
3982  Address = (PVOID)PAGE_ROUND_DOWN(Address);
3983 
3984  Offset.QuadPart = ((ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)) +
3985  MemoryArea->Data.SectionData.ViewOffset.QuadPart;
3986 
3987  Section = MemoryArea->Data.SectionData.Section;
3988  Segment = MemoryArea->Data.SectionData.Segment;
3989 
3990  Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
3991  while (Entry && MM_IS_WAIT_PTE(Entry))
3992  {
3993  MmUnlockSectionSegment(Segment);
3994  MmUnlockAddressSpace(AddressSpace);
3995 
3997 
3998  MmLockAddressSpace(AddressSpace);
3999  MmLockSectionSegment(Segment);
4000  Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
4001  }
4002 
4003  /*
4004  * For a dirty, datafile, non-private page mark it as dirty in the
4005  * cache manager.
4006  */
4007  if (Segment->Flags & MM_DATAFILE_SEGMENT)
4008  {
4009  if (Page == PFN_FROM_SSE(Entry) && Dirty)
4010  {
4011 #ifndef NEWCC
4012  FileObject = MemoryArea->Data.SectionData.Section->FileObject;
4013  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
4014  CcRosMarkDirtyFile(SharedCacheMap, Offset.QuadPart + Segment->Image.FileOffset);
4015 #endif
4016  ASSERT(SwapEntry == 0);
4017  }
4018  }
4019 
4020  if (SwapEntry != 0)
4021  {
4022  /*
4023  * Sanity check
4024  */
4025  if (Segment->Flags & MM_PAGEFILE_SEGMENT)
4026  {
4027  DPRINT1("Found a swap entry for a page in a pagefile section.\n");
4028  KeBugCheck(MEMORY_MANAGEMENT);
4029  }
4030  MmFreeSwapPage(SwapEntry);
4031  }
4032  else if (Page != 0)
4033  {
4034  if (IS_SWAP_FROM_SSE(Entry) ||
4035  Page != PFN_FROM_SSE(Entry))
4036  {
4037  /*
4038  * Sanity check
4039  */
4040  if (Segment->Flags & MM_PAGEFILE_SEGMENT)
4041  {
4042  DPRINT1("Found a private page in a pagefile section.\n");
4043  KeBugCheck(MEMORY_MANAGEMENT);
4044  }
4045  /*
4046  * Just dereference private pages
4047  */
4048  SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
4049  if (SavedSwapEntry != 0)
4050  {
4051  MmFreeSwapPage(SavedSwapEntry);
4052  MmSetSavedSwapEntryPage(Page, 0);
4053  }
4054  MmDeleteRmap(Page, Process, Address);
4056  }
4057  else
4058  {
4059  MmDeleteRmap(Page, Process, Address);
4060  MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, Dirty, FALSE, NULL);
4061  }
4062  }
4063 }
struct _MM_SECTION_SEGMENT::@1714 Image
struct _Entry Entry
Definition: kefuncs.h:640
#define PFN_FROM_SSE(E)
Definition: newmm.h:7
#define MC_USER
Definition: mm.h:94
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1410
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:97
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#define MiWaitForPageEvent(Process, Address)
Definition: newmm.h:38
uint32_t ULONG_PTR
Definition: typedefs.h:63
union _MEMORY_AREA::@1717 Data
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
Definition: section.c:876
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
void * PVOID
Definition: retypes.h:9
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
_Inout_ PVOID Segment
Definition: exfuncs.h:893
struct _MMSUPPORT * PMMSUPPORT
#define MM_DATAFILE_SEGMENT
Definition: mm.h:91
* PFILE_OBJECT
Definition: iotypes.h:1954
ULONG Flags
Definition: mm.h:169
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MM_PAGEFILE_SEGMENT
Definition: mm.h:90
#define IS_SWAP_FROM_SSE(E)
Definition: newmm.h:8
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
struct _MEMORY_AREA::@1717::@1718 SectionData
ULONG_PTR SWAPENTRY
Definition: mm.h:47
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1417
NTSTATUS NTAPI CcRosMarkDirtyFile(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset)
Definition: view.c:565
#define DPRINT1
Definition: precomp.h:8
#define MmLockSectionSegment(x)
Definition: newmm.h:276
#define MM_IS_WAIT_PTE(E)
Definition: newmm.h:9
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:454
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define ULONG_PTR
Definition: config.h:101
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1403
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143
VOID NTAPI MmFreeSwapPage(SWAPENTRY Entry)
Definition: pagefile.c:278
LONGLONG QuadPart
Definition: typedefs.h:112
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:470

◆ MmFreeSectionSegments()

VOID NTAPI MmFreeSectionSegments ( PFILE_OBJECT  FileObject)

Definition at line 804 of file section.c.

Referenced by CcRosDereferenceCache(), and CcRosReleaseFileCache().

805 {
806  if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
807  {
808  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
809  PMM_SECTION_SEGMENT SectionSegments;
810  ULONG NrSegments;
811  ULONG i;
812 
813  ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)FileObject->SectionObjectPointer->ImageSectionObject;
814  NrSegments = ImageSectionObject->NrSegments;
815  SectionSegments = ImageSectionObject->Segments;
816  for (i = 0; i < NrSegments; i++)
817  {
818  if (SectionSegments[i].ReferenceCount != 0)
819  {
820  DPRINT1("Image segment %lu still referenced (was %lu)\n", i,
821  SectionSegments[i].ReferenceCount);
822  KeBugCheck(MEMORY_MANAGEMENT);
823  }
824  MmFreePageTablesSectionSegment(&SectionSegments[i], NULL);
825  }
826  ExFreePool(ImageSectionObject->Segments);
827  ExFreePool(ImageSectionObject);
828  FileObject->SectionObjectPointer->ImageSectionObject = NULL;
829  }
830  if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
831  {
833 
834  Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
835  DataSectionObject;
836 
837  if (Segment->ReferenceCount != 0)
838  {
839  DPRINT1("Data segment still referenced\n");
840  KeBugCheck(MEMORY_MANAGEMENT);
841  }
843  ExFreePool(Segment);
844  FileObject->SectionObjectPointer->DataSectionObject = NULL;
845  }
846 }
GLenum GLclampf GLint i
Definition: glfuncs.h:14
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
_Inout_ PVOID Segment
Definition: exfuncs.h:893
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT
if(!(yy_init))
Definition: macro.lex.yy.c:717
PMM_SECTION_SEGMENT Segments
Definition: mm.h:189
VOID NTAPI MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment, FREE_SECTION_PAGE_FUN FreePage)
Definition: sptab.c:278
#define for
Definition: utility.h:88
struct _MM_SECTION_SEGMENT * PMM_SECTION_SEGMENT
ULONG ReferenceCount
Definition: mm.h:166
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ MmInitSectionImplementation()

NTSTATUS INIT_FUNCTION NTAPI MmInitSectionImplementation ( VOID  )

Definition at line 2803 of file section.c.

Referenced by MmInitSystem().

2804 {
2805  OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
2807 
2808  DPRINT("Creating Section Object Type\n");
2809 
2810  /* Initialize the section based root */
2813 
2814  /* Initialize the Section object type */
2815  RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
2816  RtlInitUnicodeString(&Name, L"Section");
2817  ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
2818  ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(ROS_SECTION_OBJECT);
2819  ObjectTypeInitializer.PoolType = PagedPool;
2820  ObjectTypeInitializer.UseDefaultObject = TRUE;
2821  ObjectTypeInitializer.GenericMapping = MmpSectionMapping;
2822  ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection;
2823  ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
2824  ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
2825  ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
2826  ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
2827 
2829 
2830  return(STATUS_SUCCESS);
2831 }
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1048
#define TRUE
Definition: types.h:120
VOID NTAPI MmpCloseSection(IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
Definition: section.c:2740
ULONG_PTR NumberGenericTableElements
Definition: mmtypes.h:669
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:110
#define OBJ_OPENLINK
Definition: winternl.h:230
MMADDRESS_NODE BalancedRoot
Definition: mmtypes.h:663
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
static GENERIC_MAPPING MmpSectionMapping
Definition: section.c:166
struct NameRec_ * Name
Definition: cdprocs.h:464
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
OB_CLOSE_METHOD CloseProcedure
Definition: obtypes.h:368
struct _ROS_SECTION_OBJECT ROS_SECTION_OBJECT
POBJECT_TYPE MmSectionObjectType
Definition: section.c:136
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
NTSTATUS INIT_FUNCTION NTAPI MmCreatePhysicalMemorySection(VOID)
Definition: section.c:2752
static const WCHAR L[]
Definition: oid.c:1087
VOID NTAPI MmpDeleteSection(PVOID ObjectBody)
Definition: section.c:2641
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
union _MMADDRESS_NODE::@2486 u1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2710
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
struct _MMADDRESS_NODE * Parent
Definition: mmtypes.h:650

◆ MmMapViewInSystemSpace()

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

Definition at line 4841 of file section.c.

Referenced by EngLoadModuleForWrite(), ExpInitNls(), IntGdiAddFontResource(), and MmMapViewInSessionSpace().

4844 {
4845  PROS_SECTION_OBJECT Section;
4847  NTSTATUS Status;
4848  PAGED_CODE();
4849 
4851  {
4853  &MmSession,
4854  MappedBase,
4855  ViewSize);
4856  }
4857 
4858  DPRINT("MmMapViewInSystemSpace() called\n");
4859 
4861  AddressSpace = MmGetKernelAddressSpace();
4862 
4863  MmLockAddressSpace(AddressSpace);
4864 
4865 
4866  if ((*ViewSize) == 0)
4867  {
4868  (*ViewSize) = Section->MaximumSize.u.LowPart;
4869  }
4870  else if ((*ViewSize) > Section->MaximumSize.u.LowPart)
4871  {
4872  (*ViewSize) = Section->MaximumSize.u.LowPart;
4873  }
4874 
4875  MmLockSectionSegment(Section->Segment);
4876 
4877 
4878  Status = MmMapViewOfSegment(AddressSpace,
4879  Section,
4880  Section->Segment,
4881  MappedBase,
4882  *ViewSize,
4884  0,
4885  0);
4886 
4887  MmUnlockSectionSegment(Section->Segment);
4888  MmUnlockAddressSpace(AddressSpace);
4889 
4890  return Status;
4891 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
struct _LARGE_INTEGER::@2193 u
LARGE_INTEGER MaximumSize
Definition: mm.h:196
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1410
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS MmMapViewOfSegment(PMMSUPPORT AddressSpace, PROS_SECTION_OBJECT Section, PMM_SECTION_SEGMENT Segment, PVOID *BaseAddress, SIZE_T ViewSize, ULONG Protect, ULONG ViewOffset, ULONG AllocationType)
Definition: section.c:3887
#define PAGED_CODE()
Definition: video.h:57
void DPRINT(...)
Definition: polytest.cpp:61
struct _ROS_SECTION_OBJECT * PROS_SECTION_OBJECT
NTSTATUS NTAPI MiMapViewInSystemSpace(IN PVOID Section, IN PMMSESSION Session, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:1053
Status
Definition: gdiplustypes.h:24
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1432
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:493
#define MmLockSectionSegment(x)
Definition: newmm.h:276
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
PMM_SECTION_SEGMENT Segment
Definition: mm.h:203
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1403
#define PAGE_READWRITE
Definition: nt_native.h:1304
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PVOID Section)
Definition: miarm.h:1036
MMSESSION MmSession
Definition: section.c:108

◆ MmMapViewOfArm3Section()

NTSTATUS NTAPI MmMapViewOfArm3Section ( IN PVOID  SectionObject,
IN PEPROCESS  Process,
IN OUT PVOID BaseAddress,
IN ULONG_PTR  ZeroBits,
IN SIZE_T  CommitSize,
IN OUT PLARGE_INTEGER SectionOffset  OPTIONAL,
IN OUT PSIZE_T  ViewSize,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG  AllocationType,
IN ULONG  Protect 
)

Definition at line 2834 of file section.c.

Referenced by MmMapViewOfSection().

2844 {
2847  PSECTION Section;
2848  PCONTROL_AREA ControlArea;
2849  ULONG ProtectionMask;
2850  NTSTATUS Status;
2851  ULONG64 CalculatedViewSize;
2852  PAGED_CODE();
2853 
2854  /* Get the segment and control area */
2855  Section = (PSECTION)SectionObject;
2856  ControlArea = Section->Segment->ControlArea;
2857 
2858  /* These flags/states are not yet supported by ARM3 */
2859  ASSERT(Section->u.Flags.Image == 0);
2860  ASSERT(Section->u.Flags.NoCache == 0);
2861  ASSERT(Section->u.Flags.WriteCombined == 0);
2862  ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
2863 
2864  /* FIXME */
2865  if ((AllocationType & MEM_RESERVE) != 0)
2866  {
2867  DPRINT1("MmMapViewOfArm3Section called with MEM_RESERVE, this is not implemented yet!!!\n");
2868  return STATUS_NOT_IMPLEMENTED;
2869  }
2870 
2871  /* Check if the mapping protection is compatible with the create */
2873  {
2874  DPRINT1("Mapping protection is incompatible\n");
2876  }
2877 
2878  /* Check if the offset and size would cause an overflow */
2879  if (((ULONG64)SectionOffset->QuadPart + *ViewSize) <
2880  (ULONG64)SectionOffset->QuadPart)
2881  {
2882  DPRINT1("Section offset overflows\n");
2883  return STATUS_INVALID_VIEW_SIZE;
2884  }
2885 
2886  /* Check if the offset and size are bigger than the section itself */
2887  if (((ULONG64)SectionOffset->QuadPart + *ViewSize) >
2888  (ULONG64)Section->SizeOfSection.QuadPart)
2889  {
2890  DPRINT1("Section offset is larger than section\n");
2891  return STATUS_INVALID_VIEW_SIZE;
2892  }
2893 
2894  /* Check if the caller did not specify a view size */
2895  if (!(*ViewSize))
2896  {
2897  /* Compute it for the caller */
2898  CalculatedViewSize = Section->SizeOfSection.QuadPart -
2899  SectionOffset->QuadPart;
2900 
2901  /* Check if it's larger than 4GB or overflows into kernel-mode */
2902  if (!NT_SUCCESS(RtlULongLongToSIZET(CalculatedViewSize, ViewSize)) ||
2903  (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < CalculatedViewSize))
2904  {
2905  DPRINT1("Section view won't fit\n");
2906  return STATUS_INVALID_VIEW_SIZE;
2907  }
2908  }
2909 
2910  /* Check if the commit size is larger than the view size */
2911  if (CommitSize > *ViewSize)
2912  {
2913  DPRINT1("Attempting to commit more than the view itself\n");
2915  }
2916 
2917  /* Check if the view size is larger than the section */
2918  if (*ViewSize > (ULONG64)Section->SizeOfSection.QuadPart)
2919  {
2920  DPRINT1("The view is larger than the section\n");
2921  return STATUS_INVALID_VIEW_SIZE;
2922  }
2923 
2924  /* Compute and validate the protection mask */
2925  ProtectionMask = MiMakeProtectionMask(Protect);
2926  if (ProtectionMask == MM_INVALID_PROTECTION)
2927  {
2928  DPRINT1("The protection is invalid\n");
2930  }
2931 
2932  /* We only handle pagefile-backed sections, which cannot be writecombined */
2933  if (Protect & PAGE_WRITECOMBINE)
2934  {
2935  DPRINT1("Cannot write combine a pagefile-backed section\n");
2937  }
2938 
2939  /* Start by attaching to the current process if needed */
2940  if (PsGetCurrentProcess() != Process)
2941  {
2942  KeStackAttachProcess(&Process->Pcb, &ApcState);
2943  Attached = TRUE;
2944  }
2945 
2946  /* Do the actual mapping */
2947  Status = MiMapViewOfDataSection(ControlArea,
2948  Process,
2949  BaseAddress,
2950  SectionOffset,
2951  ViewSize,
2952  Section,
2954  ProtectionMask,
2955  CommitSize,
2956  ZeroBits,
2957  AllocationType);
2958 
2959  /* Detach if needed, then return status */
2960  if (Attached) KeUnstackDetachProcess(&ApcState);
2961  return Status;
2962 }
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT InheritDisposition
Definition: mmfuncs.h:404
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:404
#define MM_INVALID_PROTECTION
Definition: miarm.h:71
#define TRUE
Definition: types.h:120
KAPC_STATE
Definition: ketypes.h:1273
BOOLEAN NTAPI MiIsProtectionCompatible(IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
Definition: section.c:118
PSEGMENT Segment
Definition: mmtypes.h:813
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:214
ULONG PhysicalMemory
Definition: mmtypes.h:465
ULONG InitialPageProtection
Definition: mmtypes.h:820
LONG NTSTATUS
Definition: precomp.h:26
union _SECTION::@2497 u
#define PAGED_CODE()
Definition: video.h:57
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:401
uint32_t ULONG_PTR
Definition: typedefs.h:63
static BOOL Attached
Definition: vidbios.c:3905
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:814
#define MEM_RESERVE
Definition: nt_native.h:1314
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
struct _SECTION * PSECTION
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:404
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:465
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:159
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:404
#define STATUS_SECTION_PROTECTION
Definition: ntstatus.h:300
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned __int64 ULONG64
Definition: imports.h:198
MMSECTION_FLAGS Flags
Definition: mmtypes.h:818
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:291
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG AllocationType
Definition: mmfuncs.h:404
Status
Definition: gdiplustypes.h:24
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:254
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
#define STATUS_INVALID_PARAMETER_10
Definition: ntstatus.h:470
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1471
#define DPRINT1
Definition: precomp.h:8
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:42
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
MMSECTION_FLAGS Flags
Definition: mmtypes.h:523
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *BaseAddress, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T ViewSize, IN PSECTION Section, IN SECTION_INHERIT InheritDisposition, IN ULONG ProtectionMask, IN SIZE_T CommitSize, IN ULONG_PTR ZeroBits, IN ULONG AllocationType)
Definition: section.c:1253
union _CONTROL_AREA::@2481 u
ULONG WriteCombined
Definition: mmtypes.h:485
LONGLONG QuadPart
Definition: typedefs.h:112

◆ MmMapViewOfSection()

NTSTATUS NTAPI MmMapViewOfSection ( IN PVOID  SectionObject,
IN PEPROCESS  Process,
IN OUT PVOID BaseAddress,
IN ULONG_PTR  ZeroBits,
IN SIZE_T  CommitSize,
IN OUT PLARGE_INTEGER SectionOffset  OPTIONAL,
IN OUT PSIZE_T  ViewSize,
IN SECTION_INHERIT  InheritDisposition,
IN ULONG  AllocationType,
IN ULONG  Protect 
)

Definition at line 4496 of file section.c.

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

4506 {
4507  PROS_SECTION_OBJECT Section;
4509  ULONG ViewOffset;
4511  BOOLEAN NotAtBase = FALSE;
4512 
4514  {
4515  DPRINT("Mapping ARM3 section into %s\n", Process->ImageFileName);
4517  Process,
4518  BaseAddress,
4519  ZeroBits,
4520  CommitSize,
4521  SectionOffset,
4522  ViewSize,
4525  Protect);
4526  }
4527 
4528  ASSERT(Process);
4529 
4531  {
4533  }
4534 
4535  /* FIXME: We should keep this, but it would break code checking equality */
4536  Protect &= ~PAGE_NOCACHE;
4537 
4539  AddressSpace = &Process->Vm;
4540 
4542 
4543  MmLockAddressSpace(AddressSpace);
4544 
4545  if (Section->AllocationAttributes & SEC_IMAGE)
4546  {
4547  ULONG i;
4548  ULONG NrSegments;
4549  ULONG_PTR ImageBase;
4550  SIZE_T ImageSize;
4551  PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
4552  PMM_SECTION_SEGMENT SectionSegments;
4553 
4554  ImageSectionObject = Section->ImageSection;
4555  SectionSegments = ImageSectionObject->Segments;
4556  NrSegments = ImageSectionObject->NrSegments;
4557 
4558  ImageBase = (ULONG_PTR)*BaseAddress;
4559  if (ImageBase == 0)
4560  {
4561  ImageBase = (ULONG_PTR)ImageSectionObject->BasedAddress;
4562  }
4563 
4564  ImageSize = 0;
4565  for (i = 0; i < NrSegments; i++)
4566  {
4567  ULONG_PTR MaxExtent;
4568  MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
4569  SectionSegments[i].Length.QuadPart);
4570  ImageSize = max(ImageSize, MaxExtent);
4571  }
4572 
4573  ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize;
4574 
4575  /* Check for an illegal base address */
4576  if (((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress) ||
4577  ((ImageBase + ImageSize) < ImageSize))
4578  {
4579  ASSERT(*BaseAddress == NULL);
4580  ImageBase = ALIGN_DOWN_BY((ULONG_PTR)MmHighestUserAddress - ImageSize,
4582  NotAtBase = TRUE;
4583  }
4584  else if (ImageBase != ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY))
4585  {
4586  ASSERT(*BaseAddress == NULL);
4587  ImageBase = ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY);
4588  NotAtBase = TRUE;
4589  }
4590 
4591  /* Check there is enough space to map the section at that point. */
4592  if (MmLocateMemoryAreaByRegion(AddressSpace, (PVOID)ImageBase,
4593  PAGE_ROUND_UP(ImageSize)) != NULL)
4594  {
4595  /* Fail if the user requested a fixed base address. */
4596  if ((*BaseAddress) != NULL)
4597  {
4598  MmUnlockAddressSpace(AddressSpace);
4600  }
4601  /* Otherwise find a gap to map the image. */
4602  ImageBase = (ULONG_PTR)MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), MM_VIRTMEM_GRANULARITY, FALSE);
4603  if (ImageBase == 0)
4604  {
4605  MmUnlockAddressSpace(AddressSpace);
4607  }
4608  /* Remember that we loaded image at a different base address */
4609  NotAtBase = TRUE;
4610  }
4611 
4612  for (i = 0; i < NrSegments; i++)
4613  {
4614  PVOID SBaseAddress = (PVOID)
4615  ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
4616  MmLockSectionSegment(&SectionSegments[i]);
4617  Status = MmMapViewOfSegment(AddressSpace,
4618  Section,
4619  &SectionSegments[i],
4620  &SBaseAddress,
4621  SectionSegments[i].Length.LowPart,
4622  SectionSegments[i].Protection,
4623  0,
4624  0);
4625  MmUnlockSectionSegment(&SectionSegments[i]);
4626  if (!NT_SUCCESS(Status))
4627  {
4628  MmUnlockAddressSpace(AddressSpace);
4629  return(Status);
4630  }
4631  }
4632 
4633  *BaseAddress = (PVOID)ImageBase;
4634  *ViewSize = ImageSize;
4635  }
4636  else
4637  {
4638  /* check for write access */
4641  {
4642  MmUnlockAddressSpace(AddressSpace);
4644  }
4645  /* check for read access */
4648  {
4649  MmUnlockAddressSpace(AddressSpace);
4651  }
4652  /* check for execute access */
4655  {
4656  MmUnlockAddressSpace(AddressSpace);
4658  }
4659 
4660  if (SectionOffset == NULL)
4661  {
4662  ViewOffset = 0;
4663  }
4664  else
4665  {
4666  ViewOffset = SectionOffset->u.LowPart;
4667  }
4668 
4669  if ((ViewOffset % PAGE_SIZE) != 0)
4670  {
4671  MmUnlockAddressSpace(AddressSpace);
4672  return(STATUS_MAPPED_ALIGNMENT);
4673  }
4674 
4675  if ((*ViewSize) == 0)
4676  {
4677  (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset;
4678  }
4679  else if (((*ViewSize)+ViewOffset) > Section->MaximumSize.u.LowPart)
4680  {
4681  (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset;
4682  }
4683 
4685 
4686  MmLockSectionSegment(Section->Segment);
4687  Status = MmMapViewOfSegment(AddressSpace,
4688  Section,
4689  Section->Segment,
4690  BaseAddress,
4691  *ViewSize,
4692  Protect,
4693  ViewOffset,
4695  MmUnlockSectionSegment(Section->Segment);
4696  if (!NT_SUCCESS(Status))
4697  {
4698  MmUnlockAddressSpace(AddressSpace);
4699  return(Status);
4700  }
4701  }
4702 
4703  MmUnlockAddressSpace(AddressSpace);
4705 
4706  if (NotAtBase)
4707  Status = STATUS_IMAGE_NOT_AT_BASE;
4708  else
4709  Status = STATUS_SUCCESS;
4710 
4711  return Status;
4712 }
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT InheritDisposition
Definition: mmfuncs.h:404