mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 18:11:57 +00:00
[NTFS] - Add support for directory creation. Add some helper functions, some comments, and some fixes.
+AddIndexRoot() - Creates an $INDEX_ROOT attribute and adds it to a file record. AddNewMftEntry() - Make sure the buffer used by RtlInitializeBitmap() is ULONG-aligned, and a ULONG-multiple in size, per MSDN. AllocateIndexNode() - Calculate BytesNeeded correctly. Read $BITMAP attribute before increasing its length, in anticipation of a future commit that will check for a free bit before assigning a new index record to the end of the allocation. Use appropriate Set*AttributeDataLength() function, as $BITMAP can be resident or non-resident. B_TREE_FILENAME_NODE - Give two members more accurate names: change "ExistsOnDisk" member to "HasValidVCN" and rename "NodeNumber" member "VCN." +CreateEmptyBTree() - Creates a B-Tree to represent an empty directory (for AddIndexRoot). +NtfsCreateEmptyFileRecord() - Creates an empty file record in memory, with no attributes. CreateIndexRootFromBTree() - Fix TotalSizeOfEntries calculation. +NtfsCreateDirectory() - Creates a file record for an empty directory and adds it to the mft. svn path=/branches/GSoC_2016/NTFS/; revision=75692
This commit is contained in:
parent
c63e7e54b5
commit
b033f00f58
5 changed files with 542 additions and 113 deletions
|
@ -167,7 +167,11 @@ AddFileName(PFILE_RECORD_HEADER FileRecord,
|
|||
FileNameAttribute->LastWriteTime = SystemTime.QuadPart;
|
||||
FileNameAttribute->LastAccessTime = SystemTime.QuadPart;
|
||||
|
||||
FileNameAttribute->FileAttributes = NTFS_FILE_TYPE_ARCHIVE;
|
||||
// Is this a directory?
|
||||
if(FileRecord->Flags & FRH_DIRECTORY)
|
||||
FileNameAttribute->FileAttributes = NTFS_FILE_TYPE_DIRECTORY;
|
||||
else
|
||||
FileNameAttribute->FileAttributes = NTFS_FILE_TYPE_ARCHIVE;
|
||||
|
||||
// we need to extract the filename from the path
|
||||
DPRINT1("Pathname: %wZ\n", &FileObject->FileName);
|
||||
|
@ -254,6 +258,112 @@ AddFileName(PFILE_RECORD_HEADER FileRecord,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name AddIndexRoot
|
||||
* @implemented
|
||||
*
|
||||
* Adds an $INDEX_ROOT attribute to a given FileRecord.
|
||||
*
|
||||
* @param Vcb
|
||||
* Pointer to an NTFS_VCB for the destination volume.
|
||||
*
|
||||
* @param FileRecord
|
||||
* Pointer to a complete file record to add the attribute to. Caller is responsible for
|
||||
* ensuring FileRecord is large enough to contain $INDEX_ROOT.
|
||||
*
|
||||
* @param AttributeAddress
|
||||
* Pointer to the region of memory that will receive the $INDEX_ROOT attribute.
|
||||
* This address must reside within FileRecord. Must be aligned to an 8-byte boundary (relative to FileRecord).
|
||||
*
|
||||
* @param NewIndexRoot
|
||||
* Pointer to an INDEX_ROOT_ATTRIBUTE containing the index root that will be copied to the new attribute.
|
||||
*
|
||||
* @param RootLength
|
||||
* The length of NewIndexRoot, in bytes.
|
||||
*
|
||||
* @param Name
|
||||
* Pointer to a string of 16-bit Unicode characters naming the attribute. Most often, this will be L"$I30".
|
||||
*
|
||||
* @param NameLength
|
||||
* The number of wide-characters in the name. L"$I30" Would use 4 here.
|
||||
*
|
||||
* @return
|
||||
* STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end
|
||||
* of the given file record.
|
||||
*
|
||||
* @remarks
|
||||
* This function is intended to assist in creating new folders.
|
||||
* Only adding the attribute to the end of the file record is supported; AttributeAddress must
|
||||
* be of type AttributeEnd.
|
||||
* It's the caller's responsibility to ensure the given file record has enough memory allocated
|
||||
* for the attribute, and this memory must have been zeroed.
|
||||
*/
|
||||
NTSTATUS
|
||||
AddIndexRoot(PNTFS_VCB Vcb,
|
||||
PFILE_RECORD_HEADER FileRecord,
|
||||
PNTFS_ATTR_RECORD AttributeAddress,
|
||||
PINDEX_ROOT_ATTRIBUTE NewIndexRoot,
|
||||
ULONG RootLength,
|
||||
PCWSTR Name,
|
||||
USHORT NameLength)
|
||||
{
|
||||
ULONG AttributeLength;
|
||||
// Calculate the header length
|
||||
ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
|
||||
// Back up the file record's final ULONG (even though it doesn't matter)
|
||||
ULONG FileRecordEnd = AttributeAddress->Length;
|
||||
ULONG NameOffset;
|
||||
ULONG ValueOffset;
|
||||
ULONG BytesAvailable;
|
||||
|
||||
if (AttributeAddress->Type != AttributeEnd)
|
||||
{
|
||||
DPRINT1("FIXME: Can only add $DATA attribute to the end of a file record.\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NameOffset = ResidentHeaderLength;
|
||||
|
||||
// Calculate ValueOffset, which will be aligned to a 4-byte boundary
|
||||
ValueOffset = ALIGN_UP_BY(NameOffset + (sizeof(WCHAR) * NameLength), VALUE_OFFSET_ALIGNMENT);
|
||||
|
||||
// Calculate length of attribute
|
||||
AttributeLength = ValueOffset + RootLength;
|
||||
AttributeLength = ALIGN_UP_BY(AttributeLength, ATTR_RECORD_ALIGNMENT);
|
||||
|
||||
// Make sure the file record is large enough for the new attribute
|
||||
BytesAvailable = Vcb->NtfsInfo.BytesPerFileRecord - FileRecord->BytesInUse;
|
||||
if (BytesAvailable < AttributeLength)
|
||||
{
|
||||
DPRINT1("FIXME: Not enough room in file record for index allocation attribute!\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Set Attribute fields
|
||||
RtlZeroMemory(AttributeAddress, AttributeLength);
|
||||
|
||||
AttributeAddress->Type = AttributeIndexRoot;
|
||||
AttributeAddress->Length = AttributeLength;
|
||||
AttributeAddress->NameLength = NameLength;
|
||||
AttributeAddress->NameOffset = NameOffset;
|
||||
AttributeAddress->Instance = FileRecord->NextAttributeNumber++;
|
||||
|
||||
AttributeAddress->Resident.ValueLength = RootLength;
|
||||
AttributeAddress->Resident.ValueOffset = ValueOffset;
|
||||
|
||||
// Set the name
|
||||
RtlCopyMemory((PCHAR)((ULONG_PTR)AttributeAddress + NameOffset), Name, NameLength * sizeof(WCHAR));
|
||||
|
||||
// Copy the index root attribute
|
||||
RtlCopyMemory((PCHAR)((ULONG_PTR)AttributeAddress + ValueOffset), NewIndexRoot, RootLength);
|
||||
|
||||
// move the attribute-end and file-record-end markers to the end of the file record
|
||||
AttributeAddress = (PNTFS_ATTR_RECORD)((ULONG_PTR)AttributeAddress + AttributeAddress->Length);
|
||||
SetFileRecordEnd(FileRecord, AttributeAddress, FileRecordEnd);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name AddRun
|
||||
* @implemented
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue