From 84a1280fd6a4572894bbb70fac70c455958e6d02 Mon Sep 17 00:00:00 2001 From: Trevor Thompson Date: Sun, 26 Jun 2016 21:06:02 +0000 Subject: [PATCH] [NTFS] Allow for an existing file to be opened with FILE_OVERWRITE, FILE_OVERWRITE_IF, or FILE_SUPERSEDE dispositions, and truncate that file. This allows for a file to be opened and saved in Notepad.exe [provided that file is non-resident and its allocation size doesn't need to change]. svn path=/branches/GSoC_2016/NTFS/; revision=71680 --- drivers/filesystems/ntfs/create.c | 60 ++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/drivers/filesystems/ntfs/create.c b/drivers/filesystems/ntfs/create.c index 5662806880c..344c16464ff 100644 --- a/drivers/filesystems/ntfs/create.c +++ b/drivers/filesystems/ntfs/create.c @@ -476,14 +476,66 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject, return Status; } - /* HUGLY HACK: Can't overwrite or supersede a file yet... */ if (RequestedDisposition == FILE_OVERWRITE || RequestedDisposition == FILE_OVERWRITE_IF || RequestedDisposition == FILE_SUPERSEDE) { - DPRINT1("Cannot yet perform an overwrite or supersede request on NTFS volume\n"); - NtfsCloseFile(DeviceExt, FileObject); - return STATUS_ACCESS_DENIED; + PFILE_RECORD_HEADER fileRecord = NULL; + PNTFS_ATTR_CONTEXT dataContext = NULL; + ULONG DataAttributeOffset; + LARGE_INTEGER Zero; + Zero.QuadPart = 0; + + // TODO: check for appropriate access + + ExAcquireResourceExclusiveLite(&(Fcb->MainResource), TRUE); + + fileRecord = ExAllocatePoolWithTag(NonPagedPool, + Fcb->Vcb->NtfsInfo.BytesPerFileRecord, + TAG_NTFS); + if (fileRecord) + { + + Status = ReadFileRecord(Fcb->Vcb, + Fcb->MFTIndex, + fileRecord); + if (!NT_SUCCESS(Status)) + goto DoneOverwriting; + + // find the data attribute and set it's length to 0 (TODO: Handle Alternate Data Streams) + Status = FindAttribute(Fcb->Vcb, fileRecord, AttributeData, L"", 0, &dataContext, &DataAttributeOffset); + if (!NT_SUCCESS(Status)) + goto DoneOverwriting; + + Status = SetAttributeDataLength(FileObject, Fcb, dataContext, DataAttributeOffset, fileRecord, &Zero); + } + else + { + Status = STATUS_NO_MEMORY; + } + + DoneOverwriting: + if (fileRecord) + ExFreePool(fileRecord); + if (dataContext) + ReleaseAttributeContext(dataContext); + + ExReleaseResourceLite(&(Fcb->MainResource)); + + if (!NT_SUCCESS(Status)) + { + NtfsCloseFile(DeviceExt, FileObject); + return Status; + } + + if (RequestedDisposition == FILE_SUPERSEDE) + { + Irp->IoStatus.Information = FILE_SUPERSEDED; + } + else + { + Irp->IoStatus.Information = FILE_OVERWRITTEN; + } } } else