VirtualBox

source: vbox/trunk/src/libs/curl-7.83.1/lib/version_win32.c@ 97138

最後變更 在這個檔案從97138是 95312,由 vboxsync 提交於 3 年 前

libs/{curl,libxml2}: OSE export fixes, bugref:8515

  • 屬性 svn:eol-style 設為 native
檔案大小: 10.3 KB
 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2016 - 2022, Steve Holme, <[email protected]>.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23#include "curl_setup.h"
24
25#if defined(WIN32)
26
27#include <curl/curl.h>
28#include "version_win32.h"
29#include "warnless.h"
30
31/* The last #include files should be: */
32#include "curl_memory.h"
33#include "memdebug.h"
34
35/* This Unicode version struct works for VerifyVersionInfoW (OSVERSIONINFOEXW)
36 and RtlVerifyVersionInfo (RTLOSVERSIONINFOEXW) */
37struct OUR_OSVERSIONINFOEXW {
38 ULONG dwOSVersionInfoSize;
39 ULONG dwMajorVersion;
40 ULONG dwMinorVersion;
41 ULONG dwBuildNumber;
42 ULONG dwPlatformId;
43 WCHAR szCSDVersion[128];
44 USHORT wServicePackMajor;
45 USHORT wServicePackMinor;
46 USHORT wSuiteMask;
47 UCHAR wProductType;
48 UCHAR wReserved;
49};
50
51/*
52 * curlx_verify_windows_version()
53 *
54 * This is used to verify if we are running on a specific windows version.
55 *
56 * Parameters:
57 *
58 * majorVersion [in] - The major version number.
59 * minorVersion [in] - The minor version number.
60 * buildVersion [in] - The build version number. If 0, this parameter is
61 * ignored.
62 * platform [in] - The optional platform identifier.
63 * condition [in] - The test condition used to specifier whether we are
64 * checking a version less then, equal to or greater than
65 * what is specified in the major and minor version
66 * numbers.
67 *
68 * Returns TRUE if matched; otherwise FALSE.
69 */
70bool curlx_verify_windows_version(const unsigned int majorVersion,
71 const unsigned int minorVersion,
72 const unsigned int buildVersion,
73 const PlatformIdentifier platform,
74 const VersionCondition condition)
75{
76 bool matched = FALSE;
77
78#if defined(CURL_WINDOWS_APP)
79 (void)buildVersion;
80
81 /* We have no way to determine the Windows version from Windows apps,
82 so let's assume we're running on the target Windows version. */
83 const WORD fullVersion = MAKEWORD(minorVersion, majorVersion);
84 const WORD targetVersion = (WORD)_WIN32_WINNT;
85
86 switch(condition) {
87 case VERSION_LESS_THAN:
88 matched = targetVersion < fullVersion;
89 break;
90
91 case VERSION_LESS_THAN_EQUAL:
92 matched = targetVersion <= fullVersion;
93 break;
94
95 case VERSION_EQUAL:
96 matched = targetVersion == fullVersion;
97 break;
98
99 case VERSION_GREATER_THAN_EQUAL:
100 matched = targetVersion >= fullVersion;
101 break;
102
103 case VERSION_GREATER_THAN:
104 matched = targetVersion > fullVersion;
105 break;
106 }
107
108 if(matched && (platform == PLATFORM_WINDOWS)) {
109 /* we're always running on PLATFORM_WINNT */
110 matched = FALSE;
111 }
112#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
113 (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
114 OSVERSIONINFO osver;
115
116 memset(&osver, 0, sizeof(osver));
117 osver.dwOSVersionInfoSize = sizeof(osver);
118
119 /* Find out Windows version */
120 if(GetVersionEx(&osver)) {
121 /* Verify the Operating System version number */
122 switch(condition) {
123 case VERSION_LESS_THAN:
124 if(osver.dwMajorVersion < majorVersion ||
125 (osver.dwMajorVersion == majorVersion &&
126 osver.dwMinorVersion < minorVersion) ||
127 (buildVersion != 0 &&
128 (osver.dwMajorVersion == majorVersion &&
129 osver.dwMinorVersion == minorVersion &&
130 osver.dwBuildNumber < buildVersion)))
131 matched = TRUE;
132 break;
133
134 case VERSION_LESS_THAN_EQUAL:
135 if(osver.dwMajorVersion < majorVersion ||
136 (osver.dwMajorVersion == majorVersion &&
137 osver.dwMinorVersion < minorVersion) ||
138 (osver.dwMajorVersion == majorVersion &&
139 osver.dwMinorVersion == minorVersion &&
140 (buildVersion == 0 ||
141 osver.dwBuildNumber <= buildVersion)))
142 matched = TRUE;
143 break;
144
145 case VERSION_EQUAL:
146 if(osver.dwMajorVersion == majorVersion &&
147 osver.dwMinorVersion == minorVersion &&
148 (buildVersion == 0 ||
149 osver.dwBuildNumber == buildVersion))
150 matched = TRUE;
151 break;
152
153 case VERSION_GREATER_THAN_EQUAL:
154 if(osver.dwMajorVersion > majorVersion ||
155 (osver.dwMajorVersion == majorVersion &&
156 osver.dwMinorVersion > minorVersion) ||
157 (osver.dwMajorVersion == majorVersion &&
158 osver.dwMinorVersion == minorVersion &&
159 (buildVersion == 0 ||
160 osver.dwBuildNumber >= buildVersion)))
161 matched = TRUE;
162 break;
163
164 case VERSION_GREATER_THAN:
165 if(osver.dwMajorVersion > majorVersion ||
166 (osver.dwMajorVersion == majorVersion &&
167 osver.dwMinorVersion > minorVersion) ||
168 (buildVersion != 0 &&
169 (osver.dwMajorVersion == majorVersion &&
170 osver.dwMinorVersion == minorVersion &&
171 osver.dwBuildNumber > buildVersion)))
172 matched = TRUE;
173 break;
174 }
175
176 /* Verify the platform identifier (if necessary) */
177 if(matched) {
178 switch(platform) {
179 case PLATFORM_WINDOWS:
180 if(osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
181 matched = FALSE;
182 break;
183
184 case PLATFORM_WINNT:
185 if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
186 matched = FALSE;
187 break;
188
189 default: /* like platform == PLATFORM_DONT_CARE */
190 break;
191 }
192 }
193 }
194#else
195 ULONGLONG cm = 0;
196 struct OUR_OSVERSIONINFOEXW osver;
197 BYTE majorCondition;
198 BYTE minorCondition;
199 BYTE buildCondition;
200 BYTE spMajorCondition;
201 BYTE spMinorCondition;
202 DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION |
203 VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
204
205 typedef LONG (APIENTRY *RTLVERIFYVERSIONINFO_FN)
206 (struct OUR_OSVERSIONINFOEXW *, ULONG, ULONGLONG);
207 static RTLVERIFYVERSIONINFO_FN pRtlVerifyVersionInfo;
208 static bool onetime = true; /* safe because first call is during init */
209
210 if(onetime) {
211 pRtlVerifyVersionInfo = CURLX_FUNCTION_CAST(RTLVERIFYVERSIONINFO_FN,
212 (GetProcAddress(GetModuleHandleA("ntdll"), "RtlVerifyVersionInfo")));
213 onetime = false;
214 }
215
216 switch(condition) {
217 case VERSION_LESS_THAN:
218 majorCondition = VER_LESS;
219 minorCondition = VER_LESS;
220 buildCondition = VER_LESS;
221 spMajorCondition = VER_LESS_EQUAL;
222 spMinorCondition = VER_LESS_EQUAL;
223 break;
224
225 case VERSION_LESS_THAN_EQUAL:
226 majorCondition = VER_LESS_EQUAL;
227 minorCondition = VER_LESS_EQUAL;
228 buildCondition = VER_LESS_EQUAL;
229 spMajorCondition = VER_LESS_EQUAL;
230 spMinorCondition = VER_LESS_EQUAL;
231 break;
232
233 case VERSION_EQUAL:
234 majorCondition = VER_EQUAL;
235 minorCondition = VER_EQUAL;
236 buildCondition = VER_EQUAL;
237 spMajorCondition = VER_GREATER_EQUAL;
238 spMinorCondition = VER_GREATER_EQUAL;
239 break;
240
241 case VERSION_GREATER_THAN_EQUAL:
242 majorCondition = VER_GREATER_EQUAL;
243 minorCondition = VER_GREATER_EQUAL;
244 buildCondition = VER_GREATER_EQUAL;
245 spMajorCondition = VER_GREATER_EQUAL;
246 spMinorCondition = VER_GREATER_EQUAL;
247 break;
248
249 case VERSION_GREATER_THAN:
250 majorCondition = VER_GREATER;
251 minorCondition = VER_GREATER;
252 buildCondition = VER_GREATER;
253 spMajorCondition = VER_GREATER_EQUAL;
254 spMinorCondition = VER_GREATER_EQUAL;
255 break;
256
257 default:
258 return FALSE;
259 }
260
261 memset(&osver, 0, sizeof(osver));
262 osver.dwOSVersionInfoSize = sizeof(osver);
263 osver.dwMajorVersion = majorVersion;
264 osver.dwMinorVersion = minorVersion;
265 osver.dwBuildNumber = buildVersion;
266 if(platform == PLATFORM_WINDOWS)
267 osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
268 else if(platform == PLATFORM_WINNT)
269 osver.dwPlatformId = VER_PLATFORM_WIN32_NT;
270
271 cm = VerSetConditionMask(cm, VER_MAJORVERSION, majorCondition);
272 cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition);
273 cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition);
274 cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition);
275
276 if(platform != PLATFORM_DONT_CARE) {
277 cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
278 dwTypeMask |= VER_PLATFORMID;
279 }
280
281 /* Later versions of Windows have version functions that may not return the
282 real version of Windows unless the application is so manifested. We prefer
283 the real version always, so we use the Rtl variant of the function when
284 possible. Note though the function signatures have underlying fundamental
285 types that are the same, the return values are different. */
286 if(pRtlVerifyVersionInfo)
287 matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
288 else
289 matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver, dwTypeMask, cm);
290
291 /* Compare the build number separately. VerifyVersionInfo normally compares
292 major.minor in hierarchical order (eg 1.9 is less than 2.0) but does not
293 do the same for build (eg 1.9 build 222 is not less than 2.0 build 111).
294 Build comparison is only needed when build numbers are equal (eg 1.9 is
295 always less than 2.0 so build comparison is not needed). */
296 if(matched && buildVersion &&
297 (condition == VERSION_EQUAL ||
298 ((condition == VERSION_GREATER_THAN_EQUAL ||
299 condition == VERSION_LESS_THAN_EQUAL) &&
300 curlx_verify_windows_version(majorVersion, minorVersion, 0,
301 platform, VERSION_EQUAL)))) {
302
303 cm = VerSetConditionMask(0, VER_BUILDNUMBER, buildCondition);
304 dwTypeMask = VER_BUILDNUMBER;
305 if(pRtlVerifyVersionInfo)
306 matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
307 else
308 matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
309 dwTypeMask, cm);
310 }
311
312#endif
313
314 return matched;
315}
316
317#endif /* WIN32 */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette