mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 12:02:02 +00:00
[NTFS] - Refactor to allow the copy of the attribute stored in NTFS_ATTR_CONTEXT to have a dynamic length; change Record member from an NTFS_ATTR_RECORD to a PNTFS_ATTR_RECORD. Rename it pRecord to reinforce the change. Fix some bugs related to the record size changing.
-PrepareAttributeContext() - update to allocate memory for pRecord. Don't assume allocations are succeeding. -ReleaseAttributeContext() - update to free memory for pRecord. -InternalSetResidentAttributeLength() - Increase size of AttrContext->pRecord as needed. Update to return an NTSTATUS. -SetResidentAttributeDataLength() - Fix bug that could occur when migrating resident attributes to non-resident if AttrContext->pRecord is too small for the new attribute. -AddRun() - Fix a bug by reallocating AttrContext->pRecord if the record needs to be enlarged. svn path=/branches/GSoC_2016/NTFS/; revision=75493
This commit is contained in:
parent
f2e47474f0
commit
4dfcd1d582
10 changed files with 216 additions and 120 deletions
|
@ -303,17 +303,17 @@ AddRun(PNTFS_VCB Vcb,
|
|||
NTSTATUS Status;
|
||||
int DataRunMaxLength;
|
||||
PNTFS_ATTR_RECORD DestinationAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + AttrOffset);
|
||||
ULONG NextAttributeOffset = AttrOffset + AttrContext->Record.Length;
|
||||
ULONG NextAttributeOffset = AttrOffset + AttrContext->pRecord->Length;
|
||||
ULONGLONG NextVBN = 0;
|
||||
|
||||
PUCHAR RunBuffer;
|
||||
ULONG RunBufferSize;
|
||||
|
||||
if (!AttrContext->Record.IsNonResident)
|
||||
if (!AttrContext->pRecord->IsNonResident)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (AttrContext->Record.NonResident.AllocatedSize != 0)
|
||||
NextVBN = AttrContext->Record.NonResident.HighestVCN + 1;
|
||||
if (AttrContext->pRecord->NonResident.AllocatedSize != 0)
|
||||
NextVBN = AttrContext->pRecord->NonResident.HighestVCN + 1;
|
||||
|
||||
// Add newly-assigned clusters to mcb
|
||||
_SEH2_TRY
|
||||
|
@ -344,12 +344,14 @@ AddRun(PNTFS_VCB Vcb,
|
|||
ConvertLargeMCBToDataRuns(&AttrContext->DataRunsMCB, RunBuffer, Vcb->NtfsInfo.BytesPerCluster, &RunBufferSize);
|
||||
|
||||
// Get the amount of free space between the start of the of the first data run and the attribute end
|
||||
DataRunMaxLength = AttrContext->Record.Length - AttrContext->Record.NonResident.MappingPairsOffset;
|
||||
DataRunMaxLength = AttrContext->pRecord->Length - AttrContext->pRecord->NonResident.MappingPairsOffset;
|
||||
|
||||
// Do we need to extend the attribute (or convert to attribute list)?
|
||||
if (DataRunMaxLength < RunBufferSize)
|
||||
{
|
||||
PNTFS_ATTR_RECORD NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + NextAttributeOffset);
|
||||
PNTFS_ATTR_RECORD NewRecord;
|
||||
|
||||
DataRunMaxLength += Vcb->NtfsInfo.BytesPerFileRecord - NextAttributeOffset - (sizeof(ULONG) * 2);
|
||||
|
||||
// Can we move the end of the attribute?
|
||||
|
@ -363,12 +365,22 @@ AddRun(PNTFS_VCB Vcb,
|
|||
}
|
||||
|
||||
// calculate position of end markers
|
||||
NextAttributeOffset = AttrOffset + AttrContext->Record.NonResident.MappingPairsOffset + RunBufferSize;
|
||||
NextAttributeOffset = AttrOffset + AttrContext->pRecord->NonResident.MappingPairsOffset + RunBufferSize;
|
||||
NextAttributeOffset = ALIGN_UP_BY(NextAttributeOffset, ATTR_RECORD_ALIGNMENT);
|
||||
|
||||
// Update the length
|
||||
// Update the length of the destination attribute
|
||||
DestinationAttribute->Length = NextAttributeOffset - AttrOffset;
|
||||
AttrContext->Record.Length = DestinationAttribute->Length;
|
||||
|
||||
// Create a new copy of the attribute
|
||||
NewRecord = ExAllocatePoolWithTag(NonPagedPool, DestinationAttribute->Length, TAG_NTFS);
|
||||
RtlCopyMemory(NewRecord, AttrContext->pRecord, AttrContext->pRecord->Length);
|
||||
NewRecord->Length = DestinationAttribute->Length;
|
||||
|
||||
// Free the old copy of the attribute, which won't be large enough
|
||||
ExFreePoolWithTag(AttrContext->pRecord, TAG_NTFS);
|
||||
|
||||
// Set the attribute context's record to the new copy
|
||||
AttrContext->pRecord = NewRecord;
|
||||
|
||||
// End the file record
|
||||
NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + NextAttributeOffset);
|
||||
|
@ -377,14 +389,19 @@ AddRun(PNTFS_VCB Vcb,
|
|||
|
||||
// Update HighestVCN
|
||||
DestinationAttribute->NonResident.HighestVCN =
|
||||
AttrContext->Record.NonResident.HighestVCN = max(NextVBN - 1 + RunLength,
|
||||
AttrContext->Record.NonResident.HighestVCN);
|
||||
AttrContext->pRecord->NonResident.HighestVCN = max(NextVBN - 1 + RunLength,
|
||||
AttrContext->pRecord->NonResident.HighestVCN);
|
||||
|
||||
// Write data runs to destination attribute
|
||||
RtlCopyMemory((PVOID)((ULONG_PTR)DestinationAttribute + DestinationAttribute->NonResident.MappingPairsOffset),
|
||||
RunBuffer,
|
||||
RunBufferSize);
|
||||
|
||||
// Update the attribute copy in the attribute context
|
||||
RtlCopyMemory((PVOID)((ULONG_PTR)AttrContext->pRecord + AttrContext->pRecord->NonResident.MappingPairsOffset),
|
||||
RunBuffer,
|
||||
RunBufferSize);
|
||||
|
||||
// Update the file record
|
||||
Status = UpdateFileRecord(Vcb, AttrContext->FileMFTIndex, FileRecord);
|
||||
|
||||
|
@ -723,7 +740,7 @@ FreeClusters(PNTFS_VCB Vcb,
|
|||
ULONG ClustersLeftToFree = ClustersToFree;
|
||||
|
||||
PNTFS_ATTR_RECORD DestinationAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + AttrOffset);
|
||||
ULONG NextAttributeOffset = AttrOffset + AttrContext->Record.Length;
|
||||
ULONG NextAttributeOffset = AttrOffset + AttrContext->pRecord->Length;
|
||||
PNTFS_ATTR_RECORD NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + NextAttributeOffset);
|
||||
|
||||
PUCHAR RunBuffer;
|
||||
|
@ -736,7 +753,7 @@ FreeClusters(PNTFS_VCB Vcb,
|
|||
RTL_BITMAP Bitmap;
|
||||
ULONG LengthWritten;
|
||||
|
||||
if (!AttrContext->Record.IsNonResident)
|
||||
if (!AttrContext->pRecord->IsNonResident)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -767,7 +784,7 @@ FreeClusters(PNTFS_VCB Vcb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
BitmapDataSize = AttributeDataLength(&DataContext->Record);
|
||||
BitmapDataSize = AttributeDataLength(DataContext->pRecord);
|
||||
BitmapDataSize = min(BitmapDataSize, ULONG_MAX);
|
||||
ASSERT((BitmapDataSize * 8) >= Vcb->NtfsInfo.ClusterCount);
|
||||
BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, Vcb->NtfsInfo.BytesPerSector), TAG_NTFS);
|
||||
|
@ -802,10 +819,10 @@ FreeClusters(PNTFS_VCB Vcb,
|
|||
// deallocate this cluster
|
||||
RtlClearBits(&Bitmap, LargeLbn, 1);
|
||||
}
|
||||
FsRtlTruncateLargeMcb(&AttrContext->DataRunsMCB, AttrContext->Record.NonResident.HighestVCN);
|
||||
FsRtlTruncateLargeMcb(&AttrContext->DataRunsMCB, AttrContext->pRecord->NonResident.HighestVCN);
|
||||
|
||||
// decrement HighestVCN, but don't let it go below 0
|
||||
AttrContext->Record.NonResident.HighestVCN = min(AttrContext->Record.NonResident.HighestVCN, AttrContext->Record.NonResident.HighestVCN - 1);
|
||||
AttrContext->pRecord->NonResident.HighestVCN = min(AttrContext->pRecord->NonResident.HighestVCN, AttrContext->pRecord->NonResident.HighestVCN - 1);
|
||||
ClustersLeftToFree--;
|
||||
}
|
||||
|
||||
|
@ -837,7 +854,7 @@ FreeClusters(PNTFS_VCB Vcb,
|
|||
ConvertLargeMCBToDataRuns(&AttrContext->DataRunsMCB, RunBuffer, Vcb->NtfsInfo.BytesPerCluster, &RunBufferSize);
|
||||
|
||||
// Update HighestVCN
|
||||
DestinationAttribute->NonResident.HighestVCN = AttrContext->Record.NonResident.HighestVCN;
|
||||
DestinationAttribute->NonResident.HighestVCN = AttrContext->pRecord->NonResident.HighestVCN;
|
||||
|
||||
// Write data runs to destination attribute
|
||||
RtlCopyMemory((PVOID)((ULONG_PTR)DestinationAttribute + DestinationAttribute->NonResident.MappingPairsOffset),
|
||||
|
@ -848,9 +865,12 @@ FreeClusters(PNTFS_VCB Vcb,
|
|||
if (NextAttribute->Type == AttributeEnd)
|
||||
{
|
||||
// update attribute length
|
||||
AttrContext->Record.Length = ALIGN_UP_BY(AttrContext->Record.NonResident.MappingPairsOffset + RunBufferSize,
|
||||
DestinationAttribute->Length = ALIGN_UP_BY(AttrContext->pRecord->NonResident.MappingPairsOffset + RunBufferSize,
|
||||
ATTR_RECORD_ALIGNMENT);
|
||||
DestinationAttribute->Length = AttrContext->Record.Length;
|
||||
|
||||
ASSERT(DestinationAttribute->Length <= AttrContext->pRecord->Length);
|
||||
|
||||
AttrContext->pRecord->Length = DestinationAttribute->Length;
|
||||
|
||||
// write end markers
|
||||
NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)DestinationAttribute + DestinationAttribute->Length);
|
||||
|
@ -893,7 +913,7 @@ InternalReadNonResidentAttributes(PFIND_ATTR_CONTXT Context)
|
|||
}
|
||||
|
||||
ListContext = PrepareAttributeContext(Attribute);
|
||||
ListSize = AttributeDataLength(&ListContext->Record);
|
||||
ListSize = AttributeDataLength(ListContext->pRecord);
|
||||
if (ListSize > 0xFFFFFFFF)
|
||||
{
|
||||
ReleaseAttributeContext(ListContext);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue