ReactOS 0.4.17-dev-357-ga8f14ff
section.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for section.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 

Functions

static BOOLEAN MiIsProtectionCompatible (IN ULONG SectionPageProtection, IN ULONG NewSectionPageProtection)
 
ULONG NTAPI MiMakeProtectionMask (IN ULONG Protect)
 
BOOLEAN NTAPI MiInitializeSystemSpaceMap (IN PMMSESSION InputSession OPTIONAL)
 
static PVOID MiInsertInSystemSpace (IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
 
static NTSTATUS MiAddMappedPtes (IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea, IN LONGLONG SectionOffset)
 
VOID NTAPI MiFillSystemPageDirectory (IN PVOID Base, IN SIZE_T NumberOfBytes)
 
static NTSTATUS MiCheckPurgeAndUpMapCount (IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
 
PSUBSECTION NTAPI MiLocateSubsection (IN PMMVAD Vad, IN ULONG_PTR Vpn)
 
static VOID MiSegmentDelete (IN PSEGMENT Segment)
 
static VOID MiCheckControlArea (IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
 
static VOID MiDereferenceControlArea (IN PCONTROL_AREA ControlArea)
 
VOID NTAPI MiRemoveMappedView (IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
 
static NTSTATUS MiUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
 
static NTSTATUS MiSessionCommitPageTables (IN PVOID StartVa, IN PVOID EndVa)
 
NTSTATUS MiMapViewInSystemSpace (_In_ PVOID Section, _In_ PMMSESSION Session, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset)
 
static NTSTATUS MiMapViewOfDataSection (_In_ PCONTROL_AREA ControlArea, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _Inout_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_ PSECTION Section, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG ProtectionMask, _In_ SIZE_T CommitSize, _In_ ULONG_PTR ZeroBits, _In_ ULONG AllocationType)
 
static NTSTATUS MiCreateDataFileMap (IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
 
static NTSTATUS MiCreatePagingFileMap (OUT PSEGMENT *Segment, IN ULONG64 MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
 
PFILE_OBJECT NTAPI MmGetFileObjectForSection (IN PVOID SectionObject)
 
static PFILE_OBJECT MiGetFileObjectForVad (_In_ PMMVAD Vad)
 
VOID NTAPI MmGetImageInformation (OUT PSECTION_IMAGE_INFORMATION ImageInformation)
 
static NTSTATUS MmGetFileNameForFileObject (IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
 
NTSTATUS NTAPI MmGetFileNameForSection (IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
 
NTSTATUS NTAPI MmGetFileNameForAddress (IN PVOID Address, OUT PUNICODE_STRING ModuleName)
 
NTSTATUS NTAPI MiQueryMemorySectionName (IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
 
VOID NTAPI MiFlushTbAndCapture (IN PMMVAD FoundVad, IN PMMPTE PointerPte, IN ULONG ProtectionMask, IN PMMPFN Pfn1, IN BOOLEAN UpdateDirty)
 
static VOID MiRemoveMappedPtes (IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
 
static ULONG MiRemoveFromSystemSpace (IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
 
static NTSTATUS MiUnmapViewInSystemSpace (IN PMMSESSION Session, IN PVOID MappedBase)
 
NTSTATUS NTAPI MmCreateArm3Section (OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER InputMaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
 
NTSTATUS NTAPI MmMapViewOfArm3Section (_In_ PVOID SectionObject, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _When_(*ViewSize !=0, _Pre_opt_valid_) _When_(*ViewSize==0, _Pre_valid_) PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Protect)
 
BOOLEAN NTAPI MmDisableModifiedWriteOfSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
 
BOOLEAN NTAPI MmForceSectionClosed (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
 
NTSTATUS NTAPI MmMapViewInSessionSpace (IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
 
NTSTATUS NTAPI MmUnmapViewInSessionSpace (IN PVOID MappedBase)
 
NTSTATUS NTAPI MmUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress)
 
NTSTATUS NTAPI MmUnmapViewInSystemSpace (IN PVOID MappedBase)
 
NTSTATUS NTAPI MmCommitSessionMappedView (IN PVOID MappedBase, IN SIZE_T ViewSize)
 
VOID NTAPI MiDeleteARM3Section (PVOID ObjectBody)
 
ULONG NTAPI MmDoesFileHaveUserWritableReferences (IN PSECTION_OBJECT_POINTERS SectionPointer)
 
NTSTATUS NTAPI NtAreMappedFilesTheSame (IN PVOID File1MappedAsAnImage, IN PVOID File2MappedAsFile)
 
NTSTATUS NTAPI NtCreateSection (OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
 
NTSTATUS NTAPI NtOpenSection (OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
 
NTSTATUS NTAPI NtMapViewOfSection (_In_ HANDLE SectionHandle, _In_ HANDLE ProcessHandle, _Outptr_result_bytebuffer_(*ViewSize) _Pre_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Win32Protect)
 
NTSTATUS NTAPI NtUnmapViewOfSection (IN HANDLE ProcessHandle, IN PVOID BaseAddress)
 
NTSTATUS NTAPI NtExtendSection (IN HANDLE SectionHandle, IN OUT PLARGE_INTEGER NewMaximumSize)
 

Variables

ACCESS_MASK MmMakeSectionAccess [8]
 
ACCESS_MASK MmMakeFileAccess [8]
 
CHAR MmUserProtectionToMask1 [16]
 
CHAR MmUserProtectionToMask2 [16]
 
ULONG MmCompatibleProtectionMask [8]
 
MMSESSION MmSession
 
KGUARDED_MUTEX MmSectionCommitMutex
 
MM_AVL_TABLE MmSectionBasedRoot
 
KGUARDED_MUTEX MmSectionBasedMutex
 
PVOID MmHighSectionBase
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 15 of file section.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file section.c.

Function Documentation

◆ MiAddMappedPtes()

static NTSTATUS MiAddMappedPtes ( IN PMMPTE  FirstPte,
IN PFN_NUMBER  PteCount,
IN PCONTROL_AREA  ControlArea,
IN LONGLONG  SectionOffset 
)
static

Definition at line 401 of file section.c.

405{
407 PMMPTE PointerPte, ProtoPte, LastProtoPte, LastPte;
408 PSUBSECTION Subsection;
409
410 /* Mapping at offset not supported yet */
411 ASSERT(SectionOffset == 0);
412
413 /* ARM3 doesn't support this yet */
414 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
415 ASSERT(ControlArea->u.Flags.Rom == 0);
416 ASSERT(ControlArea->FilePointer == NULL);
417
418 /* Sanity checks */
419 ASSERT(PteCount != 0);
420 ASSERT(ControlArea->NumberOfMappedViews >= 1);
421 ASSERT(ControlArea->NumberOfUserReferences >= 1);
422 ASSERT(ControlArea->NumberOfSectionReferences != 0);
423 ASSERT(ControlArea->u.Flags.BeingCreated == 0);
424 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
425 ASSERT(ControlArea->u.Flags.BeingPurged == 0);
426
427 /* Get the PTEs for the actual mapping */
428 PointerPte = FirstPte;
429 LastPte = FirstPte + PteCount;
430
431 /* Get the prototype PTEs that desribe the section mapping in the subsection */
432 Subsection = (PSUBSECTION)(ControlArea + 1);
433 ProtoPte = Subsection->SubsectionBase;
434 LastProtoPte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
435
436 /* Loop the PTEs for the mapping */
437 while (PointerPte < LastPte)
438 {
439 /* We may have run out of prototype PTEs in this subsection */
440 if (ProtoPte >= LastProtoPte)
441 {
442 /* But we don't handle this yet */
443 ASSERT(FALSE);
444 }
445
446 /* The PTE should be completely clear */
447 ASSERT(PointerPte->u.Long == 0);
448
449 /* Build the prototype PTE and write it */
450 MI_MAKE_PROTOTYPE_PTE(&TempPte, ProtoPte);
451 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
452
453 /* Keep going */
454 PointerPte++;
455 ProtoPte++;
456 }
457
458 /* No failure path */
459 return STATUS_SUCCESS;
460}
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:1000
#define ASSERT(a)
Definition: mode.c:44
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
struct _SUBSECTION * PSUBSECTION
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, IN PMMPTE PointerPte)
Definition: mm.h:342
#define STATUS_SUCCESS
Definition: shellext.h:65
union _MMPTE::@2548 u
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG PtesInSubsection
Definition: mmtypes.h:583
PMMPTE SubsectionBase
Definition: mmtypes.h:581

Referenced by MiMapViewInSystemSpace().

◆ MiCheckControlArea()

static VOID MiCheckControlArea ( IN PCONTROL_AREA  ControlArea,
IN KIRQL  OldIrql 
)
static

Definition at line 716 of file section.c.

718{
719 BOOLEAN DeleteSegment = FALSE;
721
722 /* Check if this is the last reference or view */
723 if (!(ControlArea->NumberOfMappedViews) &&
724 !(ControlArea->NumberOfSectionReferences))
725 {
726 /* There should be no more user references either */
727 ASSERT(ControlArea->NumberOfUserReferences == 0);
728
729 /* Not yet supported */
730 ASSERT(ControlArea->FilePointer == NULL);
731
732 /* The control area is being destroyed */
733 ControlArea->u.Flags.BeingDeleted = TRUE;
734 DeleteSegment = TRUE;
735 }
736
737 /* Release the PFN lock */
738 MiReleasePfnLock(OldIrql);
739
740 /* Delete the segment if needed */
741 if (DeleteSegment)
742 {
743 /* No more user write references at all */
744 ASSERT(ControlArea->WritableUserReferences == 0);
745 MiSegmentDelete(ControlArea->Segment);
746 }
747}
static VOID MiSegmentDelete(IN PSEGMENT Segment)
Definition: section.c:593
unsigned char BOOLEAN
Definition: actypes.h:127
#define TRUE
Definition: types.h:120
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:1042
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by MiDeleteARM3Section(), MiDereferenceControlArea(), MiRemoveMappedPtes(), MiRemoveMappedView(), and MmCreateArm3Section().

◆ MiCheckPurgeAndUpMapCount()

static NTSTATUS MiCheckPurgeAndUpMapCount ( IN PCONTROL_AREA  ControlArea,
IN BOOLEAN  FailIfSystemViews 
)
static

Definition at line 532 of file section.c.

534{
536
537 /* Flag not yet supported */
538 ASSERT(FailIfSystemViews == FALSE);
539
540 /* Lock the PFN database */
541 OldIrql = MiAcquirePfnLock();
542
543 /* State not yet supported */
544 ASSERT(ControlArea->u.Flags.BeingPurged == 0);
545
546 /* Increase the reference counts */
547 ControlArea->NumberOfMappedViews++;
548 ControlArea->NumberOfUserReferences++;
549 ASSERT(ControlArea->NumberOfSectionReferences != 0);
550
551 /* Release the PFN lock and return success */
552 MiReleasePfnLock(OldIrql);
553 return STATUS_SUCCESS;
554}
UCHAR KIRQL
Definition: env_spec_w32.h:591

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

◆ MiCreateDataFileMap()

static NTSTATUS MiCreateDataFileMap ( IN PFILE_OBJECT  File,
OUT PSEGMENT Segment,
IN PLARGE_INTEGER  MaximumSize,
IN ULONG  SectionPageProtection,
IN ULONG  AllocationAttributes,
IN ULONG  IgnoreFileSizing 
)
static

Definition at line 1412 of file section.c.

1418{
1419 /* Not yet implemented */
1420 ASSERT(FALSE);
1421 *Segment = NULL;
1423}
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

Referenced by MmCreateArm3Section().

◆ MiCreatePagingFileMap()

static NTSTATUS MiCreatePagingFileMap ( OUT PSEGMENT Segment,
IN ULONG64  MaximumSize,
IN ULONG  ProtectionMask,
IN ULONG  AllocationAttributes 
)
static

Definition at line 1427 of file section.c.

1431{
1432 ULONGLONG SizeLimit;
1433 PFN_COUNT PteCount;
1434 PMMPTE PointerPte;
1435 MMPTE TempPte;
1436 PCONTROL_AREA ControlArea;
1437 PSEGMENT NewSegment;
1438 PSUBSECTION Subsection;
1439 PAGED_CODE();
1440
1441 /* No large pages in ARM3 yet */
1443
1444 /* Pagefile-backed sections need a known size */
1445 if (MaximumSize == 0)
1447
1448 /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1449 SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
1450 SizeLimit /= sizeof(MMPTE);
1451 SizeLimit <<= PAGE_SHIFT;
1452
1453 /* Fail if this size is too big */
1454 if (MaximumSize > SizeLimit)
1455 {
1457 }
1458
1459 /* Calculate how many Prototype PTEs will be needed */
1460 PteCount = (PFN_COUNT)((MaximumSize + PAGE_SIZE - 1) >> PAGE_SHIFT);
1461
1462 /* For commited memory, we must have a valid protection mask */
1463 if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1464
1465 /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1466 NewSegment = ExAllocatePoolWithTag(PagedPool,
1467 sizeof(SEGMENT) +
1468 sizeof(MMPTE) * (PteCount - 1),
1469 'tSmM');
1470 if (!NewSegment)
1471 {
1473 }
1474 *Segment = NewSegment;
1475
1476 /* Now allocate the control area, which has the subsection structure */
1477 ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1478 sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1479 'tCmM');
1480 if (!ControlArea)
1481 {
1482 ExFreePoolWithTag(Segment, 'tSmM');
1484 }
1485
1486 /* And zero it out, filling the basic segmnet pointer and reference fields */
1487 RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1488 ControlArea->Segment = NewSegment;
1489 ControlArea->NumberOfSectionReferences = 1;
1490 ControlArea->NumberOfUserReferences = 1;
1491
1492 /* Convert allocation attributes to control area flags */
1493 if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1494 if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1495 if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1496
1497 /* We just allocated it */
1498 ControlArea->u.Flags.BeingCreated = 1;
1499
1500 /* The subsection follows, write the mask, PTE count and point back to the CA */
1501 Subsection = (PSUBSECTION)(ControlArea + 1);
1502 Subsection->ControlArea = ControlArea;
1503 Subsection->PtesInSubsection = PteCount;
1504 Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1505
1506 /* Zero out the segment's prototype PTEs, and link it with the control area */
1507 PointerPte = &NewSegment->ThePtes[0];
1508 RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1509 NewSegment->PrototypePte = PointerPte;
1510 NewSegment->ControlArea = ControlArea;
1511
1512 /* Save some extra accounting data for the segment as well */
1513 NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1514 NewSegment->SizeOfSegment = ((ULONGLONG)PteCount) * PAGE_SIZE;
1515 NewSegment->TotalNumberOfPtes = PteCount;
1516 NewSegment->NonExtendedPtes = PteCount;
1517
1518 /* The subsection's base address is the first Prototype PTE in the segment */
1519 Subsection->SubsectionBase = PointerPte;
1520
1521 /* Start with an empty PTE, unless this is a commit operation */
1522 TempPte.u.Long = 0;
1524 {
1525 /* In which case, write down the protection mask in the Prototype PTEs */
1526 TempPte.u.Soft.Protection = ProtectionMask;
1527
1528 /* For accounting, also mark these pages as being committed */
1529 NewSegment->NumberOfCommittedPages = PteCount;
1530 }
1531
1532 /* The template PTE itself for the segment should also have the mask set */
1533 NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1534
1535 /* Write out the prototype PTEs, for now they're simply demand zero */
1536#ifdef _WIN64
1537 RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1538#else
1539 RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1540#endif
1541 return STATUS_SUCCESS;
1542}
#define PAGED_CODE()
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
SIZE_T MmSizeOfPagedPoolInBytes
Definition: miarm.h:590
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _MMPTE MMPTE
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG AllocationAttributes
Definition: mmfuncs.h:364
struct _SEGMENT SEGMENT
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SEC_LARGE_PAGES
Definition: mmtypes.h:103
#define SEC_RESERVE
Definition: nt_native.h:1326
#define SEC_BASED
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:572
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:394
PSEGMENT Segment
Definition: mmtypes.h:521
ULONG NumberOfSectionReferences
Definition: mmtypes.h:523
ULONG NumberOfUserReferences
Definition: mmtypes.h:527
MMSECTION_FLAGS Flags
Definition: mmtypes.h:531
union _CONTROL_AREA::@2862 u
ULONG64 Protection
Definition: mmtypes.h:88
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
ULONG BeingCreated
Definition: mmtypes.h:464
union _SEGMENT::@2860 u1
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:409
PEPROCESS CreatingProcess
Definition: mmtypes.h:422
ULONG TotalNumberOfPtes
Definition: mmtypes.h:410
MMPTE SegmentPteTemplate
Definition: mmtypes.h:414
PMMPTE PrototypePte
Definition: mmtypes.h:429
MMPTE ThePtes[1]
Definition: mmtypes.h:430
ULONGLONG SizeOfSegment
Definition: mmtypes.h:413
ULONG NonExtendedPtes
Definition: mmtypes.h:411
ULONG NumberOfCommittedPages
Definition: mmtypes.h:415
union _SUBSECTION::@2864 u
MMSUBSECTION_FLAGS SubsectionFlags
Definition: mmtypes.h:577
PCONTROL_AREA ControlArea
Definition: mmtypes.h:573
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define PsGetCurrentProcess
Definition: psfuncs.h:17
NTSYSAPI VOID NTAPI RtlFillMemoryUlonglong(_Out_writes_bytes_all_(Length) PVOID Destination, _In_ SIZE_T Length, _In_ ULONGLONG Pattern)

Referenced by MmCreateArm3Section().

◆ MiDeleteARM3Section()

VOID NTAPI MiDeleteARM3Section ( PVOID  ObjectBody)

Definition at line 2965 of file section.c.

2966{
2968 PCONTROL_AREA ControlArea;
2969 KIRQL OldIrql;
2970
2971 SectionObject = (PSECTION)ObjectBody;
2972
2973 if (SectionObject->u.Flags.Based == 1)
2974 {
2975 /* Remove the node from the global section address tree */
2979 }
2980
2981 /* Lock the PFN database */
2982 OldIrql = MiAcquirePfnLock();
2983
2984 ASSERT(SectionObject->Segment);
2985 ASSERT(SectionObject->Segment->ControlArea);
2986
2987 ControlArea = SectionObject->Segment->ControlArea;
2988
2989 /* Dereference */
2990 ControlArea->NumberOfSectionReferences--;
2991 ControlArea->NumberOfUserReferences--;
2992
2993 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
2994
2995 /* Check it. It will delete it if there is no more reference to it */
2996 MiCheckControlArea(ControlArea, OldIrql);
2997}
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
static VOID MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:716
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:403
struct _SECTION * PSECTION
ULONG BeingDeleted
Definition: mmtypes.h:463

Referenced by MmpDeleteSection().

◆ MiDereferenceControlArea()

static VOID MiDereferenceControlArea ( IN PCONTROL_AREA  ControlArea)
static

Definition at line 751 of file section.c.

752{
754
755 /* Lock the PFN database */
756 OldIrql = MiAcquirePfnLock();
757
758 /* Drop reference counts */
759 ControlArea->NumberOfMappedViews--;
760 ControlArea->NumberOfUserReferences--;
761
762 /* Check if it's time to delete the CA. This releases the lock */
763 MiCheckControlArea(ControlArea, OldIrql);
764}

Referenced by MiMapViewInSystemSpace(), and MiMapViewOfDataSection().

◆ MiFillSystemPageDirectory()

VOID NTAPI MiFillSystemPageDirectory ( IN PVOID  Base,
IN SIZE_T  NumberOfBytes 
)

Definition at line 464 of file section.c.

466{
467 PMMPDE PointerPde, LastPde, SystemMapPde;
469 PFN_NUMBER PageFrameIndex, ParentPage;
471 PAGED_CODE();
472
473 /* Find the PDEs needed for this mapping */
474 PointerPde = MiAddressToPde(Base);
475 LastPde = MiAddressToPde((PVOID)((ULONG_PTR)Base + NumberOfBytes - 1));
476
477#if (_MI_PAGING_LEVELS == 2)
478 /* Find the system double-mapped PDE that describes this mapping */
479 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
480#else
481 /* We don't have a double mapping */
482 SystemMapPde = PointerPde;
483#endif
484
485 /* Use the PDE template and loop the PDEs */
487 while (PointerPde <= LastPde)
488 {
489 /* Lock the PFN database */
490 OldIrql = MiAcquirePfnLock();
491
492 /* Check if we don't already have this PDE mapped */
493 if (SystemMapPde->u.Hard.Valid == 0)
494 {
495 /* Grab a page for it */
497 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
498 PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
499 ASSERT(PageFrameIndex);
500 TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
501
502#if (_MI_PAGING_LEVELS == 2)
503 ParentPage = MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_PER_PAGE];
504#else
505 ParentPage = MiPdeToPpe(PointerPde)->u.Hard.PageFrameNumber;
506#endif
507 /* Initialize its PFN entry, with the parent system page directory page table */
508 MiInitializePfnForOtherProcess(PageFrameIndex,
509 (PMMPTE)PointerPde,
510 ParentPage);
511
512 /* Make the system PDE entry valid */
513 MI_WRITE_VALID_PDE(SystemMapPde, TempPde);
514
515 /* The system PDE entry might be the PDE itself, so check for this */
516 if (PointerPde->u.Hard.Valid == 0)
517 {
518 /* It's different, so make the real PDE valid too */
519 MI_WRITE_VALID_PDE(PointerPde, TempPde);
520 }
521 }
522
523 /* Release the lock and keep going with the next PDE */
524 MiReleasePfnLock(OldIrql);
525 SystemMapPde++;
526 PointerPde++;
527 }
528}
ULONG_PTR PFN_NUMBER
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
#define ULONG_PTR
Definition: config.h:101
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:537
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:236
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1301
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1025
#define SYSTEM_PD_SIZE
Definition: miarm.h:32
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
FORCEINLINE PMMPDE MiPdeToPpe(PMMPDE PointerPde)
Definition: mm.h:292
#define MiAddressToPde(x)
Definition: mm.h:156
#define PDE_PER_PAGE
Definition: mm.h:21
#define MI_SET_PROCESS2(x)
Definition: mm.h:329
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:344
#define MI_SET_USAGE(x)
Definition: mm.h:327
PMMPDE MmSystemPagePtes
Definition: init.c:41
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
MMPTE ValidKernelPde
Definition: init.c:28
ULONG PageFrameNumber
Definition: mmtypes.h:74
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036

Referenced by MiMapViewInSystemSpace(), and MmCreateVirtualMappingUnsafeEx().

◆ MiFlushTbAndCapture()

VOID NTAPI MiFlushTbAndCapture ( IN PMMVAD  FoundVad,
IN PMMPTE  PointerPte,
IN ULONG  ProtectionMask,
IN PMMPFN  Pfn1,
IN BOOLEAN  UpdateDirty 
)

Definition at line 1827 of file section.c.

1832{
1833 MMPTE TempPte, PreviousPte;
1834 KIRQL OldIrql;
1835 BOOLEAN RebuildPte = FALSE;
1836
1837 //
1838 // User for sanity checking later on
1839 //
1840 PreviousPte = *PointerPte;
1841
1842 //
1843 // Build the PTE and acquire the PFN lock
1844 //
1846 PointerPte,
1847 ProtectionMask,
1848 PreviousPte.u.Hard.PageFrameNumber);
1849 OldIrql = MiAcquirePfnLock();
1850
1851 //
1852 // We don't support I/O mappings in this path yet
1853 //
1854 ASSERT(Pfn1 != NULL);
1855 ASSERT(Pfn1->u3.e1.CacheAttribute != MiWriteCombined);
1856
1857 //
1858 // Make sure new protection mask doesn't get in conflict and fix it if it does
1859 //
1860 if (Pfn1->u3.e1.CacheAttribute == MiCached)
1861 {
1862 //
1863 // This is a cached PFN
1864 //
1865 if (ProtectionMask & (MM_NOCACHE | MM_NOACCESS))
1866 {
1867 RebuildPte = TRUE;
1868 ProtectionMask &= ~(MM_NOCACHE | MM_NOACCESS);
1869 }
1870 }
1871 else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
1872 {
1873 //
1874 // This is a non-cached PFN
1875 //
1876 if ((ProtectionMask & (MM_NOCACHE | MM_NOACCESS)) != MM_NOCACHE)
1877 {
1878 RebuildPte = TRUE;
1879 ProtectionMask &= ~MM_NOACCESS;
1880 ProtectionMask |= MM_NOCACHE;
1881 }
1882 }
1883
1884 if (RebuildPte)
1885 {
1887 PointerPte,
1888 ProtectionMask,
1889 PreviousPte.u.Hard.PageFrameNumber);
1890 }
1891
1892 //
1893 // Write the new PTE, making sure we are only changing the bits
1894 //
1895 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
1896
1897 //
1898 // Flush the TLB
1899 //
1900 ASSERT(PreviousPte.u.Hard.Valid == 1);
1902 ASSERT(PreviousPte.u.Hard.Valid == 1);
1903
1904 //
1905 // Windows updates the relevant PFN1 information, we currently don't.
1906 //
1907 if (UpdateDirty && PreviousPte.u.Hard.Dirty)
1908 {
1909 if (!Pfn1->u3.e1.Modified)
1910 {
1911 DPRINT1("FIXME: Mark PFN as dirty\n");
1912 }
1913 }
1914
1915 //
1916 // Not supported in ARM3
1917 //
1918 ASSERT(FoundVad->u.VadFlags.VadType != VadWriteWatch);
1919
1920 //
1921 // Release the PFN lock, we are done
1922 //
1923 MiReleasePfnLock(OldIrql);
1924}
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:834
#define MM_NOCACHE
Definition: miarm.h:56
@ MiWriteCombined
Definition: miarm.h:416
@ MiCached
Definition: miarm.h:415
@ MiNonCached
Definition: miarm.h:414
#define MM_NOACCESS
Definition: miarm.h:65
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:985
@ VadWriteWatch
Definition: mmtypes.h:208
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:535
ULONG64 Dirty
Definition: mmtypes.h:164

Referenced by MiProtectVirtualMemory().

◆ MiGetFileObjectForVad()

static PFILE_OBJECT MiGetFileObjectForVad ( _In_ PMMVAD  Vad)
static

Definition at line 1565 of file section.c.

1567{
1568 PCONTROL_AREA ControlArea;
1570
1571 /* Check if this is a RosMm memory area */
1572 if (MI_IS_MEMORY_AREA_VAD(Vad))
1573 {
1575
1576 /* We do not expect ARM3 memory areas here, those are kernel only */
1577 ASSERT(MI_IS_ROSMM_VAD(Vad));
1578
1579 /* Check if it's a section view (RosMm section) */
1581 {
1582 /* Get the section pointer to the SECTION_OBJECT */
1583 FileObject = MemoryArea->SectionData.Segment->FileObject;
1584 }
1585 else
1586 {
1587#ifdef NEWCC
1588 ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1589 DPRINT1("VAD is a cache section!\n");
1590#else
1591 ASSERT(FALSE);
1592#endif
1593 return NULL;
1594 }
1595 }
1596 else
1597 {
1598 /* Make sure it's not a VM VAD */
1599 if (Vad->u.VadFlags.PrivateMemory == 1)
1600 {
1601 DPRINT1("VAD is not a section\n");
1602 return NULL;
1603 }
1604
1605 /* Get the control area */
1606 ControlArea = Vad->ControlArea;
1607 if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1608 {
1609 DPRINT1("Address is not a section\n");
1610 return NULL;
1611 }
1612
1613 /* Get the file object */
1614 FileObject = ControlArea->FilePointer;
1615 }
1616
1617 /* Return the file object */
1618 return FileObject;
1619}
_In_ PMEMORY_AREA MemoryArea
Definition: newmm.h:207
struct _MEMORY_AREA * PMEMORY_AREA
#define MI_IS_MEMORY_AREA_VAD(Vad)
Definition: mm.h:271
#define MI_IS_ROSMM_VAD(Vad)
Definition: mm.h:273
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
PFILE_OBJECT FilePointer
Definition: mmtypes.h:533
struct _MEMORY_AREA::@1962 SectionData
ULONG Type
Definition: mm.h:257
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by MmGetFileNameForAddress(), and NtAreMappedFilesTheSame().

◆ MiInitializeSystemSpaceMap()

BOOLEAN NTAPI MiInitializeSystemSpaceMap ( IN PMMSESSION InputSession  OPTIONAL)

Definition at line 222 of file section.c.

223{
224 SIZE_T AllocSize, BitmapSize, Size;
225 PVOID ViewStart;
226 PMMSESSION Session;
227
228 /* Check if this a session or system space */
229 if (InputSession)
230 {
231 /* Use the input session */
232 Session = InputSession;
233 ViewStart = MiSessionViewStart;
235 }
236 else
237 {
238 /* Use the system space "session" */
239 Session = &MmSession;
240 ViewStart = MiSystemViewStart;
242 }
243
244 /* Initialize the system space lock */
247
248 /* Set the start address */
249 Session->SystemSpaceViewStart = ViewStart;
250
251 /* Create a bitmap to describe system space */
252 BitmapSize = sizeof(RTL_BITMAP) + ((((Size / MI_SYSTEM_VIEW_BUCKET_SIZE) + 31) / 32) * sizeof(ULONG));
254 BitmapSize,
255 TAG_MM);
256 ASSERT(Session->SystemSpaceBitMap);
258 (PULONG)(Session->SystemSpaceBitMap + 1),
260
261 /* Set system space fully empty to begin with */
263
264 /* Set default hash flags */
265 Session->SystemSpaceHashSize = 31;
266 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
267 Session->SystemSpaceHashEntries = 0;
268
269 /* Calculate how much space for the hash views we'll need */
270 AllocSize = sizeof(MMVIEW) * Session->SystemSpaceHashSize;
271 ASSERT(AllocSize < PAGE_SIZE);
272
273 /* Allocate and zero the view table */
276 PagedPool,
277 AllocSize,
278 TAG_MM);
279 ASSERT(Session->SystemSpaceViewTable != NULL);
280 RtlZeroMemory(Session->SystemSpaceViewTable, AllocSize);
281
282 /* Success */
283 return TRUE;
284}
MMSESSION MmSession
Definition: section.c:107
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlClearAllBits
Definition: dbgbitmap.h:329
#define RTL_BITMAP
Definition: dbgbitmap.h:323
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define MI_SYSTEM_VIEW_BUCKET_SIZE
Definition: miarm.h:265
struct _MMVIEW MMVIEW
PVOID MiSessionViewStart
Definition: init.c:30
ULONG MmSessionViewSize
Definition: init.c:35
ULONG MmSystemViewSize
Definition: init.c:39
PVOID MiSystemViewStart
Definition: init.c:38
ULONG SystemSpaceHashKey
Definition: miarm.h:460
ULONG SystemSpaceHashEntries
Definition: miarm.h:459
PKGUARDED_MUTEX SystemSpaceViewLockPointer
Definition: miarm.h:455
PRTL_BITMAP SystemSpaceBitMap
Definition: miarm.h:462
PCHAR SystemSpaceViewStart
Definition: miarm.h:456
ULONG SystemSpaceHashSize
Definition: miarm.h:458
PMMVIEW SystemSpaceViewTable
Definition: miarm.h:457
KGUARDED_MUTEX SystemSpaceViewLock
Definition: miarm.h:454
#define TAG_MM
Definition: tag.h:113
uint32_t * PULONG
Definition: typedefs.h:59
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by MiBuildPagedPool(), and MiSessionCreateInternal().

◆ MiInsertInSystemSpace()

static PVOID MiInsertInSystemSpace ( IN PMMSESSION  Session,
IN ULONG  Buckets,
IN PCONTROL_AREA  ControlArea 
)
static

Definition at line 288 of file section.c.

291{
292 PVOID Base;
293 ULONG Hash, i, HashSize;
295 PMMVIEW OldTable;
296 PAGED_CODE();
297
298 /* Stay within 4GB */
300
301 /* Lock system space */
302 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
303
304 /* Check if we're going to exhaust hash entries */
305 if ((Session->SystemSpaceHashEntries + 8) > Session->SystemSpaceHashSize)
306 {
307 /* Double the hash size */
308 HashSize = Session->SystemSpaceHashSize * 2;
309
310 /* Save the old table and allocate a new one */
311 OldTable = Session->SystemSpaceViewTable;
312 Session->SystemSpaceViewTable = ExAllocatePoolWithTag(Session ==
313 &MmSession ?
315 PagedPool,
316 HashSize *
317 sizeof(MMVIEW),
318 TAG_MM);
319 if (!Session->SystemSpaceViewTable)
320 {
321 /* Failed to allocate a new table, keep the old one for now */
322 Session->SystemSpaceViewTable = OldTable;
323 }
324 else
325 {
326 /* Clear the new table and set the new ahsh and key */
327 RtlZeroMemory(Session->SystemSpaceViewTable, HashSize * sizeof(MMVIEW));
328 Session->SystemSpaceHashSize = HashSize;
329 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
330
331 /* Loop the old table */
332 for (i = 0; i < Session->SystemSpaceHashSize / 2; i++)
333 {
334 /* Check if the entry was valid */
335 if (OldTable[i].Entry)
336 {
337 /* Re-hash the old entry and search for space in the new table */
338 Hash = (OldTable[i].Entry >> 16) % Session->SystemSpaceHashKey;
339 while (Session->SystemSpaceViewTable[Hash].Entry)
340 {
341 /* Loop back at the beginning if we had an overflow */
342 if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
343 }
344
345 /* Write the old entry in the new table */
346 Session->SystemSpaceViewTable[Hash] = OldTable[i];
347 }
348 }
349
350 /* Free the old table */
351 ExFreePool(OldTable);
352 }
353 }
354
355 /* Check if we ran out */
356 if (Session->SystemSpaceHashEntries == Session->SystemSpaceHashSize)
357 {
358 DPRINT1("Ran out of system view hash entries\n");
359 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
360 return NULL;
361 }
362
363 /* Find space where to map this view */
364 i = RtlFindClearBitsAndSet(Session->SystemSpaceBitMap, Buckets, 0);
365 if (i == 0xFFFFFFFF)
366 {
367 /* Out of space, fail */
368 Session->BitmapFailures++;
369 DPRINT1("Out of system view space\n");
370 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
371 return NULL;
372 }
373
374 /* Compute the base address */
375 Base = (PVOID)((ULONG_PTR)Session->SystemSpaceViewStart + (i * MI_SYSTEM_VIEW_BUCKET_SIZE));
377
378 /* Get the hash entry for this allocation */
379 Entry = (ULONG_PTR)Base + Buckets;
380 Hash = (Entry >> 16) % Session->SystemSpaceHashKey;
381
382 /* Loop hash entries until a free one is found */
383 while (Session->SystemSpaceViewTable[Hash].Entry)
384 {
385 /* Unless we overflow, in which case loop back at hash o */
386 if (++Hash >= Session->SystemSpaceHashSize) Hash = 0;
387 }
388
389 /* Add this entry into the hash table */
390 Session->SystemSpaceViewTable[Hash].Entry = Entry;
391 Session->SystemSpaceViewTable[Hash].ControlArea = ControlArea;
392
393 /* Hash entry found, increment total and return the base address */
394 Session->SystemSpaceHashEntries++;
395 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
396 return Base;
397}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
static int Hash(const char *)
Definition: reader.c:2237
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Entry
Definition: section.c:5216
Definition: miarm.h:447
ULONG_PTR Entry
Definition: miarm.h:448
void * PVOID
Definition: typedefs.h:50
#define NT_ASSERT
Definition: rtlfuncs.h:3327

Referenced by MiMapViewInSystemSpace().

◆ MiIsProtectionCompatible()

static BOOLEAN MiIsProtectionCompatible ( IN ULONG  SectionPageProtection,
IN ULONG  NewSectionPageProtection 
)
static

Definition at line 117 of file section.c.

119{
120 ULONG ProtectionMask, CompatibleMask;
121
122 /* Calculate the protection mask and make sure it's valid */
124 if (ProtectionMask == MM_INVALID_PROTECTION)
125 {
126 DPRINT1("Invalid protection mask\n");
127 return FALSE;
128 }
129
130 /* Calculate the compatible mask */
131 CompatibleMask = MmCompatibleProtectionMask[ProtectionMask & 0x7] |
133
134 /* See if the mapping protection is compatible with the create protection */
135 return ((CompatibleMask | NewSectionPageProtection) == CompatibleMask);
136}
ULONG MmCompatibleProtectionMask[8]
Definition: section.c:84
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:140
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:363
#define PAGE_NOCACHE
Definition: nt_native.h:1314
#define PAGE_GUARD
Definition: nt_native.h:1313
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78

Referenced by MmMapViewOfArm3Section().

◆ MiLocateSubsection()

PSUBSECTION NTAPI MiLocateSubsection ( IN PMMVAD  Vad,
IN ULONG_PTR  Vpn 
)

Definition at line 558 of file section.c.

560{
561 PSUBSECTION Subsection;
562 PCONTROL_AREA ControlArea;
563 ULONG_PTR PteOffset;
564
565 /* Get the control area */
566 ControlArea = Vad->ControlArea;
567 ASSERT(ControlArea->u.Flags.Rom == 0);
568 ASSERT(ControlArea->u.Flags.Image == 0);
569 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
570
571 /* Get the subsection */
572 Subsection = (PSUBSECTION)(ControlArea + 1);
573
574 /* We only support single-subsection segments */
575 ASSERT(Subsection->SubsectionBase != NULL);
576 ASSERT(Vad->FirstPrototypePte >= Subsection->SubsectionBase);
577 ASSERT(Vad->FirstPrototypePte < &Subsection->SubsectionBase[Subsection->PtesInSubsection]);
578
579 /* Compute the PTE offset */
580 PteOffset = Vpn - Vad->StartingVpn;
581 PteOffset += Vad->FirstPrototypePte - Subsection->SubsectionBase;
582
583 /* Again, we only support single-subsection segments */
584 ASSERT(PteOffset < 0xF0000000);
585 ASSERT(PteOffset < Subsection->PtesInSubsection);
586
587 /* Return the subsection */
588 return Subsection;
589}
ULONG GlobalOnlyPerSession
Definition: mmtypes.h:491

Referenced by MiDeleteVirtualAddresses().

◆ MiMakeProtectionMask()

ULONG NTAPI MiMakeProtectionMask ( IN ULONG  Protect)

Definition at line 140 of file section.c.

141{
142 ULONG Mask1, Mask2, ProtectMask;
143
144 /* PAGE_EXECUTE_WRITECOMBINE is theoretically the maximum */
146
147 /*
148 * Windows API protection mask can be understood as two bitfields, differing
149 * by whether or not execute rights are being requested
150 */
151 Mask1 = Protect & 0xF;
152 Mask2 = (Protect >> 4) & 0xF;
153
154 /* Check which field is there */
155 if (!Mask1)
156 {
157 /* Mask2 must be there, use it to determine the PTE protection */
158 if (!Mask2) return MM_INVALID_PROTECTION;
159 ProtectMask = MmUserProtectionToMask2[Mask2];
160 }
161 else
162 {
163 /* Mask2 should not be there, use Mask1 to determine the PTE mask */
164 if (Mask2) return MM_INVALID_PROTECTION;
165 ProtectMask = MmUserProtectionToMask1[Mask1];
166 }
167
168 /* Make sure the final mask is a valid one */
169 if (ProtectMask == MM_INVALID_PROTECTION) return MM_INVALID_PROTECTION;
170
171 /* Check for PAGE_GUARD option */
172 if (Protect & PAGE_GUARD)
173 {
174 /* It's not valid on no-access, nocache, or writecombine pages */
175 if ((ProtectMask == MM_NOACCESS) ||
177 {
178 /* Fail such requests */
180 }
181
182 /* This actually turns on guard page in this scenario! */
183 ProtectMask |= MM_GUARDPAGE;
184 }
185
186 /* Check for nocache option */
187 if (Protect & PAGE_NOCACHE)
188 {
189 /* The earlier check should've eliminated this possibility */
190 ASSERT((Protect & PAGE_GUARD) == 0);
191
192 /* Check for no-access page or write combine page */
193 if ((ProtectMask == MM_NOACCESS) || (Protect & PAGE_WRITECOMBINE))
194 {
195 /* Such a request is invalid */
197 }
198
199 /* Add the PTE flag */
200 ProtectMask |= MM_NOCACHE;
201 }
202
203 /* Check for write combine option */
205 {
206 /* The two earlier scenarios should've caught this */
208
209 /* Don't allow on no-access pages */
210 if (ProtectMask == MM_NOACCESS) return MM_INVALID_PROTECTION;
211
212 /* This actually turns on write-combine in this scenario! */
213 ProtectMask |= MM_NOACCESS;
214 }
215
216 /* Return the final MM PTE protection mask */
217 return ProtectMask;
218}
CHAR MmUserProtectionToMask1[16]
Definition: section.c:44
CHAR MmUserProtectionToMask2[16]
Definition: section.c:64
#define MM_GUARDPAGE
Definition: miarm.h:57
#define PAGE_NOACCESS
Definition: nt_native.h:1305
static int Protect(const char **args)
Definition: vfdcmd.c:2132

Referenced by MiIsProtectionCompatible(), MiProtectVirtualMemory(), MmCreateArm3Section(), MmCreateSection(), MmCreateVirtualMappingUnsafeEx(), MmInsertMemoryArea(), MmMapViewOfArm3Section(), MmSetPageProtect(), NtAllocateVirtualMemory(), and NtMapViewOfSection().

◆ MiMapViewInSystemSpace()

NTSTATUS MiMapViewInSystemSpace ( _In_ PVOID  Section,
_In_ PMMSESSION  Session,
_Outptr_result_bytebuffer_ *ViewSize PVOID MappedBase,
_Inout_ PSIZE_T  ViewSize,
_Inout_ PLARGE_INTEGER  SectionOffset 
)

Definition at line 1041 of file section.c.

1047{
1048 PVOID Base;
1049 PCONTROL_AREA ControlArea;
1050 ULONG Buckets;
1051 LONGLONG SectionSize;
1053 PAGED_CODE();
1054
1055 /* Get the control area, check for any flags ARM3 doesn't yet support */
1056 ControlArea = ((PSECTION)Section)->Segment->ControlArea;
1057 ASSERT(ControlArea->u.Flags.Image == 0);
1058 ASSERT(ControlArea->FilePointer == NULL);
1059 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1060 ASSERT(ControlArea->u.Flags.Rom == 0);
1061 ASSERT(ControlArea->u.Flags.WasPurged == 0);
1062
1063 /* Increase the reference and map count on the control area, no purges yet */
1064 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1066
1067 /* Get the section size at creation time */
1068 SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart;
1069
1070 /* If the caller didn't specify a view size, assume until the end of the section */
1071 if (!(*ViewSize))
1072 {
1073 /* Check for overflow first */
1074 if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX)
1075 {
1076 DPRINT1("Section end is too far away from the specified offset.\n");
1077 MiDereferenceControlArea(ControlArea);
1079 }
1080 *ViewSize = SectionSize - SectionOffset->QuadPart;
1081 }
1082
1083 /* Check overflow */
1084 if ((SectionOffset->QuadPart + *ViewSize) < SectionOffset->QuadPart)
1085 {
1086 DPRINT1("Integer overflow between size & offset!\n");
1087 MiDereferenceControlArea(ControlArea);
1089 }
1090
1091 /* Check if the caller wanted a larger section than the view */
1092 if (SectionOffset->QuadPart + *ViewSize > SectionSize)
1093 {
1094 /* Fail */
1095 DPRINT1("View is too large\n");
1096 MiDereferenceControlArea(ControlArea);
1098 }
1099
1100 /* Get the number of 64K buckets required for this mapping */
1102 if (*ViewSize & (MI_SYSTEM_VIEW_BUCKET_SIZE - 1)) Buckets++;
1103
1104 /* Check if the view is more than 4GB large */
1105 if (Buckets >= MI_SYSTEM_VIEW_BUCKET_SIZE)
1106 {
1107 /* Fail */
1108 DPRINT1("View is too large\n");
1109 MiDereferenceControlArea(ControlArea);
1111 }
1112
1113 /* Insert this view into system space and get a base address for it */
1114 Base = MiInsertInSystemSpace(Session, Buckets, ControlArea);
1115 if (!Base)
1116 {
1117 /* Fail */
1118 DPRINT1("Out of system space\n");
1119 MiDereferenceControlArea(ControlArea);
1120 return STATUS_NO_MEMORY;
1121 }
1122
1123 /* What's the underlying session? */
1124 if (Session == &MmSession)
1125 {
1126 /* Create the PDEs needed for this mapping, and double-map them if needed */
1129 }
1130 else
1131 {
1132 /* Create the PDEs needed for this mapping */
1134 (PVOID)((ULONG_PTR)Base +
1135 Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
1137 }
1138
1139 /* Create the actual prototype PTEs for this mapping */
1142 ControlArea,
1143 SectionOffset->QuadPart);
1145
1146 /* Return the base address of the mapping and success */
1147 *MappedBase = Base;
1148 return STATUS_SUCCESS;
1149}
static NTSTATUS MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea, IN BOOLEAN FailIfSystemViews)
Definition: section.c:532
VOID NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:464
static NTSTATUS MiAddMappedPtes(IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, IN PCONTROL_AREA ControlArea, IN LONGLONG SectionOffset)
Definition: section.c:401
static VOID MiDereferenceControlArea(IN PCONTROL_AREA ControlArea)
Definition: section.c:751
static PVOID MiInsertInSystemSpace(IN PMMSESSION Session, IN ULONG Buckets, IN PCONTROL_AREA ControlArea)
Definition: section.c:288
static NTSTATUS MiSessionCommitPageTables(IN PVOID StartVa, IN PVOID EndVa)
Definition: section.c:925
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define SIZE_T_MAX
Definition: dhcpd.h:91
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define MiAddressToPte(x)
Definition: mm.h:145
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:361
ULONG WasPurged
Definition: mmtypes.h:478
int64_t LONGLONG
Definition: typedefs.h:68
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492
#define BYTES_TO_PAGES(Size)

Referenced by MmMapViewInSessionSpace(), and MmMapViewInSystemSpaceEx().

◆ MiMapViewOfDataSection()

static NTSTATUS MiMapViewOfDataSection ( _In_ PCONTROL_AREA  ControlArea,
_In_ PEPROCESS  Process,
_Outptr_result_bytebuffer_ *ViewSize _Pre_opt_valid_ PVOID BaseAddress,
_Inout_ PLARGE_INTEGER  SectionOffset,
_Inout_ PSIZE_T  ViewSize,
_In_ PSECTION  Section,
_In_range_(ViewShare, ViewUnmap) SECTION_INHERIT  InheritDisposition,
_In_ ULONG  ProtectionMask,
_In_ SIZE_T  CommitSize,
_In_ ULONG_PTR  ZeroBits,
_In_ ULONG  AllocationType 
)
static

Definition at line 1153 of file section.c.

1165{
1166 PMMVAD_LONG Vad;
1167 ULONG_PTR StartAddress;
1168 ULONG_PTR ViewSizeInPages;
1169 PSUBSECTION Subsection;
1171 PFN_NUMBER PteOffset;
1173 ULONG QuotaCharge = 0, QuotaExcess = 0;
1174 PMMPTE PointerPte, LastPte;
1175 MMPTE TempPte;
1176 ULONG Granularity = MM_VIRTMEM_GRANULARITY;
1177
1178 DPRINT("Mapping ARM3 data section\n");
1179
1180 /* Check for invalid inherit disposition */
1181 ASSERT((InheritDisposition >= ViewShare) && (InheritDisposition <= ViewUnmap));
1182
1183 /* Get the segment for this section */
1184 Segment = ControlArea->Segment;
1185
1186#ifdef _M_IX86
1187 /* ALlow being less restrictive on x86. */
1189 Granularity = PAGE_SIZE;
1190#endif
1191
1192 /* One can only reserve a file-based mapping, not shared memory! */
1193 if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1194 {
1196 }
1197
1198 /* First, increase the map count. No purging is supported yet */
1199 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1200 if (!NT_SUCCESS(Status)) return Status;
1201
1202 /* Check if the caller specified the view size */
1203 if (!(*ViewSize))
1204 {
1205 LONGLONG ViewSizeLL;
1206
1207 /* The caller did not, so pick a 64K aligned view size based on the offset */
1208 SectionOffset->LowPart &= ~(_64K - 1);
1209
1210 /* Calculate size and make sure this fits */
1211 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &ViewSizeLL))
1212 || !NT_SUCCESS(RtlLongLongToSIZET(ViewSizeLL, ViewSize))
1213 || (*ViewSize > MAXLONG_PTR))
1214 {
1215 MiDereferenceControlArea(ControlArea);
1217 }
1218 }
1219 else
1220 {
1221 /* A size was specified, align it to a 64K boundary
1222 * and check for overflow or huge value. */
1223 if (!NT_SUCCESS(RtlSIZETAdd(*ViewSize, SectionOffset->LowPart & (_64K - 1), ViewSize))
1224 || (*ViewSize > MAXLONG_PTR))
1225 {
1226 MiDereferenceControlArea(ControlArea);
1228 }
1229
1230 /* Align the offset as well to make this an aligned map */
1231 SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1232 }
1233
1234 /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1235 ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1236
1237 /* Windows ASSERTs for this flag */
1238 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1239
1240 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1241 ASSERT(ControlArea->u.Flags.Rom == 0);
1242 Subsection = (PSUBSECTION)(ControlArea + 1);
1243
1244 /* Sections with extended segments are not supported in ARM3 */
1245 ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1246
1247 /* Within this section, figure out which PTEs will describe the view */
1248 PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1249
1250 /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1251 ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1252 ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1253
1254 /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1255 ASSERT(PteOffset < Subsection->PtesInSubsection);
1256
1257 /* In ARM3, only page-file backed sections (shared memory) are supported now */
1258 ASSERT(ControlArea->FilePointer == NULL);
1259
1260 /* Windows ASSERTs for this too -- there must be a subsection base address */
1261 ASSERT(Subsection->SubsectionBase != NULL);
1262
1263 /* Compute how much commit space the segment will take */
1264 if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1265 {
1266 /* Charge for the maximum pages */
1267 QuotaCharge = BYTES_TO_PAGES(CommitSize);
1268 }
1269
1270 /* ARM3 does not currently support large pages */
1271 ASSERT(Segment->SegmentFlags.LargePages == 0);
1272
1273 /* Calculate how many pages the region spans */
1274 ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1275
1276 /* A VAD can now be allocated. Do so and zero it out */
1277 /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1278 ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1279 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1280 if (!Vad)
1281 {
1282 MiDereferenceControlArea(ControlArea);
1284 }
1285
1286 RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1287 Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1288
1289 /* Write all the data required in the VAD for handling a fault */
1290 Vad->ControlArea = ControlArea;
1291 Vad->u.VadFlags.CommitCharge = 0;
1292 Vad->u.VadFlags.Protection = ProtectionMask;
1293 Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1294 Vad->u2.VadFlags2.Inherit = (InheritDisposition == ViewShare);
1295 if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1296 {
1297 /* This isn't really implemented yet, but handle setting the flag */
1298 Vad->u.VadFlags.NoChange = 1;
1299 Vad->u2.VadFlags2.SecNoChange = 1;
1300 }
1301
1302 /* Finally, write down the first and last prototype PTE */
1303 Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1304 PteOffset += ViewSizeInPages - 1;
1305 ASSERT(PteOffset < Subsection->PtesInSubsection);
1306 Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1307
1308 /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1310
1311 /* FIXME: Should setup VAD bitmap */
1313
1314 /* Check if anything was committed */
1315 if (QuotaCharge)
1316 {
1317 /* Set the start and end PTE addresses, and pick the template PTE */
1318 PointerPte = Vad->FirstPrototypePte;
1319 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1320 TempPte = Segment->SegmentPteTemplate;
1321
1322 /* Acquire the commit lock and loop all prototype PTEs to be committed */
1324 while (PointerPte < LastPte)
1325 {
1326 /* Make sure the PTE is already invalid */
1327 if (PointerPte->u.Long == 0)
1328 {
1329 /* And write the invalid PTE */
1330 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1331 }
1332 else
1333 {
1334 /* The PTE is valid, so skip it */
1335 QuotaExcess++;
1336 }
1337
1338 /* Move to the next PTE */
1339 PointerPte++;
1340 }
1341
1342 /* Now check how many pages exactly we committed, and update accounting */
1343 ASSERT(QuotaCharge >= QuotaExcess);
1344 QuotaCharge -= QuotaExcess;
1345 Segment->NumberOfCommittedPages += QuotaCharge;
1346 ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1347
1348 /* Now that we're done, release the lock */
1350 }
1351
1352 /* Is it SEC_BASED, or did the caller manually specify an address? */
1353 if (*BaseAddress != NULL)
1354 {
1355 /* Just align what the caller gave us */
1356 StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1357 }
1358 else if (Section->Address.StartingVpn != 0)
1359 {
1360 /* It is a SEC_BASED mapping, use the address that was generated */
1361 StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1362 }
1363 else
1364 {
1365 StartAddress = 0;
1366 }
1367
1369 if (!NT_SUCCESS(Status))
1370 {
1371 ExFreePoolWithTag(Vad, 'ldaV');
1372 MiDereferenceControlArea(ControlArea);
1373
1375 Segment->NumberOfCommittedPages -= QuotaCharge;
1377 return Status;
1378 }
1379
1380 /* Insert the VAD */
1382 &StartAddress,
1383 ViewSizeInPages * PAGE_SIZE,
1385 Granularity,
1387 if (!NT_SUCCESS(Status))
1388 {
1389 ExFreePoolWithTag(Vad, 'ldaV');
1390 MiDereferenceControlArea(ControlArea);
1391
1393 Segment->NumberOfCommittedPages -= QuotaCharge;
1395
1397 return Status;
1398 }
1399
1400 /* Windows stores this for accounting purposes, do so as well */
1401 if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1402
1403 /* Finally, let the caller know where, and for what size, the view was mapped */
1404 *ViewSize = ViewSizeInPages * PAGE_SIZE;
1405 *BaseAddress = (PVOID)StartAddress;
1406 DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1407 return STATUS_SUCCESS;
1408}
KGUARDED_MUTEX MmSectionCommitMutex
Definition: section.c:108
#define ALIGN_DOWN_BY(size, align)
#define MAXULONG_PTR
Definition: basetsd.h:97
#define MAXLONG_PTR
Definition: basetsd.h:98
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define _64K
Definition: miarm.h:23
NTSTATUS NTAPI MiInsertVadEx(_Inout_ PMMVAD Vad, _In_ ULONG_PTR *BaseAddress, _In_ SIZE_T ViewSize, _In_ ULONG_PTR HighestAddress, _In_ ULONG_PTR Alignment, _In_ ULONG AllocationType)
Definition: vadnode.c:245
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR ZeroBits
Definition: mmfuncs.h:405
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ ULONG AllocationType
Definition: mmfuncs.h:410
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
#define MEM_DOS_LIM
Definition: mmtypes.h:90
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
@ ViewUnmap
Definition: nt_native.h:1282
@ ViewShare
Definition: nt_native.h:1281
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:577
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
#define DPRINT
Definition: sndvol32.h:73
ULONG FileOffset
Definition: mmtypes.h:706
ULONG Inherit
Definition: mmtypes.h:713
ULONG SecNoChange
Definition: mmtypes.h:707
ULONG_PTR NoChange
Definition: mmtypes.h:693
ULONG_PTR Protection
Definition: mmtypes.h:696
ULONG_PTR CommitCharge
Definition: mmtypes.h:691
PMMPTE LastContiguousPte
Definition: mmtypes.h:767
PMMPTE FirstPrototypePte
Definition: mmtypes.h:766
PVOID Banked
Definition: mmtypes.h:780
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
union _MMVAD_LONG::@2873 u2
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
union _MMVAD_LONG::@2872 u
union _MMVAD_LONG::@2875 u4

Referenced by MmMapViewOfArm3Section().

◆ MiQueryMemorySectionName()

NTSTATUS NTAPI MiQueryMemorySectionName ( IN HANDLE  ProcessHandle,
IN PVOID  BaseAddress,
OUT PVOID  MemoryInformation,
IN SIZE_T  MemoryInformationLength,
OUT PSIZE_T  ReturnLength 
)

Definition at line 1760 of file section.c.

1765{
1769 PMEMORY_SECTION_NAME SectionName = NULL;
1771
1774 NULL,
1776 (PVOID*)(&Process),
1777 NULL);
1778
1779 if (!NT_SUCCESS(Status))
1780 {
1781 DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1782 return Status;
1783 }
1784
1786
1787 if (NT_SUCCESS(Status))
1788 {
1789 SectionName = MemoryInformation;
1790 if (PreviousMode != KernelMode)
1791 {
1792 _SEH2_TRY
1793 {
1794 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1795 (PWSTR)(SectionName + 1),
1796 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1798
1800
1801 }
1803 {
1805 }
1806 _SEH2_END;
1807 }
1808 else
1809 {
1810 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1811 (PWSTR)(SectionName + 1),
1812 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1814
1816
1817 }
1818
1820 }
1822 return Status;
1823}
NTSTATUS NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName)
Definition: section.c:1697
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
#define ExGetPreviousMode
Definition: ex.h:143
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:162
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define KernelMode
Definition: asm.h:38
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
TCHAR ModuleFileName[MAX_PATH+1]
Definition: rundll32.c:56
UNICODE_STRING SectionFileName
Definition: mmtypes.h:326
uint16_t * PWSTR
Definition: typedefs.h:56
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by NtQueryVirtualMemory().

◆ MiRemoveFromSystemSpace()

static ULONG MiRemoveFromSystemSpace ( IN PMMSESSION  Session,
IN PVOID  Base,
OUT PCONTROL_AREA ControlArea 
)
static

Definition at line 2030 of file section.c.

2033{
2034 ULONG Hash, Size, Count = 0;
2036 PAGED_CODE();
2037
2038 /* Compute the hash for this entry and loop trying to find it */
2039 Entry = (ULONG_PTR)Base >> 16;
2040 Hash = Entry % Session->SystemSpaceHashKey;
2041 while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2042 {
2043 /* Check if we overflew past the end of the hash table */
2044 if (++Hash >= Session->SystemSpaceHashSize)
2045 {
2046 /* Reset the hash to zero and keep searching from the bottom */
2047 Hash = 0;
2048 if (++Count == 2)
2049 {
2050 /* But if we overflew twice, then this is not a real mapping */
2051 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2052 (ULONG_PTR)Base,
2053 1,
2054 0,
2055 0);
2056 }
2057 }
2058 }
2059
2060 /* One less entry */
2061 Session->SystemSpaceHashEntries--;
2062
2063 /* Extract the size and clear the entry */
2064 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2065 Session->SystemSpaceViewTable[Hash].Entry = 0;
2066
2067 /* Return the control area and the size */
2068 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2069 return Size;
2070}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
int Count
Definition: noreturn.cpp:7

Referenced by MiUnmapViewInSystemSpace().

◆ MiRemoveMappedPtes()

static VOID MiRemoveMappedPtes ( IN PVOID  BaseAddress,
IN ULONG  NumberOfPtes,
IN PCONTROL_AREA  ControlArea,
IN PMMSUPPORT  Ws 
)
static

Definition at line 1928 of file section.c.

1932{
1933 PMMPTE PointerPte, ProtoPte;//, FirstPte;
1934 PMMPDE PointerPde, SystemMapPde;
1935 PMMPFN Pfn1, Pfn2;
1936 MMPTE PteContents;
1937 KIRQL OldIrql;
1938 DPRINT("Removing mapped view at: 0x%p\n", BaseAddress);
1939
1940 ASSERT(Ws == NULL);
1941
1942 /* Get the PTE and loop each one */
1943 PointerPte = MiAddressToPte(BaseAddress);
1944 //FirstPte = PointerPte;
1945 while (NumberOfPtes)
1946 {
1947 /* Check if the PTE is already valid */
1948 PteContents = *PointerPte;
1949 if (PteContents.u.Hard.Valid == 1)
1950 {
1951 /* Get the PFN entry */
1952 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
1953
1954 /* Get the PTE */
1955 PointerPde = MiPteToPde(PointerPte);
1956
1957 /* Lock the PFN database and make sure this isn't a mapped file */
1958 OldIrql = MiAcquirePfnLock();
1959 ASSERT(((Pfn1->u3.e1.PrototypePte) && (Pfn1->OriginalPte.u.Soft.Prototype)) == 0);
1960
1961 /* Mark the page as modified accordingly */
1962 if (MI_IS_PAGE_DIRTY(&PteContents))
1963 Pfn1->u3.e1.Modified = 1;
1964
1965 /* Was the PDE invalid */
1966 if (PointerPde->u.Long == 0)
1967 {
1968#if (_MI_PAGING_LEVELS == 2)
1969 /* Find the system double-mapped PDE that describes this mapping */
1970 SystemMapPde = &MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)];
1971
1972 /* Make it valid */
1973 ASSERT(SystemMapPde->u.Hard.Valid == 1);
1974 MI_WRITE_VALID_PDE(PointerPde, *SystemMapPde);
1975#else
1976 DBG_UNREFERENCED_LOCAL_VARIABLE(SystemMapPde);
1977 ASSERT(FALSE);
1978#endif
1979 }
1980
1981 /* Dereference the PDE and the PTE */
1982 Pfn2 = MiGetPfnEntry(PFN_FROM_PTE(PointerPde));
1983 MiDecrementShareCount(Pfn2, PFN_FROM_PTE(PointerPde));
1985 MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents));
1986
1987 /* Release the PFN lock */
1988 MiReleasePfnLock(OldIrql);
1989 }
1990 else
1991 {
1992 /* Windows ASSERT */
1993 ASSERT((PteContents.u.Long == 0) || (PteContents.u.Soft.Prototype == 1));
1994
1995 /* Check if this is a prototype pointer PTE */
1996 if (PteContents.u.Soft.Prototype == 1)
1997 {
1998 /* Get the prototype PTE */
1999 ProtoPte = MiProtoPteToPte(&PteContents);
2000
2001 /* We don't support anything else atm */
2002 ASSERT(ProtoPte->u.Long == 0);
2003 }
2004 }
2005
2006 /* Make the PTE into a zero PTE */
2007 PointerPte->u.Long = 0;
2008
2009 /* Move to the next PTE */
2010 PointerPte++;
2011 NumberOfPtes--;
2012 }
2013
2014 /* Flush the TLB */
2016
2017 /* Acquire the PFN lock */
2018 OldIrql = MiAcquirePfnLock();
2019
2020 /* Decrement the accounting counters */
2021 ControlArea->NumberOfUserReferences--;
2022 ControlArea->NumberOfMappedViews--;
2023
2024 /* Check if we should destroy the CA and release the lock */
2025 MiCheckControlArea(ControlArea, OldIrql);
2026}
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:331
#define MI_IS_PAGE_DIRTY(x)
Definition: mm.h:112
#define MiProtoPteToPte(x)
Definition: mm.h:316
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToPde(_Pte)
Definition: mm.h:121
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1046
USHORT PrototypePte
Definition: mm.h:373
USHORT Modified
Definition: mm.h:370
Definition: mm.h:390
union _MMPFN::@1965 u3
MMPTE OriginalPte
Definition: mm.h:426
MMPFNENTRY e1
Definition: mm.h:413
ULONG64 Prototype
Definition: mmtypes.h:89

Referenced by MiUnmapViewInSystemSpace().

◆ MiRemoveMappedView()

VOID NTAPI MiRemoveMappedView ( IN PEPROCESS  CurrentProcess,
IN PMMVAD  Vad 
)

Definition at line 768 of file section.c.

770{
772 PCONTROL_AREA ControlArea;
773 PETHREAD CurrentThread = PsGetCurrentThread();
774
775 /* Get the control area */
776 ControlArea = Vad->ControlArea;
777
778 /* We only support non-extendable, non-image, pagefile-backed regular sections */
779 ASSERT(Vad->u.VadFlags.VadType == VadNone);
780 ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
781 ASSERT(ControlArea);
782 ASSERT(ControlArea->FilePointer == NULL);
784
785 /* Delete the actual virtual memory pages */
786 MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
787 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
788 Vad);
789
790 /* Release the working set */
791 MiUnlockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
792
793 /* Lock the PFN database */
794 OldIrql = MiAcquirePfnLock();
795
796 /* Remove references */
797 ControlArea->NumberOfMappedViews--;
798 ControlArea->NumberOfUserReferences--;
799
800 /* Check if it should be destroyed */
801 MiCheckControlArea(ControlArea, OldIrql);
802}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1246
VOID NTAPI MiDeleteVirtualAddresses(_In_ ULONG_PTR Va, _In_ ULONG_PTR EndingAddress, _In_opt_ PMMVAD Vad)
Definition: virtual.c:530
@ VadNone
Definition: mmtypes.h:204
ULONG NumberOfMappedViews
Definition: mmtypes.h:525

Referenced by MiUnmapViewOfSection(), and MmCleanProcessAddressSpace().

◆ MiSegmentDelete()

static VOID MiSegmentDelete ( IN PSEGMENT  Segment)
static

Definition at line 593 of file section.c.

594{
595 PCONTROL_AREA ControlArea;
596 SEGMENT_FLAGS SegmentFlags;
597 PSUBSECTION Subsection;
598 PMMPTE PointerPte, LastPte, PteForProto;
599 PMMPFN Pfn1;
600 PFN_NUMBER PageFrameIndex;
603
604 /* Capture data */
605 SegmentFlags = Segment->SegmentFlags;
606 ControlArea = Segment->ControlArea;
607
608 /* Make sure control area is on the right delete path */
609 ASSERT(ControlArea->u.Flags.BeingDeleted == 1);
610 ASSERT(ControlArea->WritableUserReferences == 0);
611
612 /* These things are not supported yet */
613 ASSERT(ControlArea->DereferenceList.Flink == NULL);
614 ASSERT(!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File));
615 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
616 ASSERT(ControlArea->u.Flags.Rom == 0);
617
618 /* Get the subsection and PTEs for this segment */
619 Subsection = (PSUBSECTION)(ControlArea + 1);
620 PointerPte = Subsection->SubsectionBase;
621 LastPte = PointerPte + Segment->NonExtendedPtes;
622
623 /* Lock the PFN database */
624 OldIrql = MiAcquirePfnLock();
625
626 /* Check if the master PTE is invalid */
627 PteForProto = MiAddressToPte(PointerPte);
628 if (!PteForProto->u.Hard.Valid)
629 {
630 /* Fault it in */
632 }
633
634 /* Loop all the segment PTEs */
635 while (PointerPte < LastPte)
636 {
637 /* Check if it's time to switch master PTEs if we passed a PDE boundary */
638 if (MiIsPteOnPdeBoundary(PointerPte) &&
639 (PointerPte != Subsection->SubsectionBase))
640 {
641 /* Check if the master PTE is invalid */
642 PteForProto = MiAddressToPte(PointerPte);
643 if (!PteForProto->u.Hard.Valid)
644 {
645 /* Fault it in */
647 }
648 }
649
650 /* This should be a prototype PTE */
651 TempPte = *PointerPte;
652 ASSERT(SegmentFlags.LargePages == 0);
653 ASSERT(TempPte.u.Hard.Valid == 0);
654
655 /* See if we should clean things up */
656 if (!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File))
657 {
658 /*
659 * This is a section backed by the pagefile. Now that it doesn't exist anymore,
660 * we can give everything back to the system.
661 */
662 ASSERT(TempPte.u.Soft.Prototype == 0);
663
664 if (TempPte.u.Soft.Transition == 1)
665 {
666 /* We can give the page back for other use */
667 DPRINT("Releasing page for transition PTE %p\n", PointerPte);
668 PageFrameIndex = PFN_FROM_PTE(&TempPte);
669 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
670
671 /* As this is a paged-backed section, nobody should reference it anymore (no cache or whatever) */
672 ASSERT(Pfn1->u3.ReferenceCount == 0);
673
674 /* And it should be in standby or modified list */
676
677 /* Unlink it and put it back in free list */
679
680 /* Temporarily mark this as active and make it free again */
682 MI_SET_PFN_DELETED(Pfn1);
683
684 MiInsertPageInFreeList(PageFrameIndex);
685 }
686 else if (TempPte.u.Soft.PageFileHigh != 0)
687 {
688 /* Should not happen for now */
689 ASSERT(FALSE);
690 }
691 }
692 else
693 {
694 /* unsupported for now */
695 ASSERT(FALSE);
696
697 /* File-backed section must have prototype PTEs */
698 ASSERT(TempPte.u.Soft.Prototype == 1);
699 }
700
701 /* Zero the PTE and keep going */
702 PointerPte->u.Long = 0;
703 PointerPte++;
704 }
705
706 /* Release the PFN lock */
707 MiReleasePfnLock(OldIrql);
708
709 /* Free the structures */
710 ExFreePool(ControlArea);
712}
ULONG NTAPI MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress, IN KIRQL OldIrql)
Definition: virtual.c:235
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:208
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:611
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:265
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1581
@ ActiveAndValid
Definition: mmtypes.h:159
@ ModifiedPageList
Definition: mmtypes.h:156
@ StandbyPageList
Definition: mmtypes.h:155
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:306
ULONG WritableUserReferences
Definition: mmtypes.h:537
LIST_ENTRY DereferenceList
Definition: mmtypes.h:522
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT PageLocation
Definition: mm.h:375
USHORT ReferenceCount
Definition: mm.h:412
ULONG LargePages
Definition: mmtypes.h:403

Referenced by MiCheckControlArea().

◆ MiSessionCommitPageTables()

static NTSTATUS MiSessionCommitPageTables ( IN PVOID  StartVa,
IN PVOID  EndVa 
)
static

Definition at line 925 of file section.c.

927{
930 PMMPDE StartPde, EndPde;
932 PMMPFN Pfn1;
933 PFN_NUMBER PageCount = 0, ActualPages = 0, PageFrameNumber;
934
935 /* Windows sanity checks */
936 ASSERT(StartVa >= (PVOID)MmSessionBase);
938 ASSERT(PAGE_ALIGN(EndVa) == EndVa);
939
940 /* Get the start and end PDE, then loop each one */
941 StartPde = MiAddressToPde(StartVa);
942 EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
943 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
944 while (StartPde <= EndPde)
945 {
946#ifndef _M_AMD64
947 /* If we don't already have a page table for it, increment count */
948 if (MmSessionSpace->PageTables[Index].u.Long == 0) PageCount++;
949#endif
950 /* Move to the next one */
951 StartPde++;
952 Index++;
953 }
954
955 /* If there's no page tables to create, bail out */
956 if (PageCount == 0) return STATUS_SUCCESS;
957
958 /* Reset the start PDE and index */
959 StartPde = MiAddressToPde(StartVa);
960 Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
961
962 /* Loop each PDE while holding the working set lock */
963// MiLockWorkingSet(PsGetCurrentThread(),
964// &MmSessionSpace->GlobalVirtualAddress->Vm);
965#ifdef _M_AMD64
966_WARN("MiSessionCommitPageTables halfplemented for amd64")
971 DBG_UNREFERENCED_LOCAL_VARIABLE(PageFrameNumber);
972 ASSERT(FALSE);
973#else
974 while (StartPde <= EndPde)
975 {
976 /* Check if we already have a page table */
978 {
979 /* We don't, so the PDE shouldn't be ready yet */
980 ASSERT(StartPde->u.Hard.Valid == 0);
981
982 /* ReactOS check to avoid MiEnsureAvailablePageOrWait */
984
985 /* Acquire the PFN lock and grab a zero page */
986 OldIrql = MiAcquirePfnLock();
988 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
990 PageFrameNumber = MiRemoveZeroPage(Color);
991 TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
992 MI_WRITE_VALID_PDE(StartPde, TempPde);
993
994 /* Write the page table in session space structure */
997
998 /* Initialize the PFN */
999 MiInitializePfnForOtherProcess(PageFrameNumber,
1000 StartPde,
1002
1003 /* And now release the lock */
1004 MiReleasePfnLock(OldIrql);
1005
1006 /* Get the PFN entry and make sure there's no event for it */
1007 Pfn1 = MI_PFN_ELEMENT(PageFrameNumber);
1008 ASSERT(Pfn1->u1.Event == NULL);
1009
1010 /* Increment the number of pages */
1011 ActualPages++;
1012 }
1013
1014 /* Move to the next PDE */
1015 StartPde++;
1016 Index++;
1017 }
1018#endif
1019
1020 /* Make sure we didn't do more pages than expected */
1021 ASSERT(ActualPages <= PageCount);
1022
1023 /* Release the working set lock */
1024// MiUnlockWorkingSet(PsGetCurrentThread(),
1025// &MmSessionSpace->GlobalVirtualAddress->Vm);
1026
1027
1028 /* If we did at least one page... */
1029 if (ActualPages)
1030 {
1031 /* Update the performance counters! */
1034 }
1035
1036 /* Return status */
1037 return STATUS_SUCCESS;
1038}
#define _WARN(msg)
Definition: debug.h:135
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:211
ULONG MmSecondaryColorMask
Definition: mminit.c:258
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
PVOID MmSessionBase
Definition: init.c:33
PVOID MiSessionSpaceEnd
Definition: init.c:27
MMPTE ValidKernelPdeLocal
Definition: init.c:32
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:484
PMMPDE PageTables
Definition: miarm.h:511
SIZE_T CommittedPages
Definition: miarm.h:486
SIZE_T NonPageablePages
Definition: miarm.h:485
_In_ WDFCOLLECTION _In_ ULONG Index
#define PAGE_ALIGN(Va)

Referenced by MiMapViewInSystemSpace().

◆ MiUnmapViewInSystemSpace()

static NTSTATUS MiUnmapViewInSystemSpace ( IN PMMSESSION  Session,
IN PVOID  MappedBase 
)
static

Definition at line 2074 of file section.c.

2076{
2077 ULONG Size;
2078 PCONTROL_AREA ControlArea;
2079 PAGED_CODE();
2080
2081 /* Remove this mapping */
2082 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2083 Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2084
2085 /* Clear the bits for this mapping */
2086 RtlClearBits(Session->SystemSpaceBitMap,
2087 (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2088 Size);
2089
2090 /* Convert the size from a bit size into the actual size */
2091 Size = Size * (_64K >> PAGE_SHIFT);
2092
2093 /* Remove the PTEs now */
2094 MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2095 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2096
2097 /* Return success */
2098 return STATUS_SUCCESS;
2099}
static ULONG MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2030
static VOID MiRemoveMappedPtes(IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
Definition: section.c:1928
#define RtlClearBits
Definition: dbgbitmap.h:331

Referenced by MmUnmapViewInSessionSpace(), and MmUnmapViewInSystemSpace().

◆ MiUnmapViewOfSection()

static NTSTATUS MiUnmapViewOfSection ( IN PEPROCESS  Process,
IN PVOID  BaseAddress,
IN ULONG  Flags 
)
static

Definition at line 806 of file section.c.

809{
812 PMMVAD Vad;
813 PVOID DbgBase = NULL;
816 PETHREAD CurrentThread = PsGetCurrentThread();
817 PEPROCESS CurrentProcess = PsGetCurrentProcess();
818 PAGED_CODE();
819
820 /* Check if we need to lock the address space */
821 if (!Flags) MmLockAddressSpace(&Process->Vm);
822
823 /* Find the VAD for the address and make sure it's a section VAD */
824 Vad = MiLocateVad(&Process->VadRoot, BaseAddress);
825 if (!(Vad) || (Vad->u.VadFlags.PrivateMemory))
826 {
827 /* Couldn't find it, or invalid VAD, fail */
828 DPRINT1("No VAD or invalid VAD\n");
831 }
832
833 /* Check for RosMm memory area */
834 if (MI_IS_MEMORY_AREA_VAD(Vad))
835 {
836 /* Call Mm API */
840 return Status;
841 }
842
843 /* Check if we should attach to the process */
844 if (CurrentProcess != Process)
845 {
846 /* The process is different, do an attach */
848 Attached = TRUE;
849 }
850
851 /* Check if the process is already dead */
852 if (Process->VmDeleted)
853 {
854 /* Fail the call */
855 DPRINT1("Process died!\n");
858 goto Quickie;
859 }
860
861 /* We should be attached */
863
864 /* We need the base address for the debugger message on image-backed VADs */
865 if (Vad->u.VadFlags.VadType == VadImageMap)
866 {
867 DbgBase = (PVOID)(Vad->StartingVpn >> PAGE_SHIFT);
868 }
869
870 /* Compute the size of the VAD region */
871 RegionSize = PAGE_SIZE + ((Vad->EndingVpn - Vad->StartingVpn) << PAGE_SHIFT);
872
873 /* For SEC_NO_CHANGE sections, we need some extra checks */
874 if (Vad->u.VadFlags.NoChange == 1)
875 {
876 /* Are we allowed to mess with this VAD? */
878 (PVOID)(Vad->StartingVpn >> PAGE_SHIFT),
881 if (!NT_SUCCESS(Status))
882 {
883 /* We failed */
884 DPRINT1("Trying to unmap protected VAD!\n");
886 goto Quickie;
887 }
888 }
889
890 /* Not currently supported */
892
893 /* FIXME: Remove VAD charges */
894
895 /* Lock the working set */
897
898 /* Remove the VAD */
899 ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
900 MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
902
903 /* Remove the PTEs for this view, which also releases the working set lock */
905
906 /* FIXME: Remove commitment */
907
908 /* Update performance counter and release the lock */
909 Process->VirtualSize -= RegionSize;
911
912 /* Destroy the VAD and return success */
913 ExFreePool(Vad);
915
916 /* Failure and success case -- send debugger message, detach, and return */
917Quickie:
918 if (DbgBase) DbgkUnMapViewOfSection(DbgBase);
920 return Status;
921}
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:768
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
PMMVAD NTAPI MiLocateVad(_In_ PMM_AVL_TABLE Table, _In_ PVOID VirtualAddress)
Definition: vadnode.c:116
#define MM_DELETE_CHECK
Definition: miarm.h:260
NTSTATUS NTAPI MiCheckSecuredVad(IN PMMVAD Vad, IN PVOID Base, IN SIZE_T Size, IN ULONG ProtectionMask)
Definition: vadnode.c:815
NTSTATUS NTAPI MiRosUnmapViewOfSection(_In_ PEPROCESS Process, _In_ PMEMORY_AREA MemoryArea, _In_ PVOID BaseAddress, _In_ BOOLEAN SkipDebuggerNotify)
Definition: section.c:3630
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1176
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
@ VadRotatePhysical
Definition: mmtypes.h:210
@ VadImageMap
Definition: mmtypes.h:206
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1695
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1708
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:355
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
ULONG_PTR VadType
Definition: mmtypes.h:694
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
union _MMVAD::@2869 u
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
static BOOL Attached
Definition: vidbios.c:3905
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
KAPC_STATE
Definition: ketypes.h:1727

Referenced by MmUnmapViewOfSection(), and NtUnmapViewOfSection().

◆ MmCommitSessionMappedView()

NTSTATUS NTAPI MmCommitSessionMappedView ( IN PVOID  MappedBase,
IN SIZE_T  ViewSize 
)

Definition at line 2802 of file section.c.

2804{
2805 ULONG_PTR StartAddress, EndingAddress, Base;
2806 ULONG Hash, Count = 0, Size, QuotaCharge;
2807 PMMSESSION Session;
2808 PMMPTE LastProtoPte, PointerPte, ProtoPte;
2809 PCONTROL_AREA ControlArea;
2811 PSUBSECTION Subsection;
2812 MMPTE TempPte;
2813 PAGED_CODE();
2814
2815 /* Make sure the base isn't past the session view range */
2818 {
2819 DPRINT1("Base outside of valid range\n");
2821 }
2822
2823 /* Make sure the size isn't past the session view range */
2826 {
2827 DPRINT1("Size outside of valid range\n");
2829 }
2830
2831 /* Sanity check */
2832 ASSERT(ViewSize != 0);
2833
2834 /* Process must be in a session */
2835 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2836 {
2837 DPRINT1("Process is not in session\n");
2839 }
2840
2841 /* Compute the correctly aligned base and end addresses */
2842 StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
2843 EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
2844
2845 /* Sanity check and grab the session */
2847 Session = &MmSessionSpace->Session;
2848
2849 /* Get the hash entry for this allocation */
2850 Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
2851
2852 /* Lock system space */
2854
2855 /* Loop twice so we can try rolling over if needed */
2856 while (TRUE)
2857 {
2858 /* Extract the size and base addresses from the entry */
2859 Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
2860 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2861
2862 /* Convert the size to bucket chunks */
2864
2865 /* Bail out if this entry fits in here */
2866 if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
2867
2868 /* Check if we overflew past the end of the hash table */
2869 if (++Hash >= Session->SystemSpaceHashSize)
2870 {
2871 /* Reset the hash to zero and keep searching from the bottom */
2872 Hash = 0;
2873 if (++Count == 2)
2874 {
2875 /* But if we overflew twice, then this is not a real mapping */
2876 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2877 Base,
2878 2,
2879 0,
2880 0);
2881 }
2882 }
2883 }
2884
2885 /* Make sure the view being mapped is not file-based */
2886 ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2887 if (ControlArea->FilePointer != NULL)
2888 {
2889 /* It is, so we have to bail out */
2890 DPRINT1("Only page-filed backed sections can be commited\n");
2893 }
2894
2895 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
2896 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2897 ASSERT(ControlArea->u.Flags.Rom == 0);
2898 Subsection = (PSUBSECTION)(ControlArea + 1);
2899
2900 /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
2901 ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
2902 QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
2903 LastProtoPte = ProtoPte + QuotaCharge;
2904 if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
2905 {
2906 DPRINT1("PTE is out of bounds\n");
2909 }
2910
2911 /* Acquire the commit lock and count all the non-committed PTEs */
2913 PointerPte = ProtoPte;
2914 while (PointerPte < LastProtoPte)
2915 {
2916 if (PointerPte->u.Long) QuotaCharge--;
2917 PointerPte++;
2918 }
2919
2920 /* Was everything committed already? */
2921 if (!QuotaCharge)
2922 {
2923 /* Nothing to do! */
2926 return STATUS_SUCCESS;
2927 }
2928
2929 /* Pick the segment and template PTE */
2930 Segment = ControlArea->Segment;
2931 TempPte = Segment->SegmentPteTemplate;
2932 ASSERT(TempPte.u.Long != 0);
2933
2934 /* Loop all prototype PTEs to be committed */
2935 PointerPte = ProtoPte;
2936 while (PointerPte < LastProtoPte)
2937 {
2938 /* Make sure the PTE is already invalid */
2939 if (PointerPte->u.Long == 0)
2940 {
2941 /* And write the invalid PTE */
2942 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2943 }
2944
2945 /* Move to the next PTE */
2946 PointerPte++;
2947 }
2948
2949 /* Check if we had at least one page charged */
2950 if (QuotaCharge)
2951 {
2952 /* Update the accounting data */
2953 Segment->NumberOfCommittedPages += QuotaCharge;
2955 }
2956
2957 /* Release all */
2960 return STATUS_SUCCESS;
2961}
VOID FASTCALL KeReleaseGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:75
VOID FASTCALL KeAcquireGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:64
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
SIZE_T MmSharedCommit
Definition: freelist.c:31
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:363
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:570
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:569
PCONTROL_AREA ControlArea
Definition: miarm.h:449
MMSESSION Session
Definition: miarm.h:501

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

2116{
2117 SECTION Section;
2118 PSECTION NewSection;
2119 PSUBSECTION Subsection;
2120 PSEGMENT NewSegment, Segment;
2122 PCONTROL_AREA ControlArea;
2123 ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
2125 BOOLEAN FileLock = FALSE, KernelCall = FALSE;
2126 KIRQL OldIrql;
2128 BOOLEAN UserRefIncremented = FALSE;
2129 PVOID PreviousSectionPointer;
2130
2131 /* Make the same sanity checks that the Nt interface should've validated */
2134 SEC_NO_CHANGE)) == 0);
2144
2145 /* Convert section flag to page flag */
2148
2149 /* Check to make sure the protection is correct. Nt* does this already */
2151 if (ProtectionMask == MM_INVALID_PROTECTION)
2152 {
2153 DPRINT1("Invalid protection mask\n");
2155 }
2156
2157 /* Check if this is going to be a data or image backed file section */
2158 if ((FileHandle) || (FileObject))
2159 {
2160 /* These cannot be mapped with large pages */
2162
2163 /* For now, only support the mechanism through a file handle */
2165
2166 /* Reference the file handle to get the object */
2168 MmMakeFileAccess[ProtectionMask],
2171 (PVOID*)&File,
2172 NULL);
2173 if (!NT_SUCCESS(Status)) return Status;
2174
2175 /* Make sure Cc has been doing its job */
2176 if (!File->SectionObjectPointer)
2177 {
2178 /* This is not a valid file system-based file, fail */
2181 }
2182
2183 /* Image-file backed sections are not yet supported */
2185
2186 /* Compute the size of the control area, and allocate it */
2187 ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
2188 ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
2189 if (!ControlArea)
2190 {
2193 }
2194
2195 /* Zero it out */
2196 RtlZeroMemory(ControlArea, ControlAreaSize);
2197
2198 /* Did we get a handle, or an object? */
2199 if (FileHandle)
2200 {
2201 /* We got a file handle so we have to lock down the file */
2202#if 0
2204 if (!NT_SUCCESS(Status))
2205 {
2206 ExFreePool(ControlArea);
2208 return Status;
2209 }
2210#else
2211 /* ReactOS doesn't support this API yet, so do nothing */
2214#endif
2215 /* Update the top-level IRP so that drivers know what's happening */
2217 FileLock = TRUE;
2218 }
2219
2220 /* Lock the PFN database while we play with the section pointers */
2221 OldIrql = MiAcquirePfnLock();
2222
2223 /* Image-file backed sections are not yet supported */
2225
2226 /* There should not already be a control area for this file */
2227 ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
2228 NewSegment = NULL;
2229
2230 /* Write down that this CA is being created, and set it */
2231 ControlArea->u.Flags.BeingCreated = TRUE;
2233 PreviousSectionPointer = File->SectionObjectPointer;
2234 File->SectionObjectPointer->DataSectionObject = ControlArea;
2235
2236 /* We can release the PFN lock now */
2237 MiReleasePfnLock(OldIrql);
2238
2239 /* We don't support previously-mapped file */
2240 ASSERT(NewSegment == NULL);
2241
2242 /* Image-file backed sections are not yet supported */
2244
2245 /* So we always create a data file map */
2247 &Segment,
2248 InputMaximumSize,
2251 KernelCall);
2252 if (!NT_SUCCESS(Status))
2253 {
2254 /* Lock the PFN database while we play with the section pointers */
2255 OldIrql = MiAcquirePfnLock();
2256
2257 /* Reset the waiting-for-deletion event */
2258 ASSERT(ControlArea->WaitingForDeletion == NULL);
2259 ControlArea->WaitingForDeletion = NULL;
2260
2261 /* Set the file pointer NULL flag */
2262 ASSERT(ControlArea->u.Flags.FilePointerNull == 0);
2263 ControlArea->u.Flags.FilePointerNull = TRUE;
2264
2265 /* Delete the data section object */
2267 File->SectionObjectPointer->DataSectionObject = NULL;
2268
2269 /* No longer being created */
2270 ControlArea->u.Flags.BeingCreated = FALSE;
2271
2272 /* We can release the PFN lock now */
2273 MiReleasePfnLock(OldIrql);
2274
2275 /* Check if we locked and set the IRP */
2276 if (FileLock)
2277 {
2278 /* Undo */
2280 //FsRtlReleaseFile(File);
2281 }
2282
2283 /* Free the control area and de-ref the file object */
2284 ExFreePool(ControlArea);
2286
2287 /* All done */
2288 return Status;
2289 }
2290
2291 /* On success, we expect this */
2292 ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
2293
2294 /* Check if a maximum size was specified */
2295 if (!InputMaximumSize->QuadPart)
2296 {
2297 /* Nope, use the segment size */
2298 Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
2299 }
2300 else
2301 {
2302 /* Yep, use the entered size */
2303 Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
2304 }
2305 }
2306 else
2307 {
2308 /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
2310
2311 /* Not yet supported */
2313
2314 /* So this must be a pagefile-backed section, create the mappings needed */
2315 Status = MiCreatePagingFileMap(&NewSegment,
2316 InputMaximumSize->QuadPart,
2317 ProtectionMask,
2319 if (!NT_SUCCESS(Status)) return Status;
2320
2321 /* Set the size here, and read the control area */
2322 Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
2323 ControlArea = NewSegment->ControlArea;
2324
2325 /* MiCreatePagingFileMap increments user references */
2326 UserRefIncremented = TRUE;
2327 }
2328
2329 /* Did we already have a segment? */
2330 if (!NewSegment)
2331 {
2332 /* This must be the file path and we created a segment */
2333 NewSegment = Segment;
2334 ASSERT(File != NULL);
2335
2336 /* Acquire the PFN lock while we set control area flags */
2337 OldIrql = MiAcquirePfnLock();
2338
2339 /* We don't support this race condition yet, so assume no waiters */
2340 ASSERT(ControlArea->WaitingForDeletion == NULL);
2341 ControlArea->WaitingForDeletion = NULL;
2342
2343 /* Image-file backed sections are not yet supported, nor ROM images */
2345 ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
2346
2347 /* Take off the being created flag, and then release the lock */
2348 ControlArea->u.Flags.BeingCreated = FALSE;
2349 MiReleasePfnLock(OldIrql);
2350 }
2351
2352 /* Check if we locked the file earlier */
2353 if (FileLock)
2354 {
2355 /* Reset the top-level IRP and release the lock */
2357 //FsRtlReleaseFile(File);
2358 FileLock = FALSE;
2359 }
2360
2361 /* Set the initial section object data */
2363
2364 /* The mapping created a control area and segment, save the flags */
2365 Section.Segment = NewSegment;
2366 Section.u.LongFlags = ControlArea->u.LongFlags;
2367
2368 /* Check if this is a user-mode read-write non-image file mapping */
2369 if (!(FileObject) &&
2371 !(ControlArea->u.Flags.Image) &&
2372 (ControlArea->FilePointer))
2373 {
2374 /* Add a reference and set the flag */
2375 Section.u.Flags.UserWritable = TRUE;
2376 InterlockedIncrement((volatile LONG*)&ControlArea->WritableUserReferences);
2377 }
2378
2379 /* Check for image mappings or page file mappings */
2380 if ((ControlArea->u.Flags.Image) || !(ControlArea->FilePointer))
2381 {
2382 /* Charge the segment size, and allocate a subsection */
2383 PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
2384 Size = sizeof(SUBSECTION);
2385 }
2386 else
2387 {
2388 /* Charge nothing, and allocate a mapped subsection */
2389 PagedCharge = 0;
2390 Size = sizeof(MSUBSECTION);
2391 }
2392
2393 /* Check if this is a normal CA */
2394 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2395 ASSERT(ControlArea->u.Flags.Rom == 0);
2396
2397 /* Charge only a CA, and the subsection is right after */
2398 NonPagedCharge = sizeof(CONTROL_AREA);
2399 Subsection = (PSUBSECTION)(ControlArea + 1);
2400
2401 /* We only support single-subsection mappings */
2402 NonPagedCharge += Size;
2403 ASSERT(Subsection->NextSubsection == NULL);
2404
2405 /* Create the actual section object, with enough space for the prototype PTEs */
2410 NULL,
2411 sizeof(SECTION),
2412 PagedCharge,
2413 NonPagedCharge,
2414 (PVOID*)&NewSection);
2415 if (!NT_SUCCESS(Status))
2416 {
2417 /* Check if this is a user-mode read-write non-image file mapping */
2418 if (!(FileObject) &&
2420 !(ControlArea->u.Flags.Image) &&
2421 (ControlArea->FilePointer))
2422 {
2423 /* Remove a reference and check the flag */
2424 ASSERT(Section.u.Flags.UserWritable == 1);
2425 InterlockedDecrement((volatile LONG*)&ControlArea->WritableUserReferences);
2426 }
2427
2428 /* Check if a user reference was added */
2429 if (UserRefIncremented)
2430 {
2431 /* Acquire the PFN lock while we change counters */
2432 OldIrql = MiAcquirePfnLock();
2433
2434 /* Decrement the accounting counters */
2435 ControlArea->NumberOfSectionReferences--;
2436 ASSERT((LONG)ControlArea->NumberOfUserReferences > 0);
2437 ControlArea->NumberOfUserReferences--;
2438
2439 /* Check if we should destroy the CA and release the lock */
2440 MiCheckControlArea(ControlArea, OldIrql);
2441 }
2442
2443 /* Return the failure code */
2444 return Status;
2445 }
2446
2447 /* NOTE: Past this point, all failures will be handled by Ob upon ref->0 */
2448
2449 /* Now copy the local section object from the stack into this new object */
2450 RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
2451 NewSection->Address.StartingVpn = 0;
2452
2453 /* For now, only user calls are supported */
2454 ASSERT(KernelCall == FALSE);
2455 NewSection->u.Flags.UserReference = TRUE;
2456
2457 /* Is this a "based" allocation, in which all mappings are identical? */
2459 {
2460 /* Lock the VAD tree during the search */
2462
2463 /* Is it a brand new ControArea ? */
2464 if (ControlArea->u.Flags.BeingCreated == 1)
2465 {
2466 ASSERT(ControlArea->u.Flags.Based == 1);
2467 /* Then we must find a global address, top-down */
2470 _64K,
2472 (ULONG_PTR*)&ControlArea->Segment->BasedAddress);
2473
2474 if (!NT_SUCCESS(Status))
2475 {
2476 /* No way to find a valid range. */
2478 ControlArea->u.Flags.Based = 0;
2479 NewSection->u.Flags.Based = 0;
2480 ObDereferenceObject(NewSection);
2481 return Status;
2482 }
2483
2484 /* Compute the ending address and insert it into the VAD tree */
2485 NewSection->Address.StartingVpn = (ULONG_PTR)ControlArea->Segment->BasedAddress;
2486 NewSection->Address.EndingVpn = NewSection->Address.StartingVpn + NewSection->SizeOfSection.LowPart - 1;
2487 MiInsertBasedSection(NewSection);
2488 }
2489 else
2490 {
2491 /* 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 !*/
2492 ASSERT(FALSE);
2493 }
2494
2496 }
2497
2498 /* The control area is not being created anymore */
2499 if (ControlArea->u.Flags.BeingCreated == 1)
2500 {
2501 /* Acquire the PFN lock while we set control area flags */
2502 OldIrql = MiAcquirePfnLock();
2503
2504 /* Take off the being created flag, and then release the lock */
2505 ControlArea->u.Flags.BeingCreated = 0;
2506 NewSection->u.Flags.BeingCreated = 0;
2507
2508 MiReleasePfnLock(OldIrql);
2509 }
2510
2511 /* Migrate the attribute into a flag */
2513
2514 /* If R/W access is not requested, this might eventually become a CoW mapping */
2516 {
2517 NewSection->u.Flags.CopyOnWrite = TRUE;
2518 }
2519
2520 /* Write down if this was a kernel call */
2521 ControlArea->u.Flags.WasPurged |= KernelCall;
2522 ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
2523
2524 /* Make sure the segment and the section are the same size, or the section is smaller */
2525 ASSERT((ULONG64)NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
2526
2527 /* Return the object and the creation status */
2528 *SectionObject = (PVOID)NewSection;
2529 return Status;
2530}
static NTSTATUS MiCreateDataFileMap(IN PFILE_OBJECT File, OUT PSEGMENT *Segment, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN ULONG IgnoreFileSizing)
Definition: section.c:1412
static NTSTATUS MiCreatePagingFileMap(OUT PSEGMENT *Segment, IN ULONG64 MaximumSize, IN ULONG ProtectionMask, IN ULONG AllocationAttributes)
Definition: section.c:1427
PVOID MmHighSectionBase
Definition: section.c:111
ACCESS_MASK MmMakeFileAccess[8]
Definition: section.c:32
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
Definition: File.h:16
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
VOID NTAPI MiInsertBasedSection(IN PSECTION Section)
Definition: vadnode.c:386
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree(IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base)
Definition: vadnode.c:711
unsigned __int64 ULONG64
Definition: imports.h:198
#define SECTION
Definition: profile.c:31
struct _SUBSECTION SUBSECTION
#define SEC_NOCACHE
Definition: mmtypes.h:101
#define SEC_IMAGE
Definition: mmtypes.h:97
struct _MSUBSECTION MSUBSECTION
struct _CONTROL_AREA CONTROL_AREA
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
Definition: fastio.c:1653
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:362
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:574
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:399
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
long LONG
Definition: pedump.c:60
POBJECT_TYPE MmSectionObjectType
Definition: section.c:196
PEVENT_COUNTER WaitingForDeletion
Definition: mmtypes.h:534
ULONG LongFlags
Definition: mmtypes.h:530
ULONG_PTR StartingVpn
Definition: mmtypes.h:653
ULONG_PTR EndingVpn
Definition: mmtypes.h:654
ULONG NoChange
Definition: mmtypes.h:486
ULONG UserReference
Definition: mmtypes.h:479
ULONG CopyOnWrite
Definition: mmtypes.h:474
ULONG FilePointerNull
Definition: mmtypes.h:482
ULONG UserWritable
Definition: mmtypes.h:489
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
ULONG LongFlags
Definition: mmtypes.h:816
union _SECTION::@2878 u
PSEGMENT Segment
Definition: mmtypes.h:812
ULONG InitialPageProtection
Definition: mmtypes.h:819
MMADDRESS_NODE Address
Definition: mmtypes.h:811
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:813
PVOID BasedAddress
Definition: mmtypes.h:418
struct _SUBSECTION * NextSubsection
Definition: mmtypes.h:584
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106

Referenced by MmCreateSection().

◆ MmDisableModifiedWriteOfSection()

BOOLEAN NTAPI MmDisableModifiedWriteOfSection ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointer)

Definition at line 2680 of file section.c.

2681{
2683 return FALSE;
2684}

◆ MmDoesFileHaveUserWritableReferences()

ULONG NTAPI MmDoesFileHaveUserWritableReferences ( IN PSECTION_OBJECT_POINTERS  SectionPointer)

Definition at line 3001 of file section.c.

3002{
3004 return 0;
3005}
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30

Referenced by FatCheckShareAccess().

◆ MmForceSectionClosed()

BOOLEAN NTAPI MmForceSectionClosed ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointer,
IN BOOLEAN  DelayClose 
)

Definition at line 2691 of file section.c.

2693{
2695 return FALSE;
2696}

Referenced by RxPurgeFcbInSystemCache(), and RxPurgeNetFcb().

◆ MmGetFileNameForAddress()

NTSTATUS NTAPI MmGetFileNameForAddress ( IN PVOID  Address,
OUT PUNICODE_STRING  ModuleName 
)

Definition at line 1697 of file section.c.

1699{
1700 POBJECT_NAME_INFORMATION ModuleNameInformation;
1703 PMMVAD Vad;
1705
1706 /* Lock address space */
1709
1710 /* Get the VAD */
1711 Vad = MiLocateAddress(Address);
1712 if (Vad == NULL)
1713 {
1714 /* Fail, the address does not exist */
1715 DPRINT1("No VAD at address %p\n", Address);
1718 }
1719
1720 /* Get the file object pointer for the VAD */
1722 if (FileObject == NULL)
1723 {
1724 DPRINT1("Failed to get file object for Address %p\n", Address);
1727 }
1728
1729 /* Reference the file object */
1731
1732 /* Unlock address space */
1734
1735 /* Get the filename of the file object */
1736 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1737
1738 /* Dereference the file object */
1740
1741 /* Check if we were able to get the file object name */
1742 if (NT_SUCCESS(Status))
1743 {
1744 /* Init modulename */
1745 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1747
1748 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1749 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1750
1751 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1752 }
1753
1754 /* Return status */
1755 return Status;
1756}
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1565
static NTSTATUS MmGetFileNameForFileObject(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1644
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace(VOID)
Definition: mm.h:1723
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:651
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:403
static WCHAR Address[46]
Definition: ping.c:68
UNICODE_STRING Name
Definition: nt_native.h:1273
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by DbgkpPostFakeModuleMessages(), and MiQueryMemorySectionName().

◆ MmGetFileNameForFileObject()

static NTSTATUS MmGetFileNameForFileObject ( IN PFILE_OBJECT  FileObject,
OUT POBJECT_NAME_INFORMATION ModuleName 
)
static

Definition at line 1644 of file section.c.

1646{
1647 POBJECT_NAME_INFORMATION ObjectNameInfo;
1650
1651 /* Allocate memory for our structure */
1652 ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, 1024, TAG_MM);
1653 if (!ObjectNameInfo) return STATUS_NO_MEMORY;
1654
1655 /* Query the name */
1657 ObjectNameInfo,
1658 1024,
1659 &ReturnLength);
1660 if (!NT_SUCCESS(Status))
1661 {
1662 /* Failed, free memory */
1663 DPRINT1("Name query failed\n");
1664 ExFreePoolWithTag(ObjectNameInfo, TAG_MM);
1665 *ModuleName = NULL;
1666 return Status;
1667 }
1668
1669 /* Success */
1670 *ModuleName = ObjectNameInfo;
1671 return STATUS_SUCCESS;
1672}
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207

Referenced by MmGetFileNameForAddress(), and MmGetFileNameForSection().

◆ MmGetFileNameForSection()

NTSTATUS NTAPI MmGetFileNameForSection ( IN PVOID  Section,
OUT POBJECT_NAME_INFORMATION ModuleName 
)

Definition at line 1676 of file section.c.

1678{
1680 PSECTION SectionObject = Section;
1681
1682 /* Make sure it's an image section */
1683 if (SectionObject->u.Flags.Image == 0)
1684 {
1685 /* It's not, fail */
1686 DPRINT1("Not an image section\n");
1688 }
1689
1690 /* Get the file object */
1693}
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID SectionObject)
Definition: section.c:1546

Referenced by DbgkCreateThread(), and DbgkpSectionToFileHandle().

◆ MmGetFileObjectForSection()

PFILE_OBJECT NTAPI MmGetFileObjectForSection ( IN PVOID  SectionObject)

Definition at line 1546 of file section.c.

1547{
1548 PSECTION Section = SectionObject;
1551
1552 /* Check if it's an ARM3, or ReactOS section */
1554 {
1555 /* Return the file pointer stored in the control area */
1556 return Section->Segment->ControlArea->FilePointer;
1557 }
1558
1559 /* Return the file object */
1560 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1561}
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1105

Referenced by CcGetFileObjectFromBcb(), CcGetFileObjectFromSectionPtrs(), CcShutdownSystem(), MmGetFileNameForSection(), MmInitializeProcessAddressSpace(), and PsReferenceProcessFilePointer().

◆ MmGetImageInformation()

VOID NTAPI MmGetImageInformation ( OUT PSECTION_IMAGE_INFORMATION  ImageInformation)

Definition at line 1623 of file section.c.

1624{
1626
1627 /* Get the section object of this process*/
1628 SectionObject = PsGetCurrentProcess()->SectionObject;
1631
1632 if (SectionObject->u.Flags.Image == 0)
1633 {
1634 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1635 return;
1636 }
1637
1638 /* Return the image information */
1639 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1640}
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT

Referenced by NtQueryInformationProcess().

◆ MmMapViewInSessionSpace()

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

Definition at line 2703 of file section.c.

2706{
2707 PAGED_CODE();
2709
2710 // HACK
2711 if (MiIsRosSectionObject(Section))
2712 {
2713 return MmMapViewInSystemSpace(Section, MappedBase, ViewSize);
2714 }
2715
2716 /* Process must be in a session */
2717 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2718 {
2719 DPRINT1("Process is not in session\n");
2721 }
2722
2723 /* Use the system space API, but with the session view instead */
2725 SectionOffset.QuadPart = 0;
2726 return MiMapViewInSystemSpace(Section,
2728 MappedBase,
2729 ViewSize,
2730 &SectionOffset);
2731}
NTSTATUS MiMapViewInSystemSpace(_In_ PVOID Section, _In_ PMMSESSION Session, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset)
Definition: section.c:1041
NTSTATUS NTAPI MmMapViewInSystemSpace(IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:4504

Referenced by _Success_(), InitGdiHandleTable(), and UserCreateHeap().

◆ MmMapViewOfArm3Section()

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

Definition at line 2537 of file section.c.

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

Referenced by MmMapViewOfSection().

◆ MmUnmapViewInSessionSpace()

NTSTATUS NTAPI MmUnmapViewInSessionSpace ( IN PVOID  MappedBase)

Definition at line 2738 of file section.c.

2739{
2740 PAGED_CODE();
2741
2742 // HACK
2744 {
2746 }
2747
2748 /* Process must be in a session */
2749 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2750 {
2751 DPRINT1("Proess is not in session\n");
2753 }
2754
2755 /* Use the system space API, but with the session view instead */
2758 MappedBase);
2759}
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:2777
static NTSTATUS MiUnmapViewInSystemSpace(IN PMMSESSION Session, IN PVOID MappedBase)
Definition: section.c:2074
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:185

Referenced by EngFreeSectionMem(), and IntFreeDesktopHeap().

◆ MmUnmapViewInSystemSpace()

NTSTATUS NTAPI MmUnmapViewInSystemSpace ( IN PVOID  MappedBase)

Definition at line 2777 of file section.c.

2778{
2780 PAGED_CODE();
2781
2782 /* Was this mapped by RosMm? */
2786 {
2789 return Status;
2790 }
2792
2793 /* It was not, call the ARM3 routine */
2795}
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:4614
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:61
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:97
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1730

Referenced by CcRosInternalFreeVacb(), EngFreeModule(), MmUnmapViewInSessionSpace(), and SharedMem_Release().

◆ MmUnmapViewOfSection()

NTSTATUS NTAPI MmUnmapViewOfSection ( IN PEPROCESS  Process,
IN PVOID  BaseAddress 
)

Definition at line 2766 of file section.c.

2768{
2770}
static NTSTATUS MiUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
Definition: section.c:806

Referenced by _Function_class_(), _Success_(), EngUnmapSectionView(), IntMapDesktopView(), IntUnmapDesktopView(), IntUserHeapCreate(), LpcpDeletePort(), MiLoadImageSection(), and UnmapGlobalUserHeap().

◆ NtAreMappedFilesTheSame()

NTSTATUS NTAPI NtAreMappedFilesTheSame ( IN PVOID  File1MappedAsAnImage,
IN PVOID  File2MappedAsFile 
)

Definition at line 3011 of file section.c.

3013{
3015 PMMVAD Vad1, Vad2;
3016 PFILE_OBJECT FileObject1, FileObject2;
3018
3019 /* Lock address space */
3022
3023 /* Get the VAD for Address 1 */
3024 Vad1 = MiLocateAddress(File1MappedAsAnImage);
3025 if (Vad1 == NULL)
3026 {
3027 /* Fail, the address does not exist */
3028 DPRINT1("No VAD at address 1 %p\n", File1MappedAsAnImage);
3030 goto Exit;
3031 }
3032
3033 /* Get the VAD for Address 2 */
3034 Vad2 = MiLocateAddress(File2MappedAsFile);
3035 if (Vad2 == NULL)
3036 {
3037 /* Fail, the address does not exist */
3038 DPRINT1("No VAD at address 2 %p\n", File2MappedAsFile);
3040 goto Exit;
3041 }
3042
3043 /* Get the file object pointer for VAD 1 */
3044 FileObject1 = MiGetFileObjectForVad(Vad1);
3045 if (FileObject1 == NULL)
3046 {
3047 DPRINT1("Failed to get file object for Address 1 %p\n", File1MappedAsAnImage);
3049 goto Exit;
3050 }
3051
3052 /* Get the file object pointer for VAD 2 */
3053 FileObject2 = MiGetFileObjectForVad(Vad2);
3054 if (FileObject2 == NULL)
3055 {
3056 DPRINT1("Failed to get file object for Address 2 %p\n", File2MappedAsFile);
3058 goto Exit;
3059 }
3060
3061 /* Make sure Vad1 is an image mapping */
3062 if (Vad1->u.VadFlags.VadType != VadImageMap)
3063 {
3064 DPRINT1("Address 1 (%p) is not an image mapping\n", File1MappedAsAnImage);
3066 goto Exit;
3067 }
3068
3069 /* SectionObjectPointer is equal if the files are equal */
3070 if (FileObject1->SectionObjectPointer == FileObject2->SectionObjectPointer)
3071 {
3073 }
3074 else
3075 {
3077 }
3078
3079Exit:
3080 /* Unlock address space */
3082 return Status;
3083}
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:354
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:542
static void Exit(void)
Definition: sock.c:1330

◆ NtCreateSection()

NTSTATUS NTAPI NtCreateSection ( OUT PHANDLE  SectionHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN PLARGE_INTEGER MaximumSize  OPTIONAL,
IN ULONG SectionPageProtection  OPTIONAL,
IN ULONG  AllocationAttributes,
IN HANDLE FileHandle  OPTIONAL 
)

Definition at line 3090 of file section.c.

3097{
3098 LARGE_INTEGER SafeMaximumSize;
3100 HANDLE Handle;
3103 PAGED_CODE();
3104
3105 /* Check for non-existing flags */
3108 SEC_NO_CHANGE)))
3109 {
3110 if (!(AllocationAttributes & 1))
3111 {
3112 DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
3114 }
3115 }
3116
3117 /* Check for no allocation type */
3119 {
3120 DPRINT1("Missing allocation type in allocation attributes\n");
3122 }
3123
3124 /* Check for image allocation with invalid attributes */
3128 {
3129 DPRINT1("Image allocation with invalid attributes\n");
3131 }
3132
3133 /* Check for allocation type is both commit and reserve */
3135 {
3136 DPRINT1("Commit and reserve in the same time\n");
3138 }
3139
3140 /* Now check for valid protection */
3145 {
3146 DPRINT1("Sections don't support these protections\n");
3148 }
3149
3150 /* Use a maximum size of zero, if none was specified */
3151 SafeMaximumSize.QuadPart = 0;
3152
3153 /* Check for user-mode caller */
3154 if (PreviousMode != KernelMode)
3155 {
3156 /* Enter SEH */
3157 _SEH2_TRY
3158 {
3159 /* Safely check user-mode parameters */
3160 if (MaximumSize) SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
3161 MaximumSize = &SafeMaximumSize;
3162 ProbeForWriteHandle(SectionHandle);
3163 }
3165 {
3166 /* Return the exception code */
3168 }
3169 _SEH2_END;
3170 }
3171 else if (!MaximumSize) MaximumSize = &SafeMaximumSize;
3172
3173 /* Check that MaximumSize is valid if backed by paging file */
3174 if ((!FileHandle) && (!MaximumSize->QuadPart))
3176
3177 /* Create the section */
3184 FileHandle,
3185 NULL);
3186 if (!NT_SUCCESS(Status)) return Status;
3187
3188 /* FIXME: Should zero last page for a file mapping */
3189
3190 /* Now insert the object */
3192 NULL,
3194 0,
3195 NULL,
3196 &Handle);
3197 if (NT_SUCCESS(Status))
3198 {
3199 /* Enter SEH */
3200 _SEH2_TRY
3201 {
3202 /* Return the handle safely */
3203 *SectionHandle = Handle;
3204 }
3206 {
3207 /* Nothing here */
3208 }
3209 _SEH2_END;
3210 }
3211
3212 /* Return the status */
3213 return Status;
3214}
ULONG Handle
Definition: gdb_input.c:15
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
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:4677
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664

Referenced by BasepMapFile(), CabinetExtractFile(), CabinetOpen(), CON_API(), CreateFileMappingW(), CreateProcessInternalW(), CreateSection(), CSR_API(), CsrpConnectToServer(), CsrSrvCreateSharedSection(), get_binary_type(), get_manifest_in_manifest_file(), get_manifest_in_pe_file(), GRAPHICS_BUFFER_Initialize(), GuiConsoleShowConsoleProperties(), InitFunctionPtrs(), IntGetCodePageEntry(), LdrpCheckForLoadedDll(), LdrpCreateDllSection(), LdrVerifyImageMatchesChecksum(), MapFile(), SdbpOpenMemMappedFile(), SetupCopyFile(), SmpInitializeKnownDllsInternal(), START_TEST(), Test_BasedSection(), Test_EmptyFile(), Test_ImageSection(), Test_ImageSection2(), Test_PageFileSection(), Test_RawSize(), Test_SectionContents(), Test_Truncate(), and TH32CreateSnapshotSectionInitialize().

◆ NtExtendSection()

NTSTATUS NTAPI NtExtendSection ( IN HANDLE  SectionHandle,
IN OUT PLARGE_INTEGER  NewMaximumSize 
)

Definition at line 3531 of file section.c.

3533{
3534 LARGE_INTEGER SafeNewMaximumSize;
3535 PSECTION Section;
3538
3539 /* Check for user-mode parameters */
3540 if (PreviousMode != KernelMode)
3541 {
3542 /* Enter SEH */
3543 _SEH2_TRY
3544 {
3545 /* Probe and capture the maximum size, it's both read and write */
3546 ProbeForWriteLargeInteger(NewMaximumSize);
3547 SafeNewMaximumSize = *NewMaximumSize;
3548 }
3550 {
3551 /* Return the exception code */
3553 }
3554 _SEH2_END;
3555 }
3556 else
3557 {
3558 /* Just read the size directly */
3559 SafeNewMaximumSize = *NewMaximumSize;
3560 }
3561
3562 /* Reference the section */
3563 Status = ObReferenceObjectByHandle(SectionHandle,
3567 (PVOID*)&Section,
3568 NULL);
3569 if (!NT_SUCCESS(Status)) return Status;
3570
3571 Status = MmExtendSection(Section, &SafeNewMaximumSize);
3572
3573 /* Dereference the section */
3574 ObDereferenceObject(Section);
3575
3576 if (NT_SUCCESS(Status))
3577 {
3578 _SEH2_TRY
3579 {
3580 /* Write back the new size */
3581 *NewMaximumSize = SafeNewMaximumSize;
3582 }
3584 {
3586 }
3587 _SEH2_END;
3588 }
3589
3590 /* Return the status */
3592}
#define SECTION_EXTEND_SIZE
Definition: nt_native.h:1294
NTSTATUS NTAPI MmExtendSection(_In_ PVOID Section, _Inout_ PLARGE_INTEGER NewSize)
Definition: section.c:5451
#define ProbeForWriteLargeInteger(Ptr)
Definition: probe.h:46

◆ NtMapViewOfSection()

NTSTATUS NTAPI NtMapViewOfSection ( _In_ HANDLE  SectionHandle,
_In_ HANDLE  ProcessHandle,
_Outptr_result_bytebuffer_ *ViewSize _Pre_valid_ PVOID BaseAddress,
_In_ ULONG_PTR  ZeroBits,
_In_ SIZE_T  CommitSize,
_Inout_opt_ PLARGE_INTEGER  SectionOffset,
_Inout_ PSIZE_T  ViewSize,
_In_range_(ViewShare, ViewUnmap) SECTION_INHERIT  InheritDisposition,
_In_ ULONG  AllocationType,
_In_ ULONG  Win32Protect 
)

Definition at line 3271 of file section.c.

3282{
3283 PVOID SafeBaseAddress;
3284 LARGE_INTEGER SafeSectionOffset;
3285 SIZE_T SafeViewSize;
3286 PSECTION Section;
3290 ULONG ProtectionMask;
3292#if defined(_M_IX86) || defined(_M_AMD64)
3293 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3295#else
3296 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3298#endif
3299
3300 /* Check for invalid inherit disposition */
3301 if ((InheritDisposition < ViewShare) || (InheritDisposition > ViewUnmap))
3302 {
3303 DPRINT1("Invalid inherit disposition: %d\n", InheritDisposition);
3305 }
3306
3307 /* Allow only valid allocation types */
3308 if (AllocationType & ~ValidAllocationType)
3309 {
3310 DPRINT1("Invalid allocation type\n");
3312 }
3313
3314 /* Convert the protection mask, and validate it */
3315 ProtectionMask = MiMakeProtectionMask(Win32Protect);
3316 if (ProtectionMask == MM_INVALID_PROTECTION)
3317 {
3318 DPRINT1("Invalid page protection\n");
3320 }
3321
3322 /* Now convert the protection mask into desired section access mask */
3323 DesiredAccess = MmMakeSectionAccess[ProtectionMask & 0x7];
3324
3325 /* Assume no section offset */
3326 SafeSectionOffset.QuadPart = 0;
3327
3328 /* Enter SEH */
3329 _SEH2_TRY
3330 {
3331 /* Check for unsafe parameters */
3332 if (PreviousMode != KernelMode)
3333 {
3334 /* Probe the parameters */
3337 }
3338
3339 /* Check if a section offset was given */
3340 if (SectionOffset)
3341 {
3342 /* Check for unsafe parameters and capture section offset */
3344 SafeSectionOffset = *SectionOffset;
3345 }
3346
3347 /* Capture the other parameters */
3348 SafeBaseAddress = *BaseAddress;
3349 SafeViewSize = *ViewSize;
3350 }
3352 {
3353 /* Return the exception code */
3355 }
3356 _SEH2_END;
3357
3358 /* Check for kernel-mode address */
3359 if (SafeBaseAddress > MM_HIGHEST_VAD_ADDRESS)
3360 {
3361 DPRINT1("Kernel base not allowed\n");
3363 }
3364
3365 /* Check for range entering kernel-mode */
3366 if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)SafeBaseAddress) < SafeViewSize)
3367 {
3368 DPRINT1("Overflowing into kernel base not allowed\n");
3370 }
3371
3372 /* Check for invalid zero bits */
3373 if (ZeroBits)
3374 {
3376 {
3377 DPRINT1("Invalid zero bits\n");
3379 }
3380
3381 if ((((ULONG_PTR)SafeBaseAddress << ZeroBits) >> ZeroBits) != (ULONG_PTR)SafeBaseAddress)
3382 {
3383 DPRINT1("Invalid zero bits\n");
3385 }
3386
3387 if (((((ULONG_PTR)SafeBaseAddress + SafeViewSize) << ZeroBits) >> ZeroBits) != ((ULONG_PTR)SafeBaseAddress + SafeViewSize))
3388 {
3389 DPRINT1("Invalid zero bits\n");
3391 }
3392 }
3393
3394 /* Reference the process */
3399 (PVOID*)&Process,
3400 NULL);
3401 if (!NT_SUCCESS(Status)) return Status;
3402
3403 /* Reference the section */
3404 Status = ObReferenceObjectByHandle(SectionHandle,
3408 (PVOID*)&Section,
3409 NULL);
3410 if (!NT_SUCCESS(Status))
3411 {
3413 return Status;
3414 }
3415
3416 if (Section->u.Flags.PhysicalMemory)
3417 {
3418 if (PreviousMode == UserMode &&
3419 SafeSectionOffset.QuadPart + SafeViewSize > MmHighestPhysicalPage << PAGE_SHIFT)
3420 {
3421 DPRINT1("Denying map past highest physical page.\n");
3422 ObDereferenceObject(Section);
3425 }
3426 }
3427 else if (!(AllocationType & MEM_DOS_LIM))
3428 {
3429 /* Check for non-allocation-granularity-aligned BaseAddress */
3430 if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
3431 {
3432 DPRINT("BaseAddress is not at 64-kilobyte address boundary.\n");
3433 ObDereferenceObject(Section);
3436 }
3437
3438 /* Do the same for the section offset */
3439 if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
3440 {
3441 DPRINT("SectionOffset is not at 64-kilobyte address boundary.\n");
3442 ObDereferenceObject(Section);
3445 }
3446 }
3447
3448 /* Now do the actual mapping */
3449 Status = MmMapViewOfSection(Section,
3450 Process,
3451 &SafeBaseAddress,
3452 ZeroBits,
3453 CommitSize,
3454 &SafeSectionOffset,
3455 &SafeViewSize,
3456 InheritDisposition,
3458 Win32Protect);
3459
3460 /* Return data only on success */
3461 if (NT_SUCCESS(Status))
3462 {
3463 /* Check if this is an image for the current process */
3464 if ((Section->u.Flags.Image) &&
3467 {
3468 /* Notify the debugger */
3469 DbgkMapViewOfSection(Section,
3470 SafeBaseAddress,
3471 SafeSectionOffset.LowPart,
3472 SafeViewSize);
3473 }
3474
3475 /* Enter SEH */
3476 _SEH2_TRY
3477 {
3478 /* Return parameters to user */
3479 *BaseAddress = SafeBaseAddress;
3480 *ViewSize = SafeViewSize;
3481 if (SectionOffset) *SectionOffset = SafeSectionOffset;
3482 }
3484 {
3485 /* Nothing to do */
3486 }
3487 _SEH2_END;
3488 }
3489
3490 /* Dereference all objects and return status */
3491 ObDereferenceObject(Section);
3493 return Status;
3494}
ACCESS_MASK MmMakeSectionAccess[8]
Definition: section.c:20
VOID NTAPI DbgkMapViewOfSection(IN PVOID Section, IN PVOID BaseAddress, IN ULONG SectionOffset, IN ULONG_PTR ViewSize)
Definition: dbgkutil.c:380
#define PROCESS_VM_OPERATION
Definition: pstypes.h:156
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define UserMode
Definition: asm.h:39
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ ULONG _In_ ULONG Win32Protect
Definition: mmfuncs.h:412
#define MEM_TOP_DOWN
Definition: nt_native.h:1324
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define MEM_LARGE_PAGES
Definition: nt_native.h:1325
#define MI_MAX_ZERO_BITS
Definition: mm.h:83
POBJECT_TYPE PsProcessType
Definition: process.c:20
#define STATUS_MAPPED_ALIGNMENT
Definition: ntstatus.h:798
#define STATUS_INVALID_PARAMETER_8
Definition: ntstatus.h:576
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:571
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:192
#define ProbeForWritePointer(Ptr)
Definition: probe.h:42
#define ProbeForWriteSize_t(Ptr)
Definition: probe.h:45
NTSTATUS NTAPI MmMapViewOfSection(_In_ PVOID SectionObject, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Protect)
Definition: section.c:4031
#define ALIGN_DOWN_POINTER_BY(ptr, align)
Definition: umtypes.h:82

Referenced by BasepLoadLibraryAsDatafile(), CabinetExtractFile(), CabinetOpen(), CON_API(), CsrSrvAttachSharedSection(), CsrSrvCreateSharedSection(), get_manifest_in_manifest_file(), get_manifest_in_pe_file(), GRAPHICS_BUFFER_Initialize(), GuiApplyUserSettings(), GuiConsoleShowConsoleProperties(), Heap32ListFirst(), Heap32ListNext(), InitFunctionPtrs(), LdrpMapDll(), LdrVerifyImageMatchesChecksum(), MapFile(), MapViewOfFileEx(), Module32FirstW(), Module32NextW(), Process32FirstW(), Process32NextW(), SdbpOpenMemMappedFile(), SetupCopyFile(), START_TEST(), Test_BasedSection(), test_cross_process_notifications(), Test_ImageSection(), Test_ImageSection2(), test_notifications(), test_NtMapViewOfSection(), Test_PageFileSection(), test_query_image_information(), test_query_region_information(), Test_RawSize(), Test_SectionContents(), Test_Truncate(), TestPhysicalMemorySection(), TH32CreateSnapshotSectionInitialize(), Thread32First(), and Thread32Next().

◆ NtOpenSection()

NTSTATUS NTAPI NtOpenSection ( OUT PHANDLE  SectionHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes 
)

Definition at line 3218 of file section.c.

3221{
3222 HANDLE Handle;
3225 PAGED_CODE();
3226
3227 /* Check for user-mode caller */
3228 if (PreviousMode != KernelMode)
3229 {
3230 /* Enter SEH */
3231 _SEH2_TRY
3232 {
3233 /* Safely check user-mode parameters */
3234 ProbeForWriteHandle(SectionHandle);
3235 }
3237 {
3238 /* Return the exception code */
3240 }
3241 _SEH2_END;
3242 }
3243
3244 /* Try opening the object */
3248 NULL,
3250 NULL,
3251 &Handle);
3252
3253 /* Enter SEH */
3254 _SEH2_TRY
3255 {
3256 /* Return the handle safely */
3257 *SectionHandle = Handle;
3258 }
3260 {
3261 /* Nothing here */
3262 }
3263 _SEH2_END;
3264
3265 /* Return the status */
3266 return Status;
3267}
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532

Referenced by IntGetCodePageEntry(), LdrpCheckForKnownDll(), NtOpenObject(), OpenFileMappingFromApp(), and OpenFileMappingW().

◆ NtUnmapViewOfSection()

NTSTATUS NTAPI NtUnmapViewOfSection ( IN HANDLE  ProcessHandle,
IN PVOID  BaseAddress 
)

Definition at line 3498 of file section.c.

3500{
3504
3505 /* Don't allowing mapping kernel views */
3507 {
3508 DPRINT1("Trying to unmap a kernel view\n");
3510 }
3511
3512 /* Reference the process */
3517 (PVOID*)&Process,
3518 NULL);
3519 if (!NT_SUCCESS(Status)) return Status;
3520
3521 /* Unmap the view */
3523
3524 /* Dereference the process and return status */
3526 return Status;
3527}
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17

Referenced by BasepSxsCloseHandles(), CabinetExtractFile(), close_cross_process_connection(), CloseCabinet(), CON_API(), CsrSrvCreateSharedSection(), FreeLibrary(), FreeLibraryAndExitThread(), get_manifest_in_manifest_file(), get_manifest_in_pe_file(), GRAPHICS_BUFFER_Destroy(), GRAPHICS_BUFFER_Initialize(), GuiApplyUserSettings(), GuiConsoleShowConsoleProperties(), Heap32ListFirst(), Heap32ListNext(), InitFunctionPtrs(), LdrpCheckForLoadedDll(), LdrpMapDll(), LdrUnloadDll(), LdrVerifyImageMatchesChecksum(), Module32FirstW(), Module32NextW(), Process32FirstW(), Process32NextW(), SdbpCloseMemMappedFile(), SetupCopyFile(), START_TEST(), test_cross_process_notifications(), test_image_mappings(), Test_ImageSection(), test_locale_nls(), test_notifications(), test_NtMapViewOfSection(), test_NtMapViewOfSectionEx(), Test_PageFileSection(), test_query_image_information(), test_query_region_information(), Test_RawSize(), test_section_access(), Test_SectionContents(), Test_Truncate(), TH32CreateSnapshotSectionInitialize(), Thread32First(), Thread32Next(), UnMapFile(), and UnmapViewOfFile().

Variable Documentation

◆ MmCompatibleProtectionMask

◆ MmHighSectionBase

PVOID MmHighSectionBase

Definition at line 111 of file section.c.

Referenced by MmArmInitSystem(), and MmCreateArm3Section().

◆ MmMakeFileAccess

ACCESS_MASK MmMakeFileAccess[8]

◆ MmMakeSectionAccess

ACCESS_MASK MmMakeSectionAccess[8]

◆ MmSectionBasedMutex

KGUARDED_MUTEX MmSectionBasedMutex

Definition at line 110 of file section.c.

Referenced by MiDeleteARM3Section(), MmArmInitSystem(), and MmCreateArm3Section().

◆ MmSectionBasedRoot

◆ MmSectionCommitMutex

◆ MmSession

◆ MmUserProtectionToMask1

◆ MmUserProtectionToMask2