private FileRecord ReadMftRecord(bool useMftMirror, bool readMftMirror) { NTFSBootRecord bootRecord = m_volume.BootRecord; if (bootRecord != null) { long mftStartLCN = useMftMirror ? (long)bootRecord.MftMirrorStartLCN : (long)bootRecord.MftStartLCN; long mftSegmentNumber = readMftMirror ? MftMirrorSegmentNumber : MasterFileTableSegmentNumber; FileRecordSegment mftRecordSegment = ReadFileRecordSegment(mftStartLCN, mftSegmentNumber); if (!mftRecordSegment.IsBaseFileRecord) { throw new InvalidDataException("Invalid MFT record, not a base record"); } AttributeRecord attributeListRecord = mftRecordSegment.GetImmediateAttributeRecord(AttributeType.AttributeList, String.Empty); if (attributeListRecord == null) { return(new FileRecord(mftRecordSegment)); } else { // I have never personally seen an MFT with an attribute list AttributeList attributeList = new AttributeList(m_volume, attributeListRecord); List <AttributeListEntry> entries = attributeList.ReadEntries(); List <MftSegmentReference> references = AttributeList.GetSegmentReferenceList(entries); int baseSegmentIndex = MftSegmentReference.IndexOfSegmentNumber(references, MasterFileTableSegmentNumber); if (baseSegmentIndex >= 0) { references.RemoveAt(baseSegmentIndex); } List <FileRecordSegment> recordSegments = new List <FileRecordSegment>(); // we want the base record segment first recordSegments.Add(mftRecordSegment); foreach (MftSegmentReference reference in references) { FileRecordSegment segment = ReadFileRecordSegment(mftStartLCN, reference); if (segment != null) { recordSegments.Add(segment); } else { throw new InvalidDataException("Invalid MFT record, missing segment"); } } return(new FileRecord(recordSegments)); } } else { return(null); } }
public FileRecord GetFileRecord(long baseSegmentNumber) { FileRecordSegment baseSegment = GetFileRecordSegment(baseSegmentNumber); if (baseSegment != null && baseSegment.IsBaseFileRecord) { AttributeRecord attributeListRecord = baseSegment.GetImmediateAttributeRecord(AttributeType.AttributeList, String.Empty); if (attributeListRecord == null) { return(new FileRecord(baseSegment)); } else { // The attribute list contains entries for every attribute the record has (excluding the attribute list), // including attributes that reside within the base record segment. AttributeList attributeList = new AttributeList(m_volume, attributeListRecord); List <AttributeListEntry> entries = attributeList.ReadEntries(); List <MftSegmentReference> references = AttributeList.GetSegmentReferenceList(entries); int baseSegmentIndex = MftSegmentReference.IndexOfSegmentNumber(references, baseSegmentNumber); if (baseSegmentIndex >= 0) { references.RemoveAt(baseSegmentIndex); } List <FileRecordSegment> recordSegments = new List <FileRecordSegment>(); // we want the base record segment first recordSegments.Add(baseSegment); foreach (MftSegmentReference reference in references) { FileRecordSegment segment = GetFileRecordSegment(reference); if (segment != null) { recordSegments.Add(segment); } else { // record is invalid return(null); } } return(new FileRecord(recordSegments)); } } else { return(null); } }
private FileRecord ReadMftRecord() { NTFSBootRecord bootRecord = m_volume.BootRecord; if (bootRecord != null) { long mftStartLCN; if (m_useMftMirror) { mftStartLCN = (long)bootRecord.MftMirrorStartLCN; } else { mftStartLCN = (long)bootRecord.MftStartLCN; } FileRecordSegment mftRecordSegment = GetRecordSegmentOfMasterFileTable(mftStartLCN, MasterFileTableSegmentNumber); if (!mftRecordSegment.IsBaseFileRecord) { return(null); } AttributeRecord attributeListRecord = mftRecordSegment.GetImmediateAttributeRecord(AttributeType.AttributeList); if (attributeListRecord == null) { return(new FileRecord(mftRecordSegment)); } else { // I have never personally seen an MFT with an attribute list AttributeListRecord attributeList = new AttributeListRecord(m_volume, attributeListRecord); List <MftSegmentReference> references = attributeList.GetSegmentReferenceList(); int baseSegmentIndex = MftSegmentReference.IndexOfSegmentNumber(references, MasterFileTableSegmentNumber); if (baseSegmentIndex >= 0) { references.RemoveAt(baseSegmentIndex); } List <FileRecordSegment> recordSegments = new List <FileRecordSegment>(); // we want the base record segment first recordSegments.Add(mftRecordSegment); foreach (MftSegmentReference reference in references) { FileRecordSegment segment = GetRecordSegmentOfMasterFileTable(mftStartLCN, reference); if (segment != null) { recordSegments.Add(segment); } else { // MFT is invalid return(null); } } return(new FileRecord(recordSegments)); } } else { return(null); } }