コード例 #1
0
        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);
        }
コード例 #2
0
        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;
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
 public void Reset()
 {
     _attributes.Clear();
     _flags           = FileRecordFlags.None;
     _hardLinkCount   = 0;
     _nextAttributeId = 0;
     _recordRealSize  = 0;
 }
コード例 #5
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;
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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;
        }
コード例 #9
0
ファイル: FileRecord.cs プロジェクト: joconno4/MediaPortal-2
        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;
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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;
        }
コード例 #12
0
        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);
        }
コード例 #13
0
ファイル: File.cs プロジェクト: git-thinh/MediaPortal-2
        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);
        }
コード例 #14
0
        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;
        }
コード例 #15
0
        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;
        }
コード例 #16
0
ファイル: NtfsFileSystem.cs プロジェクト: alexcmd/DiscUtils
        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;
        }
コード例 #17
0
ファイル: FileRecord.cs プロジェクト: AnotherAltr/Rc.Core
        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;
        }
コード例 #18
0
ファイル: FileRecord.cs プロジェクト: AnotherAltr/Rc.Core
 public void Reset()
 {
     _attributes.Clear();
     _flags = FileRecordFlags.None;
     _hardLinkCount = 0;
     _nextAttributeId = 0;
     _recordRealSize = 0;
 }
コード例 #19
0
ファイル: FileRecord.cs プロジェクト: AnotherAltr/Rc.Core
        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;
            }
        }
コード例 #20
0
ファイル: NtfsFormatter.cs プロジェクト: AnotherAltr/Rc.Core
        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;
        }
コード例 #21
0
ファイル: File.cs プロジェクト: alexcmd/DiscUtils
        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;
        }
コード例 #22
0
        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;
        }
コード例 #23
0
ファイル: File.cs プロジェクト: joconno4/MediaPortal-2
        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;
        }