{
SIZE_T SizeLimit;
PFN_COUNT PteCount;
PMMPTE PointerPte;
MMPTETempPte;
PCONTROL_AREA ControlArea;
PSEGMENT NewSegment;
PSUBSECTION Subsection;
PAGED_CODE();
/* No large pages in ARM3 yet */ASSERT((AllocationAttributes & SEC_LARGE_PAGES) == 0);
/* Pagefile-backed sections need a known size */if (!(*MaximumSize)) returnSTATUS_INVALID_PARAMETER_4;
/* Calculate the maximum size possible, given the Prototype PTEs we'll need */
SizeLimit = MAXULONG_PTR - sizeof(SEGMENT);
SizeLimit /= sizeof(MMPTE);
SizeLimit <<= PAGE_SHIFT;
/* Fail if this size is too big */if (*MaximumSize > SizeLimit) returnSTATUS_SECTION_TOO_BIG;
/* Calculate how many Prototype PTEs will be needed */
PteCount = (PFN_COUNT)((*MaximumSize + PAGE_SIZE - 1) >> PAGE_SHIFT);
/* For commited memory, we must have a valid protection mask */if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
/* The segment contains all the Prototype PTEs, allocate it in paged pool */
NewSegment = ExAllocatePoolWithTag(PagedPool,
sizeof(SEGMENT) +
sizeof(MMPTE) * (PteCount - 1),
'tSmM');
ASSERT(NewSegment);
*Segment = NewSegment;
/* Now allocate the control area, which has the subsection structure */
ControlArea = ExAllocatePoolWithTag(NonPagedPool,
sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
'tCmM');
ASSERT(ControlArea);
/* And zero it out, filling the basic segmnet pointer and reference fields */RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
ControlArea->Segment = NewSegment;
ControlArea->NumberOfSectionReferences = 1;
ControlArea->NumberOfUserReferences = 1;
/* Convert allocation attributes to control area flags */if (AllocationAttributes & SEC_BASED) ControlArea->u.Flags.Based = 1;
if (AllocationAttributes & SEC_RESERVE) ControlArea->u.Flags.Reserve = 1;
if (AllocationAttributes & SEC_COMMIT) ControlArea->u.Flags.Commit = 1;
/* The subsection follows, write the mask, PTE count and point back to the CA */
Subsection = (PSUBSECTION)(ControlArea + 1);
Subsection->ControlArea = ControlArea;
Subsection->PtesInSubsection = PteCount;
Subsection->u.SubsectionFlags.Protection = ProtectionMask;
/* Zero out the segment's prototype PTEs, and link it with the control area */
PointerPte = &NewSegment->ThePtes[0];
RtlZeroMemory(NewSegment, sizeof(SEGMENT));
NewSegment->PrototypePte = PointerPte;
NewSegment->ControlArea = ControlArea;
/* Save some extra accounting data for the segment as well */
NewSegment->u1.CreatingProcess = PsGetCurrentProcess();
NewSegment->SizeOfSegment = PteCount * PAGE_SIZE;
NewSegment->TotalNumberOfPtes = PteCount;
NewSegment->NonExtendedPtes = PteCount;
/* The subsection's base address is the first Prototype PTE in the segment */
Subsection->SubsectionBase = PointerPte;
/* Start with an empty PTE, unless this is a commit operation */
TempPte.u.Long = 0;
if (AllocationAttributes & SEC_COMMIT)
{
/* In which case, write down the protection mask in the Prototype PTEs */
TempPte.u.Soft.Protection = ProtectionMask;
/* For accounting, also mark these pages as being committed */
NewSegment->NumberOfCommittedPages = PteCount;
}
/* The template PTE itself for the segment should also have the mask set */
NewSegment->SegmentPteTemplate.u.Soft.Protection = ProtectionMask;
/* Write out the prototype PTEs, for now they're simply demand zero */#ifdef _WIN64RtlFillMemoryUlonglong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
#elseRtlFillMemoryUlong(PointerPte, PteCount * sizeof(MMPTE), TempPte.u.Long);
#endifreturnSTATUS_SUCCESS;
}
Generated on Sun May 27 2012 06:08:12 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.