Matt wrote:
Regarding the version info. Following Remy's suggestion that it is
inefficient to call GetFileVersionInfo on a DLL
That is not what I said.
not sure if that is just DLL or if it applies to executables also
It applies to any executable. GetFileVersionInfo*() opens its own handle
to the specified file on the filesystem - even if it is accessing the same
file that created the calling process. That is what makes it an inefficient
API for an executable to access its own own version resource, which is already
present in the calling process's memory.
Now you can pass `p_res` and `dwSize` to some code which expects to
use the value returned by `GetFileVersionInfo`.
If you take the resource pointer returned by LockResource() and pass it as-is
to VerQueryValue(), you will
CRASH it (I've done it before). The memory
block returned by LockResource() is read-only, but VerQueryValue() requires
the memory blocked to be writable instead. GetFileVersionInfo*() guarantees
that, since you have to allocate the memory block that it fills. VerQueryValue()
also expects certain data inside of the memory block to be fixed up by GetFileVersionInfo*()
- something LockResource() does not do - so if you did pass the raw resource
block to VerQueryValue(), the only data it could safely extract without runing
into problems is the VS_FIXEDFILEINFO structure and none of the localized
data.
If you want to use LockResource() with VerQueryValue(), you need to make
a
copy of the resource data first, eg:
HRSRC h_res = FindResource(hinst, MAKEINTRESOURCE(1), RT_VERSION);
HGLOBAL h_dat = LoadResource(hinst, h_res);
DWORD dwSize = SizeofResource(hinst, h_res);
void *p_res = LockResource(h_dat);
BYTE *p_res_copy = new BYTE[dwSize];
memcpy(p_res, p_res_copy, dwSize);
// Now you can pass `p_res_copy` and `dwSize` to some code which
// expects to use the value returned by `GetFileVersionInfo`.
delete[] p_res_copy;
Although this appeared to work, I found another page on stackoverflow
which suggested that you are not supposed to call VerQueryValue on
the buffer returned by LockResource as it might write the buffer, so I
actually now copy this buffer and pass the copy to the code for reading it.
That is correct.
--
Remy Lebeau (TeamB)
Connect with Us