Пример #1
0
        public BTPage(byte[] pageData, BREF _ref, PSTFile pst)
        {
            this._ref             = _ref;
            this.InternalChildren = new List <BTPage>();
            this._trailer         = new PageTrailer(pageData.RangeSubset(496, 16));
            this._numEntries      = pageData[488];
            this._maxEntries      = pageData[489];
            this._cbEnt           = pageData[490];
            this._cLevel          = pageData[491];

            this.Entries = new List <BTPAGEENTRY>();
            for (var i = 0; i < this._numEntries; i++)
            {
                var curEntryBytes = pageData.RangeSubset(i * this._cbEnt, this._cbEnt);
                if (this._cLevel == 0)
                {
                    if (this._trailer.PageType == PageType.NBT)
                    {
                        this.Entries.Add(new NBTENTRY(curEntryBytes));
                    }
                    else
                    {
                        var curEntry = new BBTENTRY(curEntryBytes);
                        this.Entries.Add(curEntry);
                    }
                }
                else
                {
                    //btentries
                    var entry = new BTENTRY(curEntryBytes);
                    this.Entries.Add(entry);
                    using (var view = pst.PSTMMF.CreateViewAccessor((long)entry.BREF.IB, 512))
                    {
                        var bytes = new byte[512];
                        view.ReadArray(0, bytes, 0, 512);
                        this.InternalChildren.Add(new BTPage(bytes, entry.BREF, pst));
                    }
                }
            }
        }
Пример #2
0
        private static Dictionary <ulong, NodeDataDTO> GetSubNodeData(BBTENTRY entry, PSTFile pst, int take = int.MaxValue)
        {
            var allData   = GetBBTEntryData(entry, pst);
            var dataBlock = allData[0];

            if (entry.Internal)
            {
                var type   = dataBlock.Data[0];
                var cLevel = dataBlock.Data[1];
                if (cLevel == 0) //SLBlock, no intermediate
                {
                    return(GetSLBlockData(new SLBLOCK(dataBlock), pst, take));
                }
                else //SIBlock
                {
                    return(GetSIBlockData(new SIBLOCK(dataBlock), pst));
                }
            }
            else
            {
                throw new Exception("Whoops");
            }
        }
Пример #3
0
        //for a given bbt entry, retrieve the raw bytes associated with the BID
        //this includes retrieving data trees via xblocks
        public static List <BlockDataDTO> GetBBTEntryData(BBTENTRY entry, PSTFile pst)
        {
            if (entry == null)
            {
                throw new InvalidDataException("Failed while parsing BBTEntry, the data block was invalid, try running a PST repair");
            }

            var dataSize  = entry.BlockByteCount;
            var blockSize = entry.BlockByteCount + 16;

            if (blockSize % 64 != 0)
            {
                blockSize += 64 - (blockSize % 64);
            }
            List <BlockDataDTO> dataBlocks;

            /*if (isSubNode)
             * {
             *  using (var viewer = PSTFile.PSTMMF.CreateViewAccessor((long)entry.BREF.IB, blockSize))
             *  {
             *      var blockBytes = new byte[dataSize];
             *      viewer.ReadArray(0, blockBytes, 0, dataSize);
             *      dataBlocks = new List<BlockDataDTO>
             *                       {new BlockDataDTO {Data = blockBytes, PstOffset = entry.BREF.IB, BBTEntry = entry}};
             *      return dataBlocks;
             *  }
             * } else */
            if (entry.Internal)
            {
                using (var viewer = pst.PSTMMF.CreateViewAccessor((long)entry.BREF.IB, blockSize))
                {
                    var blockBytes = new byte[dataSize];
                    viewer.ReadArray(0, blockBytes, 0, dataSize);

                    var trailerBytes = new byte[16];
                    viewer.ReadArray(blockSize - 16, trailerBytes, 0, 16);
                    var trailer = new BlockTrailer(trailerBytes, 0);

                    var dataBlockDTO = new BlockDataDTO
                    {
                        Data      = blockBytes,
                        PstOffset = entry.BREF.IB,
                        CRCOffset = (uint)((long)entry.BREF.IB + (blockSize - 12)),
                        BBTEntry  = entry
                    };
                    var type  = blockBytes[0];
                    var level = blockBytes[1];

                    if (type == 2) //si or sl entry
                    {
                        return(new List <BlockDataDTO> {
                            dataBlockDTO
                        });
                    }
                    else if (type == 1)
                    {
                        if (blockBytes[1] == 0x01) //XBLOCK
                        {
                            var xblock = new XBLOCK(dataBlockDTO);
                            return(BlockBO.GetXBlockData(xblock, pst));
                        }
                        else //XXBLOCK
                        {
                            var xxblock = new XXBLOCK(dataBlockDTO);
                            return(BlockBO.GetXXBlockData(xxblock, pst));
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }
            else
            {
                using (var viewer = pst.PSTMMF.CreateViewAccessor((long)entry.BREF.IB, blockSize))
                {
                    var dataBytes = new byte[dataSize];
                    viewer.ReadArray(0, dataBytes, 0, dataSize);

                    var trailerBytes = new byte[16];
                    viewer.ReadArray(blockSize - 16, trailerBytes, 0, 16);
                    var trailer = new BlockTrailer(trailerBytes, 0);
                    dataBlocks = new List <BlockDataDTO>
                    {
                        new BlockDataDTO
                        {
                            Data      = dataBytes,
                            PstOffset = entry.BREF.IB,
                            CRC32     = trailer.CRC,
                            CRCOffset = (uint)(blockSize - 12),
                            BBTEntry  = entry
                        }
                    };
                }
            }

            for (int i = 0; i < dataBlocks.Count; i++)
            {
                var temp = dataBlocks[i].Data;
                DatatEncoder.CryptPermute(temp, temp.Length, false, pst);
            }
            return(dataBlocks);
        }