public static IndexAllocationChunk ParseBody(INTFSInfo ntfsInfo, byte[] data, int offset) { Debug.Assert(data.Length >= 36); IndexAllocationChunk res = new IndexAllocationChunk(); // Parse res.Signature = Encoding.ASCII.GetString(data, offset + 0, 4); Debug.Assert(res.Signature == "INDX"); res.OffsetToUSN = BitConverter.ToUInt16(data, offset + 4); res.USNSizeWords = BitConverter.ToUInt16(data, offset + 6); res.LogFileUSN = BitConverter.ToUInt64(data, offset + 8); res.VCNInIndexAllocation = BitConverter.ToUInt64(data, offset + 16); res.OffsetToFirstIndex = BitConverter.ToUInt32(data, offset + 24); res.SizeOfIndexTotal = BitConverter.ToUInt32(data, offset + 28); res.SizeOfIndexAllocated = BitConverter.ToUInt32(data, offset + 32); res.HasChildren = data[36]; Debug.Assert(data.Length >= offset + res.OffsetToUSN + 2 + res.USNSizeWords * 2); res.USNNumber = new byte[2]; Array.Copy(data, offset + res.OffsetToUSN, res.USNNumber, 0, 2); res.USNData = new byte[res.USNSizeWords * 2 - 2]; Array.Copy(data, offset + res.OffsetToUSN + 2, res.USNData, 0, res.USNData.Length); // Patch USN Data NtfsUtils.ApplyUSNPatch(data, offset, (res.SizeOfIndexAllocated + 24) / ntfsInfo.BytesPrSector, (ushort)ntfsInfo.BytesPrSector, res.USNNumber, res.USNData); Debug.Assert(offset + res.SizeOfIndexTotal <= data.Length); // Parse entries List <IndexEntry> entries = new List <IndexEntry>(); int pointer = offset + (int)(res.OffsetToFirstIndex + 24); // Offset is relative to 0x18 while (pointer <= offset + res.SizeOfIndexTotal + 24) { IndexEntry entry = IndexEntry.ParseData(data, offset + (int)res.SizeOfIndexTotal - pointer + 24, pointer); if (entry.Flags.HasFlag(MFTIndexEntryFlags.LastEntry)) { break; } entries.Add(entry); pointer += entry.Size; } res.Entries = entries.ToArray(); return(res); }
internal override void ParseAttributeResidentBody(byte[] data, int maxLength, int offset) { base.ParseAttributeResidentBody(data, maxLength, offset); // Debug.Assert(maxLength >= 32); IndexType = (AttributeType)BitConverter.ToUInt32(data, offset); CollationRule = BitConverter.ToUInt32(data, offset + 4); IndexAllocationSize = BitConverter.ToUInt32(data, offset + 8); ClustersPrIndexRecord = data[offset + 12]; OffsetToFirstIndex = BitConverter.ToUInt32(data, offset + 16); SizeOfIndexTotal = BitConverter.ToUInt32(data, offset + 20); SizeOfIndexAllocated = BitConverter.ToUInt32(data, offset + 24); IndexFlags = (MFTIndexRootFlags)data[offset + 28]; List <IndexEntry> entries = new List <IndexEntry>(); // Parse entries int pointer = offset + 32; while (pointer <= offset + SizeOfIndexTotal + 32) { IndexEntry entry = IndexEntry.ParseData(data, (int)SizeOfIndexTotal - (pointer - offset) + 32, pointer); if ((entry.Flags & MFTIndexEntryFlags.LastEntry) != 0) { break; } entries.Add(entry); pointer += entry.Size; } Entries = entries; }