https://git.reactos.org/?p=reactos.git;a=commitdiff;h=84a1280fd6a4572894bbb70fac70c455958e6d02

commit 84a1280fd6a4572894bbb70fac70c455958e6d02
Author: Trevor Thompson <[email protected]>
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

Reply via email to