protected override void Read(byte[] buffer, int offset) { LogFileSequenceNumber = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x08); SequenceNumber = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x10); HardLinkCount = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x12); _firstAttributeOffset = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x14); Flags = (FileRecordFlags)EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x16); RealSize = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x18); AllocatedSize = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x1C); BaseFile = new FileRecordReference(EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x20)); NextAttributeId = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x28); if (UpdateSequenceOffset >= 0x30) { _index = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x2C); _haveIndex = true; } Attributes = new List <AttributeRecord>(); int focus = _firstAttributeOffset; while (true) { int length; AttributeRecord attr = AttributeRecord.FromBytes(buffer, focus, out length); if (attr == null) { break; } Attributes.Add(attr); focus += length; } }
private bool VerifyMftRecord(byte[] recordData, bool presentInBitmap, int bytesPerSector) { bool ok = true; // // Verify the attributes seem OK... // byte[] tempBuffer = new byte[recordData.Length]; Array.Copy(recordData, tempBuffer, tempBuffer.Length); GenericFixupRecord genericRecord = new GenericFixupRecord(bytesPerSector); genericRecord.FromBytes(tempBuffer, 0); int pos = Utilities.ToUInt16LittleEndian(genericRecord.Content, 0x14); while (Utilities.ToUInt32LittleEndian(genericRecord.Content, pos) != 0xFFFFFFFF) { int attrLen; try { AttributeRecord ar = AttributeRecord.FromBytes(genericRecord.Content, pos, out attrLen); if (attrLen != ar.Size) { ReportError("Attribute size is different to calculated size. AttrId={0}", ar.AttributeId); ok = false; } if (ar.IsNonResident) { NonResidentAttributeRecord nrr = (NonResidentAttributeRecord)ar; if (nrr.DataRuns.Count > 0) { long totalVcn = 0; foreach (var run in nrr.DataRuns) { totalVcn += run.RunLength; } if (totalVcn != nrr.LastVcn - nrr.StartVcn + 1) { ReportError("Declared VCNs doesn't match data runs. AttrId={0}", ar.AttributeId); ok = false; } } } } catch { ReportError("Failure parsing attribute at pos={0}", pos); return(false); } pos += attrLen; } // // Now consider record as a whole // FileRecord record = new FileRecord(bytesPerSector); record.FromBytes(recordData, 0); bool inUse = (record.Flags & FileRecordFlags.InUse) != 0; if (inUse != presentInBitmap) { ReportError("MFT bitmap and record in-use flag don't agree. Mft={0}, Record={1}", presentInBitmap ? "InUse" : "Free", inUse ? "InUse" : "Free"); ok = false; } if (record.Size != record.RealSize) { ReportError("MFT record real size is different to calculated size. Stored in MFT={0}, Calculated={1}", record.RealSize, record.Size); ok = false; } if (Utilities.ToUInt32LittleEndian(recordData, (int)record.RealSize - 8) != uint.MaxValue) { ReportError("MFT record is not correctly terminated with 0xFFFFFFFF"); ok = false; } return(ok); }