Windows Installer Hacking

From Apache OpenOffice Wiki
Jump to: navigation, search


This page explains how to modify a Windows installer EXE (the big, >70 MB one which contains everything).

Why?

Normally this is a bad idea, and it is better to build OOo from scratch yourself. However, this may not be possible for various reasons, e.g. if:

  • You don't have the (non-Free) toolchain available to build OOo.
  • You're modifying a non-Free OOo derivative and don't have the source.
  • You don't have the time and resources available to build OOo
  • etc.

OOo_2.0_Windows_install_en-US.exe

This is an NSIS self-extracting installer. It contains the following structure:

   openofficeorg1.cab
   openofficeorg2.cab
   openofficeorg3.cab
   openofficeorg4.cab
   openofficeorg20.msi
   instmsia.exe
   instmsiw.exe
   licenses/
   readmes/
   setup.exe
   setup.ini

In the OOo 2.0 build process it is built from its contents using a command (at "call_nsis" in solenv/bin/modules/installer/download.pm) which does something like the following:

   /cygdrive/c/Program\ Files/NSIS/makensis.exe c:/ooo2/ooo-build/build/ooo680-m3/instsetoo_native/wntmsci10.pro/OpenOffice/nsis/en-US/downloadtemplate.nsi

The file

   downloadtemplate.nsi

contains instructions for building the .exe. Its directory also contains

   English_pack.nsh
   English_pack.nlf

which both consist of text strings in the installer language and are referenced from downloadtemplate.nsi. (Various .ico and .bmp files, located outside the directory, are also referenced).

CAB files

These contain the actual files which get extracted. Although CAB files can apparently store a directory tree structure, these ones are flat. The filenames inside the CAB are often, but not always, the same as the names when installed.

N.B. The order in which files are stored is very important!

   cabextract -l # lists the contents of a cab file.
   makecab.exe /F blah.ddf # Create CAB from blah.ddf, a spec+filelist

The "blah.ddf" file can be generated with a perl script like this:

#!/usr/bin/perl -w
# 
# Files to pack: c:\msi\files
# Output file path is relative to that directory
# Temporary work space: c:\msi\makecabtemp
# Usage: perl make-ddf.pl (list of names of files to pack, in order, without path)
# 
print <<EOF;
.Set CabinetName1=../out.cab
.Set ReservePerCabinetSize=128
.Set MaxDiskSize=CDROM
.Set CompressionType=LZX
.Set Compress=ON
.Set CompressionLevel=2
.Set Cabinet=ON
.Set DiskDirectoryTemplate=c:/msi/makecabtemp
EOF
for my $file (@ARGV) {
    print qq("c:\\msi\\files\\$file" $file\n);
}

Some files in the CABs may not actually get installed: See Component.idt below.

MSI file

This is a relational database which controls the installation process. It can be dumped into tab-separated text files (*.idt), one per table, using

   MsiDb.Exe -e -d blah.msi -f c:\text_file_dest *

The text files can be dumped back into a new MSI like this:

   MsiDb.Exe -i -d blah_new.msi -f c:\text_file_dest *.idt

(N.B. In both cases, be sure to surround the * in quotes if you're using a UNIX shell)

If you edit these text files, you have to be pretty careful, because there is all sorts of referrential integrity to preserve between tables. To modify the install, some tables are particularly important:

File.idt

This is a list of files which *potentially* can be installed.

  • File is the name of the file in the archive.
  • Each file is part of a Component.
  • FileSize speaks for itself.
  • Sequence is the order in which the files appear in the CABs, and the

installer will *fail* if it is not correct. (The Sequence is across all CAB files, so for instance the first file in CAB 3 has the Sequence number one higher than the last file in CAB 2).

Directory.idt

Defines directories per feature component

Media.idt

Specifies the CABs from which to obtain files. Crucially, this specifies the file number ranges contained within each CAB, so if you add any files you will probably have to alter this.

Feature.idt

Defines Features, i.e. groupings of functionality which can be selected in the installer.

FeatureComponent.idt

Each Feature is a set of components.

Component.idt

Specifies into which directory a component is installed (relative to Directory.idt), etc. KeyPath is the First file in the component (in Sequence order) (?)

Full paths of executables

  • C:\Program Files\Microsoft Platform SDK\Bin\MsiDb.Exe
  • C:\WINDOWS\system32\makecab.exe (on Windows XP)
  • cabextract - UNIX (or cygwin) program
Personal tools