There are a bunch of different ways we may want to upgrade the users
configuration:
- Changes to $WINEPREFIX (~/.wine), for example:
- Introducing faked DLL headers
- Improved drive detection
- Changing the way the registry is stored
- Adding stuff to the virtual Windows drive
- Modifying the registry
- Adding new keys
- Adding new appdefaults (default config options should be in the
code itself). While we have a policy of not having app-specific
hacks in Wine, some situations are very hard to resolve without
custom overrides. The Internet Explorer installer does a bunch of
things we really don't want it to do. The DCOM
installer needs custom overrides to convince it to install. And so
on.
- Registering new COM DLLs
(these all boil down to rerunning wine.inf)
- Adding new binaries such as fonts, PE DLLs (think Moz AX control),
and so on. These may be placed somewhere in the Wine install directory
and then symlinked or copied (presumably linked) into drive C.
This leads to the following questions:
- How do we know when to upgrade the users wineprefix?
- How do we avoid disturbing the users configuration?
- What implementation do we use to upgrade it?
One potential implementation for knowing when to upgrade the wineprefix
is to version it in a similar manner to how we version the wineserver
protocol: with a simple incrementing integer. This could be stored in
the registry, and Wines initialization sequence changed to be:
...
Does $WINEPREFIX exist? No, call wineprefixcreate
- Continue with startup
+ Yes? Check the wineprefix version key, if it is < the
+ version compiled into the source run
+ "wineprefixcreate --upgrade $oldversion $newversion", which then
+ performs the upgrade. If it exits with a zero exit code, the
+ version key is set to the number compiled into the source.
+ Then continue with startup
If registry access is too difficult here, a simpler implementation could
be used: just store the number in a .version file.
How do we avoid disturbing the users configuration? Alexandre already
laid out the plan for this, which is to have HKLM (HKEY_LOCAL_MACHINE)
devoted to the defaults we cunningly choose for maximum kewlness, and
HKCU (HKEY_CURRENT_USER) is where the users settings are stored. These
override the defaults, meaning we can change the default settings by
altering wine.inf, then bumping the wineprefix version so triggering a
remerge of the default registry contents.
This means modifying each piece of code where we read the registry to
figure out a user-configurable option. The algorithm becomes:
* Check the relevant key in HKCU, if it exists use it
* Otherwise, if it's an appdefault, check the same key in HKLM
* Otherwise, use the hardcoded default
In most cases, there's no point in duplicating the points at which we
can control the defaults, doing it in the code is fine. So, it basically
means grepping the source to find out where we read settings from, and
changing them to use HKCU instead of HKLM, perhaps also reading HKLM
depending on the context of the setting (settings that can be used in
appdefaults should check both).
I don't know how common these settings are but it might be worth having
a utility function either in a DLL or inline in a header to do this.
Registry code isn't complicated but it is tedious and easy to mess up,
so we might as well reduce code duplication at the same time.
I think the best implementation is to keep the code responsible for
managing WINEPREFIX in wineprefixcreate, and simply extend this program
to handle upgrades as well. OK, so the name will be a bit inaccurate but
let's not change it - users are already discovering the new program and
getting used to it, no need to modify it now especially as it's mostly
an internal program.
In the above example the old version and new version numbers were passed
to wineprefixcreate but most of the time that information wouldn't be
needed, for instance if we were to introduce fake DLL headers we could
simply check if they already existed and skip that part if so. I think
there's no harm in running wine.inf multiple times, so we could just do
that every time for both creation and upgrade.
I *think* this addresses most of the issues with upgrades, though I'm
sure Alexandre can think of more :) Potential unresolved problems:
- [How] do we lock wineprefix during upgrade so other processes
that are run hang about until it's done?
- Currently moving registry keys about is done actually
in the code itself: we copy it across then print a message
telling the user to delete the old setting manually. There's
a fair bit of evidence that some users simply don't spot/understand
these warnings. Also, we want to allow people to upgrade Wine with
quite long intervals in between yet eventually this code gets deleted.
Maybe a better solution is just to have wineprefixcreate understand
how to move registry keys around in response to bumping the version.
If the script gets too unwieldy, we could split particular upgrades
into separate scripts in $prefix/share/wine.
- Are there any wierd setups where parts of wineprefix are shared
between different users/systems that we need to take into account?
Thoughts? Comments?
thanks -mike