Example #1
0
 private UsnJrnl(byte[] bytes, string volume, ref int offset)
 {
     uint RecordLength = RecordLength = BitConverter.ToUInt32(bytes, (0x00 + offset));
     VolumePath = volume;
     Version = new System.Version(BitConverter.ToUInt16(bytes, (0x04 + offset)), BitConverter.ToUInt16(bytes, (0x06 + offset)));
     RecordNumber = (BitConverter.ToUInt64(bytes, (0x08 + offset)) & 0x0000FFFFFFFFFFFF);
     FileSequenceNumber = ParentFileSequenceNumber = BitConverter.ToUInt16(bytes, (0x0E + offset));
     ParentFileRecordNumber = (BitConverter.ToUInt64(bytes, (0x10 + offset)) & 0x0000FFFFFFFFFFFF);
     ParentFileSequenceNumber = BitConverter.ToUInt16(bytes, (0x16 + offset));
     Usn = BitConverter.ToUInt64(bytes, (0x18 + offset));
     TimeStamp = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, (0x20 + offset)));
     Reason = ((USN_REASON)BitConverter.ToUInt32(bytes, (0x28 + offset)));
     SourceInfo = ((USN_SOURCE)BitConverter.ToUInt32(bytes, (0x2C + offset)));
     SecurityId = BitConverter.ToUInt32(bytes, (0x30 + offset));
     FileAttributes = ((StandardInformation.ATTR_STDINFO_PERMISSION)BitConverter.ToUInt32(bytes, (0x34 + offset)));
     ushort fileNameLength = BitConverter.ToUInt16(bytes, (0x38 + offset));
     ushort fileNameOffset = BitConverter.ToUInt16(bytes, (0x3A + offset));
     FileName = Encoding.Unicode.GetString(bytes, 0x3C + offset, fileNameLength);
     offset += (int)RecordLength;
 }
Example #2
0
        private UsnJrnl(byte[] bytes, string volume, ref int offset)
        {
            uint RecordLength = RecordLength = BitConverter.ToUInt32(bytes, (0x00 + offset));

            VolumePath               = volume;
            Version                  = new System.Version(BitConverter.ToUInt16(bytes, (0x04 + offset)), BitConverter.ToUInt16(bytes, (0x06 + offset)));
            RecordNumber             = (BitConverter.ToUInt64(bytes, (0x08 + offset)) & 0x0000FFFFFFFFFFFF);
            FileSequenceNumber       = ParentFileSequenceNumber = BitConverter.ToUInt16(bytes, (0x0E + offset));
            ParentFileRecordNumber   = (BitConverter.ToUInt64(bytes, (0x10 + offset)) & 0x0000FFFFFFFFFFFF);
            ParentFileSequenceNumber = BitConverter.ToUInt16(bytes, (0x16 + offset));
            Usn            = BitConverter.ToUInt64(bytes, (0x18 + offset));
            TimeStamp      = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, (0x20 + offset)));
            Reason         = ((USN_REASON)BitConverter.ToUInt32(bytes, (0x28 + offset)));
            SourceInfo     = ((USN_SOURCE)BitConverter.ToUInt32(bytes, (0x2C + offset)));
            SecurityId     = BitConverter.ToUInt32(bytes, (0x30 + offset));
            FileAttributes = ((StandardInformation.ATTR_STDINFO_PERMISSION)BitConverter.ToUInt32(bytes, (0x34 + offset)));
            ushort fileNameLength = BitConverter.ToUInt16(bytes, (0x38 + offset));
            ushort fileNameOffset = BitConverter.ToUInt16(bytes, (0x3A + offset));

            FileName = Encoding.Unicode.GetString(bytes, 0x3C + offset, fileNameLength);
            offset  += (int)RecordLength;
        }
        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
            }
        }
        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 = Util.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
            }
        }
Example #7
0
        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
            }
        }
Example #8
0
        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
            }
        }
Example #9
0
        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
            }
        }
Example #10
0
        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

                //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 = 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
            }
        }
Example #11
0
        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*/
            }
        }
Example #12
0
        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*/
            }
        }