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
This commit is contained in:
Trevor Thompson 2016-06-26 21:06:02 +00:00 committed by Thomas Faber
parent f47efca89f
commit 84a1280fd6

View 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