IndexAllocationRecord.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. // IndexAllocation attribute is always non-resident
  14. public class IndexAllocationRecord : NonResidentAttributeRecord
  15. {
  16. public IndexAllocationRecord(byte[] buffer, int offset) : base(buffer, offset)
  17. {
  18. }
  19. public KeyValuePairList<MftSegmentReference, FileNameRecord> GetAllEntries(NTFSVolume volume, IndexRootRecord rootRecord)
  20. {
  21. KeyValuePairList<MftSegmentReference, FileNameRecord> result = new KeyValuePairList<MftSegmentReference, FileNameRecord>();
  22. List<IndexNodeEntry> parents = new List<IndexNodeEntry>(rootRecord.IndexEntries);
  23. List<IndexRecord> leaves = new List<IndexRecord>();
  24. int parentIndex = 0;
  25. while (parentIndex < parents.Count)
  26. {
  27. IndexNodeEntry parent = parents[parentIndex];
  28. byte[] clusters = this.ReadDataClusters(volume, parent.SubnodeVCN, rootRecord.ClustersPerIndexRecord);
  29. IndexRecord record = new IndexRecord(clusters, 0);
  30. if (record.HasChildren)
  31. {
  32. foreach (IndexNodeEntry node in record.IndexEntries)
  33. {
  34. parents.Add(node);
  35. }
  36. }
  37. else
  38. {
  39. leaves.Add(record);
  40. }
  41. parentIndex++;
  42. }
  43. foreach (IndexNodeEntry node in parents)
  44. {
  45. if (!node.IsLastEntry)
  46. {
  47. // Some of the tree data in NTFS is contained in non-leaf keys
  48. FileNameRecord parentRecord = new FileNameRecord(node.Key, 0);
  49. result.Add(node.SegmentReference, parentRecord);
  50. }
  51. }
  52. foreach (IndexRecord record in leaves)
  53. {
  54. foreach (FileNameIndexEntry entry in record.FileNameEntries)
  55. {
  56. result.Add(entry.FileReference, entry.Record);
  57. }
  58. }
  59. result.Sort(Compare);
  60. return result;
  61. }
  62. public static int Compare(KeyValuePair<MftSegmentReference, FileNameRecord> entryA, KeyValuePair<MftSegmentReference, FileNameRecord> entryB)
  63. {
  64. return String.Compare(entryA.Value.FileName, entryB.Value.FileName);
  65. }
  66. }
  67. }