Release 1.5.29.
[wine] / dlls / kernel32 / tests / version.c
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 /* Needed for PRODUCT_* defines and GetProductInfo() */
22 #define _WIN32_WINNT 0x0600
23
24 #include <assert.h>
25
26 #include "wine/test.h"
27 #include "winbase.h"
28
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);
32
33 #define KERNEL32_GET_PROC(func)                                     \
34     p##func = (void *)GetProcAddress(hKernel32, #func);
35
36 static void init_function_pointers(void)
37 {
38     HMODULE hKernel32;
39
40     hKernel32 = GetModuleHandleA("kernel32.dll");
41
42     KERNEL32_GET_PROC(GetProductInfo);
43     KERNEL32_GET_PROC(VerifyVersionInfoA);
44     KERNEL32_GET_PROC(VerSetConditionMask);
45 }
46
47 static void test_GetProductInfo(void)
48 {
49     DWORD product;
50     DWORD res;
51     DWORD table[] = {9,8,7,6,
52                      7,0,0,0,
53                      6,2,0,0,
54                      6,1,2,0,
55                      6,1,1,0,
56                      6,1,0,2,
57                      6,1,0,0,
58                      6,0,3,0,
59                      6,0,2,0,
60                      6,0,1,5,
61                      6,0,1,0,
62                      6,0,0,0,
63                      5,3,0,0,
64                      5,2,0,0,
65                      5,1,0,0,
66                      5,0,0,0,
67                      0};
68
69     DWORD *entry = table;
70
71     if (!pGetProductInfo)
72     {
73         /* Not present before Vista */
74         win_skip("GetProductInfo() not available\n");
75         return;
76     }
77
78     while (*entry)
79     {
80         /* SetLastError() / GetLastError(): value is untouched */
81         product = 0xdeadbeef;
82         SetLastError(0xdeadbeef);
83         res = pGetProductInfo(entry[0], entry[1], entry[2], entry[3], &product);
84
85         if (entry[0] >= 6)
86             ok(res && (product > PRODUCT_UNDEFINED) && (product <= PRODUCT_PROFESSIONAL_WMC),
87                "got %d and 0x%x (expected TRUE and a valid PRODUCT_* value)\n", res, product);
88         else
89             ok(!res && !product && (GetLastError() == 0xdeadbeef),
90                "got %d and 0x%x with 0x%x (expected FALSE and PRODUCT_UNDEFINED with LastError untouched)\n",
91                res, product, GetLastError());
92
93         entry+= 4;
94     }
95
96     /* NULL pointer is not a problem */
97     SetLastError(0xdeadbeef);
98     res = pGetProductInfo(6, 1, 0, 0, NULL);
99     ok( (!res) && (GetLastError() == 0xdeadbeef),
100         "got %d with 0x%x (expected FALSE with LastError untouched\n", res, GetLastError());
101 }
102
103 static void test_GetVersionEx(void)
104 {
105     OSVERSIONINFOA infoA;
106     OSVERSIONINFOEXA infoExA;
107     BOOL ret;
108
109     if (0)
110     {
111         /* Silently crashes on XP */
112         GetVersionExA(NULL);
113     }
114
115     SetLastError(0xdeadbeef);
116     memset(&infoA,0,sizeof infoA);
117     ret = GetVersionExA(&infoA);
118     ok(!ret, "Expected GetVersionExA to fail\n");
119     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
120         GetLastError() == 0xdeadbeef /* Win9x */,
121         "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
122         GetLastError());
123
124     SetLastError(0xdeadbeef);
125     infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA) / 2;
126     ret = GetVersionExA(&infoA);
127     ok(!ret, "Expected GetVersionExA to fail\n");
128     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
129         GetLastError() == 0xdeadbeef /* Win9x */,
130         "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
131         GetLastError());
132
133     SetLastError(0xdeadbeef);
134     infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA) * 2;
135     ret = GetVersionExA(&infoA);
136     ok(!ret, "Expected GetVersionExA to fail\n");
137     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
138         GetLastError() == 0xdeadbeef /* Win9x */,
139         "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
140         GetLastError());
141
142     SetLastError(0xdeadbeef);
143     infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
144     ret = GetVersionExA(&infoA);
145     ok(ret, "Expected GetVersionExA to succeed\n");
146     ok(GetLastError() == 0xdeadbeef,
147         "Expected 0xdeadbeef, got %d\n", GetLastError());
148
149     SetLastError(0xdeadbeef);
150     infoExA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
151     ret = GetVersionExA((OSVERSIONINFOA *)&infoExA);
152     ok(ret ||
153        broken(ret == 0), /* win95 */
154        "Expected GetVersionExA to succeed\n");
155 }
156
157 static void test_VerifyVersionInfo(void)
158 {
159     OSVERSIONINFOEX info;
160     BOOL ret;
161     DWORD servicepack, error;
162
163     if(!pVerifyVersionInfoA || !pVerSetConditionMask)
164     {
165         win_skip("Needed functions not available\n");
166         return;
167     }
168
169     /* Before we start doing some tests we should check what the version of
170      * the ServicePack is. Tests on a box with no ServicePack will fail otherwise.
171      */
172     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
173     GetVersionExA((OSVERSIONINFO *)&info);
174     servicepack = info.wServicePackMajor;
175     memset(&info, 0, sizeof(info));
176
177     ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION,
178         pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
179     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
180
181     SetLastError(0xdeadbeef);
182     ret = pVerifyVersionInfoA(&info, VER_BUILDNUMBER | VER_MAJORVERSION |
183         VER_MINORVERSION/* | VER_PLATFORMID | VER_SERVICEPACKMAJOR |
184         VER_SERVICEPACKMINOR | VER_SUITENAME | VER_PRODUCT_TYPE */,
185         pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
186     error = GetLastError();
187     ok(!ret, "VerifyVersionInfoA succeeded\n");
188     ok(error == ERROR_OLD_WIN_VERSION,
189        "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
190
191     /* tests special handling of VER_SUITENAME */
192
193     ret = pVerifyVersionInfoA(&info, VER_SUITENAME,
194         pVerSetConditionMask(0, VER_SUITENAME, VER_AND));
195     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
196
197     ret = pVerifyVersionInfoA(&info, VER_SUITENAME,
198         pVerSetConditionMask(0, VER_SUITENAME, VER_OR));
199     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
200
201     /* test handling of version numbers */
202     
203     /* v3.10 is always less than v4.x even
204      * if the minor version is tested */
205     info.dwMajorVersion = 3;
206     info.dwMinorVersion = 10;
207     ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
208         pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
209             VER_MAJORVERSION, VER_GREATER_EQUAL));
210     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
211
212     info.dwMinorVersion = 0;
213     info.wServicePackMajor = 10;
214     ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
215         pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
216             VER_MAJORVERSION, VER_GREATER_EQUAL));
217     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
218
219     info.wServicePackMajor = 0;
220     info.wServicePackMinor = 10;
221     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
222         pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
223             VER_MAJORVERSION, VER_GREATER_EQUAL));
224     ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
225
226     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
227     GetVersionEx((OSVERSIONINFO *)&info);
228     info.wServicePackMinor++;
229     SetLastError(0xdeadbeef);
230     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
231         pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
232     error = GetLastError();
233     ok(!ret, "VerifyVersionInfoA succeeded\n");
234     ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some wink2 */,
235        "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
236
237     if (servicepack == 0)
238     {
239         skip("There is no ServicePack on this system\n");
240     }
241     else
242     {
243         info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
244         GetVersionEx((OSVERSIONINFO *)&info);
245         info.wServicePackMajor--;
246         ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
247             pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER));
248         ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
249
250         info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
251         GetVersionEx((OSVERSIONINFO *)&info);
252         info.wServicePackMajor--;
253         ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
254             pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
255         ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
256     }
257
258     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
259     GetVersionEx((OSVERSIONINFO *)&info);
260     info.wServicePackMajor++;
261     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
262         pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS));
263     ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
264
265     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
266     GetVersionEx((OSVERSIONINFO *)&info);
267     info.wServicePackMajor++;
268     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
269         pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS_EQUAL));
270     ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
271
272     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
273     GetVersionEx((OSVERSIONINFO *)&info);
274     info.wServicePackMajor--;
275     SetLastError(0xdeadbeef);
276     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
277         pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL));
278     error = GetLastError();
279     ok(!ret, "VerifyVersionInfoA succeeded\n");
280     ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
281        "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
282
283     /* test the failure hierarchy for the four version fields */
284
285     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
286     GetVersionEx((OSVERSIONINFO *)&info);
287     info.wServicePackMajor++;
288     SetLastError(0xdeadbeef);
289     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
290         pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
291     error = GetLastError();
292     ok(!ret, "VerifyVersionInfoA succeeded\n");
293     ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
294        "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
295
296     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
297     GetVersionEx((OSVERSIONINFO *)&info);
298     info.dwMinorVersion++;
299     SetLastError(0xdeadbeef);
300     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
301         pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
302     error = GetLastError();
303     ok(!ret, "VerifyVersionInfoA succeeded\n");
304     ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
305        "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
306
307     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
308     GetVersionEx((OSVERSIONINFO *)&info);
309     info.dwMajorVersion++;
310     SetLastError(0xdeadbeef);
311     ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
312         pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
313     error = GetLastError();
314     ok(!ret, "VerifyVersionInfoA succeeded\n");
315     ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
316        "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
317
318     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
319         pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
320     ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
321
322     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
323     GetVersionEx((OSVERSIONINFO *)&info);
324     info.dwBuildNumber++;
325     SetLastError(0xdeadbeef);
326     ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
327         pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
328     error = GetLastError();
329     ok(!ret, "VerifyVersionInfoA succeeded\n");
330     ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
331        "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
332
333     ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
334         pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
335     ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
336
337     /* test bad dwOSVersionInfoSize */
338     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
339     GetVersionEx((OSVERSIONINFO *)&info);
340     info.dwOSVersionInfoSize = 0;
341     ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
342         pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
343     ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
344 }
345
346 START_TEST(version)
347 {
348     init_function_pointers();
349
350     test_GetProductInfo();
351     test_GetVersionEx();
352     test_VerifyVersionInfo();
353 }