@@ -4846,7 +4846,7 @@
show_windows_version(const unsigned int flags)
{
struct gc_arena gc = gc_new();
- msg(flags, "Windows version %s", win32_version_string(&gc, true));
+ msg(flags, "Windows version: %s", win32_version_string(&gc));
gc_free(&gc);
}
#endif
@@ -2060,7 +2060,7 @@
}
buf_printf(&out, "IV_SSL=%s\n", get_ssl_library_version() );
#if defined(_WIN32)
- buf_printf(&out, "IV_PLAT_VER=%s\n", win32_version_string(&gc, false));
+ buf_printf(&out, "IV_PLAT_VER=%s\n", win32_version_string(&gc));
#else
struct utsname u;
uname(&u);
@@ -5428,11 +5428,8 @@
NETSH_PATH_SUFFIX, adapter_index,
print_in6_addr(addr_list[i], 0, &gc));
- /* disable slow address validation on Windows 7 and higher */
- if (win32_version_info() >= WIN_7)
- {
- argv_printf_cat(&argv, "%s", "validate=no");
- }
+ /* disable slow address validation */
+ argv_printf_cat(&argv, "%s", "validate=no");
/* Treat errors while adding as non-fatal as we do not check for duplicates */
netsh_command(&argv, 1, (i==0) ? M_FATAL : M_NONFATAL);
@@ -5498,9 +5495,8 @@
adapter_index,
print_in_addr_t(addr_list[i], 0, &gc));
- /* disable slow address validation on Windows 7 and higher */
- /* only for DNS */
- if (is_dns && win32_version_info() >= WIN_7)
+ /* disable slow address validation for DNS */
+ if (is_dns)
{
argv_printf_cat(&argv, "%s", "validate=no");
}
@@ -1283,42 +1283,6 @@
return true;
}
-int
-win32_version_info(void)
-{
- if (!IsWindowsXPOrGreater())
- {
- msg(M_FATAL, "Error: Windows version must be XP or greater.");
- }
-
- if (!IsWindowsVistaOrGreater())
- {
- return WIN_XP;
- }
-
- if (!IsWindows7OrGreater())
- {
- return WIN_VISTA;
- }
-
- if (!IsWindows8OrGreater())
- {
- return WIN_7;
- }
-
- if (!IsWindows8Point1OrGreater())
- {
- return WIN_8;
- }
-
- if (!IsWindows10OrGreater())
- {
- return WIN_8_1;
- }
-
- return WIN_10;
-}
-
typedef enum {
ARCH_X86,
ARCH_AMD64,
@@ -1420,52 +1384,40 @@
}
}
+typedef LONG (WINAPI *RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
+
const char *
-win32_version_string(struct gc_arena *gc, bool add_name)
+win32_version_string(struct gc_arena *gc)
{
- int version = win32_version_info();
- struct buffer out = alloc_buf_gc(256, gc);
-
- switch (version)
+ HMODULE hMod = GetModuleHandleW(L"ntdll.dll");
+ if (!hMod)
{
- case WIN_XP:
- buf_printf(&out, "5.1%s", add_name ? " (Windows XP)" : "");
- break;
-
- case WIN_VISTA:
- buf_printf(&out, "6.0%s", add_name ? " (Windows Vista)" : "");
- break;
-
- case WIN_7:
- buf_printf(&out, "6.1%s", add_name ? " (Windows 7)" : "");
- break;
-
- case WIN_8:
- buf_printf(&out, "6.2%s", add_name ? " (Windows 8)" : "");
- break;
-
- case WIN_8_1:
- buf_printf(&out, "6.3%s", add_name ? " (Windows 8.1)" : "");
- break;
-
- case WIN_10:
- buf_printf(&out, "10.0%s", add_name ? " (Windows 10 or greater)" : "");
- break;
-
- default:
- msg(M_NONFATAL, "Unknown Windows version: %d", version);
- buf_printf(&out, "0.0%s", add_name ? " (unknown)" : "");
- break;
+ return "N/A";
}
- buf_printf(&out, ", ");
+ RtlGetVersionPtr fn = (RtlGetVersionPtr)GetProcAddress(hMod, "RtlGetVersion");
+ if (!fn)
+ {
+ return "N/A";
+ }
+
+ RTL_OSVERSIONINFOW rovi = { 0 };
+ rovi.dwOSVersionInfoSize = sizeof(rovi);
+ if (fn(&rovi) != 0)
+ {
+ return "N/A";
+ }
+
+ struct buffer out = alloc_buf_gc(256, gc);
+
+ buf_printf(&out, "%lu.%lu.%lu", rovi.dwMajorVersion, rovi.dwMinorVersion, rovi.dwBuildNumber);
+
+ buf_printf(&out, ",");
arch_t process_arch, host_arch;
win32_get_arch(&process_arch, &host_arch);
win32_print_arch(process_arch, &out);
- buf_printf(&out, " executable");
-
if (host_arch != ARCH_NATIVE)
{
buf_printf(&out, " running on ");
@@ -292,20 +292,13 @@
bool win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel);
-#define WIN_XP 0
-#define WIN_VISTA 1
-#define WIN_7 2
-#define WIN_8 3
-#define WIN_8_1 4
-#define WIN_10 5
-
-int win32_version_info(void);
-
-/*
- * String representation of Windows version number and name, see
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx
+/**
+ * @brief Get Windows version string with architecture info.
+ *
+ * @param gc gc arena to allocate string.
+ * @return Version string, or "N/A" on failure.
*/
-const char *win32_version_string(struct gc_arena *gc, bool add_name);
+const char *win32_version_string(struct gc_arena *gc);
/*
* Send the |size| bytes in buffer |data| to the interactive service |pipe|