Upgrade management

Mike Hearn m.hearn at signal.QinetiQ.com
Tue Sep 28 06:46:12 CDT 2004


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



More information about the wine-devel mailing list