rubrapack Manual←↑→

30 Package formats for implementers

These pages describe what a program has to write to produce a Windows Installer package (.msi) and an MSIX package or bundle that Windows accepts, and how to sign them. They are written from public specifications and from experiments against Windows itself, so that you can build your own tool from them without reading rubrapack's code - or check rubrapack's code against them.

PageCovers
Compound File Binary (CFB)Compound File Binary: the container every .msi is
The MSI database inside the compound fileStreams, string pool, system tables, table encoding, IDT export
Summary informationThe summary information stream and its code page trap
The smallest package that installs, repairs, upgrades and uninstallsThe tables that install, upgrade, repair and uninstall: files, registry, shortcuts, services, fonts, dialogs, per-user packages, sequences
Program files: machine type and versionProgram files: machine type and version resource
Cabinets, MSZIP and deflateCabinet files, MSZIP blocks, the deflate encoder
Deterministic identities and reproducible packagesDeterministic GUIDs and keys, reproducible builds
Authenticode signaturesAuthenticode signatures for PE files and MSI packages: the digests, the CMS structure Windows accepts, ECDSA, RFC 3161 timestamps
Checking your output against WindowsHow to check your output with Windows' own components
MSIX packagesMSIX: the ZIP layout, block map, manifest, virtual registry and file system, extensions, bundles, signatures
Registry hive files (REGF)Registry hive files (REGF), as MSIX Registry.dat and User.dat hold them

30.1 How to read the facts#

Every statement is tagged with where it comes from:

No text or code here comes from other MSI, MSIX, cabinet or registry implementations.

30.2 Conventions#

30.3 The pipeline, in one picture#

source description --> tables (rows of strings/integers/streams)
                   --> MSI database encoding (string pool + one stream per table)
                   --> files packed into a cabinet (stored or MSZIP) --> one more stream
                   --> summary information stream
                   --> all streams written into one compound file  = the .msi

An MSIX package is simpler: the payload files (each deflated in independent 64 KiB parts), AppxManifest.xml, AppxBlockMap.xml (a hash per part) and [Content_Types].xml in one ZIP64 archive, with Registry.dat/User.dat hives for registry values; a bundle stores packages side by side; a signature adds AppxSignature.p7x (MSIX packages, Registry hive files (REGF)).

Each arrow is a page above. None of it needs Windows to produce: rubrapack builds the same bytes on Linux and on Windows.