From: Doug Harrison [MVP] on
On 20 Jun 2005 07:11:34 -0700, tnewton(a)cbnco.com wrote:

> What I meant to say was, I don't see why my DLL function has to open a
> file to access the version information, given that the version
> information and my function are both inside the loaded DLL.

The API is designed in terms of that. You probably could figure out another
way, but it wouldn't be worth the trouble, IMO.

> And, how
> can I be sure that the DLL file that GetFileVersionInfo opens is the
> same DLL that is calling it?

Use GetModuleFileName on the HMODULE supplied to you in DllMain.

--
Doug Harrison
Microsoft MVP - Visual C++
From: Joseph M. Newcomer on
OK, I'm curious. How can you replace a currently-installed DLL? (Note that I think I know
one trick, but I'm not sure it still works).

Note that if the resources are in use, it is normally impossible to replace a DLL.
joe

On Mon, 20 Jun 2005 17:49:28 +0200, Mihajlo CvetanoviĆ½ <mac(a)RnEeMtOsVeEt.co.yu> wrote:

>Joseph M. Newcomer wrote:
>> It is a bit more complex than that, and his concern was "going to the file system", which,
>> guess what, FindResource must do anyway! So his concern is pointless, and shows he is not
>> thinking clearly about how to solve a trivial problem in a trivial way using a trivial
>> method, but wants to "improve" on it by somehow bypassing the documented, working
>> mechanism to implement some ad-hoc mechanism that could break on the next release of the
>> OS, because of a peculiar idea that "going to the file system" somehow is a Bad Thing.
>>
>> I always worry about how poorly we are training people when they even consider such issues
>> worthy of discussion.
>
>I think tnewton really stumbled on something here because it *is*
>possible to rename currently loaded dll, and place another with the
>previous name. In this situation GetFileVersionInfo will return invalid
>data (if the old dll is still loaded).
>
>This could be an issue if you want to update dll on the fly, and you
>have only restart mechanism available, but not stop/start mechanism. In
>this case updating must be done with "rename and copy another" routine.
>In all the other cases the "prize" isn't worth the effort.

Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Mihajlo Cvetanovi? on
Joseph M. Newcomer wrote:
> OK, I'm curious. How can you replace a currently-installed DLL? (Note that I think I know
> one trick, but I'm not sure it still works).
>
> Note that if the resources are in use, it is normally impossible to replace a DLL.

Suppose we want to update some example.dll (place another with the same
name). Many processes have it loaded and we can't just call MoveFile on
it. Suppose further that we choose not to use MoveFileEx with
MOVEFILE_DELAY_UNTIL_REBOOT, which would be the logical thing to do (but
requires administrator privileges).

So, we do this (and I believe this is the trick you're referring to):
rename example.dll to old_example.dll, copy there new example.dll, and
tell each process to either reload the library, or to restart itself (if
it's a service) or we just close the process and open it again. When all
the processes load new example.dll we can safely delete old_example.dll.

In the mean time some processes will have old_example.dll loaded, but if
they call GetFileVersionInfo they will "think" they have new
example.dll, which may have undesired results. So to avoid this we can't
use GetFileVersionInfo, and instead we should use something that deals
with HMODULE, like FindResourceEx-LoadResource.

The point is that IF we can restart the computer OR we can stop all
processes, replace the file, and start all processes OR there aren't any
undesired results with GetFileVersionInfo THEN we don't need FindResourceEx.
From: Doug Harrison [MVP] on
On Tue, 21 Jun 2005 12:44:18 +0200, Mihajlo CvetanoviĆ½ wrote:

> rename example.dll to old_example.dll, copy there new example.dll, and
> tell each process to either reload the library, or to restart itself (if
> it's a service) or we just close the process and open it again. When all
> the processes load new example.dll we can safely delete old_example.dll.
>
> In the mean time some processes will have old_example.dll loaded, but if
> they call GetFileVersionInfo they will "think" they have new
> example.dll, which may have undesired results. So to avoid this we can't
> use GetFileVersionInfo, and instead we should use something that deals
> with HMODULE, like FindResourceEx-LoadResource.

Ugh. You would typically use GetModuleFileName on the HMODULE given to you
in DllMain. So, two questions:

Q1. Does GetModuleFileName(hModule) stay in step with the file system?

A: No, it does not, at least not with EXEs.

Q2. Does the system still prevent multiple loads of the same DLL if the
name is changed while the process has it loaded?

A: ?

--
Doug Harrison
Microsoft MVP - Visual C++
From: Mihajlo Cvetanovi? on
Doug Harrison [MVP] wrote:
> Ugh. You would typically use GetModuleFileName on the HMODULE given to you
> in DllMain. So, two questions:
>
> Q1. Does GetModuleFileName(hModule) stay in step with the file system?
>
> A: No, it does not, at least not with EXEs.

But I haven't mentioned GetModuleFileName. If we want to do this "right"
we have to make a function that'll access the version info resource by
its module handle (basically all that GetFileVersionInfo does, except
load/access the module by its name).

> Q2. Does the system still prevent multiple loads of the same DLL if the
> name is changed while the process has it loaded?
>
> A: ?

If the process loads the library implicitly then it must free it
implicitly (by finishing the process). The question doesn't apply to
this case.

If the process loads the library with LoadLibrary then it must free it
with FreeLibrary. If the library is not completely freed then all
following calls to LoadLibrary will just increment internal reference
counter, and the bug will present itself because the DLL actually isn't
changed (and old_example.dll can't be deleted).