From d562e0ed532f366b929be43bee7da7c9ad3cee59 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sun, 27 Sep 2026 11:22:57 +0900 Subject: [PATCH] Etc.uname: Report the actual Windows version GetVersionEx reports 6.2.9200 on Windows 8.1 and later unless the manifest of the executable declares them as supported, and ruby.manifest does not. RtlGetVersion is not affected by the manifest. Co-Authored-By: Claude Opus 5.5 --- ext/etc/etc.c | 8 ++++++-- test/etc/test_etc.rb | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ext/etc/etc.c b/ext/etc/etc.c index 7155c88..1c82c7c 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -800,6 +800,8 @@ static VALUE etc_uname(VALUE obj) { #ifdef _WIN32 + typedef long (WINAPI version_func)(OSVERSIONINFOW *); + version_func *pRtlGetVersion; OSVERSIONINFOW v; SYSTEM_INFO s; const char *sysname, *mach; @@ -808,9 +810,11 @@ etc_uname(VALUE obj) DWORD len = 0; WCHAR *buf; + /* GetVersionEx reports 6.2 unless the manifest declares Windows 8.1 or later */ + pRtlGetVersion = (version_func *)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"); v.dwOSVersionInfoSize = sizeof(v); - if (!GetVersionExW(&v)) - rb_sys_fail("GetVersionEx"); + if (!pRtlGetVersion || pRtlGetVersion(&v)) + rb_notimplement(); result = rb_hash_new(); sysname = "Windows_NT"; diff --git a/test/etc/test_etc.rb b/test/etc/test_etc.rb index d0e19f3..39cac7c 100644 --- a/test/etc/test_etc.rb +++ b/test/etc/test_etc.rb @@ -131,6 +131,11 @@ def test_uname } end + def test_uname_release_on_windows + release = IO.popen(%w[cmd.exe /c ver], "rb", &:read)[/\d+\.\d+\.\d+/] + assert_equal(release, Etc.uname[:release]) + end if /mswin|mingw/ =~ RUBY_PLATFORM + def test_sysconf begin Etc.sysconf