When writing to a file, increase the file size if trying to write past the end.
*FindAttribute() has been given an optional pointer to a ULONG that will receive the offset of the found attribute from the beginning of the record. This is to allow for found attributes to be written back into their file records.
+SetAttributeDataLength()
+UpdateFileRecord() - Updates a file record in the master file table at a given index.
+AddFixupArray() - Prepares a file record or directory index for writing to the disk.

svn path=/branches/GSoC_2016/NTFS/; revision=71660
This commit is contained in:
Trevor Thompson 2016-06-22 21:20:50 +00:00 committed by Thomas Faber
parent ea6b9622c4
commit ba33b9faac
8 changed files with 226 additions and 29 deletions

View file

@ -95,7 +95,7 @@ NtfsReadFile(PDEVICE_EXTENSION DeviceExt,
}
Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext);
Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext, NULL);
if (!NT_SUCCESS(Status))
{
NTSTATUS BrowseStatus;
@ -309,6 +309,7 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt,
PNTFS_FCB Fcb;
PFILE_RECORD_HEADER FileRecord;
PNTFS_ATTR_CONTEXT DataContext;
ULONG AttributeOffset;
ULONGLONG StreamSize;
DPRINT("NtfsWriteFile(%p, %p, %p, %u, %u, %x, %p)\n", DeviceExt, FileObject, Buffer, Length, WriteOffset, IrpFlags, LengthWritten);
@ -361,9 +362,10 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt,
DPRINT("Found record for %wS\n", Fcb->ObjectName);
// Find the attribute (in the NTFS sense of the word) with the data stream for our file
// Find the attribute with the data stream for our file
DPRINT("Finding Data Attribute...\n");
Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext);
Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext,
&AttributeOffset);
// Did we fail to find the attribute?
if (!NT_SUCCESS(Status))
@ -405,13 +407,39 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt,
// Are we trying to write beyond the end of the stream?
if (WriteOffset + Length > StreamSize)
{
// TODO: allocate additional clusters as needed and expand stream
DPRINT1("WriteOffset: %lu\tLength: %lu\tStreamSize: %I64u\n", WriteOffset, Length, StreamSize);
DPRINT1("TODO: Stream embiggening (appending files) is not yet supported!\n");
ReleaseAttributeContext(DataContext);
ExFreePoolWithTag(FileRecord, TAG_NTFS);
*LengthWritten = 0; // We didn't write anything
return STATUS_ACCESS_DENIED; // temporarily; we don't change file sizes yet
// is increasing the stream size allowed?
if (!(Fcb->Flags & FCB_IS_VOLUME) &&
!(IrpFlags & IRP_PAGING_IO))
{
LARGE_INTEGER DataSize;
ULONGLONG AllocationSize;
DataSize.QuadPart = WriteOffset + Length;
AllocationSize = ROUND_UP(DataSize.QuadPart, Fcb->Vcb->NtfsInfo.BytesPerCluster);
// set the attribute data length
Status = SetAttributeDataLength(FileObject, Fcb, DataContext, AttributeOffset, FileRecord, DeviceExt, &DataSize);
if (!NT_SUCCESS(Status))
{
ReleaseAttributeContext(DataContext);
ExFreePoolWithTag(FileRecord, TAG_NTFS);
*LengthWritten = 0;
return Status;
}
// now we need to update this file's size in every directory index entry that references it
// (saved for a later commit)
}
else
{
// TODO - just fail for now
ReleaseAttributeContext(DataContext);
ExFreePoolWithTag(FileRecord, TAG_NTFS);
*LengthWritten = 0;
return STATUS_ACCESS_DENIED;
}
}
DPRINT("Length: %lu\tWriteOffset: %lu\tStreamSize: %I64u\n", Length, WriteOffset, StreamSize);