Search code examples
windowsvisual-c++wmi

Getting Windows version 23H2 from Win32_OperatingSystem


Code:

std::map<CString, CString> mapWindowsVersions
{
    { L"22631", L"23H2" },
    { L"22621", L"22H2" },
    { L"22000", L"21H2" },
    { L"19044", L"21H2" },
    { L"19043", L"21H1" },
    { L"19042", L"20H2" },
    { L"19041", L"2004" },
    { L"18363", L"1909" },
    { L"18362", L"1903" },
    { L"17763", L"1809" },
    { L"17134", L"1803" },
    { L"16299", L"1709" }
};
VARIANT vtProp{};
hres = pclsObj->Get(L"BuildNumber", 0, &vtProp, 0, 0);
strSystemInfo.AppendFormat(L"  Build Number: %s\r\n", mapWindowsVersions[vtProp.bstrVal]);
VariantClear(&vtProp);

This works., I gleaned release descriptions from here. But is there a built-in way to get this description, eg: 23H2?


Solution

  • I don't know the answer off-the-top-of-my-head, but I know where to start looking: winver.exe.

    Here's my About Windows dialog, which dutifully displays the "Version 22H2" string you're after:

    enter image description here

    • Firing up winver.exe in WinDbg or Ghidra or whathaveyou shows that winver.exe just calls into Shell32.dll!ShellAboutW to do all its actual work.
    • ...which in-turn sets-up a Dialog Resource using the (non-exported) function AboutDlgProc to drive the About Windows dialog.
    • ...which calls _InitAboutDlg to load the data (strings, text, etc) into the Dialog's labels/placeholders.
    • ...which opens the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion registry key and then extracts values based on some arbitrary business rules:
      • Apparently there's a (WinRT? C++/CX?) API called EnableH2UIVersioning which controls whether the "22H2"-style release name will be displayed or not. When this is true then the "22H2" string comes from HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DisplayVersion, otherwise it uses HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId.
    • On my machine, both DisplayVersion and ReleaseId are present, but ReleaseId contains the incorrect/old value of "2009" - which means that ReleaseId cannot be trusted if present.