Hello all :)
I am trying to get version information from a file. My code works perfectly for me, but fails on several others' machines. Because I can't reproduce the bug, I'm having quite a time finding the issue.
Does anyone see anything majorly wrong with this?
LPBYTE versionInformationBlock;
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *langBlockPointer;
UINT translationsCount;
void fileData::enumVersionInformationBlock()
{
bits.set(VERSIONINFOCHECKED);
disable64.disableFS(); //Shut down WOW64
DWORD zero = 0;
DWORD lengthOfVersionData =
GetFileVersionInfoSize(getFileName().c_str(),&zero);
if (!lengthOfVersionData)
{
disable64.enableFS();
return;
}
versionInformationBlock = new BYTE[lengthOfVersionData];
GetFileVersionInfo(getFileName().c_str(),zero,lengthOfVersionData,versionInformationBlock);
VerQueryValue(versionInformationBlock,L"\\VarFileInfo\\Translation",(LPVOID*)&langBlockPointer,&translationsCount);
translationsCount /= sizeof(struct LANGANDCODEPAGE);
disable64.enableFS();
}
std::wstring fileData::getVersionInformationString(const std::wstring& str)
{
if (!bits[VERSIONINFOCHECKED])
enumVersionInformationBlock();
if (!versionInformationBlock)
return L"!VERINFO: NOT PE FILE!";
LPCTSTR retString;
UINT retStringLength;
std::wstring result;
static const wchar_t hexChars[] = L"0123456789ABCDEF";
wchar_t hexLanguage[26] = L"\\StringFileInfo\\ \\";
for( size_t idx = 0; idx < translationsCount; idx++ )
{
hexLanguage[16] = *(hexChars + ((langBlockPointer[idx].wLanguage >> 12) & 0x0F));
hexLanguage[17] = *(hexChars + ((langBlockPointer[idx].wLanguage >> 8 ) & 0x0F));
hexLanguage[18] = *(hexChars + ((langBlockPointer[idx].wLanguage >> 4 ) & 0x0F));
hexLanguage[19] = *(hexChars + ( langBlockPointer[idx].wLanguage & 0x0F));
hexLanguage[20] = *(hexChars + ((langBlockPointer[idx].wCodePage >> 12) & 0x0F));
hexLanguage[21] = *(hexChars + ((langBlockPointer[idx].wCodePage >> 8 ) & 0x0F));
hexLanguage[22] = *(hexChars + ((langBlockPointer[idx].wCodePage >> 4 ) & 0x0F));
hexLanguage[23] = *(hexChars + ( langBlockPointer[idx].wCodePage & 0x0F));
std::wstring targetResource(hexLanguage,25);
targetResource.append(str);
if (!VerQueryValue(versionInformationBlock,targetResource.c_str(),(LPVOID *)&retString,&retStringLength))
{
return std::wstring(L"!DOESN'T APPER TO EXIST IN FILE! ERROR: ").append(boost::lexical_cast<std::wstring>(GetLastError()));
}
retStringLength--;
if (!result.empty())
result.append(L" / ");
std::wstring toAppend;
toAppend.assign(retString,retStringLength);
boost::algorithm::trim(toAppend);
result.append(toAppend);
}
return result;
}
std::wstring fileData::getVerCompany()
{
return getVersionInformationString(L"CompanyName");
}
~fileData()
{
if (versionInformationBlock)
delete [] versionInformationBlock;
};
What's really bugging me is that it isn't throwing any of my error messages... it keeps returning garbage.
Any ideas?
Billy3
-
It looks like you are not checking for errors from many of the system calls you are using. For example,
GetFileVersionInfo
will return zero if there is an error getting the data, at which point you can callGetLastError
to find out what the specific failure was. Likewise,GetFileVersionInfoSize
will return zero if there is an error. It looks like you check for that failure but don't bother to log the system error code (again, useGetLastError
to retrieve that value).I suggest you add the error handling code for the system calls you are using. Most likely one of those is failing, and probably leaving a very meaningful error code for you to inspect with
GetLastError
. -
Try the following:
- Retrieve the reason for
GetFileVersion
's failure by usingGetLastError
- Tell us what OS it works on and what OS it doesn't
- Check if
GetFileVersionInfo
succeeds or not (againGetLastError
) - Read the Remarks section of the MSDN documentation of the abovementioned functions repeatedly and check if you are not missing something.
- Retrieve the reason for
-
nvm. Seems Stackoverflow beats the heck out of me if it isn't answered.....
Billy3
0 comments:
Post a Comment