Пример #1
0
 /// <summary>
 /// Adds an existing attribute.
 /// </summary>
 /// <param name="attrRec">The attribute to add</param>
 /// <returns>The new Id of the attribute</returns>
 /// <remarks>This method is used to move an attribute between different MFT records</remarks>
 internal ushort AddAttribute(AttributeRecord attrRec)
 {
     attrRec.AttributeId = _nextAttributeId++;
     _attributes.Add(attrRec);
     _attributes.Sort();
     return(attrRec.AttributeId);
 }
Пример #2
0
        private bool ExpelAttribute(FileRecord record)
        {
            List <AttributeRecord> attrs = record.Attributes;

            for (int i = attrs.Count - 1; i >= 0; --i)
            {
                AttributeRecord attr = attrs[i];
                if (attr.AttributeType > AttributeType.AttributeList)
                {
                    foreach (var targetRecord in _records)
                    {
                        if (_mft.RecordSize - targetRecord.Size >= attr.Size)
                        {
                            MoveAttribute(record, attr, targetRecord);
                            return(true);
                        }
                    }

                    FileRecord newFileRecord = _mft.AllocateRecord(FileRecordFlags.None);
                    newFileRecord.BaseFile = record.Reference;
                    _records.Add(newFileRecord);
                    MoveAttribute(record, attr, newFileRecord);
                    return(true);
                }
            }

            return(false);
        }
Пример #3
0
 /// <summary>
 /// Adds an existing attribute.
 /// </summary>
 /// <param name="attrRec">The attribute to add.</param>
 /// <returns>The new Id of the attribute.</returns>
 /// <remarks>This method is used to move an attribute between different MFT records.</remarks>
 public ushort AddAttribute(AttributeRecord attrRec)
 {
     attrRec.AttributeId = NextAttributeId++;
     Attributes.Add(attrRec);
     Attributes.Sort();
     return(attrRec.AttributeId);
 }
Пример #4
0
 public void SetExtent(FileRecordReference containingFile, AttributeRecord record)
 {
     _containingFile = containingFile;
     _record         = record;
     _extents.Clear();
     _extents.Add(new AttributeReference(containingFile, record.AttributeId), record);
 }
Пример #5
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);
        }
Пример #6
0
        protected override void Read(byte[] buffer, int offset)
        {
            LogFileSequenceNumber = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x08);
            SequenceNumber        = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x10);
            HardLinkCount         = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x12);
            _firstAttributeOffset = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x14);
            Flags           = (FileRecordFlags)EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x16);
            RealSize        = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x18);
            AllocatedSize   = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x1C);
            BaseFile        = new FileRecordReference(EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x20));
            NextAttributeId = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x28);

            if (UpdateSequenceOffset >= 0x30)
            {
                _index     = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x2C);
                _haveIndex = true;
            }

            Attributes = new List <AttributeRecord>();
            int focus = _firstAttributeOffset;

            while (true)
            {
                int             length;
                AttributeRecord attr = AttributeRecord.FromBytes(buffer, focus, out length);
                if (attr == null)
                {
                    break;
                }

                Attributes.Add(attr);
                focus += length;
            }
        }
Пример #7
0
 protected NtfsAttribute(File file, FileRecordReference containingFile, AttributeRecord record)
 {
     _file           = file;
     _containingFile = containingFile;
     _primaryRecord  = record;
     _extents        = new Dictionary <AttributeReference, AttributeRecord>();
     _extents.Add(new AttributeReference(containingFile, record.AttributeId), _primaryRecord);
 }
Пример #8
0
 public void SetExtent(FileRecordReference containingFile, AttributeRecord record)
 {
     _cachedRawBuffer = null;
     _containingFile  = containingFile;
     _primaryRecord   = record;
     _extents.Clear();
     _extents.Add(new AttributeReference(containingFile, record.AttributeId), record);
 }
Пример #9
0
        internal void Delete()
        {
            if (_records[0].HardLinkCount != 0)
            {
                throw new InvalidOperationException("Attempt to delete in-use file: " + ToString());
            }

            NtfsStream objIdStream = GetStream(AttributeType.ObjectId, null);

            if (objIdStream != null)
            {
                ObjectId objId = objIdStream.GetContent <ObjectId>();
                Context.ObjectIds.Remove(objId.Id);
            }

            foreach (var attr in _attributes)
            {
                attr.GetDataBuffer().SetCapacity(0);
            }

            AttributeRecord attrListRec = _records[0].GetAttribute(AttributeType.AttributeList);

            if (attrListRec != null)
            {
                StructuredNtfsAttribute <AttributeList> attrList = (StructuredNtfsAttribute <AttributeList>)GetAttribute(new AttributeReference(MftReference, attrListRec.AttributeId));
                foreach (var record in attrList.Content)
                {
                    FileRecord attrFileRecord = _records[0];
                    if (record.BaseFileReference.MftIndex != _records[0].MasterFileTableIndex)
                    {
                        attrFileRecord = _context.Mft.GetRecord(record.BaseFileReference);
                    }

                    if (attrFileRecord != null)
                    {
                        attrFileRecord.RemoveAttribute(record.AttributeId);
                        if (attrFileRecord.Attributes.Count == 0)
                        {
                            _context.Mft.RemoveRecord(record.BaseFileReference);
                        }
                    }
                }
            }

            List <AttributeRecord> records = new List <AttributeRecord>(_records[0].Attributes);

            foreach (var record in records)
            {
                _records[0].RemoveAttribute(record.AttributeId);
            }

            _attributes.Clear();

            _context.Mft.RemoveRecord(MftReference);
            _context.ForgetFile(this);
        }
Пример #10
0
        public override int Read(long pos, byte[] buffer, int offset, int count)
        {
            AttributeRecord record = _attribute.PrimaryRecord;

            if (!CanRead)
            {
                throw new IOException("Attempt to read from file not opened for read");
            }

            StreamUtilities.AssertBufferParameters(buffer, offset, count);

            if (pos >= Capacity)
            {
                return(0);
            }

            // Limit read to length of attribute
            int totalToRead = (int)Math.Min(count, Capacity - pos);
            int toRead      = totalToRead;

            // Handle uninitialized bytes at end of attribute
            if (pos + totalToRead > record.InitializedDataLength)
            {
                if (pos >= record.InitializedDataLength)
                {
                    // We're just reading zero bytes from the uninitialized area
                    Array.Clear(buffer, offset, totalToRead);
                    pos += totalToRead;
                    return(totalToRead);
                }

                // Partial read of uninitialized area
                Array.Clear(buffer, offset + (int)(record.InitializedDataLength - pos),
                            (int)(pos + toRead - record.InitializedDataLength));
                toRead = (int)(record.InitializedDataLength - pos);
            }

            int numRead = 0;

            while (numRead < toRead)
            {
                IBuffer extentBuffer = _attribute.RawBuffer;

                int justRead = extentBuffer.Read(pos + numRead, buffer, offset + numRead, toRead - numRead);
                if (justRead == 0)
                {
                    break;
                }

                numRead += justRead;
            }

            return(totalToRead);
        }
Пример #11
0
        /// <summary>
        /// Creates a new attribute at a fixed cluster.
        /// </summary>
        /// <param name="type">The type of the new attribute.</param>
        /// <param name="name">The name of the new attribute.</param>
        /// <param name="flags">The flags of the new attribute.</param>
        /// <param name="firstCluster">The first cluster to assign to the attribute.</param>
        /// <param name="numClusters">The number of sequential clusters to assign to the attribute.</param>
        /// <param name="bytesPerCluster">The number of bytes in each cluster.</param>
        /// <returns>The new attribute.</returns>
        private NtfsAttribute CreateAttribute(AttributeType type, string name, AttributeFlags flags, long firstCluster, ulong numClusters, uint bytesPerCluster)
        {
            bool   indexed = _context.AttributeDefinitions.IsIndexed(type);
            ushort id      = _records[0].CreateNonResidentAttribute(type, name, flags, firstCluster, numClusters, bytesPerCluster);

            AttributeRecord newAttrRecord = _records[0].GetAttribute(id);
            NtfsAttribute   newAttr       = NtfsAttribute.FromRecord(this, MftReference, newAttrRecord);

            _attributes.Add(newAttr);
            UpdateAttributeList();
            MarkMftRecordDirty();
            return(newAttr);
        }
Пример #12
0
        /// <summary>
        /// Creates a new attribute.
        /// </summary>
        /// <param name="type">The type of the new attribute.</param>
        /// <param name="name">The name of the new attribute.</param>
        /// <param name="flags">The flags of the new attribute.</param>
        /// <returns>The new attribute.</returns>
        private NtfsAttribute CreateAttribute(AttributeType type, string name, AttributeFlags flags)
        {
            bool   indexed = _context.AttributeDefinitions.IsIndexed(type);
            ushort id      = _records[0].CreateAttribute(type, name, indexed, flags);

            AttributeRecord newAttrRecord = _records[0].GetAttribute(id);
            NtfsAttribute   newAttr       = NtfsAttribute.FromRecord(this, MftReference, newAttrRecord);

            _attributes.Add(newAttr);
            UpdateAttributeList();

            MarkMftRecordDirty();

            return(newAttr);
        }
Пример #13
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();
        }
Пример #14
0
        private bool ExpelAttribute(FileRecord record)
        {
            if (record.MasterFileTableIndex == MasterFileTable.MftIndex)
            {
                // Special case for MFT - can't fully expel attributes, instead split most of the data runs off.
                List <AttributeRecord> attrs = record.Attributes;
                for (int i = attrs.Count - 1; i >= 0; --i)
                {
                    AttributeRecord attr = attrs[i];
                    if (attr.AttributeType == AttributeType.Data)
                    {
                        if (SplitAttribute(record, (NonResidentAttributeRecord)attr, true))
                        {
                            return(true);
                        }
                    }
                }
            }
            else
            {
                List <AttributeRecord> attrs = record.Attributes;
                for (int i = attrs.Count - 1; i >= 0; --i)
                {
                    AttributeRecord attr = attrs[i];
                    if (attr.AttributeType > AttributeType.AttributeList)
                    {
                        foreach (FileRecord targetRecord in _records)
                        {
                            if (_mft.RecordSize - targetRecord.Size >= attr.Size)
                            {
                                MoveAttribute(record, attr, targetRecord);
                                return(true);
                            }
                        }

                        FileRecord newFileRecord = _mft.AllocateRecord(FileRecordFlags.None, record.IsMftRecord);
                        newFileRecord.BaseFile = record.Reference;
                        _records.Add(newFileRecord);
                        MoveAttribute(record, attr, newFileRecord);
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #15
0
        public bool ReplaceExtent(AttributeReference oldRef, AttributeReference newRef, AttributeRecord record)
        {
            _cachedRawBuffer = null;

            if (!_extents.Remove(oldRef))
            {
                return(false);
            }
            if (oldRef.Equals(Reference) || _extents.Count == 0)
            {
                _primaryRecord  = record;
                _containingFile = newRef.File;
            }

            _extents.Add(newRef, record);
            return(true);
        }
Пример #16
0
        public bool ReplaceExtent(AttributeReference oldRef, AttributeReference newRef, AttributeRecord record)
        {
            if (!_extents.Remove(oldRef))
            {
                return(false);
            }
            else
            {
                if (oldRef.Equals(Reference) || _extents.Count == 0)
                {
                    _record         = record;
                    _containingFile = newRef.File;
                }

                _extents.Add(newRef, record);
                return(true);
            }
        }
Пример #17
0
        public static AttributeListRecord FromAttribute(AttributeRecord attr, FileRecordReference mftRecord)
        {
            AttributeListRecord newRecord = new AttributeListRecord()
            {
                Type              = attr.AttributeType,
                Name              = attr.Name,
                StartVcn          = 0,
                BaseFileReference = mftRecord,
                AttributeId       = attr.AttributeId
            };

            if (attr.IsNonResident)
            {
                newRecord.StartVcn = (ulong)((NonResidentAttributeRecord)attr).StartVcn;
            }

            return(newRecord);
        }
Пример #18
0
        public override void Clear(long pos, int count)
        {
            AttributeRecord record = _attribute.PrimaryRecord;

            if (!CanWrite)
            {
                throw new IOException("Attempt to write to file not opened for write");
            }

            if (count == 0)
            {
                return;
            }

            _attribute.RawBuffer.Clear(pos, count);

            if (!record.IsNonResident)
            {
                _file.MarkMftRecordDirty();
            }
        }
Пример #19
0
        private IBuffer GetExtentBuffer(long targetPos, out long streamStartPos)
        {
            AttributeRecord rec = null;

            if (_attribute.Extents.Count == 1)
            {
                // Handled as a special case, because sometimes _file can be null (for diagnostics)
                rec            = _attribute.LastExtent;
                streamStartPos = 0;
            }
            else
            {
                long bytesPerCluster = _file.Context.BiosParameterBlock.BytesPerCluster;
                long vcn             = targetPos / bytesPerCluster;

                NonResidentAttributeRecord nonResident = _attribute.GetNonResidentExtent(vcn);
                streamStartPos = nonResident.StartVcn * bytesPerCluster;
                rec            = nonResident;
            }

            return(rec.GetDataBuffer(_file));
        }
Пример #20
0
        internal void MakeAttributeNonResident(AttributeReference attrRef, int maxData)
        {
            NtfsAttribute attr = GetAttribute(attrRef);

            if (attr.IsNonResident)
            {
                throw new InvalidOperationException("Attribute is already non-resident");
            }

            ushort          id            = _records[0].CreateNonResidentAttribute(attr.Type, attr.Name, attr.Flags);
            AttributeRecord newAttrRecord = _records[0].GetAttribute(id);

            IBuffer attrBuffer = attr.GetDataBuffer();

            byte[] tempData = StreamUtilities.ReadFully(attrBuffer, 0, (int)Math.Min(maxData, attrBuffer.Capacity));

            RemoveAttributeExtents(attr);
            attr.SetExtent(_records[0].Reference, newAttrRecord);

            attr.GetDataBuffer().Write(0, tempData, 0, tempData.Length);

            UpdateAttributeList();
        }
Пример #21
0
        public override void Write(long pos, byte[] buffer, int offset, int count)
        {
            AttributeRecord record = _attribute.PrimaryRecord;

            if (!CanWrite)
            {
                throw new IOException("Attempt to write to file not opened for write");
            }

            StreamUtilities.AssertBufferParameters(buffer, offset, count);

            if (count == 0)
            {
                return;
            }

            _attribute.RawBuffer.Write(pos, buffer, offset, count);

            if (!record.IsNonResident)
            {
                _file.MarkMftRecordDirty();
            }
        }
Пример #22
0
 public void AddExtent(FileRecordReference containingFile, AttributeRecord record)
 {
     _cachedRawBuffer = null;
     _extents.Add(new AttributeReference(containingFile, record.AttributeId), record);
 }
Пример #23
0
        public static NtfsAttribute FromRecord(File file, FileRecordReference recordFile, AttributeRecord record)
        {
            switch (record.AttributeType)
            {
            case AttributeType.StandardInformation:
                return(new StructuredNtfsAttribute <StandardInformation>(file, recordFile, record));

            case AttributeType.FileName:
                return(new StructuredNtfsAttribute <FileNameRecord>(file, recordFile, record));

            case AttributeType.SecurityDescriptor:
                return(new StructuredNtfsAttribute <SecurityDescriptor>(file, recordFile, record));

            case AttributeType.Data:
                return(new NtfsAttribute(file, recordFile, record));

            case AttributeType.Bitmap:
                return(new NtfsAttribute(file, recordFile, record));

            case AttributeType.VolumeName:
                return(new StructuredNtfsAttribute <VolumeName>(file, recordFile, record));

            case AttributeType.VolumeInformation:
                return(new StructuredNtfsAttribute <VolumeInformation>(file, recordFile, record));

            case AttributeType.IndexRoot:
                return(new NtfsAttribute(file, recordFile, record));

            case AttributeType.IndexAllocation:
                return(new NtfsAttribute(file, recordFile, record));

            case AttributeType.ObjectId:
                return(new StructuredNtfsAttribute <ObjectId>(file, recordFile, record));

            case AttributeType.ReparsePoint:
                return(new StructuredNtfsAttribute <ReparsePointRecord>(file, recordFile, record));

            case AttributeType.AttributeList:
                return(new StructuredNtfsAttribute <AttributeList>(file, recordFile, record));

            default:
                return(new NtfsAttribute(file, recordFile, record));
            }
        }
        private bool VerifyMftRecord(byte[] recordData, bool presentInBitmap, int bytesPerSector)
        {
            bool ok = true;

            //
            // Verify the attributes seem OK...
            //
            byte[] tempBuffer = new byte[recordData.Length];
            Array.Copy(recordData, tempBuffer, tempBuffer.Length);
            GenericFixupRecord genericRecord = new GenericFixupRecord(bytesPerSector);

            genericRecord.FromBytes(tempBuffer, 0);

            int pos = Utilities.ToUInt16LittleEndian(genericRecord.Content, 0x14);

            while (Utilities.ToUInt32LittleEndian(genericRecord.Content, pos) != 0xFFFFFFFF)
            {
                int attrLen;
                try
                {
                    AttributeRecord ar = AttributeRecord.FromBytes(genericRecord.Content, pos, out attrLen);
                    if (attrLen != ar.Size)
                    {
                        ReportError("Attribute size is different to calculated size.  AttrId={0}", ar.AttributeId);
                        ok = false;
                    }

                    if (ar.IsNonResident)
                    {
                        NonResidentAttributeRecord nrr = (NonResidentAttributeRecord)ar;
                        if (nrr.DataRuns.Count > 0)
                        {
                            long totalVcn = 0;
                            foreach (var run in nrr.DataRuns)
                            {
                                totalVcn += run.RunLength;
                            }

                            if (totalVcn != nrr.LastVcn - nrr.StartVcn + 1)
                            {
                                ReportError("Declared VCNs doesn't match data runs.  AttrId={0}", ar.AttributeId);
                                ok = false;
                            }
                        }
                    }
                }
                catch
                {
                    ReportError("Failure parsing attribute at pos={0}", pos);
                    return(false);
                }

                pos += attrLen;
            }

            //
            // Now consider record as a whole
            //
            FileRecord record = new FileRecord(bytesPerSector);

            record.FromBytes(recordData, 0);

            bool inUse = (record.Flags & FileRecordFlags.InUse) != 0;

            if (inUse != presentInBitmap)
            {
                ReportError("MFT bitmap and record in-use flag don't agree.  Mft={0}, Record={1}", presentInBitmap ? "InUse" : "Free", inUse ? "InUse" : "Free");
                ok = false;
            }

            if (record.Size != record.RealSize)
            {
                ReportError("MFT record real size is different to calculated size.  Stored in MFT={0}, Calculated={1}", record.RealSize, record.Size);
                ok = false;
            }

            if (Utilities.ToUInt32LittleEndian(recordData, (int)record.RealSize - 8) != uint.MaxValue)
            {
                ReportError("MFT record is not correctly terminated with 0xFFFFFFFF");
                ok = false;
            }

            return(ok);
        }
Пример #25
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);
        }
Пример #26
0
        private void LoadAttributes()
        {
            Dictionary <long, FileRecord> extraFileRecords = new Dictionary <long, FileRecord>();

            AttributeRecord attrListRec = _records[0].GetAttribute(AttributeType.AttributeList);

            if (attrListRec != null)
            {
                NtfsAttribute lastAttr = null;

                StructuredNtfsAttribute <AttributeList> attrListAttr =
                    (StructuredNtfsAttribute <AttributeList>)NtfsAttribute.FromRecord(this, MftReference, attrListRec);
                AttributeList attrList = attrListAttr.Content;
                _attributes.Add(attrListAttr);

                foreach (AttributeListRecord record in attrList)
                {
                    FileRecord attrFileRecord = _records[0];
                    if (record.BaseFileReference.MftIndex != _records[0].MasterFileTableIndex)
                    {
                        if (!extraFileRecords.TryGetValue(record.BaseFileReference.MftIndex, out attrFileRecord))
                        {
                            attrFileRecord = _context.Mft.GetRecord(record.BaseFileReference);
                            if (attrFileRecord != null)
                            {
                                extraFileRecords[attrFileRecord.MasterFileTableIndex] = attrFileRecord;
                            }
                        }
                    }

                    if (attrFileRecord != null)
                    {
                        AttributeRecord attrRec = attrFileRecord.GetAttribute(record.AttributeId);

                        if (attrRec != null)
                        {
                            if (record.StartVcn == 0)
                            {
                                lastAttr = NtfsAttribute.FromRecord(this, record.BaseFileReference, attrRec);
                                _attributes.Add(lastAttr);
                            }
                            else
                            {
                                lastAttr.AddExtent(record.BaseFileReference, attrRec);
                            }
                        }
                    }
                }

                foreach (KeyValuePair <long, FileRecord> extraFileRecord in extraFileRecords)
                {
                    _records.Add(extraFileRecord.Value);
                }
            }
            else
            {
                foreach (AttributeRecord record in _records[0].Attributes)
                {
                    _attributes.Add(NtfsAttribute.FromRecord(this, MftReference, record));
                }
            }
        }
Пример #27
0
 public StructuredNtfsAttribute(File file, FileRecordReference containingFile, AttributeRecord record)
     : base(file, containingFile, record)
 {
     _structure = new T();
 }