IndexRecord.cs 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Utilities;
  11. namespace DiskAccessLibrary.FileSystems.NTFS
  12. {
  13. public class IndexRecord
  14. {
  15. public const string ValidSignature = "INDX";
  16. /* Index Record Header start*/
  17. /* Start of MULTI_SECTOR_HEADER */
  18. public string Signature = ValidSignature;
  19. // private ushort UpdateSequenceArrayOffset;
  20. // private ushort UpdateSequenceArraySize; // number of (2 byte) words
  21. /* End of MULTI_SECTOR_HEADER */
  22. public ulong LogFileSequenceNumber;
  23. public ulong RecordVCN;
  24. /* Header */
  25. /* Index Header start */
  26. public uint EntriesOffset; // relative to Index record header start offset
  27. public uint IndexLength; // including the Index record header
  28. public uint AllocatedLength; // including the Index record header
  29. public bool HasChildren; // level?
  30. // 3 zero bytes (padding)
  31. /* Index Header end */
  32. public ushort UpdateSequenceNumber;
  33. /* Index Record Header end*/
  34. public List<IndexNodeEntry> IndexEntries = new List<IndexNodeEntry>();
  35. public List<FileNameIndexEntry> FileNameEntries = new List<FileNameIndexEntry>();
  36. public IndexRecord(byte[] buffer, int offset)
  37. {
  38. Signature = ByteReader.ReadAnsiString(buffer, offset + 0x00, 4);
  39. ushort updateSequenceArrayOffset = LittleEndianConverter.ToUInt16(buffer, offset + 0x04);
  40. ushort updateSequenceArraySize = LittleEndianConverter.ToUInt16(buffer, offset + 0x06);
  41. LogFileSequenceNumber = LittleEndianConverter.ToUInt64(buffer, offset + 0x08);
  42. RecordVCN = LittleEndianConverter.ToUInt64(buffer, offset + 0x10);
  43. EntriesOffset = LittleEndianConverter.ToUInt32(buffer, offset + 0x18);
  44. IndexLength = LittleEndianConverter.ToUInt32(buffer, offset + 0x1C);
  45. AllocatedLength = LittleEndianConverter.ToUInt32(buffer, offset + 0x20);
  46. HasChildren = ByteReader.ReadByte(buffer, offset + 0x24) > 0;
  47. int position = offset + updateSequenceArrayOffset;
  48. UpdateSequenceNumber = LittleEndianConverter.ToUInt16(buffer, position);
  49. position += 2;
  50. List<byte[]> updateSequenceReplacementData = new List<byte[]>();
  51. for (int index = 0; index < updateSequenceArraySize - 1; index++)
  52. {
  53. byte[] endOfSectorBytes = new byte[2];
  54. endOfSectorBytes[0] = buffer[position + 0];
  55. endOfSectorBytes[1] = buffer[position + 1];
  56. updateSequenceReplacementData.Add(endOfSectorBytes);
  57. position += 2;
  58. }
  59. MultiSectorHelper.DecodeSegmentBuffer(buffer, offset, UpdateSequenceNumber, updateSequenceReplacementData);
  60. position = 0x18 + (int)EntriesOffset;
  61. if (HasChildren)
  62. {
  63. IndexNode node = new IndexNode(buffer, position);
  64. IndexEntries = node.Entries;
  65. }
  66. else
  67. {
  68. FileNameIndexLeafNode leaf = new FileNameIndexLeafNode(buffer, position);
  69. FileNameEntries = leaf.Entries;
  70. }
  71. }
  72. }
  73. }