On Fri, Jul 21, 2000 at 09:07:43AM +0100, David Howells wrote:
> 
> Andreas Mohr wrote:
> > Sure, that's what I'll be working on soon.
> > However most probably that won't be libraries (.so), but rather completely
> > new NE or PE "fake DLLs" with a complete header and version resources.
> 
> Will you then be building the wine code into these DLL files rather than into
> real .so files?
No, of course not, as it's not possible.

> And if not, will there be some mechanism by which if someone tries to
> dynamically load one of these DLLs, it will dynamically load the real .so file
> in addition or instead?
Yes, I will need to take care of that.
I'll probably add a flag bit somewhere in the header of these fake DLLs
that will tell the loader to give up on native loading.

> Out of interest, why do you want fake NE/PE DLLs? Is it because some programs
> try to 'manually' parse the DLLs rather than using system routines?
I thought that it's better to include a header (which would be small anyway)
for these files instead of just "touch"ing them.

And I previously thought of adding different VS_VERSION_INFO resources for
different Windows versions to the fake DLLs.
But this is not good, I think.

Right now the GetFileVersionInfo*() functions in Wine read the VERSION_INFO
directly from the file, which fails if only the builtin DLL is available,
but not the "real" DLL.

IMHO the best way would be to include *all* VERSION_INFO resources in the
builtin DLLs and *none* in the fake DLL files, as I never saw any program
that reads them directly from the file so far (and any program that does
is severely screwed IMHO as GetFileVersionInfo*() doesn't lack any
functionality and thus can be used without a problem).
And BTW, we already have a VERSION_INFO in at least some resource files
for builtin DLLs.
Just add VERSION_INFO_W31, VERSION_INFO_W95, VERSION_INFO_NT4 and so on
and decide to read them on a winver basis and you're set.

Now the problem is:
How do we implement the reading of the VERSION_INFO ?
The current way of directly reading its content from a DLL *file*
is pretty fast.
At first I thought I'd just check whether we have a Wine builtin version
of the file name given for GetFileVersionInfo*() available and then branch
to the code that returns the VERSION_INFO_xxx for this builtin DLL
(I'd have to write this code), and if no builtin available, then just read
the native DLLs VERSION_INFO via the old code that we use right now.
But I forgot about the loadorder thing, because:
If you told Wine to use the native version of e.g. COMCTL32.DLL, but
GetFileVersionInfo*() is implemented to only check whether the builtin DLL
is available and read the builtin's resources in that case, then this is
a grave mistake (conflict as we use native DLL, but read builtin's
VERSION_INFO_xxx).

That's why IMHO we should just LoadLibrary() (i.e. obey the loadorder)
*any* file name given for GetFileVersionInfo*() and read out the
VERSION_INFO_xxx by using the Windows resource handling functions
and throw the whole code for directly reading out the VERSION_INFO
from a file away.
Or does GetFileVersionInfo*() get used for non-libraries sometimes, too ?
(I'm afraid it does)
In this case we can't throw away the old code that directly reads the content
from the file, as we need to use it in case LoadLibrary() of the file fails.

Yes, I know, using LoadLibrary() for the file instead of directly reading
the VERSION_INFO from the file might be rather slow for big DLL files,
but I think we don't really have an alternative here...
(as this solves the loadorder problem that otherwise would be pretty hard
to fix IMHO).
And programs most probably will use GetFileVersionInfo*() only once anyway.
And in some months there will be only builtin DLLs left for the
core system DLLs that we *need* to LoadLibrary() in order to get
their VERSION_INFO.
So the situations where we can use direct VERSION_INFO access will decrease
anyway.

And a GetFileVersionInfo*() normally happens directly before a LoadLibrary()
anyway.
Hmm, a question about that:
If we do the LoadLibrary() in GetFileVersionInfo*() and do a FreeLibrary()
at the end (usage count down to 0 again ! -> removal),
then the LoadLibrary() of the same file probably done by the Windows
program some lines later will need to load the whole library again, no ?
Maybe we should use a service timer callback for doing the FreeLibrary()
2 minutes later in order to keep the usage count from going to 0 before
the program has loaded the library ?

If my thoughts so far are OK for you, then I'll go for implementing it :)

Andreas Mohr

Reply via email to