msvcrt: Move invalid parameter tests to msvcr90.
[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 static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
29 typedef int (__cdecl *_INITTERM_E_FN)(void);
30 static int (__cdecl *p_initterm_e)(_INITTERM_E_FN *table, _INITTERM_E_FN *end);
31 static void* (__cdecl *p_encode_pointer)(void *);
32 static void* (__cdecl *p_decode_pointer)(void *);
33 static void* (__cdecl *p_encoded_null)(void);
34 static int *p_sys_nerr;
35 static int* (__cdecl *p__sys_nerr)(void);
36 static char **p_sys_errlist;
37 static char** (__cdecl *p__sys_errlist)(void);
38 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
39 static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
40
41 int cb_called[4];
42
43 /* ########## */
44
45 void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
46         const wchar_t *function, const wchar_t *file,
47         unsigned line, unsigned *res)
48 {
49     ok(expression == NULL, "expression is not NULL\n");
50     ok(function == NULL, "function is not NULL\n");
51     ok(file == NULL, "file is not NULL\n");
52     ok(line == 0, "line = %u\n", line);
53     ok(res == NULL, "res = %p\n", res);
54 }
55
56 static int initterm_cb0(void)
57 {
58     cb_called[0]++;
59     return 0;
60 }
61
62 static int initterm_cb1(void)
63 {
64     cb_called[1]++;
65     return 1;
66 }
67
68 static int initterm_cb2(void)
69 {
70     cb_called[2]++;
71     return 2;
72 }
73
74
75 static void test__initterm_e(void)
76 {
77     _INITTERM_E_FN table[4];
78     int res;
79
80     if (!p_initterm_e) {
81         skip("_initterm_e not found\n");
82         return;
83     }
84
85     memset(table, 0, sizeof(table));
86
87     memset(cb_called, 0, sizeof(cb_called));
88     errno = 0xdeadbeef;
89     res = p_initterm_e(table, table);
90     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
91         "got %d with 0x%x {%d, %d, %d}\n",
92         res, errno, cb_called[0], cb_called[1], cb_called[2]);
93
94     memset(cb_called, 0, sizeof(cb_called));
95     errno = 0xdeadbeef;
96     res = p_initterm_e(table, NULL);
97     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
98         "got %d with 0x%x {%d, %d, %d}\n",
99         res, errno, cb_called[0], cb_called[1], cb_called[2]);
100
101     if (0) {
102         /* this crash on Windows */
103         errno = 0xdeadbeef;
104         res = p_initterm_e(NULL, table);
105         trace("got %d with 0x%x\n", res, errno);
106     }
107
108     table[0] = initterm_cb0;
109     memset(cb_called, 0, sizeof(cb_called));
110     errno = 0xdeadbeef;
111     res = p_initterm_e(table, &table[1]);
112     ok( !res && (cb_called[0] == 1) && !cb_called[1] && !cb_called[2],
113         "got %d with 0x%x {%d, %d, %d}\n",
114         res, errno, cb_called[0], cb_called[1], cb_called[2]);
115
116
117     /* init-function returning failure */
118     table[1] = initterm_cb1;
119     memset(cb_called, 0, sizeof(cb_called));
120     errno = 0xdeadbeef;
121     res = p_initterm_e(table, &table[3]);
122     ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
123         "got %d with 0x%x {%d, %d, %d}\n",
124         res, errno, cb_called[0], cb_called[1], cb_called[2]);
125
126     /* init-function not called, when end < start */
127     memset(cb_called, 0, sizeof(cb_called));
128     errno = 0xdeadbeef;
129     res = p_initterm_e(&table[3], table);
130     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
131         "got %d with 0x%x {%d, %d, %d}\n",
132         res, errno, cb_called[0], cb_called[1], cb_called[2]);
133
134     /* initialization stop after first non-zero result */
135     table[2] = initterm_cb0;
136     memset(cb_called, 0, sizeof(cb_called));
137     errno = 0xdeadbeef;
138     res = p_initterm_e(table, &table[3]);
139     ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
140         "got %d with 0x%x {%d, %d, %d}\n",
141         res, errno, cb_called[0], cb_called[1], cb_called[2]);
142
143     /* NULL pointer in the array are skipped */
144     table[1] = NULL;
145     table[2] = initterm_cb2;
146     memset(cb_called, 0, sizeof(cb_called));
147     errno = 0xdeadbeef;
148     res = p_initterm_e(table, &table[3]);
149     ok( (res == 2) && (cb_called[0] == 1) && !cb_called[1] && (cb_called[2] == 1),
150         "got %d with 0x%x {%d, %d, %d}\n",
151         res, errno, cb_called[0], cb_called[1], cb_called[2]);
152
153 }
154
155 static void test__encode_pointer(void)
156 {
157     void *ptr, *res;
158
159     if(!p_encode_pointer || !p_decode_pointer || !p_encoded_null) {
160         win_skip("_encode_pointer, _decode_pointer or _encoded_null not found\n");
161         return;
162     }
163
164     ptr = (void*)0xdeadbeef;
165     res = p_encode_pointer(ptr);
166     res = p_decode_pointer(res);
167     ok(res == ptr, "Pointers are different after encoding and decoding\n");
168
169     ptr = p_encode_pointer(p_encode_pointer);
170     res = EncodePointer(p_encode_pointer);
171     ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
172     ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
173
174     ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
175 }
176
177 static void test_error_messages(void)
178 {
179     int *size, size_copy;
180
181     if(!p_sys_nerr || !p__sys_nerr || !p_sys_errlist || !p__sys_errlist) {
182         win_skip("Skipping test_error_messages tests\n");
183         return;
184     }
185
186     size = p__sys_nerr();
187     size_copy = *size;
188     ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
189
190     *size = 20;
191     ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
192
193     *size = size_copy;
194
195     ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
196 }
197
198 static void test__strtoi64(void)
199 {
200     __int64 res;
201     unsigned __int64 ures;
202
203     if(!p_strtoi64 || !p_strtoui64) {
204         win_skip("_strtoi64 or _strtoui64 not found\n");
205         return;
206     }
207
208     if(!p_set_invalid_parameter_handler) {
209         win_skip("_set_invalid_parameter_handler not found\n");
210         return;
211     }
212
213     errno = 0xdeadbeef;
214     res = p_strtoi64(NULL, NULL, 10);
215     ok(res == 0, "res != 0\n");
216     res = p_strtoi64("123", NULL, 1);
217     ok(res == 0, "res != 0\n");
218     res = p_strtoi64("123", NULL, 37);
219     ok(res == 0, "res != 0\n");
220     ures = p_strtoui64(NULL, NULL, 10);
221     ok(ures == 0, "res = %d\n", (int)ures);
222     ures = p_strtoui64("123", NULL, 1);
223     ok(ures == 0, "res = %d\n", (int)ures);
224     ures = p_strtoui64("123", NULL, 37);
225     ok(ures == 0, "res = %d\n", (int)ures);
226     ok(errno == 0xdeadbeef, "errno = %x\n", errno);
227 }
228
229 /* ########## */
230
231 START_TEST(msvcr90)
232 {
233     HMODULE hcrt;
234
235     SetLastError(0xdeadbeef);
236     hcrt = LoadLibraryA("msvcr90.dll");
237     if (!hcrt) {
238         win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
239         return;
240     }
241
242     p_set_invalid_parameter_handler = (void *) GetProcAddress(hcrt, "_set_invalid_parameter_handler");
243     if(p_set_invalid_parameter_handler)
244         ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
245                 "Invalid parameter handler was already set\n");
246
247     p_initterm_e = (void *) GetProcAddress(hcrt, "_initterm_e");
248     p_encode_pointer = (void *) GetProcAddress(hcrt, "_encode_pointer");
249     p_decode_pointer = (void *) GetProcAddress(hcrt, "_decode_pointer");
250     p_encoded_null = (void *) GetProcAddress(hcrt, "_encoded_null");
251     p_sys_nerr = (void *) GetProcAddress(hcrt, "_sys_nerr");
252     p__sys_nerr = (void *) GetProcAddress(hcrt, "__sys_nerr");
253     p_sys_errlist = (void *) GetProcAddress(hcrt, "_sys_errlist");
254     p__sys_errlist = (void *) GetProcAddress(hcrt, "__sys_errlist");
255     p_strtoi64 = (void *) GetProcAddress(hcrt, "_strtoi64");
256     p_strtoui64 = (void *) GetProcAddress(hcrt, "_strtoui64");
257
258     test__initterm_e();
259     test__encode_pointer();
260     test_error_messages();
261     test__strtoi64();
262 }