Bug 1193033 - Teach mozinfo to get the real os version number for Windows >= 8.1, r=ted
☠☠ backed out by b83de6011de4 ☠ ☠
authorJames Graham <james@hoppipolla.co.uk>
Tue, 11 Aug 2015 16:43:20 +0100
changeset 257578 e18c579d29f128f90560e64c6ea1062a51e59fe3
parent 257577 08caf7dd050274fcd091f5d9bef5ab2e2c031c68
child 257579 0cf9bfd5af47ed565d31694c9dae1fb879a7423f
push id29223
push userkwierso@gmail.com
push dateThu, 13 Aug 2015 22:18:08 +0000
treeherdermozilla-central@4b35236fc76e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs1193033
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1193033 - Teach mozinfo to get the real os version number for Windows >= 8.1, r=ted For contemporary versions of Windows the sys.getwindowsversion call is unreliable because it depends on a API which had its return value frozen. If we detect this case use an alternate API instead
testing/mozbase/mozinfo/mozinfo/mozinfo.py
--- a/testing/mozbase/mozinfo/mozinfo/mozinfo.py
+++ b/testing/mozbase/mozinfo/mozinfo/mozinfo.py
@@ -23,16 +23,39 @@ from .string_version import StringVersio
 class unknown(object):
     """marker class for unknown information"""
     def __nonzero__(self):
         return False
     def __str__(self):
         return 'UNKNOWN'
 unknown = unknown() # singleton
 
+def get_windows_version():
+    import ctypes
+    class OSVERSIONINFOEXW(ctypes.Structure):
+        _fields_ = [('dwOSVersionInfoSize', ctypes.c_ulong),
+                    ('dwMajorVersion', ctypes.c_ulong),
+                    ('dwMinorVersion', ctypes.c_ulong),
+                    ('dwBuildNumber', ctypes.c_ulong),
+                    ('dwPlatformId', ctypes.c_ulong),
+                    ('szCSDVersion', ctypes.c_wchar*128),
+                    ('wServicePackMajor', ctypes.c_ushort),
+                    ('wServicePackMinor', ctypes.c_ushort),
+                    ('wSuiteMask', ctypes.c_ushort),
+                    ('wProductType', ctypes.c_byte),
+                    ('wReserved', ctypes.c_byte)]
+
+    os_version = OSVERSIONINFOEXW()
+    os_version.dwOSVersionInfoSize = ctypes.sizeof(os_version)
+    retcode = ctypes.windll.Ntdll.RtlGetVersion(ctypes.byref(os_version))
+    if retcode != 0:
+        raise OSError
+
+    return os_version.dwMajorVersion, os_version.dwMinorVersion, os_version.dwBuildNumber
+
 # get system information
 info = {'os': unknown,
         'processor': unknown,
         'version': unknown,
         'os_version': unknown,
         'bits': unknown,
         'has_sandbox': unknown }
 (system, node, release, version, machine, processor) = platform.uname()
@@ -45,16 +68,24 @@ if system in ["Microsoft", "Windows"]:
     # http://bugs.python.org/issue7860
     if "PROCESSOR_ARCHITEW6432" in os.environ:
         processor = os.environ.get("PROCESSOR_ARCHITEW6432", processor)
     else:
         processor = os.environ.get('PROCESSOR_ARCHITECTURE', processor)
     system = os.environ.get("OS", system).replace('_', ' ')
     (major, minor, _, _, service_pack) = os.sys.getwindowsversion()
     info['service_pack'] = service_pack
+    if major >= 6 and minor >= 2:
+        # On windows >= 8.1 the system call that getwindowsversion uses has
+        # been frozen to always return the same values. In this case we call
+        # the RtlGetVersion API directly, which still provides meaningful
+        # values, at least for now.
+        major, minor, build_number = get_windows_version()
+        version = "%d.%d.%d" % (major, minor, build_number)
+
     os_version = "%d.%d" % (major, minor)
 elif system == "Linux":
     if hasattr(platform, "linux_distribution"):
         (distro, os_version, codename) = platform.linux_distribution()
     else:
         (distro, os_version, codename) = platform.dist()
     if not processor:
         processor = machine