[NTFS]
authorTrevor Thompson <tmt256@email.vccs.edu>
Sun, 26 Jun 2016 21:06:02 +0000 (21:06 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 10 Dec 2017 10:13:31 +0000 (11:13 +0100)
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

index 5662806..344c164 100644 (file)
@@ -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