Beispiel #1
0
 public RootStructure(byte[] buffer, int offset)
 {
     ibFileEOF  = LittleEndianConverter.ToUInt64(buffer, offset + 4);
     ibAMapLast = LittleEndianConverter.ToUInt64(buffer, offset + 12);
     cbAMapFree = LittleEndianConverter.ToUInt64(buffer, offset + 20);
     cbPMapFree = LittleEndianConverter.ToUInt64(buffer, offset + 28);
     BREFNBT    = new BlockRef(buffer, offset + 36);
     BREFBBT    = new BlockRef(buffer, offset + 52);
     fAMapValid = ByteReader.ReadByte(buffer, offset + 68);
     bReserved  = ByteReader.ReadByte(buffer, offset + 69);
     wReserved  = LittleEndianConverter.ToUInt16(buffer, offset + 70);
 }
Beispiel #2
0
        public static BTreePage ReadFromStream(Stream stream, BlockRef blockRef)
        {
            long offset = (long)blockRef.ib;

            stream.Seek(offset, SeekOrigin.Begin);
            byte[] buffer = new byte[Length];
            stream.Read(buffer, 0, Length);
            PageTypeName ptype = (PageTypeName)buffer[PageTrailer.OffsetFromPageStart + 0];
            BTreePage    page;
            byte         cLevel = buffer[491];

            if (cLevel > 0)
            {
                // If cLevel is greater than 0, then each entry in the array is of type BTENTRY.
                page = new BTreeIndexPage(buffer);
            }
            else
            {
                // If cLevel is 0, then each entry is either of type BBTENTRY or NBTENTRY, depending on the ptype of the page.
                if (ptype == PageTypeName.ptypeBBT)
                {
                    page = new BlockBTreeLeafPage(buffer);
                }
                else if (ptype == PageTypeName.ptypeNBT)
                {
                    page = new NodeBTreeLeafPage(buffer);
                }
                else
                {
                    throw new ArgumentException("BTreePage has incorrect ptype");
                }
            }
            page.Offset = (ulong)blockRef.ib;
            if (blockRef.bid.Value != page.BlockID.Value)
            {
                throw new InvalidBlockIDException();
            }
            uint crc = PSTCRCCalculation.ComputeCRC(buffer, PageTrailer.OffsetFromPageStart);

            if (page.pageTrailer.dwCRC != crc)
            {
                throw new InvalidChecksumException();
            }

            uint signature = BlockTrailer.ComputeSignature(blockRef.ib, blockRef.bid.Value);

            if (page.pageTrailer.wSig != signature)
            {
                throw new InvalidChecksumException();
            }
            return(page);
        }
Beispiel #3
0
        public BTreePage GetPage(BlockRef blockRef)
        {
            ulong blockID = blockRef.bid.Value;

            if (m_pageBuffer.ContainsKey(blockID))
            {
                return(m_pageBuffer[blockID]);
            }
            else
            {
                BTreePage page = BTreePage.ReadFromStream(m_file.BaseStream, blockRef);
                m_pageBuffer.Add(blockRef.bid.Value, page);
                return(page);
            }
        }
Beispiel #4
0
 public BTreeIndexEntry(byte[] buffer, int offset)
 {
     btkey = LittleEndianConverter.ToUInt64(buffer, offset + 0);
     BREF  = new BlockRef(buffer, offset + 8);
 }
Beispiel #5
0
 public BTreeIndexEntry()
 {
     BREF = new BlockRef();
 }
Beispiel #6
0
        public static Block ReadFromStream(Stream stream, BlockRef blockRef, int dataLength, bCryptMethodName bCryptMethod)
        {
            long offset      = (long)blockRef.ib;
            int  totalLength = GetTotalBlockLength(dataLength);

            stream.Seek(offset, SeekOrigin.Begin);
            byte[] buffer = new byte[totalLength];
            stream.Read(buffer, 0, totalLength);

            BlockTrailer trailer = BlockTrailer.ReadFromEndOfBuffer(buffer);
            Block        block;

            if (trailer.bid.Internal)
            {
                // XBlock or XXBlock
                byte btype  = buffer[0];
                byte cLevel = buffer[1];
                if (btype == (byte)BlockType.XBlock && cLevel == 0x01)
                {
                    // XBLOCK
                    block = new XBlock(buffer);
                }
                else if (btype == (byte)BlockType.XXBlock && cLevel == 0x02)
                {
                    // XXBLOCK
                    block = new XXBlock(buffer);
                }
                else if (btype == (byte)BlockType.SLBLOCK && cLevel == 0x00)
                {
                    // SLBLock
                    block = new SubnodeLeafBlock(buffer);
                }
                else if (btype == (byte)BlockType.SIBLOCK && cLevel == 0x01)
                {
                    // SIBLock
                    block = new SubnodeIntermediateBlock(buffer);
                }
                else
                {
                    throw new Exception("Internal block, but not XBLOCK, XXBlock, SLBLOCK or SIBLOCK");
                }
            }
            else
            {
                block = new DataBlock(buffer, bCryptMethod);
            }

            // See question 3 at:
            // http://social.msdn.microsoft.com/Forums/en-CA/os_binaryfile/thread/923f5964-4a89-4811-86c2-06a553c34510
            // However, so far all tests suggest that there should be no problem to use BlockID.Value for both arguments
            if (blockRef.bid.LookupValue != block.BlockID.LookupValue)
            {
                throw new InvalidBlockIDException();
            }

            if (dataLength != trailer.cb)
            {
                throw new Exception("Invalid block length");
            }

            uint crc = PSTCRCCalculation.ComputeCRC(buffer, dataLength);

            if (block.BlockTrailer.dwCRC != crc)
            {
                throw new InvalidChecksumException();
            }

            uint signature = BlockTrailer.ComputeSignature(blockRef.ib, blockRef.bid.Value);

            if (block.BlockTrailer.wSig != signature)
            {
                throw new InvalidChecksumException();
            }

            return(block);
        }
Beispiel #7
0
 public BlockBTreeEntry(byte[] buffer, int offset)
 {
     BREF = new BlockRef(buffer, offset + 0);
     cb   = LittleEndianConverter.ToUInt16(buffer, offset + 16);
     cRef = LittleEndianConverter.ToUInt16(buffer, offset + 18);
 }
Beispiel #8
0
        public ushort cRef; // Reference count: indicating the count of references to this block.
        //public uint dwPadding

        public BlockBTreeEntry()
        {
            BREF = new BlockRef();
        }