summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2021-10-04 15:52:01 -0400
committerJay Satiro <raysatiro@yahoo.com>2021-10-07 03:18:22 -0400
commit5044909ca251d3d190d8c5cc45243a04d244eaed (patch)
tree588ef740cc8098320ca65944f1a8b63ca4dac988
parenta031614a8470bc7ef269e98c1a6a38b0b822ff24 (diff)
downloadcurl-5044909ca251d3d190d8c5cc45243a04d244eaed.tar.gz
version_win32: use actual version instead of manifested version
- Use RtlVerifyVersionInfo instead of VerifyVersionInfo, when possible. Later versions of Windows have normal version functions that compare and return versions based on the way the application is manifested, instead of the actual version of Windows the application is running on. We prefer the actual version of Windows so we'll now call the Rtl variant of version functions (RtlVerifyVersionInfo) which does a proper comparison of the actual version. Reported-by: Wyatt O'Day Ref: https://github.com/curl/curl/pull/7727 Fixes https://github.com/curl/curl/issues/7742 Closes https://github.com/curl/curl/pull/7810
-rw-r--r--lib/system_win32.c2
-rw-r--r--lib/version_win32.c51
-rw-r--r--src/tool_doswin.c2
3 files changed, 50 insertions, 5 deletions
diff --git a/lib/system_win32.c b/lib/system_win32.c
index 2939fd0d7..d4e194831 100644
--- a/lib/system_win32.c
+++ b/lib/system_win32.c
@@ -102,6 +102,8 @@ CURLcode Curl_win32_init(long flags)
Curl_if_nametoindex = pIfNameToIndex;
}
+ /* curlx_verify_windows_version must be called during init at least once
+ because it has its own initialization routine. */
if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
Curl_isVistaOrGreater = TRUE;
diff --git a/lib/version_win32.c b/lib/version_win32.c
index b8157e989..9df921fd6 100644
--- a/lib/version_win32.c
+++ b/lib/version_win32.c
@@ -26,11 +26,28 @@
#include <curl/curl.h>
#include "version_win32.h"
+#include "warnless.h"
/* The last #include files should be: */
#include "curl_memory.h"
#include "memdebug.h"
+/* This Unicode version struct works for VerifyVersionInfoW (OSVERSIONINFOEXW)
+ and RtlVerifyVersionInfo (RTLOSVERSIONINFOEXW) */
+struct OUR_OSVERSIONINFOEXW {
+ ULONG dwOSVersionInfoSize;
+ ULONG dwMajorVersion;
+ ULONG dwMinorVersion;
+ ULONG dwBuildNumber;
+ ULONG dwPlatformId;
+ WCHAR szCSDVersion[128];
+ USHORT wServicePackMajor;
+ USHORT wServicePackMinor;
+ USHORT wSuiteMask;
+ UCHAR wProductType;
+ UCHAR wReserved;
+};
+
/*
* curlx_verify_windows_version()
*
@@ -152,12 +169,23 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
}
#else
ULONGLONG cm = 0;
- OSVERSIONINFOEX osver;
+ struct OUR_OSVERSIONINFOEXW osver;
BYTE majorCondition;
BYTE minorCondition;
BYTE spMajorCondition;
BYTE spMinorCondition;
+ typedef LONG (APIENTRY *RTLVERIFYVERSIONINFO_FN)
+ (struct OUR_OSVERSIONINFOEXW *, ULONG, ULONGLONG);
+ static RTLVERIFYVERSIONINFO_FN pRtlVerifyVersionInfo;
+ static bool onetime = true; /* safe because first call is during init */
+
+ if(onetime) {
+ pRtlVerifyVersionInfo = CURLX_FUNCTION_CAST(RTLVERIFYVERSIONINFO_FN,
+ (GetProcAddress(GetModuleHandleA("ntdll"), "RtlVerifyVersionInfo")));
+ onetime = false;
+ }
+
switch(condition) {
case VERSION_LESS_THAN:
majorCondition = VER_LESS;
@@ -214,10 +242,23 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
if(platform != PLATFORM_DONT_CARE)
cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
- if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
- VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
- cm))
- matched = TRUE;
+ /* Later versions of Windows have version functions that may not return the
+ real version of Windows unless the application is so manifested. We prefer
+ the real version always, so we use the Rtl variant of the function when
+ possible. Note though the function signatures have underlying fundamental
+ types that are the same, the return values are different. */
+ if(pRtlVerifyVersionInfo) {
+ matched = !pRtlVerifyVersionInfo(&osver,
+ (VER_MAJORVERSION | VER_MINORVERSION |
+ VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
+ cm);
+ }
+ else {
+ matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
+ (VER_MAJORVERSION | VER_MINORVERSION |
+ VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
+ cm);
+ }
#endif
return matched;
diff --git a/src/tool_doswin.c b/src/tool_doswin.c
index 98e13bc09..1ad9cddc3 100644
--- a/src/tool_doswin.c
+++ b/src/tool_doswin.c
@@ -766,6 +766,8 @@ bool tool_isVistaOrGreater;
CURLcode win32_init(void)
{
+ /* curlx_verify_windows_version must be called during init at least once
+ because it has its own initialization routine. */
if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL))
tool_isVistaOrGreater = true;