4

I am trying to retrieve kernel32.dll version in order to perform a Windows version check. Yet, for some reason, even though kernel32.dll's version (as seen in file properties) is 10.0.10586.0, the returned version is: 6.2.10586.0 how come?

    DWORD dwDummy;
    DWORD dwFVISize = GetFileVersionInfoSize(lpszFilePath, &dwDummy);
    LPBYTE lpVersionInfo = new BYTE[dwFVISize];
    if (GetFileVersionInfo(lpszFilePath, 0, dwFVISize, lpVersionInfo) == 0)
    {
        return FALSE;
    }

    UINT uLen;
    VS_FIXEDFILEINFO *lpFfi;
    BOOL bVer = VerQueryValue(lpVersionInfo, L"\\", (LPVOID *)&lpFfi, &uLen);

    if (!bVer || uLen == 0)
    {
        return FALSE;
    }
    DWORD dwFileVersionMS = lpFfi->dwFileVersionMS;
    DWORD dwFileVersionLS = lpFfi->dwFileVersionLS;
    delete[] lpVersionInfo;

    DWORD dwLeftMost = HIWORD(dwFileVersionMS);
    DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
    DWORD dwSecondRight = HIWORD(dwFileVersionLS);
    DWORD dwRightMost = LOWORD(dwFileVersionLS);

Kernel32.dll properties (same as in SysWow64): enter image description here

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
RanH
  • 740
  • 1
  • 11
  • 31
  • Build your app as a 64 bit executable and see if you get the same result. – Jonathan Potter Jun 28 '16 at 07:27
  • 2
    See [how to detect windows 10 in c++](http://stackoverflow.com/q/36543301/1889329) for an alternate approach. – IInspectable Jun 28 '16 at 07:27
  • "in order to perform a windows version check." - fastest and most effective use RtlGetNtVersionNumbers for this – RbMm Jun 28 '16 at 10:43
  • 1
    @RbMm: `RtlGetNtVersionNumbers` is undocumented. It is not part of the public programming interface, and may not be available in a future version of the OS. Why not recommend [RtlGetVersion](https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910.aspx) instead? At least that's documented (even though calling a kernel-mode routine from user-mode may not be supported in a future OS as well). – IInspectable Jun 28 '16 at 12:01
  • @IInspectable yes, RtlGetVersion also good choice for determinate os version number(both in kernel and user mode). when i wrote about RtlGetNtVersionNumbers - this was not recommendation, but this function is absolute fastest and lightweight way for get version numbers only. not public programming interface ? but exported. about undocumented - util this is exist and not changed from xp(think and in win2000 but cannot check) to win 10 latest build. visa versa GetVersion[Ex] is well documented, but it behavior is changed - so now it can not correct work in 8.1 and 10. – RbMm Jun 28 '16 at 12:33
  • 2
    @RbMm: Programming isn't about statistics. Just because an API hasn't changed in ** doesn't mean that it won't go away at **. Better performance is not ever a valid reason to ignore a documented API. If you don't care about correctness it is trivially easy to improve the performance (by omitting the call altogether). – IInspectable Jun 28 '16 at 12:45
  • 1
    This code will leak memory if `VerQueryValue` fails, due to the early return just before freeing `lpVersionInfo`. Not a big deal really, just wanted to point it out. – sir-pinecone Apr 29 '19 at 19:33

2 Answers2

7

You are reading the wrong fields from the version information for this task. Instead of dwFileVersionMS and dwFileVersionLS use dwProductVersionMS and dwProductVersionLS.

The file version fields are subject to supportedOS compatibility issues. That is their values depend on the supportedOS levels declared in your application manifest. On the other hand the product version fields do not depend on the manifest.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • is it relevant even though the file version is the same as the product version? I am trying it now. – RanH Jun 28 '16 at 07:15
  • Your code yields 6.2 when I run it, but 10.0 when you use the correct fields. – David Heffernan Jun 28 '16 at 07:47
  • You should really have pulled this out into a separate [mcve]. That would have made it easier for all of us to investigate, you included. – David Heffernan Jun 28 '16 at 07:55
  • " wrong fields" - dwFileVersionMS not wrong field, but it can be "fixed" . dwProductVersionMS - not fixed now (before "fix" dwFileVersionMS==dwProductVersionMS) – RbMm Jun 28 '16 at 09:19
  • @RbMm They are the wrong fields in the sense that the asker is, presumably, looking for the true version rather than the compat version. I mean, otherwise the asker would just call `GetVersionEx`. – David Heffernan Jun 28 '16 at 09:55
  • "in order to perform a windows version check." - need at all another API use. – RbMm Jun 28 '16 at 10:57
  • 1
    @RbMm I don't understand that comment at all. Do you understand why people check product version of a system DLL? – David Heffernan Jun 28 '16 at 10:59
  • yes, author want perform a windows version check. but selected way for this - not very good, from my look. the absolut fastest and universal way(work from xp up to latest win10) - ULONG Major, Minor, Build; RtlGetNtVersionNumbers(&Major, &Minor, &Build); - here near 10 asm instructions only, in compare with many many thousands with check version fron file(and why kernel32 ?) – RbMm Jun 28 '16 at 11:04
  • 3
    I think that perhaps you should take that up with the asker rather than commenting on my answer, which after all just addressed the question that was asked. Remember to mention that `RtlGetNtVersionNumbers` is an undocumented API that might not exist in a future release. Note also that the asker is doing what MS suggest: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724429(v=vs.85).aspx – David Heffernan Jun 28 '16 at 11:11
  • 2
    Which says: *To obtain the full version number for the operating system, call the GetFileVersionInfo function on one of the system DLLs, such as Kernel32.dll, then call VerQueryValue to obtain the \\StringFileInfo\\\\ProductVersion subblock of the file version information.* Finally, I don't imagine that this code is really going to be a performance bottleneck. – David Heffernan Jun 28 '16 at 11:11
5

Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2).

this is from GetVersionEx function MSDN description. for GetFileVersionInfo no such note, but really this doing same. i look under debugger: enter image description here

enter image description here

so 10.0 ( 0xA000) in dwFileVersionMS can be fixed to 6.2 or 6.3 but dwProductVersionMS - not changed (0xA000 ~ 10.0) think need fix MSDN documentation for GetFileVersionInfo[Ex] :)

RbMm
  • 31,280
  • 3
  • 35
  • 56