Tuesday, April 8, 2008

Care for a Date?

While file system time stamps are not the ultimate arbiter of whether or not files have been edited, they can be useful in determining at a glance whether files have been edited.

Unfortunately, the Windows Installer API forces the Last Write Time timestamp to update just by opening a file in anything other than read only mode. Orca, and InstEd, don't (by default) open files in read only mode. Therefore just by opening a database file (not transforms) in Orca, even if no changes are made and a File->Save is never executed, the timestamp of the file will be changed when the file is closed.

This can be unfortunate when customising an msi installation, and trying to determine at a glance whether the source msi has been changed or whether all the changes have been kept in mst files (as they ideally should).

Why is this?
As previously discussed, the Windows Installer file format is based on OLE Structured Storage. The Structured Storage API provides a "transaction" mode, whereby changes to a file can be discarded. Coincidentally, the Windows Installer API also provides a transaction mode. It is almost certain that the Windows Installer transaction mode utilises the OLE Structured Storage transaction mode, rather than implementing transactions itself.

It is this transaction mode with which Orca, and InstEd, open files by default. Using this mode, the tool can make many changes to the file, and they get discarded unless specifically committed (File->Save). This allows fast saving (no need to save all the tables when saving, just call Commit), and easy discarding (simply don't call Commit).

But the underlying OLE Structure Storage transaction mode can, if required, save changes in "scratch" areas in the file, until such time as they are committed. Therefore, in transaction mode, the file must be opened with write permissions, even if commit is never called.

And at the NTFS file system level, as soon as a file handle that has been opened with write access is closed, the Last Write Time timestamp is updated.

The good news is that InstEd preserves the Last Write Time timestamp if no changes are made to the file. It does this by storing the timestamp when the file is opened, updating the stored timestamp whenever Save is called, and resetting the Last Write Time to the stored version whenever the file is closed.

Transform files are never opened with write permissions until they are saved, and therefore don't suffer the same problem.

No comments: