Monday, March 30, 2009

Burgling the _Storages table.

I was recently asked why InstEd doesn't allow the user to save binary fields from the _Storages table. The simple answer is that the Windows Installer API doesn't support it.

The long answer is that InstEd does let you extract them, you just have to hoodwink it.

As some background, the _Storages table is a representation, in Windows Installer table form, of the OLE structured storage list of "storages". Some of the stuff that lives as "storages" are transforms and cabinets in patches, and language transforms in msi's.

For example, this article discusses how instmsi.msi (contained in instmsiw.exe) manages to install using the appropriate language gui. It embeds as "storages" transforms that change the gui text strings, and names them with the appropriate language id.

(As a side note, while the article says that Windows Installer can automatically detect, extract, and apply the relevant language transform (from version 2 forward), the instmsi(a/w).exe files that redistribute Windows Installer actually contain another stub exe called instmsi.exe that launches the instmsi.msi. This stub exe calls functions such as StgOpenStorage and GetUserDefaultLangID. Which makes me wonder if it is only with this stub exe that the language transforms are automatically applied, or whether it is only because of the bootstrapping that this functionality is required in the stub exe. i.e. Lanugage transformations may be automatically handled by Windows Installer for all subsequent msi's. Does anyone know the answer?)

The MSDN article on the _Storages table explicitly declares: Data cannot be read from the _Storages table.

Basically, it's an usual table, and InstEd doesn't have the logic yet to treat it differently from the other tables. So it can only be used as a way to list the storages.

However, becuase most of the useful data in a patch file is stored as "storages" InstEd provides the option when opening a patch file (from the File->Open menu), to extract all the storages.

So, by renaming an msi to give it a .msp extension and then opening it in InstEd, you will be given the option to extract all the "storages" from the files. In this way you can extract all the storages.

It's not a very pretty way to do it, but it works. In the future, this table may receive some work to make it easier to work with.

msidb.exe also allows you to extract/add/remove storages. And then are any number of OLE Structured Storage editors available on the web.

Microsoft's Heath Stewart has also written some blogs and tools related to this.

No comments: