1 /*
2  * Unit test suite for version functions
3  *
4  * Copyright 2006 Robert Shearman
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include "wine/test.h"
22 #include "winbase.h"
23 #include "winternl.h"
24 
25 static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
26 static NTSTATUS (WINAPI * pRtlGetVersion)(RTL_OSVERSIONINFOEXW *);
27 
28 #define GET_PROC(func)                                     \
29     p##func = (void *)GetProcAddress(hmod, #func);
30 
init_function_pointers(void)31 static void init_function_pointers(void)
32 {
33     HMODULE hmod;
34 
35     hmod = GetModuleHandleA("kernel32.dll");
36 
37     GET_PROC(GetProductInfo);
38 
39     hmod = GetModuleHandleA("ntdll.dll");
40 
41     GET_PROC(RtlGetVersion);
42 }
43 
test_GetProductInfo(void)44 static void test_GetProductInfo(void)
45 {
46     DWORD product;
47     DWORD res;
48     DWORD table[] = {9,8,7,6,
49                      7,0,0,0,
50                      6,2,0,0,
51                      6,1,2,0,
52                      6,1,1,0,
53                      6,1,0,2,
54                      6,1,0,0,
55                      6,0,3,0,
56                      6,0,2,0,
57                      6,0,1,5,
58                      6,0,1,0,
59                      6,0,0,0,
60                      5,3,0,0,
61                      5,2,0,0,
62                      5,1,0,0,
63                      5,0,0,0,
64                      0};
65 
66     DWORD *entry = table;
67 
68     if (!pGetProductInfo)
69     {
70         /* Not present before Vista */
71         win_skip("GetProductInfo() not available\n");
72         return;
73     }
74 
75     while (*entry)
76     {
77         /* SetLastError() / GetLastError(): value is untouched */
78         product = 0xdeadbeef;
79         SetLastError(0xdeadbeef);
80         res = pGetProductInfo(entry[0], entry[1], entry[2], entry[3], &product);
81 
82         if (entry[0] >= 6)
83             ok(res && (product > PRODUCT_UNDEFINED) && (product <= PRODUCT_ENTERPRISE_S_N_EVALUATION),
84                "got %d and 0x%x (expected TRUE and a valid PRODUCT_* value)\n", res, product);
85         else
86             ok(!res && !product && (GetLastError() == 0xdeadbeef),
87                "got %d and 0x%x with 0x%x (expected FALSE and PRODUCT_UNDEFINED with LastError untouched)\n",
88                res, product, GetLastError());
89 
90         entry+= 4;
91     }
92 
93     /* NULL pointer is not a problem */
94     SetLastError(0xdeadbeef);
95     res = pGetProductInfo(6, 1, 0, 0, NULL);
96     ok( (!res) && (GetLastError() == 0xdeadbeef),
97         "got %d with 0x%x (expected FALSE with LastError untouched\n", res, GetLastError());
98 }
99 
test_GetVersionEx(void)100 static void test_GetVersionEx(void)
101 {
102     OSVERSIONINFOA infoA;
103     OSVERSIONINFOEXA infoExA;
104     BOOL ret;
105 
106     if (0)
107     {
108         /* Silently crashes on XP */
109         GetVersionExA(NULL);
110     }
111 
112     SetLastError(0xdeadbeef);
113     memset(&infoA,0,sizeof infoA);
114     ret = GetVersionExA(&infoA);
115     ok(!ret, "Expected GetVersionExA to fail\n");
116     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
117         GetLastError() == 0xdeadbeef /* Win9x */,
118         "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
119         GetLastError());
120 
121     SetLastError(0xdeadbeef);
122     infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA) / 2;
123     ret = GetVersionExA(&infoA);
124     ok(!ret, "Expected GetVersionExA to fail\n");
125     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
126         GetLastError() == 0xdeadbeef /* Win9x */,
127         "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
128         GetLastError());
129 
130     SetLastError(0xdeadbeef);
131     infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA) * 2;
132     ret = GetVersionExA(&infoA);
133     ok(!ret, "Expected GetVersionExA to fail\n");
134     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
135         GetLastError() == 0xdeadbeef /* Win9x */,
136         "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
137         GetLastError());
138 
139     SetLastError(0xdeadbeef);
140     infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
141     ret = GetVersionExA(&infoA);
142     ok(ret, "Expected GetVersionExA to succeed\n");
143     ok(GetLastError() == 0xdeadbeef,
144         "Expected 0xdeadbeef, got %d\n", GetLastError());
145 
146     SetLastError(0xdeadbeef);
147     infoExA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
148     ret = GetVersionExA((OSVERSIONINFOA *)&infoExA);
149     ok(ret, "GetVersionExA failed.\n");
150 
151     if (!infoExA.wServicePackMajor && !infoExA.wServicePackMinor)
152         ok(!infoExA.szCSDVersion[0], "got '%s'\n", infoExA.szCSDVersion);
153 }
154 
test_VerifyVersionInfo(void)155 static void test_VerifyVersionInfo(void)
156 {
157     enum srcversion_mode
158     {
159         SRCVERSION_ZERO         = 0,
160         SRCVERSION_CURRENT      = 1,
161         SRCVERSION_INC_MINOR    = 2,
162         SRCVERSION_INC_SP_MINOR = 3,
163         SRCVERSION_INC_SP_MAJOR = 4,
164         SRCVERSION_DEC_SP_MAJOR = 5,
165         SRCVERSION_DEC_MAJOR    = 6,
166         SRCVERSION_INC_BUILD    = 7,
167         SRCVERSION_REQUIRES_SP  = 0x1000,
168     };
169 
170     struct verify_version_test
171     {
172         DWORD verifymask; /* Type mask for VerifyVersionInfo() */
173         DWORD srcinfo;    /* The way current version info is modified. */
174         DWORD err;        /* Error code on failure, 0 on success. */
175 
176         DWORD typemask1;
177         DWORD condition1;
178         DWORD typemask2;
179         DWORD condition2;
180         DWORD typemask3;
181         DWORD condition3;
182         DWORD typemask4;
183         DWORD condition4;
184 
185         BOOL todo;
186     } verify_version_tests[] =
187     {
188         {
189             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
190             SRCVERSION_INC_MINOR,
191             0,
192 
193             VER_MAJORVERSION, VER_EQUAL,
194             VER_MINORVERSION, VER_LESS,
195         },
196         {
197             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
198             SRCVERSION_INC_MINOR,
199             ERROR_OLD_WIN_VERSION,
200 
201             VER_MAJORVERSION, VER_GREATER_EQUAL,
202             VER_MINORVERSION, VER_LESS,
203         },
204         {
205             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
206             SRCVERSION_CURRENT,
207             0,
208 
209             VER_MAJORVERSION, VER_GREATER_EQUAL,
210             VER_MINORVERSION, VER_LESS,
211         },
212         {
213             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
214             SRCVERSION_CURRENT,
215             0,
216 
217             VER_MAJORVERSION, VER_GREATER_EQUAL,
218             VER_MINORVERSION, VER_AND,
219         },
220         {
221             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
222             SRCVERSION_INC_MINOR,
223             0,
224 
225             VER_MAJORVERSION, VER_LESS_EQUAL,
226             VER_MINORVERSION, VER_LESS,
227         },
228         {
229             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
230             SRCVERSION_INC_MINOR,
231             ERROR_OLD_WIN_VERSION,
232 
233             VER_MAJORVERSION, VER_AND,
234             VER_MINORVERSION, VER_LESS,
235         },
236         {
237             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
238             SRCVERSION_INC_MINOR,
239             ERROR_OLD_WIN_VERSION,
240 
241             VER_MAJORVERSION, VER_OR,
242             VER_MINORVERSION, VER_LESS,
243         },
244         {
245             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
246             SRCVERSION_INC_SP_MINOR,
247             ERROR_OLD_WIN_VERSION,
248 
249             VER_MINORVERSION, VER_EQUAL,
250             VER_SERVICEPACKMINOR, VER_LESS,
251         },
252         {
253             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
254             SRCVERSION_INC_SP_MINOR,
255             ERROR_OLD_WIN_VERSION,
256 
257             VER_MAJORVERSION, VER_EQUAL,
258             VER_SERVICEPACKMINOR, VER_LESS,
259         },
260         {
261             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
262             SRCVERSION_INC_SP_MAJOR,
263             ERROR_OLD_WIN_VERSION,
264 
265             VER_MAJORVERSION, VER_EQUAL,
266             VER_SERVICEPACKMAJOR, VER_EQUAL,
267         },
268         {
269             VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
270             SRCVERSION_INC_SP_MINOR,
271             0,
272 
273             VER_SERVICEPACKMAJOR, VER_EQUAL,
274             VER_SERVICEPACKMINOR, VER_LESS,
275         },
276         {
277             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
278             SRCVERSION_INC_SP_MINOR,
279             ERROR_OLD_WIN_VERSION,
280 
281             VER_SERVICEPACKMAJOR, VER_EQUAL,
282             VER_SERVICEPACKMINOR, VER_LESS,
283         },
284         {
285             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
286             SRCVERSION_INC_SP_MINOR,
287             0,
288 
289             VER_MINORVERSION, VER_EQUAL,
290             VER_SERVICEPACKMAJOR, VER_EQUAL,
291             VER_SERVICEPACKMINOR, VER_LESS,
292         },
293         {
294             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
295             SRCVERSION_INC_SP_MINOR,
296             ERROR_OLD_WIN_VERSION,
297 
298             VER_MINORVERSION, VER_EQUAL,
299             VER_SERVICEPACKMAJOR, VER_EQUAL,
300             VER_SERVICEPACKMINOR, VER_LESS,
301         },
302         {
303             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
304             SRCVERSION_INC_SP_MINOR,
305             0,
306 
307             VER_MAJORVERSION, VER_EQUAL,
308             VER_MINORVERSION, VER_EQUAL,
309             VER_SERVICEPACKMAJOR, VER_EQUAL,
310             VER_SERVICEPACKMINOR, VER_LESS,
311         },
312         {
313             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
314             SRCVERSION_INC_SP_MINOR,
315             ERROR_OLD_WIN_VERSION,
316 
317             VER_MAJORVERSION, VER_EQUAL,
318             VER_MINORVERSION, VER_GREATER_EQUAL,
319             VER_SERVICEPACKMAJOR, VER_EQUAL,
320             VER_SERVICEPACKMINOR, VER_LESS,
321         },
322         {
323             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
324             SRCVERSION_INC_SP_MAJOR,
325             0,
326 
327             VER_MAJORVERSION, VER_LESS_EQUAL,
328             VER_SERVICEPACKMAJOR, VER_GREATER,
329         },
330         {
331             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
332             SRCVERSION_INC_SP_MAJOR,
333             ERROR_OLD_WIN_VERSION,
334 
335             VER_MAJORVERSION, VER_EQUAL,
336             VER_SERVICEPACKMAJOR, VER_LESS,
337         },
338         {
339             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
340             SRCVERSION_INC_SP_MAJOR,
341             ERROR_OLD_WIN_VERSION,
342 
343             VER_MINORVERSION, VER_EQUAL,
344             VER_SERVICEPACKMAJOR, VER_LESS,
345         },
346         {
347             VER_MAJORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
348             SRCVERSION_INC_SP_MAJOR,
349             0,
350 
351             VER_MAJORVERSION, VER_EQUAL,
352             VER_SERVICEPACKMAJOR, VER_LESS,
353         },
354         {
355             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
356             SRCVERSION_INC_SP_MAJOR,
357             ERROR_OLD_WIN_VERSION,
358 
359             VER_MAJORVERSION, VER_EQUAL,
360             VER_SERVICEPACKMAJOR, VER_LESS,
361         },
362         {
363             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
364             SRCVERSION_INC_SP_MAJOR,
365             0,
366 
367             VER_MAJORVERSION, VER_EQUAL,
368             VER_MINORVERSION, VER_EQUAL,
369             VER_SERVICEPACKMAJOR, VER_LESS,
370         },
371         {
372             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
373             SRCVERSION_INC_SP_MAJOR,
374             ERROR_OLD_WIN_VERSION,
375 
376             VER_MAJORVERSION, VER_GREATER_EQUAL,
377             VER_SERVICEPACKMAJOR, VER_LESS,
378         },
379         {
380             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
381             SRCVERSION_DEC_MAJOR,
382             0,
383 
384             VER_MAJORVERSION, VER_GREATER_EQUAL,
385             VER_SERVICEPACKMAJOR, VER_LESS,
386         },
387         {
388             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
389             SRCVERSION_CURRENT,
390             0,
391 
392             VER_MAJORVERSION, VER_GREATER_EQUAL,
393             VER_SERVICEPACKMAJOR, VER_LESS,
394         },
395         {
396             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
397             SRCVERSION_INC_SP_MAJOR,
398             ERROR_OLD_WIN_VERSION,
399 
400             VER_MAJORVERSION, VER_GREATER_EQUAL,
401             VER_MINORVERSION, VER_EQUAL,
402             VER_SERVICEPACKMAJOR, VER_LESS,
403         },
404         {
405             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
406             SRCVERSION_INC_SP_MAJOR,
407             ERROR_OLD_WIN_VERSION,
408 
409             VER_MAJORVERSION, VER_GREATER_EQUAL,
410             VER_MINORVERSION, VER_GREATER_EQUAL,
411             VER_SERVICEPACKMAJOR, VER_LESS_EQUAL,
412         },
413         {
414             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
415             SRCVERSION_INC_SP_MAJOR,
416             ERROR_OLD_WIN_VERSION,
417 
418             VER_MAJORVERSION, VER_GREATER_EQUAL,
419             VER_SERVICEPACKMAJOR, VER_AND,
420         },
421         {
422             VER_MAJORVERSION | VER_MINORVERSION,
423             SRCVERSION_ZERO,
424             0,
425 
426             VER_MAJORVERSION, VER_GREATER_EQUAL,
427         },
428         {
429             VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER,
430             SRCVERSION_ZERO,
431             ERROR_OLD_WIN_VERSION,
432 
433             VER_MAJORVERSION, VER_GREATER_EQUAL,
434         },
435         {
436             VER_SUITENAME,
437             SRCVERSION_ZERO,
438             0,
439 
440             VER_SUITENAME, VER_AND,
441         },
442         {
443             VER_SUITENAME,
444             SRCVERSION_ZERO,
445             0,
446 
447             VER_SUITENAME, VER_OR,
448         },
449         {
450             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
451             SRCVERSION_INC_SP_MINOR,
452             ERROR_OLD_WIN_VERSION,
453 
454             VER_MINORVERSION, VER_GREATER_EQUAL,
455         },
456         {
457             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
458             SRCVERSION_INC_SP_MAJOR,
459             0,
460 
461             VER_MINORVERSION, VER_LESS,
462         },
463         {
464             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
465             SRCVERSION_INC_SP_MAJOR,
466             0,
467 
468             VER_MINORVERSION, VER_LESS_EQUAL,
469         },
470         {
471             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
472             SRCVERSION_INC_SP_MAJOR,
473             ERROR_OLD_WIN_VERSION,
474 
475             VER_MINORVERSION, VER_EQUAL,
476         },
477         {
478             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
479             SRCVERSION_INC_SP_MAJOR,
480             ERROR_OLD_WIN_VERSION,
481 
482             VER_MINORVERSION, VER_GREATER_EQUAL,
483         },
484         {
485             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
486             SRCVERSION_INC_MINOR,
487             ERROR_OLD_WIN_VERSION,
488 
489             VER_MINORVERSION, VER_GREATER_EQUAL,
490         },
491         {
492             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
493             SRCVERSION_INC_MINOR,
494             ERROR_OLD_WIN_VERSION,
495 
496             VER_MINORVERSION, VER_GREATER_EQUAL,
497         },
498         {
499             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
500             SRCVERSION_CURRENT,
501             0,
502 
503             VER_MINORVERSION, VER_GREATER_EQUAL,
504         },
505         {
506             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
507             SRCVERSION_INC_BUILD,
508             ERROR_OLD_WIN_VERSION,
509 
510             VER_MINORVERSION, VER_GREATER_EQUAL,
511         },
512         {
513             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
514             SRCVERSION_INC_BUILD,
515             0,
516 
517             VER_MINORVERSION, VER_GREATER_EQUAL,
518         },
519         {
520             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
521             SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
522             0,
523 
524             VER_MINORVERSION, VER_GREATER,
525         },
526         {
527             VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
528             SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
529             0,
530 
531             VER_MINORVERSION, VER_GREATER_EQUAL,
532         },
533         {
534             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
535             SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
536             ERROR_OLD_WIN_VERSION,
537 
538             VER_MAJORVERSION, VER_EQUAL,
539             VER_SERVICEPACKMAJOR, VER_GREATER,
540         },
541         {
542             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
543             SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
544             0,
545 
546             VER_MAJORVERSION, VER_GREATER_EQUAL,
547             VER_MINORVERSION, VER_EQUAL,
548             VER_SERVICEPACKMAJOR, VER_GREATER,
549         },
550         {
551             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
552             SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
553             0,
554 
555             VER_MAJORVERSION, VER_GREATER_EQUAL,
556             VER_MINORVERSION, VER_LESS_EQUAL,
557             VER_SERVICEPACKMAJOR, VER_GREATER,
558         },
559         {
560             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
561             SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
562             0,
563 
564             VER_MAJORVERSION, VER_GREATER_EQUAL,
565             VER_MINORVERSION, VER_AND,
566             VER_SERVICEPACKMAJOR, VER_GREATER,
567         },
568         {
569             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
570             SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
571             ERROR_OLD_WIN_VERSION,
572 
573             VER_SERVICEPACKMAJOR, VER_GREATER,
574             VER_SERVICEPACKMINOR, VER_EQUAL,
575         },
576     };
577 
578     OSVERSIONINFOEXA info;
579     DWORD servicepack;
580     unsigned int i;
581     BOOL ret;
582 
583     /* Before we start doing some tests we should check what the version of
584      * the ServicePack is. Tests on a box with no ServicePack will fail otherwise.
585      */
586     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
587     GetVersionExA((OSVERSIONINFOA *)&info);
588     servicepack = info.wServicePackMajor;
589     if (servicepack == 0)
590         skip("There is no ServicePack on this system. Some tests will be skipped.\n");
591 
592     /* Win8.1+ returns Win8 version in GetVersionEx when there's no app manifest targeting 8.1 */
593     if (info.dwMajorVersion == 6 && info.dwMinorVersion == 2)
594     {
595         RTL_OSVERSIONINFOEXW rtlinfo;
596         rtlinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
597         ok(!pRtlGetVersion(&rtlinfo), "RtlGetVersion failed\n");
598 
599         if (rtlinfo.dwMajorVersion != 6 || rtlinfo.dwMinorVersion != 2)
600         {
601             win_skip("GetVersionEx and VerifyVersionInfo are faking values\n");
602             return;
603         }
604     }
605 
606     for (i = 0; i < sizeof(verify_version_tests)/sizeof(verify_version_tests[0]); i++)
607     {
608         struct verify_version_test *test = &verify_version_tests[i];
609         DWORD srcinfo = test->srcinfo;
610         ULONGLONG mask;
611 
612         if (servicepack == 0 && srcinfo & SRCVERSION_REQUIRES_SP)
613             continue;
614         srcinfo &= ~SRCVERSION_REQUIRES_SP;
615 
616         info.dwOSVersionInfoSize = sizeof(info);
617         GetVersionExA((OSVERSIONINFOA *)&info);
618 
619         switch (srcinfo)
620         {
621         case SRCVERSION_ZERO:
622             memset(&info, 0, sizeof(info));
623             break;
624         case SRCVERSION_INC_MINOR:
625             info.dwMinorVersion++;
626             break;
627         case SRCVERSION_INC_SP_MINOR:
628             info.wServicePackMinor++;
629             break;
630         case SRCVERSION_INC_SP_MAJOR:
631             info.wServicePackMajor++;
632             break;
633         case SRCVERSION_DEC_SP_MAJOR:
634             info.wServicePackMajor--;
635             break;
636         case SRCVERSION_DEC_MAJOR:
637             info.dwMajorVersion--;
638             break;
639         case SRCVERSION_INC_BUILD:
640             info.dwBuildNumber++;
641             break;
642         default:
643             ;
644         }
645 
646         mask = VerSetConditionMask(0, test->typemask1, test->condition1);
647         if (test->typemask2)
648             mask = VerSetConditionMask(mask, test->typemask2, test->condition2);
649         if (test->typemask3)
650             mask = VerSetConditionMask(mask, test->typemask3, test->condition3);
651         if (test->typemask4)
652             mask = VerSetConditionMask(mask, test->typemask4, test->condition4);
653 
654         SetLastError(0xdeadbeef);
655         ret = VerifyVersionInfoA(&info, test->verifymask, mask);
656     todo_wine_if(test->todo)
657     {
658         ok(test->err ? !ret : ret, "%u: unexpected return value %d.\n", i, ret);
659         if (!ret)
660             ok(GetLastError() == test->err, "%u: unexpected error code %d, expected %d.\n", i, GetLastError(), test->err);
661     }
662     }
663 
664     /* test handling of version numbers */
665     /* v3.10 is always less than v4.x even
666      * if the minor version is tested */
667     info.dwMajorVersion = 3;
668     info.dwMinorVersion = 10;
669     ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
670         VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
671             VER_MAJORVERSION, VER_GREATER_EQUAL));
672     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
673 
674     info.dwMinorVersion = 0;
675     info.wServicePackMajor = 10;
676     ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
677         VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
678             VER_MAJORVERSION, VER_GREATER_EQUAL));
679     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
680 
681     info.wServicePackMajor = 0;
682     info.wServicePackMinor = 10;
683     ret = VerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
684         VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
685             VER_MAJORVERSION, VER_GREATER_EQUAL));
686     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
687 
688     /* test bad dwOSVersionInfoSize */
689     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
690     GetVersionExA((OSVERSIONINFOA *)&info);
691     info.dwOSVersionInfoSize = 0;
692     ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
693         VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
694     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
695 }
696 
START_TEST(version)697 START_TEST(version)
698 {
699     init_function_pointers();
700 
701     test_GetProductInfo();
702     test_GetVersionEx();
703     test_VerifyVersionInfo();
704 }
705