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); }
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(); }
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(); }
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); } } }