https://git.reactos.org/?p=reactos.git;a=commitdiff;h=84a1280fd6a4572894bbb…
commit 84a1280fd6a4572894bbb70fac70c455958e6d02
Author: Trevor Thompson <tmt256(a)email.vccs.edu>
AuthorDate: Sun Jun 26 21:06:02 2016 +0000
[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 5662806880..344c16464f 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