private void VerifyDirectories() { foreach (FileRecord fr in _context.Mft.Records) { if (fr.BaseFile.Value != 0) { continue; } File f = new File(_context, fr); foreach (var stream in f.AllStreams) { if (stream.AttributeType == AttributeType.IndexRoot && stream.Name == "$I30") { IndexView <FileNameRecord, FileRecordReference> dir = new IndexView <FileNameRecord, FileRecordReference>(f.GetIndex("$I30")); foreach (var entry in dir.Entries) { FileRecord refFile = _context.Mft.GetRecord(entry.Value); // Make sure each referenced file actually exists... if (refFile == null) { ReportError("Directory {0} references non-existent file {1}", f, entry.Key); } File referencedFile = new File(_context, refFile); StandardInformation si = referencedFile.StandardInformation; if (si.CreationTime != entry.Key.CreationTime || si.MftChangedTime != entry.Key.MftChangedTime || si.ModificationTime != entry.Key.ModificationTime) { ReportInfo("Directory entry {0} in {1} is out of date", entry.Key, f); } } } } } }
public void UpdateRecordInMft() { if (_dirty) { 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) { var record = _records[i]; bool fixedAttribute = true; while (record.Size > _mft.RecordSize && fixedAttribute) { fixedAttribute = false; if (!fixedAttribute && !record.IsMftRecord) { foreach (var 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 (var 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; } } } _dirty = false; foreach (var record in _records) { _mft.WriteRecord(record); } } }