Beispiel #1
0
        private void LoadData(MFTLoadDepth loadDepth = MFTLoadDepth.Full)
        {
            if (loadDepth.CompareTo(_dataLoaded) <= 0)
            {
                // If we're not loading more than we already have, just stop here.
                return;
            }

            string Magic = Encoding.ASCII.GetString(_data, 0, 4);

            if (!Magic.Equals("FILE"))
            {
                Console.Error.WriteLine("Warning: MFT record number {0} was missing the 'FILE' header. Skipping.", RecordNum);
                // This record is invalid, so don't read any more.
                Valid = false;
                return;
            }

            ushort updateSequenceOffset = BitConverter.ToUInt16(_data, 4);
            ushort updateSequenceLength = BitConverter.ToUInt16(_data, 6);

            ushort updateSequenceNumber = BitConverter.ToUInt16(_data, updateSequenceOffset);

            ushort[] updateSequenceArray = new ushort[updateSequenceLength - 1];
            ushort   read = 1;

            while (read < updateSequenceLength)
            {
                updateSequenceArray[read - 1] = BitConverter.ToUInt16(_data, (ushort)(updateSequenceOffset + read * 2));
                read++;
            }

            // Apply fixups to the in-memory array
            try {
                FixupStream.FixArray(_data, updateSequenceNumber, updateSequenceArray, (int)BytesPerSector);
            } catch (NTFSFixupException e) {
                Console.Error.WriteLine(e);
                // This record is invalid, so don't read any more.
                Valid = false;
                return;
            }

            LoadHeader();
            LoadAttributes(AttributeOffset, loadDepth);

            if (_attributes.Count == 0)
            {
                Console.Error.WriteLine("Warning: MFT record number {0} had no attributes.", RecordNum);
            }

            _dataLoaded = loadDepth;

            // If we've loaded everything, dispose of the underlying byte array.
            if (_dataLoaded == MFTLoadDepth.Full)
            {
                _data = null;
            }
        }
Beispiel #2
0
        private MFTRecord(ulong recordNum, FileSystemNTFS fileSystem, byte[] data,
                          MFTLoadDepth loadDepth, string path)
        {
            this.RecordNum         = recordNum;
            this.FileSystem        = fileSystem;
            this.BytesPerSector    = fileSystem.BytesPerSector;
            this.SectorsPerCluster = fileSystem.SectorsPerCluster;
            this.PartitionStream   = fileSystem.Store;

            Valid = true;

            _data = data;
            _path = path;

            Flags = (RecordFlags)BitConverter.ToUInt16(_data, 22);

            if (loadDepth != MFTLoadDepth.None)
            {
                LoadData(loadDepth);
            }
        }
Beispiel #3
0
        public static MFTRecord Load(ulong recordNum, FileSystemNTFS fileSystem, MFTLoadDepth loadDepth = MFTLoadDepth.Full, string path = "")
        {
            ulong startOffset = recordNum * (ulong)fileSystem.SectorsPerMFTRecord * (ulong)fileSystem.BytesPerSector;

            IDataStream stream;

            //Special case for MFT - can't read itself
            if (recordNum == 0)
            {
                stream = new SubStream(fileSystem.Store, fileSystem.MFTSector * (ulong)fileSystem.BytesPerSector, (ulong)(fileSystem.SectorsPerMFTRecord * fileSystem.BytesPerSector));
            }
            else
            {
                stream = new SubStream(fileSystem.MFT, startOffset, (ulong)(fileSystem.SectorsPerMFTRecord * fileSystem.BytesPerSector));
            }

            // Read the whole record into memory
            byte[] data = stream.GetBytes(0, stream.StreamLength);

            return(new MFTRecord(recordNum, fileSystem, data, loadDepth, path));
        }
Beispiel #4
0
        private void LoadAttributes(int startOffset, MFTLoadDepth loadDepth)
        {
            _attributes = new List <MFTAttribute>();
            while (true)
            {
                //Align to 8 byte boundary
                if (startOffset % 8 != 0)
                {
                    startOffset = (startOffset / 8 + 1) * 8;
                }

                // Read the attribute type and length and determine whether we care about this attribute.
                AttributeType type = (AttributeType)BitConverter.ToUInt32(_data, startOffset);
                if (type == AttributeType.End)
                {
                    break;
                }
                int length = BitConverter.ToUInt16(_data, startOffset + 4);
                if (loadDepth == MFTLoadDepth.NameAttributeOnly && type != AttributeType.FileName)
                {
                    // Skip this attribute if we're only loading the filename
                    startOffset += length;
                    continue;
                }

                MFTAttribute attribute = MFTAttribute.Load(_data, startOffset, this);
                if (!attribute.NonResident)
                {
                    switch (attribute.Type)
                    {
                    case AttributeType.StandardInformation:
                        LoadStandardAttribute(startOffset + attribute.ValueOffset);
                        break;

                    case AttributeType.FileName:
                        LoadNameAttribute(startOffset + attribute.ValueOffset);
                        break;

                    case AttributeType.AttributeList:
                        LoadExternalAttributeList(startOffset + attribute.ValueOffset, attribute);
                        break;

                    case AttributeType.VolumeLabel:
                        LoadVolumeLabelAttribute(startOffset + attribute.ValueOffset, (int)attribute.ValueLength);
                        break;
                    }
                }
                if (attribute.Valid)
                {
                    if (attribute.Type == AttributeType.Data)
                    {
                        if (attribute.Name == null)
                        {
                            if (_dataAttribute != null)
                            {
                                Console.Error.WriteLine("Warning: multiple unnamed data streams found on MFT record {0}.", RecordNum);
                            }
                            _dataAttribute = attribute;
                        }
                        else
                        {
                            _namedDataAttributes.Add(attribute);
                        }
                    }
                    _attributes.Add(attribute);
                }

                startOffset += (int)attribute.Length;
            }
        }
		private void LoadAttributes(int startOffset, MFTLoadDepth loadDepth) {
			_attributes = new List<MFTAttribute>();
			while (true) {
				//Align to 8 byte boundary
				if (startOffset % 8 != 0) {
					startOffset = (startOffset / 8 + 1) * 8;
				}

				// Read the attribute type and length and determine whether we care about this attribute.
				AttributeType type = (AttributeType)BitConverter.ToUInt32(_data, startOffset);
				if (type == AttributeType.End) {
					break;
				}
				int length = BitConverter.ToUInt16(_data, startOffset + 4);
				if (loadDepth == MFTLoadDepth.NameAttributeOnly && type != AttributeType.FileName) {
					// Skip this attribute if we're only loading the filename
					startOffset += length;
					continue;
				}

				MFTAttribute attribute = MFTAttribute.Load(_data, startOffset, this);
				if (!attribute.NonResident) {
					switch (attribute.Type) {
						case AttributeType.StandardInformation:
							LoadStandardAttribute(startOffset + attribute.ValueOffset);
							break;
						case AttributeType.FileName:
							LoadNameAttribute(startOffset + attribute.ValueOffset);
							break;
						case AttributeType.AttributeList:
							LoadExternalAttributeList(startOffset + attribute.ValueOffset, attribute);
							break;
						case AttributeType.VolumeLabel:
							LoadVolumeLabelAttribute(startOffset + attribute.ValueOffset, (int)attribute.ValueLength);
							break;
					}
				}
				if (attribute.Valid) {
					if (attribute.Type == AttributeType.Data) {
						if (attribute.Name == null) {
							if (_dataAttribute != null) {
								Console.Error.WriteLine("Warning: multiple unnamed data streams found on MFT record {0}.", RecordNum);
							}
							_dataAttribute = attribute;
						} else {
							_namedDataAttributes.Add(attribute);
						}
					}
					_attributes.Add(attribute);
				}

				startOffset += (int)attribute.Length;
			}
		}
		private void LoadData(MFTLoadDepth loadDepth = MFTLoadDepth.Full) {
			if (loadDepth.CompareTo(_dataLoaded) <= 0) {
				// If we're not loading more than we already have, just stop here.
				return;
			}

			string Magic = Encoding.ASCII.GetString(_data, 0, 4);
			if (!Magic.Equals("FILE")) {
				Console.Error.WriteLine("Warning: MFT record number {0} was missing the 'FILE' header. Skipping.", RecordNum);
				// This record is invalid, so don't read any more.
				Valid = false;
				return;
			}

			ushort updateSequenceOffset = BitConverter.ToUInt16(_data, 4);
			ushort updateSequenceLength = BitConverter.ToUInt16(_data, 6);

			ushort updateSequenceNumber = BitConverter.ToUInt16(_data, updateSequenceOffset);
			ushort[] updateSequenceArray = new ushort[updateSequenceLength - 1];
			ushort read = 1;
			while (read < updateSequenceLength) {
				updateSequenceArray[read - 1] = BitConverter.ToUInt16(_data, (ushort)(updateSequenceOffset + read * 2));
				read++;
			}

			// Apply fixups to the in-memory array
			try {
				FixupStream.FixArray(_data, updateSequenceNumber, updateSequenceArray, (int)BytesPerSector);
			} catch (NTFSFixupException e) {
				Console.Error.WriteLine(e);
				// This record is invalid, so don't read any more.
				Valid = false;
				return;
			}

			LoadHeader();
			LoadAttributes(AttributeOffset, loadDepth);

			if (_attributes.Count == 0) {
				Console.Error.WriteLine("Warning: MFT record number {0} had no attributes.", RecordNum);
			}

			_dataLoaded = loadDepth;

			// If we've loaded everything, dispose of the underlying byte array.
			if (_dataLoaded == MFTLoadDepth.Full) {
				_data = null;
			}
		}
		private MFTRecord(ulong recordNum, FileSystemNTFS fileSystem, byte[] data,
				MFTLoadDepth loadDepth, string path) {
			this.RecordNum = recordNum;
			this.FileSystem = fileSystem;
			this.BytesPerSector = fileSystem.BytesPerSector;
			this.SectorsPerCluster = fileSystem.SectorsPerCluster;
			this.PartitionStream = fileSystem.Store;

			Valid = true;

			_data = data;
			_path = path;

			Flags = (RecordFlags)BitConverter.ToUInt16(_data, 22);

			if (loadDepth != MFTLoadDepth.None) {
				LoadData(loadDepth);
			}
		}
		public static MFTRecord Load(ulong recordNum, FileSystemNTFS fileSystem, MFTLoadDepth loadDepth = MFTLoadDepth.Full, string path = "") {
			ulong startOffset = recordNum * (ulong)fileSystem.SectorsPerMFTRecord * (ulong)fileSystem.BytesPerSector;

			IDataStream stream;

			//Special case for MFT - can't read itself
			if (recordNum == 0) {
				stream = new SubStream(fileSystem.Store, fileSystem.MFTSector * (ulong)fileSystem.BytesPerSector, (ulong)(fileSystem.SectorsPerMFTRecord * fileSystem.BytesPerSector));
			} else {
				stream = new SubStream(fileSystem.MFT, startOffset, (ulong)(fileSystem.SectorsPerMFTRecord * fileSystem.BytesPerSector));
			}

			// Read the whole record into memory
			byte[] data = stream.GetBytes(0, stream.StreamLength);

			return new MFTRecord(recordNum, fileSystem, data, loadDepth, path);
		}