public FileRecord AllocateRecord(FileRecordFlags flags) { long index = _bitmap.AllocateFirstAvailable(FirstAvailableMftIndex); if (index * _recordLength >= _recordStream.Length) { // Note: 64 is significant, since bitmap extends by 8 bytes (=64 bits) at a time. long newEndIndex = Utilities.RoundUp(index + 1, 64); for (long i = index; i < newEndIndex; ++i) { FileRecord record = new FileRecord(_bytesPerSector, _recordLength, (uint)i); WriteRecord(record); } } FileRecord newRecord = GetRecord(index, true); newRecord.ReInitialize(_bytesPerSector, _recordLength, (uint)index); _recordCache[index] = newRecord; newRecord.Flags = FileRecordFlags.InUse | flags; WriteRecord(newRecord); _self.UpdateRecordInMft(); return(newRecord); }
protected override void Read(byte[] buffer, int offset) { _logFileSequenceNumber = Utilities.ToUInt64LittleEndian(buffer, offset + 0x08); _sequenceNumber = Utilities.ToUInt16LittleEndian(buffer, offset + 0x10); _hardLinkCount = Utilities.ToUInt16LittleEndian(buffer, offset + 0x12); _firstAttributeOffset = Utilities.ToUInt16LittleEndian(buffer, offset + 0x14); _flags = (FileRecordFlags)Utilities.ToUInt16LittleEndian(buffer, offset + 0x16); _recordRealSize = Utilities.ToUInt32LittleEndian(buffer, offset + 0x18); _recordAllocatedSize = Utilities.ToUInt32LittleEndian(buffer, offset + 0x1C); _baseFile = new FileRecordReference(Utilities.ToUInt64LittleEndian(buffer, offset + 0x20)); _nextAttributeId = Utilities.ToUInt16LittleEndian(buffer, offset + 0x28); if (UpdateSequenceOffset >= 0x30) { _index = Utilities.ToUInt32LittleEndian(buffer, offset + 0x2C); _haveIndex = true; } _attributes = new List <AttributeRecord>(); int focus = _firstAttributeOffset; while (true) { int length; AttributeRecord attr = AttributeRecord.FromBytes(buffer, focus, out length); if (attr == null) { break; } _attributes.Add(attr); focus += (int)length; } }
public static File CreateNew(INtfsContext context, FileRecordFlags flags, FileAttributeFlags dirFlags) { File newFile = context.AllocateFile(flags); FileAttributeFlags fileFlags = FileAttributeFlags.Archive | FileRecord.ConvertFlags(flags) | (dirFlags & FileAttributeFlags.Compressed); AttributeFlags dataAttrFlags = AttributeFlags.None; if ((dirFlags & FileAttributeFlags.Compressed) != 0) { dataAttrFlags |= AttributeFlags.Compressed; } StandardInformation.InitializeNewFile(newFile, fileFlags); if (context.ObjectIds != null) { Guid newId = CreateNewGuid(context); NtfsStream stream = newFile.CreateStream(AttributeType.ObjectId, null); ObjectId objId = new ObjectId(); objId.Id = newId; stream.SetContent(objId); context.ObjectIds.Add(newId, newFile.MftReference, newId, Guid.Empty, Guid.Empty); } newFile.CreateAttribute(AttributeType.Data, dataAttrFlags); newFile.UpdateRecordInMft(); return(newFile); }
public void Reset() { _attributes.Clear(); _flags = FileRecordFlags.None; _hardLinkCount = 0; _nextAttributeId = 0; _recordRealSize = 0; }
public FileRecordSegment(byte[] buffer, int offset, int bytesPerSector, long segmentNumber) { Signature = ByteReader.ReadAnsiString(buffer, offset + 0x00, 4); ushort updateSequenceArrayOffset = LittleEndianConverter.ToUInt16(buffer, offset + 0x04); ushort updateSequenceArraySize = LittleEndianConverter.ToUInt16(buffer, offset + 0x06); LogFileSequenceNumber = LittleEndianConverter.ToUInt64(buffer, offset + 0x08); SequenceNumber = LittleEndianConverter.ToUInt16(buffer, offset + 0x10); HardLinkCount = LittleEndianConverter.ToUInt16(buffer, offset + 0x12); ushort firstAttributeOffset = LittleEndianConverter.ToUInt16(buffer, offset + 0x14); m_flags = (FileRecordFlags)LittleEndianConverter.ToUInt16(buffer, offset + 0x16); uint segmentRealSize = LittleEndianConverter.ToUInt32(buffer, offset + 0x18); uint segmentAllocatedSize = LittleEndianConverter.ToUInt32(buffer, offset + 0x1C); BaseFileRecordSegmentNumber = LittleEndianConverter.ToUInt64(buffer, offset + 0x20); NextAttributeId = LittleEndianConverter.ToUInt16(buffer, offset + 0x28); // 2 zeros - padding MftSegmentNumberXP = LittleEndianConverter.ToUInt32(buffer, offset + 0x2C); // There is an UpdateSequenceNumber for the FileRecordSegment, // and an entry in the UpdateSequenceArray for each sector of the record // The last two bytes of each sector contains this entry for integrity-check purposes int position = offset + updateSequenceArrayOffset; UpdateSequenceNumber = LittleEndianConverter.ToUInt16(buffer, position); position += 2; // This stores the data that was supposed to be placed at the end of each sector, and was replaced with an UpdateSequenceNumber List <byte[]> updateSequenceReplacementData = new List <byte[]>(); for (int index = 0; index < updateSequenceArraySize - 1; index++) { byte[] endOfSectorBytes = new byte[2]; endOfSectorBytes[0] = buffer[position + 0]; endOfSectorBytes[1] = buffer[position + 1]; updateSequenceReplacementData.Add(endOfSectorBytes); position += 2; } MultiSectorHelper.DecodeSegmentBuffer(buffer, offset, UpdateSequenceNumber, updateSequenceReplacementData); // read attributes position = offset + firstAttributeOffset; while (!IsEndMarker(buffer, position)) { AttributeRecord attribute = AttributeRecord.FromBytes(buffer, position); m_immediateAttributes.Add(attribute); position += (int)attribute.StoredRecordLength; if (position > buffer.Length) { throw new InvalidDataException("Improper attribute length"); } } m_mftSegmentNumber = segmentNumber; }
public FileRecord AllocateRecord(FileRecordFlags flags, bool isMft) { long index; if (isMft) { // Have to take a lot of care extending the MFT itself, to ensure we never end up unable to // bootstrap the file system via the MFT itself - hence why special records are reserved // for MFT's own MFT record overflow. for (int i = 15; i > 11; --i) { FileRecord r = GetRecord(i, false); if (r.BaseFile.SequenceNumber == 0) { r.Reset(); r.Flags |= FileRecordFlags.InUse; WriteRecord(r); return(r); } } throw new IOException("MFT too fragmented - unable to allocate MFT overflow record"); } else { index = _bitmap.AllocateFirstAvailable(FirstAvailableMftIndex); } if (index * _recordLength >= _recordStream.Length) { // Note: 64 is significant, since bitmap extends by 8 bytes (=64 bits) at a time. long newEndIndex = Utilities.RoundUp(index + 1, 64); _recordStream.SetLength(newEndIndex * _recordLength); for (long i = index; i < newEndIndex; ++i) { FileRecord record = new FileRecord(_bytesPerSector, _recordLength, (uint)i); WriteRecord(record); } } FileRecord newRecord = GetRecord(index, true); newRecord.ReInitialize(_bytesPerSector, _recordLength, (uint)index); _recordCache[index] = newRecord; newRecord.Flags = FileRecordFlags.InUse | flags; WriteRecord(newRecord); _self.UpdateRecordInMft(); return(newRecord); }
public FileRecord AllocateRecord(long index, FileRecordFlags flags) { _bitmap.MarkPresent(index); FileRecord newRecord = new FileRecord(_bytesPerSector, _recordLength, (uint)index); _recordCache[index] = newRecord; newRecord.Flags = FileRecordFlags.InUse | flags; WriteRecord(newRecord); _self.UpdateRecordInMft(); return(newRecord); }
public void ReInitialize(int sectorSize, int recordLength, uint index) { Initialize("FILE", sectorSize, recordLength); _sequenceNumber++; _flags = FileRecordFlags.None; _recordAllocatedSize = (uint)recordLength; _nextAttributeId = 0; _index = index; _hardLinkCount = 0; _baseFile = new FileRecordReference(0); _attributes = new List <AttributeRecord>(); _haveIndex = true; }
public void ReInitialize(int sectorSize, int recordLength, uint index) { Initialize("FILE", sectorSize, recordLength); _sequenceNumber++; _flags = FileRecordFlags.None; _recordAllocatedSize = (uint)recordLength; _nextAttributeId = 0; _index = index; _hardLinkCount = 0; _baseFile = new FileRecordReference(0); _attributes = new List<AttributeRecord>(); _haveIndex = true; }
private File CreateSystemFile(long mftIndex, FileRecordFlags flags) { FileRecord fileRec = _context.Mft.AllocateRecord((uint)mftIndex, flags); fileRec.SequenceNumber = (ushort)mftIndex; File file = new File(_context, fileRec); StandardInformation.InitializeNewFile(file, FileAttributeFlags.Hidden | FileAttributeFlags.System | FileRecord.ConvertFlags(flags)); file.CreateStream(AttributeType.Data, null); file.UpdateRecordInMft(); return(file); }
public FileRecordSegment(byte[] buffer, int offset, long segmentNumber) { MultiSectorHeader multiSectorHeader = new MultiSectorHeader(buffer, offset + 0x00); if (multiSectorHeader.Signature != ValidSignature) { throw new InvalidDataException("Invalid FILE record signature"); } LogFileSequenceNumber = LittleEndianConverter.ToUInt64(buffer, offset + 0x08); m_sequenceNumber = LittleEndianConverter.ToUInt16(buffer, offset + 0x10); ReferenceCount = LittleEndianConverter.ToUInt16(buffer, offset + 0x12); ushort firstAttributeOffset = LittleEndianConverter.ToUInt16(buffer, offset + 0x14); m_flags = (FileRecordFlags)LittleEndianConverter.ToUInt16(buffer, offset + 0x16); uint segmentLength = LittleEndianConverter.ToUInt32(buffer, offset + 0x18); uint segmentAllocatedLength = LittleEndianConverter.ToUInt32(buffer, offset + 0x1C); m_baseFileRecordSegment = new MftSegmentReference(buffer, offset + 0x20); NextAttributeInstance = LittleEndianConverter.ToUInt16(buffer, offset + 0x28); // 2 bytes padding m_segmentNumberOnDisk = LittleEndianConverter.ToUInt32(buffer, offset + 0x2C); UpdateSequenceNumber = LittleEndianConverter.ToUInt16(buffer, offset + multiSectorHeader.UpdateSequenceArrayOffset); if (firstAttributeOffset % 8 > 0) { throw new InvalidDataException("Corrupt file record segment, first attribute not aligned to 8-byte boundary"); } // Read attributes int position = offset + firstAttributeOffset; while (!IsEndMarker(buffer, position)) { AttributeRecord attribute = AttributeRecord.FromBytes(buffer, position); m_immediateAttributes.Add(attribute); position += (int)attribute.RecordLengthOnDisk; if (position > buffer.Length) { throw new InvalidDataException("Invalid attribute length"); } } m_segmentNumber = segmentNumber; }
internal static FileAttributeFlags ConvertFlags(FileRecordFlags source) { FileAttributeFlags result = FileAttributeFlags.None; if ((source & FileRecordFlags.IsDirectory) != 0) { result |= FileAttributeFlags.Directory; } if ((source & FileRecordFlags.HasViewIndex) != 0) { result |= FileAttributeFlags.IndexView; } if ((source & FileRecordFlags.IsMetaFile) != 0) { result |= FileAttributeFlags.Hidden | FileAttributeFlags.System; } return(result); }
internal static File CreateNew(INtfsContext context, FileRecordFlags flags) { DateTime now = DateTime.UtcNow; File newFile = context.AllocateFile(flags); StandardInformation.InitializeNewFile(newFile, FileAttributeFlags.Archive | FileRecord.ConvertFlags(flags)); if (context.ObjectIds != null) { Guid newId = CreateNewGuid(context); NtfsStream stream = newFile.CreateStream(AttributeType.ObjectId, null); ObjectId objId = new ObjectId(); objId.Id = newId; stream.SetContent(objId); context.ObjectIds.Add(newId, newFile.MftReference, newId, Guid.Empty, Guid.Empty); } newFile.CreateAttribute(AttributeType.Data, AttributeFlags.None); newFile.UpdateRecordInMft(); return(newFile); }
public FileRecord AllocateRecord(FileRecordFlags flags, bool isMft) { long index; if (isMft) { // Have to take a lot of care extending the MFT itself, to ensure we never end up unable to // bootstrap the file system via the MFT itself - hence why special records are reserved // for MFT's own MFT record overflow. for (int i = 15; i > 11; --i) { FileRecord r = GetRecord(i, false); if (r.BaseFile.SequenceNumber == 0) { r.Reset(); r.Flags |= FileRecordFlags.InUse; WriteRecord(r); return r; } } throw new IOException("MFT too fragmented - unable to allocate MFT overflow record"); } else { index = _bitmap.AllocateFirstAvailable(FirstAvailableMftIndex); } if (index * _recordLength >= _recordStream.Length) { // Note: 64 is significant, since bitmap extends by 8 bytes (=64 bits) at a time. long newEndIndex = Utilities.RoundUp(index + 1, 64); _recordStream.SetLength(newEndIndex * _recordLength); for (long i = index; i < newEndIndex; ++i) { FileRecord record = new FileRecord(_bytesPerSector, _recordLength, (uint)i); WriteRecord(record); } } FileRecord newRecord = GetRecord(index, true); newRecord.ReInitialize(_bytesPerSector, _recordLength, (uint)index); _recordCache[index] = newRecord; newRecord.Flags = FileRecordFlags.InUse | flags; WriteRecord(newRecord); _self.UpdateRecordInMft(); return newRecord; }
public FileRecord AllocateRecord(FileRecordFlags flags) { long index = _bitmap.AllocateFirstAvailable(FirstAvailableMftIndex); if (index * _recordLength >= _recordStream.Length) { // Note: 64 is significant, since bitmap extends by 8 bytes (=64 bits) at a time. long newEndIndex = Utilities.RoundUp(index + 1, 64); for (long i = index; i < newEndIndex; ++i) { FileRecord record = new FileRecord(_bytesPerSector, _recordLength, (uint)i); WriteRecord(record); } } FileRecord newRecord = GetRecord(index, true); newRecord.ReInitialize(_bytesPerSector, _recordLength, (uint)index); _recordCache[index] = newRecord; newRecord.Flags = FileRecordFlags.InUse | flags; WriteRecord(newRecord); _self.UpdateRecordInMft(); return newRecord; }
internal File AllocateFile(FileRecordFlags flags) { File result = null; if ((flags & FileRecordFlags.IsDirectory) != 0) { result = new Directory(_context, _context.Mft.AllocateRecord(flags, false)); } else { result = new File(_context, _context.Mft.AllocateRecord(flags, false)); } _fileCache[result.MftReference.MftIndex] = result; return result; }
public static FileAttributeFlags ConvertFlags(FileRecordFlags source) { FileAttributeFlags result = FileAttributeFlags.None; if ((source & FileRecordFlags.IsDirectory) != 0) { result |= FileAttributeFlags.Directory; } if ((source & FileRecordFlags.HasViewIndex) != 0) { result |= FileAttributeFlags.IndexView; } if ((source & FileRecordFlags.IsMetaFile) != 0) { result |= FileAttributeFlags.Hidden | FileAttributeFlags.System; } return result; }
protected override void Read(byte[] buffer, int offset) { _logFileSequenceNumber = Utilities.ToUInt64LittleEndian(buffer, offset + 0x08); _sequenceNumber = Utilities.ToUInt16LittleEndian(buffer, offset + 0x10); _hardLinkCount = Utilities.ToUInt16LittleEndian(buffer, offset + 0x12); _firstAttributeOffset = Utilities.ToUInt16LittleEndian(buffer, offset + 0x14); _flags = (FileRecordFlags)Utilities.ToUInt16LittleEndian(buffer, offset + 0x16); _recordRealSize = Utilities.ToUInt32LittleEndian(buffer, offset + 0x18); _recordAllocatedSize = Utilities.ToUInt32LittleEndian(buffer, offset + 0x1C); _baseFile = new FileRecordReference(Utilities.ToUInt64LittleEndian(buffer, offset + 0x20)); _nextAttributeId = Utilities.ToUInt16LittleEndian(buffer, offset + 0x28); if (UpdateSequenceOffset >= 0x30) { _index = Utilities.ToUInt32LittleEndian(buffer, offset + 0x2C); _haveIndex = true; } _attributes = new List<AttributeRecord>(); int focus = _firstAttributeOffset; while (true) { int length; AttributeRecord attr = AttributeRecord.FromBytes(buffer, focus, out length); if (attr == null) { break; } _attributes.Add(attr); focus += (int)length; } }
private File CreateSystemFile(long mftIndex, FileRecordFlags flags) { FileRecord fileRec = _context.Mft.AllocateRecord((uint)mftIndex, flags); fileRec.SequenceNumber = (ushort)mftIndex; File file = new File(_context, fileRec); StandardInformation.InitializeNewFile(file, FileAttributeFlags.Hidden | FileAttributeFlags.System | FileRecord.ConvertFlags(flags)); file.CreateStream(AttributeType.Data, null); file.UpdateRecordInMft(); return file; }
public static File CreateNew(INtfsContext context, FileRecordFlags flags, FileAttributeFlags dirFlags) { File newFile = context.AllocateFile(flags); FileAttributeFlags fileFlags = FileAttributeFlags.Archive | FileRecord.ConvertFlags(flags) | (dirFlags & FileAttributeFlags.Compressed); AttributeFlags dataAttrFlags = AttributeFlags.None; if ((dirFlags & FileAttributeFlags.Compressed) != 0) { dataAttrFlags |= AttributeFlags.Compressed; } StandardInformation.InitializeNewFile(newFile, fileFlags); if (context.ObjectIds != null) { Guid newId = CreateNewGuid(context); NtfsStream stream = newFile.CreateStream(AttributeType.ObjectId, null); ObjectId objId = new ObjectId(); objId.Id = newId; stream.SetContent(objId); context.ObjectIds.Add(newId, newFile.MftReference, newId, Guid.Empty, Guid.Empty); } newFile.CreateAttribute(AttributeType.Data, dataAttrFlags); newFile.UpdateRecordInMft(); return newFile; }
public FileRecord AllocateRecord(long index, FileRecordFlags flags) { _bitmap.MarkPresent(index); FileRecord newRecord = new FileRecord(_bytesPerSector, _recordLength, (uint)index); _recordCache[index] = newRecord; newRecord.Flags = FileRecordFlags.InUse | flags; WriteRecord(newRecord); _self.UpdateRecordInMft(); return newRecord; }
internal static File CreateNew(INtfsContext context, FileRecordFlags flags) { DateTime now = DateTime.UtcNow; File newFile = context.AllocateFile(flags); StandardInformation.InitializeNewFile(newFile, FileAttributeFlags.Archive | FileRecord.ConvertFlags(flags)); if (context.ObjectIds != null) { Guid newId = CreateNewGuid(context); NtfsStream stream = newFile.CreateStream(AttributeType.ObjectId, null); ObjectId objId = new ObjectId(); objId.Id = newId; stream.SetContent(objId); context.ObjectIds.Add(newId, newFile.MftReference, newId, Guid.Empty, Guid.Empty); } newFile.CreateAttribute(AttributeType.Data, AttributeFlags.None); newFile.UpdateRecordInMft(); return newFile; }