Tuesday, February 16, 2010

Extract embedded MST from MSI installer

last week, one of my colleagues asked me if embedded MST files in an MSI installer can be extracted for verification. i had tried out several MSI APIs mostly using VBScript in retrieving info on MSI and MSPs 2-3 years back when i was studying the installer concept. well, with the MSI APIs, you can access the _Storages table of the installer and lists the names of the embedded MSTs. however, the Data field which holds the binary data cannot be accessed and will also return a data size of 0bytes! API description in MSDN clearly states this too...

anyway, so what i did was to make use of msidb.exe utility which is shipped with the MS platform SDK. you will need to specify the MSI file path and the name of the storage i.e. the MST (usually the codepage or locale number) to extract the file. i used the MSI APIs in vbscript to list the names of the embedded storages and specify them in the commandline option of msidb.exe to extract it...

last weekend, i had some free time to check on the MSI APIs. i was wondering how msidb.exe is extracting the data since the description in the _Storages table notes that the Data field cannot be accessed!? after awhile, i came to understand that you'll have to treat the msi file as any compound file like Office files which have embedded storages in them. and this led me to the IStorage::OpenStorage and related APIs in MSDN. using these OLE Storage related APIs, i was able to extract the MSTs and save them externally.

here's the command line tool (stgxtr.exe) which will extract all the data in the storage of a compound file. i just tested this with an MSI so i don't have any idea if this works with other compound files...

[Usage]
$>stgxtr.exe <pathToMSIFileWithEmbeddedMST>

the extracted files will be saved on the current directory and are named with their corresponding storage names. i currently did not add the feature of extracting specific storage name but might implement it later when necessary. if you need to extract specific storage out of the MSI, you can use msidb.exe instead.

1 comment:

erdo said...

Super! Thanks a lot.