Retrieve Build Version (Windows 10)

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
WOW, I had not yet tested this until now. Microsoft hinted at the use of versioning functions to test build numbers... This methodology however in the Windows 10 preview would indicate that Windows 10 is actually Windows 8 however...
Code:
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <iostream>

enum OS_VER_INFO { OS_VER_MAJOR, OS_VER_MINOR, OS_VER_BUILD };

BOOL os_version_equals(DWORD version, OS_VER_INFO osver_info)
{
  OSVERSIONINFOEX osver_ex;
  ::ZeroMemory(&osver_ex, sizeof(osver_ex));
  osver_ex.dwOSVersionInfoSize = sizeof(osver_ex);

  DWORD type_mask;
  if (osver_info == OS_VER_MAJOR)
  {
    osver_ex.dwMajorVersion = version;
    type_mask = VER_MAJORVERSION;
  }
  else if (osver_info == OS_VER_MINOR)
  {
    osver_ex.dwMinorVersion = version;
    type_mask = VER_MINORVERSION;
  }
  else
  {
    osver_ex.dwBuildNumber = version;
    type_mask = VER_BUILDNUMBER;
  }
  ULONGLONG condition_mask = ::VerSetConditionMask(0, type_mask, VER_EQUAL);
  return ::VerifyVersionInfo(&osver_ex, type_mask, condition_mask);
}

BOOL Check()
{
  return os_version_equals(6, OS_VER_MAJOR) && os_version_equals(2, OS_VER_MINOR);
}

int main()
{
  bool b = Check();
  std::cout << std::boolalpha << b << '\n';
}

OS version 6.2 evaluates to true from my test code.

Without the use of the version helper API provided by Microsoft for the depreciation of other functions, this was a way to determine the exact version of an OS to an accuracy of major and minor version as far as my code is concerned. Unless this will change in the future, I don't see there any other way to detect Windows 10, other than to get file information from kernel32.dll... In which case I can get the major, minor, and build version accurately.

So I guess the question begs, does this mark the beginning of 2 more depreciated functions? (VerSetConditionMask & VerifyVersionInfo). Or is this something to be fixed later with the official release of Windows 10. Perhaps it's too early to tell, but right now this is pretty quirky.
 
I understand that you're not using GetVersion/GetVersionEx, but there's a little comment in the documentation for that function which I wonder - just wonder - whether should be in the function VerifyVersionInfo documentation too in some form or other.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx said:
The value returned by the GetVersion function now depends on how the application is manifested.

Applications not manifested for Windows 8.1 will return the Windows 8 OS version value (6.2). Once an application is manifested for a given operating system version, GetVersion will always return the version that the application is manifested for in future releases. To manifest your applications for Windows 8.1 please refer to Targeting your application for Windows 8.1.
I almost wonder whether these new functions do weird things if manifested for an old OS. How was yours manifested? Is this a possibility or completely off the mark?


To be honest, a depreciation of these two functions would not be a huge loss :p
 
No, because VerifyVersionInfo() still evaluates major and minor version properly up until 8.1, whereas GetVersion(Ex) does not. GetVersion(Ex) reports accurate data with the proper compatibility manifest though, yes.
 
Lel why not just read from Registry?

Code:
#include <Windows.h>
#include <String>

std::wstring ReadRegistryKey(HKEY wsRoot, std::wstring wsPath, std::wstring wsKey)
{
    HKEY hKey;
    DWORD dwType;
    DWORD dwData;

    if (RegOpenKeyEx(wsRoot, wsPath.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
    {
        printf("ERROR: Register Path");
        RegCloseKey(hKey);
    }
    else if (RegQueryValueEx(hKey, wsKey.c_str(), NULL, &dwType, NULL, &dwData) != ERROR_SUCCESS)
    {
        printf("ERROR: Register Key");
        RegCloseKey(hKey);
    }
    else if (dwType != REG_SZ)
    {
        printf("ERROR: Register Type");
        RegCloseKey(hKey);
    }

    std::wstring wsValue(dwData / sizeof(wchar_t), L'\0');

    if (RegQueryValueEx(hKey, wsKey.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&wsValue[0]), &dwData) != ERROR_SUCCESS)
    {
        printf("ERROR: Register Value");
        RegCloseKey(hKey);
    }

    RegCloseKey(hKey);

    size_t szNullTerminator = wsValue.find_first_of(L'\0');

    if (szNullTerminator != std::string::npos)
    {
        wsValue.resize(szNullTerminator);
    }

    return wsValue;
}

int main()
{
    std::wstring wsRegisterKey = ReadRegistryKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"CurrentBuild");
    LPCWSTR lpRegisterKey = wsRegisterKey.c_str();

    wprintf(lpRegisterKey);
    getchar();
}
 
Most simple solution always seems to be the hardest one to start with in the order of thought processing. ;) I forgot about that registry key too.. :lol:

You're missing some headers in the code (i.e. <cstdio>) but that's fine and not really relevant.
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top