1

My code below is similar to the example in the VerQueryValue() documentation:

// Structure used to store enumerated languages and code pages.

HRESULT hr;

struct LANGANDCODEPAGE {
  WORD wLanguage;
  WORD wCodePage;
} *lpTranslate;

// Read the list of languages and code pages.

VerQueryValue(pBlock, 
              TEXT("\\VarFileInfo\\Translation"),
              (LPVOID*)&lpTranslate,
              &cbTranslate);

// Read the file description for each language and code page.

for( i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ )
{
  hr = StringCchPrintf(SubBlock, 50,
            TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
            lpTranslate[i].wLanguage,
            lpTranslate[i].wCodePage);
    if (FAILED(hr))
    {
    // TODO: write error handler.
    }

  // Retrieve file description for language and code page "i". 
  VerQueryValue(pBlock, 
                SubBlock, 
                &lpBuffer, 
                &dwBytes); 
}

The code can retrieve string informations for other exe files, but only for 1 particular file, it can not retrieve string infos (I noticed the language is zero for this case).

By using file explorer, I can see the language is 'Language Neutral'. But, the code shows language part is 0 and codepage part is 1252.

  1. Is it normal to get language as 0?
  2. Furthermore, I'm not able to get CompanyName and other string, but those are available from windows file explorer.

Here's the screenshots in VC++ for that exe: enter image description here

Any ideas?

user1633272
  • 2,007
  • 5
  • 25
  • 48
  • 1
    You say File Explorer reports the language as "Language Neutral". Well. `LANG_NEUTRAL` in the Win32 API is defined as 0. So what is the actual problem? You say you can't get the `CompanyName`, but you did not show that code. Did you check all of the available languages in the version info? English in particular? Windows Explorer doesn't just stop at one language, it has fallbacks if something is missing in a particular language – Remy Lebeau Oct 12 '17 at 18:09
  • @RemyLebeau not able to get string values using the example code. – user1633272 Oct 12 '17 at 18:11
  • That is not particularly helpful when you haven't shown the actual data from the executable's version info resource. If we can't see what you are querying, we can't tell you what you are doing wrong – Remy Lebeau Oct 12 '17 at 18:12
  • @RemyLebeau screenshot attached. – user1633272 Oct 13 '17 at 02:01
  • that is still not helpful – Remy Lebeau Oct 13 '17 at 02:02
  • Sorry, I didn't get the point, the exe is not owned by me, how could I show the actual data? – user1633272 Oct 13 '17 at 02:03
  • 2
    You can open an EXE in visual studio and browse its resources. – Dave S Oct 13 '17 at 02:09
  • @DaveS Thanks! Screenshot updated. It shows language is 0409. I guess I need to retrieve 0409 (default language code) in case of language = 0, do you know what API can offer this value? – user1633272 Oct 13 '17 at 02:14
  • @user1633272 does the resource have multiple languages in it to begin with? First you said it was neutral, now you are saying it is English. What is the actual result of your enumeration? Typically, when querying a file's version, you should check if there is a value in the language of the calling thread, then if not found then check for neutral, then if not then check for English. – Remy Lebeau Oct 13 '17 at 03:00
  • @RemyLebeau The enumeration only get 1 language which is 0(neutral). You mean the enumeration is not reliable? I also added one more screenshot, it shows neutral in the resource tree, but after opening, it shows '040904e4' in 'Block Header'. – user1633272 Oct 13 '17 at 03:08
  • @user1633272 it can't be neutral and English at the same time. And that is certainly not English text in the screenshot. Is `sizeof(LANGANDCODEPAGE)` 4 or 6+? Is `cbTranslate` 4 or 8+! – Remy Lebeau Oct 13 '17 at 03:12
  • @RemyLebeau screenshot updated, if you see the tab name of version window, it also shows 'Neutral'. sizeof(LANGANDCODEPAGE) == 4 and cbTranslate == 4. – user1633272 Oct 13 '17 at 03:23
  • @user1633272 the bottom screenshot is lying. Neutral is not English. If `lpTranslate[0].wLanguage` is 0 then it is Neutral. If the actual string table says English, then the version resource is corrupted – Remy Lebeau Oct 13 '17 at 03:27
  • @RemyLebeau :), I can use "\\StringFileInfo\\040904e4\\..." to get the correct Chinese string values. 0409 == MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT). – user1633272 Oct 13 '17 at 03:31
  • @user1633272 yes `0409` = English. and `04e4` = codepage 1252, which doesn't support Chinese. Whoever setup this EXE clearly don't know what they are doing. Putting Chinese text in an English string table is so very wrong, and clearly doesn't match the translation table either way. – Remy Lebeau Oct 13 '17 at 03:33
  • @RemyLebeau, that's true. It also tell us the translation table is not always reliable. Maybe VC++ and explorer use the fallback mechanism you mentioned to identify the language. I can do similar logic. – user1633272 Oct 13 '17 at 03:40
  • 2
    @user1633272 see the comments on [Can't read FileVersionInfo with Code Page mismatch](https://stackoverflow.com/questions/37953472/), there is some useful heuristics info described. Also see the documentation for how the `dwLanguageId` parameter of [`FormatMessage()`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx) heuristicly searches for resource strings – Remy Lebeau Oct 13 '17 at 03:54

0 Answers0