April 9Apr 9 Getting real version number of Windows 8.1:This doesn't work:https://gist.github.com/ijat/396663fc902683f9a86be84a7fcd88c5it returns bogus 5.1 version: 5 major 1 minor RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion"); if (fxPtr != NULL) { rovi.dwOSVersionInfoSize = sizeof(rovi); if ( STATUS_SUCCESS == fxPtr(&rovi) ) { OSVERSIONINFO os; ZeroMemory(&os, sizeof(OSVERSIONINFO)); os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); os.dwMajorVersion = rovi.dwMajorVersion; os.dwMinorVersion = rovi.dwMinorVersion; int sheetmajor = os.dwMajorVersion; // 5 int sheetminor = os.dwMinorVersion; // 1 return os; } }for Windows 10 I use this and it works:https://codereview.stackexchange.com/questions/107898/get-os-name-in-cchar* majorv_str = TryReadRegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentMajorVersionNumber");char* minorv_str = TryReadRegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentMinorVersionNumber");
April 9Apr 9 Author https://stackoverflow.com/questions/37700605/getting-windows-os-version-programmatically[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion]"CurrentVersion"="6.3"Problem solved.
April 9Apr 9 Author Use the reg query command in Command Prompt or PowerShell to display registry values. The basic syntax is reg query "KeyName" /v "ValueName". To see all values under a key, omit /v.So I've used:reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentVersionin command prompt return "6.3" proper value but in the program return 5.1 value.WTF is going on?
April 9Apr 9 This works as expected for Windows 8.1...; *********************************************************************************************************************** ;- Global System Libraries ; *********************************************************************************************************************** Global NtDLL = OpenLibrary(#PB_Any, "ntdll.dll") ; *********************************************************************************************************************** ;- Prototypes - NtDLL ; *********************************************************************************************************************** Prototype.i RtlGetVersion_(dlpVersionInformation) Global RtlGetVersion_.RtlGetVersion_ RtlGetVersion_ = GetFunction(NtDLL, "RtlGetVersion") ; The RtlGetVersion routine returns version information about the currently running operating system. Procedure.s GetWindowsVersion() Protected RTL.OSVERSIONINFOEX #STATUS_SUCCESS = #Null RTL\dwOSVersionInfoSize = SizeOf(RTL) If RtlGetVersion_ If RtlGetVersion_(@RTL.OSVERSIONINFOEX) = #STATUS_SUCCESS OS_dwMajor = RTL\dwMajorVersion OS_dwMinor = RTL\dwMinorVersion OS_dwBuild = RTL\dwBuildNumber ProcedureReturn Str(OS_dwMajor) + "." + OS_dwMinor + "." + OS_dwBuild EndIf EndIf ProcedureReturn "#NULL" EndProcedure Debug GetWindowsVersion()Ted.
April 9Apr 9 Author 15 minutes ago, Teddy Rogers said:This works as expected for Windows 8.1...; *********************************************************************************************************************** ;- Global System Libraries ; *********************************************************************************************************************** Global NtDLL = OpenLibrary(#PB_Any, "ntdll.dll") ; *********************************************************************************************************************** ;- Prototypes - NtDLL ; *********************************************************************************************************************** Prototype.i RtlGetVersion_(dlpVersionInformation) Global RtlGetVersion_.RtlGetVersion_ RtlGetVersion_ = GetFunction(NtDLL, "RtlGetVersion") ; The RtlGetVersion routine returns version information about the currently running operating system. Procedure.s GetWindowsVersion() Protected RTL.OSVERSIONINFOEX #STATUS_SUCCESS = #Null RTL\dwOSVersionInfoSize = SizeOf(RTL) If RtlGetVersion_ If RtlGetVersion_(@RTL.OSVERSIONINFOEX) = #STATUS_SUCCESS OS_dwMajor = RTL\dwMajorVersion OS_dwMinor = RTL\dwMinorVersion OS_dwBuild = RTL\dwBuildNumber ProcedureReturn Str(OS_dwMajor) + "." + OS_dwMinor + "." + OS_dwBuild EndIf EndIf ProcedureReturn "#NULL" EndProcedure Debug GetWindowsVersion()Ted.Thanks. I think that my Windows 8.1 is corrupted or something,I can't even find Windows Defender on that Windows,unfortunately I only have 2 backups of Windows with Windows 8.1.
April 9Apr 9 Author Here is my code: RTL_OSVERSIONINFOW rovi = { 0 }; HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll"); if (hMod) { RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion"); if (fxPtr != NULL) { rovi.dwOSVersionInfoSize = sizeof(rovi); if ( STATUS_SUCCESS == fxPtr(&rovi) ) { OSVERSIONINFO os; ZeroMemory(&os, sizeof(OSVERSIONINFO)); os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); os.dwMajorVersion = rovi.dwMajorVersion; os.dwMinorVersion = rovi.dwMinorVersion; int sheetmajor = os.dwMajorVersion; // 5 int sheetminor = os.dwMinorVersion; // 1 return os; } } }returns v5.1 Here is registry key read: char* version_str = TryReadRegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion"); char* TryReadRegistryKey(HKEY hkey,char* regpath, char* valuename) { LONG lResult; HKEY hKey2; DWORD dwType; DWORD dwBytes = 100; lResult = RegOpenKeyEx(hkey, regpath, 0, KEY_READ|KEY_QUERY_VALUE|KEY_WOW64_32KEY, &hKey2); if (lResult != ERROR_SUCCESS) return 0; lResult = RegQueryValueEx(hKey2, valuename, 0, &dwType, (LPBYTE)buffer_keep, &dwBytes); RegCloseKey(hKey2); if (lResult == ERROR_SUCCESS) return buffer_keep; return 0; } also return v5.1.@Teddy Rogers I will be very great-full if you post an compiled exe if that is possible.
April 9Apr 9 4 hours ago, boot said: src & exe ...GetWinVer_src.zip@boot , I was unable to compile your code for x86 on VS 2022, so I wrote my own based off of what you provided. I was able to compile (x86/x64) and run this code on WIN7+:// // Windows Version Reader by Stingered (2026) // Compatible: Windows 7 through Windows 11 (hopefully) // #include <Windows.h> #include <stdio.h> #include <iostream> typedef NTSTATUS(NTAPI* pfnRtlGetVersion)(PRTL_OSVERSIONINFOW); void GetRealVersion(DWORD* major, DWORD* minor, DWORD* build, DWORD* revision) { HMODULE hMod = GetModuleHandleW(L"ntdll.dll"); if (hMod) { pfnRtlGetVersion RtlGetVersion = (pfnRtlGetVersion)GetProcAddress(hMod, "RtlGetVersion"); if (RtlGetVersion) { OSVERSIONINFOEXW osvi = { 0 }; osvi.dwOSVersionInfoSize = sizeof(osvi); if (RtlGetVersion((PRTL_OSVERSIONINFOW)&osvi) == 0) { // STATUS_SUCCESS if (major) *major = osvi.dwMajorVersion; if (minor) *minor = osvi.dwMinorVersion; if (build) *build = osvi.dwBuildNumber; } } } HKEY hKey; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { DWORD ubr = 0; DWORD size = sizeof(ubr); if (RegQueryValueExW(hKey, L"UBR", NULL, NULL, (LPBYTE)&ubr, &size) == ERROR_SUCCESS) { if (revision) *revision = ubr; } RegCloseKey(hKey); } } int main() { std::cout << "\r\n Windows OS Version Reader\r\n"; std::cout << " Compatibility: Windows 7 through Windows 11 (hopefully)\r\n"; DWORD major = 0; DWORD minor = 0; DWORD build = 0; DWORD revision = 0; GetRealVersion(&major, &minor, &build, &revision); printf("\r\n Windows Version -> %u.%u.%u.%u\r\n", major, minor, build, revision); printf("\n"); system("pause"); return 0; } Edited April 9Apr 9 by Stingered
April 11Apr 11 Author char* version_str = TryReadRegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion"); // CurrentVersion" if (version_str!=0&&((finded = strstr(version_str,".")) != NULL)) // doesn't work in Windows 8.1 neither on Windows 10. RTL_OSVERSIONINFOW rovi = { 0 }; HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll"); if (hMod) { RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion"); if (fxPtr != NULL) { rovi.dwOSVersionInfoSize = sizeof(rovi); if ( STATUS_SUCCESS == fxPtr(&rovi) ) { OSVERSIONINFO os; ZeroMemory(&os, sizeof(OSVERSIONINFO)); os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); os.dwMajorVersion = rovi.dwMajorVersion; os.dwMinorVersion = rovi.dwMinorVersion; return os; } } } // doesn't work in Windows 8.1 neither on Windows 10. PPEB2 pPeb = NtCurrentPeb(); if (pPeb!=NULL) { OSVERSIONINFO os; ZeroMemory(&os, sizeof(OSVERSIONINFO)); os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); os.dwMajorVersion = pPeb->OSMajorVersion; os.dwMinorVersion = pPeb->OSMinorVersion; return os; } // works on all versions of Windows including Windows XP; Windows 8.1, Windows 10, Windows 11. char* majorv_str = TryReadRegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentMajorVersionNumber"); // Works on Windows 10 and Windows 11.So RtlGetVersion doesn't work on Windows 8.1 neither TryReadRegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion"); "CurrentVersion" seems to be virtualized.So I will use TryReadRegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentMajorVersionNumber"); and if fails PPEB2 pPeb = NtCurrentPeb(); from now.Thank you @boot
April 11Apr 11 On 4/9/2026 at 11:20 PM, CodeExplorer said:I will be very great-full if you post an compiled exe if that is possible.Apologies for the late response. Let me know if this was not what you wanted...Ted. RtlGetVersion.zip
April 12Apr 12 Author 12 hours ago, Teddy Rogers said:Apologies for the late response. Let me know if this was not what you wanted...Ted.RtlGetVersion.zipThanks. Your example works, but in my Visual C++ program RtlGetVersion doesn't work, probability I'm missing some config.I was able to fix this by @boot samples; all works fine now.
April 12Apr 12 19 minutes ago, CodeExplorer said:Thanks. Your example works, but in my Visual C++ program RtlGetVersion doesn't work, probability I'm missing some config.I was able to fix this by @boot samples; all works fine now.I didn't try Teddy's, but this method seems to get the same results I had earlier and is supposedly Windows 2000+ (off of stackoverflow). Seems very similar to my earlier code (tiny edits for granularity).#include <windows.h> #include <stdio.h> typedef LONG(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOEXW); DWORD GetUBR() { HKEY hKey; DWORD ubr = 0; DWORD size = sizeof(ubr); if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { RegQueryValueExW(hKey, L"UBR", NULL, NULL, (LPBYTE)&ubr, &size); RegCloseKey(hKey); } return ubr; } int main() { HMODULE ntdll = GetModuleHandleW(L"ntdll.dll"); if (!ntdll) { printf("Failed to load ntdll.dll\n"); return 1; } RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(ntdll, "RtlGetVersion"); if (!RtlGetVersion) { printf("RtlGetVersion not found\n"); return 1; } RTL_OSVERSIONINFOEXW ver = { 0 }; ver.dwOSVersionInfoSize = sizeof(ver); if (RtlGetVersion(&ver) != 0) { printf("RtlGetVersion failed\n"); return 1; } DWORD ubr = GetUBR(); printf("Version: %lu.%lu.%lu.%lu\n", ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, ubr ); return 0; } Edited April 12Apr 12 by Stingered
Create an account or sign in to comment