示例#1
0
        private bool SplitAttribute(FileRecord record)
        {
            if (record.Attributes.Count != 1)
            {
                throw new InvalidOperationException("Attempting to split attribute in MFT record containing multiple attributes");
            }

            AttributeRecord targetAttr = record.FirstAttribute;

            if (targetAttr.AttributeType != AttributeType.Data)
            {
                throw new InvalidOperationException("Attempting to split non-Data attribute");
            }

            AttributeRecord newAttr = targetAttr.Split(record);

            // Find a home for the new attribute record
            FileRecord newAttrHome = null;

            foreach (var targetRecord in _records)
            {
                if (_mft.RecordSize - targetRecord.Size >= newAttr.Size)
                {
                    targetRecord.AddAttribute(newAttr);
                    newAttrHome = targetRecord;
                }
            }
            if (newAttrHome == null)
            {
                newAttrHome          = _mft.AllocateRecord(FileRecordFlags.None);
                newAttrHome.BaseFile = 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);
        }
示例#2
0
        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 (NtfsAttribute attr in _attributes)
            {
                attr.ReplaceExtent(oldRef, newRef, attrRec);
            }

            UpdateAttributeList();
        }
示例#3
0
文件: File.cs 项目: alexcmd/DiscUtils
        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();
        }
示例#4
0
        private bool SplitAttribute(FileRecord record, NonResidentAttributeRecord targetAttr, bool atStart)
        {
            if (targetAttr.DataRuns.Count <= 1)
            {
                return(false);
            }

            int splitIndex = 1;

            if (!atStart)
            {
                List <DataRun> runs = targetAttr.DataRuns;

                splitIndex = runs.Count - 1;
                int saved = runs[splitIndex].Size;
                while (splitIndex > 1 && record.Size - saved > record.AllocatedSize)
                {
                    --splitIndex;
                    saved += runs[splitIndex].Size;
                }
            }

            AttributeRecord newAttr = targetAttr.Split(splitIndex);

            // Find a home for the new attribute record
            FileRecord newAttrHome = null;

            foreach (FileRecord 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 (NtfsAttribute attr in _attributes)
            {
                foreach (KeyValuePair <AttributeReference, AttributeRecord> 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);
        }