views:

208

answers:

3

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

+3  A: 

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 call GetLastError 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, use GetLastError 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.

Eric Melski
+4  A: 

Try the following:

  • Retrieve the reason for GetFileVersion's failure by using GetLastError
  • Tell us what OS it works on and what OS it doesn't
  • Check if GetFileVersionInfo succeeds or not (again GetLastError)
  • Read the Remarks section of the MSDN documentation of the abovementioned functions repeatedly and check if you are not missing something.
dirkgently
A: 

nvm. Seems Stackoverflow beats the heck out of me if it isn't answered.....

Billy3

Billy ONeal