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/fastfat... ============================================================================== --- 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=3... ============================================================================== --- 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; }