[RFC PATCH 0/5] XAudio PE conversion.

Esme Povirk (she/they) esme at codeweavers.com
Fri Sep 3 15:52:35 CDT 2021


A simpler solution might be to do something similar to the
DELAYIMPORTS mechanism, but instead of using __wine_spec_delay_load,
we'd use some special Wine-specific function to load the .dll, which
would search the system paths first for the dll and its dependencies,
and (if found there) set a "system" flag so that normal dll resolution
doesn't find it in memory.

This would mean that we don't need to give any special treatment to
builtin dlls, just dll's loaded using this particular mechanism.

Then again, the dll would still be visible to Windows software, even
if trying to load it by just the basename wouldn't find that version,
so it might still cause problems.

On Fri, Sep 3, 2021 at 2:11 PM Zebediah Figura (she/her)
<zfigura at codeweavers.com> wrote:
>
>
>
> On 9/3/21 12:02 PM, Alexandre Julliard wrote:
> > "Zebediah Figura (she/her)" <zfigura at codeweavers.com> writes:
> >
> >> On 9/3/21 3:26 AM, Alexandre Julliard wrote:
> >>> "Zebediah Figura (she/her)" <zfigura at codeweavers.com> writes:
> >>>
> >>>> Actually, an alternate solution occurred to me:
> >>>>
> >>>> If we are loading any library that is a dependency of a builtin
> >>>> library, always load it from a fixed path like /usr/lib/wine/ext/, and
> >>>> essentially treat it as if we had loaded using an absolute path
> >>>> instead of a relative path, so as to skip existing DLLs loaded under
> >>>> that name.
> >>>>
> >>>> Mark that DLL with an internal flag, and don't consider it when
> >>>> searching for existing DLLs with that name, to avoid the other side.
> >>>>
> >>>> I know there are a lot of other things standing in the way of shared
> >>>> libraries, and that this would require some nontrivial loader work,
> >>>> but does it at least seem plausible? Are there snags I'm not noticing?
> >>> Sure, you can try to create a separate namespace for these without
> >>> actually changing their names. It's not clear to me how you are going to
> >>> determine which DLLs should go into that namespace, and how that's going
> >>> to work with apps that do import resolving by hand.
> >>> You'll also have to invent some mechanism to have Wine treat them as
> >>> builtins even though they don't have the builtin flag.
> >>
> >> The distinguishing factor I was thinking of is that if it's a system
> >> lib or linked to by a system lib, it's marked as a system lib. That
> >> doesn't work for libraries loaded dynamically, and there we have the
> >> extra caveat that we don't want to mark every dynamically loaded
> >> library as a system lib, so I think we'd need an internal flag to
> >> LoadLibraryExW().
> >
> > I don't see how this would work. All such libraries will import msvcrt
> > or kernel32, but you can't have these end up in a separate namespace.
> >
> > And how do you define a "system lib"? Do you somehow tell the PE loader
> > the actual Unix path that the dll was loaded from?  What if the distro
> > installs the Wine DLLs in the same dir?
> >
> >>> And somehow you
> >>> need to differentiate them from the exact same DLLs being shipped by an
> >>> app...
> >>
> >> Sorry, I'm not sure what you mean by this, that's different from what
> >> I described above?
> >
> > Well, you'll need to copy, say, zlib1.dll into the prefix. How do you
> > know this is the zlib1.dll from the system package, and not one
> > installed by an app?  Do you add the builtin flag, altering the binary
> > when copying it?
> >
>
> I did fail to consider that case, thanks.
>
> After thinking about it for a while I've come up with the following
> algorithm:
>
> Suppose that module A imports module B.
>
> 1. If module A is marked "builtin" or "system":
>
>      a. Try to find a module marked "builtin" or "system" in memory, and
> return it if found. (Skip "builtin" if the load order requires.)
>
>      b. Try to load a module from WINESYSTEMDLLDIR#. If found, mark the
> module as "system".
>
>      c. Try to find a module marked "native" in memory, and return it if
> found. (Skip this step if the load order requires.)
>
>      d. Try to load a builtin or native module using the normal logic.
>
> 2. Otherwise, i.e. module A is native:
>
>      a. Try to find a module marked "builtin" or "native" (modulo load
> order) in memory, and return it if found. Skip "system".
>
>      b. Try to load a builtin or native module using the normal logic.
>
>
> This should avoid ever loading a system module for a native module; it
> should avoid loading a native module when we want a system module
> (provided that system modules are present; if they aren't things are
> already broken). It should also handle e.g. ucrtbase imports, regardless
> if ucrtbase is builtin or native.
>
> The downside I can see is that if ucrtbase is native, we'll always
> search WINESYSTEMDLLDIRs for it. If that's a performance problem, we
> could always bypass step 1b for a predefined list of modules.
>
> This does rely on the fact that WINESYSTEMDLLDIRs are unique and only
> contain system libraries. It's not obvious to me that would be a problem
> to guarantee. The list might contain one or more paths like:
>
> * C:/windows/system32/wine-ext/ [1]
> * Z:/usr/x86_64-w64-mingw32/bin/ [2]
> * Z:/usr/lib/wine/ext/
>
> I'm sure this all looks like a pile of hacks. Granted, it doesn't look
> unreasonable to me, but I suppose I'm also biased. I'm just trying my
> best to make dynamic libraries a possibility, because static libraries
> suck for development. And, more importantly, I'm trying to give
> distributions an accurate representation of our requirements.
>
>
> [1] As far as I'm aware, the only reason we need to copy libraries to
> the C: drive is that anticheats *might* complain if libraries are loaded
> from another drive? Was there a concrete example of this? Or was there
> another problem I was missing?
>
> [2] Or distribution equivalent. That's assuming that distributions are
> in favor of having us dynamically link to pre-built libraries, though,
> and that's an open question. It's also not clear how we would get this path.
>



More information about the wine-devel mailing list