@bun-win32/wimgapi
v2.0.1
Published
Zero-dependency, zero-overhead Win32 WIMGAPI bindings for Bun (FFI) on Windows.
Maintainers
Readme
@bun-win32/wimgapi
Zero-dependency, zero-overhead Win32 WIMGAPI bindings for Bun on Windows.
Overview
@bun-win32/wimgapi exposes the wimgapi.dll exports using Bun's FFI. It provides a single class, Wimgapi, which lazily binds native symbols on first use. You can optionally preload a subset or all symbols up-front via Preload().
The Windows Imaging Interface (WIMGAPI) is the supported, in-process API for Windows image (.wim) files — create/open archives, capture a directory tree, apply or enumerate an image, mount/unmount, split, export, set references, and stream live progress through a message callback. It is the same engine DISM.exe and ImageX drive, with no process spawn. It complements @bun-win32/dismapi (image servicing).
The bindings are strongly typed for a smooth DX in TypeScript.
Features
- Bun-first ergonomics on Windows 10/11.
- Direct FFI to
wimgapi.dll(image capture/apply/mount/split/export, message callbacks). - In-source docs in
structs/Wimgapi.tswith links to Microsoft Docs. - Lazy binding on first call; optional eager preload (
Wimgapi.Preload()). - No wrapper overhead; calls map 1:1 to native APIs.
- Strongly-typed Win32 aliases and the full WIM flag/message enums (see
types/Wimgapi.ts).
Requirements
- Bun runtime
- Windows 10 or later
- An elevated process for capture/apply/mount (
WIMCaptureImage/WIMApplyImage/WIMMountImageneedSeBackupPrivilege/SeRestorePrivilege). Opening a.wimread-only and enumerating it (WIMApplyImagewithWIM_FLAG_NO_APPLY) needs no privilege.
Installation
bun add @bun-win32/wimgapiQuick Start
import Wimgapi, { WIMCreationDisposition, WIMDesiredAccess } from '@bun-win32/wimgapi';
const wide = (s: string) => Buffer.from(s + '\0', 'utf16le');
// Open an existing .wim read-only and read its header + image count.
const result = Buffer.alloc(4);
const hWim = Wimgapi.WIMCreateFile(wide('C:\\images\\install.wim').ptr!, WIMDesiredAccess.WIM_GENERIC_READ, WIMCreationDisposition.WIM_OPEN_EXISTING, 0, 0, result.ptr!);
if (hWim !== 0n) {
console.log('images in archive:', Wimgapi.WIMGetImageCount(hWim));
const wimInfo = Buffer.alloc(560); // WIM_INFO
if (Wimgapi.WIMGetAttributes(hWim, wimInfo.ptr!, 560)) {
console.log('compression type:', wimInfo.readUInt32LE(540));
}
Wimgapi.WIMCloseHandle(hWim); // always pair create/open with close
}[!NOTE] AI agents: see
AI.mdfor the package binding contract and source-navigation guidance. It explains how to use the package without scanning the entire implementation.
Examples
Run the included examples (run elevated, or pass an existing .wim path, for full output):
bun run example/wim-inspector.ts [path\to\image.wim]
bun run example/wim-xray.ts [path\to\image.wim]- wim-inspector — a thorough diagnostic: decoded
WIM_INFOheader (GUID, compression, parts, attributes), per-image XML manifest, and the live system-wide mounted-image table. - wim-xray — a live truecolor X-ray of an image's file tree, driven by the real imaging engine calling back into a
bun:ffiJSCallback (registered viaWIMRegisterMessageCallback, enumerated withWIMApplyImage(hImage, NULL, WIM_FLAG_NO_APPLY)).
Notes
- Either rely on lazy binding or call
Wimgapi.Preload(). - All WIM functions are wide-only (no
A/Wsplit); strings are UTF-16LE NUL-terminated buffers. - Handles (
WIMCreateFile/WIMLoadImage/WIMCaptureImagereturns) arebigint; failure is0n. Always release them withWIMCloseHandle. WIMGetImageInformationreturns a WIM-allocated UTF-16 buffer via aPVOID*out-pointer plus aDWORDbyte count; read the count from your own buffer, then free the buffer withKernel32.LocalFree.- Sizing pattern:
WIMGetMountedImages(NULL, &cb)/WIMGetMountedImageInfo(level, &count, NULL, 0, &cb)return the required buffer size; allocate, then call again. - Register a
WIMMessageCallback(abun:ffiJSCallback passed asFARPROC) for live progress; returnWIM_MSG_SUCCESSto continue orWIM_MSG_ABORT_IMAGEto cancel. Keep the JSCallback alive for the duration of the operation. - Seven exported file-IO/enumeration functions (
WIMReadImageFile,WIMCreateImageFile,WIMFindFirstImageFile,WIMFindNextImageFile,WIMEnumImageFiles,WIMInitFileIOCallbacks,WIMSetFileIOCallbackTemporaryPath) and theDll*server entries are undocumented internals and intentionally not bound. - Windows only. Bun runtime required.
- SAL types & naming: nullability is in the type —
Optional<T>(formally optional, SAL_*opt_) andNullable<T>(plain[in]/[out]the docs say can be NULL), the null sentinel derived fromT(nullfor pointersLP*/P*,0nfor handles/by-value addresses); direction is in the parameter name —_out(_Out_),_in_out(_Inout_),_In_bare. SeeAI.mdand the repoAGENTS.md.
