Author: arty
Date: Wed Aug 27 09:25:09 2008
New Revision: 35698
URL:
http://svn.reactos.org/svn/reactos?rev=35698&view=rev
Log:
Replace my rtl/bitmap.c change.
Completely replace my section.c adaptations.
Some WIP in cache.
Much better, not perfect yet.
Modified:
branches/arty-newcc/lib/rtl/bitmap.c
branches/arty-newcc/ntoskrnl/cache/cachesub.c
branches/arty-newcc/ntoskrnl/cache/fssup.c
branches/arty-newcc/ntoskrnl/cache/pinsup.c
branches/arty-newcc/ntoskrnl/include/internal/cc.h
branches/arty-newcc/ntoskrnl/mm/section.c
Modified: branches/arty-newcc/lib/rtl/bitmap.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/lib/rtl/bitmap.c?rev…
==============================================================================
--- branches/arty-newcc/lib/rtl/bitmap.c [iso-8859-1] (original)
+++ branches/arty-newcc/lib/rtl/bitmap.c [iso-8859-1] Wed Aug 27 09:25:09 2008
@@ -867,14 +867,14 @@
RtlTestBit(PRTL_BITMAP BitMapHeader,
ULONG BitNumber)
{
- PULONG Ptr;
+ PUCHAR Ptr;
if (BitNumber >= BitMapHeader->SizeOfBitMap)
return FALSE;
- Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32);
-
- return (BOOLEAN)(*Ptr & (1 << (BitNumber % 32)));
+ Ptr = (PUCHAR)BitMapHeader->Buffer + (BitNumber / 8);
+
+ return (BOOLEAN)(*Ptr & (1 << (BitNumber % 8)));
}
/*
Modified: branches/arty-newcc/ntoskrnl/cache/cachesub.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/cache…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/cachesub.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/cache/cachesub.c [iso-8859-1] Wed Aug 27 09:25:09 2008
@@ -185,6 +185,16 @@
LARGE_INTEGER ToWrite = *FileOffset;
IO_STATUS_BLOCK IOSB;
+ if (!SectionObjectPointer->SharedCacheMap)
+ {
+ if (IoStatus)
+ {
+ IoStatus->Status = STATUS_SUCCESS;
+ IoStatus->Information = 0;
+ }
+ return;
+ }
+
BOOLEAN Result = CcpMapData
((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap,
FileOffset,
@@ -227,6 +237,48 @@
IoStatus->Status = IOSB.Status;
IoStatus->Information = 0;
}
+}
+
+BOOLEAN
+NTAPI
+CcFlushImageSection
+(PSECTION_OBJECT_POINTERS SectionObjectPointer,
+ MMFLUSH_TYPE FlushType)
+{
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
+ PNOCC_BCB Bcb;
+ PLIST_ENTRY Entry;
+ IO_STATUS_BLOCK IOSB;
+ BOOLEAN Result = TRUE;
+
+ for (Entry = Map->AssociatedBcb.Flink;
+ Entry != &Map->AssociatedBcb;
+ Entry = Entry->Flink)
+ {
+ Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
+
+ if (!Bcb->Dirty) continue;
+
+ switch (FlushType)
+ {
+ case MmFlushForDelete:
+ CcPurgeCacheSection
+ (Bcb->FileObject->SectionObjectPointer,
+ &Bcb->FileOffset,
+ Bcb->Length,
+ FALSE);
+ break;
+ case MmFlushForWrite:
+ CcFlushCache
+ (Bcb->FileObject->SectionObjectPointer,
+ &Bcb->FileOffset,
+ Bcb->Length,
+ &IOSB);
+ break;
+ }
+ }
+
+ return Result;
}
// Always succeeds for us
Modified: branches/arty-newcc/ntoskrnl/cache/fssup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/fssup…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/fssup.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/cache/fssup.c [iso-8859-1] Wed Aug 27 09:25:09 2008
@@ -108,8 +108,9 @@
FileObject->SectionObjectPointer->SharedCacheMap = Map;
Map->FileObject = FileObject;
Map->NumberOfMaps = 0;
+ Map->FileSizes = *FileSizes;
+ DPRINT("FileSizes->ValidDataLength %x\n",
FileSizes->ValidDataLength.LowPart);
InitializeListHead(&Map->AssociatedBcb);
- return;
}
BOOLEAN
@@ -174,7 +175,21 @@
CcSetFileSizes(IN PFILE_OBJECT FileObject,
IN PCC_FILE_SIZES FileSizes)
{
- /* Nothing to do */
+ PNOCC_CACHE_MAP Map =
(PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ if (!Map) return;
+ Map->FileSizes = *FileSizes;
+ DPRINT("FileSizes->ValidDataLength %x\n",
FileSizes->ValidDataLength.LowPart);
+}
+
+BOOLEAN
+NTAPI
+CcGetFileSizes(IN PFILE_OBJECT FileObject,
+ IN PCC_FILE_SIZES FileSizes)
+{
+ PNOCC_CACHE_MAP Map =
(PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ if (!Map) return FALSE;
+ *FileSizes = Map->FileSizes;
+ return TRUE;
}
BOOLEAN
Modified: branches/arty-newcc/ntoskrnl/cache/pinsup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/pinsu…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/pinsup.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/cache/pinsup.c [iso-8859-1] Wed Aug 27 09:25:09 2008
@@ -454,9 +454,13 @@
if (!SectionObject)
{
+ PNOCC_CACHE_MAP Map =
(PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ ULONG SectionSize = min(CACHE_STRIPE, Map->FileSizes.ValidDataLength.QuadPart -
Target.QuadPart);
+ DPRINT("Allocating a cache stripe at %x:%d\n",
+ Target.LowPart, SectionSize);
Status = CcpAllocateSection
(FileObject,
- CACHE_STRIPE,
+ SectionSize,
PAGE_READWRITE,
&SectionObject);
@@ -587,7 +591,17 @@
FALSE,
FALSE,
NULL);
- MmProbeAndLockPages(TheBcb->Pinned, KernelMode, IoReadAccess);
+ _SEH_TRY
+ {
+ MmProbeAndLockPages(TheBcb->Pinned, KernelMode, IoReadAccess);
+ }
+ _SEH_HANDLE
+ {
+ IoFreeMdl(TheBcb->Pinned);
+ TheBcb->Pinned = NULL;
+ Result = FALSE;
+ }
+ _SEH_END;
}
return TRUE;
@@ -607,6 +621,58 @@
if (Result)
{
PNOCC_BCB TheBcb = (PNOCC_BCB)*Bcb;
+ if (!TheBcb->Pinned)
+ {
+ TheBcb->Pinned = IoAllocateMdl
+ (TheBcb->BaseAddress,
+ TheBcb->Length,
+ FALSE,
+ FALSE,
+ NULL);
+ _SEH_TRY
+ {
+ MmProbeAndLockPages(TheBcb->Pinned, KernelMode, IoReadAccess);
+ }
+ _SEH_HANDLE
+ {
+ IoFreeMdl(TheBcb->Pinned);
+ TheBcb->Pinned = NULL;
+ Result = FALSE;
+ }
+ _SEH_END;
+ }
+ }
+
+ return Result;
+}
+
+BOOLEAN
+NTAPI
+CcPreparePinWrite(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Zero,
+ IN ULONG Flags,
+ OUT PVOID *Bcb,
+ OUT PVOID *Buffer)
+{
+ BOOLEAN GotIt = CcPinMappedData
+ (FileObject,
+ FileOffset,
+ Length,
+ Flags,
+ Bcb);
+
+ PNOCC_BCB TheBcb = (PNOCC_BCB)*Bcb;
+ ULONG Start = TheBcb - CcCacheSections;
+
+ DPRINT("CcPreparePinWrite(#%x)\n", Start);
+
+ if (GotIt)
+ {
+ CcCacheSections[Start].Dirty = TRUE;
+ *Buffer = (PVOID)((PCHAR)TheBcb->BaseAddress + (FileOffset->QuadPart -
TheBcb->FileOffset.QuadPart));
+ DPRINT("Returning Buffer: %x\n", *Buffer);
if (!TheBcb->Pinned)
{
TheBcb->Pinned = IoAllocateMdl
@@ -619,48 +685,6 @@
}
}
- return Result;
-}
-
-BOOLEAN
-NTAPI
-CcPreparePinWrite(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN BOOLEAN Zero,
- IN ULONG Flags,
- OUT PVOID *Bcb,
- OUT PVOID *Buffer)
-{
- BOOLEAN GotIt = CcPinMappedData
- (FileObject,
- FileOffset,
- Length,
- Flags,
- Bcb);
-
- PNOCC_BCB TheBcb = (PNOCC_BCB)*Bcb;
- ULONG Start = TheBcb - CcCacheSections;
-
- DPRINT("CcPreparePinWrite(#%x)\n", Start);
-
- if (GotIt)
- {
- CcCacheSections[Start].Dirty = TRUE;
- *Buffer = (PVOID)((PCHAR)TheBcb->BaseAddress + (FileOffset->QuadPart -
TheBcb->FileOffset.QuadPart));
- DPRINT("Returning Buffer: %x\n", *Buffer);
- if (!TheBcb->Pinned)
- {
- TheBcb->Pinned = IoAllocateMdl
- (TheBcb->BaseAddress,
- TheBcb->Length,
- FALSE,
- FALSE,
- NULL);
- MmProbeAndLockPages(TheBcb->Pinned, KernelMode, IoReadAccess);
- }
- }
-
DPRINT("Done\n");
return GotIt;
}
Modified: branches/arty-newcc/ntoskrnl/include/internal/cc.h
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/include/int…
==============================================================================
--- branches/arty-newcc/ntoskrnl/include/internal/cc.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/include/internal/cc.h [iso-8859-1] Wed Aug 27 09:25:09
2008
@@ -102,27 +102,6 @@
LONG ActivePrefetches;
} PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS;
-#if 0
-typedef struct _BCB
-{
- LIST_ENTRY BcbSegmentListHead;
- LIST_ENTRY BcbRemoveListEntry;
- BOOLEAN RemoveOnClose;
- ULONG TimeStamp;
- PFILE_OBJECT FileObject;
- ULONG CacheSegmentSize;
- LARGE_INTEGER AllocationSize;
- LARGE_INTEGER FileSize;
- PCACHE_MANAGER_CALLBACKS Callbacks;
- PVOID LazyWriteContext;
- KSPIN_LOCK BcbLock;
- ULONG RefCount;
-#if defined(DBG) || defined(KDBG)
- BOOLEAN Trace; /* enable extra trace output for this BCB and it's cache segments */
-#endif
-} BCB, *PBCB;
-#endif
-
typedef struct _NOCC_BCB
{
/* Public part */
@@ -150,9 +129,10 @@
typedef struct _NOCC_CACHE_MAP
{
- LIST_ENTRY AssociatedBcb;
- PFILE_OBJECT FileObject;
- ULONG NumberOfMaps;
+ LIST_ENTRY AssociatedBcb;
+ PFILE_OBJECT FileObject;
+ ULONG NumberOfMaps;
+ CC_FILE_SIZES FileSizes;
} NOCC_CACHE_MAP, *PNOCC_CACHE_MAP;
VOID
@@ -188,28 +168,14 @@
NTAPI
CcInitCacheZeroPage(VOID);
-NTSTATUS
-NTAPI
-CcRosFlushDirtyPages(
- ULONG Target,
- PULONG Count
-);
-
-VOID
-NTAPI
-CcRosDereferenceCache(PFILE_OBJECT FileObject);
-
-VOID
-NTAPI
-CcRosReferenceCache(PFILE_OBJECT FileObject);
-
-VOID
-NTAPI
-CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer);
-
-NTSTATUS
-NTAPI
-CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
+/* Called by section.c */
+BOOLEAN
+NTAPI
+CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer, MMFLUSH_TYPE
FlushType);
+
+BOOLEAN
+NTAPI
+CcGetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
/*
* Macro for generic cache manage bugchecking. Note that this macro assumes
Modified: branches/arty-newcc/ntoskrnl/mm/section.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section.…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section.c [iso-8859-1] Wed Aug 27 09:25:09 2008
@@ -45,7 +45,7 @@
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
-#define NDEBUG
+//#define NDEBUG
#include <internal/debug.h>
#include <reactos/exeformat.h>
@@ -155,66 +155,79 @@
ULONG Length,
PIO_STATUS_BLOCK ReadStatus)
{
- NTSTATUS Status;
- PIRP Irp = NULL;
- KEVENT ReadWait;
- PDEVICE_OBJECT DeviceObject = MmGetDeviceObjectForFile(FileObject);
- PIO_STACK_LOCATION IrpSp;
-
- DPRINT1
- ("PAGING READ File %wZ Offset %x Length %d\n",
- &FileObject->FileName,
- FileOffset->u.LowPart,
- Length);
-
- KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
-
- Irp = IoBuildAsynchronousFsdRequest
- (IRP_MJ_READ,
- DeviceObject,
- Buffer,
- PAGE_SIZE,
- FileOffset,
- ReadStatus);
-
- if (!Irp)
+ NTSTATUS Status;
+ PIRP Irp = NULL;
+ KEVENT ReadWait;
+ PDEVICE_OBJECT DeviceObject = MmGetDeviceObjectForFile(FileObject);
+ PCHAR BufferWalk;
+ PHYSICAL_ADDRESS Page;
+ PIO_STACK_LOCATION IrpSp;
+
+ DPRINT1
+ ("PAGING READ File %wZ Offset %x Length %d\n",
+ &FileObject->FileName,
+ FileOffset->u.LowPart,
+ Length);
+
+ KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
+
+ Irp = IoBuildAsynchronousFsdRequest
+ (IRP_MJ_READ,
+ DeviceObject,
+ Buffer,
+ Length,
+ FileOffset,
+ ReadStatus);
+
+ if (!Irp)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE;
+
+ ObReferenceObject(FileObject);
+
+ Irp->UserEvent = &ReadWait;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ IrpSp = IoGetNextIrpStackLocation(Irp);
+ IrpSp->FileObject = FileObject;
+
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ if (!NT_SUCCESS
+ (KeWaitForSingleObject
+ (&ReadWait,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL)))
{
- return STATUS_NO_MEMORY;
+ DPRINT1("Warning: Failed to wait for synchronous IRP\n");
+ ASSERT(FALSE);
+ ObDereferenceObject(FileObject);
+ return Status;
}
-
- Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE;
-
- ObReferenceObject(FileObject);
-
- Irp->UserEvent = &ReadWait;
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- IrpSp = IoGetNextIrpStackLocation(Irp);
- IrpSp->FileObject = FileObject;
-
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- if (!NT_SUCCESS
- (KeWaitForSingleObject
- (&ReadWait,
- Suspended,
- KernelMode,
- FALSE,
- NULL)))
- {
- DPRINT1("Warning: Failed to wait for synchronous IRP\n");
- ASSERT(FALSE);
- ObDereferenceObject(FileObject);
- return Status;
- }
- }
-
- ObDereferenceObject(FileObject);
-
- DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
-
- return ReadStatus->Status;
+ }
+
+ ObDereferenceObject(FileObject);
+
+ DPRINT("Paging IO Done: %08x [%02x %02x %02x %02x ...]\n",
ReadStatus->Status,
+ ((PCHAR)Buffer)[0] & 0xff,
+ ((PCHAR)Buffer)[1] & 0xff,
+ ((PCHAR)Buffer)[2] & 0xff,
+ ((PCHAR)Buffer)[3] & 0xff);
+
+ for (BufferWalk = (PCHAR)Buffer; BufferWalk < (PCHAR)Buffer + Length; BufferWalk
+= PAGE_SIZE)
+ {
+ Page = MmGetPhysicalAddress((PVOID)BufferWalk);
+ DPRINT("Setting page clean: %x\n", Page.u.LowPart);
+ //MmSetCleanAllRmaps((PFN_TYPE)(Page.QuadPart >> PAGE_SHIFT));
+ }
+
+ return ReadStatus->Status;
}
NTSTATUS
@@ -226,75 +239,82 @@
ULONG Length,
PIO_STATUS_BLOCK ReadStatus)
{
- NTSTATUS Status;
- PIRP Irp = NULL;
- KEVENT ReadWait;
- PDEVICE_OBJECT DeviceObject;
- PIO_STACK_LOCATION IrpSp;
-
- ASSERT(FileObject);
- ASSERT(FileOffset);
- ASSERT(Buffer);
- ASSERT(ReadStatus);
-
- DeviceObject = MmGetDeviceObjectForFile(FileObject);
-
- ASSERT(DeviceObject);
-
- DPRINT1
- ("PAGING WRITE: FileObject %x Offset %x Length %d\n",
- &FileObject,
- FileOffset->LowPart,
- Length);
-
- KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
-
- Irp = IoBuildAsynchronousFsdRequest
- (IRP_MJ_WRITE,
- DeviceObject,
- Buffer,
- Length,
- FileOffset,
- ReadStatus);
-
- if (!Irp)
+ NTSTATUS Status;
+ PIRP Irp = NULL;
+ KEVENT ReadWait;
+ PDEVICE_OBJECT DeviceObject;
+ PCHAR BufferWalk;
+ PHYSICAL_ADDRESS Page;
+ PIO_STACK_LOCATION IrpSp;
+
+ ASSERT(FileObject);
+ ASSERT(FileOffset);
+ ASSERT(Buffer);
+ ASSERT(ReadStatus);
+
+ DeviceObject = MmGetDeviceObjectForFile(FileObject);
+
+ ASSERT(DeviceObject);
+
+ DPRINT1
+ ("PAGING WRITE: FileObject %x Offset %x Length %d\n",
+ &FileObject,
+ FileOffset->LowPart,
+ Length);
+
+ KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
+
+ Irp = IoBuildAsynchronousFsdRequest
+ (IRP_MJ_WRITE,
+ DeviceObject,
+ Buffer,
+ Length,
+ FileOffset,
+ ReadStatus);
+
+ if (!Irp)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE;
+
+ ObReferenceObject(FileObject);
+
+ Irp->UserEvent = &ReadWait;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ IrpSp = IoGetNextIrpStackLocation(Irp);
+ IrpSp->FileObject = FileObject;
+
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ if (!NT_SUCCESS
+ (KeWaitForSingleObject
+ (&ReadWait,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL)))
{
- return STATUS_NO_MEMORY;
+ DPRINT1("Warning: Failed to wait for synchronous IRP\n");
+ ASSERT(FALSE);
+ ObDereferenceObject(FileObject);
+ return Status;
}
-
- Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE;
-
- ObReferenceObject(FileObject);
-
- Irp->UserEvent = &ReadWait;
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- IrpSp = IoGetNextIrpStackLocation(Irp);
- IrpSp->FileObject = FileObject;
-
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- if (!NT_SUCCESS
- (KeWaitForSingleObject
- (&ReadWait,
- Suspended,
- KernelMode,
- FALSE,
- NULL)))
- {
- DPRINT1("Warning: Failed to wait for synchronous IRP\n");
- ASSERT(FALSE);
- ObDereferenceObject(FileObject);
- return Status;
- }
- }
-
- ObDereferenceObject(FileObject);
-
- DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
-
- return ReadStatus->Status;
+ }
+
+ ObDereferenceObject(FileObject);
+
+ DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
+ for (BufferWalk = (PCHAR)Buffer; BufferWalk < (PCHAR)Buffer + Length; BufferWalk
+= PAGE_SIZE)
+ {
+ Page = MmGetPhysicalAddress((PVOID)BufferWalk);
+ //MmSetCleanAllRmaps((PFN_TYPE)(Page.QuadPart >> PAGE_SHIFT));
+ }
+
+ return ReadStatus->Status;
}
NTSTATUS
@@ -457,7 +477,7 @@
{
DPRINT1("Image segment %d still referenced (was %d)\n", i,
SectionSegments[i].ReferenceCount);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmFreePageTablesSectionSegment(&SectionSegments[i]);
}
@@ -475,7 +495,7 @@
if (Segment->ReferenceCount != 0)
{
DPRINT1("Data segment still referenced\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmFreePageTablesSectionSegment(Segment);
ExFreePool(Segment);
@@ -523,7 +543,7 @@
TAG_SECTION_PAGE_TABLE);
if (Table == NULL)
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
memset(Table, 0, sizeof(SECTION_PAGE_TABLE));
DPRINT("Table %x\n", Table);
@@ -576,16 +596,16 @@
if (Entry == 0)
{
DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (SHARE_COUNT_FROM_SSE(Entry) == MAX_SHARE_COUNT)
{
DPRINT1("Maximum share count reached\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (IS_SWAP_FROM_SSE(Entry))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) + 1);
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
@@ -600,21 +620,22 @@
BOOLEAN PageOut)
{
ULONG Entry;
+ BOOLEAN IsDirectMapped = FALSE;
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
if (Entry == 0)
{
DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (SHARE_COUNT_FROM_SSE(Entry) == 0)
{
DPRINT1("Zero share count for unshare\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (IS_SWAP_FROM_SSE(Entry))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) - 1);
/*
@@ -629,12 +650,33 @@
BOOLEAN IsImageSection;
LARGE_INTEGER FileOffset;
- FileOffset.QuadPart = Segment->FileOffset.QuadPart + Offset;
+ FileOffset.QuadPart = Offset + Segment->FileOffset.QuadPart;
IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
Page = PFN_FROM_SSE(Entry);
FileObject = Section->FileObject;
+ if (FileObject != NULL &&
+ !(Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+ {
+
+ if ((FileOffset.QuadPart % PAGE_SIZE) == 0 &&
+ (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection))
+ {
+ IO_STATUS_BLOCK IOSB;
+ IsDirectMapped = TRUE;
+ CcFlushCache
+ (FileObject->SectionObjectPointer,
+ &FileOffset,
+ PAGE_SIZE,
+ &IOSB);
+ if (!NT_SUCCESS(IOSB.Status))
+ {
+ DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n",
IOSB.Status);
+ ASSERT(FALSE);
+ }
+ }
+ }
SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
if (SavedSwapEntry == 0)
@@ -655,6 +697,10 @@
else
{
MmSetPageEntrySectionSegment(Segment, Offset, 0);
+ if (!IsDirectMapped)
+ {
+ MmReleasePageMemoryConsumer(MC_USER, Page);
+ }
}
}
else
@@ -676,7 +722,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("MM: Failed to write to swap page (Status was
0x%.8X)\n", Status);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
}
MmSetPageEntrySectionSegment(Segment, Offset,
MAKE_SWAP_SSE(SavedSwapEntry));
@@ -687,7 +733,7 @@
else
{
DPRINT1("Found a swapentry for a non private page in an image or data
file sgment\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
}
}
@@ -696,88 +742,6 @@
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
}
return(SHARE_COUNT_FROM_SSE(Entry) > 0);
-}
-
-NTSTATUS
-NTAPI
-MiReadPage(PMEMORY_AREA MemoryArea,
- PLARGE_INTEGER FileOffset,
- PPFN_TYPE Page)
-/*
- * FUNCTION: Read a page for a section backed memory area.
- * PARAMETERS:
- * MemoryArea - Memory area to read the page for.
- * Offset - Offset of the page to read.
- * Page - Variable that receives a page contains the read data.
- */
-{
- PFILE_OBJECT FileObject;
- NTSTATUS Status = STATUS_SUCCESS;
- BOOLEAN IsImageSection;
- PVOID Buffer = NULL;
- IO_STATUS_BLOCK ReadStatus;
- FILE_STANDARD_INFORMATION FileInfo;
- PMM_SECTION_SEGMENT Segment;
- PROS_SECTION_OBJECT Section;
-
- *Page = 0;
-
- Segment = MemoryArea->Data.SectionData.Segment;
- Section = MemoryArea->Data.SectionData.Section;
- FileObject = Section->FileObject;
- ASSERT(FileObject);
- IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
-
- DPRINT("MiReadPage: FileObject %x, Offset %x\n", FileObject,
FileOffset->LowPart);
-
- Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, Page);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Buffer = MmCreateHyperspaceMapping(*Page);
- if (!Buffer)
- {
- Status = STATUS_NO_MEMORY;
- goto cleanup;
- }
-
- DPRINT("Read File Name:[%wZ] At:%x\n", &FileObject->FileName,
FileOffset->LowPart);
-
- /* Delayed section info, if needed */
- if (Section->MaximumSize.QuadPart == ~0ll)
- {
- Status = IoQueryFileInformation
- (FileObject,
- FileStandardInformation,
- sizeof(FILE_STANDARD_INFORMATION),
- &FileInfo,
- &ReadStatus.Information);
-
- if (NT_SUCCESS(Status))
- {
- Section->MaximumSize = FileInfo.EndOfFile;
- Segment->RawLength = FileInfo.EndOfFile.QuadPart -
Segment->FileOffset.QuadPart;
- Segment->Length = PAGE_ROUND_UP(Segment->RawLength);
- }
- }
-
- /*
- * If the cache segment isn't up to date then call the file
- * system to read in the data.
- */
-
- Status = MiSimpleRead(FileObject, FileOffset, Buffer, max(PAGE_SIZE,
Segment->FileOffset.QuadPart + Segment->RawLength - FileOffset->QuadPart),
&ReadStatus);
- DPRINT("MiSimpleRead: Status %08x\n", Status);
-
-cleanup:
- if (Buffer) MmDeleteHyperspaceMapping(Buffer);
- if (!NT_SUCCESS(Status) && *Page) MmReleasePageMemoryConsumer(MC_USER,
*Page);
-
- DPRINT("Finished MiReadPage: Status %x\n", Status);
-
- return Status;
}
NTSTATUS
@@ -850,7 +814,7 @@
if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
@@ -868,12 +832,12 @@
if (Status != STATUS_SUCCESS)
{
DPRINT1("Failed to wait for page op, status = %x\n", Status);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (PageOp->Status == STATUS_PENDING)
{
DPRINT1("Woke for page op before completion\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmLockAddressSpace(AddressSpace);
/*
@@ -931,7 +895,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmInsertRmap(Page, Process, (PVOID)PAddress);
}
@@ -945,6 +909,16 @@
DPRINT("Address 0x%.8X\n", Address);
return(STATUS_SUCCESS);
}
+ else
+ {
+ Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Didn't get a page\n");
+ ASSERT(FALSE);
+ return Status;
+ }
+ }
HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
if (HasSwapEntry)
@@ -960,7 +934,7 @@
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
{
DPRINT1("Found a swaped out private page in a pagefile section.\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmUnlockSectionSegment(Segment);
@@ -970,14 +944,14 @@
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
Status = MmReadFromSwapPage(SwapEntry, Page);
if (!NT_SUCCESS(Status))
{
DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmLockAddressSpace(AddressSpace);
Status = MmCreateVirtualMapping(Process,
@@ -988,7 +962,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
return(Status);
}
@@ -1033,7 +1007,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
return(Status);
}
/*
@@ -1069,7 +1043,7 @@
}
if (!NT_SUCCESS(Status))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
Status = MmCreateVirtualMapping(Process,
Address,
@@ -1079,7 +1053,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
return(Status);
}
MmInsertRmap(Page, Process, (PVOID)PAddress);
@@ -1115,7 +1089,7 @@
MmUnlockSectionSegment(Segment);
MmUnlockAddressSpace(AddressSpace);
- if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
+ if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
(Offset >= PAGE_ROUND_UP(Segment->RawLength) &&
Section->AllocationAttributes & SEC_IMAGE))
{
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
@@ -1126,17 +1100,37 @@
}
else
{
- LARGE_INTEGER ReadOffset;
- ReadOffset.QuadPart =
- Segment->FileOffset.QuadPart +
- Offset;
- Status = MiReadPage(MemoryArea, &ReadOffset, &Page);
+ PVOID Buffer = MmCreateHyperspaceMapping(Page);
+ ULONG RemainingLength;
+ LARGE_INTEGER TotalOffset;
+ IO_STATUS_BLOCK IOSB;
+
+ TotalOffset.QuadPart = Segment->FileOffset.QuadPart + Offset;
+ RemainingLength = Segment->RawLength - Offset;
+
+ if ((RemainingLength > PAGE_SIZE) || (Segment->Length == 0))
+ RemainingLength = PAGE_SIZE;
+
+ DPRINT("Segment->RawLength %d\n", Segment->RawLength);
+ DPRINT("Segment->Length %d\n", Segment->Length);
+ DPRINT("Reading at offset %x (relative %x)\n", TotalOffset.LowPart, Offset);
+ DPRINT("RemainingLength %x\n", RemainingLength);
+
+ Status = MiSimpleRead
+ (Section->FileObject,
+ &TotalOffset,
+ Buffer,
+ RemainingLength,
+ &IOSB);
+
if (!NT_SUCCESS(Status))
{
DPRINT1("MiReadPage failed (Status %x)\n", Status);
}
- DPRINT("PAGING IO DONE: %08x\n", Status);
- }
+
+ MmDeleteHyperspaceMapping(Buffer);
+ }
+
if (!NT_SUCCESS(Status))
{
/*
@@ -1165,7 +1159,7 @@
if (Entry != Entry1)
{
DPRINT1("Someone changed ppte entry while we slept\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
@@ -1184,7 +1178,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmInsertRmap(Page, Process, (PVOID)PAddress);
@@ -1213,13 +1207,13 @@
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
Status = MmReadFromSwapPage(SwapEntry, Page);
if (!NT_SUCCESS(Status))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
@@ -1236,7 +1230,7 @@
if (Entry != Entry1)
{
DPRINT1("Someone changed ppte entry while we slept\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
@@ -1259,7 +1253,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmInsertRmap(Page, Process, (PVOID)PAddress);
if (Locked)
@@ -1291,7 +1285,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmInsertRmap(Page, Process, (PVOID)PAddress);
if (Locked)
@@ -1385,7 +1379,7 @@
if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
@@ -1401,12 +1395,12 @@
if (Status == STATUS_TIMEOUT)
{
DPRINT1("Failed to wait for page op, status = %x\n", Status);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (PageOp->Status == STATUS_PENDING)
{
DPRINT1("Woke for page op before completion\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
* Restart the operation
@@ -1428,7 +1422,7 @@
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage);
if (!NT_SUCCESS(Status))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
@@ -1453,13 +1447,13 @@
if (!NT_SUCCESS(Status))
{
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
return(Status);
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (Locked)
{
@@ -1541,6 +1535,7 @@
LARGE_INTEGER FileOffset;
NTSTATUS Status;
PFILE_OBJECT FileObject;
+ BOOLEAN DirectMapped;
BOOLEAN IsImageSection;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
@@ -1552,13 +1547,27 @@
Context.Segment = MemoryArea->Data.SectionData.Segment;
Context.Section = MemoryArea->Data.SectionData.Section;
- Context.Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
- + MemoryArea->Data.SectionData.ViewOffset;
- FileOffset.QuadPart = Context.Segment->FileOffset.QuadPart + Context.Offset;
+ Context.Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress;
+ FileOffset.QuadPart = Context.Offset + Context.Segment->FileOffset.QuadPart;
IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE :
FALSE;
FileObject = Context.Section->FileObject;
+ if (FileObject != NULL &&
+ !(Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+ {
+ /*
+ * If the file system is letting us go directly to the cache and the
+ * memory area was mapped at an offset in the file which is page aligned
+ * then note this is a direct mapped page.
+ */
+ if ((FileOffset.QuadPart % PAGE_SIZE) == 0 &&
+ (Context.Offset + PAGE_SIZE <= Context.Segment->RawLength ||
!IsImageSection))
+ {
+ DirectMapped = TRUE;
+ }
+ }
+
/*
* This should never happen since mappings of physical memory are never
@@ -1569,7 +1578,7 @@
DPRINT1("Trying to page out from physical memory section address 0x%X "
"process %d\n", Address,
Process ? Process->UniqueProcessId : 0);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
@@ -1580,7 +1589,7 @@
{
DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n",
Process ? Process->UniqueProcessId : 0, Address);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
Page = MmGetPfnForProcess(Process, Address);
SwapEntry = MmGetSavedSwapEntryPage(Page);
@@ -1600,6 +1609,7 @@
Context.Private = FALSE;
}
+ MmReferencePage(Page);
MmDeleteAllRmaps(Page, (PVOID)&Context, MmPageOutDeleteMapping);
/*
@@ -1611,7 +1621,7 @@
if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT) &&
!(Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
}
@@ -1629,7 +1639,7 @@
{
DPRINT1("Found a %s private page (address %x) in a pagefile
segment.\n",
Context.WasDirty ? "dirty" : "clean", Address);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (!Context.WasDirty && SwapEntry != 0)
{
@@ -1647,7 +1657,7 @@
{
DPRINT1("Found a %s private page (address %x) in a shared section
segment.\n",
Context.WasDirty ? "dirty" : "clean", Address);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
if (!Context.WasDirty || SwapEntry != 0)
{
@@ -1662,6 +1672,45 @@
return(STATUS_SUCCESS);
}
}
+ else if (!Context.Private && DirectMapped)
+ {
+ IO_STATUS_BLOCK IOSB;
+
+ if (SwapEntry != 0)
+ {
+ DPRINT1("Found a swapentry for a non private and direct mapped page
(address %x)\n",
+ Address);
+ ASSERT(FALSE);
+ }
+ CcFlushCache
+ (FileObject->SectionObjectPointer,
+ &FileOffset,
+ PAGE_SIZE,
+ &IOSB);
+ Status = IOSB.Status;
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status);
+ ASSERT(FALSE);
+ }
+ MmReleasePageMemoryConsumer(MC_CACHE, Page);
+ PageOp->Status = STATUS_SUCCESS;
+ MmspCompleteAndReleasePageOp(PageOp);
+ return(STATUS_SUCCESS);
+ }
+ else if (!Context.WasDirty && !DirectMapped && !Context.Private)
+ {
+ if (SwapEntry != 0)
+ {
+ DPRINT1("Found a swap entry for a non dirty, non private and not direct
mapped page (address %x)\n",
+ Address);
+ ASSERT(FALSE);
+ }
+ MmReleasePageMemoryConsumer(MC_USER, Page);
+ PageOp->Status = STATUS_SUCCESS;
+ MmspCompleteAndReleasePageOp(PageOp);
+ return(STATUS_SUCCESS);
+ }
else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
{
MmSetSavedSwapEntryPage(Page, 0);
@@ -1672,7 +1721,7 @@
MmUnlockAddressSpace(AddressSpace);
if (!NT_SUCCESS(Status))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmReleasePageMemoryConsumer(MC_USER, Page);
PageOp->Status = STATUS_SUCCESS;
@@ -1800,7 +1849,7 @@
MmUnlockAddressSpace(AddressSpace);
if (!NT_SUCCESS(Status))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
}
else
@@ -1822,6 +1871,7 @@
PMM_PAGEOP PageOp)
{
ULONG Offset;
+ LARGE_INTEGER TotalOffset;
PROS_SECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment;
PFN_TYPE Page;
@@ -1830,22 +1880,38 @@
BOOLEAN Private;
NTSTATUS Status;
PFILE_OBJECT FileObject;
+ BOOLEAN DirectMapped;
BOOLEAN IsImageSection;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
Address = (PVOID)PAGE_ROUND_DOWN(Address);
- Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
- + MemoryArea->Data.SectionData.ViewOffset;
+ Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress;
/*
* Get the segment and section.
*/
Segment = MemoryArea->Data.SectionData.Segment;
+ TotalOffset.QuadPart = Segment->FileOffset.QuadPart + Offset;
Section = MemoryArea->Data.SectionData.Section;
IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
FileObject = Section->FileObject;
+ DirectMapped = FALSE;
+ if (FileObject != NULL &&
+ !(Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
+ {
+ /*
+ * If the file system is letting us go directly to the cache and the
+ * memory area was mapped at an offset in the file which is page aligned
+ * then note this is a direct mapped page.
+ */
+ if (((Offset + Segment->FileOffset.QuadPart) % PAGE_SIZE) == 0 &&
+ (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection))
+ {
+ DirectMapped = TRUE;
+ }
+ }
/*
* This should never happen since mappings of physical memory are never
@@ -1856,7 +1922,7 @@
DPRINT1("Trying to write back page from physical memory mapped at %X "
"process %d\n", Address,
Process ? Process->UniqueProcessId : 0);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
@@ -1867,7 +1933,7 @@
{
DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n",
Process ? Process->UniqueProcessId : 0, Address);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
Page = MmGetPfnForProcess(Process, Address);
SwapEntry = MmGetSavedSwapEntryPage(Page);
@@ -1890,6 +1956,23 @@
* Speculatively set all mappings of the page to clean.
*/
MmSetCleanAllRmaps(Page);
+
+ /*
+ * If this page was direct mapped from the cache then the cache manager
+ * will take care of writing it back to disk.
+ */
+ if (DirectMapped && !Private)
+ {
+ ASSERT(SwapEntry == 0);
+ CcFlushCache
+ (FileObject->SectionObjectPointer,
+ &TotalOffset,
+ PAGE_SIZE,
+ NULL);
+ PageOp->Status = STATUS_SUCCESS;
+ MmspCompleteAndReleasePageOp(PageOp);
+ return(STATUS_SUCCESS);
+ }
/*
* If necessary, allocate an entry in the paging file for this page
@@ -1972,7 +2055,7 @@
PFN_TYPE Page;
Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
- + MemoryArea->Data.SectionData.ViewOffset;
+ + MemoryArea->Data.SectionData.ViewOffset;
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
Page = MmGetPfnForProcess(Process, Address);
@@ -2017,7 +2100,6 @@
if ((MemoryArea->Flags & SEC_NO_CHANGE) &&
Region->Protect != Protect)
{
- CHECKPOINT1;
return STATUS_INVALID_PAGE_PROTECTION;
}
@@ -2222,7 +2304,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create PhysicalMemory section\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
Status = ObInsertObject(PhysSection,
NULL,
@@ -2353,12 +2435,14 @@
*/
{
PROS_SECTION_OBJECT Section;
+ NTSTATUS Status;
LARGE_INTEGER MaximumSize;
PMM_SECTION_SEGMENT Segment;
- NTSTATUS Status;
ULONG FileAccess;
-
- DPRINT("MmCreateDataFileSection [%wZ]\n", &FileObject->FileName);
+ IO_STATUS_BLOCK Iosb;
+ CC_FILE_SIZES FileSizes;
+ FILE_STANDARD_INFORMATION FileInfo;
+ KIRQL OldIrql;
/*
* Create the section
@@ -2374,7 +2458,6 @@
(PVOID*)(PVOID)&Section);
if (!NT_SUCCESS(Status))
{
- DPRINT("Failed: %08x\n", Status);
return(Status);
}
/*
@@ -2398,6 +2481,46 @@
}
/*
+ * Reference the file handle
+ */
+ ObReferenceObject(FileObject);
+
+ /* A hack: If we're cached, we can overcome deadlocking with the upper
+ * layer filesystem call by retriving the object sizes from the cache
+ * which is made to keep track. If I had to guess, they were figuring
+ * out a similar problem.
+ */
+ if (!CcGetFileSizes(FileObject, &FileSizes))
+ {
+ /* This means the file isn't cached (yet) ... consequently, this
+ * call is not recursive from the cache. */
+ /*
+ * FIXME: This is propably not entirely correct. We can't look into
+ * the standard FCB header because it might not be initialized yet
+ * (as in case of the EXT2FS driver by Manoj Paul Joseph where the
+ * standard file information is filled on first request).
+ */
+ DPRINT("IoQueryFileInformation\n");
+ Status = IoQueryFileInformation
+ (FileObject,
+ FileStandardInformation,
+ sizeof(FILE_STANDARD_INFORMATION),
+ &FileInfo,
+ &Iosb.Information);
+ DPRINT("IoQueryFileInformation -> %08x\n", Status);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(Section);
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+
+ FileSizes.ValidDataLength = FileInfo.EndOfFile;
+ FileSizes.FileSize = FileInfo.EndOfFile;
+ }
+
+ /*
* FIXME: Revise this once a locking order for file size changes is
* decided
*/
@@ -2407,52 +2530,68 @@
}
else
{
- MaximumSize.QuadPart = ~0ll;
- }
-
- /*
- * Lock the file
- */
- Status = MmspWaitForFileLock(FileObject);
- if (Status != STATUS_SUCCESS)
- {
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- DPRINT("Failed: %08x\n", Status);
- return(Status);
- }
-
+ MaximumSize = FileSizes.ValidDataLength;
+ /* Mapping zero-sized files isn't allowed. */
+ if (MaximumSize.QuadPart == 0)
+ {
+ ObDereferenceObject(Section);
+ ObDereferenceObject(FileObject);
+ return STATUS_FILE_INVALID;
+ }
+ }
+
+ if (MaximumSize.QuadPart > FileSizes.ValidDataLength.QuadPart)
+ {
+ DPRINT("IoSetInformation expanding from %x to %x\n",
+ MaximumSize.LowPart, FileSizes.ValidDataLength.LowPart);
+ Status = IoSetInformation(FileObject,
+ FileAllocationInformation,
+ sizeof(LARGE_INTEGER),
+ &MaximumSize);
+ DPRINT("IoSetInformation -> %08x\n", Status);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(Section);
+ ObDereferenceObject(FileObject);
+ return(STATUS_SECTION_NOT_EXTENDED);
+ }
+ }
+
+ Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
+ TAG_MM_SECTION_SEGMENT);
+ if (Segment == NULL)
+ {
+ ObDereferenceObject(Section);
+ ObDereferenceObject(FileObject);
+ return(STATUS_NO_MEMORY);
+ }
+
+ ExInitializeFastMutex(&Segment->Lock);
+ Segment->ReferenceCount = 1;
+ Section->Segment = Segment;
+
+ KeAcquireSpinLock(&FileObject->IrpListLock, &OldIrql);
/*
* If this file hasn't been mapped as a data file before then allocate a
* section segment to describe the data file mapping
*/
if (FileObject->SectionObjectPointer->DataSectionObject == NULL)
{
- Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
- TAG_MM_SECTION_SEGMENT);
- if (Segment == NULL)
- {
- //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- DPRINT("Failed: STATUS_NO_MEMORY\n");
- return(STATUS_NO_MEMORY);
- }
- Section->Segment = Segment;
- Segment->ReferenceCount = 1;
- ExInitializeFastMutex(&Segment->Lock);
+ FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
+ KeReleaseSpinLock(&FileObject->IrpListLock, OldIrql);
+
/*
* Set the lock before assigning the segment to the file object
*/
ExAcquireFastMutex(&Segment->Lock);
- FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
-
+
+ DPRINT("Filling out Segment info (No previous data section)\n");
Segment->FileOffset.QuadPart = 0;
Segment->Protection = SectionPageProtection;
Segment->Flags = MM_DATAFILE_SEGMENT;
Segment->Characteristics = 0;
Segment->WriteCopy = FALSE;
-
if (AllocationAttributes & SEC_RESERVE)
{
Segment->Length = Segment->RawLength = 0;
@@ -2460,13 +2599,18 @@
else
{
Segment->RawLength = MaximumSize.u.LowPart;
- Segment->Length = MaximumSize.u.LowPart;
+ Segment->Length = PAGE_ROUND_UP(Segment->RawLength);
}
Segment->VirtualAddress = 0;
RtlZeroMemory(&Segment->PageDirectory, sizeof(SECTION_PAGE_DIRECTORY));
}
else
{
+ KeReleaseSpinLock(&FileObject->IrpListLock, OldIrql);
+ ExFreePool(Segment);
+
+ DPRINT("Filling out Segment info (previous data section)\n");
+
/*
* If the file is already mapped as a data file then we may need
* to extend it
@@ -2476,6 +2620,7 @@
DataSectionObject;
Section->Segment = Segment;
(void)InterlockedIncrementUL(&Segment->ReferenceCount);
+
MmLockSectionSegment(Segment);
if (MaximumSize.u.LowPart > Segment->RawLength &&
@@ -2485,11 +2630,15 @@
Segment->Length = PAGE_ROUND_UP(Segment->RawLength);
}
}
+
MmUnlockSectionSegment(Segment);
+
Section->FileObject = FileObject;
Section->MaximumSize = MaximumSize;
+
+ //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
+
*SectionObject = Section;
- DPRINT("Success\n");
return(STATUS_SUCCESS);
}
@@ -2564,20 +2713,19 @@
OUT PULONG ReadSize)
{
NTSTATUS Status;
- PFILE_OBJECT FileObject = (PFILE_OBJECT)File;
LARGE_INTEGER FileOffset;
ULONG AdjustOffset;
ULONG OffsetAdjustment;
ULONG BufferSize;
ULONG UsedSize;
PVOID Buffer;
- IO_STATUS_BLOCK ReadStatus;
-
+ IO_STATUS_BLOCK Iosb;
+
ASSERT_IRQL_LESS(DISPATCH_LEVEL);
if(Length == 0)
{
- KEBUGCHECK(STATUS_INVALID_PARAMETER_4);
+ ASSERT(FALSE);
}
FileOffset = *Offset;
@@ -2585,7 +2733,7 @@
/* Negative/special offset: it cannot be used in this context */
if(FileOffset.u.HighPart < 0)
{
- KEBUGCHECK(STATUS_INVALID_PARAMETER_5);
+ ASSERT(FALSE);
}
AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart);
@@ -2607,26 +2755,21 @@
UsedSize = 0;
- Status = MiSimpleRead(FileObject, &FileOffset, Buffer, Length, &ReadStatus);
- DPRINT("MiSimpleRead: Status %08x\n", Status);
-
- UsedSize = ReadStatus.Information;
-
- DPRINT("ExeFmtpReadFile -> %x:%x\n", Status, UsedSize);
+ Status = MiSimpleRead(File, &FileOffset, Buffer, BufferSize, &Iosb);
if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
{
Status = STATUS_IN_PAGE_ERROR;
ASSERT(!NT_SUCCESS(Status));
}
+
+ UsedSize = Iosb.Information;
if(NT_SUCCESS(Status))
{
*Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
*AllocBase = Buffer;
*ReadSize = UsedSize - OffsetAdjustment;
- DPRINT("Data @ %x Buffer @ %x Read Size %d\n", *Data, *AllocBase,
*ReadSize);
- DPRINT("First couple of bytes: %02x%02x\n", ((PCHAR)Data)[0] & 0xff,
((PCHAR)Data)[1] & 0xff);
}
else
{
@@ -2914,8 +3057,8 @@
/* Unaligned segments must be contiguous within the file */
if (Segment->FileOffset.QuadPart !=
- (EffectiveSegment->FileOffset.QuadPart +
- EffectiveSegment->RawLength))
+ (EffectiveSegment->FileOffset.QuadPart +
+ EffectiveSegment->RawLength))
{
return FALSE;
}
@@ -3001,6 +3144,8 @@
&FileHeaderBuffer,
&FileHeaderSize);
+ DPRINT("ExeFmtpReadFile %x\n", Status);
+
if (!NT_SUCCESS(Status))
return Status;
@@ -3068,10 +3213,10 @@
if(ImageSectionObject->ImageBase == 0)
{
- if(ImageSectionObject->ImageCharacteristics & IMAGE_FILE_DLL)
- ImageSectionObject->ImageBase = 0x10000000;
- else
- ImageSectionObject->ImageBase = 0x00400000;
+ if(ImageSectionObject->ImageCharacteristics & IMAGE_FILE_DLL)
+ ImageSectionObject->ImageBase = 0x10000000;
+ else
+ ImageSectionObject->ImageBase = 0x00400000;
}
/*
@@ -3116,7 +3261,7 @@
{
ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
ImageSectionObject->Segments[i].ReferenceCount = 1;
-
+
RtlZeroMemory(&ImageSectionObject->Segments[i].PageDirectory,
sizeof(ImageSectionObject->Segments[i].PageDirectory));
}
@@ -3165,12 +3310,7 @@
/*
* Reference the file handle
*/
- Status = ObReferenceObject(FileObject);
-
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
+ ObReferenceObject(FileObject);
/*
* Create the section
@@ -3196,7 +3336,7 @@
Section->SectionPageProtection = SectionPageProtection;
Section->AllocationAttributes = AllocationAttributes;
- if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject
== NULL)
+ if (FileObject->SectionObjectPointer->ImageSectionObject == NULL)
{
NTSTATUS StatusExeFmt;
@@ -3214,6 +3354,7 @@
if (!NT_SUCCESS(StatusExeFmt))
{
+ DPRINT("StatusExeFmt %08x\n", StatusExeFmt);
if(ImageSectionObject->Segments != NULL)
ExFreePool(ImageSectionObject->Segments);
@@ -3287,6 +3428,7 @@
Status = STATUS_SUCCESS;
}
Section->FileObject = FileObject;
+ //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
*SectionObject = Section;
return(Status);
}
@@ -3348,7 +3490,6 @@
SectionHandle);
}
- DPRINT("NtCreateSection -> %08x\n", Status);
return Status;
}
@@ -3544,7 +3685,6 @@
*/
if (Protect & ~PAGE_FLAGS_VALID_FROM_USER_MODE)
{
- CHECKPOINT1;
return STATUS_INVALID_PARAMETER_10;
}
@@ -3558,7 +3698,6 @@
tmpProtect != PAGE_EXECUTE_READWRITE &&
tmpProtect != PAGE_EXECUTE_WRITECOPY)
{
- CHECKPOINT1;
return STATUS_INVALID_PAGE_PROTECTION;
}
@@ -3685,11 +3824,12 @@
return(Status);
}
-VOID
+VOID static
MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
{
ULONG Entry;
+ PFILE_OBJECT FileObject;
ULONG Offset;
SWAPENTRY SavedSwapEntry;
PMM_PAGEOP PageOp;
@@ -3698,7 +3838,6 @@
PMM_SECTION_SEGMENT Segment;
PMM_AVL_TABLE AddressSpace;
PEPROCESS Process;
-
AddressSpace = (PMM_AVL_TABLE)Context;
Process = MmGetAddressSpaceOwner(AddressSpace);
@@ -3706,7 +3845,7 @@
Address = (PVOID)PAGE_ROUND_DOWN(Address);
Offset = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
- MemoryArea->Data.SectionData.ViewOffset;
+ MemoryArea->Data.SectionData.ViewOffset;
Section = MemoryArea->Data.SectionData.Section;
Segment = MemoryArea->Data.SectionData.Segment;
@@ -3722,7 +3861,7 @@
if (Status != STATUS_SUCCESS)
{
DPRINT1("Failed to wait for page op, status = %x\n", Status);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmLockAddressSpace(AddressSpace);
@@ -3739,39 +3878,17 @@
*/
if (Segment->Flags & MM_DATAFILE_SEGMENT)
{
- if (Page == PFN_FROM_SSE(Entry) && Dirty)
- {
- LARGE_INTEGER FileOffset;
- IO_STATUS_BLOCK ReadStatus;
- ULONG RemainingLength;
- PVOID Buffer = MmCreateHyperspaceMapping(Page);
- NTSTATUS Status;
-
- FileOffset.QuadPart = Offset;
-
- MmUnlockSectionSegment(Segment);
- MmUnlockAddressSpace(AddressSpace);
-
- RemainingLength = min(PAGE_SIZE, Segment->FileOffset.QuadPart + Segment->Length
- FileOffset.QuadPart);
- DPRINT("Writing no more than %d bytes\n", RemainingLength);
-
- if (RemainingLength > 0)
- {
- Status = MiSimpleWrite
- (Section->FileObject,
- &FileOffset,
- Buffer,
- min(RemainingLength, PAGE_SIZE),
- &ReadStatus);
- }
- else
- Status = STATUS_SUCCESS;
-
- MmLockAddressSpace(AddressSpace);
- MmLockSectionSegment(Segment);
-
- MmDeleteHyperspaceMapping(Buffer);
- }
+ if (Page == PFN_FROM_SSE(Entry) && Dirty)
+ {
+ IO_STATUS_BLOCK IOSB;
+ FileObject = MemoryArea->Data.SectionData.Section->FileObject;
+ CcFlushCache
+ (FileObject->SectionObjectPointer,
+ &Segment->FileOffset,
+ Segment->Length,
+ &IOSB);
+ ASSERT(SwapEntry == 0);
+ }
}
if (SwapEntry != 0)
@@ -3782,7 +3899,7 @@
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
{
DPRINT1("Found a swap entry for a page in a pagefile section.\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmFreeSwapPage(SwapEntry);
}
@@ -3797,7 +3914,7 @@
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
{
DPRINT1("Found a private page in a pagefile section.\n");
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
/*
* Just dereference private pages
@@ -3923,7 +4040,7 @@
if (Status != STATUS_SUCCESS)
{
DPRINT1("Failed to wait for page op, status = %x\n", Status);
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
@@ -3969,7 +4086,7 @@
}
if (i >= NrSegments)
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
for (i = 0; i < NrSegments; i++)
@@ -4391,7 +4508,6 @@
Protect != PAGE_EXECUTE_READWRITE &&
Protect != PAGE_EXECUTE_WRITECOPY)
{
- CHECKPOINT1;
return STATUS_INVALID_PAGE_PROTECTION;
}
@@ -4488,21 +4604,18 @@
if ((Protect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) &&
!(Section->SectionPageProtection &
(PAGE_READWRITE|PAGE_EXECUTE_READWRITE)))
{
- CHECKPOINT1;
return STATUS_SECTION_PROTECTION;
}
/* check for read access */
if ((Protect &
(PAGE_READONLY|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_WRITECOPY)) &&
!(Section->SectionPageProtection &
(PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)))
{
- CHECKPOINT1;
return STATUS_SECTION_PROTECTION;
}
/* check for execute access */
if ((Protect &
(PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY))
&&
!(Section->SectionPageProtection &
(PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)))
{
- CHECKPOINT1;
return STATUS_SECTION_PROTECTION;
}
@@ -4510,7 +4623,7 @@
{
/* Following this pointer would lead to us to the dark side */
/* What to do? Bugcheck? Return status? Do the mambo? */
- KEBUGCHECK(MEMORY_MANAGEMENT);
+ KeBugCheck(MEMORY_MANAGEMENT);
}
if (SectionOffset == NULL)
@@ -4588,30 +4701,7 @@
MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
IN MMFLUSH_TYPE FlushType)
{
-
- switch(FlushType)
- {
- case MmFlushForDelete:
- if (SectionObjectPointer->ImageSectionObject ||
- SectionObjectPointer->DataSectionObject)
- {
- return FALSE;
- }
- break;
-
- case MmFlushForWrite:
- break;
- }
-
-#if 0
- CcFlushCache
- (SectionObjectPointer,
- NULL,
- 0,
- NULL);
-#endif
-
- return FALSE;
+ return CcFlushImageSection(SectionObjectPointer, FlushType);
}
/*
@@ -4627,50 +4717,6 @@
}
-NTSTATUS STDCALL
-MmMapViewInSystemSpaceAtOffset
-(IN PVOID SectionObject,
- OUT PVOID *MappedBase,
- PLARGE_INTEGER FileOffset,
- IN OUT PULONG ViewSize)
-{
- PROS_SECTION_OBJECT Section;
- PMM_AVL_TABLE AddressSpace;
- NTSTATUS Status;
-
- DPRINT("MmMapViewInSystemSpaceAtOffset() called offset %x\n",
FileOffset->LowPart);
-
- Section = (PROS_SECTION_OBJECT)SectionObject;
- AddressSpace = MmGetKernelAddressSpace();
-
- MmLockAddressSpace(AddressSpace);
-
- if ((*ViewSize) == 0)
- {
- (*ViewSize) = Section->MaximumSize.u.LowPart;
- }
- else if ((*ViewSize) > Section->MaximumSize.u.LowPart)
- {
- (*ViewSize) = Section->MaximumSize.u.LowPart;
- }
-
- MmLockSectionSegment(Section->Segment);
-
- Status = MmMapViewOfSegment(AddressSpace,
- Section,
- Section->Segment,
- MappedBase,
- *ViewSize,
- PAGE_READWRITE,
- FileOffset->LowPart,
- 0);
-
- MmUnlockSectionSegment(Section->Segment);
- MmUnlockAddressSpace(AddressSpace);
-
- return Status;
-}
-
/*
* @implemented
*/
@@ -4690,6 +4736,7 @@
MmLockAddressSpace(AddressSpace);
+
if ((*ViewSize) == 0)
{
(*ViewSize) = Section->MaximumSize.u.LowPart;
@@ -4700,6 +4747,7 @@
}
MmLockSectionSegment(Section->Segment);
+
Status = MmMapViewOfSegment(AddressSpace,
Section,
@@ -4707,13 +4755,57 @@
MappedBase,
*ViewSize,
PAGE_READWRITE,
- 0,
+ 0,
0);
MmUnlockSectionSegment(Section->Segment);
MmUnlockAddressSpace(AddressSpace);
return Status;
+}
+
+NTSTATUS STDCALL
+MmMapViewInSystemSpaceAtOffset
+(IN PVOID SectionObject,
+ OUT PVOID *MappedBase,
+ PLARGE_INTEGER FileOffset,
+ IN OUT PULONG ViewSize)
+{
+ PROS_SECTION_OBJECT Section;
+ PMM_AVL_TABLE AddressSpace;
+ NTSTATUS Status;
+
+ DPRINT("MmMapViewInSystemSpaceAtOffset() called offset %x\n",
FileOffset->LowPart);
+
+ Section = (PROS_SECTION_OBJECT)SectionObject;
+ AddressSpace = MmGetKernelAddressSpace();
+
+ MmLockAddressSpace(AddressSpace);
+
+ if ((*ViewSize) == 0)
+ {
+ (*ViewSize) = Section->MaximumSize.u.LowPart;
+ }
+ else if ((*ViewSize) > Section->MaximumSize.u.LowPart)
+ {
+ (*ViewSize) = Section->MaximumSize.u.LowPart;
+ }
+
+ MmLockSectionSegment(Section->Segment);
+
+ Status = MmMapViewOfSegment(AddressSpace,
+ Section,
+ Section->Segment,
+ MappedBase,
+ *ViewSize,
+ PAGE_READWRITE,
+ FileOffset->LowPart,
+ 0);
+
+ MmUnlockSectionSegment(Section->Segment);
+ MmUnlockAddressSpace(AddressSpace);
+
+ return Status;
}
/*
@@ -4745,11 +4837,7 @@
AddressSpace = MmGetKernelAddressSpace();
- MmLockAddressSpace(AddressSpace);
-
Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
-
- MmUnlockAddressSpace(AddressSpace);
return Status;
}
@@ -4830,9 +4918,8 @@
* Handle to a file to create a section mapped to a file
* instead of a memory backed section;
*
- * FileObject
- * Specifies a FILE_OBJECT. If this isn't NULL, then FileHandle
- * is ignored.
+ * File
+ * Unknown.
*
* RETURN VALUE
* Status.
@@ -4846,100 +4933,104 @@
IN PLARGE_INTEGER MaximumSize,
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
- IN HANDLE FileHandle OPTIONAL,
- IN PFILE_OBJECT FileObject OPTIONAL)
-{
- PFILE_OBJECT OriginalFileObject = FileObject;
- ULONG Protection;
- NTSTATUS Status;
- ULONG FileAccess = 0;
- BOOLEAN ReferencedFile = FALSE;
- PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
-
- /*
- * Check the protection
- */
- Protection = SectionPageProtection & ~(PAGE_GUARD|PAGE_NOCACHE);
- if (Protection != PAGE_NOACCESS &&
- Protection != PAGE_READONLY &&
- Protection != PAGE_READWRITE &&
- Protection != PAGE_WRITECOPY &&
- Protection != PAGE_EXECUTE &&
- Protection != PAGE_EXECUTE_READ &&
- Protection != PAGE_EXECUTE_READWRITE &&
- Protection != PAGE_EXECUTE_WRITECOPY)
- {
- CHECKPOINT1;
- return STATUS_INVALID_PAGE_PROTECTION;
- }
-
- if ((DesiredAccess == SECTION_ALL_ACCESS ||
- (DesiredAccess & SECTION_MAP_WRITE)) &&
- (Protection == PAGE_READWRITE ||
- Protection == PAGE_EXECUTE_READWRITE))
- FileAccess = FILE_GENERIC_WRITE;
- else
- FileAccess = FILE_GENERIC_READ;
-
- /*
- * Reference the file handle
- */
- if (!FileObject && FileHandle)
- {
- Status = ObReferenceObjectByHandle(FileHandle,
- FileAccess,
- IoFileObjectType,
- ExGetPreviousMode(),
- (PVOID*)(PVOID)&FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Failed: %x\n", Status);
- return Status;
- }
- else
- ReferencedFile = TRUE;
- }
-
- if (AllocationAttributes & SEC_IMAGE)
- {
- DPRINT("Creating an image section\n");
- Status = MmCreateImageSection(SectionObject,
- DesiredAccess,
- ObjectAttributes,
- MaximumSize,
- SectionPageProtection,
- AllocationAttributes,
- FileObject);
- if (!NT_SUCCESS(Status))
- DPRINT("Failed: %x\n", Status);
- }
-
- else if (FileHandle != NULL || OriginalFileObject != NULL)
- {
- Status = MmCreateDataFileSection(SectionObject,
- DesiredAccess,
- ObjectAttributes,
- MaximumSize,
- SectionPageProtection,
- AllocationAttributes,
- FileObject);
- if (!NT_SUCCESS(Status))
- DPRINT("Failed: %x\n", Status);
- }
- else
- {
- Status = MmCreatePageFileSection(SectionObject,
- DesiredAccess,
- ObjectAttributes,
- MaximumSize,
- SectionPageProtection,
- AllocationAttributes);
- if (!NT_SUCCESS(Status))
- DPRINT("Failed: %x\n", Status);
- }
-
- return(Status);
+ IN HANDLE FileHandle OPTIONAL,
+ IN PFILE_OBJECT FileObject OPTIONAL)
+{
+ PFILE_OBJECT OriginalFileObject = FileObject;
+ ULONG Protection;
+ NTSTATUS Status;
+ ULONG FileAccess = 0;
+ BOOLEAN ReferencedFile = FALSE;
+ PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
+
+ /*
+ * Check the protection
+ */
+ Protection = SectionPageProtection & ~(PAGE_GUARD|PAGE_NOCACHE);
+ if (Protection != PAGE_NOACCESS &&
+ Protection != PAGE_READONLY &&
+ Protection != PAGE_READWRITE &&
+ Protection != PAGE_WRITECOPY &&
+ Protection != PAGE_EXECUTE &&
+ Protection != PAGE_EXECUTE_READ &&
+ Protection != PAGE_EXECUTE_READWRITE &&
+ Protection != PAGE_EXECUTE_WRITECOPY)
+ {
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
+
+ if ((DesiredAccess == SECTION_ALL_ACCESS ||
+ (DesiredAccess & SECTION_MAP_WRITE)) &&
+ (Protection == PAGE_READWRITE ||
+ Protection == PAGE_EXECUTE_READWRITE))
+ FileAccess = FILE_GENERIC_WRITE;
+ else
+ FileAccess = FILE_GENERIC_READ;
+
+ /*
+ * Reference the file handle
+ */
+ if (!FileObject && FileHandle)
+ {
+ Status = ObReferenceObjectByHandle
+ (FileHandle,
+ FileAccess,
+ IoFileObjectType,
+ ExGetPreviousMode(),
+ (PVOID*)(PVOID)&FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Failed: %x\n", Status);
+ return Status;
+ }
+ else
+ ReferencedFile = TRUE;
+ }
+
+ if (AllocationAttributes & SEC_IMAGE)
+ {
+ DPRINT("Creating an image section\n");
+ Status = MmCreateImageSection
+ (SectionObject,
+ DesiredAccess,
+ ObjectAttributes,
+ MaximumSize,
+ SectionPageProtection,
+ AllocationAttributes,
+ FileObject);
+ if (!NT_SUCCESS(Status))
+ DPRINT("Failed: %x\n", Status);
+ }
+ else if (FileHandle != NULL || OriginalFileObject != NULL)
+ {
+ DPRINT("Creating a data section\n");
+ Status = MmCreateDataFileSection
+ (SectionObject,
+ DesiredAccess,
+ ObjectAttributes,
+ MaximumSize,
+ SectionPageProtection,
+ AllocationAttributes,
+ FileObject);
+ if (!NT_SUCCESS(Status))
+ DPRINT("Failed: %x\n", Status);
+ }
+ else
+ {
+ DPRINT("Creating a page file section\n");
+ Status = MmCreatePageFileSection
+ (SectionObject,
+ DesiredAccess,
+ ObjectAttributes,
+ MaximumSize,
+ SectionPageProtection,
+ AllocationAttributes);
+ if (!NT_SUCCESS(Status))
+ DPRINT("Failed: %x\n", Status);
+ }
+
+ return(Status);
}
NTSTATUS