2 * Unit test suite for version functions
4 * Copyright 2006 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* Needed for PRODUCT_* defines and GetProductInfo() */
22 #define _WIN32_WINNT 0x0600
26 #include "wine/test.h"
29 static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
30 static BOOL (WINAPI * pVerifyVersionInfoA)(LPOSVERSIONINFOEXA, DWORD, DWORDLONG);
31 static ULONGLONG (WINAPI * pVerSetConditionMask)(ULONGLONG, DWORD, BYTE);
33 #define KERNEL32_GET_PROC(func) \
34 p##func = (void *)GetProcAddress(hKernel32, #func);
36 static void init_function_pointers(void)
40 hKernel32 = GetModuleHandleA("kernel32.dll");
42 KERNEL32_GET_PROC(GetProductInfo);
43 KERNEL32_GET_PROC(VerifyVersionInfoA);
44 KERNEL32_GET_PROC(VerSetConditionMask);
47 #define PRODUCT2NAME(x) case x:\
50 static const char * product_to_name(DWORD product)
54 PRODUCT2NAME(PRODUCT_PROFESSIONAL)
55 PRODUCT2NAME(PRODUCT_STANDARD_SERVER)
56 PRODUCT2NAME(PRODUCT_BUSINESS)
57 PRODUCT2NAME(PRODUCT_ULTIMATE)
58 PRODUCT2NAME(PRODUCT_ULTIMATE_N)
59 PRODUCT2NAME(PRODUCT_HOME_PREMIUM)
65 static void test_GetProductInfo(void)
70 DWORD table[] = {9,8,7,6,
92 /* Not present before Vista */
93 win_skip("GetProductInfo() not available\n");
97 memset(&os, 0, sizeof(OSVERSIONINFOEXA));
98 os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
99 res = GetVersionExA((OSVERSIONINFOA *)&os);
100 ok(res, "got %d (expected TRUE)\n", res);
102 trace("%s %u.%u (SP: %u.%u)\n", os.wProductType == VER_NT_WORKSTATION ? "Workstation" : "Server",
103 os.dwMajorVersion, os.dwMinorVersion, os.wServicePackMajor, os.wServicePackMinor);
107 /* SetLastError() / GetLastError(): value is untouched */
108 product = 0xdeadbeef;
109 SetLastError(0xdeadbeef);
110 res = pGetProductInfo(entry[0], entry[1], entry[2], entry[3], &product);
111 trace("%d.%d / %d.%d: got %d and 0x%x %s\n",
112 entry[0], entry[1], entry[2], entry[3], res, product, product_to_name(product));
115 ok(res && (product > PRODUCT_UNDEFINED) && (product <= PRODUCT_EMBEDDED) && (GetLastError() == 0xdeadbeef),
116 "got %d and 0x%x with 0x%x (expected TRUE and a valid PRODUCT_* value with LastError untouched)\n",
117 res, product, GetLastError());
119 ok(!res && !product && (GetLastError() == 0xdeadbeef),
120 "got %d and 0x%x with 0x%x (expected FALSE and PRODUCT_UNDEFINED with LastError untouched)\n",
121 res, product, GetLastError());
126 /* NULL pointer is not a problem */
127 SetLastError(0xdeadbeef);
128 res = pGetProductInfo(6, 1, 0, 0, NULL);
129 ok( (!res) && (GetLastError() == 0xdeadbeef),
130 "got %d with 0x%x (expected FALSE with LastError untouched\n", res, GetLastError());
133 static void test_GetVersionEx(void)
135 OSVERSIONINFOA infoA;
136 OSVERSIONINFOEXA infoExA;
141 /* Silently crashes on XP */
145 SetLastError(0xdeadbeef);
146 memset(&infoA,0,sizeof infoA);
147 ret = GetVersionExA(&infoA);
148 ok(!ret, "Expected GetVersionExA to fail\n");
149 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
150 GetLastError() == 0xdeadbeef /* Win9x */,
151 "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
154 SetLastError(0xdeadbeef);
155 infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA) / 2;
156 ret = GetVersionExA(&infoA);
157 ok(!ret, "Expected GetVersionExA to fail\n");
158 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
159 GetLastError() == 0xdeadbeef /* Win9x */,
160 "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
163 SetLastError(0xdeadbeef);
164 infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA) * 2;
165 ret = GetVersionExA(&infoA);
166 ok(!ret, "Expected GetVersionExA to fail\n");
167 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
168 GetLastError() == 0xdeadbeef /* Win9x */,
169 "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
172 SetLastError(0xdeadbeef);
173 infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
174 ret = GetVersionExA(&infoA);
175 ok(ret, "Expected GetVersionExA to succeed\n");
176 ok(GetLastError() == 0xdeadbeef,
177 "Expected 0xdeadbeef, got %d\n", GetLastError());
179 SetLastError(0xdeadbeef);
180 infoExA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
181 ret = GetVersionExA((OSVERSIONINFOA *)&infoExA);
183 broken(ret == 0), /* win95 */
184 "Expected GetVersionExA to succeed\n");
185 ok(GetLastError() == 0xdeadbeef,
186 "Expected 0xdeadbeef, got %d\n", GetLastError());
189 static void test_VerifyVersionInfo(void)
191 OSVERSIONINFOEX info;
193 DWORD servicepack, error;
195 if(!pVerifyVersionInfoA || !pVerSetConditionMask)
197 win_skip("Needed functions not available\n");
201 /* Before we start doing some tests we should check what the version of
202 * the ServicePack is. Tests on a box with no ServicePack will fail otherwise.
204 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
205 GetVersionExA((OSVERSIONINFO *)&info);
206 servicepack = info.wServicePackMajor;
207 memset(&info, 0, sizeof(info));
209 ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION,
210 pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
211 ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
213 SetLastError(0xdeadbeef);
214 ret = pVerifyVersionInfoA(&info, VER_BUILDNUMBER | VER_MAJORVERSION |
215 VER_MINORVERSION/* | VER_PLATFORMID | VER_SERVICEPACKMAJOR |
216 VER_SERVICEPACKMINOR | VER_SUITENAME | VER_PRODUCT_TYPE */,
217 pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
218 error = GetLastError();
219 ok(!ret, "VerifyVersionInfoA succeeded\n");
220 ok(error == ERROR_OLD_WIN_VERSION,
221 "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
223 /* tests special handling of VER_SUITENAME */
225 ret = pVerifyVersionInfoA(&info, VER_SUITENAME,
226 pVerSetConditionMask(0, VER_SUITENAME, VER_AND));
227 ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
229 ret = pVerifyVersionInfoA(&info, VER_SUITENAME,
230 pVerSetConditionMask(0, VER_SUITENAME, VER_OR));
231 ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
233 /* test handling of version numbers */
235 /* v3.10 is always less than v4.x even
236 * if the minor version is tested */
237 info.dwMajorVersion = 3;
238 info.dwMinorVersion = 10;
239 ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
240 pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
241 VER_MAJORVERSION, VER_GREATER_EQUAL));
242 ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
244 info.dwMinorVersion = 0;
245 info.wServicePackMajor = 10;
246 ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
247 pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
248 VER_MAJORVERSION, VER_GREATER_EQUAL));
249 ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
251 info.wServicePackMajor = 0;
252 info.wServicePackMinor = 10;
253 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
254 pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
255 VER_MAJORVERSION, VER_GREATER_EQUAL));
256 ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
258 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
259 GetVersionEx((OSVERSIONINFO *)&info);
260 info.wServicePackMinor++;
261 SetLastError(0xdeadbeef);
262 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
263 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
264 error = GetLastError();
265 ok(!ret, "VerifyVersionInfoA succeeded\n");
266 ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some wink2 */,
267 "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
269 if (servicepack == 0)
271 skip("There is no ServicePack on this system\n");
275 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
276 GetVersionEx((OSVERSIONINFO *)&info);
277 info.wServicePackMajor--;
278 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
279 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER));
280 ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
282 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
283 GetVersionEx((OSVERSIONINFO *)&info);
284 info.wServicePackMajor--;
285 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
286 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
287 ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
290 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
291 GetVersionEx((OSVERSIONINFO *)&info);
292 info.wServicePackMajor++;
293 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
294 pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS));
295 ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
297 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
298 GetVersionEx((OSVERSIONINFO *)&info);
299 info.wServicePackMajor++;
300 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
301 pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS_EQUAL));
302 ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
304 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
305 GetVersionEx((OSVERSIONINFO *)&info);
306 info.wServicePackMajor--;
307 SetLastError(0xdeadbeef);
308 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
309 pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL));
310 error = GetLastError();
311 ok(!ret, "VerifyVersionInfoA succeeded\n");
312 ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
313 "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
315 /* test the failure hierarchy for the four version fields */
317 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
318 GetVersionEx((OSVERSIONINFO *)&info);
319 info.wServicePackMajor++;
320 SetLastError(0xdeadbeef);
321 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
322 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
323 error = GetLastError();
324 ok(!ret, "VerifyVersionInfoA succeeded\n");
325 ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
326 "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
328 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
329 GetVersionEx((OSVERSIONINFO *)&info);
330 info.dwMinorVersion++;
331 SetLastError(0xdeadbeef);
332 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
333 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
334 error = GetLastError();
335 ok(!ret, "VerifyVersionInfoA succeeded\n");
336 ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
337 "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
339 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
340 GetVersionEx((OSVERSIONINFO *)&info);
341 info.dwMajorVersion++;
342 SetLastError(0xdeadbeef);
343 ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
344 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
345 error = GetLastError();
346 ok(!ret, "VerifyVersionInfoA succeeded\n");
347 ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
348 "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
350 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
351 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
352 ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
354 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
355 GetVersionEx((OSVERSIONINFO *)&info);
356 info.dwBuildNumber++;
357 SetLastError(0xdeadbeef);
358 ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
359 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
360 error = GetLastError();
361 ok(!ret, "VerifyVersionInfoA succeeded\n");
362 ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
363 "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
365 ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
366 pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
367 ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
369 /* test bad dwOSVersionInfoSize */
370 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
371 GetVersionEx((OSVERSIONINFO *)&info);
372 info.dwOSVersionInfoSize = 0;
373 ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
374 pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
375 ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
380 init_function_pointers();
382 test_GetProductInfo();
384 test_VerifyVersionInfo();