Пример #1
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);
        }
Пример #2
0
        public void Delete()
        {
            if (_records[0].HardLinkCount != 0)
            {
                throw new InvalidOperationException("Attempt to delete in-use file: " + ToString());
            }

            _context.ForgetFile(this);

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

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

            // Truncate attributes, allowing for truncation silently removing the AttributeList attribute
            // in some cases (large file with all attributes first extent in the first MFT record).  This
            // releases all allocated clusters in most cases.
            List <NtfsAttribute> truncateAttrs = new List <NtfsAttribute>(_attributes.Count);

            foreach (NtfsAttribute attr in _attributes)
            {
                if (attr.Type != AttributeType.AttributeList)
                {
                    truncateAttrs.Add(attr);
                }
            }

            foreach (NtfsAttribute attr in truncateAttrs)
            {
                attr.GetDataBuffer().SetCapacity(0);
            }

            // If the attribute list record remains, free any possible clusters it owns.  We've now freed
            // all clusters.
            NtfsAttribute attrList = GetAttribute(AttributeType.AttributeList, null);

            if (attrList != null)
            {
                attrList.GetDataBuffer().SetCapacity(0);
            }

            // Now go through the MFT records, freeing them up
            foreach (FileRecord mftRecord in _records)
            {
                _context.Mft.RemoveRecord(mftRecord.Reference);
            }

            _attributes.Clear();
            _records.Clear();
        }
Пример #3
0
        public void Accessed()
        {
            DateTime now = DateTime.UtcNow;

            NtfsStream          siStream = GetStream(AttributeType.StandardInformation, null);
            StandardInformation si       = siStream.GetContent <StandardInformation>();

            si.LastAccessTime = now;
            siStream.SetContent(si);

            MarkMftRecordDirty();
        }
Пример #4
0
        public void UpdateRecordInMft()
        {
            if (MftRecordIsDirty)
            {
                if (NtfsTransaction.Current != null)
                {
                    NtfsStream          stream = GetStream(AttributeType.StandardInformation, null);
                    StandardInformation si     = stream.GetContent <StandardInformation>();
                    si.MftChangedTime = NtfsTransaction.Current.Timestamp;
                    stream.SetContent(si);
                }

                bool fixesApplied = true;
                while (fixesApplied)
                {
                    fixesApplied = false;

                    for (int i = 0; i < _records.Count; ++i)
                    {
                        FileRecord record = _records[i];

                        bool fixedAttribute = true;
                        while (record.Size > _mft.RecordSize && fixedAttribute)
                        {
                            fixedAttribute = false;

                            if (!fixedAttribute && !record.IsMftRecord)
                            {
                                foreach (AttributeRecord attr in record.Attributes)
                                {
                                    if (!attr.IsNonResident &&
                                        !_context.AttributeDefinitions.MustBeResident(attr.AttributeType))
                                    {
                                        MakeAttributeNonResident(
                                            new AttributeReference(record.Reference, attr.AttributeId),
                                            (int)attr.DataLength);
                                        fixedAttribute = true;
                                        break;
                                    }
                                }
                            }

                            if (!fixedAttribute)
                            {
                                foreach (AttributeRecord attr in record.Attributes)
                                {
                                    if (attr.AttributeType == AttributeType.IndexRoot &&
                                        ShrinkIndexRoot(attr.Name))
                                    {
                                        fixedAttribute = true;
                                        break;
                                    }
                                }
                            }

                            if (!fixedAttribute)
                            {
                                if (record.Attributes.Count == 1)
                                {
                                    fixedAttribute = SplitAttribute(record);
                                }
                                else
                                {
                                    if (_records.Count == 1)
                                    {
                                        CreateAttributeList();
                                    }

                                    fixedAttribute = ExpelAttribute(record);
                                }
                            }

                            fixesApplied |= fixedAttribute;
                        }
                    }
                }

                MftRecordIsDirty = false;
                foreach (FileRecord record in _records)
                {
                    _mft.WriteRecord(record);
                }
            }
        }