ReactOS 0.4.17-dev-116-ga4b6fe9
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::@2535 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 1409 of file section.c.

1415{
1416 /* Not yet implemented */
1417 ASSERT(FALSE);
1418 *Segment = NULL;
1420}
#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 1424 of file section.c.

1428{
1429 ULONGLONG SizeLimit;
1430 PFN_COUNT PteCount;
1431 PMMPTE PointerPte;
1432 MMPTE TempPte;
1433 PCONTROL_AREA ControlArea;
1434 PSEGMENT NewSegment;
1435 PSUBSECTION Subsection;
1436 PAGED_CODE();
1437
1438 /* No large pages in ARM3 yet */
1440
1441 /* Pagefile-backed sections need a known size */
1442 if (MaximumSize == 0)
1444
1445 /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
1446 SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
1447 SizeLimit /= sizeof(MMPTE);
1448 SizeLimit <<= PAGE_SHIFT;
1449
1450 /* Fail if this size is too big */
1451 if (MaximumSize > SizeLimit)
1452 {
1454 }
1455
1456 /* Calculate how many Prototype PTEs will be needed */
1457 PteCount = (PFN_COUNT)((MaximumSize + PAGE_SIZE - 1) >> PAGE_SHIFT);
1458
1459 /* For commited memory, we must have a valid protection mask */
1460 if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
1461
1462 /* The segment contains all the Prototype PTEs, allocate it in paged pool */
1463 NewSegment = ExAllocatePoolWithTag(PagedPool,
1464 sizeof(SEGMENT) +
1465 sizeof(MMPTE) * (PteCount - 1),
1466 'tSmM');
1467 if (!NewSegment)
1468 {
1470 }
1471 *Segment = NewSegment;
1472
1473 /* Now allocate the control area, which has the subsection structure */
1474 ControlArea = ExAllocatePoolWithTag(NonPagedPool,
1475 sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
1476 'tCmM');
1477 if (!ControlArea)
1478 {
1479 ExFreePoolWithTag(Segment, 'tSmM');
1481 }
1482
1483 /* And zero it out, filling the basic segmnet pointer and reference fields */
1484 RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
1485 ControlArea->Segment = NewSegment;
1486 ControlArea->NumberOfSectionReferences = 1;
1487 ControlArea->NumberOfUserReferences = 1;
1488
1489 /* Convert allocation attributes to control area flags */
1490 if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
1491 if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
1492 if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
1493
1494 /* We just allocated it */
1495 ControlArea->u.Flags.BeingCreated = 1;
1496
1497 /* The subsection follows, write the mask, PTE count and point back to the CA */
1498 Subsection = (PSUBSECTION)(ControlArea + 1);
1499 Subsection->ControlArea = ControlArea;
1500 Subsection->PtesInSubsection = PteCount;
1501 Subsection->u.SubsectionFlags.Protection = ProtectionMask;
1502
1503 /* Zero out the segment's prototype PTEs, and link it with the control area */
1504 PointerPte = &NewSegment->ThePtes[0];
1505 RtlZeroMemory(NewSegment, sizeof(SEGMENT));
1506 NewSegment->PrototypePte = PointerPte;
1507 NewSegment->ControlArea = ControlArea;
1508
1509 /* Save some extra accounting data for the segment as well */
1510 NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
1511 NewSegment->SizeOfSegment = ((ULONGLONG)PteCount) * PAGE_SIZE;
1512 NewSegment->TotalNumberOfPtes = PteCount;
1513 NewSegment->NonExtendedPtes = PteCount;
1514
1515 /* The subsection's base address is the first Prototype PTE in the segment */
1516 Subsection->SubsectionBase = PointerPte;
1517
1518 /* Start with an empty PTE, unless this is a commit operation */
1519 TempPte.u.Long = 0;
1521 {
1522 /* In which case, write down the protection mask in the Prototype PTEs */
1523 TempPte.u.Soft.Protection = ProtectionMask;
1524
1525 /* For accounting, also mark these pages as being committed */
1526 NewSegment->NumberOfCommittedPages = PteCount;
1527 }
1528
1529 /* The template PTE itself for the segment should also have the mask set */
1530 NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
1531
1532 /* Write out the prototype PTEs, for now they're simply demand zero */
1533#ifdef _WIN64
1534 RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1535#else
1536 RtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
1537#endif
1538 return STATUS_SUCCESS;
1539}
#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
union _CONTROL_AREA::@2849 u
ULONG NumberOfUserReferences
Definition: mmtypes.h:527
MMSECTION_FLAGS Flags
Definition: mmtypes.h:531
ULONG64 Protection
Definition: mmtypes.h:88
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
ULONG BeingCreated
Definition: mmtypes.h:464
union _SEGMENT::@2847 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::@2851 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 2958 of file section.c.

2959{
2961 PCONTROL_AREA ControlArea;
2962 KIRQL OldIrql;
2963
2964 SectionObject = (PSECTION)ObjectBody;
2965
2966 if (SectionObject->u.Flags.Based == 1)
2967 {
2968 /* Remove the node from the global section address tree */
2972 }
2973
2974 /* Lock the PFN database */
2975 OldIrql = MiAcquirePfnLock();
2976
2977 ASSERT(SectionObject->Segment);
2978 ASSERT(SectionObject->Segment->ControlArea);
2979
2980 ControlArea = SectionObject->Segment->ControlArea;
2981
2982 /* Dereference */
2983 ControlArea->NumberOfSectionReferences--;
2984 ControlArea->NumberOfUserReferences--;
2985
2986 ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
2987
2988 /* Check it. It will delete it if there is no more reference to it */
2989 MiCheckControlArea(ControlArea, OldIrql);
2990}
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 1824 of file section.c.

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

1564{
1565 PCONTROL_AREA ControlArea;
1567
1568 /* Check if this is a RosMm memory area */
1569 if (MI_IS_MEMORY_AREA_VAD(Vad))
1570 {
1572
1573 /* We do not expect ARM3 memory areas here, those are kernel only */
1574 ASSERT(MI_IS_ROSMM_VAD(Vad));
1575
1576 /* Check if it's a section view (RosMm section) */
1578 {
1579 /* Get the section pointer to the SECTION_OBJECT */
1580 FileObject = MemoryArea->SectionData.Segment->FileObject;
1581 }
1582 else
1583 {
1584#ifdef NEWCC
1585 ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
1586 DPRINT1("VAD is a cache section!\n");
1587#else
1588 ASSERT(FALSE);
1589#endif
1590 return NULL;
1591 }
1592 }
1593 else
1594 {
1595 /* Make sure it's not a VM VAD */
1596 if (Vad->u.VadFlags.PrivateMemory == 1)
1597 {
1598 DPRINT1("VAD is not a section\n");
1599 return NULL;
1600 }
1601
1602 /* Get the control area */
1603 ControlArea = Vad->ControlArea;
1604 if ((ControlArea == NULL) || !ControlArea->u.Flags.Image)
1605 {
1606 DPRINT1("Address is not a section\n");
1607 return NULL;
1608 }
1609
1610 /* Get the file object */
1611 FileObject = ControlArea->FilePointer;
1612 }
1613
1614 /* Return the file object */
1615 return FileObject;
1616}
_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::@1949 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:112
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:25
_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 /* Get the segment for this section */
1181 Segment = ControlArea->Segment;
1182
1183#ifdef _M_IX86
1184 /* ALlow being less restrictive on x86. */
1186 Granularity = PAGE_SIZE;
1187#endif
1188
1189 /* One can only reserve a file-based mapping, not shared memory! */
1190 if ((AllocationType & MEM_RESERVE) && !(ControlArea->FilePointer))
1191 {
1193 }
1194
1195 /* First, increase the map count. No purging is supported yet */
1196 Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
1197 if (!NT_SUCCESS(Status)) return Status;
1198
1199 /* Check if the caller specified the view size */
1200 if (!(*ViewSize))
1201 {
1202 LONGLONG ViewSizeLL;
1203
1204 /* The caller did not, so pick a 64K aligned view size based on the offset */
1205 SectionOffset->LowPart &= ~(_64K - 1);
1206
1207 /* Calculate size and make sure this fits */
1208 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &ViewSizeLL))
1209 || !NT_SUCCESS(RtlLongLongToSIZET(ViewSizeLL, ViewSize))
1210 || (*ViewSize > MAXLONG_PTR))
1211 {
1212 MiDereferenceControlArea(ControlArea);
1214 }
1215 }
1216 else
1217 {
1218 /* A size was specified, align it to a 64K boundary
1219 * and check for overflow or huge value. */
1220 if (!NT_SUCCESS(RtlSIZETAdd(*ViewSize, SectionOffset->LowPart & (_64K - 1), ViewSize))
1221 || (*ViewSize > MAXLONG_PTR))
1222 {
1223 MiDereferenceControlArea(ControlArea);
1225 }
1226
1227 /* Align the offset as well to make this an aligned map */
1228 SectionOffset->LowPart &= ~((ULONG)_64K - 1);
1229 }
1230
1231 /* We must be dealing with a 64KB aligned offset. This is a Windows ASSERT */
1232 ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
1233
1234 /* Windows ASSERTs for this flag */
1235 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
1236
1237 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
1238 ASSERT(ControlArea->u.Flags.Rom == 0);
1239 Subsection = (PSUBSECTION)(ControlArea + 1);
1240
1241 /* Sections with extended segments are not supported in ARM3 */
1242 ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
1243
1244 /* Within this section, figure out which PTEs will describe the view */
1245 PteOffset = (PFN_NUMBER)(SectionOffset->QuadPart >> PAGE_SHIFT);
1246
1247 /* The offset must be in this segment's PTE chunk and it must be valid. Windows ASSERTs */
1248 ASSERT(PteOffset < Segment->TotalNumberOfPtes);
1249 ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
1250
1251 /* In ARM3, only one subsection is used for now. It must contain these PTEs */
1252 ASSERT(PteOffset < Subsection->PtesInSubsection);
1253
1254 /* In ARM3, only page-file backed sections (shared memory) are supported now */
1255 ASSERT(ControlArea->FilePointer == NULL);
1256
1257 /* Windows ASSERTs for this too -- there must be a subsection base address */
1258 ASSERT(Subsection->SubsectionBase != NULL);
1259
1260 /* Compute how much commit space the segment will take */
1261 if ((CommitSize) && (Segment->NumberOfCommittedPages < Segment->TotalNumberOfPtes))
1262 {
1263 /* Charge for the maximum pages */
1264 QuotaCharge = BYTES_TO_PAGES(CommitSize);
1265 }
1266
1267 /* ARM3 does not currently support large pages */
1268 ASSERT(Segment->SegmentFlags.LargePages == 0);
1269
1270 /* Calculate how many pages the region spans */
1271 ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
1272
1273 /* A VAD can now be allocated. Do so and zero it out */
1274 /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
1275 ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */
1276 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
1277 if (!Vad)
1278 {
1279 MiDereferenceControlArea(ControlArea);
1281 }
1282
1283 RtlZeroMemory(Vad, sizeof(MMVAD_LONG));
1284 Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL;
1285
1286 /* Write all the data required in the VAD for handling a fault */
1287 Vad->ControlArea = ControlArea;
1288 Vad->u.VadFlags.CommitCharge = 0;
1289 Vad->u.VadFlags.Protection = ProtectionMask;
1290 Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
1291 Vad->u2.VadFlags2.Inherit = (InheritDisposition == ViewShare);
1292 if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
1293 {
1294 /* This isn't really implemented yet, but handle setting the flag */
1295 Vad->u.VadFlags.NoChange = 1;
1296 Vad->u2.VadFlags2.SecNoChange = 1;
1297 }
1298
1299 /* Finally, write down the first and last prototype PTE */
1300 Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
1301 PteOffset += ViewSizeInPages - 1;
1302 ASSERT(PteOffset < Subsection->PtesInSubsection);
1303 Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
1304
1305 /* Make sure the prototype PTE ranges make sense, this is a Windows ASSERT */
1307
1308 /* FIXME: Should setup VAD bitmap */
1310
1311 /* Check if anything was committed */
1312 if (QuotaCharge)
1313 {
1314 /* Set the start and end PTE addresses, and pick the template PTE */
1315 PointerPte = Vad->FirstPrototypePte;
1316 LastPte = PointerPte + BYTES_TO_PAGES(CommitSize);
1317 TempPte = Segment->SegmentPteTemplate;
1318
1319 /* Acquire the commit lock and loop all prototype PTEs to be committed */
1321 while (PointerPte < LastPte)
1322 {
1323 /* Make sure the PTE is already invalid */
1324 if (PointerPte->u.Long == 0)
1325 {
1326 /* And write the invalid PTE */
1327 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1328 }
1329 else
1330 {
1331 /* The PTE is valid, so skip it */
1332 QuotaExcess++;
1333 }
1334
1335 /* Move to the next PTE */
1336 PointerPte++;
1337 }
1338
1339 /* Now check how many pages exactly we committed, and update accounting */
1340 ASSERT(QuotaCharge >= QuotaExcess);
1341 QuotaCharge -= QuotaExcess;
1342 Segment->NumberOfCommittedPages += QuotaCharge;
1343 ASSERT(Segment->NumberOfCommittedPages <= Segment->TotalNumberOfPtes);
1344
1345 /* Now that we're done, release the lock */
1347 }
1348
1349 /* Is it SEC_BASED, or did the caller manually specify an address? */
1350 if (*BaseAddress != NULL)
1351 {
1352 /* Just align what the caller gave us */
1353 StartAddress = ALIGN_DOWN_BY((ULONG_PTR)*BaseAddress, Granularity);
1354 }
1355 else if (Section->Address.StartingVpn != 0)
1356 {
1357 /* It is a SEC_BASED mapping, use the address that was generated */
1358 StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart;
1359 }
1360 else
1361 {
1362 StartAddress = 0;
1363 }
1364
1366 if (!NT_SUCCESS(Status))
1367 {
1368 ExFreePoolWithTag(Vad, 'ldaV');
1369 MiDereferenceControlArea(ControlArea);
1370
1372 Segment->NumberOfCommittedPages -= QuotaCharge;
1374 return Status;
1375 }
1376
1377 /* Insert the VAD */
1379 &StartAddress,
1380 ViewSizeInPages * PAGE_SIZE,
1382 Granularity,
1384 if (!NT_SUCCESS(Status))
1385 {
1386 ExFreePoolWithTag(Vad, 'ldaV');
1387 MiDereferenceControlArea(ControlArea);
1388
1390 Segment->NumberOfCommittedPages -= QuotaCharge;
1392
1394 return Status;
1395 }
1396
1397 /* Windows stores this for accounting purposes, do so as well */
1398 if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
1399
1400 /* Finally, let the caller know where, and for what size, the view was mapped */
1401 *ViewSize = ViewSizeInPages * PAGE_SIZE;
1402 *BaseAddress = (PVOID)StartAddress;
1403 DPRINT("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
1404 return STATUS_SUCCESS;
1405}
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
@ 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
union _MMVAD_LONG::@2860 u2
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
union _MMVAD_LONG::@2859 u
union _MMVAD_LONG::@2862 u4
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771

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

1762{
1766 PMEMORY_SECTION_NAME SectionName = NULL;
1768
1771 NULL,
1773 (PVOID*)(&Process),
1774 NULL);
1775
1776 if (!NT_SUCCESS(Status))
1777 {
1778 DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
1779 return Status;
1780 }
1781
1783
1784 if (NT_SUCCESS(Status))
1785 {
1786 SectionName = MemoryInformation;
1787 if (PreviousMode != KernelMode)
1788 {
1789 _SEH2_TRY
1790 {
1791 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1792 (PWSTR)(SectionName + 1),
1793 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1795
1797
1798 }
1800 {
1802 }
1803 _SEH2_END;
1804 }
1805 else
1806 {
1807 RtlInitEmptyUnicodeString(&SectionName->SectionFileName,
1808 (PWSTR)(SectionName + 1),
1809 MemoryInformationLength - sizeof(MEMORY_SECTION_NAME));
1811
1813
1814 }
1815
1817 }
1819 return Status;
1820}
NTSTATUS NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName)
Definition: section.c:1694
_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 2027 of file section.c.

2030{
2031 ULONG Hash, Size, Count = 0;
2033 PAGED_CODE();
2034
2035 /* Compute the hash for this entry and loop trying to find it */
2036 Entry = (ULONG_PTR)Base >> 16;
2037 Hash = Entry % Session->SystemSpaceHashKey;
2038 while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Entry)
2039 {
2040 /* Check if we overflew past the end of the hash table */
2041 if (++Hash >= Session->SystemSpaceHashSize)
2042 {
2043 /* Reset the hash to zero and keep searching from the bottom */
2044 Hash = 0;
2045 if (++Count == 2)
2046 {
2047 /* But if we overflew twice, then this is not a real mapping */
2048 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2049 (ULONG_PTR)Base,
2050 1,
2051 0,
2052 0);
2053 }
2054 }
2055 }
2056
2057 /* One less entry */
2058 Session->SystemSpaceHashEntries--;
2059
2060 /* Extract the size and clear the entry */
2061 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2062 Session->SystemSpaceViewTable[Hash].Entry = 0;
2063
2064 /* Return the control area and the size */
2065 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2066 return Size;
2067}
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 1925 of file section.c.

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

2073{
2074 ULONG Size;
2075 PCONTROL_AREA ControlArea;
2076 PAGED_CODE();
2077
2078 /* Remove this mapping */
2079 KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
2080 Size = MiRemoveFromSystemSpace(Session, MappedBase, &ControlArea);
2081
2082 /* Clear the bits for this mapping */
2083 RtlClearBits(Session->SystemSpaceBitMap,
2084 (ULONG)(((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16),
2085 Size);
2086
2087 /* Convert the size from a bit size into the actual size */
2088 Size = Size * (_64K >> PAGE_SHIFT);
2089
2090 /* Remove the PTEs now */
2091 MiRemoveMappedPtes(MappedBase, Size, ControlArea, NULL);
2092 KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
2093
2094 /* Return success */
2095 return STATUS_SUCCESS;
2096}
static ULONG MiRemoveFromSystemSpace(IN PMMSESSION Session, IN PVOID Base, OUT PCONTROL_AREA *ControlArea)
Definition: section.c:2027
static VOID MiRemoveMappedPtes(IN PVOID BaseAddress, IN ULONG NumberOfPtes, IN PCONTROL_AREA ControlArea, IN PMMSUPPORT Ws)
Definition: section.c:1925
#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::@2856 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:1711

Referenced by MmUnmapViewOfSection(), and NtUnmapViewOfSection().

◆ MmCommitSessionMappedView()

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

Definition at line 2795 of file section.c.

2797{
2798 ULONG_PTR StartAddress, EndingAddress, Base;
2799 ULONG Hash, Count = 0, Size, QuotaCharge;
2800 PMMSESSION Session;
2801 PMMPTE LastProtoPte, PointerPte, ProtoPte;
2802 PCONTROL_AREA ControlArea;
2804 PSUBSECTION Subsection;
2805 MMPTE TempPte;
2806 PAGED_CODE();
2807
2808 /* Make sure the base isn't past the session view range */
2811 {
2812 DPRINT1("Base outside of valid range\n");
2814 }
2815
2816 /* Make sure the size isn't past the session view range */
2819 {
2820 DPRINT1("Size outside of valid range\n");
2822 }
2823
2824 /* Sanity check */
2825 ASSERT(ViewSize != 0);
2826
2827 /* Process must be in a session */
2828 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2829 {
2830 DPRINT1("Process is not in session\n");
2832 }
2833
2834 /* Compute the correctly aligned base and end addresses */
2835 StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
2836 EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
2837
2838 /* Sanity check and grab the session */
2840 Session = &MmSessionSpace->Session;
2841
2842 /* Get the hash entry for this allocation */
2843 Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
2844
2845 /* Lock system space */
2847
2848 /* Loop twice so we can try rolling over if needed */
2849 while (TRUE)
2850 {
2851 /* Extract the size and base addresses from the entry */
2852 Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
2853 Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
2854
2855 /* Convert the size to bucket chunks */
2857
2858 /* Bail out if this entry fits in here */
2859 if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
2860
2861 /* Check if we overflew past the end of the hash table */
2862 if (++Hash >= Session->SystemSpaceHashSize)
2863 {
2864 /* Reset the hash to zero and keep searching from the bottom */
2865 Hash = 0;
2866 if (++Count == 2)
2867 {
2868 /* But if we overflew twice, then this is not a real mapping */
2869 KeBugCheckEx(DRIVER_UNMAPPING_INVALID_VIEW,
2870 Base,
2871 2,
2872 0,
2873 0);
2874 }
2875 }
2876 }
2877
2878 /* Make sure the view being mapped is not file-based */
2879 ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
2880 if (ControlArea->FilePointer != NULL)
2881 {
2882 /* It is, so we have to bail out */
2883 DPRINT1("Only page-filed backed sections can be commited\n");
2886 }
2887
2888 /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
2889 ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
2890 ASSERT(ControlArea->u.Flags.Rom == 0);
2891 Subsection = (PSUBSECTION)(ControlArea + 1);
2892
2893 /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
2894 ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
2895 QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
2896 LastProtoPte = ProtoPte + QuotaCharge;
2897 if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
2898 {
2899 DPRINT1("PTE is out of bounds\n");
2902 }
2903
2904 /* Acquire the commit lock and count all the non-committed PTEs */
2906 PointerPte = ProtoPte;
2907 while (PointerPte < LastProtoPte)
2908 {
2909 if (PointerPte->u.Long) QuotaCharge--;
2910 PointerPte++;
2911 }
2912
2913 /* Was everything committed already? */
2914 if (!QuotaCharge)
2915 {
2916 /* Nothing to do! */
2919 return STATUS_SUCCESS;
2920 }
2921
2922 /* Pick the segment and template PTE */
2923 Segment = ControlArea->Segment;
2924 TempPte = Segment->SegmentPteTemplate;
2925 ASSERT(TempPte.u.Long != 0);
2926
2927 /* Loop all prototype PTEs to be committed */
2928 PointerPte = ProtoPte;
2929 while (PointerPte < LastProtoPte)
2930 {
2931 /* Make sure the PTE is already invalid */
2932 if (PointerPte->u.Long == 0)
2933 {
2934 /* And write the invalid PTE */
2935 MI_WRITE_INVALID_PTE(PointerPte, TempPte);
2936 }
2937
2938 /* Move to the next PTE */
2939 PointerPte++;
2940 }
2941
2942 /* Check if we had at least one page charged */
2943 if (QuotaCharge)
2944 {
2945 /* Update the accounting data */
2946 Segment->NumberOfCommittedPages += QuotaCharge;
2948 }
2949
2950 /* Release all */
2953 return STATUS_SUCCESS;
2954}
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 2105 of file section.c.

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

2674{
2676 return FALSE;
2677}

◆ MmDoesFileHaveUserWritableReferences()

ULONG NTAPI MmDoesFileHaveUserWritableReferences ( IN PSECTION_OBJECT_POINTERS  SectionPointer)

Definition at line 2994 of file section.c.

2995{
2997 return 0;
2998}
#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 2684 of file section.c.

2686{
2688 return FALSE;
2689}

Referenced by RxPurgeFcbInSystemCache(), and RxPurgeNetFcb().

◆ MmGetFileNameForAddress()

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

Definition at line 1694 of file section.c.

1696{
1697 POBJECT_NAME_INFORMATION ModuleNameInformation;
1700 PMMVAD Vad;
1702
1703 /* Lock address space */
1706
1707 /* Get the VAD */
1708 Vad = MiLocateAddress(Address);
1709 if (Vad == NULL)
1710 {
1711 /* Fail, the address does not exist */
1712 DPRINT1("No VAD at address %p\n", Address);
1715 }
1716
1717 /* Get the file object pointer for the VAD */
1719 if (FileObject == NULL)
1720 {
1721 DPRINT1("Failed to get file object for Address %p\n", Address);
1724 }
1725
1726 /* Reference the file object */
1728
1729 /* Unlock address space */
1731
1732 /* Get the filename of the file object */
1733 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1734
1735 /* Dereference the file object */
1737
1738 /* Check if we were able to get the file object name */
1739 if (NT_SUCCESS(Status))
1740 {
1741 /* Init modulename */
1742 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1744
1745 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1746 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1747
1748 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1749 }
1750
1751 /* Return status */
1752 return Status;
1753}
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1562
static NTSTATUS MmGetFileNameForFileObject(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1641
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 1641 of file section.c.

1643{
1644 POBJECT_NAME_INFORMATION ObjectNameInfo;
1647
1648 /* Allocate memory for our structure */
1649 ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, 1024, TAG_MM);
1650 if (!ObjectNameInfo) return STATUS_NO_MEMORY;
1651
1652 /* Query the name */
1654 ObjectNameInfo,
1655 1024,
1656 &ReturnLength);
1657 if (!NT_SUCCESS(Status))
1658 {
1659 /* Failed, free memory */
1660 DPRINT1("Name query failed\n");
1661 ExFreePoolWithTag(ObjectNameInfo, TAG_MM);
1662 *ModuleName = NULL;
1663 return Status;
1664 }
1665
1666 /* Success */
1667 *ModuleName = ObjectNameInfo;
1668 return STATUS_SUCCESS;
1669}
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 1673 of file section.c.

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

Referenced by DbgkCreateThread(), and DbgkpSectionToFileHandle().

◆ MmGetFileObjectForSection()

PFILE_OBJECT NTAPI MmGetFileObjectForSection ( IN PVOID  SectionObject)

Definition at line 1543 of file section.c.

1544{
1545 PSECTION Section = SectionObject;
1548
1549 /* Check if it's an ARM3, or ReactOS section */
1551 {
1552 /* Return the file pointer stored in the control area */
1553 return Section->Segment->ControlArea->FilePointer;
1554 }
1555
1556 /* Return the file object */
1557 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1558}
#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 1620 of file section.c.

1621{
1623
1624 /* Get the section object of this process*/
1625 SectionObject = PsGetCurrentProcess()->SectionObject;
1628
1629 if (SectionObject->u.Flags.Image == 0)
1630 {
1631 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1632 return;
1633 }
1634
1635 /* Return the image information */
1636 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1637}
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 2696 of file section.c.

2699{
2700 PAGED_CODE();
2702
2703 // HACK
2704 if (MiIsRosSectionObject(Section))
2705 {
2706 return MmMapViewInSystemSpace(Section, MappedBase, ViewSize);
2707 }
2708
2709 /* Process must be in a session */
2710 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2711 {
2712 DPRINT1("Process is not in session\n");
2714 }
2715
2716 /* Use the system space API, but with the session view instead */
2718 SectionOffset.QuadPart = 0;
2719 return MiMapViewInSystemSpace(Section,
2721 MappedBase,
2722 ViewSize,
2723 &SectionOffset);
2724}
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 2534 of file section.c.

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

2732{
2733 PAGED_CODE();
2734
2735 // HACK
2737 {
2739 }
2740
2741 /* Process must be in a session */
2742 if (PsGetCurrentProcess()->ProcessInSession == FALSE)
2743 {
2744 DPRINT1("Proess is not in session\n");
2746 }
2747
2748 /* Use the system space API, but with the session view instead */
2751 MappedBase);
2752}
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:2770
static NTSTATUS MiUnmapViewInSystemSpace(IN PMMSESSION Session, IN PVOID MappedBase)
Definition: section.c:2071
#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 2770 of file section.c.

2771{
2773 PAGED_CODE();
2774
2775 /* Was this mapped by RosMm? */
2779 {
2782 return Status;
2783 }
2785
2786 /* It was not, call the ARM3 routine */
2788}
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 2759 of file section.c.

2761{
2763}
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 3004 of file section.c.

3006{
3008 PMMVAD Vad1, Vad2;
3009 PFILE_OBJECT FileObject1, FileObject2;
3011
3012 /* Lock address space */
3015
3016 /* Get the VAD for Address 1 */
3017 Vad1 = MiLocateAddress(File1MappedAsAnImage);
3018 if (Vad1 == NULL)
3019 {
3020 /* Fail, the address does not exist */
3021 DPRINT1("No VAD at address 1 %p\n", File1MappedAsAnImage);
3023 goto Exit;
3024 }
3025
3026 /* Get the VAD for Address 2 */
3027 Vad2 = MiLocateAddress(File2MappedAsFile);
3028 if (Vad2 == NULL)
3029 {
3030 /* Fail, the address does not exist */
3031 DPRINT1("No VAD at address 2 %p\n", File2MappedAsFile);
3033 goto Exit;
3034 }
3035
3036 /* Get the file object pointer for VAD 1 */
3037 FileObject1 = MiGetFileObjectForVad(Vad1);
3038 if (FileObject1 == NULL)
3039 {
3040 DPRINT1("Failed to get file object for Address 1 %p\n", File1MappedAsAnImage);
3042 goto Exit;
3043 }
3044
3045 /* Get the file object pointer for VAD 2 */
3046 FileObject2 = MiGetFileObjectForVad(Vad2);
3047 if (FileObject2 == NULL)
3048 {
3049 DPRINT1("Failed to get file object for Address 2 %p\n", File2MappedAsFile);
3051 goto Exit;
3052 }
3053
3054 /* Make sure Vad1 is an image mapping */
3055 if (Vad1->u.VadFlags.VadType != VadImageMap)
3056 {
3057 DPRINT1("Address 1 (%p) is not an image mapping\n", File1MappedAsAnImage);
3059 goto Exit;
3060 }
3061
3062 /* SectionObjectPointer is equal if the files are equal */
3063 if (FileObject1->SectionObjectPointer == FileObject2->SectionObjectPointer)
3064 {
3066 }
3067 else
3068 {
3070 }
3071
3072Exit:
3073 /* Unlock address space */
3075 return Status;
3076}
#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 3083 of file section.c.

3090{
3091 LARGE_INTEGER SafeMaximumSize;
3093 HANDLE Handle;
3096 PAGED_CODE();
3097
3098 /* Check for non-existing flags */
3101 SEC_NO_CHANGE)))
3102 {
3103 if (!(AllocationAttributes & 1))
3104 {
3105 DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
3107 }
3108 }
3109
3110 /* Check for no allocation type */
3112 {
3113 DPRINT1("Missing allocation type in allocation attributes\n");
3115 }
3116
3117 /* Check for image allocation with invalid attributes */
3121 {
3122 DPRINT1("Image allocation with invalid attributes\n");
3124 }
3125
3126 /* Check for allocation type is both commit and reserve */
3128 {
3129 DPRINT1("Commit and reserve in the same time\n");
3131 }
3132
3133 /* Now check for valid protection */
3138 {
3139 DPRINT1("Sections don't support these protections\n");
3141 }
3142
3143 /* Use a maximum size of zero, if none was specified */
3144 SafeMaximumSize.QuadPart = 0;
3145
3146 /* Check for user-mode caller */
3147 if (PreviousMode != KernelMode)
3148 {
3149 /* Enter SEH */
3150 _SEH2_TRY
3151 {
3152 /* Safely check user-mode parameters */
3153 if (MaximumSize) SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
3154 MaximumSize = &SafeMaximumSize;
3155 ProbeForWriteHandle(SectionHandle);
3156 }
3158 {
3159 /* Return the exception code */
3161 }
3162 _SEH2_END;
3163 }
3164 else if (!MaximumSize) MaximumSize = &SafeMaximumSize;
3165
3166 /* Check that MaximumSize is valid if backed by paging file */
3167 if ((!FileHandle) && (!MaximumSize->QuadPart))
3169
3170 /* Create the section */
3177 FileHandle,
3178 NULL);
3179 if (!NT_SUCCESS(Status)) return Status;
3180
3181 /* FIXME: Should zero last page for a file mapping */
3182
3183 /* Now insert the object */
3185 NULL,
3187 0,
3188 NULL,
3189 &Handle);
3190 if (NT_SUCCESS(Status))
3191 {
3192 /* Enter SEH */
3193 _SEH2_TRY
3194 {
3195 /* Return the handle safely */
3196 *SectionHandle = Handle;
3197 }
3199 {
3200 /* Nothing here */
3201 }
3202 _SEH2_END;
3203 }
3204
3205 /* Return the status */
3206 return Status;
3207}
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 3524 of file section.c.

3526{
3527 LARGE_INTEGER SafeNewMaximumSize;
3528 PSECTION Section;
3531
3532 /* Check for user-mode parameters */
3533 if (PreviousMode != KernelMode)
3534 {
3535 /* Enter SEH */
3536 _SEH2_TRY
3537 {
3538 /* Probe and capture the maximum size, it's both read and write */
3539 ProbeForWriteLargeInteger(NewMaximumSize);
3540 SafeNewMaximumSize = *NewMaximumSize;
3541 }
3543 {
3544 /* Return the exception code */
3546 }
3547 _SEH2_END;
3548 }
3549 else
3550 {
3551 /* Just read the size directly */
3552 SafeNewMaximumSize = *NewMaximumSize;
3553 }
3554
3555 /* Reference the section */
3556 Status = ObReferenceObjectByHandle(SectionHandle,
3560 (PVOID*)&Section,
3561 NULL);
3562 if (!NT_SUCCESS(Status)) return Status;
3563
3564 Status = MmExtendSection(Section, &SafeNewMaximumSize);
3565
3566 /* Dereference the section */
3567 ObDereferenceObject(Section);
3568
3569 if (NT_SUCCESS(Status))
3570 {
3571 _SEH2_TRY
3572 {
3573 /* Write back the new size */
3574 *NewMaximumSize = SafeNewMaximumSize;
3575 }
3577 {
3579 }
3580 _SEH2_END;
3581 }
3582
3583 /* Return the status */
3585}
#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 3264 of file section.c.

3275{
3276 PVOID SafeBaseAddress;
3277 LARGE_INTEGER SafeSectionOffset;
3278 SIZE_T SafeViewSize;
3279 PSECTION Section;
3283 ULONG ProtectionMask;
3285#if defined(_M_IX86) || defined(_M_AMD64)
3286 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3288#else
3289 static const ULONG ValidAllocationType = (MEM_TOP_DOWN | MEM_LARGE_PAGES |
3291#endif
3292
3293 /* Check for invalid inherit disposition */
3294 if ((InheritDisposition > ViewUnmap) || (InheritDisposition < ViewShare))
3295 {
3296 DPRINT1("Invalid inherit disposition\n");
3298 }
3299
3300 /* Allow only valid allocation types */
3301 if (AllocationType & ~ValidAllocationType)
3302 {
3303 DPRINT1("Invalid allocation type\n");
3305 }
3306
3307 /* Convert the protection mask, and validate it */
3308 ProtectionMask = MiMakeProtectionMask(Win32Protect);
3309 if (ProtectionMask == MM_INVALID_PROTECTION)
3310 {
3311 DPRINT1("Invalid page protection\n");
3313 }
3314
3315 /* Now convert the protection mask into desired section access mask */
3316 DesiredAccess = MmMakeSectionAccess[ProtectionMask & 0x7];
3317
3318 /* Assume no section offset */
3319 SafeSectionOffset.QuadPart = 0;
3320
3321 /* Enter SEH */
3322 _SEH2_TRY
3323 {
3324 /* Check for unsafe parameters */
3325 if (PreviousMode != KernelMode)
3326 {
3327 /* Probe the parameters */
3330 }
3331
3332 /* Check if a section offset was given */
3333 if (SectionOffset)
3334 {
3335 /* Check for unsafe parameters and capture section offset */
3337 SafeSectionOffset = *SectionOffset;
3338 }
3339
3340 /* Capture the other parameters */
3341 SafeBaseAddress = *BaseAddress;
3342 SafeViewSize = *ViewSize;
3343 }
3345 {
3346 /* Return the exception code */
3348 }
3349 _SEH2_END;
3350
3351 /* Check for kernel-mode address */
3352 if (SafeBaseAddress > MM_HIGHEST_VAD_ADDRESS)
3353 {
3354 DPRINT1("Kernel base not allowed\n");
3356 }
3357
3358 /* Check for range entering kernel-mode */
3359 if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)SafeBaseAddress) < SafeViewSize)
3360 {
3361 DPRINT1("Overflowing into kernel base not allowed\n");
3363 }
3364
3365 /* Check for invalid zero bits */
3366 if (ZeroBits)
3367 {
3369 {
3370 DPRINT1("Invalid zero bits\n");
3372 }
3373
3374 if ((((ULONG_PTR)SafeBaseAddress << ZeroBits) >> ZeroBits) != (ULONG_PTR)SafeBaseAddress)
3375 {
3376 DPRINT1("Invalid zero bits\n");
3378 }
3379
3380 if (((((ULONG_PTR)SafeBaseAddress + SafeViewSize) << ZeroBits) >> ZeroBits) != ((ULONG_PTR)SafeBaseAddress + SafeViewSize))
3381 {
3382 DPRINT1("Invalid zero bits\n");
3384 }
3385 }
3386
3387 /* Reference the process */
3392 (PVOID*)&Process,
3393 NULL);
3394 if (!NT_SUCCESS(Status)) return Status;
3395
3396 /* Reference the section */
3397 Status = ObReferenceObjectByHandle(SectionHandle,
3401 (PVOID*)&Section,
3402 NULL);
3403 if (!NT_SUCCESS(Status))
3404 {
3406 return Status;
3407 }
3408
3409 if (Section->u.Flags.PhysicalMemory)
3410 {
3411 if (PreviousMode == UserMode &&
3412 SafeSectionOffset.QuadPart + SafeViewSize > MmHighestPhysicalPage << PAGE_SHIFT)
3413 {
3414 DPRINT1("Denying map past highest physical page.\n");
3415 ObDereferenceObject(Section);
3418 }
3419 }
3420 else if (!(AllocationType & MEM_DOS_LIM))
3421 {
3422 /* Check for non-allocation-granularity-aligned BaseAddress */
3423 if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
3424 {
3425 DPRINT("BaseAddress is not at 64-kilobyte address boundary.\n");
3426 ObDereferenceObject(Section);
3429 }
3430
3431 /* Do the same for the section offset */
3432 if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
3433 {
3434 DPRINT("SectionOffset is not at 64-kilobyte address boundary.\n");
3435 ObDereferenceObject(Section);
3438 }
3439 }
3440
3441 /* Now do the actual mapping */
3442 Status = MmMapViewOfSection(Section,
3443 Process,
3444 &SafeBaseAddress,
3445 ZeroBits,
3446 CommitSize,
3447 &SafeSectionOffset,
3448 &SafeViewSize,
3449 InheritDisposition,
3451 Win32Protect);
3452
3453 /* Return data only on success */
3454 if (NT_SUCCESS(Status))
3455 {
3456 /* Check if this is an image for the current process */
3457 if ((Section->u.Flags.Image) &&
3460 {
3461 /* Notify the debugger */
3462 DbgkMapViewOfSection(Section,
3463 SafeBaseAddress,
3464 SafeSectionOffset.LowPart,
3465 SafeViewSize);
3466 }
3467
3468 /* Enter SEH */
3469 _SEH2_TRY
3470 {
3471 /* Return parameters to user */
3472 *BaseAddress = SafeBaseAddress;
3473 *ViewSize = SafeViewSize;
3474 if (SectionOffset) *SectionOffset = SafeSectionOffset;
3475 }
3477 {
3478 /* Nothing to do */
3479 }
3480 _SEH2_END;
3481 }
3482
3483 /* Dereference all objects and return status */
3484 ObDereferenceObject(Section);
3486 return Status;
3487}
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
@ ViewUnmap
Definition: nt_native.h:1282
#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 3211 of file section.c.

3214{
3215 HANDLE Handle;
3218 PAGED_CODE();
3219
3220 /* Check for user-mode caller */
3221 if (PreviousMode != KernelMode)
3222 {
3223 /* Enter SEH */
3224 _SEH2_TRY
3225 {
3226 /* Safely check user-mode parameters */
3227 ProbeForWriteHandle(SectionHandle);
3228 }
3230 {
3231 /* Return the exception code */
3233 }
3234 _SEH2_END;
3235 }
3236
3237 /* Try opening the object */
3241 NULL,
3243 NULL,
3244 &Handle);
3245
3246 /* Enter SEH */
3247 _SEH2_TRY
3248 {
3249 /* Return the handle safely */
3250 *SectionHandle = Handle;
3251 }
3253 {
3254 /* Nothing here */
3255 }
3256 _SEH2_END;
3257
3258 /* Return the status */
3259 return Status;
3260}
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 3491 of file section.c.

3493{
3497
3498 /* Don't allowing mapping kernel views */
3500 {
3501 DPRINT1("Trying to unmap a kernel view\n");
3503 }
3504
3505 /* Reference the process */
3510 (PVOID*)&Process,
3511 NULL);
3512 if (!NT_SUCCESS(Status)) return Status;
3513
3514 /* Unmap the view */
3516
3517 /* Dereference the process and return status */
3519 return Status;
3520}
#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