Wine Staging 1.7.33 introduced a feature called DLL Redirects which make
it possible to dynamically exchange the DLLs a program tries to load.
This feature is currently used by our CSMT implementation to replace
wined3d.dll
with wined3d-csmt.dll
to allow switching it on and off
at runtime. These redirects are controlled through registry keys and
work with builtin/wine dlls and native/win32 dlls.
Adding redirects
In order to add a redirection, you need to create a registry key using regedit. You can either create a global dll redirection under
HKEY_CURRENT_USER\Software\Wine\DllRedirects
or an application specific one under
HKEY_CURRENT_USER\Software\Wine\AppDefaults\[app.exe]\DllRedirects
(replace [app.exe] with the actual filename of the executable).
If you want to add a redirect from broken.dll to working.dll, you need to create a string value (REG_SZ) with broken as name (you need to strip off the .dll extension) and working.dll as value. Alternatively you can also specify a full win32 path to the dll.
Here you can see what it looks like for the CSMT redirect:
How does it work?
We added some logic to Wine's dll loader to replace the filename of the
loaded dll. Wine itself thinks that the original dll is loaded and
therefore all API functions like GetModuleFileName
or
GetModuleHandle
will still work as if the original was loaded. This
makes it almost impossible for an application to find out that the wrong
library is loaded. There are some ways like checking the actual file
content of the library against the loaded memory chunks but it is
unlikely that an application implements something like this. However,
this approach also has some drawbacks which may be fixed in future
versions.
Drawbacks
You can only redirect existing dlls because an application can query the full path of a loaded library and it is not clear which path we should return for non existing dlls. A library may be anywhere in the programs search path (C:\windows\system32, current working directory, ...) and we therefore require the file to exist.
The current implementation of DLL redirects does not store any information about loaded dlls which were redirected. This causes trouble if an application tries to manually load the target of a redirection while the same library is already loaded under a different name. Wine does not notice that the library was already loaded and tries to load it a second time. The behaviour of builtin/native DLLs is slightly different, but in both cases an application might be confused.