PST Forge Documentation

PST Forge is a high-performance, cross-platform C++ library for creating Microsoft Outlook PST files programmatically. Unlike other libraries, it does not require Outlook to be installed and works on Windows, Linux, and macOS.

Features

  • No Outlook Dependency: Generate PSTs on any server or client machine.
  • Cross-Platform: Works on Windows (MSVC), Linux (GCC/Clang), and macOS.
  • Comprehensive Item Support:
    • Messages (Emails) with Rich Text/HTML bodies
    • Calendar Events (Appointments, Meetings, Recurrence)
    • Tasks (Status, Due Dates)
    • Journal Entries
  • Attachments: Full support for adding file attachments.
  • Unicode Support: Full UTF-8 support for subjects, bodies, and filenames (including Emojis 🚀).
  • Node.js Bindings: Native N-API bindings for using high-performance C++ from JavaScript.

Installation (Enterprise Edition)

C++ SDK

Include the static library and headers from your distribution package.

# CMakeList.txt
find_package(PSTWriter REQUIRED)
target_link_libraries(myapp PRIVATE PSTWriter::Static)

Node.js Module

Install via your private registry or local tarball:

npm install @enterprise/pst-writer

C++ Quick Start

Here's a complete example generating a PST with a folder and a message.

#include "pst_writer/pst_writer.hpp"
#include "pst_writer/message.hpp"

using namespace pst_writer;

int main() {
    // 1. Initialize Writer
    PSTWriter writer("output.pst", CompatibilityMode::Standard);

    // 2. Create Folder
    writer.createFolder("Inbox");

    // 3. Create Message
    Message msg;
    msg.subject = "Hello World";
    msg.body_plain = "This is a test message.";
    msg.from_name = "PST Writer";
    msg.from_email = "bot@example.com";
    
    // Add Recipient
    msg.recipients.push_back({"User", "user@example.com", RecipientType::To});

    // Add Attachment (Binary Data)
    std::string content = "Attachment content";
    std::vector<uint8_t> data(content.begin(), content.end());
    msg.attachments.push_back({"test.txt", data});

    // 4. Add to PST & Close
    writer.addMessage(msg, "Inbox");
    writer.close();
    
    return 0;
}

C++ Class: PSTWriter

The main entry point for the library.

class PSTWriter {
public:
    PSTWriter(const std::string& path, CompatibilityMode mode = CompatibilityMode::Simplified);
    ~PSTWriter();

    // Folders
    uint64_t createFolder(const std::string& name);

    // Items
    uint64_t addMessage(const Message& msg, const std::string& folder);
    uint64_t addEvent(const CalendarEvent& evt, const std::vector<std::string>& path);
    uint64_t addTask(const TaskItem& task, const std::vector<std::string>& path);
    uint64_t addJournal(const JournalEntry& entry, const std::vector<std::string>& path);

    // Utility
    void compact(); // Flush buffers
    void close();   // Finalize file
};

C++ Data Structures

Message Struct

struct Message {
    std::string subject;
    std::string body_plain;
    std::string body_html;
    std::string from_name;
    std::string from_email;
    std::vector<Recipient> recipients;
    std::vector<Attachment> attachments;
    std::chrono::system_clock::time_point timestamp;
};

CalendarEvent Struct

struct CalendarEvent {
    std::string subject;
    std::string location;
    std::chrono::system_clock::time_point start_time;
    std::chrono::system_clock::time_point end_time;
    bool is_all_day;
    BusyStatus busy_status;     // Free, Tentative, Busy, OutOfOffice
    MeetingStatus meeting_status;
    RecurrencePattern recurrence;
};

Node.js Quick Start

The Node.js API uses a Builder pattern for creating messages and events.

const { PstWriter, PstMessage, PstEvent } = require('pst-writer');

// 1. Initialize
const writer = new PstWriter("output.pst");
writer.createFolder("Inbox");

// 2. Build Message
const msg = new PstMessage();
msg.setSubject("Hello directly from Node");
msg.setBody("This is cool!");
msg.setSender("Node Bot", "bot@node.js");
msg.addRecipient("User", "user@example.com", 1); // 1=To, 2=Cc, 3=Bcc

// Add Attachment (File Path)
msg.addAttachment("image.png", "/path/to/image.png");

// 3. Write
writer.addMessage("Inbox", msg);

// 4. Build Event
const evt = new PstEvent();
evt.setSubject("Team Meeting");
evt.setStartTime(Date.now());
evt.setEndTime(Date.now() + 3600000); // +1 hour
evt.setLocation("Conference Room A");

writer.addEvent("Calendar", evt);

writer.close();

Node.js Class: PstWriter

  • new PstWriter(path): Create a new writer.
  • createFolder(name): Create a top-level folder.
  • addMessage(folderName, messageObj): Add a generic message.
  • addEvent(folderPath, eventObj): Add a calendar event. Folder path string (e.g., "Calendar/Work").
  • close(): Finalize the file.

Node.js Builders

These classes are used to construct items before adding them to the PST.

PstMessage API

  • setSubject(string)
  • setBody(string): Plain text body.
  • setSender(name, email)
  • addRecipient(name, email, type): Type: 1(To), 2(Cc), 3(Bcc).
  • addAttachment(filename, filepath): Note: Takes a file path string, not binary data.

PstEvent API

  • setStartTime(ms) / setEndTime(ms): Unix timestamp in milliseconds.
  • setLocation(string)
  • setAllDay(boolean)
  • setRecurrence(type, interval, ...)

C# / .NET API

The library includes a P/Invoke wrapper for seamless integration with .NET applications. It follows the `IDisposable` pattern for automatic resource management.

using PSTWriter;

// 1. Initialize (IDisposable ensures resource cleanup)
using (var writer = new PstWriter("output.pst")) {
    
    // 2. Create Structure
    writer.CreateFolder("Inbox");

    // 3. Create Message
    using (var msg = new PstMessage()) {
        msg.Subject = "Report from C#";
        msg.Body = "Generated via .NET Core";
        msg.SetSender("Service Account", "svc@domain.com");
        
        // Add Recipient
        msg.AddRecipient("Admin", "admin@domain.com", RecipientType.To);

        // Add Attachment
        msg.AddAttachment("log.txt", "C:\\logs\\daily.log");

        // Write to PST
        writer.AddMessage("Inbox", msg);
    }

    // 4. Create Calendar Event
    using (var evt = new PstEvent()) {
        evt.Subject = "Sync Meeting";
        evt.StartTime = DateTime.UtcNow;
        evt.EndTime = DateTime.UtcNow.AddHours(1);
        evt.Location = "Virtual";
        
        writer.AddEvent("Calendar", evt);
    }
    
    // Auto-closed on dispose, or explicit close:
    writer.Close();
}

Integration Patterns

PST Forge is built to fit into modern data pipelines.

Forensics & e-Discovery

Use the C++ API for maximum throughput when ingesting terabytes of raw disk blocks or email fragments. The thread-safe allocator allows you to run parallel scraping threads that feed a single `PSTWriter` instance.

Cloud Migration (Node.js)

For simple Glue logic, use the Node.js bindings. Connect to Google Workspace APIs or Microsoft Graph API using standard Node.js libraries, fetch emails as JSON/MIME, and pipe them directly into `PstWriter`.

Enterprise Archives (.NET)

Integrate with existing Exchange Server archival agents or SharePoint exporters using the C# bindings. The library compiles to a standard DLL that can be deployed alongside your compiled .NET binaries.


Unicode & Internationalization

The library fully supports UTF-8. You can use international characters and emojis in:

  • Folder names: "收件箱"
  • Subjects: "Hello 🌍"
  • Body content
  • Sender/Recipient names

Performance

For high-throughput applications, the C++ API offers addMessagesParallel to utilize multi-core processors for writing messages. The library also buffers writes intelligently to minimize disk I/O.