private void PreVerifyMft(File file) { int recordLength = _context.BiosParameterBlock.MftRecordSize; int bytesPerSector = _context.BiosParameterBlock.BytesPerSector; // Check out the MFT's clusters foreach (var range in file.GetAttribute(AttributeType.Data, null).GetClusters()) { if (!VerifyClusterRange(range)) { ReportError("Corrupt cluster range in MFT data attribute {0}", range.ToString()); Abort(); } } foreach (var range in file.GetAttribute(AttributeType.Bitmap, null).GetClusters()) { if (!VerifyClusterRange(range)) { ReportError("Corrupt cluster range in MFT bitmap attribute {0}", range.ToString()); Abort(); } } using (Stream mftStream = file.OpenStream(AttributeType.Data, null, FileAccess.Read)) using (Stream bitmapStream = file.OpenStream(AttributeType.Bitmap, null, FileAccess.Read)) { Bitmap bitmap = new Bitmap(bitmapStream, long.MaxValue); long index = 0; while (mftStream.Position < mftStream.Length) { byte[] recordData = Utilities.ReadFully(mftStream, recordLength); string magic = Utilities.BytesToString(recordData, 0, 4); if (magic != "FILE") { if (bitmap.IsPresent(index)) { ReportError("Invalid MFT record magic at index {0} - was ({2},{3},{4},{5}) \"{1}\"", index, magic.Trim('\0'), (int)magic[0], (int)magic[1], (int)magic[2], (int)magic[3]); } } else { if (!VerifyMftRecord(recordData, bitmap.IsPresent(index), bytesPerSector)) { ReportError("Invalid MFT record at index {0}", index); StringBuilder bldr = new StringBuilder(); for (int i = 0; i < recordData.Length; ++i) { bldr.Append(string.Format(CultureInfo.InvariantCulture, " {0:X2}", recordData[i])); } ReportInfo("MFT record binary data for index {0}:{1}", index, bldr.ToString()); } } index++; } } }
private bool SelfCheckIndexNode(byte[] buffer, int offset, Bitmap bitmap, IndexRoot root, string fileName, string indexName) { bool ok = true; IndexHeader header = new IndexHeader(buffer, offset); IndexEntry lastEntry = null; IComparer<byte[]> collator = root.GetCollator(_context.UpperCase); int pos = (int)header.OffsetToFirstEntry; while (pos < header.TotalSizeOfEntries) { IndexEntry entry = new IndexEntry(indexName == "$I30"); entry.Read(buffer, offset + pos); pos += entry.Size; if ((entry.Flags & IndexEntryFlags.Node) != 0) { long bitmapIdx = entry.ChildrenVirtualCluster / Utilities.Ceil(root.IndexAllocationSize, _context.BiosParameterBlock.SectorsPerCluster * _context.BiosParameterBlock.BytesPerSector); if (!bitmap.IsPresent(bitmapIdx)) { ReportError("Index entry {0} is non-leaf, but child vcn {1} is not in bitmap at index {2}", Index.EntryAsString(entry, fileName, indexName), entry.ChildrenVirtualCluster, bitmapIdx); } } if ((entry.Flags & IndexEntryFlags.End) != 0) { if (pos != header.TotalSizeOfEntries) { ReportError("Found END index entry {0}, but not at end of node", Index.EntryAsString(entry, fileName, indexName)); ok = false; } } if (lastEntry != null && collator.Compare(lastEntry.KeyBuffer, entry.KeyBuffer) >= 0) { ReportError("Found entries out of order {0} was before {1}", Index.EntryAsString(lastEntry, fileName, indexName), Index.EntryAsString(entry, fileName, indexName)); ok = false; } lastEntry = entry; } return ok; }