VerQueryValue - Problem

Sep 14, 2012 at 10:22am
Hi,

i have a problem with one of my functions. In one of the last lines:
if (VerQueryValue(lpVI, tszVerStrName, &lpt, (PUINT)cbBufSize)){
name = ((LPTSTR)lpt); //wanna have the description - application name
}

This is never true. i cant image a solution for that. Can you plz help me?


wchar_t* GetVersionString(wchar_t* szFile)
{	
	DWORD dwLen, dwUseless;
    LPTSTR lpVI;
	wchar_t* name;
    UINT verMajor;
 
	dwLen = GetFileVersionInfoSizeEx(FILE_VER_GET_NEUTRAL,(LPWSTR)szFile, &dwUseless);
    if (dwLen==0)
	{
        return 0;
	}else{
		int o = 0;
	}
 
    lpVI = (LPTSTR) GlobalAlloc(GPTR, dwLen);
    if (lpVI)
    {
        DWORD dwBufSize;
        VS_FIXEDFILEINFO* lpFFI;
        BOOL bRet = FALSE;
        WORD* langInfo;
        UINT cbLang;
        WCHAR tszVerStrName[128];
        LPVOID lpt;
        UINT cbBufSize = 0;
 
        GetFileVersionInfo((LPTSTR)szFile, NULL, dwLen, lpVI);
 
        if (VerQueryValue(lpVI, L"\\",(LPVOID *) &lpFFI, (UINT *) &dwBufSize))
        {
            //We now have the VS_FIXEDFILEINFO in lpFFI
            verMajor = HIWORD(lpFFI->dwFileVersionMS);
        }
        //First, to get string information, we need to get language information.
        VerQueryValue(lpVI, L"\\VarFileInfo\\Translation",(LPVOID*)&langInfo, &cbLang);
        //Prepare the label -- default lang is bytes 0 & 1 of langInfo
        wsprintf(tszVerStrName, L"\\StringFileInfo\\%04x%04x\\%s",langInfo[0], langInfo[1], L"Description");
        //Get the string from the resource data
        if (VerQueryValue(lpVI, tszVerStrName, &lpt, (PUINT)cbBufSize))
            name = ((LPTSTR)lpt);    //*must* save this
        //Cleanup
        GlobalFree((HGLOBAL)lpVI);
    }
	return name;
}


best regards

:-)
Last edited on Sep 14, 2012 at 10:24am
Sep 14, 2012 at 4:22pm
Microsoft webpage for GetFileVersionInfoSizeEx() says:

FILE_VER_GET_NEUTRAL
0x002



Loads the version resource strings from the corresponding MUI file, if available, and loads the binary version information (VS_FIXEDFILEINFO) from the corresponding language-neutral file, if available. This flag must be combined with FILE_VER_GET_LOCALISED.


http://msdn.microsoft.com/en-us/library/windows/desktop/aa969435%28v=vs.85%29.aspx
Sep 15, 2012 at 8:34am
okay. hmm like this?

GetFileVersionInfoExW(FILE_VER_GET_NEUTRAL|FILE_VER_GET_LOCALISED,(LPWSTR)szFile, NULL, dwLen, lpVI);

befor the function:
- szFile = 0x00371e30 L"C:\\Users\\Admin\\Documents\\Visual Studio 2012\\Projects\\MFCApplication1\\Debug\\MFCApplication1.exe"
- dwLen = 1652

after this function:
lpVI = 0x00372058 L"̸4"
Sep 15, 2012 at 11:12am
You have another error, you incorrectly use GlobalAlloc function. This returns a handle which later must be passed to GlobalLock()/GlobalUnlock() to obtain the memory pointer, it is not intended to cast the return value directly.

And generally always use GetLastError after each function call to see where it fails.
Sep 15, 2012 at 4:11pm
@mordoran

Actually, when GlobalAlloc is called with GPTR it is OK (and pretty comon practice) to just to cast the return as it's already a memory address. For example, the sample code in this MSDN entry shows GlobalAlloc + GPTR + cast...

Formatted Date and Time Strings
http://msdn.microsoft.com/en-us/library/cc194815.aspx

You see, GPTR is GMEM_FIXED | GMEM_ZEROINIT. And GMEM_FIXED requests a fixed block of memory: i.e. the return value is a memory pointer.

It's when you use GMEM_MOVEABLE that a handle (to a moveable block of memory) is returned and you are required to use GlobalLock to obtain an actual pointer.

(Calling GlobalLock on a pointer returned when you GlobalAlloc with GPTR is benign: it just gives you the same--already fixed--address back.)

Andy
Last edited on Sep 15, 2012 at 4:40pm
Sep 16, 2012 at 12:28pm
Thanks for the answers.

The error-Code is 1813 (from GetLastError)), it means, that the ressource was not found. But there have to be a ressource.

The error-Code is set here:
if (VerQueryValue(lpVI, tszVerStrName, &lpt, (PUINT)cbBufSize))


Does anyone have an advide?

best regards
Sep 16, 2012 at 12:41pm
#1 Open the binary and check the resource looks as expected

#2 Use either

GetFileVersionInfoSize + GetFileVersionInfo

or

GetFileVersionInfoSizeEx + GetFileVersionInfoEx

i.e. don't mix Ex and non-Ex (just in case...)

#3 Are you using the MUI mechanism? If not, the right flag value might be none (i.e. 0)

(the non-Ex prob calls the Ex version with no flags?)
Last edited on Sep 16, 2012 at 12:42pm
Sep 19, 2012 at 5:05pm
Hi,

thanks for the answer. i changed my code.
it looks like this now:
~see code below

But its still not working and i really dont know why...
here are a few debug-values:

dwLen = 1652

szFile = 0x004d1bb0 L"C:\\Users\\Admin\\Documents\\Visual Studio 2012\\Projects\\MFCApplication1\\Debug\\MFCApplication1.exe"

now From GetFileVersionInfoExW(...): lpVI = 0x004d1dd8 L"̸4" // looks in editor more like a "Á"

error = 0

cbLang = 4

langInfo[0] = 1031

langInfo[1] = 1200

tszVerStrName = 0x0037e3b0 L"\\StringFileInfo\\040704b0\\Description"

error = 1813  //<<--- dont know why!?


Here's now the code:
DWORD dwLen, dwUseless;
    LPTSTR lpVI;
	wchar_t* name;
    UINT verMajor;
 
	dwLen = GetFileVersionInfoSizeEx(FILE_VER_GET_NEUTRAL|FILE_VER_GET_LOCALISED,(LPWSTR)szFile, &dwUseless);
    if (dwLen==0)
	{
        return 0;
	}else{
		int o = 0;
	}
 
    lpVI = (LPTSTR) GlobalAlloc(GPTR, dwLen);
    if (lpVI)
    {
        DWORD dwBufSize;
        VS_FIXEDFILEINFO* lpFFI;
        BOOL bRet = FALSE;
        WORD* langInfo;
        UINT cbLang;
        WCHAR tszVerStrName[128];
        LPVOID lpt;
        UINT cbBufSize = 0;
 
        GetFileVersionInfoExW(FILE_VER_GET_NEUTRAL|FILE_VER_GET_LOCALISED,(LPWSTR)szFile, NULL, dwLen, lpVI);
 
        if (VerQueryValue(lpVI, L"\\",(LPVOID *) &lpFFI, (UINT *) &dwBufSize))
        {
            //We now have the VS_FIXEDFILEINFO in lpFFI
            verMajor = HIWORD(lpFFI->dwFileVersionMS);
        }
		DWORD error = GetLastError();
        //First, to get string information, we need to get language information.
        VerQueryValue(lpVI, L"\\VarFileInfo\\Translation",(LPVOID*)&langInfo, &cbLang);
		error = GetLastError();
        //Prepare the label -- default lang is bytes 0 & 1 of langInfo
        wsprintf(tszVerStrName, L"\\StringFileInfo\\%04x%04x\\%s",langInfo[0], langInfo[1], L"Description");
        //Get the string from the resource data
        if (VerQueryValue(lpVI, tszVerStrName, &lpt, (PUINT)cbBufSize))
            name = ((LPTSTR)lpt);    //*must* save this
		error = GetLastError();
        //Cleanup
        GlobalFree((HGLOBAL)lpVI);
    }
	return name;



Who can solve this problem? BE my hero lol :D
Last edited on Sep 19, 2012 at 5:07pm
Sep 19, 2012 at 6:36pm
This seems like bad cast to me:
VerQueryValue(lpVI, tszVerStrName, &lpt, (PUINT)cbBufSize)

after you declared cbBufSize as UINT initialized with 0.

Try this:
VerQueryValue(lpVI, tszVerStrName, &lpt, &cbBufSize)
Sep 20, 2012 at 1:48pm

this doesnt solve my problem. cdBufSize is 0 at this Moment. The Error still exists.


Sep 20, 2012 at 3:53pm
It is 0 at the moment, but its value will be changed after calling win32 function VerQueryValue..

When this method returns, contains a pointer to the size of the requested data pointed to by lplpBuffer: for version information values, the length in characters of the string stored at lplpBuffer; for translation array values, the size in bytes of the array stored at lplpBuffer; and for root block, the size in bytes of the structure.
Topic archived. No new replies allowed.