mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[NTOSKRNL]: Cleanup MmCreateArm3Section a little bit to handle file-backed sections in the future.
[NTOSKRNL]: Remove an ASSERT(FALSE) that was only there for testing. [NTOSKRNL]: Support transition pages during prototype PTE faults, which is our first try at soft faults! Should fix ASSERTs that were seen in the previous attempts in ole32, corrupting the registry. [NTOSKRNL]: It's fine for MiCreatePagingFileMap to fail in MmCreateSection -- don't assert and simply return failure. Should fix the ASSERTs taht were seen in KmTest. [NTOSKRNL]: Enable richard's ARM3 section code unconditionally for all non-file backed sections. Works4me. Let's see what Testbot says. Nobody has showed me how to use/where is PatchBot, and google founds 0 relevant results, so this is going into main again. However I'm actually home this week to revert if something goes wrong :) svn path=/trunk/; revision=57209
This commit is contained in:
parent
5666d93992
commit
cda03c0940
4 changed files with 304 additions and 46 deletions
|
@ -980,8 +980,51 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
|
||||||
else if ((TempPte.u.Soft.Prototype == 0) &&
|
else if ((TempPte.u.Soft.Prototype == 0) &&
|
||||||
(TempPte.u.Soft.Transition == 1))
|
(TempPte.u.Soft.Transition == 1))
|
||||||
{
|
{
|
||||||
/* No standby support yet */
|
/* This is a standby page, bring it back from the cache */
|
||||||
ASSERT(FALSE);
|
PageFrameIndex = TempPte.u.Trans.PageFrameNumber;
|
||||||
|
DPRINT1("oooh, shiny, a soft fault! 0x%lx\n", PageFrameIndex);
|
||||||
|
Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
|
||||||
|
ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
|
||||||
|
|
||||||
|
/* Should not yet happen in ReactOS */
|
||||||
|
ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
|
||||||
|
ASSERT(Pfn1->u4.InPageError == 0);
|
||||||
|
|
||||||
|
/* Get the page */
|
||||||
|
MiUnlinkPageFromList(Pfn1);
|
||||||
|
|
||||||
|
/* Bump its reference count */
|
||||||
|
ASSERT(Pfn1->u2.ShareCount == 0);
|
||||||
|
InterlockedIncrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
|
||||||
|
Pfn1->u2.ShareCount++;
|
||||||
|
|
||||||
|
/* Make it valid again */
|
||||||
|
/* This looks like another macro.... */
|
||||||
|
Pfn1->u3.e1.PageLocation = ActiveAndValid;
|
||||||
|
ASSERT(PointerProtoPte->u.Hard.Valid == 0);
|
||||||
|
ASSERT(PointerProtoPte->u.Trans.Prototype == 0);
|
||||||
|
ASSERT(PointerProtoPte->u.Trans.Transition == 1);
|
||||||
|
TempPte.u.Long = (PointerProtoPte->u.Long & ~0xFFF) |
|
||||||
|
MmProtectToPteMask[PointerProtoPte->u.Trans.Protection];
|
||||||
|
TempPte.u.Hard.Valid = 1;
|
||||||
|
TempPte.u.Hard.Accessed = 1;
|
||||||
|
|
||||||
|
/* Is the PTE writeable? */
|
||||||
|
if (((Pfn1->u3.e1.Modified) && (TempPte.u.Hard.Write)) &&
|
||||||
|
(TempPte.u.Hard.CopyOnWrite == 0))
|
||||||
|
{
|
||||||
|
/* Make it dirty */
|
||||||
|
TempPte.u.Hard.Dirty = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Make it clean */
|
||||||
|
TempPte.u.Hard.Dirty = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the valid PTE */
|
||||||
|
MI_WRITE_VALID_PTE(PointerProtoPte, TempPte);
|
||||||
|
ASSERT(PointerPte->u.Hard.Valid == 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1335,7 +1335,6 @@ MiDecrementReferenceCount(IN PMMPFN Pfn1,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see which list this page should go into */
|
/* Check to see which list this page should go into */
|
||||||
ASSERT(FALSE);
|
|
||||||
if (Pfn1->u3.e1.Modified == 1)
|
if (Pfn1->u3.e1.Modified == 1)
|
||||||
{
|
{
|
||||||
/* Push it into the modified page list */
|
/* Push it into the modified page list */
|
||||||
|
|
|
@ -1243,6 +1243,37 @@ MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiSubsectionConsistent(IN PSUBSECTION Subsection)
|
||||||
|
{
|
||||||
|
/* ReactOS only supports systems with 4K pages and 4K sectors */
|
||||||
|
ASSERT(Subsection->u.SubsectionFlags.SectorEndOffset == 0);
|
||||||
|
|
||||||
|
/* Therefore, then number of PTEs should be equal to the number of sectors */
|
||||||
|
if (Subsection->NumberOfFullSectors != Subsection->PtesInSubsection)
|
||||||
|
{
|
||||||
|
/* Break and warn if this is inconsistent */
|
||||||
|
DPRINT1("Mm: Subsection inconsistent (%x vs %x)\n",
|
||||||
|
Subsection->NumberOfFullSectors, Subsection->PtesInSubsection);
|
||||||
|
DbgBreakPoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MiCreateDataFileMap(IN PFILE_OBJECT File,
|
||||||
|
OUT PSEGMENT *Segment,
|
||||||
|
IN PSIZE_T MaximumSize,
|
||||||
|
IN ULONG SectionPageProtection,
|
||||||
|
IN ULONG AllocationAttributes,
|
||||||
|
IN ULONG IgnoreFileSizing)
|
||||||
|
{
|
||||||
|
/* Not yet implemented */
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiCreatePagingFileMap(OUT PSEGMENT *Segment,
|
MiCreatePagingFileMap(OUT PSEGMENT *Segment,
|
||||||
|
@ -2048,15 +2079,15 @@ MmCreateArm3Section(OUT PVOID *SectionObject,
|
||||||
SECTION Section;
|
SECTION Section;
|
||||||
PSECTION NewSection;
|
PSECTION NewSection;
|
||||||
PSUBSECTION Subsection;
|
PSUBSECTION Subsection;
|
||||||
PSEGMENT NewSegment;
|
PSEGMENT NewSegment, Segment;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PCONTROL_AREA ControlArea;
|
PCONTROL_AREA ControlArea;
|
||||||
ULONG ProtectionMask;
|
ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
|
||||||
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
/* ARM3 does not yet support this */
|
BOOLEAN FileLock = FALSE, KernelCall = FALSE;
|
||||||
ASSERT(FileHandle == NULL);
|
KIRQL OldIrql;
|
||||||
ASSERT(FileObject == NULL);
|
PFILE_OBJECT File;
|
||||||
ASSERT((AllocationAttributes & SEC_LARGE_PAGES) == 0);
|
PVOID PreviousSectionPointer;
|
||||||
|
|
||||||
/* Make the same sanity checks that the Nt interface should've validated */
|
/* Make the same sanity checks that the Nt interface should've validated */
|
||||||
ASSERT((AllocationAttributes & ~(SEC_COMMIT | SEC_RESERVE | SEC_BASED |
|
ASSERT((AllocationAttributes & ~(SEC_COMMIT | SEC_RESERVE | SEC_BASED |
|
||||||
|
@ -2079,53 +2110,229 @@ MmCreateArm3Section(OUT PVOID *SectionObject,
|
||||||
ProtectionMask = MiMakeProtectionMask(SectionPageProtection);
|
ProtectionMask = MiMakeProtectionMask(SectionPageProtection);
|
||||||
if (ProtectionMask == MM_INVALID_PROTECTION) return STATUS_INVALID_PAGE_PROTECTION;
|
if (ProtectionMask == MM_INVALID_PROTECTION) return STATUS_INVALID_PAGE_PROTECTION;
|
||||||
|
|
||||||
/* A handle must be supplied with SEC_IMAGE, and this is the no-handle path */
|
/* Check if this is going to be a data or image backed file section */
|
||||||
|
if ((FileHandle) || (FileObject))
|
||||||
|
{
|
||||||
|
/* These cannot be mapped with large pages */
|
||||||
|
if (AllocationAttributes & SEC_LARGE_PAGES) return STATUS_INVALID_PARAMETER_6;
|
||||||
|
|
||||||
|
/* For now, only support the mechanism through a file handle */
|
||||||
|
ASSERT(FileObject == NULL);
|
||||||
|
|
||||||
|
/* Reference the file handle to get the object */
|
||||||
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
|
MmMakeFileAccess[ProtectionMask],
|
||||||
|
IoFileObjectType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&File,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Make sure Cc has been doing its job */
|
||||||
|
if (!File->SectionObjectPointer)
|
||||||
|
{
|
||||||
|
/* This is not a valid file system-based file, fail */
|
||||||
|
ObDereferenceObject(File);
|
||||||
|
return STATUS_INVALID_FILE_FOR_SECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Image-file backed sections are not yet supported */
|
||||||
|
ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
|
||||||
|
|
||||||
|
/* Compute the size of the control area, and allocate it */
|
||||||
|
ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
|
||||||
|
ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
|
||||||
|
if (!ControlArea)
|
||||||
|
{
|
||||||
|
ObDereferenceObject(File);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero it out */
|
||||||
|
RtlZeroMemory(ControlArea, ControlAreaSize);
|
||||||
|
|
||||||
|
/* Did we get a handle, or an object? */
|
||||||
|
if (FileHandle)
|
||||||
|
{
|
||||||
|
/* We got a file handle so we have to lock down the file */
|
||||||
|
#if 0
|
||||||
|
Status = FsRtlAcquireToCreateMappedSection(File, SectionPageProtection);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePool(ControlArea);
|
||||||
|
ObDereferenceObject(File);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* ReactOS doesn't support this API yet, so do nothing */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
#endif
|
||||||
|
/* Update the top-level IRP so that drivers know what's happening */
|
||||||
|
IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP);
|
||||||
|
FileLock = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock the PFN database while we play with the section pointers */
|
||||||
|
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||||
|
|
||||||
|
/* Image-file backed sections are not yet supported */
|
||||||
|
ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
|
||||||
|
|
||||||
|
/* There should not already be a control area for this file */
|
||||||
|
ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
|
||||||
|
NewSegment = NULL;
|
||||||
|
|
||||||
|
/* Write down that this CA is being created, and set it */
|
||||||
|
ControlArea->u.Flags.BeingCreated = TRUE;
|
||||||
|
PreviousSectionPointer = File->SectionObjectPointer;
|
||||||
|
File->SectionObjectPointer->DataSectionObject = ControlArea;
|
||||||
|
|
||||||
|
/* We can release the PFN lock now */
|
||||||
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
|
||||||
|
|
||||||
|
/* We don't support previously-mapped file */
|
||||||
|
ASSERT(NewSegment == NULL);
|
||||||
|
|
||||||
|
/* Image-file backed sections are not yet supported */
|
||||||
|
ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
|
||||||
|
|
||||||
|
/* So we always create a data file map */
|
||||||
|
Status = MiCreateDataFileMap(File,
|
||||||
|
&Segment,
|
||||||
|
(PSIZE_T)InputMaximumSize,
|
||||||
|
SectionPageProtection,
|
||||||
|
AllocationAttributes,
|
||||||
|
KernelCall);
|
||||||
|
ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
|
||||||
|
ASSERT(NT_SUCCESS(Status));
|
||||||
|
|
||||||
|
/* Check if a maximum size was specified */
|
||||||
|
if (!InputMaximumSize->QuadPart)
|
||||||
|
{
|
||||||
|
/* Nope, use the segment size */
|
||||||
|
Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Yep, use the entered size */
|
||||||
|
Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
|
||||||
if (AllocationAttributes & SEC_IMAGE) return STATUS_INVALID_FILE_FOR_SECTION;
|
if (AllocationAttributes & SEC_IMAGE) return STATUS_INVALID_FILE_FOR_SECTION;
|
||||||
|
|
||||||
|
/* Not yet supported */
|
||||||
|
ASSERT((AllocationAttributes & SEC_LARGE_PAGES) == 0);
|
||||||
|
|
||||||
/* So this must be a pagefile-backed section, create the mappings needed */
|
/* So this must be a pagefile-backed section, create the mappings needed */
|
||||||
Status = MiCreatePagingFileMap(&NewSegment,
|
Status = MiCreatePagingFileMap(&NewSegment,
|
||||||
(PSIZE_T)InputMaximumSize,
|
(PSIZE_T)InputMaximumSize,
|
||||||
ProtectionMask,
|
ProtectionMask,
|
||||||
AllocationAttributes);
|
AllocationAttributes);
|
||||||
ASSERT(NT_SUCCESS(Status));
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
ASSERT(NewSegment != NULL);
|
|
||||||
|
/* Set the size here, and read the control area */
|
||||||
|
Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
|
||||||
|
ControlArea = NewSegment->ControlArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we already have a segment? */
|
||||||
|
if (!NewSegment)
|
||||||
|
{
|
||||||
|
/* This must be the file path and we created a segment */
|
||||||
|
NewSegment = Segment;
|
||||||
|
ASSERT(File != NULL);
|
||||||
|
|
||||||
|
/* Acquire the PFN lock while we set control area flags */
|
||||||
|
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||||
|
|
||||||
|
/* We don't support this race condition yet, so assume no waiters */
|
||||||
|
ASSERT(ControlArea->WaitingForDeletion == NULL);
|
||||||
|
ControlArea->WaitingForDeletion = NULL;
|
||||||
|
|
||||||
|
/* Image-file backed sections are not yet supported, nor ROM images */
|
||||||
|
ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
|
||||||
|
ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
|
||||||
|
|
||||||
|
/* Take off the being created flag, and then release the lock */
|
||||||
|
ControlArea->u.Flags.BeingCreated = FALSE;
|
||||||
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we locked the file earlier */
|
||||||
|
if (FileLock)
|
||||||
|
{
|
||||||
|
/* Reset the top-level IRP and release the lock */
|
||||||
|
IoSetTopLevelIrp(NULL);
|
||||||
|
//FsRtlReleaseFile(File);
|
||||||
|
FileLock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the initial section object data */
|
/* Set the initial section object data */
|
||||||
Section.InitialPageProtection = SectionPageProtection;
|
Section.InitialPageProtection = SectionPageProtection;
|
||||||
Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
|
|
||||||
Section.Segment = NewSegment;
|
|
||||||
|
|
||||||
/* THe mapping created a control area and segment, save the flags */
|
/* The mapping created a control area and segment, save the flags */
|
||||||
ControlArea = NewSegment->ControlArea;
|
Section.Segment = NewSegment;
|
||||||
Section.u.LongFlags = ControlArea->u.LongFlags;
|
Section.u.LongFlags = ControlArea->u.LongFlags;
|
||||||
|
|
||||||
/* ARM3 cannot support these right now, make sure they're not being set */
|
/* Check if this is a user-mode read-write non-image file mapping */
|
||||||
ASSERT(ControlArea->u.Flags.Image == 0);
|
if (!(FileObject) &&
|
||||||
ASSERT(ControlArea->FilePointer == NULL);
|
(SectionPageProtection & (PAGE_READWRITE | PAGE_EXECUTE_READWRITE)) &&
|
||||||
|
(ControlArea->u.Flags.Image == 0) &&
|
||||||
|
(ControlArea->FilePointer != NULL))
|
||||||
|
{
|
||||||
|
/* Add a reference and set the flag */
|
||||||
|
Section.u.Flags.UserWritable = 1;
|
||||||
|
InterlockedIncrement((PLONG)&ControlArea->WritableUserReferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for image mappings or page file mappings */
|
||||||
|
if ((ControlArea->u.Flags.Image == 1) || !(ControlArea->FilePointer))
|
||||||
|
{
|
||||||
|
/* Charge the segment size, and allocate a subsection */
|
||||||
|
PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
|
||||||
|
Size = sizeof(SUBSECTION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Charge nothing, and allocate a mapped subsection */
|
||||||
|
PagedCharge = 0;
|
||||||
|
Size = sizeof(MSUBSECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this is a normal CA */
|
||||||
ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
|
ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
|
||||||
ASSERT(ControlArea->u.Flags.Rom == 0);
|
ASSERT(ControlArea->u.Flags.Rom == 0);
|
||||||
ASSERT(ControlArea->u.Flags.WasPurged == 0);
|
|
||||||
|
|
||||||
/* A pagefile-backed mapping only has one subsection, and this is all ARM3 supports */
|
/* Charge only a CA, and the subsection is right after */
|
||||||
|
NonPagedCharge = sizeof(CONTROL_AREA);
|
||||||
Subsection = (PSUBSECTION)(ControlArea + 1);
|
Subsection = (PSUBSECTION)(ControlArea + 1);
|
||||||
|
|
||||||
|
/* We only support single-subsection mappings */
|
||||||
|
NonPagedCharge += Size;
|
||||||
ASSERT(Subsection->NextSubsection == NULL);
|
ASSERT(Subsection->NextSubsection == NULL);
|
||||||
|
|
||||||
/* Create the actual section object, with enough space for the prototype PTEs */
|
/* Create the actual section object, with enough space for the prototype PTEs */
|
||||||
Status = ObCreateObject(ExGetPreviousMode(),
|
Status = ObCreateObject(PreviousMode,
|
||||||
MmSectionObjectType,
|
MmSectionObjectType,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
ExGetPreviousMode(),
|
PreviousMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(SECTION),
|
sizeof(SECTION),
|
||||||
sizeof(SECTION) +
|
PagedCharge,
|
||||||
NewSegment->TotalNumberOfPtes * sizeof(MMPTE),
|
NonPagedCharge,
|
||||||
sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
|
|
||||||
(PVOID*)&NewSection);
|
(PVOID*)&NewSection);
|
||||||
ASSERT(NT_SUCCESS(Status));
|
ASSERT(NT_SUCCESS(Status));
|
||||||
|
|
||||||
/* Now copy the local section object from the stack into this new object */
|
/* Now copy the local section object from the stack into this new object */
|
||||||
RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
|
RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
|
||||||
NewSection->Address.StartingVpn = 0;
|
NewSection->Address.StartingVpn = 0;
|
||||||
|
|
||||||
|
/* For now, only user calls are supported */
|
||||||
|
ASSERT(KernelCall == FALSE);
|
||||||
NewSection->u.Flags.UserReference = TRUE;
|
NewSection->u.Flags.UserReference = TRUE;
|
||||||
|
|
||||||
/* Migrate the attribute into a flag */
|
/* Migrate the attribute into a flag */
|
||||||
|
@ -2171,6 +2378,13 @@ MmCreateArm3Section(OUT PVOID *SectionObject,
|
||||||
KeReleaseGuardedMutex(&MmSectionBasedMutex);
|
KeReleaseGuardedMutex(&MmSectionBasedMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write down if this was a kernel call */
|
||||||
|
ControlArea->u.Flags.WasPurged |= KernelCall;
|
||||||
|
ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
|
||||||
|
|
||||||
|
/* Make sure the segment and the section are the same size, or the section is smaller */
|
||||||
|
ASSERT(NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
|
||||||
|
|
||||||
/* Return the object and the creation status */
|
/* Return the object and the creation status */
|
||||||
*SectionObject = (PVOID)NewSection;
|
*SectionObject = (PVOID)NewSection;
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -4860,9 +4860,10 @@ MmCreateSection (OUT PVOID * Section,
|
||||||
PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
|
PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
|
||||||
|
|
||||||
/* Check if an ARM3 section is being created instead */
|
/* Check if an ARM3 section is being created instead */
|
||||||
if (AllocationAttributes & 1)
|
if (!(AllocationAttributes & SEC_IMAGE) && (AllocationAttributes))
|
||||||
|
{
|
||||||
|
if (!(FileObject) && !(FileHandle))
|
||||||
{
|
{
|
||||||
DPRINT1("Creating ARM3 section\n");
|
|
||||||
return MmCreateArm3Section(Section,
|
return MmCreateArm3Section(Section,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
|
@ -4872,6 +4873,7 @@ MmCreateSection (OUT PVOID * Section,
|
||||||
FileHandle,
|
FileHandle,
|
||||||
FileObject);
|
FileObject);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the protection
|
* Check the protection
|
||||||
|
|
Loading…
Reference in a new issue