Bodu.IO.Pst Namespace
- Package
-
Bodu.IO.Pst 0.7.1
Purpose
Bodu.IO.Pst is a low-level, read-only container reader for the Outlook personal-folders format (PST / MS-PST, Unicode and ANSI formats). It reads the node database (NDB) - the header, the node and block B-trees, block data with the format's permute and cyclic content encodings decoded and checksums verified, multi-block data trees, and per-node subnode trees - and the LTP layer over it: heap-on-node, BTree-on-heap, and per-node property-context and table-context views with wire-typed values. It carries no MAPI semantics and no write support: interpreting a property as a subject or a sender is the job of the Bodu.Formats.Outlook.Pst mail-store reader layered on top, which shares the Bodu.Formats.Outlook MAPI value model with the .msg reader.
A PST file is a node-oriented database in a single file. PstFile opens it as a disposable session; every object - folders, messages, tables, internal maps - is a PstNode addressed by a 32-bit PstNodeId whose five low bits carry its PstNodeType. Payloads assemble transparently from multi-block data trees, stream through a decoded-block LRU cache, and a node's private subnode tree carries its children (a message's recipient and attachment tables, for example).
Static documentation
- Introduction - the headline types, the layering beneath the mail-store reader, and the scenarios the library covers.
- Core concepts - node database, NID/BID, data and subnode trees, heap-on-node, property and table contexts, validation levels.
- Getting started - install and minimal samples for opening, enumerating, and reading.
- Binary Formats & I/O topic overview - where the container sits beneath the format readers.
Key types
Session and nodes
- PstFile - the disposable read session. Factories
OpenRead(path /Stream) andOpen(Stream, options, leaveOpen), the cheapIsPstFileprobe;Format/CryptMethod, the node directory viaEnumerateNodes, and lookup viaGetNode/TryGetNode. - PstNode - one node.
ReadAllBytes(buffered),OpenDataStream(a seekable read-only stream keeping one leaf block resident, bound to the session - it throws once the session is disposed),DataLength(priced without payload reads);EnumerateSubnodes/TryGetSubnode; and the LTP viewsReadPropertyContext/ReadTableContext. - PstNodeId / PstNodeType - the 32-bit identifier (five type bits + 27-bit index) with the well-known anchors
MessageStore(0x21),NameToIdMap(0x61), andRootFolder(0x122). - PstNodeInfo - an immutable directory snapshot: identifier, parent, payload length, and whether subnodes are present.
LTP views
- PstPropertyContext - the node's property bag: a tag-ordered collection of PstPropertyValue entries (16-bit property identifier, raw wire type, payload resolved on access, typed accessors) with
TryGetValue/GetValue, plus the streaming pairTryGetValueLength/TryOpenValueStreamthat prices or reads a value without materializing it. - PstTableContext - the node's table: PstTableColumn metadata,
RowCount, streamingEnumerateRows(one matrix block resident at a time), and keyedTryGetRow. PstTableRow exposesRowId,TryGetCell,EnumerateCells, and the streaming pairTryGetCellLength/TryOpenCellStream.
Options and formats
- PstFileOptions -
ValidationLevel(PstValidationLevel:Compatible/Strict/Minimal) and the decoded-block LRUBlockCacheSize(default 256 entries;0disables). - PstFileFormat / PstCryptMethod - the header's declared variant (both
UnicodeandAnsiare read; the OST variant is rejected) and content encoding.
Errors
- PstFileException (base, with a PstFileError category), PstFileFormatException (malformed content at the active validation level), PstUnsupportedFormatException (recognized but unsupported variant - the 4 KiB-page OST), PstNodeNotFoundException (a
GetNodemiss).
Example
using Bodu.IO.Pst;
using PstFile file = PstFile.OpenRead("archive.pst");
// The store object's raw property bag.
PstNode store = file.GetNode(PstNodeId.MessageStore);
foreach (PstPropertyValue value in store.ReadPropertyContext())
Console.WriteLine($"0x{value.PropertyId:X4} (wire 0x{value.WireType:X4}): {value.RawData.Length} bytes");
// The root folder's hierarchy table: each row identifier is a child folder's node identifier.
var hierarchyId = new PstNodeId(PstNodeType.HierarchyTable, PstNodeId.RootFolder.Index);
if (file.TryGetNode(hierarchyId, out PstNode? table))
{
foreach (PstTableRow row in table.ReadTableContext().EnumerateRows())
Console.WriteLine($"child folder 0x{row.RowId:X8}");
}
Classes
- PstFile
Provides a disposable, read-only session over a PST file's node database (Unicode or ANSI format): the header facts, the node directory, and per-node data and subnode access.
- PstFileException
Represents an error raised while reading a PST file. Serves as the base of the library's exception hierarchy.
- PstFileFormatException
Represents an error raised when a PST file's structure is malformed or fails validation.
- PstFileOptions
Controls how a PstFile is opened and validated.
- PstNode
Represents one node of the node database: raw access to its data payload and its subnode tree.
- PstNodeInfo
Provides an immutable snapshot of a node's directory facts: its identifier, its parent, the size of its data payload, and whether it carries a subnode tree.
- PstNodeNotFoundException
Represents a lookup for a node that does not exist in the file.
- PstPropertyContext
Represents a node's property context (
PC): the LTP property bag of 16-bit property identifiers with wire-typed values, in the manner the exploration plan sketches - format-agnostic, with no MAPI semantics.
- PstTableContext
Represents a node's table context (
TC): the LTP table of typed columns over identifier-keyed rows, with forward-only row enumeration and keyed row lookup - format-agnostic, with no MAPI semantics.
- PstTableRow
Represents one row of a table context: the row identifier and cell access by column property identifier.
- PstUnsupportedFormatException
Represents an error raised when a PST file is recognized but uses a format variant or content encoding the library does not read (the 4 KiB-page OST variant or Windows Information Protection encryption).
Structs
- PstNodeId
Represents a 32-bit node identifier: five type bits in the low positions and a 27-bit index above them (MS-PST §2.2.2.1).
- PstPropertyValue
Represents one property value of a property context or table-context row: the 16-bit property identifier, the raw wire type code, and the resolved little-endian payload with typed accessors over it.
- PstTableColumn
Represents one column of a table context: its 16-bit property identifier, its raw wire type code, and its cell width within a row.
Enums
- PstCryptMethod
Identifies how a file's external block data is encoded (the header's
bCryptMethodvalues).
- PstFileError
Categorizes the failure a PstFileException reports, so callers can distinguish a missing object from structural corruption without parsing messages.
- PstFileFormat
Identifies the on-disk PST format variant, discriminated by the header's
wVerfield.
- PstNodeType
Identifies the kind of object a node holds - the five type bits of a PstNodeId (the
NID_TYPE_*values of MS-PST §2.2.2.1).
- PstValidationLevel
Specifies how strictly a file's structures and checksums are validated while reading.