Skip to content

Commit 1e90324

Browse files
committed
More accurate version checking using Rtl variant
1 parent 475f08a commit 1e90324

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

src/libmongoc/src/mongoc/mongoc-version-functions.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ mongoc_check_version(int required_major, int required_minor, int required_micro)
8484
}
8585

8686
#ifdef _WIN32
87+
88+
typedef NTSTATUS (APIENTRY *RTLVERIFYVERSIONINFO_FN) (PRTL_OSVERSIONINFOEXW VersionInfo, ULONG TypeMask, ULONGLONG ConditionMask);
89+
8790
/**
8891
* _mongoc_verify_windows_version:
8992
*
@@ -93,37 +96,56 @@ mongoc_check_version(int required_major, int required_minor, int required_micro)
9396
bool
9497
_mongoc_verify_windows_version(int major_version, int minor_version, int build_number, bool strictly_equal)
9598
{
96-
OSVERSIONINFOEX osvi;
99+
static RTLVERIFYVERSIONINFO_FN pRtlVerifyVersionInfo;
100+
OSVERSIONINFOEXW osvi;
97101
bool matched;
98102
int op = VER_GREATER_EQUAL;
99103

100104
if (strictly_equal) {
101105
op = VER_EQUAL;
102106
}
103107

104-
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
105-
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
108+
/* Windows version functions may not return the correct version for
109+
later Windows versions unless the application is so manifested. Try
110+
to use the more accurate kernel function RtlVerifyVersionInfo */
111+
HMODULE hDll = LoadLibrary(TEXT("Ntdll.dll"));
112+
if (hDll) {
113+
pRtlVerifyVersionInfo = (RTLVERIFYVERSIONINFO_FN)GetProcAddress(hDll, "RtlVerifyVersionInfo");
114+
}
115+
116+
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXW));
117+
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
106118
osvi.dwMajorVersion = major_version;
107119
osvi.dwMinorVersion = minor_version;
108120

109121
ULONGLONG mask = 0;
110122
VER_SET_CONDITION(mask, VER_MAJORVERSION, op);
111123
VER_SET_CONDITION(mask, VER_MINORVERSION, op);
112124

113-
matched = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, mask);
125+
if (pRtlVerifyVersionInfo) {
126+
matched = (pRtlVerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, mask) == 0);
127+
} else {
128+
matched = (VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, mask) != 0);
129+
}
114130

115131
// Compare build number separately if major and minor versions are equal
116132
if (build_number && matched && _mongoc_verify_windows_version(major_version, minor_version, 0, true)) {
117-
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
118-
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
133+
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXW));
134+
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
119135
osvi.dwBuildNumber = build_number;
120136

121137
mask = 0;
122138
VER_SET_CONDITION(mask, VER_BUILDNUMBER, op);
123139

124-
matched = VerifyVersionInfo(&osvi, VER_BUILDNUMBER, mask);
140+
if (pRtlVerifyVersionInfo) {
141+
matched = (pRtlVerifyVersionInfo(&osvi, VER_BUILDNUMBER, mask) == 0);
142+
}
143+
else {
144+
matched = (VerifyVersionInfoW(&osvi, VER_BUILDNUMBER, mask) != 0);
145+
}
125146
}
126147

127148
return matched;
128149
}
150+
129151
#endif

0 commit comments

Comments
 (0)