@@ -84,6 +84,9 @@ mongoc_check_version(int required_major, int required_minor, int required_micro)
84
84
}
85
85
86
86
#ifdef _WIN32
87
+
88
+ typedef NTSTATUS (APIENTRY * RTLVERIFYVERSIONINFO_FN ) (PRTL_OSVERSIONINFOEXW VersionInfo , ULONG TypeMask , ULONGLONG ConditionMask );
89
+
87
90
/**
88
91
* _mongoc_verify_windows_version:
89
92
*
@@ -93,37 +96,56 @@ mongoc_check_version(int required_major, int required_minor, int required_micro)
93
96
bool
94
97
_mongoc_verify_windows_version (int major_version , int minor_version , int build_number , bool strictly_equal )
95
98
{
96
- OSVERSIONINFOEX osvi ;
99
+ static RTLVERIFYVERSIONINFO_FN pRtlVerifyVersionInfo ;
100
+ OSVERSIONINFOEXW osvi ;
97
101
bool matched ;
98
102
int op = VER_GREATER_EQUAL ;
99
103
100
104
if (strictly_equal ) {
101
105
op = VER_EQUAL ;
102
106
}
103
107
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 );
106
118
osvi .dwMajorVersion = major_version ;
107
119
osvi .dwMinorVersion = minor_version ;
108
120
109
121
ULONGLONG mask = 0 ;
110
122
VER_SET_CONDITION (mask , VER_MAJORVERSION , op );
111
123
VER_SET_CONDITION (mask , VER_MINORVERSION , op );
112
124
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
+ }
114
130
115
131
// Compare build number separately if major and minor versions are equal
116
132
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 );
119
135
osvi .dwBuildNumber = build_number ;
120
136
121
137
mask = 0 ;
122
138
VER_SET_CONDITION (mask , VER_BUILDNUMBER , op );
123
139
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
+ }
125
146
}
126
147
127
148
return matched ;
128
149
}
150
+
129
151
#endif
0 commit comments