public FileRecord GetRecord(long index, bool ignoreMagic, bool ignoreBitmap) { if (ignoreBitmap || _bitmap == null || _bitmap.IsPresent(index)) { FileRecord result = _recordCache[index]; if (result != null) { return(result); } if ((index + 1) * _recordLength <= _recordStream.Length) { _recordStream.Position = index * _recordLength; byte[] recordBuffer = Utilities.ReadFully(_recordStream, _recordLength); result = new FileRecord(_bytesPerSector); result.FromBytes(recordBuffer, 0, ignoreMagic); result.LoadedIndex = (uint)index; } else { result = new FileRecord(_bytesPerSector, _recordLength, (uint)index); } _recordCache[index] = result; return(result); } return(null); }
private long ExtendRun(long count, List <Tuple <long, long> > result, long start, long end) { long focusCluster = start; while (!_bitmap.IsPresent(focusCluster) && focusCluster < end && focusCluster - start < count) { ++focusCluster; } long numFound = focusCluster - start; if (numFound > 0) { _bitmap.MarkPresentRange(start, numFound); result.Add(new Tuple <long, long>(start, numFound)); } return(numFound); }
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); }
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; }