public void UpdateHeapHeader(HeapOnNodeHeader header) { HeapOnNodeFirstBlockData blockData = (HeapOnNodeFirstBlockData)GetBlockData(0); blockData.HeapHeader = header; UpdateBuffer(0, blockData); }
// We no longer create new TCs, we simply use the template and modify to another data tree public static TableContext CreateNewTableContext(PSTFile file, List <TableColumnDescriptor> columns) { HeapOnNode heap = HeapOnNode.CreateNewHeap(file); TableContextInfo tcInfo = new TableContextInfo(); tcInfo.rgTCOLDESC = columns; tcInfo.UpdateDataLayout(); HeapID newUserRoot = heap.AddItemToHeap(tcInfo.GetBytes()); // The heap header may have just been updated HeapOnNodeHeader header = heap.HeapHeader; header.bClientSig = OnHeapTypeName.bTypeTC; header.hidUserRoot = newUserRoot; heap.UpdateHeapHeader(header); BTreeOnHeapHeader bTreeHeader = new BTreeOnHeapHeader(); bTreeHeader.cbKey = TableContextRowID.RecordKeyLength; bTreeHeader.cbEnt = TableContextRowID.RecordDataLength; tcInfo.hidRowIndex = heap.AddItemToHeap(bTreeHeader.GetBytes()); // this will replace the item in place (as they have the same size since number of columns was not modified) heap.ReplaceHeapItem(header.hidUserRoot, tcInfo.GetBytes()); return(new TableContext(heap, null)); }
/// <summary> /// http://social.msdn.microsoft.com/Forums/en-US/os_binaryfile/thread/a5f9c653-40f5-4638-85d3-00c54607d984/ /// Outlook 2003 MUST have a valid rgbFillLevel for write operations /// </summary> private void UpdateFillLevelMap() { int blocksToProcess = Math.Min(m_dataTree.DataBlockCount, 8); HeapOnNodeHeader header = this.HeapHeader; for (int blockIndex = 0; blockIndex < blocksToProcess; blockIndex++) { if (m_blocksToUpdate.Contains(blockIndex)) { HeapOnNodeBlockData blockData = GetBlockData(blockIndex); byte fillLevel = HeapOnNodeHelper.GetBlockFillLevel(blockData); header.rgbFillLevel[blockIndex] = fillLevel; } } UpdateHeapHeader(header); for (int blockIndex = 8; blockIndex < m_dataTree.DataBlockCount; blockIndex += 128) { int blocksLeft = m_dataTree.DataBlockCount - blockIndex; blocksToProcess = Math.Min(blocksLeft, 128); HeapOnNodeBitmapHeader bitmapHeader = GetBitmapHeader(blockIndex); for (int blockOffset = 0; blockOffset < blocksToProcess; blockOffset++) { if (m_blocksToUpdate.Contains(blockIndex + blockOffset)) { HeapOnNodeBlockData blockData = GetBlockData(blockIndex + blockOffset); byte fillLevel = HeapOnNodeHelper.GetBlockFillLevel(blockData); bitmapHeader.rgbFillLevel[blockOffset] = fillLevel; } } UpdateBitmapHeader(blockIndex, bitmapHeader); blocksLeft -= blocksToProcess; } }
public void UpdateTableContextInfo() { HeapID newUserRootHeapID = m_heap.ReplaceHeapItem(m_heap.HeapHeader.hidUserRoot, m_tcInfo.GetBytes()); if (m_heap.HeapHeader.hidUserRoot != newUserRootHeapID) { HeapOnNodeHeader heapHeader = m_heap.HeapHeader; heapHeader.hidUserRoot = newUserRootHeapID; m_heap.UpdateHeapHeader(heapHeader); } }
/// <param name="subnodeBTree">Subnode BTree that will be associated with the new PC</param> public static PropertyContext CreateNewPropertyContext(PSTFile file, SubnodeBTree subnodeBTree) { HeapOnNode heap = HeapOnNode.CreateNewHeap(file); BTreeOnHeapHeader bTreeHeader = new BTreeOnHeapHeader(); bTreeHeader.cbKey = PropertyContextRecord.RecordKeyLength; bTreeHeader.cbEnt = PropertyContextRecord.RecordDataLength; HeapID newUserRoot = heap.AddItemToHeap(bTreeHeader.GetBytes()); // The heap header may have just been updated HeapOnNodeHeader header = heap.HeapHeader; header.bClientSig = OnHeapTypeName.bTypePC; header.hidUserRoot = newUserRoot; heap.UpdateHeapHeader(header); heap.FlushToDataTree(); return(new PropertyContext(heap, subnodeBTree)); }
public HeapOnNodeFirstBlockData(byte[] buffer) { HeapHeader = new HeapOnNodeHeader(buffer, 0); PopulateHeapItems(buffer, HeapHeader.ibHnpm); }
/// <summary> /// Create new first block /// </summary> public HeapOnNodeFirstBlockData() { HeapHeader = new HeapOnNodeHeader(); }