private void MoveAttribute(FileRecord record, AttributeRecord attrRec, FileRecord targetRecord) { AttributeReference oldRef = new AttributeReference(record.Reference, attrRec.AttributeId); record.RemoveAttribute(attrRec.AttributeId); targetRecord.AddAttribute(attrRec); AttributeReference newRef = new AttributeReference(targetRecord.Reference, attrRec.AttributeId); foreach (var attr in _attributes) { attr.ReplaceExtent(oldRef, newRef, attrRec); } UpdateAttributeList(); }
private bool SplitAttribute(FileRecord record, NonResidentAttributeRecord targetAttr, bool atStart) { if (targetAttr.DataRuns.Count <= 1) { return(false); } int splitIndex = 1; if (!atStart) { // Approximation only - assumes each run is at least one byte saved. Could calculate the // actual index here. splitIndex = (int)(targetAttr.DataRuns.Count - (record.Size - record.AllocatedSize)); } AttributeRecord newAttr = targetAttr.Split(splitIndex); // Find a home for the new attribute record FileRecord newAttrHome = null; foreach (var targetRecord in _records) { if (!targetRecord.IsMftRecord && _mft.RecordSize - targetRecord.Size >= newAttr.Size) { targetRecord.AddAttribute(newAttr); newAttrHome = targetRecord; } } if (newAttrHome == null) { newAttrHome = _mft.AllocateRecord(_records[0].Flags & (~FileRecordFlags.InUse), record.IsMftRecord); newAttrHome.BaseFile = record.BaseFile.IsNull ? record.Reference : record.BaseFile; _records.Add(newAttrHome); newAttrHome.AddAttribute(newAttr); } // Add the new attribute record as an extent on the attribute it split from bool added = false; foreach (var attr in _attributes) { foreach (var existingRecord in attr.Extents) { if (existingRecord.Key.File == record.Reference && existingRecord.Key.AttributeId == targetAttr.AttributeId) { attr.AddExtent(newAttrHome.Reference, newAttr); added = true; break; } } if (added) { break; } } UpdateAttributeList(); return(true); }