Thursday at 09:43 AM3 days 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");
Thursday at 09:59 AM3 days Author https://stackoverflow.com/questions/37700605/getting-windows-os-version-programmatically[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion]"CurrentVersion"="6.3"Problem solved.
Thursday at 01:39 PM3 days 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?
Thursday at 02:36 PM3 days 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.
Thursday at 02:55 PM3 days 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.
Thursday at 03:20 PM3 days 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.
Thursday at 10:31 PM3 days 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 Thursday at 10:31 PM3 days by Stingered
Saturday at 03:55 AM2 days 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
Saturday at 12:31 PM1 day 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
Yesterday at 01:16 AM1 day 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.
Yesterday at 01:43 AM1 day 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 yesterday at 01:46 AM1 day by Stingered
Create an account or sign in to comment