[glib/improve-win32-version-2-70: 1/2] gwin32.c: Split out call to RtlGetVersion()
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/improve-win32-version-2-70: 1/2] gwin32.c: Split out call to RtlGetVersion()
- Date: Wed, 24 Nov 2021 02:46:11 +0000 (UTC)
commit 2e99a1529106624f95a63a0f303c64abeb3bcd45
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Fri Nov 19 11:50:26 2021 +0800
gwin32.c: Split out call to RtlGetVersion()
Unfortunately, we may well be likely to need to call RtlGetVersion() via
GetModuleHandle() + GetProcAddress(), so split out the call to RtlGetVersion()
into a private function of its own, so that we can reuse the same code in other
parts of GLib, so that we can:
* Determine better in a more fine-tuned way to determine whether we are on
Windows 10/11 and/or Server 2016/2019/2022, since we need to rely on the
build number.
* Just call RtlGetVersion() once, when needed, as that is all that is needed.
We could re-use the same function once to compare what we got when we
called RtlGetVersion() and do what is necessary there.
glib/glib-init.h | 1 +
glib/gwin32.c | 66 ++++++++++++++++++++++++++++++++++++--------------------
2 files changed, 44 insertions(+), 23 deletions(-)
---
diff --git a/glib/glib-init.h b/glib/glib-init.h
index c25cbb0a1..4c812d9d6 100644
--- a/glib/glib-init.h
+++ b/glib/glib-init.h
@@ -39,6 +39,7 @@ void g_console_win32_init (void);
void g_clock_win32_init (void);
void g_crash_handler_win32_init (void);
void g_crash_handler_win32_deinit (void);
+gboolean _g_win32_call_rtl_version (OSVERSIONINFOEXW *info);
extern HMODULE glib_dll;
#endif
diff --git a/glib/gwin32.c b/glib/gwin32.c
index f4590916f..04d0a89b5 100644
--- a/glib/gwin32.c
+++ b/glib/gwin32.c
@@ -491,6 +491,48 @@ G_GNUC_END_IGNORE_DEPRECATIONS
return dirname;
}
+/*
+ * private API to call Windows's RtlGetVersion(), which may need to be called
+ * via GetProcAddress()
+ */
+gboolean
+_g_win32_call_rtl_version (OSVERSIONINFOEXW *info)
+{
+ static OSVERSIONINFOEXW result;
+ static gsize inited = 0;
+
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ if (g_once_init_enter (&inited))
+ {
+#if WINAPI_FAMILY != MODERN_API_FAMILY
+ /* For non-modern UI Apps, use the LoadLibraryW()/GetProcAddress() thing */
+ typedef NTSTATUS (WINAPI fRtlGetVersion) (PRTL_OSVERSIONINFOEXW);
+
+ fRtlGetVersion *RtlGetVersion;
+ HMODULE hmodule = LoadLibraryW (L"ntdll.dll");
+ g_return_val_if_fail (hmodule != NULL, FALSE);
+
+ RtlGetVersion = (fRtlGetVersion *) GetProcAddress (hmodule, "RtlGetVersion");
+ g_return_val_if_fail (RtlGetVersion != NULL, FALSE);
+#endif
+
+ memset (&result, 0, sizeof (OSVERSIONINFOEXW));
+ result.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
+
+ RtlGetVersion (&result);
+
+#if WINAPI_FAMILY != MODERN_API_FAMILY
+ FreeLibrary (hmodule);
+#endif
+ g_once_init_leave (&inited, TRUE);
+ }
+
+ *info = result;
+
+ return TRUE;
+}
+
/**
* g_win32_check_windows_version:
* @major: major version of Windows
@@ -526,31 +568,13 @@ g_win32_check_windows_version (const gint major,
gboolean is_ver_checked = FALSE;
gboolean is_type_checked = FALSE;
-#if WINAPI_FAMILY != MODERN_API_FAMILY
- /* For non-modern UI Apps, use the LoadLibraryW()/GetProcAddress() thing */
- typedef NTSTATUS (WINAPI fRtlGetVersion) (PRTL_OSVERSIONINFOEXW);
-
- fRtlGetVersion *RtlGetVersion;
- HMODULE hmodule;
-#endif
/* We Only Support Checking for XP or later */
g_return_val_if_fail (major >= 5 && (major <=6 || major == 10), FALSE);
g_return_val_if_fail ((major >= 5 && minor >= 1) || major >= 6, FALSE);
/* Check for Service Pack Version >= 0 */
g_return_val_if_fail (spver >= 0, FALSE);
-
-#if WINAPI_FAMILY != MODERN_API_FAMILY
- hmodule = LoadLibraryW (L"ntdll.dll");
- g_return_val_if_fail (hmodule != NULL, FALSE);
-
- RtlGetVersion = (fRtlGetVersion *) GetProcAddress (hmodule, "RtlGetVersion");
- g_return_val_if_fail (RtlGetVersion != NULL, FALSE);
-#endif
-
- memset (&osverinfo, 0, sizeof (OSVERSIONINFOEXW));
- osverinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
- RtlGetVersion (&osverinfo);
+ g_return_val_if_fail (_g_win32_call_rtl_version (&osverinfo), FALSE);
/* check the OS and Service Pack Versions */
if (osverinfo.dwMajorVersion > major)
@@ -588,10 +612,6 @@ g_win32_check_windows_version (const gint major,
}
}
-#if WINAPI_FAMILY != MODERN_API_FAMILY
- FreeLibrary (hmodule);
-#endif
-
return is_ver_checked && is_type_checked;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]