public DataBlock(byte[] buffer, bCryptMethodName bCryptMethod) : base(buffer) { m_bCryptMethod = bCryptMethod; Data = new byte[BlockTrailer.cb]; Array.Copy(buffer, Data, BlockTrailer.cb); // DataBlock's data may be decoded Data = GetDecodedData(); }
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(); } }
// Data tree root is either a single data block, or an XBlock / XXBlock public DataTree(PSTFile file, Block rootBlock) : base(file) { m_bCryptMethod = file.Header.bCryptMethod; m_rootBlock = rootBlock; }
private Block m_rootBlock; // can be DataBlock, XBlock or XXBlock (or null [if we deleted the data tree]) /// <summary> /// Create new data tree /// </summary> public DataTree(PSTFile file) : base(file) { m_bCryptMethod = file.Header.bCryptMethod; m_rootBlock = new DataBlock(m_bCryptMethod); AddBlock(m_rootBlock); }
public DataBlock(bCryptMethodName bCryptMethod) { m_bCryptMethod = bCryptMethod; }
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); }