/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
-#include "../cache/newcc.h"
-#include "../cache/section/newmm.h"
+#include <cache/newcc.h>
+#include <cache/section/newmm.h>
#define NDEBUG
#include <debug.h>
#include <reactos/exeformat.h>
SECTION_ALL_ACCESS
};
-static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
-{
- ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */
- ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionImageInformation */
-};
/* FUNCTIONS *****************************************************************/
SIZE_T nPrevVirtualEndOfSegment = 0;
ULONG nFileSizeOfHeaders = 0;
ULONG i;
+ ULONG AlignedLength;
ASSERT(FileHeader);
ASSERT(FileHeaderSize > 0);
if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
+ /* NT HEADER */
+ nStatus = STATUS_INVALID_IMAGE_PROTECT;
+
/* not a Windows executable */
if(pidhDosHeader->e_lfanew <= 0)
DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
- /* NT HEADER */
- nStatus = STATUS_INVALID_IMAGE_FORMAT;
-
if(!Intsafe_AddULong32(&cbFileHeaderOffsetSize, pidhDosHeader->e_lfanew, RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)))
DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
NTSTATUS ReturnedStatus = nStatus;
/* If it attempted to read past the end of the file, it means e_lfanew is invalid */
- if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
+ if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_INVALID_IMAGE_PROTECT;
DIE(("ReadFile failed, status %08X\n", ReturnedStatus));
}
{
ULONG cbOptHeaderOffsetSize = 0;
- nStatus = STATUS_INVALID_IMAGE_FORMAT;
+ nStatus = STATUS_INVALID_IMAGE_PROTECT;
/* don't trust an invalid NT header */
if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
+ nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
switch(piohOptHeader->Magic)
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+#ifdef _WIN64
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+#endif // _WIN64
break;
default:
else
pssSegments[i].Length.QuadPart = pishSectionHeaders[i].Misc.VirtualSize;
- pssSegments[i].Length.LowPart = ALIGN_UP_BY(pssSegments[i].Length.LowPart, nSectionAlignment);
- /* FIXME: always false */
- if (pssSegments[i].Length.QuadPart < pssSegments[i].Length.QuadPart)
+ AlignedLength = ALIGN_UP_BY(pssSegments[i].Length.LowPart, nSectionAlignment);
+ if(AlignedLength < pssSegments[i].Length.LowPart)
DIE(("Cannot align the virtual size of section %u\n", i));
+ pssSegments[i].Length.LowPart = AlignedLength;
+
if(pssSegments[i].Length.QuadPart == 0)
DIE(("Virtual size of section %u is null\n", i));
if (SHARE_COUNT_FROM_SSE(Entry) == 0)
{
PFILE_OBJECT FileObject;
-#ifndef NEWCC
- PROS_SHARED_CACHE_MAP SharedCacheMap;
-#endif
SWAPENTRY SavedSwapEntry;
PFN_NUMBER Page;
+#ifndef NEWCC
+ PROS_SHARED_CACHE_MAP SharedCacheMap;
BOOLEAN IsImageSection;
LARGE_INTEGER FileOffset;
FileOffset.QuadPart = Offset->QuadPart + Segment->Image.FileOffset;
-
IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
+#endif
Page = PFN_FROM_SSE(Entry);
FileObject = Section->FileObject;
}
PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
- Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+ Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
+ MemoryArea->Data.SectionData.ViewOffset.QuadPart;
Segment = MemoryArea->Data.SectionData.Segment;
Section = MemoryArea->Data.SectionData.Section;
- Region = MmFindRegion(MemoryArea->StartingAddress,
+ Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
&MemoryArea->Data.SectionData.RegionListHead,
Address, NULL);
ASSERT(Region != NULL);
* Check if someone else is already handling this fault, if so wait
* for them
*/
- if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
+ if (Entry && MM_IS_WAIT_PTE(Entry))
{
MmUnlockSectionSegment(Segment);
MmUnlockAddressSpace(AddressSpace);
HasSwapEntry = MmIsPageSwapEntry(Process, Address);
- if (HasSwapEntry)
+ /* See if we should use a private page */
+ if ((HasSwapEntry) || (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA))
{
SWAPENTRY DummyEntry;
/*
* Is it a wait entry?
*/
- MmGetPageFileMapping(Process, Address, &SwapEntry);
-
- if (SwapEntry == MM_WAIT_ENTRY)
+ if (HasSwapEntry)
{
- MmUnlockSectionSegment(Segment);
- MmUnlockAddressSpace(AddressSpace);
- MiWaitForPageEvent(NULL, NULL);
- MmLockAddressSpace(AddressSpace);
- return STATUS_MM_RESTART_OPERATION;
- }
+ MmGetPageFileMapping(Process, Address, &SwapEntry);
- /*
- * Must be private page we have swapped out.
- */
+ if (SwapEntry == MM_WAIT_ENTRY)
+ {
+ MmUnlockSectionSegment(Segment);
+ MmUnlockAddressSpace(AddressSpace);
+ MiWaitForPageEvent(NULL, NULL);
+ MmLockAddressSpace(AddressSpace);
+ return STATUS_MM_RESTART_OPERATION;
+ }
- /*
- * Sanity check
- */
- if (Segment->Flags & MM_PAGEFILE_SEGMENT)
- {
- DPRINT1("Found a swaped out private page in a pagefile section.\n");
- KeBugCheck(MEMORY_MANAGEMENT);
+ /*
+ * Must be private page we have swapped out.
+ */
+
+ /*
+ * Sanity check
+ */
+ if (Segment->Flags & MM_PAGEFILE_SEGMENT)
+ {
+ DPRINT1("Found a swaped out private page in a pagefile section.\n");
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+ MmDeletePageFileMapping(Process, Address, &SwapEntry);
}
MmUnlockSectionSegment(Segment);
- MmDeletePageFileMapping(Process, Address, &SwapEntry);
+
+ /* Tell everyone else we are serving the fault. */
MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
MmUnlockAddressSpace(AddressSpace);
KeBugCheck(MEMORY_MANAGEMENT);
}
- Status = MmReadFromSwapPage(SwapEntry, Page);
- if (!NT_SUCCESS(Status))
+ if (HasSwapEntry)
{
- DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
- KeBugCheck(MEMORY_MANAGEMENT);
+ Status = MmReadFromSwapPage(SwapEntry, Page);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
}
+
MmLockAddressSpace(AddressSpace);
MmDeletePageFileMapping(Process, PAddress, &DummyEntry);
Status = MmCreateVirtualMapping(Process,
/*
* Store the swap entry for later use.
*/
- MmSetSavedSwapEntryPage(Page, SwapEntry);
+ if (HasSwapEntry)
+ MmSetSavedSwapEntryPage(Page, SwapEntry);
/*
* Add the page to the process's working set
return(Status);
}
- /*
- * Mark the offset within the section as having valid, in-memory
- * data
- */
+ /* Lock both segment and process address space while we proceed. */
MmLockAddressSpace(AddressSpace);
MmLockSectionSegment(Segment);
- Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
- MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
- MmUnlockSectionSegment(Segment);
MmDeletePageFileMapping(Process, PAddress, &FakeSwapEntry);
DPRINT("CreateVirtualMapping Page %x Process %p PAddress %p Attributes %x\n",
ASSERT(MmIsPagePresent(Process, PAddress));
MmInsertRmap(Page, Process, Address);
+ /* Set this section offset has being backed by our new page. */
+ Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
+ MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
+ MmUnlockSectionSegment(Segment);
+
MiSetPageEvent(Process, Address);
DPRINT("Address 0x%p\n", Address);
return(STATUS_SUCCESS);
SwapEntry = SWAPENTRY_FROM_SSE(Entry);
+ /* See if a page op is running on this segment. */
+ if (SwapEntry == MM_WAIT_ENTRY)
+ {
+ MmUnlockSectionSegment(Segment);
+ MmUnlockAddressSpace(AddressSpace);
+ MiWaitForPageEvent(NULL, NULL);
+ MmLockAddressSpace(AddressSpace);
+ return STATUS_MM_RESTART_OPERATION;
+ }
+
/*
* Release all our locks and read in the page from disk
*/
KeBugCheck(MEMORY_MANAGEMENT);
}
- /*
- * Mark the offset within the section as having valid, in-memory
- * data
- */
- Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
- MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
- MmUnlockSectionSegment(Segment);
-
/*
* Save the swap entry.
*/
MmSetSavedSwapEntryPage(Page, SwapEntry);
+
+ /* Map the page into the process address space */
Status = MmCreateVirtualMapping(Process,
PAddress,
Region->Protect,
KeBugCheck(MEMORY_MANAGEMENT);
}
MmInsertRmap(Page, Process, Address);
+
+ /*
+ * Mark the offset within the section as having valid, in-memory
+ * data
+ */
+ Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
+ MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
+ MmUnlockSectionSegment(Segment);
+
MiSetPageEvent(Process, Address);
DPRINT("Address 0x%p\n", Address);
return(STATUS_SUCCESS);
}
else
{
- /*
- * If the section offset is already in-memory and valid then just
- * take another reference to the page
- */
-
+ /* We already have a page on this section offset. Map it into the process address space. */
Page = PFN_FROM_SSE(Entry);
- MmSharePageEntrySectionSegment(Segment, &Offset);
- MmUnlockSectionSegment(Segment);
-
Status = MmCreateVirtualMapping(Process,
PAddress,
Attributes,
KeBugCheck(MEMORY_MANAGEMENT);
}
MmInsertRmap(Page, Process, Address);
+
+ /* Take a reference on it */
+ MmSharePageEntrySectionSegment(Segment, &Offset);
+ MmUnlockSectionSegment(Segment);
+
MiSetPageEvent(Process, Address);
DPRINT("Address 0x%p\n", Address);
return(STATUS_SUCCESS);
PMM_REGION Region;
ULONG_PTR Entry;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
- SWAPENTRY SwapEntry;
DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
+ /* Make sure we have a page mapping for this address. */
+ Status = MmNotPresentFaultSectionView(AddressSpace, MemoryArea, Address, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* This is invalid access ! */
+ return Status;
+ }
+
/*
* Check if the page has already been set readwrite
*/
* Find the offset of the page
*/
PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
- Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+ Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
+ MemoryArea->Data.SectionData.ViewOffset.QuadPart;
Segment = MemoryArea->Data.SectionData.Segment;
Section = MemoryArea->Data.SectionData.Section;
- Region = MmFindRegion(MemoryArea->StartingAddress,
+ Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
&MemoryArea->Data.SectionData.RegionListHead,
Address, NULL);
ASSERT(Region != NULL);
- /*
- * Lock the segment
- */
- MmLockSectionSegment(Segment);
-
- OldPage = MmGetPfnForProcess(Process, Address);
- Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-
- MmUnlockSectionSegment(Segment);
/*
* Check if we are doing COW
return(STATUS_ACCESS_VIOLATION);
}
- if (IS_SWAP_FROM_SSE(Entry) ||
- PFN_FROM_SSE(Entry) != OldPage)
- {
- /* This is a private page. We must only change the page protection. */
- MmSetPageProtect(Process, Address, Region->Protect);
- return(STATUS_SUCCESS);
- }
-
- if(OldPage == 0)
- DPRINT("OldPage == 0!\n");
-
- /*
- * Get or create a pageop
- */
+ /* Get the page mapping this section offset. */
MmLockSectionSegment(Segment);
Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
- /*
- * Wait for any other operations to complete
- */
- if (Entry == SWAPENTRY_FROM_SSE(MM_WAIT_ENTRY))
+ /* Get the current page mapping for the process */
+ ASSERT(MmIsPagePresent(Process, PAddress));
+ OldPage = MmGetPfnForProcess(Process, PAddress);
+ ASSERT(OldPage != 0);
+
+ if (IS_SWAP_FROM_SSE(Entry) ||
+ PFN_FROM_SSE(Entry) != OldPage)
{
MmUnlockSectionSegment(Segment);
- MmUnlockAddressSpace(AddressSpace);
- MiWaitForPageEvent(NULL, NULL);
- /*
- * Restart the operation
- */
- MmLockAddressSpace(AddressSpace);
- DPRINT("Address 0x%p\n", Address);
- return(STATUS_MM_RESTART_OPERATION);
+ /* This is a private page. We must only change the page protection. */
+ MmSetPageProtect(Process, PAddress, Region->Protect);
+ return(STATUS_SUCCESS);
}
- MmDeleteRmap(OldPage, Process, PAddress);
- MmDeleteVirtualMapping(Process, PAddress, NULL, NULL);
- MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY);
-
- /*
- * Release locks now we have the pageop
- */
- MmUnlockSectionSegment(Segment);
- MmUnlockAddressSpace(AddressSpace);
-
/*
* Allocate a page
*/
*/
MiCopyFromUserPage(NewPage, OldPage);
- MmLockAddressSpace(AddressSpace);
+ /*
+ * Unshare the old page.
+ */
+ DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
+ MmDeleteVirtualMapping(Process, PAddress, NULL, NULL);
+ MmDeleteRmap(OldPage, Process, PAddress);
+ MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL);
+ MmUnlockSectionSegment(Segment);
/*
* Set the PTE to point to the new page
*/
- MmDeletePageFileMapping(Process, PAddress, &SwapEntry);
Status = MmCreateVirtualMapping(Process,
PAddress,
Region->Protect,
KeBugCheck(MEMORY_MANAGEMENT);
return(Status);
}
-
- /*
- * Unshare the old page.
- */
- DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
MmInsertRmap(NewPage, Process, PAddress);
- MmLockSectionSegment(Segment);
- MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL);
- MmUnlockSectionSegment(Segment);
MiSetPageEvent(Process, Address);
DPRINT("Address 0x%p\n", Address);
PFN_NUMBER Page;
MM_SECTION_PAGEOUT_CONTEXT Context;
SWAPENTRY SwapEntry;
- ULONGLONG FileOffset;
NTSTATUS Status;
- PFILE_OBJECT FileObject;
#ifndef NEWCC
+ ULONGLONG FileOffset;
+ PFILE_OBJECT FileObject;
PROS_SHARED_CACHE_MAP SharedCacheMap = NULL;
+ BOOLEAN IsImageSection;
#endif
BOOLEAN DirectMapped;
- BOOLEAN IsImageSection;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
KIRQL OldIrql;
Context.SectionEntry = Entry;
Context.CallingProcess = Process;
- Context.Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ Context.Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
+ MemoryArea->Data.SectionData.ViewOffset.QuadPart;
- FileOffset = Context.Offset.QuadPart + Context.Segment->Image.FileOffset;
- IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
-
- FileObject = Context.Section->FileObject;
DirectMapped = FALSE;
MmLockSectionSegment(Context.Segment);
#ifndef NEWCC
+ FileOffset = Context.Offset.QuadPart + Context.Segment->Image.FileOffset;
+ IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
+ FileObject = Context.Section->FileObject;
+
if (FileObject != NULL &&
!(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
{
}
else
{
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ OldIrql = MiAcquirePfnLock();
MmReferencePage(Page);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiReleasePfnLock(OldIrql);
}
MmDeleteAllRmaps(Page, (PVOID)&Context, MmPageOutDeleteMapping);
else
{
ULONG_PTR OldEntry;
+
+ MmLockSectionSegment(Context.Segment);
+
/*
* For non-private pages if the page wasn't direct mapped then
* set it back into the section segment entry so we don't loose
Address);
// If we got here, the previous entry should have been a wait
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
- MmLockSectionSegment(Context.Segment);
OldEntry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset);
ASSERT(OldEntry == 0 || OldEntry == MAKE_SWAP_SSE(MM_WAIT_ENTRY));
MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
}
else
{
+ MmLockSectionSegment(Context.Segment);
Status = MmCreateVirtualMapping(Process,
Address,
MemoryArea->Protect,
Address);
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
+ MmUnlockSectionSegment(Context.Segment);
}
MmUnlockAddressSpace(AddressSpace);
MiSetPageEvent(NULL, NULL);
BOOLEAN Private;
NTSTATUS Status;
PFILE_OBJECT FileObject;
+#ifndef NEWCC
PROS_SHARED_CACHE_MAP SharedCacheMap = NULL;
+#endif
BOOLEAN DirectMapped;
BOOLEAN IsImageSection;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
Address = (PVOID)PAGE_ROUND_DOWN(Address);
- Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
+ MemoryArea->Data.SectionData.ViewOffset.QuadPart;
/*
if (FileObject != NULL &&
!(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
{
+#ifndef NEWCC
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
+#endif
/*
* If the file system is letting us go directly to the cache and the
ASSERT(SwapEntry == 0);
//SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset;
#ifndef NEWCC
- CcRosMarkDirtyVacb(SharedCacheMap, Offset.QuadPart);
+ CcRosMarkDirtyFile(SharedCacheMap, Offset.QuadPart);
#endif
MmLockSectionSegment(Segment);
MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry);
ULONG_PTR Entry;
PFN_NUMBER Page;
- Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
+ MemoryArea->Data.SectionData.ViewOffset.QuadPart;
Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
/*
NTSTATUS Status;
ULONG_PTR MaxLength;
- MaxLength = (ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)BaseAddress;
+ MaxLength = MA_GetEndingAddress(MemoryArea) - (ULONG_PTR)BaseAddress;
if (Length > MaxLength)
Length = (ULONG)MaxLength;
- Region = MmFindRegion(MemoryArea->StartingAddress,
+ Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
&MemoryArea->Data.SectionData.RegionListHead,
BaseAddress, NULL);
ASSERT(Region != NULL);
}
*OldProtect = Region->Protect;
- Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress,
+ Status = MmAlterRegion(AddressSpace, (PVOID)MA_GetStartingAddress(MemoryArea),
&MemoryArea->Data.SectionData.RegionListHead,
BaseAddress, Length, Region->Type, Protect,
MmAlterViewAttributes);
PROS_SECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment;
- Region = MmFindRegion((PVOID)MemoryArea->StartingAddress,
+ Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
&MemoryArea->Data.SectionData.RegionListHead,
Address, &RegionBaseAddress);
if (Region == NULL)
if (Section->AllocationAttributes & SEC_IMAGE)
{
Segment = MemoryArea->Data.SectionData.Segment;
- Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->Image.VirtualAddress;
+ Info->AllocationBase = (PUCHAR)MA_GetStartingAddress(MemoryArea) - Segment->Image.VirtualAddress;
Info->Type = MEM_IMAGE;
}
else
{
- Info->AllocationBase = MemoryArea->StartingAddress;
+ Info->AllocationBase = (PVOID)MA_GetStartingAddress(MemoryArea);
Info->Type = MEM_MAPPED;
}
Info->BaseAddress = RegionBaseAddress;
SectionSize.QuadPart = 0xFFFFFFFF;
InitializeObjectAttributes(&Obj,
&Name,
- OBJ_PERMANENT,
+ OBJ_PERMANENT | OBJ_KERNEL_EXCLUSIVE,
NULL,
NULL);
Status = MmCreateSection((PVOID)&PhysSection,
PLARGE_INTEGER UMaximumSize,
ULONG SectionPageProtection,
ULONG AllocationAttributes,
- HANDLE FileHandle)
+ PFILE_OBJECT FileObject)
/*
* Create a section backed by a data file
*/
PROS_SECTION_OBJECT Section;
NTSTATUS Status;
LARGE_INTEGER MaximumSize;
- PFILE_OBJECT FileObject;
PMM_SECTION_SEGMENT Segment;
- ULONG FileAccess;
- IO_STATUS_BLOCK Iosb;
- LARGE_INTEGER Offset;
- CHAR Buffer;
FILE_STANDARD_INFORMATION FileInfo;
ULONG Length;
(PVOID*)&Section);
if (!NT_SUCCESS(Status))
{
+ ObDereferenceObject(FileObject);
return(Status);
}
/*
Section->SectionPageProtection = SectionPageProtection;
Section->AllocationAttributes = AllocationAttributes;
- /*
- * Reference the file handle
- */
- FileAccess = MiArm3GetCorrectFileAccessMask(SectionPageProtection);
- Status = ObReferenceObjectByHandle(FileHandle,
- FileAccess,
- IoFileObjectType,
- ExGetPreviousMode(),
- (PVOID*)(PVOID)&FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(Section);
- return(Status);
- }
-
/*
* FIXME: This is propably not entirely correct. We can't look into
* the standard FCB header because it might not be initialized yet
sizeof(FILE_STANDARD_INFORMATION),
&FileInfo,
&Length);
- Iosb.Information = Length;
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Section);
{
ObDereferenceObject(Section);
ObDereferenceObject(FileObject);
- return STATUS_FILE_INVALID;
+ return STATUS_MAPPED_FILE_SIZE_ZERO;
}
}
if (MaximumSize.QuadPart > FileInfo.EndOfFile.QuadPart)
{
Status = IoSetInformation(FileObject,
- FileAllocationInformation,
+ FileEndOfFileInformation,
sizeof(LARGE_INTEGER),
&MaximumSize);
if (!NT_SUCCESS(Status))
if (FileObject->SectionObjectPointer == NULL ||
FileObject->SectionObjectPointer->SharedCacheMap == NULL)
{
- /*
- * Read a bit so caching is initiated for the file object.
- * This is only needed because MiReadPage currently cannot
- * handle non-cached streams.
- */
- Offset.QuadPart = 0;
- Status = ZwReadFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- &Buffer,
- sizeof (Buffer),
- &Offset,
- 0);
- if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
- {
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- return(Status);
- }
- if (FileObject->SectionObjectPointer == NULL ||
- FileObject->SectionObjectPointer->SharedCacheMap == NULL)
- {
- /* FIXME: handle this situation */
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- return STATUS_INVALID_PARAMETER;
- }
+ ObDereferenceObject(Section);
+ ObDereferenceObject(FileObject);
+ return STATUS_INVALID_FILE_FOR_SECTION;
}
/*
IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
);
-/* TODO: this is a standard DDK/PSDK macro */
-#ifndef RTL_NUMBER_OF
-#define RTL_NUMBER_OF(ARR_) (sizeof(ARR_) / sizeof((ARR_)[0]))
-#endif
-
static PEXEFMT_LOADER ExeFmtpLoaders[] =
{
PeFmtCreateSection,
BufferSize = Length + OffsetAdjustment;
BufferSize = PAGE_ROUND_UP(BufferSize);
+ /* Flush data since we're about to perform a non-cached read */
+ CcFlushCache(FileObject->SectionObjectPointer,
+ &FileOffset,
+ BufferSize,
+ &Iosb);
+
/*
* It's ok to use paged pool, because this is a temporary buffer only used in
* the loading of executables. The assumption is that MmCreateSection is
'rXmM');
if (!Buffer)
{
- KeBugCheck(MEMORY_MANAGEMENT);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
UsedSize = 0;
}
NTSTATUS
-ExeFmtpCreateImageSection(HANDLE FileHandle,
+ExeFmtpCreateImageSection(PFILE_OBJECT FileObject,
PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
{
LARGE_INTEGER Offset;
*/
Offset.QuadPart = 0;
- /* FIXME: use FileObject instead of FileHandle */
- Status = ExeFmtpReadFile (FileHandle,
+ Status = ExeFmtpReadFile (FileObject,
&Offset,
PAGE_SIZE * 2,
&FileHeader,
RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject));
Flags = 0;
- /* FIXME: use FileObject instead of FileHandle */
Status = ExeFmtpLoaders[i](FileHeader,
FileHeaderSize,
- FileHandle,
+ FileObject,
ImageSectionObject,
&Flags,
ExeFmtpReadFile,
if (FileObject == NULL)
return STATUS_INVALID_FILE_FOR_SECTION;
+#ifndef NEWCC
+ if (FileObject->SectionObjectPointer->SharedCacheMap == NULL)
+ {
+ DPRINT1("Denying section creation due to missing cache initialization\n");
+ return STATUS_INVALID_FILE_FOR_SECTION;
+ }
+#endif
+
/*
* Create the section
*/
if(ImageSectionObject->Segments != NULL)
ExFreePool(ImageSectionObject->Segments);
+ /*
+ * If image file is empty, then return that the file is invalid for section
+ */
+ Status = StatusExeFmt;
+ if (StatusExeFmt == STATUS_END_OF_FILE)
+ {
+ Status = STATUS_INVALID_FILE_FOR_SECTION;
+ }
+
ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
ObDereferenceObject(Section);
ObDereferenceObject(FileObject);
- return(StatusExeFmt);
+ return(Status);
}
Section->ImageSection = ImageSectionObject;
ViewSize,
Protect,
&MArea,
- FALSE,
AllocationType,
Granularity);
if (!NT_SUCCESS(Status))
MArea->Data.SectionData.Segment = Segment;
MArea->Data.SectionData.Section = Section;
MArea->Data.SectionData.ViewOffset.QuadPart = ViewOffset;
+ if (Section->AllocationAttributes & SEC_IMAGE)
+ {
+ MArea->VadNode.u.VadFlags.VadType = VadImageMap;
+ }
+
MmInitializeRegion(&MArea->Data.SectionData.RegionListHead,
ViewSize, 0, Protect);
PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
{
ULONG_PTR Entry;
+#ifndef NEWCC
PFILE_OBJECT FileObject;
PROS_SHARED_CACHE_MAP SharedCacheMap;
+#endif
LARGE_INTEGER Offset;
SWAPENTRY SavedSwapEntry;
PROS_SECTION_OBJECT Section;
Address = (PVOID)PAGE_ROUND_DOWN(Address);
- Offset.QuadPart = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
+ Offset.QuadPart = ((ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)) +
MemoryArea->Data.SectionData.ViewOffset.QuadPart;
Section = MemoryArea->Data.SectionData.Section;
Segment = MemoryArea->Data.SectionData.Segment;
Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
- while (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
+ while (Entry && MM_IS_WAIT_PTE(Entry))
{
MmUnlockSectionSegment(Segment);
MmUnlockAddressSpace(AddressSpace);
{
if (Page == PFN_FROM_SSE(Entry) && Dirty)
{
+#ifndef NEWCC
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
-#ifndef NEWCC
- CcRosMarkDirtyVacb(SharedCacheMap, Offset.QuadPart + Segment->Image.FileOffset);
+ CcRosMarkDirtyFile(SharedCacheMap, Offset.QuadPart + Segment->Image.FileOffset);
#endif
ASSERT(SwapEntry == 0);
}
NTAPI
MiRosUnmapViewOfSection(IN PEPROCESS Process,
IN PVOID BaseAddress,
- IN ULONG Flags)
+ IN BOOLEAN SkipDebuggerNotify)
{
NTSTATUS Status;
PMEMORY_AREA MemoryArea;
(MemoryArea->Type != MEMORY_AREA_CACHE)) ||
MemoryArea->DeleteInProgress)
{
- if (MemoryArea) NT_ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
+ if (MemoryArea) ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
MmUnlockAddressSpace(AddressSpace);
return STATUS_NOT_MAPPED_VIEW;
}
* and calculate the image base address */
for (i = 0; i < NrSegments; i++)
{
- if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+ if (Segment == &SectionSegments[i])
{
- if (Segment == &SectionSegments[i])
- {
- ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
- break;
- }
+ ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
+ break;
}
}
if (i >= NrSegments)
for (i = 0; i < NrSegments; i++)
{
- if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
- {
- PVOID SBaseAddress = (PVOID)
- ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
+ PVOID SBaseAddress = (PVOID)
+ ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
- Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
- NT_ASSERT(NT_SUCCESS(Status));
+ Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
+ SBaseAddress, Process, Status);
+ ASSERT(NT_SUCCESS(Status));
}
}
}
else
{
Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
- NT_ASSERT(NT_SUCCESS(Status));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
+ BaseAddress, Process, Status);
+ ASSERT(NT_SUCCESS(Status));
+ }
}
MmUnlockAddressSpace(AddressSpace);
/* Notify debugger */
- if (ImageBaseAddress) DbgkUnMapViewOfSection(ImageBaseAddress);
+ if (ImageBaseAddress && !SkipDebuggerNotify) DbgkUnMapViewOfSection(ImageBaseAddress);
return(STATUS_SUCCESS);
}
*
* @implemented
*/
-NTSTATUS NTAPI
-NtQuerySection(IN HANDLE SectionHandle,
- IN SECTION_INFORMATION_CLASS SectionInformationClass,
- OUT PVOID SectionInformation,
- IN SIZE_T SectionInformationLength,
- OUT PSIZE_T ResultLength OPTIONAL)
+NTSTATUS
+NTAPI
+NtQuerySection(
+ _In_ HANDLE SectionHandle,
+ _In_ SECTION_INFORMATION_CLASS SectionInformationClass,
+ _Out_ PVOID SectionInformation,
+ _In_ SIZE_T SectionInformationLength,
+ _Out_opt_ PSIZE_T ResultLength)
{
- PROS_SECTION_OBJECT Section;
+ PSECTION Section;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(SectionInformation,
+ SectionInformationLength,
+ __alignof(ULONG));
+ if (ResultLength != NULL)
+ {
+ ProbeForWrite(ResultLength,
+ sizeof(*ResultLength),
+ __alignof(SIZE_T));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
- Status = DefaultQueryInfoBufferCheck(SectionInformationClass,
- ExSectionInfoClass,
- sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]),
- SectionInformation,
- (ULONG)SectionInformationLength,
- NULL,
- ResultLength,
- PreviousMode);
-
- if(!NT_SUCCESS(Status))
+ if (SectionInformationClass == SectionBasicInformation)
{
- DPRINT1("NtQuerySection() failed, Status: 0x%x\n", Status);
- return Status;
+ if (SectionInformationLength < sizeof(SECTION_BASIC_INFORMATION))
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+ }
+ else if (SectionInformationClass == SectionImageInformation)
+ {
+ if (SectionInformationLength < sizeof(SECTION_IMAGE_INFORMATION))
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+ }
+ else
+ {
+ return STATUS_INVALID_INFO_CLASS;
}
Status = ObReferenceObjectByHandle(SectionHandle,
PreviousMode,
(PVOID*)(PVOID)&Section,
NULL);
- if (NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference section: 0x%lx\n", Status);
+ return Status;
+ }
+
+ if (MiIsRosSectionObject(Section))
{
+ PROS_SECTION_OBJECT RosSection = (PROS_SECTION_OBJECT)Section;
+
switch (SectionInformationClass)
{
- case SectionBasicInformation:
- {
- PSECTION_BASIC_INFORMATION Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation;
-
- _SEH2_TRY
+ case SectionBasicInformation:
{
- Sbi->Attributes = Section->AllocationAttributes;
- if (Section->AllocationAttributes & SEC_IMAGE)
+ PSECTION_BASIC_INFORMATION Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation;
+
+ _SEH2_TRY
{
- Sbi->BaseAddress = 0;
- Sbi->Size.QuadPart = 0;
+ Sbi->Attributes = RosSection->AllocationAttributes;
+ if (RosSection->AllocationAttributes & SEC_IMAGE)
+ {
+ Sbi->BaseAddress = 0;
+ Sbi->Size.QuadPart = 0;
+ }
+ else
+ {
+ Sbi->BaseAddress = (PVOID)RosSection->Segment->Image.VirtualAddress;
+ Sbi->Size.QuadPart = RosSection->Segment->Length.QuadPart;
+ }
+
+ if (ResultLength != NULL)
+ {
+ *ResultLength = sizeof(SECTION_BASIC_INFORMATION);
+ }
+ Status = STATUS_SUCCESS;
}
- else
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Sbi->BaseAddress = (PVOID)Section->Segment->Image.VirtualAddress;
- Sbi->Size.QuadPart = Section->Segment->Length.QuadPart;
+ Status = _SEH2_GetExceptionCode();
}
+ _SEH2_END;
- if (ResultLength != NULL)
- {
- *ResultLength = sizeof(SECTION_BASIC_INFORMATION);
- }
- Status = STATUS_SUCCESS;
+ break;
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+
+ case SectionImageInformation:
{
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
+ PSECTION_IMAGE_INFORMATION Sii = (PSECTION_IMAGE_INFORMATION)SectionInformation;
- break;
- }
+ _SEH2_TRY
+ {
+ if (RosSection->AllocationAttributes & SEC_IMAGE)
+ {
+ PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
+ ImageSectionObject = RosSection->ImageSection;
- case SectionImageInformation:
- {
- PSECTION_IMAGE_INFORMATION Sii = (PSECTION_IMAGE_INFORMATION)SectionInformation;
+ *Sii = ImageSectionObject->ImageInformation;
+ }
- _SEH2_TRY
- {
- if (Section->AllocationAttributes & SEC_IMAGE)
+ if (ResultLength != NULL)
+ {
+ *ResultLength = sizeof(SECTION_IMAGE_INFORMATION);
+ }
+ Status = STATUS_SUCCESS;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
- ImageSectionObject = Section->ImageSection;
-
- *Sii = ImageSectionObject->ImageInformation;
+ Status = _SEH2_GetExceptionCode();
}
+ _SEH2_END;
- if (ResultLength != NULL)
+ break;
+ }
+ }
+ }
+ else
+ {
+ switch(SectionInformationClass)
+ {
+ case SectionBasicInformation:
+ {
+ SECTION_BASIC_INFORMATION Sbi;
+
+ Sbi.Size = Section->SizeOfSection;
+ Sbi.BaseAddress = (PVOID)Section->Address.StartingVpn;
+
+ Sbi.Attributes = 0;
+ if (Section->u.Flags.Image)
+ Sbi.Attributes |= SEC_IMAGE;
+ if (Section->u.Flags.Commit)
+ Sbi.Attributes |= SEC_COMMIT;
+ if (Section->u.Flags.Reserve)
+ Sbi.Attributes |= SEC_RESERVE;
+ if (Section->u.Flags.File)
+ Sbi.Attributes |= SEC_FILE;
+ if (Section->u.Flags.Image)
+ Sbi.Attributes |= SEC_IMAGE;
+
+ /* FIXME : Complete/test the list of flags passed back from NtCreateSection */
+
+ _SEH2_TRY
{
- *ResultLength = sizeof(SECTION_IMAGE_INFORMATION);
+ *((SECTION_BASIC_INFORMATION*)SectionInformation) = Sbi;
+ if (ResultLength)
+ *ResultLength = sizeof(Sbi);
}
- Status = STATUS_SUCCESS;
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ break;
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ case SectionImageInformation:
{
- Status = _SEH2_GetExceptionCode();
+ if (!Section->u.Flags.Image)
+ {
+ Status = STATUS_SECTION_NOT_IMAGE;
+ }
+ else
+ {
+ /* Currently not supported */
+ ASSERT(FALSE);
+ }
+ break;
}
- _SEH2_END;
-
- break;
- }
}
-
- ObDereferenceObject(Section);
}
+ ObDereferenceObject(Section);
+
return(Status);
}
return STATUS_INVALID_PAGE_PROTECTION;
}
+ /* FIXME: We should keep this, but it would break code checking equality */
+ Protect &= ~PAGE_NOCACHE;
Section = (PROS_SECTION_OBJECT)SectionObject;
AddressSpace = &Process->Vm;
ImageSize = 0;
for (i = 0; i < NrSegments; i++)
{
- if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
- {
- ULONG_PTR MaxExtent;
- MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
- SectionSegments[i].Length.QuadPart);
- ImageSize = max(ImageSize, MaxExtent);
- }
+ ULONG_PTR MaxExtent;
+ MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
+ SectionSegments[i].Length.QuadPart);
+ ImageSize = max(ImageSize, MaxExtent);
}
ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize;
if (((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress) ||
((ImageBase + ImageSize) < ImageSize))
{
- NT_ASSERT(*BaseAddress == NULL);
+ ASSERT(*BaseAddress == NULL);
ImageBase = ALIGN_DOWN_BY((ULONG_PTR)MmHighestUserAddress - ImageSize,
MM_VIRTMEM_GRANULARITY);
NotAtBase = TRUE;
}
else if (ImageBase != ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY))
{
- NT_ASSERT(*BaseAddress == NULL);
+ ASSERT(*BaseAddress == NULL);
ImageBase = ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY);
NotAtBase = TRUE;
}
for (i = 0; i < NrSegments; i++)
{
- if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+ PVOID SBaseAddress = (PVOID)
+ ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
+ MmLockSectionSegment(&SectionSegments[i]);
+ Status = MmMapViewOfSegment(AddressSpace,
+ Section,
+ &SectionSegments[i],
+ &SBaseAddress,
+ SectionSegments[i].Length.LowPart,
+ SectionSegments[i].Protection,
+ 0,
+ 0);
+ MmUnlockSectionSegment(&SectionSegments[i]);
+ if (!NT_SUCCESS(Status))
{
- PVOID SBaseAddress = (PVOID)
- ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
- MmLockSectionSegment(&SectionSegments[i]);
- Status = MmMapViewOfSegment(AddressSpace,
- Section,
- &SectionSegments[i],
- &SBaseAddress,
- SectionSegments[i].Length.LowPart,
- SectionSegments[i].Protection,
- 0,
- 0);
- MmUnlockSectionSegment(&SectionSegments[i]);
- if (!NT_SUCCESS(Status))
- {
- MmUnlockAddressSpace(AddressSpace);
- return(Status);
- }
+ MmUnlockAddressSpace(AddressSpace);
+ return(Status);
}
}
return STATUS_SECTION_PROTECTION;
}
- if (ViewSize == NULL)
- {
- /* Following this pointer would lead to us to the dark side */
- /* What to do? Bugcheck? Return status? Do the mambo? */
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
if (SectionOffset == NULL)
{
ViewOffset = 0;
}
MmUnlockAddressSpace(AddressSpace);
- NT_ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
+ ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
if (NotAtBase)
Status = STATUS_IMAGE_NOT_AT_BASE;
if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
{
DPRINT1("CC failure: %lx\n", Status);
+ if (FileObject)
+ ObDereferenceObject(FileObject);
return Status;
}
// Caching is initialized...
+
+ // Hack of the hack: actually, it might not be initialized if FSD init on effective right and if file is null-size
+ // In such case, force cache by initiating a write IRP
+ if (Status == STATUS_END_OF_FILE && !(AllocationAttributes & SEC_IMAGE) && FileObject != NULL &&
+ (FileObject->SectionObjectPointer == NULL || FileObject->SectionObjectPointer->SharedCacheMap == NULL))
+ {
+ Buffer = 0xdb;
+ Status = ZwWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ &Buffer,
+ sizeof(Buffer),
+ &ByteOffset,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ LARGE_INTEGER Zero;
+ Zero.QuadPart = 0LL;
+
+ Status = IoSetInformation(FileObject,
+ FileEndOfFileInformation,
+ sizeof(LARGE_INTEGER),
+ &Zero);
+ ASSERT(NT_SUCCESS(Status));
+ }
+ }
}
#endif
MaximumSize,
SectionPageProtection,
AllocationAttributes,
- FileHandle);
- if (FileObject)
- ObDereferenceObject(FileObject);
+ FileObject);
}
#else
else if (FileHandle != NULL || FileObject != NULL)
MaximumSize,
SectionPageProtection,
AllocationAttributes);
+ if (FileObject)
+ ObDereferenceObject(FileObject);
}
return Status;