예제 #1
0
        public byte[] GetBytes(int bytesPerIndexRecord)
        {
            int               strideCount             = bytesPerIndexRecord / MultiSectorHelper.BytesPerStride;
            ushort            updateSequenceArraySize = (ushort)(1 + strideCount);
            MultiSectorHeader multiSectorHeader       = new MultiSectorHeader(ValidSignature, UpdateSequenceArrayOffset, updateSequenceArraySize);

            int updateSequenceArrayPaddedLength = (int)Math.Ceiling((double)(updateSequenceArraySize * 2) / 8) * 8;

            m_indexHeader.EntriesOffset   = (uint)(IndexHeader.Length + updateSequenceArrayPaddedLength);
            m_indexHeader.TotalLength     = (uint)(IndexHeader.Length + updateSequenceArrayPaddedLength + IndexEntry.GetLength(IndexEntries));
            m_indexHeader.AllocatedLength = (uint)(bytesPerIndexRecord - IndexHeaderOffset);

            byte[] buffer = new byte[bytesPerIndexRecord];
            multiSectorHeader.WriteBytes(buffer, 0x00);
            LittleEndianWriter.WriteUInt64(buffer, 0x08, LogFileSequenceNumber);
            LittleEndianWriter.WriteUInt64(buffer, 0x10, (ulong)RecordVBN);
            m_indexHeader.WriteBytes(buffer, 0x18);

            IndexEntry.WriteIndexEntries(buffer, UpdateSequenceArrayOffset + updateSequenceArrayPaddedLength, IndexEntries);

            // Write UpdateSequenceNumber and UpdateSequenceReplacementData
            List <byte[]> updateSequenceReplacementData = MultiSectorHelper.EncodeSegmentBuffer(buffer, 0, bytesPerIndexRecord, UpdateSequenceNumber);

            MultiSectorHelper.WriteUpdateSequenceArray(buffer, UpdateSequenceArrayOffset, updateSequenceArraySize, UpdateSequenceNumber, updateSequenceReplacementData);
            return(buffer);
        }
예제 #2
0
        /// <param name="segmentLength">This refers to the maximum length of FileRecord as defined in the Volume's BootRecord</param>
        public byte[] GetBytes(int bytesPerFileRecordSegment, ushort minorNTFSVersion)
        {
            int    strideCount             = bytesPerFileRecordSegment / MultiSectorHelper.BytesPerStride;
            ushort updateSequenceArraySize = (ushort)(1 + strideCount);

            ushort updateSequenceArrayOffset;

            if (minorNTFSVersion == 0)
            {
                updateSequenceArrayOffset = NTFS30UpdateSequenceArrayOffset;
            }
            else
            {
                updateSequenceArrayOffset = NTFS31UpdateSequenceArrayOffset;
            }

            MultiSectorHeader multiSectorHeader    = new MultiSectorHeader(ValidSignature, updateSequenceArrayOffset, updateSequenceArraySize);
            ushort            firstAttributeOffset = GetFirstAttributeOffset(bytesPerFileRecordSegment, minorNTFSVersion);

            byte[] buffer = new byte[bytesPerFileRecordSegment];
            multiSectorHeader.WriteBytes(buffer, 0x00);
            LittleEndianWriter.WriteUInt64(buffer, 0x08, LogFileSequenceNumber);
            LittleEndianWriter.WriteUInt16(buffer, 0x10, m_sequenceNumber);
            LittleEndianWriter.WriteUInt16(buffer, 0x12, ReferenceCount);
            LittleEndianWriter.WriteUInt16(buffer, 0x14, firstAttributeOffset);
            LittleEndianWriter.WriteUInt16(buffer, 0x16, (ushort)m_flags);

            LittleEndianWriter.WriteInt32(buffer, 0x1C, bytesPerFileRecordSegment);
            m_baseFileRecordSegment.WriteBytes(buffer, 0x20);
            LittleEndianWriter.WriteUInt16(buffer, 0x28, NextAttributeInstance);
            if (minorNTFSVersion == 1)
            {
                LittleEndianWriter.WriteUInt32(buffer, 0x2C, (uint)m_segmentNumber);
            }

            // write attributes
            int position = firstAttributeOffset;

            foreach (AttributeRecord attribute in m_immediateAttributes)
            {
                byte[] attributeBytes = attribute.GetBytes();
                ByteWriter.WriteBytes(buffer, position, attributeBytes);
                position += attributeBytes.Length;
            }

            byte[] marker = GetEndMarker();
            ByteWriter.WriteBytes(buffer, position, marker);
            position += marker.Length;
            position += 4; // record (length) is aligned to 8-byte boundary

            uint segmentLength = (uint)position;

            LittleEndianWriter.WriteUInt32(buffer, 0x18, segmentLength);

            // Write UpdateSequenceNumber and UpdateSequenceReplacementData
            List <byte[]> updateSequenceReplacementData = MultiSectorHelper.EncodeSegmentBuffer(buffer, 0, bytesPerFileRecordSegment, UpdateSequenceNumber);

            MultiSectorHelper.WriteUpdateSequenceArray(buffer, updateSequenceArrayOffset, updateSequenceArraySize, UpdateSequenceNumber, updateSequenceReplacementData);
            return(buffer);
        }
예제 #3
0
        public byte[] GetBytes(int bytesPerLogPage, int dataOffset)
        {
            int               strideCount             = bytesPerLogPage / MultiSectorHelper.BytesPerStride;
            ushort            updateSequenceArraySize = (ushort)(1 + strideCount);
            MultiSectorHeader multiSectorHeader       = new MultiSectorHeader(ValidSignature, UpdateSequenceArrayOffset, updateSequenceArraySize);
            ushort            nextRecordOffset        = (ushort)(dataOffset + Data.Length);

            byte[] buffer = new byte[bytesPerLogPage];
            multiSectorHeader.WriteBytes(buffer, 0);
            LittleEndianWriter.WriteUInt64(buffer, 0x08, LastLsnOrFileOffset);
            LittleEndianWriter.WriteUInt32(buffer, 0x10, (uint)Flags);
            LittleEndianWriter.WriteUInt16(buffer, 0x14, PageCount);
            LittleEndianWriter.WriteUInt16(buffer, 0x16, PagePosition);
            LittleEndianWriter.WriteUInt16(buffer, 0x18, nextRecordOffset);
            LittleEndianWriter.WriteUInt64(buffer, 0x20, LastEndLsn);
            ByteWriter.WriteBytes(buffer, dataOffset, Data);

            // Write UpdateSequenceNumber and UpdateSequenceReplacementData
            List <byte[]> updateSequenceReplacementData = MultiSectorHelper.EncodeSegmentBuffer(buffer, 0, bytesPerLogPage, UpdateSequenceNumber);

            MultiSectorHelper.WriteUpdateSequenceArray(buffer, UpdateSequenceArrayOffset, updateSequenceArraySize, UpdateSequenceNumber, updateSequenceReplacementData);
            return(buffer);
        }
예제 #4
0
        public byte[] GetBytes(int bytesPerSystemPage)
        {
            m_systemPageSize = (uint)bytesPerSystemPage;
            int               strideCount             = bytesPerSystemPage / MultiSectorHelper.BytesPerStride;
            ushort            updateSequenceArraySize = (ushort)(1 + strideCount);
            MultiSectorHeader multiSectorHeader       = new MultiSectorHeader(ValidSignature, UpdateSequenceArrayOffset, updateSequenceArraySize);
            int               restartOffset           = (int)Math.Ceiling((double)(UpdateSequenceArrayOffset + updateSequenceArraySize * 2) / 8) * 8;

            byte[] buffer = new byte[bytesPerSystemPage];
            multiSectorHeader.WriteBytes(buffer, 0);
            LittleEndianWriter.WriteUInt64(buffer, 0x08, ChkDskLsn);
            LittleEndianWriter.WriteUInt32(buffer, 0x10, m_systemPageSize);
            LittleEndianWriter.WriteUInt32(buffer, 0x14, LogPageSize);
            LittleEndianWriter.WriteUInt16(buffer, 0x18, (ushort)restartOffset);
            LittleEndianWriter.WriteInt16(buffer, 0x1A, MinorVersion);
            LittleEndianWriter.WriteInt16(buffer, 0x1C, MajorVersion);
            LogRestartArea.WriteBytes(buffer, restartOffset);

            // Write UpdateSequenceNumber and UpdateSequenceReplacementData
            List <byte[]> updateSequenceReplacementData = MultiSectorHelper.EncodeSegmentBuffer(buffer, 0, bytesPerSystemPage, UpdateSequenceNumber);

            MultiSectorHelper.WriteUpdateSequenceArray(buffer, UpdateSequenceArrayOffset, updateSequenceArraySize, UpdateSequenceNumber, updateSequenceReplacementData);
            return(buffer);
        }
예제 #5
0
        /// <param name="segmentLength">This refers to the maximum length of FileRecord as defined in the Volume's BootRecord</param>
        public byte[] GetBytes(int segmentLength, int bytesPerCluster, ushort minorNTFSVersion)
        {
            int    strideCount             = segmentLength / MultiSectorHelper.BytesPerStride;
            ushort updateSequenceArraySize = (ushort)(1 + strideCount);

            ushort updateSequenceArrayOffset;

            if (minorNTFSVersion == 0)
            {
                updateSequenceArrayOffset = NTFS30UpdateSequenceArrayOffset;
            }
            else
            {
                updateSequenceArrayOffset = NTFS31UpdateSequenceArrayOffset;
            }

            ushort firstAttributeOffset = GetFirstAttributeOffset(segmentLength, minorNTFSVersion);

            byte[] buffer = new byte[segmentLength];
            ByteWriter.WriteAnsiString(buffer, 0, Signature, 4);
            LittleEndianWriter.WriteUInt16(buffer, 0x04, updateSequenceArrayOffset);
            LittleEndianWriter.WriteUInt16(buffer, 0x06, updateSequenceArraySize);
            LittleEndianWriter.WriteUInt64(buffer, 0x08, LogFileSequenceNumber);
            LittleEndianWriter.WriteUInt16(buffer, 0x10, SequenceNumber);
            LittleEndianWriter.WriteUInt16(buffer, 0x12, HardLinkCount);
            LittleEndianWriter.WriteUInt16(buffer, 0x14, firstAttributeOffset);
            LittleEndianWriter.WriteUInt16(buffer, 0x16, (ushort)m_flags);

            LittleEndianWriter.WriteInt32(buffer, 0x1C, segmentLength);
            LittleEndianWriter.WriteUInt64(buffer, 0x20, BaseFileRecordSegmentNumber);
            LittleEndianWriter.WriteUInt16(buffer, 0x28, NextAttributeId);
            if (minorNTFSVersion == 1)
            {
                LittleEndianWriter.WriteUInt32(buffer, 0x2C, MftSegmentNumberXP);
            }

            // write attributes
            int position = firstAttributeOffset;

            foreach (AttributeRecord attribute in m_immediateAttributes)
            {
                byte[] attributeBytes = attribute.GetBytes(bytesPerCluster);
                ByteWriter.WriteBytes(buffer, position, attributeBytes);
                position += attributeBytes.Length;
            }

            byte[] marker = GetEndMarker();
            ByteWriter.WriteBytes(buffer, position, marker);
            position += marker.Length;
            position += 4; // record (length) is aligned to 8-byte boundary

            uint segmentRealSize = (uint)position;

            LittleEndianWriter.WriteUInt32(buffer, 0x18, segmentRealSize);

            // write UpdateSequenceNumber and UpdateSequenceReplacementData
            List <byte[]> updateSequenceReplacementData = MultiSectorHelper.EncodeSegmentBuffer(buffer, 0, segmentLength, UpdateSequenceNumber);

            position = updateSequenceArrayOffset;
            LittleEndianWriter.WriteUInt16(buffer, position, UpdateSequenceNumber);
            position += 2;
            foreach (byte[] endOfSectorBytes in updateSequenceReplacementData)
            {
                ByteWriter.WriteBytes(buffer, position, endOfSectorBytes);
                position += 2;
            }

            return(buffer);
        }