[glib/improve-win32-version] gutils.c: Improve Windows Server 2016/10 20H2+ detection



commit 5f56477cc7c73d3d648ee95ad5abac090719b152
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Mon Nov 22 11:56:03 2021 +0800

    gutils.c: Improve Windows Server 2016/10 20H2+ detection
    
    This improves how we obtain the Windows release versions in
    get_windows_version(), in turn g_get_os_info() for Windows Server 2016
    and later, and Windows 10 20H2 (2009) and later and Windows 11, by doing
    the following:
    
    *  Check the build number.  For Windows 11, the build number is 22000+;
       for Windows Server 2022, the build number is 20348, and for Windows
       Server 2019, the build number is 17763.  We know what OS build
       numbers to check for by the Windows OS type that we obtained by using
       g_win32_check_windows_version().  Show the actual server release
       string (i.e. Windows Server 20xx yyyy) as appropriate, as a result.
    *  Check the DisplayVersion entry in the registry under
       SOFTWARE\Microsoft\Windows NT\CurrentVersion if we obtained "2009"
       from the ReleaseId entry, since DisplayVersion replaces ReleaseId
       after Windows 10/Server 2019 20H2 (2009).  This makes things more
       clear for Windows releases after 20H2, where previously 20H2
       and 21H1 were all identified as Windows 10 [Server] 2009.
    
    This should fix issue #2443.

 glib/gutils.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 65 insertions(+), 6 deletions(-)
---
diff --git a/glib/gutils.c b/glib/gutils.c
index a6b30ae0f..21a3fa770 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -1294,18 +1294,58 @@ static gchar *
 get_windows_version (gboolean with_windows)
 {
   GString *version = g_string_new (NULL);
+  gboolean is_win_server = FALSE;
 
   if (g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_ANY))
     {
       gchar *win10_release;
+      gboolean is_win11 = FALSE;
+      OSVERSIONINFOEXW osinfo;
 
-      g_string_append (version, "10");
+      /* Are we on Windows 2016/2019/2022 Server? */
+      is_win_server = g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_SERVER);
 
-      if (!g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_WORKSTATION))
-        g_string_append (version, " Server");
+      /*
+       * This always succeeds if we get here, since the
+       * g_win32_check_windows_version() already did this!
+       * We want the OSVERSIONINFOEXW here for more even
+       * fine-grained versioning items
+       */
+      _g_win32_call_rtl_version (&osinfo);
+
+      if (!is_win_server)
+        {
+          /*
+           * Windows 11 is actually Windows 10.0.22000+,
+           * so look at the build number
+           */
+          is_win11 = (osinfo.dwBuildNumber >= 22000);
+        }
+      else
+        {
+          /*
+           * Windows 2022 Server is actually Windows 10.0.20348+,
+           * Windows 2019 Server is actually Windows 10.0.17763+,
+           * Windows 2016 Server is actually Windows 10.0.14393+,
+           * so look at the build number
+           */
+          g_string_append (version, "Server");
+          if (osinfo.dwBuildNumber >= 20348)
+            g_string_append (version, " 2022");
+          else if (osinfo.dwBuildNumber >= 17763)
+            g_string_append (version, " 2019");
+          else
+            g_string_append (version, " 2016");
+        }
 
-      /* Windows 10 is identified by its release number, such as
-       * 1511, 1607, 1703, 1709, 1803, 1809 or 1903.
+      if (is_win11)
+        g_string_append (version, "11");
+      else if (!is_win_server)
+        g_string_append (version, "10");
+
+      /* Windows 10/Server 2016+ is identified by its ReleaseId or
+       * DisplayVersion (since 20H2), such as
+       * 1511, 1607, 1703, 1709, 1803, 1809 or 1903 etc.
        * The first version of Windows 10 has no release number.
        */
       win10_release = get_registry_str (HKEY_LOCAL_MACHINE,
@@ -1316,7 +1356,26 @@ get_windows_version (gboolean with_windows)
                                         L"ReleaseId");
 
       if (win10_release != NULL)
-        g_string_append_printf (version, " %s", win10_release);
+        {
+          if (g_strcmp0 (win10_release, "2009") != 0)
+            g_string_append_printf (version, " %s", win10_release);
+          else
+            {
+              g_free (win10_release);
+
+              win10_release = get_registry_str (HKEY_LOCAL_MACHINE,
+                                                L"SOFTWARE"
+                                                L"\\Microsoft"
+                                                L"\\Windows NT"
+                                                L"\\CurrentVersion",
+                                                L"DisplayVersion");
+
+              if (win10_release != NULL)
+                g_string_append_printf (version, " %s", win10_release);
+              else
+                g_string_append_printf (version, " 2009");
+            }
+        }
 
       g_free (win10_release);
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]