VerQueryValue - Problem

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
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
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"
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.
@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
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
#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
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
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)

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


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.