#archive #world-of-warcraft #mpq #api-compatible #storm #open-file

storm-ffi

StormLib-compatible C API for the World of Warcraft MPQ archive library

1 unstable release

new 0.6.2 Feb 15, 2026

#1 in #storm

MIT/Apache

1MB
21K SLoC

storm-ffi

StormLib-compatible C API for the World of Warcraft MPQ archive library.

Crates.io Documentation License

Status

Implemented - Drop-in StormLib replacement using wow-mpq.

Overview

The storm-ffi crate provides a C-compatible Foreign Function Interface (FFI) that emulates the StormLib API, wrapping the native Rust wow-mpq implementation. This allows C/C++ applications that expect StormLib's interface to use the memory-safe Rust implementation instead.

Features

  • StormLib-compatible function signatures
  • Thread-safe handle management
  • Windows error code compatibility
  • Support for MPQ archives from World of Warcraft versions 1.12.1 through 5.4.8
  • Both static and dynamic library output

Supported Versions

  • Classic (1.12.1) - Full support
  • The Burning Crusade (2.4.3) - Full support
  • Wrath of the Lich King (3.3.5a) - Full support
  • Cataclysm (4.3.4) - Full support
  • Mists of Pandaria (5.4.8) - Full support

Usage

Add to your Cargo.toml:

[dependencies]
storm-ffi = "0.1"

Building the Library

# Build the library
cargo build --release -p storm-ffi

# Output libraries will be in target/release:
# - libstorm.so (Linux)
# - libstorm.dylib (macOS)
# - storm.dll (Windows)

C/C++ Usage

Include the generated header and link against the storm library:

#include "StormLib.h"

int main() {
    HANDLE hArchive = NULL;

    // Open an archive
    if (SFileOpenArchive("Data/patch.MPQ", 0, 0, &hArchive)) {
        // Check if a file exists
        if (SFileHasFile(hArchive, "Interface\\FrameXML\\GlobalStrings.lua")) {
            // Extract the file
            SFileExtractFile(hArchive,
                "Interface\\FrameXML\\GlobalStrings.lua",
                "GlobalStrings.lua",
                0);
        }

        // Close the archive
        SFileCloseArchive(hArchive);
    }

    return 0;
}

Supported Functions

Archive Operations

  • SFileOpenArchive - Open an existing MPQ archive
  • SFileCreateArchive - Create a new MPQ archive
  • SFileCloseArchive - Close an open archive

File Operations

  • SFileOpenFileEx - Open a file within an archive
  • SFileCloseFile - Close an open file
  • SFileReadFile - Read data from a file
  • SFileGetFileSize - Get the size of a file
  • SFileSetFilePointer - Seek within a file
  • SFileHasFile - Check if a file exists
  • SFileExtractFile - Extract a file to disk

Archive Information

  • SFileGetArchiveName - Get the archive file path
  • SFileGetFileName - Get the current file name
  • SFileGetFileInfo - Query archive/file information
  • SFileEnumFiles - Enumerate files in the archive

Utility Functions

  • SFileSetLocale / SFileGetLocale - Locale management
  • SFileGetLastError / SFileSetLastError - Error handling
  • SFileVerifyFile - Verify file integrity
  • SFileSignArchive - Sign an archive (stub)
  • SFileVerifyArchive - Verify archive signatures

Error Handling

The library uses Windows-compatible error codes:

DWORD error = SFileGetLastError();
switch (error) {
    case ERROR_SUCCESS:           // Operation succeeded
        break;
    case ERROR_FILE_NOT_FOUND:    // File not found in archive
        break;
    case ERROR_ACCESS_DENIED:     // I/O error
        break;
    case ERROR_INVALID_PARAMETER: // Invalid parameter
        break;
    case ERROR_FILE_CORRUPT:      // Archive or file corrupt
        break;
}

Examples

See the examples directory for C examples:

  • basic.c - Simple archive open/close example
  • storm_example.c - Comprehensive usage example

Building from Source

Prerequisites

  • Rust 1.92 or later
  • C compiler (for examples)
  • cbindgen (automatically installed as build dependency)

Build Steps

# Clone the repository
git clone https://github.com/wowemulation-dev/warcraft-rs
cd warcraft-rs

# Build the storm crate
cargo build --release -p storm-ffi

# Generate C header
cargo build -p storm-ffi  # cbindgen runs automatically

# Header will be at: ffi/storm-ffi/include/StormLib.h

Compatibility Notes

StormLib Differences

While the storm-ffi crate aims for StormLib compatibility, there are some differences:

  • Thread-safe by default (uses Rust's safety guarantees)
  • Error codes are translated from wow-mpq's error types
  • Some functions are stubs (e.g., SFileSignArchive)
  • No support for protected MPQs

Memory Management

  • All handles are opaque pointers managed by Rust
  • No manual memory management required from C/C++
  • Thread-local error storage for compatibility

License

Licensed under either of

at your option.

Dependencies

~35–52MB
~850K SLoC