2 * Copyright 2010 Detlef Riekenberg
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.
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.
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
26 #include "wine/test.h"
28 #define DEFINE_EXPECT(func) \
29 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
31 #define SET_EXPECT(func) \
32 expect_ ## func = TRUE
34 #define CHECK_EXPECT2(func) \
36 ok(expect_ ##func, "unexpected call " #func "\n"); \
37 called_ ## func = TRUE; \
40 #define CHECK_EXPECT(func) \
42 CHECK_EXPECT2(func); \
43 expect_ ## func = FALSE; \
46 #define CHECK_CALLED(func) \
48 ok(called_ ## func, "expected " #func "\n"); \
49 expect_ ## func = called_ ## func = FALSE; \
52 DEFINE_EXPECT(invalid_parameter_handler);
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);
67 static void* (WINAPI *pEncodePointer)(void *);
69 static int cb_called[4];
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)
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);
85 static int __cdecl initterm_cb0(void)
91 static int __cdecl initterm_cb1(void)
97 static int __cdecl initterm_cb2(void)
104 static void test__initterm_e(void)
106 _INITTERM_E_FN table[4];
110 skip("_initterm_e not found\n");
114 memset(table, 0, sizeof(table));
116 memset(cb_called, 0, sizeof(cb_called));
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]);
123 memset(cb_called, 0, sizeof(cb_called));
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]);
131 /* this crash on Windows */
133 res = p_initterm_e(NULL, table);
134 trace("got %d with 0x%x\n", res, errno);
137 table[0] = initterm_cb0;
138 memset(cb_called, 0, sizeof(cb_called));
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]);
146 /* init-function returning failure */
147 table[1] = initterm_cb1;
148 memset(cb_called, 0, sizeof(cb_called));
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]);
155 /* init-function not called, when end < start */
156 memset(cb_called, 0, sizeof(cb_called));
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]);
163 /* initialization stop after first non-zero result */
164 table[2] = initterm_cb0;
165 memset(cb_called, 0, sizeof(cb_called));
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]);
172 /* NULL pointer in the array are skipped */
174 table[2] = initterm_cb2;
175 memset(cb_called, 0, sizeof(cb_called));
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]);
184 /* Beware that _encode_pointer is a NOP before XP
185 (the parameter is returned unchanged) */
186 static void test__encode_pointer(void)
190 if(!p_encode_pointer || !p_decode_pointer || !p_encoded_null) {
191 win_skip("_encode_pointer, _decode_pointer or _encoded_null not found\n");
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");
200 ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
202 ptr = p_encode_pointer(p_encode_pointer);
203 ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
205 /* Not present before XP */
206 if (!pEncodePointer) {
207 win_skip("EncodePointer not found\n");
211 res = pEncodePointer(p_encode_pointer);
212 ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
216 static void test_error_messages(void)
218 int *size, size_copy;
220 if(!p_sys_nerr || !p__sys_nerr || !p_sys_errlist || !p__sys_errlist) {
221 win_skip("Skipping test_error_messages tests\n");
225 size = p__sys_nerr();
227 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
230 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
234 ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
237 static void test__strtoi64(void)
240 unsigned __int64 ures;
242 if(!p_strtoi64 || !p_strtoui64) {
243 win_skip("_strtoi64 or _strtoui64 not found\n");
247 if(!p_set_invalid_parameter_handler) {
248 win_skip("_set_invalid_parameter_handler not found\n");
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);
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);
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);
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);
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);
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);
292 SetLastError(0xdeadbeef);
293 hcrt = LoadLibraryA("msvcr90.dll");
295 win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
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");
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");
315 hkernel32 = GetModuleHandleA("kernel32.dll");
316 pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
319 test__encode_pointer();
320 test_error_messages();