コード例 #1
0
        public void WriteToPage(byte[] buffer, ulong fileOffset)
        {
            if (ptype == PageTypeName.ptypeBBT ||
                ptype == PageTypeName.ptypeNBT ||
                ptype == PageTypeName.ptypeDL)
            {
                wSig = BlockTrailer.ComputeSignature(fileOffset, bid.Value);
            }
            else
            {
                wSig = 0;
                // AMap, PMap, FMap, and FPMap pages have a special convention where their BID is assigned the same value as their IB
                bid = new BlockID(fileOffset);
            }


            dwCRC = PSTCRCCalculation.ComputeCRC(buffer, OffsetFromPageStart);

            int offset = OffsetFromPageStart;

            buffer[offset + 0] = (byte)ptype;
            buffer[offset + 1] = (byte)ptype;
            LittleEndianWriter.WriteUInt16(buffer, offset + 2, wSig);
            LittleEndianWriter.WriteUInt32(buffer, offset + 4, dwCRC);
            LittleEndianWriter.WriteUInt64(buffer, offset + 8, bid.Value);
        }
コード例 #2
0
        public void WriteBytes(byte[] buffer, int dataLength, int offset, ulong fileOffset)
        {
            wSig = ComputeSignature(fileOffset, bid.Value);
            // CRC is only calculated on the raw data (i.e. excluding BlockTrailer and padding)
            dwCRC = PSTCRCCalculation.ComputeCRC(buffer, dataLength);

            LittleEndianWriter.WriteUInt16(buffer, offset + 0, cb);
            LittleEndianWriter.WriteUInt16(buffer, offset + 2, wSig);
            LittleEndianWriter.WriteUInt32(buffer, offset + 4, dwCRC);
            LittleEndianWriter.WriteUInt64(buffer, offset + 8, bid.Value);
        }
コード例 #3
0
        public PSTHeader(byte[] buffer)
        {
            dwMagic         = ByteReader.ReadAnsiString(buffer, 0, 4);
            CRCPartial      = LittleEndianConverter.ToUInt32(buffer, 4);
            wMagicClient    = ByteReader.ReadAnsiString(buffer, 8, 2);
            wVer            = LittleEndianConverter.ToUInt16(buffer, 10);
            wVerClient      = LittleEndianConverter.ToUInt16(buffer, 12);
            bPlatformCreate = buffer[14];
            bPlatformAccess = buffer[15];

            dwReserved1 = LittleEndianConverter.ToUInt32(buffer, 16);
            dwReserved2 = LittleEndianConverter.ToUInt32(buffer, 20);
            // bidUnused - which is not necessarily zeroed out
            bidUnused = new BlockID(buffer, 24);
            bidNextP  = new BlockID(buffer, 32);

            dwUnique = LittleEndianConverter.ToUInt32(buffer, 40);
            int position = 44;

            for (int index = 0; index < 32; index++)
            {
                rgnid[index] = LittleEndianConverter.ToUInt32(buffer, position);
                position    += 4;
            }

            root = new RootStructure(buffer, 180);

            dwAlign = LittleEndianConverter.ToUInt32(buffer, 252);
            Array.Copy(buffer, 256, rgbFM, 0, 128);
            Array.Copy(buffer, 384, rgbFP, 0, 128);
            bSentinel    = buffer[512];
            bCryptMethod = (bCryptMethodName)buffer[513];

            bidNextB = new BlockID(buffer, 516);

            dwCRCFull = LittleEndianConverter.ToUInt32(buffer, 524);
            Array.Copy(buffer, 528, rgbReserved2, 0, 3);
            bReserved = buffer[531];
            Array.Copy(buffer, 532, rgbReserved3, 0, 32);

            uint partial = PSTCRCCalculation.ComputeCRC(buffer, 8, 471);

            if (partial != CRCPartial)
            {
                throw new InvalidChecksumException();
            }
            uint full = PSTCRCCalculation.ComputeCRC(buffer, 8, 516);

            if (full != dwCRCFull)
            {
                throw new InvalidChecksumException();
            }
        }
コード例 #4
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);
        }
コード例 #5
0
        public byte[] GetBytes(WriterCompatibilityMode writerCompatibilityMode)
        {
            byte[] buffer = new byte[HeaderLength];
            ByteWriter.WriteAnsiString(buffer, 0, dwMagic, 4);
            // update CRCPartial later
            ByteWriter.WriteAnsiString(buffer, 8, wMagicClient, 2);
            LittleEndianWriter.WriteUInt16(buffer, 10, wVer);
            LittleEndianWriter.WriteUInt16(buffer, 12, wVerClient);
            buffer[14] = bPlatformCreate;
            buffer[15] = bPlatformAccess;

            LittleEndianWriter.WriteUInt32(buffer, 16, dwReserved1);
            LittleEndianWriter.WriteUInt32(buffer, 20, dwReserved2);

            bidUnused.WriteBytes(buffer, 24);
            bidNextP.WriteBytes(buffer, 32);

            LittleEndianWriter.WriteUInt32(buffer, 40, dwUnique);

            int position = 44;

            for (int index = 0; index < 32; index++)
            {
                LittleEndianWriter.WriteUInt32(buffer, position, rgnid[index]);
                position += 4;
            }

            root.WriteBytes(buffer, 180, writerCompatibilityMode);

            LittleEndianWriter.WriteUInt32(buffer, 252, dwAlign);
            Array.Copy(rgbFM, 0, buffer, 256, 128);
            Array.Copy(rgbFP, 0, buffer, 384, 128);
            buffer[512] = bSentinel;
            buffer[513] = (byte)bCryptMethod;

            bidNextB.WriteBytes(buffer, 516);

            // update dwCRCFull later
            // ullReserved
            // dwReserved
            Array.Copy(rgbReserved2, 0, buffer, 528, 3);
            buffer[531] = bReserved;
            Array.Copy(rgbReserved3, 0, buffer, 532, 32);

            CRCPartial = PSTCRCCalculation.ComputeCRC(buffer, 8, 471);
            dwCRCFull  = PSTCRCCalculation.ComputeCRC(buffer, 8, 516);
            LittleEndianWriter.WriteUInt32(buffer, 4, CRCPartial);
            LittleEndianWriter.WriteUInt32(buffer, 524, dwCRCFull);

            return(buffer);
        }
コード例 #6
0
        public override byte[] GetBytes(ulong fileOffset)
        {
            if (rgDListPageEnt.Count > MaxNumberOfEntries)
            {
                throw new Exception("Density list contains too many entries");
            }

            byte[] buffer = new byte[Length];
            buffer[0] = bFlags;
            buffer[1] = (byte)rgDListPageEnt.Count;
            LittleEndianWriter.WriteUInt32(buffer, 4, ulCurrentPage);

            int offset = 8;

            foreach (DensityListPageEntry entry in rgDListPageEnt)
            {
                entry.WriteBytes(buffer, offset);
                offset += DensityListPageEntry.Length;
            }
            pageTrailer.dwCRC = PSTCRCCalculation.ComputeCRC(buffer, Length - PageTrailer.Length);
            pageTrailer.WriteToPage(buffer, fileOffset);

            return(buffer);
        }
コード例 #7
0
ファイル: Block.cs プロジェクト: wang-xinhong/PSTFileFormat
        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);
        }