Author: cwittich
Date: Tue Feb 3 06:39:55 2009
New Revision: 39314
URL: http://svn.reactos.org/svn/reactos?rev=39314&view=rev
Log:
-check for filesize in MmCanFileBeTruncated
-make use of MmCanFileBeTruncated in VfatSetAllocationSizeInformation
-make use of MmCanFileBeTruncated in VfatSetInformation (patch by arty with some fixes from me)
thanks to Alex for the hint that we miss the MmCanFileBeTruncated check
fixes "Anyone has referenced a cache segment behind the new size."
See issue #712 for more details.
Modified:
trunk/reactos/drivers/filesystems/fastfat/finfo.c
trunk/reactos/ntoskrnl/mm/section.c
Modified: trunk/reactos/drivers/filesystems/fastfat/finfo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/finfo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/finfo.c [iso-8859-1] Tue Feb 3 06:39:55 2009
@@ -548,10 +548,7 @@
Fcb->RFCB.FileSize.QuadPart = Size;
Fcb->RFCB.ValidDataLength.QuadPart = Size;
- if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
- {
- CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
- }
+ CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
}
NTSTATUS
@@ -692,6 +689,17 @@
}
else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
{
+
+ DPRINT("Check for the ability to set file size\n");
+ if (!MmCanFileBeTruncated
+ (FileObject->SectionObjectPointer,
+ (PLARGE_INTEGER)AllocationSize))
+ {
+ DPRINT("Couldn't set file size!\n");
+ return STATUS_USER_MAPPED_FILE;
+ }
+ DPRINT("Can set file size\n");
+
AllocSizeChanged = TRUE;
/* FIXME: Use the cached cluster/offset better way. */
Fcb->LastCluster = Fcb->LastOffset = 0;
@@ -891,6 +899,26 @@
DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
+ /* Special: We should call MmCanFileBeTruncated here to determine if changing
+ the file size would be allowed. If not, we bail with the right error.
+ We must do this before acquiring the lock. */
+ if (FileInformationClass == FileEndOfFileInformation)
+ {
+ DPRINT("Check for the ability to set file size\n");
+ if (!MmCanFileBeTruncated
+ (IrpContext->FileObject->SectionObjectPointer,
+ (PLARGE_INTEGER)SystemBuffer))
+ {
+ DPRINT("Couldn't set file size!\n");
+ IrpContext->Irp->IoStatus.Status = STATUS_USER_MAPPED_FILE;
+ IrpContext->Irp->IoStatus.Information = 0;
+ IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
+ VfatFreeIrpContext(IrpContext);
+ return STATUS_USER_MAPPED_FILE;
+ }
+ DPRINT("Can set file size\n");
+ }
+
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource,
Modified: trunk/reactos/ntoskrnl/mm/section.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] Tue Feb 3 06:39:55 2009
@@ -4714,10 +4714,10 @@
MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
IN PLARGE_INTEGER NewFileSize)
{
-
/* Check whether an ImageSectionObject exists */
if (SectionObjectPointer->ImageSectionObject != NULL)
{
+ DPRINT1("ERROR: File can't be truncated because it has an image section\n");
return FALSE;
}
@@ -4730,15 +4730,29 @@
if (Segment->ReferenceCount != 0)
{
- /* FIXME: check if NewFileSize <= current file size */
+ /* Check size of file */
+ if (SectionObjectPointer->SharedCacheMap)
+ {
+ PBCB Bcb = SectionObjectPointer->SharedCacheMap;
+ if (NewFileSize->QuadPart <= Bcb->FileSize.QuadPart)
+ {
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* Something must gone wrong
+ * how can we have a Section but no
+ * reference? */
+ DPRINT1("ERROR: DataSectionObject without reference!\n");
return FALSE;
}
}
- /* FIXME: check for outstanding write probes */
- UNIMPLEMENTED;
-
- return FALSE;
+ DPRINT1("FIXME: didn't check for outstanding write probes\n");
+
+ return TRUE;
}