hlink: Site data should only be set if the hlink has an HlinkSite.
[wine] / dlls / msvcr90 / tests / msvcr90.c
1 /*
2  * Copyright 2010 Detlef Riekenberg
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22
23 #include <windef.h>
24 #include <winbase.h>
25 #include <errno.h>
26 #include "wine/test.h"
27
28 #define DEFINE_EXPECT(func) \
29     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
30
31 #define SET_EXPECT(func) \
32     expect_ ## func = TRUE
33
34 #define CHECK_EXPECT2(func) \
35     do { \
36         ok(expect_ ##func, "unexpected call " #func "\n"); \
37         called_ ## func = TRUE; \
38     }while(0)
39
40 #define CHECK_EXPECT(func) \
41     do { \
42         CHECK_EXPECT2(func); \
43         expect_ ## func = FALSE; \
44     }while(0)
45
46 #define CHECK_CALLED(func) \
47     do { \
48         ok(called_ ## func, "expected " #func "\n"); \
49         expect_ ## func = called_ ## func = FALSE; \
50     }while(0)
51
52 DEFINE_EXPECT(invalid_parameter_handler);
53
54 static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
55 typedef int (__cdecl *_INITTERM_E_FN)(void);
56 static int (__cdecl *p_initterm_e)(_INITTERM_E_FN *table, _INITTERM_E_FN *end);
57 static void* (__cdecl *p_encode_pointer)(void *);
58 static void* (__cdecl *p_decode_pointer)(void *);
59 static void* (__cdecl *p_encoded_null)(void);
60 static int *p_sys_nerr;
61 static int* (__cdecl *p__sys_nerr)(void);
62 static char **p_sys_errlist;
63 static char** (__cdecl *p__sys_errlist)(void);
64 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
65 static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
66
67 static void* (WINAPI *pEncodePointer)(void *);
68
69 static int cb_called[4];
70
71 /* ########## */
72
73 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
74         const wchar_t *function, const wchar_t *file,
75         unsigned line, uintptr_t arg)
76 {
77     CHECK_EXPECT(invalid_parameter_handler);
78     ok(expression == NULL, "expression is not NULL\n");
79     ok(function == NULL, "function is not NULL\n");
80     ok(file == NULL, "file is not NULL\n");
81     ok(line == 0, "line = %u\n", line);
82     ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
83 }
84
85 static int __cdecl initterm_cb0(void)
86 {
87     cb_called[0]++;
88     return 0;
89 }
90
91 static int __cdecl initterm_cb1(void)
92 {
93     cb_called[1]++;
94     return 1;
95 }
96
97 static int __cdecl initterm_cb2(void)
98 {
99     cb_called[2]++;
100     return 2;
101 }
102
103
104 static void test__initterm_e(void)
105 {
106     _INITTERM_E_FN table[4];
107     int res;
108
109     if (!p_initterm_e) {
110         skip("_initterm_e not found\n");
111         return;
112     }
113
114     memset(table, 0, sizeof(table));
115
116     memset(cb_called, 0, sizeof(cb_called));
117     errno = 0xdeadbeef;
118     res = p_initterm_e(table, table);
119     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
120         "got %d with 0x%x {%d, %d, %d}\n",
121         res, errno, cb_called[0], cb_called[1], cb_called[2]);
122
123     memset(cb_called, 0, sizeof(cb_called));
124     errno = 0xdeadbeef;
125     res = p_initterm_e(table, NULL);
126     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
127         "got %d with 0x%x {%d, %d, %d}\n",
128         res, errno, cb_called[0], cb_called[1], cb_called[2]);
129
130     if (0) {
131         /* this crash on Windows */
132         errno = 0xdeadbeef;
133         res = p_initterm_e(NULL, table);
134         trace("got %d with 0x%x\n", res, errno);
135     }
136
137     table[0] = initterm_cb0;
138     memset(cb_called, 0, sizeof(cb_called));
139     errno = 0xdeadbeef;
140     res = p_initterm_e(table, &table[1]);
141     ok( !res && (cb_called[0] == 1) && !cb_called[1] && !cb_called[2],
142         "got %d with 0x%x {%d, %d, %d}\n",
143         res, errno, cb_called[0], cb_called[1], cb_called[2]);
144
145
146     /* init-function returning failure */
147     table[1] = initterm_cb1;
148     memset(cb_called, 0, sizeof(cb_called));
149     errno = 0xdeadbeef;
150     res = p_initterm_e(table, &table[3]);
151     ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
152         "got %d with 0x%x {%d, %d, %d}\n",
153         res, errno, cb_called[0], cb_called[1], cb_called[2]);
154
155     /* init-function not called, when end < start */
156     memset(cb_called, 0, sizeof(cb_called));
157     errno = 0xdeadbeef;
158     res = p_initterm_e(&table[3], table);
159     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
160         "got %d with 0x%x {%d, %d, %d}\n",
161         res, errno, cb_called[0], cb_called[1], cb_called[2]);
162
163     /* initialization stop after first non-zero result */
164     table[2] = initterm_cb0;
165     memset(cb_called, 0, sizeof(cb_called));
166     errno = 0xdeadbeef;
167     res = p_initterm_e(table, &table[3]);
168     ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
169         "got %d with 0x%x {%d, %d, %d}\n",
170         res, errno, cb_called[0], cb_called[1], cb_called[2]);
171
172     /* NULL pointer in the array are skipped */
173     table[1] = NULL;
174     table[2] = initterm_cb2;
175     memset(cb_called, 0, sizeof(cb_called));
176     errno = 0xdeadbeef;
177     res = p_initterm_e(table, &table[3]);
178     ok( (res == 2) && (cb_called[0] == 1) && !cb_called[1] && (cb_called[2] == 1),
179         "got %d with 0x%x {%d, %d, %d}\n",
180         res, errno, cb_called[0], cb_called[1], cb_called[2]);
181
182 }
183
184 /* Beware that _encode_pointer is a NOP before XP
185    (the parameter is returned unchanged) */
186 static void test__encode_pointer(void)
187 {
188     void *ptr, *res;
189
190     if(!p_encode_pointer || !p_decode_pointer || !p_encoded_null) {
191         win_skip("_encode_pointer, _decode_pointer or _encoded_null not found\n");
192         return;
193     }
194
195     ptr = (void*)0xdeadbeef;
196     res = p_encode_pointer(ptr);
197     res = p_decode_pointer(res);
198     ok(res == ptr, "Pointers are different after encoding and decoding\n");
199
200     ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
201
202     ptr = p_encode_pointer(p_encode_pointer);
203     ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
204
205     /* Not present before XP */
206     if (!pEncodePointer) {
207         win_skip("EncodePointer not found\n");
208         return;
209     }
210
211     res = pEncodePointer(p_encode_pointer);
212     ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
213
214 }
215
216 static void test_error_messages(void)
217 {
218     int *size, size_copy;
219
220     if(!p_sys_nerr || !p__sys_nerr || !p_sys_errlist || !p__sys_errlist) {
221         win_skip("Skipping test_error_messages tests\n");
222         return;
223     }
224
225     size = p__sys_nerr();
226     size_copy = *size;
227     ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
228
229     *size = 20;
230     ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
231
232     *size = size_copy;
233
234     ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
235 }
236
237 static void test__strtoi64(void)
238 {
239     __int64 res;
240     unsigned __int64 ures;
241
242     if(!p_strtoi64 || !p_strtoui64) {
243         win_skip("_strtoi64 or _strtoui64 not found\n");
244         return;
245     }
246
247     if(!p_set_invalid_parameter_handler) {
248         win_skip("_set_invalid_parameter_handler not found\n");
249         return;
250     }
251
252     errno = 0xdeadbeef;
253     SET_EXPECT(invalid_parameter_handler);
254     res = p_strtoi64(NULL, NULL, 10);
255     ok(res == 0, "res != 0\n");
256     CHECK_CALLED(invalid_parameter_handler);
257
258     SET_EXPECT(invalid_parameter_handler);
259     res = p_strtoi64("123", NULL, 1);
260     ok(res == 0, "res != 0\n");
261     CHECK_CALLED(invalid_parameter_handler);
262
263     SET_EXPECT(invalid_parameter_handler);
264     res = p_strtoi64("123", NULL, 37);
265     ok(res == 0, "res != 0\n");
266     CHECK_CALLED(invalid_parameter_handler);
267
268     SET_EXPECT(invalid_parameter_handler);
269     ures = p_strtoui64(NULL, NULL, 10);
270     ok(ures == 0, "res = %d\n", (int)ures);
271     CHECK_CALLED(invalid_parameter_handler);
272
273     SET_EXPECT(invalid_parameter_handler);
274     ures = p_strtoui64("123", NULL, 1);
275     ok(ures == 0, "res = %d\n", (int)ures);
276     CHECK_CALLED(invalid_parameter_handler);
277
278     SET_EXPECT(invalid_parameter_handler);
279     ures = p_strtoui64("123", NULL, 37);
280     ok(ures == 0, "res = %d\n", (int)ures);
281     CHECK_CALLED(invalid_parameter_handler);
282     ok(errno == 0xdeadbeef, "errno = %x\n", errno);
283 }
284
285 /* ########## */
286
287 START_TEST(msvcr90)
288 {
289     HMODULE hcrt;
290     HMODULE hkernel32;
291
292     SetLastError(0xdeadbeef);
293     hcrt = LoadLibraryA("msvcr90.dll");
294     if (!hcrt) {
295         win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
296         return;
297     }
298
299     p_set_invalid_parameter_handler = (void *) GetProcAddress(hcrt, "_set_invalid_parameter_handler");
300     if(p_set_invalid_parameter_handler)
301         ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
302                 "Invalid parameter handler was already set\n");
303
304     p_initterm_e = (void *) GetProcAddress(hcrt, "_initterm_e");
305     p_encode_pointer = (void *) GetProcAddress(hcrt, "_encode_pointer");
306     p_decode_pointer = (void *) GetProcAddress(hcrt, "_decode_pointer");
307     p_encoded_null = (void *) GetProcAddress(hcrt, "_encoded_null");
308     p_sys_nerr = (void *) GetProcAddress(hcrt, "_sys_nerr");
309     p__sys_nerr = (void *) GetProcAddress(hcrt, "__sys_nerr");
310     p_sys_errlist = (void *) GetProcAddress(hcrt, "_sys_errlist");
311     p__sys_errlist = (void *) GetProcAddress(hcrt, "__sys_errlist");
312     p_strtoi64 = (void *) GetProcAddress(hcrt, "_strtoi64");
313     p_strtoui64 = (void *) GetProcAddress(hcrt, "_strtoui64");
314
315     hkernel32 = GetModuleHandleA("kernel32.dll");
316     pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
317
318     test__initterm_e();
319     test__encode_pointer();
320     test_error_messages();
321     test__strtoi64();
322 }