internal FileRecord(byte[] recordBytes, string volume, bool fast) { VolumePath = volume; Signature = Encoding.ASCII.GetString(recordBytes, 0x00, 0x04); if (Signature == "FILE") { // Parse File Record Header OffsetOfUS = BitConverter.ToUInt16(recordBytes, 4); SizeOfUS = BitConverter.ToUInt16(recordBytes, 6); UpdateSequenceNumber = BitConverter.ToUInt16(recordBytes, OffsetOfUS); #region UpdateSequenceArray UpdateSequenceArray = new byte[(2 * SizeOfUS) - 2]; Array.Copy(recordBytes, (OffsetOfUS + 2), UpdateSequenceArray, 0, UpdateSequenceArray.Length); #endregion UpdateSequenceArray LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 8); SequenceNumber = BitConverter.ToUInt16(recordBytes, 16); Hardlinks = BitConverter.ToUInt16(recordBytes, 18); OffsetOfAttribute = BitConverter.ToUInt16(recordBytes, 20); Flags = BitConverter.ToUInt16(recordBytes, 22); #region Deleted if ((Flags & (ushort)FILE_RECORD_FLAG.INUSE) == (ushort)FILE_RECORD_FLAG.INUSE) { Deleted = false; } else { Deleted = true; } #endregion Deleted #region Directory if ((Flags & (ushort)FILE_RECORD_FLAG.DIR) == (ushort)FILE_RECORD_FLAG.DIR) { Directory = true; } else { Directory = false; } #endregion Directory RealSize = BitConverter.ToUInt32(recordBytes, 24); AllocatedSize = BitConverter.ToUInt32(recordBytes, 28); ReferenceToBase = BitConverter.ToUInt64(recordBytes, 32); NextAttrId = BitConverter.ToUInt16(recordBytes, 40); RecordNumber = BitConverter.ToUInt32(recordBytes, 44); #region Attribute // Create a byte array representing the attribute array byte[] attrArrayBytes = new byte[RealSize - OffsetOfAttribute]; Array.Copy(recordBytes, OffsetOfAttribute, attrArrayBytes, 0, attrArrayBytes.Length); // Instantiate an empty list of Attr Objects (We don't know how many attributes the record contains) List <Attr> AttributeList = new List <Attr>(); // Initialize the offset value to 0 int currentOffset = 0; if (currentOffset < (attrArrayBytes.Length - 8)) { do { // Get attribute size int attrSizeOffset = currentOffset + 4; int attrSize = BitConverter.ToInt32(attrArrayBytes, attrSizeOffset); // Create new byte array with just current attribute's bytes byte[] currentAttrBytes = new byte[attrSize]; Array.Copy(attrArrayBytes, currentOffset, currentAttrBytes, 0, currentAttrBytes.Length); // Increment currentOffset currentOffset += attrSize; Attr attr = AttributeFactory.Get(currentAttrBytes, volume); if (attr != null) { if (attr.Name == Attr.ATTR_TYPE.STANDARD_INFORMATION) { StandardInformation stdInfo = attr as StandardInformation; ModifiedTime = stdInfo.ModifiedTime; AccessedTime = stdInfo.AccessedTime; ChangedTime = stdInfo.ChangedTime; BornTime = stdInfo.BornTime; Permission = stdInfo.Permission; } else if (attr.Name == Attr.ATTR_TYPE.FILE_NAME) { FileName fN = attr as FileName; if (!(fN.Namespace == 2)) { Name = fN.Filename; ParentSequenceNumber = fN.ParentSequenceNumber; ParentRecordNumber = fN.ParentRecordNumber; FNModifiedTime = fN.ModifiedTime; FNAccessedTime = fN.AccessedTime; FNChangedTime = fN.ChangedTime; FNBornTime = fN.BornTime; } } AttributeList.Add(attr); } } while (currentOffset < (attrArrayBytes.Length - 8)); } Attribute = AttributeList.ToArray(); #endregion Attribute #region FullName if (fast) { FullName = Name; } else { StringBuilder sb = new StringBuilder(); if (RecordNumber == 0) { sb.Append(volume.Split('\\')[3]); sb.Append('\\'); sb.Append(Name); FullName = sb.ToString(); } else if (RecordNumber == 5) { FullName = volume.Split('\\')[3]; } else { FileRecord parent = new FileRecord(FileRecord.GetRecordBytes(volume, (int)ParentRecordNumber), volume, false); if (parent.SequenceNumber == this.ParentSequenceNumber) { sb.Append(parent.FullName); } else { sb.Append(@"$OrphanFiles"); } if (Name != null) { sb.Append('\\'); FullName = sb.Append(Name).ToString(); } else { FullName = sb.ToString(); } } } #endregion FullName } }
private FileRecord(ref FileRecord[] array, byte[] mftBytes, byte[] recordBytes, int bytesPerFileRecord, string volume) { VolumePath = volume; Signature = Encoding.ASCII.GetString(recordBytes, 0x00, 0x04); if (Signature == "FILE") { // Parse File Record Header OffsetOfUS = BitConverter.ToUInt16(recordBytes, 4); SizeOfUS = BitConverter.ToUInt16(recordBytes, 6); UpdateSequenceNumber = BitConverter.ToUInt16(recordBytes, OffsetOfUS); #region UpdateSequenceArray UpdateSequenceArray = new byte[(2 * SizeOfUS) - 2]; Array.Copy(recordBytes, (OffsetOfUS + 2), UpdateSequenceArray, 0, UpdateSequenceArray.Length); #endregion UpdateSequenceArray LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 8); SequenceNumber = BitConverter.ToUInt16(recordBytes, 16); Hardlinks = BitConverter.ToUInt16(recordBytes, 18); OffsetOfAttribute = BitConverter.ToUInt16(recordBytes, 20); Flags = BitConverter.ToUInt16(recordBytes, 22); #region Deleted if ((Flags & (ushort)FILE_RECORD_FLAG.INUSE) == (ushort)FILE_RECORD_FLAG.INUSE) { Deleted = false; } else { Deleted = true; } #endregion Deleted #region Directory if ((Flags & (ushort)FILE_RECORD_FLAG.DIR) == (ushort)FILE_RECORD_FLAG.DIR) { Directory = true; } else { Directory = false; } #endregion Directory RealSize = BitConverter.ToUInt32(recordBytes, 24); AllocatedSize = BitConverter.ToUInt32(recordBytes, 28); ReferenceToBase = BitConverter.ToUInt64(recordBytes, 32); NextAttrId = BitConverter.ToUInt16(recordBytes, 40); RecordNumber = BitConverter.ToUInt32(recordBytes, 44); #region Attribute // Create a byte array representing the attribute array byte[] attrArrayBytes = new byte[RealSize - OffsetOfAttribute]; ApplyFixup(ref recordBytes); Array.Copy(recordBytes, OffsetOfAttribute, attrArrayBytes, 0, attrArrayBytes.Length); // Instantiate an empty list of Attr Objects (We don't know how many attributes the record contains) List <Attr> AttributeList = new List <Attr>(); // Initialize the offset value to 0 int currentOffset = 0; if (currentOffset < (attrArrayBytes.Length - 8)) { do { // Get attribute size int attrSizeOffset = currentOffset + 4; int attrSize = BitConverter.ToInt32(attrArrayBytes, attrSizeOffset); // Create new byte array with just current attribute's bytes byte[] currentAttrBytes = new byte[attrSize]; Array.Copy(attrArrayBytes, currentOffset, currentAttrBytes, 0, currentAttrBytes.Length); // Increment currentOffset currentOffset += attrSize; Attr attr = AttributeFactory.Get(currentAttrBytes, volume); if (attr != null) { if (attr.Name == Attr.ATTR_TYPE.STANDARD_INFORMATION) { StandardInformation stdInfo = attr as StandardInformation; ModifiedTime = stdInfo.ModifiedTime; AccessedTime = stdInfo.AccessedTime; ChangedTime = stdInfo.ChangedTime; BornTime = stdInfo.BornTime; Permission = stdInfo.Permission; } else if (attr.Name == Attr.ATTR_TYPE.FILE_NAME) { FileName fN = attr as FileName; if (!(fN.Namespace == 2)) { Name = fN.Filename; ParentSequenceNumber = fN.ParentSequenceNumber; ParentRecordNumber = fN.ParentRecordNumber; FNModifiedTime = fN.ModifiedTime; FNAccessedTime = fN.AccessedTime; FNChangedTime = fN.ChangedTime; FNBornTime = fN.BornTime; } } AttributeList.Add(attr); } } while (currentOffset < (attrArrayBytes.Length - 8)); } Attribute = AttributeList.ToArray(); #endregion Attribute #region FullName StringBuilder sb = new StringBuilder(); // Record 5 is the root of the drive if (RecordNumber == 5) { sb.Append(volume.Split('\\')[3]); } else { // Derive Path by looking at ParentRecord's FullName if (array[(int)ParentRecordNumber] != null) { if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber) { sb.Append(array[(int)ParentRecordNumber].FullName); } else { sb.Append(@"$OrphanFiles\"); } } // If record for Parent does not already exist then instantiate it and add it to the array else { byte[] parentBytes = NativeMethods.GetSubArray(mftBytes, (uint)bytesPerFileRecord * (uint)ParentRecordNumber, (uint)bytesPerFileRecord); array[(int)ParentRecordNumber] = new FileRecord(ref array, mftBytes, parentBytes, bytesPerFileRecord, volume); if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber) { sb.Append(array[(int)ParentRecordNumber].FullName); } else { sb.Append(@"$OrphanFiles\"); } } // Add file name to end of path sb.Append(Name); } // Add trailing \ to any file that is a directory if (Directory) { sb.Append('\\'); } // Figure out a way to have record 15 not have a name of $MFT... FullName = sb.ToString(); #endregion FullName } }
private FileRecord(ref FileRecord[] recordArray, byte[] bytes, int offset, int bytesPerFileRecord, string volume, bool fast) { if (Encoding.ASCII.GetString(bytes, 0x00 + offset, 0x04) == "FILE") { OffsetOfUS = BitConverter.ToUInt16(bytes, 0x04 + offset); SizeOfUS = BitConverter.ToUInt16(bytes, 0x06 + offset); LogFileSequenceNumber = BitConverter.ToUInt64(bytes, 0x08 + offset); SequenceNumber = BitConverter.ToUInt16(bytes, 0x10 + offset); Hardlinks = BitConverter.ToUInt16(bytes, 0x12 + offset); OffsetOfAttribute = BitConverter.ToUInt16(bytes, 0x14 + offset); Flags = (FILE_RECORD_FLAG)BitConverter.ToUInt16(bytes, 0x16 + offset); Deleted = isDeleted(Flags); Directory = isDirectory(Flags); RealSize = BitConverter.ToInt32(bytes, 0x18 + offset); AllocatedSize = BitConverter.ToInt32(bytes, 0x1C + offset); ReferenceToBase = BitConverter.ToUInt64(bytes, 0x20 + offset); NextAttrId = BitConverter.ToUInt16(bytes, 0x28 + offset); RecordNumber = BitConverter.ToUInt32(bytes, 0x2C + offset); Attribute = FileRecordAttribute.GetInstances(bytes, OffsetOfAttribute + offset, bytesPerFileRecord, volume); #region AttributeProperties foreach (FileRecordAttribute attr in Attribute) { if (attr.Name == FileRecordAttribute.ATTR_TYPE.STANDARD_INFORMATION) { StandardInformation stdInfo = attr as StandardInformation; ModifiedTime = stdInfo.ModifiedTime; AccessedTime = stdInfo.AccessedTime; ChangedTime = stdInfo.ChangedTime; BornTime = stdInfo.BornTime; Permission = stdInfo.Permission; } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.ATTRIBUTE_LIST) { if (!(Deleted)) { AttributeList attrList = null; List <FileRecordAttribute> list = new List <FileRecordAttribute>(); list.AddRange(Attribute); if (attr.NonResident) { attrList = new AttributeList(attr as NonResident); } else { attrList = attr as AttributeList; } foreach (AttrRef attribute in attrList.AttributeReference) { if (attribute.RecordNumber != RecordNumber) { FileRecord record = null; // Test if we have already parse the record if (recordArray[attribute.RecordNumber] != null) { record = recordArray[attribute.RecordNumber]; } else { // If not parse it and add it to the array record = new FileRecord(ref recordArray, bytes, bytesPerFileRecord * (int)attribute.RecordNumber, bytesPerFileRecord, volume, fast); recordArray[attribute.RecordNumber] = record; } // Add the attributes to the attribute array list.AddRange(record.Attribute); list.Remove(attr); } } Attribute = list.ToArray(); } } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.FILE_NAME) { FileName fN = attr as FileName; if (!(fN.Namespace == 2)) { Name = fN.Filename; ParentSequenceNumber = fN.ParentSequenceNumber; ParentRecordNumber = fN.ParentRecordNumber; FNModifiedTime = fN.ModifiedTime; FNAccessedTime = fN.AccessedTime; FNChangedTime = fN.ChangedTime; FNBornTime = fN.BornTime; } } } #endregion AttributeProperties #region FullName if (fast) { FullName = Name; } else { StringBuilder sb = new StringBuilder(); string volLetter = Helper.GetVolumeLetter(volume); if (RecordNumber == 0) { sb.Append(volLetter); sb.Append('\\'); sb.Append(Name); FullName = sb.ToString(); } else if (RecordNumber == 5) { FullName = volLetter; } else { FileRecord parent = null; if (recordArray[this.ParentRecordNumber] != null) { parent = recordArray[this.ParentRecordNumber]; } else { parent = new FileRecord(ref recordArray, bytes, bytesPerFileRecord * (int)this.ParentRecordNumber, bytesPerFileRecord, volume, fast); recordArray[this.ParentRecordNumber] = parent; } if (parent.SequenceNumber == this.ParentSequenceNumber) { sb.Append(parent.FullName); } else { sb.Append(@"$OrphanFiles"); } if (Name != null) { sb.Append('\\'); FullName = sb.Append(Name).ToString(); } else { FullName = sb.ToString(); } } } #endregion FullName } }
private FileRecord(byte[] recordBytes, string volume, int bytesPerFileRecord, bool fast) { if (Encoding.ASCII.GetString(recordBytes, 0x00, 0x04) == "FILE") { VolumePath = volume; OffsetOfUS = BitConverter.ToUInt16(recordBytes, 0x04); SizeOfUS = BitConverter.ToUInt16(recordBytes, 0x06); LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 0x08); SequenceNumber = BitConverter.ToUInt16(recordBytes, 0x10); Hardlinks = BitConverter.ToUInt16(recordBytes, 0x12); OffsetOfAttribute = BitConverter.ToUInt16(recordBytes, 0x14); Flags = (FILE_RECORD_FLAG)BitConverter.ToUInt16(recordBytes, 0x16); Deleted = isDeleted(Flags); Directory = isDirectory(Flags); RealSize = BitConverter.ToInt32(recordBytes, 0x18); AllocatedSize = BitConverter.ToInt32(recordBytes, 0x1C); ReferenceToBase = BitConverter.ToUInt64(recordBytes, 0x20); NextAttrId = BitConverter.ToUInt16(recordBytes, 40); RecordNumber = BitConverter.ToUInt32(recordBytes, 44); Attribute = FileRecordAttribute.GetInstances(recordBytes, OffsetOfAttribute, bytesPerFileRecord, volume); #region AttributeProperties foreach (FileRecordAttribute attr in Attribute) { if (attr.Name == FileRecordAttribute.ATTR_TYPE.STANDARD_INFORMATION) { StandardInformation stdInfo = attr as StandardInformation; ModifiedTime = stdInfo.ModifiedTime; AccessedTime = stdInfo.AccessedTime; ChangedTime = stdInfo.ChangedTime; BornTime = stdInfo.BornTime; Permission = stdInfo.Permission; } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.ATTRIBUTE_LIST) { if (!(Deleted)) { AttributeList attrList = null; List <FileRecordAttribute> list = new List <FileRecordAttribute>(); list.AddRange(Attribute); if (attr.NonResident) { attrList = new AttributeList(attr as NonResident); } else { attrList = attr as AttributeList; } foreach (AttrRef attribute in attrList.AttributeReference) { if (attribute.RecordNumber != RecordNumber) { FileRecord record = FileRecord.Get(volume, (int)attribute.RecordNumber); list.AddRange(record.Attribute); list.Remove(attr); } } Attribute = list.ToArray(); } } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.FILE_NAME) { FileName fN = attr as FileName; if (!(fN.Namespace == 2)) { Name = fN.Filename; ParentSequenceNumber = fN.ParentSequenceNumber; ParentRecordNumber = fN.ParentRecordNumber; FNModifiedTime = fN.ModifiedTime; FNAccessedTime = fN.AccessedTime; FNChangedTime = fN.ChangedTime; FNBornTime = fN.BornTime; } } } #endregion AttributeProperties #region FullName if (fast) { FullName = Name; } else { StringBuilder sb = new StringBuilder(); string volLetter = Helper.GetVolumeLetter(volume); if (RecordNumber == 0) { sb.Append(volLetter); sb.Append('\\'); sb.Append(Name); FullName = sb.ToString(); } else if (RecordNumber == 5) { FullName = volLetter; } else { FileRecord parent = new FileRecord(GetRecordBytes(volume, (int)ParentRecordNumber), volume, bytesPerFileRecord, false); if (parent.SequenceNumber == this.ParentSequenceNumber) { sb.Append(parent.FullName); } else { sb.Append(@"$OrphanFiles"); } if (Name != null) { sb.Append('\\'); FullName = sb.Append(Name).ToString(); } else { FullName = sb.ToString(); } } } #endregion FullName } }
private FileRecord(ref FileRecord[] recordArray, byte[] bytes, int offset, int bytesPerFileRecord, string volume, bool fast) { if (Encoding.ASCII.GetString(bytes, 0x00 + offset, 0x04) == "FILE") { OffsetOfUS = BitConverter.ToUInt16(bytes, 0x04 + offset); SizeOfUS = BitConverter.ToUInt16(bytes, 0x06 + offset); LogFileSequenceNumber = BitConverter.ToUInt64(bytes, 0x08 + offset); SequenceNumber = BitConverter.ToUInt16(bytes, 0x10 + offset); Hardlinks = BitConverter.ToUInt16(bytes, 0x12 + offset); OffsetOfAttribute = BitConverter.ToUInt16(bytes, 0x14 + offset); Flags = (FILE_RECORD_FLAG)BitConverter.ToUInt16(bytes, 0x16 + offset); Deleted = isDeleted(Flags); Directory = isDirectory(Flags); RealSize = BitConverter.ToInt32(bytes, 0x18 + offset); AllocatedSize = BitConverter.ToInt32(bytes, 0x1C + offset); ReferenceToBase = BitConverter.ToUInt64(bytes, 0x20 + offset); NextAttrId = BitConverter.ToUInt16(bytes, 0x28 + offset); RecordNumber = BitConverter.ToUInt32(bytes, 0x2C + offset); Attribute = FileRecordAttribute.GetInstances(bytes, OffsetOfAttribute + offset, bytesPerFileRecord, volume); //FileRecordAttribute[] attributeArray = FileRecordAttribute.GetInstances(bytes, OffsetOfAttribute + offset, bytesPerFileRecord, volume); #region AttributeProperties //bool hasAttributeList = false; //List<FileRecordAttribute> ListOfAttributes = new List<FileRecordAttribute>(); foreach (FileRecordAttribute attr in Attribute) { if (attr.Name == FileRecordAttribute.ATTR_TYPE.STANDARD_INFORMATION) { StandardInformation stdInfo = attr as StandardInformation; ModifiedTime = stdInfo.ModifiedTime; AccessedTime = stdInfo.AccessedTime; ChangedTime = stdInfo.ChangedTime; BornTime = stdInfo.BornTime; Permission = stdInfo.Permission; } /*else if (attr.Name == FileRecordAttribute.ATTR_TYPE.ATTRIBUTE_LIST) * { * if (!(attr.NonResident)) * { * AttributeList attributeList = attr as AttributeList; * hasAttributeList = true; * * List<ulong> numList = new List<ulong>(); * * foreach (AttrRef attrRef in attributeList.AttributeReference) * { * if (!(numList.Contains(attrRef.RecordNumber))) * { * numList.Add(attrRef.RecordNumber); * } * } * * foreach (ulong i in numList) * { * if (recordArray[i] == null) * { * recordArray[i] = new FileRecordTest(ref recordArray, bytes, bytesPerFileRecord * (int)i, bytesPerFileRecord, volume, false); * } * * ListOfAttributes.AddRange(recordArray[i].Attribute); * } * } * }*/ else if (attr.Name == FileRecordAttribute.ATTR_TYPE.FILE_NAME) { FileName fN = attr as FileName; if (!(fN.Namespace == 2)) { Name = fN.Filename; ParentSequenceNumber = fN.ParentSequenceNumber; ParentRecordNumber = fN.ParentRecordNumber; FNModifiedTime = fN.ModifiedTime; FNAccessedTime = fN.AccessedTime; FNChangedTime = fN.ChangedTime; FNBornTime = fN.BornTime; } } } #endregion AttributeProperties #region FullName if (fast) { FullName = Name; } else { StringBuilder sb = new StringBuilder(); string volLetter = Helper.GetVolumeLetter(volume); if (RecordNumber == 0) { sb.Append(volLetter); sb.Append('\\'); sb.Append(Name); FullName = sb.ToString(); } else if (RecordNumber == 5) { FullName = volLetter; } else { FileRecord parent = null; if (recordArray[this.ParentRecordNumber] != null) { parent = recordArray[this.ParentRecordNumber]; } else { parent = new FileRecord(ref recordArray, bytes, bytesPerFileRecord * (int)this.ParentRecordNumber, bytesPerFileRecord, volume, fast); recordArray[this.ParentRecordNumber] = parent; } if (parent.SequenceNumber == this.ParentSequenceNumber) { sb.Append(parent.FullName); } else { sb.Append(@"$OrphanFiles"); } if (Name != null) { sb.Append('\\'); FullName = sb.Append(Name).ToString(); } else { FullName = sb.ToString(); } } } #endregion FullName } }
private FileRecord(ref FileRecord[] array, byte[] bytes, int offset, string volume, uint bytesPerFileRecord) { Signature = Encoding.ASCII.GetString(bytes, 0x00 + offset, 0x04); if (Signature == "FILE") { OffsetOfUS = BitConverter.ToUInt16(bytes, 0x04 + offset); SizeOfUS = BitConverter.ToUInt16(bytes, 0x06 + offset); LogFileSequenceNumber = BitConverter.ToUInt64(bytes, 0x08 + offset); SequenceNumber = BitConverter.ToUInt16(bytes, 0x10 + offset); Hardlinks = BitConverter.ToUInt16(bytes, 0x12 + offset); OffsetOfAttribute = BitConverter.ToUInt16(bytes, 0x14 + offset); Flags = BitConverter.ToUInt16(bytes, 0x16 + offset); Deleted = IsDeleted(Flags); Directory = IsDirectory(Flags); RealSize = BitConverter.ToUInt32(bytes, 0x18 + offset); AllocatedSize = BitConverter.ToUInt32(bytes, 0x1C + offset); ReferenceToBase = BitConverter.ToUInt64(bytes, 0x20 + offset); NextAttrId = BitConverter.ToUInt16(bytes, 0x28 + offset); RecordNumber = BitConverter.ToUInt32(bytes, 0x2C + offset); #region Attribute // Instantiate an empty list of Attr Objects (We don't know how many attributes the record contains) List <FileRecordAttribute> AttributeList = new List <FileRecordAttribute>(); int currentOffset = offset + OffsetOfAttribute; do { FileRecordAttribute attr = FileRecordAttribute.GetTest(bytes, currentOffset, volume); if (attr != null) { if (attr.Name == FileRecordAttribute.ATTR_TYPE.STANDARD_INFORMATION) { StandardInformation stdInfo = attr as StandardInformation; ModifiedTime = stdInfo.ModifiedTime; AccessedTime = stdInfo.AccessedTime; ChangedTime = stdInfo.ChangedTime; BornTime = stdInfo.BornTime; Permission = stdInfo.Permission; } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.FILE_NAME) { FileName fN = attr as FileName; if (!(fN.Namespace == 2)) { Name = fN.Filename; ParentSequenceNumber = fN.ParentSequenceNumber; ParentRecordNumber = fN.ParentRecordNumber; FNModifiedTime = fN.ModifiedTime; FNAccessedTime = fN.AccessedTime; FNChangedTime = fN.ChangedTime; FNBornTime = fN.BornTime; } } AttributeList.Add(attr); } // Get attribute size int attrSizeOffset = currentOffset + 0x04; int attrSize = BitConverter.ToInt32(bytes, attrSizeOffset); if (attrSize == 0) { break; } // Increment currentOffset currentOffset += attrSize; } while ((currentOffset - offset) < bytesPerFileRecord); Attribute = AttributeList.ToArray(); #endregion Attribute /*#region FullName * * StringBuilder sb = new StringBuilder(); * * // Record 5 is the root of the drive * if (RecordNumber == 5) * { * sb.Append(Helper.GetVolumeLetter(volume)); * } * else * { * // Derive Path by looking at ParentRecord's FullName * if (array[(int)ParentRecordNumber] != null) * { * if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber) * { * sb.Append(array[(int)ParentRecordNumber].FullName); * } * else * { * sb.Append(@"$OrphanFiles\"); * } * } * * // If record for Parent does not already exist then instantiate it and add it to the array * else * { * int parentOffset = (int)bytesPerFileRecord * (int)ParentRecordNumber; * * array[(int)ParentRecordNumber] = new FileRecord(ref array, bytes, parentOffset, volume, bytesPerFileRecord); * * if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber) * { * sb.Append(array[(int)ParentRecordNumber].FullName); * } * else * { * sb.Append(@"$OrphanFiles\"); * } * } * * // Add file name to end of path * sb.Append(Name); * } * * // Add trailing \ to any file that is a directory * if (Directory) * { * sb.Append('\\'); * } * * // Figure out a way to have record 15 not have a name of $MFT... * * FullName = sb.ToString(); * #endregion FullName*/ } }