msvcp110: Add tr2_sys__Link implementation and test.
[wine.git] / dlls / msvcp120 / tests / msvcp120.c
blob77a6050e4b3ef1d97e7da9d151ab360cb253480e
1 /*
2 * Copyright 2014 Yifu Wang for ESRI
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
19 #include <locale.h>
20 #include <stdio.h>
21 #include <math.h>
22 #include <limits.h>
24 #include "wine/test.h"
25 #include "winbase.h"
27 static inline float __port_infinity(void)
29 static const unsigned __inf_bytes = 0x7f800000;
30 return *(const float *)&__inf_bytes;
32 #define INFINITY __port_infinity()
34 static inline float __port_nan(void)
36 static const unsigned __nan_bytes = 0x7fc00000;
37 return *(const float *)&__nan_bytes;
39 #define NAN __port_nan()
41 typedef int MSVCRT_long;
42 typedef unsigned char MSVCP_bool;
44 /* xtime */
45 typedef struct {
46 __time64_t sec;
47 MSVCRT_long nsec;
48 } xtime;
50 typedef struct {
51 unsigned page;
52 int mb_max;
53 int unk;
54 BYTE isleadbyte[32];
55 } _Cvtvec;
57 struct space_info {
58 ULONGLONG capacity;
59 ULONGLONG free;
60 ULONGLONG available;
63 enum file_type {
64 status_unknown, file_not_found, regular_file, directory_file,
65 symlink_file, block_file, character_file, fifo_file, socket_file,
66 type_unknown
69 static BOOL compare_float(float f, float g, unsigned int ulps)
71 int x = *(int *)&f;
72 int y = *(int *)&g;
74 if (x < 0)
75 x = INT_MIN - x;
76 if (y < 0)
77 y = INT_MIN - y;
79 if (abs(x - y) > ulps)
80 return FALSE;
82 return TRUE;
85 static inline const char* debugstr_longlong(ULONGLONG ll)
87 static char string[17];
88 if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
89 sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
90 else
91 sprintf(string, "%lx", (unsigned long)ll);
92 return string;
95 static char* (__cdecl *p_setlocale)(int, const char*);
96 static int (__cdecl *p__setmbcp)(int);
97 static int (__cdecl *p_isleadbyte)(int);
99 static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
100 static int (__cdecl *p_xtime_get)(xtime*, int);
101 static _Cvtvec* (__cdecl *p__Getcvt)(_Cvtvec*);
102 static void (CDECL *p__Call_once)(int *once, void (CDECL *func)(void));
103 static void (CDECL *p__Call_onceEx)(int *once, void (CDECL *func)(void*), void *argv);
104 static void (CDECL *p__Do_call)(void *this);
105 static short (__cdecl *p__Dtest)(double *d);
106 static short (__cdecl *p__Dscale)(double *d, int exp);
107 static short (__cdecl *p__FExp)(float *x, float y, int exp);
109 /* filesystem */
110 static ULONGLONG(__cdecl *p_tr2_sys__File_size)(char const*);
111 static ULONGLONG(__cdecl *p_tr2_sys__File_size_wchar)(WCHAR const*);
112 static int (__cdecl *p_tr2_sys__Equivalent)(char const*, char const*);
113 static int (__cdecl *p_tr2_sys__Equivalent_wchar)(WCHAR const*, WCHAR const*);
114 static char* (__cdecl *p_tr2_sys__Current_get)(char *);
115 static WCHAR* (__cdecl *p_tr2_sys__Current_get_wchar)(WCHAR *);
116 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set)(char const*);
117 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set_wchar)(WCHAR const*);
118 static int (__cdecl *p_tr2_sys__Make_dir)(char const*);
119 static int (__cdecl *p_tr2_sys__Make_dir_wchar)(WCHAR const*);
120 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir)(char const*);
121 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir_wchar)(WCHAR const*);
122 static int (__cdecl *p_tr2_sys__Copy_file)(char const*, char const*, MSVCP_bool);
123 static int (__cdecl *p_tr2_sys__Copy_file_wchar)(WCHAR const*, WCHAR const*, MSVCP_bool);
124 static int (__cdecl *p_tr2_sys__Rename)(char const*, char const*);
125 static int (__cdecl *p_tr2_sys__Rename_wchar)(WCHAR const*, WCHAR const*);
126 static struct space_info* (__cdecl *p_tr2_sys__Statvfs)(struct space_info*, char const*);
127 static struct space_info* (__cdecl *p_tr2_sys__Statvfs_wchar)(struct space_info*, WCHAR const*);
128 static enum file_type (__cdecl *p_tr2_sys__Stat)(char const*, int *);
129 static enum file_type (__cdecl *p_tr2_sys__Lstat)(char const*, int *);
130 static __int64 (__cdecl *p_tr2_sys__Last_write_time)(char const*);
131 static void (__cdecl *p_tr2_sys__Last_write_time_set)(char const*, __int64);
132 static void* (__cdecl *p_tr2_sys__Open_dir)(char*, char const*, int *, enum file_type*);
133 static char* (__cdecl *p_tr2_sys__Read_dir)(char*, void*, enum file_type*);
134 static void (__cdecl *p_tr2_sys__Close_dir)(void*);
135 static int (__cdecl *p_tr2_sys__Link)(char const*, char const*);
137 /* thrd */
138 typedef struct
140 HANDLE hnd;
141 DWORD id;
142 } _Thrd_t;
144 #define TIMEDELTA 250 /* 250 ms uncertainty allowed */
146 typedef int (__cdecl *_Thrd_start_t)(void*);
148 static int (__cdecl *p__Thrd_equal)(_Thrd_t, _Thrd_t);
149 static int (__cdecl *p__Thrd_lt)(_Thrd_t, _Thrd_t);
150 static void (__cdecl *p__Thrd_sleep)(const xtime*);
151 static _Thrd_t (__cdecl *p__Thrd_current)(void);
152 static int (__cdecl *p__Thrd_create)(_Thrd_t*, _Thrd_start_t, void*);
153 static int (__cdecl *p__Thrd_join)(_Thrd_t, int*);
155 #ifdef __i386__
156 static ULONGLONG (__cdecl *p_i386_Thrd_current)(void);
157 static _Thrd_t __cdecl i386_Thrd_current(void)
159 union {
160 _Thrd_t thr;
161 ULONGLONG ull;
162 } r;
163 r.ull = p_i386_Thrd_current();
164 return r.thr;
166 #endif
168 /* mtx */
169 typedef void *_Mtx_t;
170 static int (__cdecl *p__Mtx_init)(_Mtx_t*, int);
171 static void (__cdecl *p__Mtx_destroy)(_Mtx_t*);
172 static int (__cdecl *p__Mtx_lock)(_Mtx_t*);
173 static int (__cdecl *p__Mtx_unlock)(_Mtx_t*);
175 /* cnd */
176 typedef void *_Cnd_t;
178 static int (__cdecl *p__Cnd_init)(_Cnd_t*);
179 static void (__cdecl *p__Cnd_destroy)(_Cnd_t*);
180 static int (__cdecl *p__Cnd_wait)(_Cnd_t*, _Mtx_t*);
181 static int (__cdecl *p__Cnd_timedwait)(_Cnd_t*, _Mtx_t*, const xtime*);
182 static int (__cdecl *p__Cnd_broadcast)(_Cnd_t*);
183 static int (__cdecl *p__Cnd_signal)(_Cnd_t*);
186 static HMODULE msvcp;
187 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
188 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
189 static BOOL init(void)
191 HANDLE msvcr;
193 msvcp = LoadLibraryA("msvcp120.dll");
194 if(!msvcp)
196 win_skip("msvcp120.dll not installed\n");
197 return FALSE;
200 SET(p__Xtime_diff_to_millis2,
201 "_Xtime_diff_to_millis2");
202 SET(p_xtime_get,
203 "xtime_get");
204 SET(p__Getcvt,
205 "_Getcvt");
206 SET(p__Call_once,
207 "_Call_once");
208 SET(p__Call_onceEx,
209 "_Call_onceEx");
210 SET(p__Do_call,
211 "_Do_call");
212 SET(p__Dtest,
213 "_Dtest");
214 SET(p__Dscale,
215 "_Dscale");
216 SET(p__FExp,
217 "_FExp");
218 if(sizeof(void*) == 8) { /* 64-bit initialization */
219 SET(p_tr2_sys__File_size,
220 "?_File_size@sys@tr2@std@@YA_KPEBD@Z");
221 SET(p_tr2_sys__File_size_wchar,
222 "?_File_size@sys@tr2@std@@YA_KPEB_W@Z");
223 SET(p_tr2_sys__Equivalent,
224 "?_Equivalent@sys@tr2@std@@YAHPEBD0@Z");
225 SET(p_tr2_sys__Equivalent_wchar,
226 "?_Equivalent@sys@tr2@std@@YAHPEB_W0@Z");
227 SET(p_tr2_sys__Current_get,
228 "?_Current_get@sys@tr2@std@@YAPEADAEAY0BAE@D@Z");
229 SET(p_tr2_sys__Current_get_wchar,
230 "?_Current_get@sys@tr2@std@@YAPEA_WAEAY0BAE@_W@Z");
231 SET(p_tr2_sys__Current_set,
232 "?_Current_set@sys@tr2@std@@YA_NPEBD@Z");
233 SET(p_tr2_sys__Current_set_wchar,
234 "?_Current_set@sys@tr2@std@@YA_NPEB_W@Z");
235 SET(p_tr2_sys__Make_dir,
236 "?_Make_dir@sys@tr2@std@@YAHPEBD@Z");
237 SET(p_tr2_sys__Make_dir_wchar,
238 "?_Make_dir@sys@tr2@std@@YAHPEB_W@Z");
239 SET(p_tr2_sys__Remove_dir,
240 "?_Remove_dir@sys@tr2@std@@YA_NPEBD@Z");
241 SET(p_tr2_sys__Remove_dir_wchar,
242 "?_Remove_dir@sys@tr2@std@@YA_NPEB_W@Z");
243 SET(p_tr2_sys__Copy_file,
244 "?_Copy_file@sys@tr2@std@@YAHPEBD0_N@Z");
245 SET(p_tr2_sys__Copy_file_wchar,
246 "?_Copy_file@sys@tr2@std@@YAHPEB_W0_N@Z");
247 SET(p_tr2_sys__Rename,
248 "?_Rename@sys@tr2@std@@YAHPEBD0@Z");
249 SET(p_tr2_sys__Rename_wchar,
250 "?_Rename@sys@tr2@std@@YAHPEB_W0@Z");
251 SET(p_tr2_sys__Statvfs,
252 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEBD@Z");
253 SET(p_tr2_sys__Statvfs_wchar,
254 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEB_W@Z");
255 SET(p_tr2_sys__Stat,
256 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
257 SET(p_tr2_sys__Lstat,
258 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
259 SET(p_tr2_sys__Last_write_time,
260 "?_Last_write_time@sys@tr2@std@@YA_JPEBD@Z");
261 SET(p_tr2_sys__Last_write_time_set,
262 "?_Last_write_time@sys@tr2@std@@YAXPEBD_J@Z");
263 SET(p_tr2_sys__Open_dir,
264 "?_Open_dir@sys@tr2@std@@YAPEAXAEAY0BAE@DPEBDAEAHAEAW4file_type@123@@Z");
265 SET(p_tr2_sys__Read_dir,
266 "?_Read_dir@sys@tr2@std@@YAPEADAEAY0BAE@DPEAXAEAW4file_type@123@@Z");
267 SET(p_tr2_sys__Close_dir,
268 "?_Close_dir@sys@tr2@std@@YAXPEAX@Z");
269 SET(p_tr2_sys__Link,
270 "?_Link@sys@tr2@std@@YAHPEBD0@Z");
271 SET(p__Thrd_current,
272 "_Thrd_current");
273 } else {
274 SET(p_tr2_sys__File_size,
275 "?_File_size@sys@tr2@std@@YA_KPBD@Z");
276 SET(p_tr2_sys__File_size_wchar,
277 "?_File_size@sys@tr2@std@@YA_KPB_W@Z");
278 SET(p_tr2_sys__Equivalent,
279 "?_Equivalent@sys@tr2@std@@YAHPBD0@Z");
280 SET(p_tr2_sys__Equivalent_wchar,
281 "?_Equivalent@sys@tr2@std@@YAHPB_W0@Z");
282 SET(p_tr2_sys__Current_get,
283 "?_Current_get@sys@tr2@std@@YAPADAAY0BAE@D@Z");
284 SET(p_tr2_sys__Current_get_wchar,
285 "?_Current_get@sys@tr2@std@@YAPA_WAAY0BAE@_W@Z");
286 SET(p_tr2_sys__Current_set,
287 "?_Current_set@sys@tr2@std@@YA_NPBD@Z");
288 SET(p_tr2_sys__Current_set_wchar,
289 "?_Current_set@sys@tr2@std@@YA_NPB_W@Z");
290 SET(p_tr2_sys__Make_dir,
291 "?_Make_dir@sys@tr2@std@@YAHPBD@Z");
292 SET(p_tr2_sys__Make_dir_wchar,
293 "?_Make_dir@sys@tr2@std@@YAHPB_W@Z");
294 SET(p_tr2_sys__Remove_dir,
295 "?_Remove_dir@sys@tr2@std@@YA_NPBD@Z");
296 SET(p_tr2_sys__Remove_dir_wchar,
297 "?_Remove_dir@sys@tr2@std@@YA_NPB_W@Z");
298 SET(p_tr2_sys__Copy_file,
299 "?_Copy_file@sys@tr2@std@@YAHPBD0_N@Z");
300 SET(p_tr2_sys__Copy_file_wchar,
301 "?_Copy_file@sys@tr2@std@@YAHPB_W0_N@Z");
302 SET(p_tr2_sys__Rename,
303 "?_Rename@sys@tr2@std@@YAHPBD0@Z");
304 SET(p_tr2_sys__Rename_wchar,
305 "?_Rename@sys@tr2@std@@YAHPB_W0@Z");
306 SET(p_tr2_sys__Statvfs,
307 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z");
308 SET(p_tr2_sys__Statvfs_wchar,
309 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PB_W@Z");
310 SET(p_tr2_sys__Stat,
311 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
312 SET(p_tr2_sys__Lstat,
313 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
314 SET(p_tr2_sys__Last_write_time,
315 "?_Last_write_time@sys@tr2@std@@YA_JPBD@Z");
316 SET(p_tr2_sys__Last_write_time_set,
317 "?_Last_write_time@sys@tr2@std@@YAXPBD_J@Z");
318 SET(p_tr2_sys__Open_dir,
319 "?_Open_dir@sys@tr2@std@@YAPAXAAY0BAE@DPBDAAHAAW4file_type@123@@Z");
320 SET(p_tr2_sys__Read_dir,
321 "?_Read_dir@sys@tr2@std@@YAPADAAY0BAE@DPAXAAW4file_type@123@@Z");
322 SET(p_tr2_sys__Close_dir,
323 "?_Close_dir@sys@tr2@std@@YAXPAX@Z");
324 SET(p_tr2_sys__Link,
325 "?_Link@sys@tr2@std@@YAHPBD0@Z");
326 #ifdef __i386__
327 SET(p_i386_Thrd_current,
328 "_Thrd_current");
329 p__Thrd_current = i386_Thrd_current;
330 #else
331 SET(p__Thrd_current,
332 "_Thrd_current");
333 #endif
335 SET(p__Thrd_equal,
336 "_Thrd_equal");
337 SET(p__Thrd_lt,
338 "_Thrd_lt");
339 SET(p__Thrd_sleep,
340 "_Thrd_sleep");
341 SET(p__Thrd_create,
342 "_Thrd_create");
343 SET(p__Thrd_join,
344 "_Thrd_join");
346 SET(p__Mtx_init,
347 "_Mtx_init");
348 SET(p__Mtx_destroy,
349 "_Mtx_destroy");
350 SET(p__Mtx_lock,
351 "_Mtx_lock");
352 SET(p__Mtx_unlock,
353 "_Mtx_unlock");
355 SET(p__Cnd_init,
356 "_Cnd_init");
357 SET(p__Cnd_destroy,
358 "_Cnd_destroy");
359 SET(p__Cnd_wait,
360 "_Cnd_wait");
361 SET(p__Cnd_timedwait,
362 "_Cnd_timedwait");
363 SET(p__Cnd_broadcast,
364 "_Cnd_broadcast");
365 SET(p__Cnd_signal,
366 "_Cnd_signal");
368 msvcr = GetModuleHandleA("msvcr120.dll");
369 p_setlocale = (void*)GetProcAddress(msvcr, "setlocale");
370 p__setmbcp = (void*)GetProcAddress(msvcr, "_setmbcp");
371 p_isleadbyte = (void*)GetProcAddress(msvcr, "isleadbyte");
372 return TRUE;
375 static void test__Xtime_diff_to_millis2(void)
377 struct {
378 __time64_t sec_before;
379 MSVCRT_long nsec_before;
380 __time64_t sec_after;
381 MSVCRT_long nsec_after;
382 MSVCRT_long expect;
383 } tests[] = {
384 {1, 0, 2, 0, 1000},
385 {0, 1000000000, 0, 2000000000, 1000},
386 {1, 100000000, 2, 100000000, 1000},
387 {1, 100000000, 1, 200000000, 100},
388 {0, 0, 0, 1000000000, 1000},
389 {0, 0, 0, 1200000000, 1200},
390 {0, 0, 0, 1230000000, 1230},
391 {0, 0, 0, 1234000000, 1234},
392 {0, 0, 0, 1234100000, 1235},
393 {0, 0, 0, 1234900000, 1235},
394 {0, 0, 0, 1234010000, 1235},
395 {0, 0, 0, 1234090000, 1235},
396 {0, 0, 0, 1234000001, 1235},
397 {0, 0, 0, 1234000009, 1235},
398 {0, 0, -1, 0, 0},
399 {0, 0, 0, -10000000, 0},
400 {0, 0, -1, -100000000, 0},
401 {-1, 0, 0, 0, 1000},
402 {0, -100000000, 0, 0, 100},
403 {-1, -100000000, 0, 0, 1100},
404 {0, 0, -1, 2000000000, 1000},
405 {0, 0, -2, 2000000000, 0},
406 {0, 0, -2, 2100000000, 100}
408 int i;
409 MSVCRT_long ret;
410 xtime t1, t2;
412 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); ++ i)
414 t1.sec = tests[i].sec_before;
415 t1.nsec = tests[i].nsec_before;
416 t2.sec = tests[i].sec_after;
417 t2.nsec = tests[i].nsec_after;
418 ret = p__Xtime_diff_to_millis2(&t2, &t1);
419 ok(ret == tests[i].expect,
420 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
421 i, tests[i].expect, ret);
425 static void test_xtime_get(void)
427 static const MSVCRT_long tests[] = {1, 50, 100, 200, 500};
428 MSVCRT_long diff;
429 xtime before, after;
430 int i;
432 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i ++)
434 p_xtime_get(&before, 1);
435 Sleep(tests[i]);
436 p_xtime_get(&after, 1);
438 diff = p__Xtime_diff_to_millis2(&after, &before);
440 ok(diff >= tests[i],
441 "xtime_get() not functioning correctly, test: %d, expect: ge %d, got: %d\n",
442 i, tests[i], diff);
445 /* Test parameter and return value */
446 before.sec = 0xdeadbeef, before.nsec = 0xdeadbeef;
447 i = p_xtime_get(&before, 0);
448 ok(i == 0, "expect xtime_get() to return 0, got: %d\n", i);
449 ok(before.sec == 0xdeadbeef && before.nsec == 0xdeadbeef,
450 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
452 before.sec = 0xdeadbeef, before.nsec = 0xdeadbeef;
453 i = p_xtime_get(&before, 1);
454 ok(i == 1, "expect xtime_get() to return 1, got: %d\n", i);
455 ok(before.sec != 0xdeadbeef && before.nsec != 0xdeadbeef,
456 "xtime_get() should have modified the xtime struct with the given option\n");
459 static void test__Getcvt(void)
461 _Cvtvec cvtvec;
462 int i;
464 p__Getcvt(&cvtvec);
465 ok(cvtvec.page == 0, "cvtvec.page = %d\n", cvtvec.page);
466 ok(cvtvec.mb_max == 1, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
467 todo_wine ok(cvtvec.unk == 1, "cvtvec.unk = %d\n", cvtvec.unk);
468 for(i=0; i<32; i++)
469 ok(cvtvec.isleadbyte[i] == 0, "cvtvec.isleadbyte[%d] = %x\n", i, cvtvec.isleadbyte[i]);
471 if(!p_setlocale(LC_ALL, ".936")) {
472 win_skip("_Getcvt tests\n");
473 return;
475 p__Getcvt(&cvtvec);
476 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
477 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
478 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
479 for(i=0; i<32; i++)
480 ok(cvtvec.isleadbyte[i] == 0, "cvtvec.isleadbyte[%d] = %x\n", i, cvtvec.isleadbyte[i]);
482 p__setmbcp(936);
483 p__Getcvt(&cvtvec);
484 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
485 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
486 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
487 for(i=0; i<32; i++) {
488 BYTE b = 0;
489 int j;
491 for(j=0; j<8; j++)
492 b |= (p_isleadbyte(i*8+j) ? 1 : 0) << j;
493 ok(cvtvec.isleadbyte[i] ==b, "cvtvec.isleadbyte[%d] = %x (%x)\n", i, cvtvec.isleadbyte[i], b);
497 static int cnt;
498 static int once;
500 static void __cdecl call_once_func(void)
502 ok(!once, "once != 0\n");
503 cnt += 0x10000;
506 static void __cdecl call_once_ex_func(void *arg)
508 int *i = arg;
510 ok(!once, "once != 0\n");
511 (*i)++;
514 static DWORD WINAPI call_once_thread(void *arg)
516 p__Call_once(&once, call_once_func);
517 return 0;
520 static DWORD WINAPI call_once_ex_thread(void *arg)
522 p__Call_onceEx(&once, call_once_ex_func, &cnt);
523 return 0;
526 static void test__Call_once(void)
528 HANDLE h[4];
529 int i;
531 for(i=0; i<4; i++)
532 h[i] = CreateThread(NULL, 0, call_once_thread, &once, 0, NULL);
533 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
534 "error waiting for all threads to finish\n");
535 ok(cnt == 0x10000, "cnt = %x\n", cnt);
536 ok(once == 1, "once = %x\n", once);
538 once = cnt = 0;
539 for(i=0; i<4; i++)
540 h[i] = CreateThread(NULL, 0, call_once_ex_thread, &once, 0, NULL);
541 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
542 "error waiting for all threads to finish\n");
543 ok(cnt == 1, "cnt = %x\n", cnt);
544 ok(once == 1, "once = %x\n", once);
547 static void **vtbl_func0;
548 #ifdef __i386__
549 /* TODO: this should be a __thiscall function */
550 static void __stdcall thiscall_func(void)
552 cnt = 1;
554 #else
555 static void __cdecl thiscall_func(void *this)
557 ok(this == &vtbl_func0, "incorrect this value\n");
558 cnt = 1;
560 #endif
562 static void test__Do_call(void)
564 void *pfunc = thiscall_func;
566 cnt = 0;
567 vtbl_func0 = &pfunc;
568 p__Do_call(&vtbl_func0);
569 ok(cnt == 1, "func was not called\n");
572 static void test__Dtest(void)
574 double d;
575 short ret;
577 d = 0;
578 ret = p__Dtest(&d);
579 ok(ret == FP_ZERO, "_Dtest(0) returned %x\n", ret);
581 d = 1;
582 ret = p__Dtest(&d);
583 ok(ret == FP_NORMAL, "_Dtest(1) returned %x\n", ret);
585 d = -1;
586 ret = p__Dtest(&d);
587 ok(ret == FP_NORMAL, "_Dtest(-1) returned %x\n", ret);
589 d = INFINITY;
590 ret = p__Dtest(&d);
591 ok(ret == FP_INFINITE, "_Dtest(INF) returned %x\n", ret);
593 d = NAN;
594 ret = p__Dtest(&d);
595 ok(ret == FP_NAN, "_Dtest(NAN) returned %x\n", ret);
598 static void test__Dscale(void)
600 double d;
601 short ret;
603 d = 0;
604 ret = p__Dscale(&d, 0);
605 ok(d == 0, "d = %f\n", d);
606 ok(ret == FP_ZERO, "ret = %x\n", ret);
608 d = 0;
609 ret = p__Dscale(&d, 1);
610 ok(d == 0, "d = %f\n", d);
611 ok(ret == FP_ZERO, "ret = %x\n", ret);
613 d = 0;
614 ret = p__Dscale(&d, -1);
615 ok(d == 0, "d = %f\n", d);
616 ok(ret == FP_ZERO, "ret = %x\n", ret);
618 d = 1;
619 ret = p__Dscale(&d, 0);
620 ok(d == 1, "d = %f\n", d);
621 ok(ret == FP_NORMAL, "ret = %x\n", ret);
623 d = 1;
624 ret = p__Dscale(&d, 1);
625 ok(d == 2, "d = %f\n", d);
626 ok(ret == FP_NORMAL, "ret = %x\n", ret);
628 d = 1;
629 ret = p__Dscale(&d, -1);
630 ok(d == 0.5, "d = %f\n", d);
631 ok(ret == FP_NORMAL, "ret = %x\n", ret);
633 d = 1;
634 ret = p__Dscale(&d, -99999);
635 ok(d == 0, "d = %f\n", d);
636 ok(ret == FP_ZERO, "ret = %x\n", ret);
638 d = 1;
639 ret = p__Dscale(&d, 999999);
640 ok(d == INFINITY, "d = %f\n", d);
641 ok(ret == FP_INFINITE, "ret = %x\n", ret);
643 d = NAN;
644 ret = p__Dscale(&d, 1);
645 ok(ret == FP_NAN, "ret = %x\n", ret);
648 static void test__FExp(void)
650 float d;
651 short ret;
653 d = 0;
654 ret = p__FExp(&d, 0, 0);
655 ok(d == 0, "d = %f\n", d);
656 ok(ret == FP_ZERO, "ret = %x\n", ret);
658 d = 0;
659 ret = p__FExp(&d, 1, 0);
660 ok(d == 1.0, "d = %f\n", d);
661 ok(ret == FP_NORMAL, "ret = %x\n", ret);
663 d = 0;
664 ret = p__FExp(&d, 1, 1);
665 ok(d == 2.0, "d = %f\n", d);
666 ok(ret == FP_NORMAL, "ret = %x\n", ret);
668 d = 0;
669 ret = p__FExp(&d, 1, 2);
670 ok(d == 4.0, "d = %f\n", d);
671 ok(ret == FP_NORMAL, "ret = %x\n", ret);
673 d = 0;
674 ret = p__FExp(&d, 10, 0);
675 ok(d == 10.0, "d = %f\n", d);
676 ok(ret == FP_NORMAL, "ret = %x\n", ret);
678 d = 1;
679 ret = p__FExp(&d, 0, 0);
680 ok(d == 0, "d = %f\n", d);
681 ok(ret == FP_ZERO, "ret = %x\n", ret);
683 d = 1;
684 ret = p__FExp(&d, 1, 0);
685 ok(compare_float(d, 2.7182817, 4), "d = %f\n", d);
686 ok(ret == FP_NORMAL, "ret = %x\n", ret);
688 d = 9e20;
689 ret = p__FExp(&d, 0, 0);
690 ok(d == 0, "d = %f\n", d);
691 ok(ret == FP_ZERO, "ret = %x\n", ret);
693 d = 90;
694 ret = p__FExp(&d, 1, 0);
695 ok(ret == FP_INFINITE, "ret = %x\n", ret);
697 d = 90;
698 ret = p__FExp(&d, 1, -50);
699 ok(compare_float(d, 1.0839359e+024, 4), "d = %g\n", d);
700 ok(ret == FP_NORMAL, "ret = %x\n", ret);
703 static void test_tr2_sys__File_size(void)
705 ULONGLONG val;
706 HANDLE file;
707 LARGE_INTEGER file_size;
708 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
709 CreateDirectoryA("tr2_test_dir", NULL);
711 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
712 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
713 file_size.QuadPart = 7;
714 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
715 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
716 CloseHandle(file);
717 val = p_tr2_sys__File_size("tr2_test_dir/f1");
718 ok(val == 7, "file_size is %s\n", debugstr_longlong(val));
719 val = p_tr2_sys__File_size_wchar(testW);
720 ok(val == 7, "file_size is %s\n", debugstr_longlong(val));
722 file = CreateFileA("tr2_test_dir/f2", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
723 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
724 CloseHandle(file);
725 val = p_tr2_sys__File_size("tr2_test_dir/f2");
726 ok(val == 0, "file_size is %s\n", debugstr_longlong(val));
728 val = p_tr2_sys__File_size("tr2_test_dir");
729 ok(val == 0, "file_size is %s\n", debugstr_longlong(val));
731 errno = 0xdeadbeef;
732 val = p_tr2_sys__File_size("tr2_test_dir/not_exists_file");
733 ok(val == 0, "file_size is %s\n", debugstr_longlong(val));
734 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
736 errno = 0xdeadbeef;
737 val = p_tr2_sys__File_size(NULL);
738 ok(val == 0, "file_size is %s\n", debugstr_longlong(val));
739 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
741 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
742 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
743 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
746 static void test_tr2_sys__Equivalent(void)
748 int val, i;
749 HANDLE file;
750 char temp_path[MAX_PATH], current_path[MAX_PATH];
751 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
752 WCHAR testW2[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','2',0};
753 struct {
754 char const *path1;
755 char const *path2;
756 int equivalent;
757 } tests[] = {
758 { NULL, NULL, -1 },
759 { NULL, "f1", -1 },
760 { "f1", NULL, -1 },
761 { "f1", "tr2_test_dir", -1 },
762 { "tr2_test_dir", "f1", -1 },
763 { "tr2_test_dir", "tr2_test_dir", -1 },
764 { "tr2_test_dir/./f1", "tr2_test_dir/f2", 0 },
765 { "tr2_test_dir/f1" , "tr2_test_dir/f1", 1 },
766 { "not_exists_file" , "tr2_test_dir/f1", 0 },
767 { "tr2_test_dir\\f1" , "tr2_test_dir/./f1", 1 },
768 { "not_exists_file" , "not_exists_file", -1 },
769 { "tr2_test_dir/f1" , "not_exists_file", 0 },
770 { "tr2_test_dir/../tr2_test_dir/f1", "tr2_test_dir/f1", 1 }
773 memset(current_path, 0, MAX_PATH);
774 GetCurrentDirectoryA(MAX_PATH, current_path);
775 memset(temp_path, 0, MAX_PATH);
776 GetTempPathA(MAX_PATH, temp_path);
777 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
778 CreateDirectoryA("tr2_test_dir", NULL);
780 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
781 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
782 CloseHandle(file);
783 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
784 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
785 CloseHandle(file);
787 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
788 errno = 0xdeadbeef;
789 val = p_tr2_sys__Equivalent(tests[i].path1, tests[i].path2);
790 ok(tests[i].equivalent == val, "tr2_sys__Equivalent(): test %d expect: %d, got %d\n", i+1, tests[i].equivalent, val);
791 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
794 val = p_tr2_sys__Equivalent_wchar(testW, testW);
795 ok(val == 1, "tr2_sys__Equivalent(): expect: 1, got %d\n", val);
796 val = p_tr2_sys__Equivalent_wchar(testW, testW2);
797 ok(val == 0, "tr2_sys__Equivalent(): expect: 0, got %d\n", val);
799 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
800 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
801 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
802 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
805 static void test_tr2_sys__Current_get(void)
807 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
808 char *temp;
809 WCHAR temp_path_wchar[MAX_PATH], current_path_wchar[MAX_PATH];
810 WCHAR *temp_wchar;
811 memset(origin_path, 0, MAX_PATH);
812 GetCurrentDirectoryA(MAX_PATH, origin_path);
813 memset(temp_path, 0, MAX_PATH);
814 GetTempPathA(MAX_PATH, temp_path);
816 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
817 memset(current_path, 0, MAX_PATH);
818 temp = p_tr2_sys__Current_get(current_path);
819 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
820 temp[strlen(temp)] = '\\';
821 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
823 GetTempPathW(MAX_PATH, temp_path_wchar);
824 ok(SetCurrentDirectoryW(temp_path_wchar), "SetCurrentDirectoryW to temp_path_wchar failed\n");
825 memset(current_path_wchar, 0, MAX_PATH);
826 temp_wchar = p_tr2_sys__Current_get_wchar(current_path_wchar);
827 ok(temp_wchar == current_path_wchar, "p_tr2_sys__Current_get_wchar returned different buffer\n");
828 temp_wchar[wcslen(temp_wchar)] = '\\';
829 ok(!wcscmp(temp_path_wchar, current_path_wchar), "test_tr2_sys__Current_get(): expect: %s, got %s\n", wine_dbgstr_w(temp_path_wchar), wine_dbgstr_w(current_path_wchar));
831 ok(SetCurrentDirectoryA(origin_path), "SetCurrentDirectoryA to origin_path failed\n");
832 memset(current_path, 0, MAX_PATH);
833 temp = p_tr2_sys__Current_get(current_path);
834 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
835 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
838 static void test_tr2_sys__Current_set(void)
840 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
841 char *temp;
842 WCHAR testW[] = {'.','/',0};
843 memset(temp_path, 0, MAX_PATH);
844 GetTempPathA(MAX_PATH, temp_path);
845 memset(origin_path, 0, MAX_PATH);
846 GetCurrentDirectoryA(MAX_PATH, origin_path);
847 temp = p_tr2_sys__Current_get(origin_path);
848 ok(temp == origin_path, "p_tr2_sys__Current_get returned different buffer\n");
850 ok(p_tr2_sys__Current_set(temp_path), "p_tr2_sys__Current_set to temp_path failed\n");
851 memset(current_path, 0, MAX_PATH);
852 temp = p_tr2_sys__Current_get(current_path);
853 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
854 temp[strlen(temp)] = '\\';
855 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
857 ok(p_tr2_sys__Current_set_wchar(testW), "p_tr2_sys__Current_set_wchar to temp_path failed\n");
858 memset(current_path, 0, MAX_PATH);
859 temp = p_tr2_sys__Current_get(current_path);
860 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
861 temp[strlen(temp)] = '\\';
862 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
864 errno = 0xdeadbeef;
865 ok(!p_tr2_sys__Current_set("not_exisist_dir"), "p_tr2_sys__Current_set to not_exist_dir succeed\n");
866 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
868 errno = 0xdeadbeef;
869 ok(!p_tr2_sys__Current_set("??invalid_name>>"), "p_tr2_sys__Current_set to ??invalid_name>> succeed\n");
870 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
872 ok(p_tr2_sys__Current_set(origin_path), "p_tr2_sys__Current_set to origin_path failed\n");
873 memset(current_path, 0, MAX_PATH);
874 temp = p_tr2_sys__Current_get(current_path);
875 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
876 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
879 static void test_tr2_sys__Make_dir(void)
881 int ret, i;
882 WCHAR testW[] = {'w','d',0};
883 struct {
884 char const *path;
885 int val;
886 } tests[] = {
887 { "tr2_test_dir", 1 },
888 { "tr2_test_dir", 0 },
889 { NULL, -1 },
890 { "??invalid_name>>", -1 }
893 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
894 errno = 0xdeadbeef;
895 ret = p_tr2_sys__Make_dir(tests[i].path);
896 ok(ret == tests[i].val, "tr2_sys__Make_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
897 ok(errno == 0xdeadbeef, "tr2_sys__Make_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
899 ret = p_tr2_sys__Make_dir_wchar(testW);
900 ok(ret == 1, "tr2_sys__Make_dir(): expect: 1, got %d\n", ret);
902 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
903 ok(p_tr2_sys__Remove_dir_wchar(testW), "expect wd to exist\n");
906 static void test_tr2_sys__Remove_dir(void)
908 MSVCP_bool ret;
909 int i;
910 struct {
911 char const *path;
912 MSVCP_bool val;
913 } tests[] = {
914 { "tr2_test_dir", TRUE },
915 { "tr2_test_dir", FALSE },
916 { NULL, FALSE },
917 { "??invalid_name>>", FALSE }
920 ok(p_tr2_sys__Make_dir("tr2_test_dir"), "tr2_sys__Make_dir() failed\n");
922 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
923 errno = 0xdeadbeef;
924 ret = p_tr2_sys__Remove_dir(tests[i].path);
925 ok(ret == tests[i].val, "test_tr2_sys__Remove_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
926 ok(errno == 0xdeadbeef, "test_tr2_sys__Remove_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
930 static void test_tr2_sys__Copy_file(void)
932 HANDLE file;
933 int ret, i;
934 LARGE_INTEGER file_size;
935 WCHAR testW[] = {'f','1',0}, testW2[] = {'f','w',0};
936 struct {
937 char const *source;
938 char const *dest;
939 MSVCP_bool fail_if_exists;
940 int last_error;
941 int last_error2;
942 MSVCP_bool is_todo;
943 } tests[] = {
944 { "f1", "f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
945 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
946 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_FILE_EXISTS, ERROR_FILE_EXISTS, FALSE },
947 { "f1", "tr2_test_dir\\f1_copy", FALSE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
948 { "tr2_test_dir", "f1", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED, FALSE },
949 { "tr2_test_dir", "tr2_test_dir_copy", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED, FALSE },
950 { NULL, "f1", TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER, TRUE },
951 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER, TRUE },
952 { "not_exist", "tr2_test_dir", TRUE, ERROR_FILE_NOT_FOUND, ERROR_FILE_NOT_FOUND, FALSE },
953 { "f1", "not_exist_dir\\f1_copy", TRUE, ERROR_PATH_NOT_FOUND, ERROR_FILE_NOT_FOUND, FALSE },
954 { "f1", "tr2_test_dir", TRUE, ERROR_ACCESS_DENIED, ERROR_FILE_EXISTS, FALSE }
957 ret = p_tr2_sys__Make_dir("tr2_test_dir");
958 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
959 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
960 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
961 file_size.QuadPart = 7;
962 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
963 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
964 CloseHandle(file);
966 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
967 errno = 0xdeadbeef;
968 ret = p_tr2_sys__Copy_file(tests[i].source, tests[i].dest, tests[i].fail_if_exists);
969 if(tests[i].is_todo)
970 todo_wine ok(ret == tests[i].last_error || ret == tests[i].last_error2,
971 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n",
972 i+1, tests[i].last_error, ret);
973 else
974 ok(ret == tests[i].last_error || ret == tests[i].last_error2,
975 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n",
976 i+1, tests[i].last_error, ret);
977 ok(errno == 0xdeadbeef, "test_tr2_sys__Copy_file(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
978 if(ret == ERROR_SUCCESS)
979 ok(p_tr2_sys__File_size(tests[i].source) == p_tr2_sys__File_size(tests[i].dest),
980 "test_tr2_sys__Copy_file(): test %d failed, two files' size are not equal\n", i+1);
982 ret = p_tr2_sys__Copy_file_wchar(testW, testW2, TRUE);
983 ok(ret == ERROR_SUCCESS, "test_tr2_sys__Copy_file_wchar() expect ERROR_SUCCESS, got %d\n", ret);
985 ok(DeleteFileA("f1"), "expect f1 to exist\n");
986 ok(DeleteFileW(testW2), "expect fw to exist\n");
987 ok(DeleteFileA("f1_copy"), "expect f1_copy to exist\n");
988 ok(DeleteFileA("tr2_test_dir/f1_copy"), "expect tr2_test_dir/f1 to exist\n");
989 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
990 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
993 static void test_tr2_sys__Rename(void)
995 int ret, i;
996 HANDLE file, h1, h2;
997 BY_HANDLE_FILE_INFORMATION info1, info2;
998 char temp_path[MAX_PATH], current_path[MAX_PATH];
999 LARGE_INTEGER file_size;
1000 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
1001 WCHAR testW2[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','w',0};
1002 struct {
1003 char const *old_path;
1004 char const *new_path;
1005 int val;
1006 } tests[] = {
1007 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_SUCCESS },
1008 { "tr2_test_dir\\f1", NULL, ERROR_INVALID_PARAMETER },
1009 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND },
1010 { NULL, "tr2_test_dir\\NULL_rename", ERROR_INVALID_PARAMETER },
1011 { "tr2_test_dir\\f1_rename", "tr2_test_dir\\??invalid_name>>", ERROR_INVALID_NAME },
1012 { "tr2_test_dir\\not_exist_file", "tr2_test_dir\\not_exist_rename", ERROR_FILE_NOT_FOUND }
1015 memset(current_path, 0, MAX_PATH);
1016 GetCurrentDirectoryA(MAX_PATH, current_path);
1017 memset(temp_path, 0, MAX_PATH);
1018 GetTempPathA(MAX_PATH, temp_path);
1019 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1020 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1022 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1023 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1024 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1025 CloseHandle(file);
1027 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1");
1028 todo_wine ok(ERROR_SUCCESS == ret, "test_tr2_sys__Rename(): expect: ERROR_SUCCESS, got %d\n", ret);
1029 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1030 errno = 0xdeadbeef;
1031 if(tests[i].val == ERROR_SUCCESS) {
1032 h1 = CreateFileA(tests[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1033 NULL, OPEN_EXISTING, 0, 0);
1034 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1035 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1036 CloseHandle(h1);
1038 SetLastError(0xdeadbeef);
1039 ret = p_tr2_sys__Rename(tests[i].old_path, tests[i].new_path);
1040 ok(ret == tests[i].val, "test_tr2_sys__Rename(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1041 ok(errno == 0xdeadbeef, "test_tr2_sys__Rename(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1042 if(ret == ERROR_SUCCESS) {
1043 h2 = CreateFileA(tests[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1044 NULL, OPEN_EXISTING, 0, 0);
1045 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1046 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1047 CloseHandle(h2);
1048 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1049 && info1.nFileIndexLow == info2.nFileIndexLow,
1050 "test_tr2_sys__Rename(): test %d expect two files equivalent\n", i+1);
1054 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1055 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1056 file_size.QuadPart = 7;
1057 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1058 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1059 CloseHandle(file);
1060 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1_rename");
1061 ok(ret == ERROR_ALREADY_EXISTS, "test_tr2_sys__Rename(): expect: ERROR_ALREADY_EXISTS, got %d\n", ret);
1062 ok(p_tr2_sys__File_size("tr2_test_dir\\f1") == 7, "test_tr2_sys__Rename(): expect: 7, got %s\n", debugstr_longlong(p_tr2_sys__File_size("tr2_test_dir\\f1")));
1063 ok(p_tr2_sys__File_size("tr2_test_dir\\f1_rename") == 0, "test_tr2_sys__Rename(): expect: 0, got %s\n",debugstr_longlong(p_tr2_sys__File_size("tr2_test_dir\\f1_rename")));
1064 ret = p_tr2_sys__Rename_wchar(testW, testW2);
1065 ok(ret == ERROR_SUCCESS, "tr2_sys__Rename_wchar(): expect: ERROR_SUCCESS, got %d\n", ret);
1067 ok(DeleteFileW(testW2), "expect fw to exist\n");
1068 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1069 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1070 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect %d got %d\n", 1, ret);
1071 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1074 static void test_tr2_sys__Statvfs(void)
1076 struct space_info info;
1077 char current_path[MAX_PATH];
1078 WCHAR current_path_wchar[MAX_PATH];
1079 memset(current_path, 0, MAX_PATH);
1080 p_tr2_sys__Current_get(current_path);
1081 memset(current_path_wchar, 0, MAX_PATH);
1082 p_tr2_sys__Current_get_wchar(current_path_wchar);
1084 p_tr2_sys__Statvfs(&info, current_path);
1085 ok(info.capacity >= info.free, "test_tr2_sys__Statvfs(): info.capacity < info.free\n");
1086 ok(info.free >= info.available, "test_tr2_sys__Statvfs(): info.free < info.available\n");
1088 p_tr2_sys__Statvfs_wchar(&info, current_path_wchar);
1089 ok(info.capacity >= info.free, "tr2_sys__Statvfs_wchar(): info.capacity < info.free\n");
1090 ok(info.free >= info.available, "tr2_sys__Statvfs_wchar(): info.free < info.available\n");
1092 p_tr2_sys__Statvfs(&info, NULL);
1093 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1094 0, debugstr_longlong(info.available));
1095 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1096 0, debugstr_longlong(info.capacity));
1097 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1098 0, debugstr_longlong(info.free));
1100 p_tr2_sys__Statvfs(&info, "not_exist");
1101 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1102 0, debugstr_longlong(info.available));
1103 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1104 0, debugstr_longlong(info.capacity));
1105 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1106 0, debugstr_longlong(info.free));
1109 static void test_tr2_sys__Stat(void)
1111 int i, err_code, ret;
1112 HANDLE file;
1113 enum file_type val;
1114 struct {
1115 char const *path;
1116 enum file_type ret;
1117 int err_code;
1118 int is_todo;
1119 } tests[] = {
1120 { NULL, status_unknown, ERROR_INVALID_PARAMETER, FALSE },
1121 { "tr2_test_dir", directory_file, ERROR_SUCCESS, FALSE },
1122 { "tr2_test_dir\\f1", regular_file, ERROR_SUCCESS, FALSE },
1123 { "tr2_test_dir\\not_exist_file ", file_not_found, ERROR_SUCCESS, FALSE },
1124 { "tr2_test_dir\\??invalid_name>>", file_not_found, ERROR_SUCCESS, FALSE },
1125 { "tr2_test_dir\\f1_link" , regular_file, ERROR_SUCCESS, TRUE },
1126 { "tr2_test_dir\\dir_link", directory_file, ERROR_SUCCESS, TRUE },
1129 CreateDirectoryA("tr2_test_dir", NULL);
1130 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1131 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1132 ok(CloseHandle(file), "CloseHandle\n");
1133 SetLastError(0xdeadbeef);
1134 ret = CreateSymbolicLinkA("tr2_test_dir/f1_link", "tr2_test_dir/f1", 0);
1135 if(!ret && (GetLastError()==ERROR_PRIVILEGE_NOT_HELD||GetLastError()==ERROR_INVALID_FUNCTION)) {
1136 tests[5].ret = tests[6].ret = file_not_found;
1137 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1138 }else {
1139 ok(ret, "CreateSymbolicLinkA failed\n");
1140 ok(CreateSymbolicLinkA("tr2_test_dir/dir_link", "tr2_test_dir", 1), "CreateSymbolicLinkA failed\n");
1143 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1144 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
1145 NMPWAIT_USE_DEFAULT_WAIT, NULL);
1146 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1147 err_code = 0xdeadbeef;
1148 val = p_tr2_sys__Stat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1149 todo_wine ok(regular_file == val, "tr2_sys__Stat(): expect: regular_file, got %d\n", val);
1150 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Stat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
1151 err_code = 0xdeadbeef;
1152 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1153 ok(status_unknown == val, "tr2_sys__Lstat(): expect: status_unknown, got %d\n", val);
1154 todo_wine ok(ERROR_PIPE_BUSY == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_PIPE_BUSY, got %d\n", err_code);
1155 ok(CloseHandle(file), "CloseHandle\n");
1156 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1157 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
1158 NMPWAIT_USE_DEFAULT_WAIT, NULL);
1159 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1160 err_code = 0xdeadbeef;
1161 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1162 todo_wine ok(regular_file == val, "tr2_sys__Lstat(): expect: regular_file, got %d\n", val);
1163 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
1164 ok(CloseHandle(file), "CloseHandle\n");
1166 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1167 err_code = 0xdeadbeef;
1168 val = p_tr2_sys__Stat(tests[i].path, &err_code);
1169 if(tests[i].is_todo)
1170 todo_wine ok(tests[i].ret == val, "tr2_sys__Stat(): test %d expect: %d, got %d\n",
1171 i+1, tests[i].ret, val);
1172 else
1173 ok(tests[i].ret == val, "tr2_sys__Stat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1174 ok(tests[i].err_code == err_code, "tr2_sys__Stat(): test %d err_code expect: %d, got %d\n",
1175 i+1, tests[i].err_code, err_code);
1177 /* test tr2_sys__Lstat */
1178 err_code = 0xdeadbeef;
1179 val = p_tr2_sys__Lstat(tests[i].path, &err_code);
1180 if(tests[i].is_todo)
1181 todo_wine ok(tests[i].ret == val, "tr2_sys__Lstat(): test %d expect: %d, got %d\n",
1182 i+1, tests[i].ret, val);
1183 else
1184 ok(tests[i].ret == val, "tr2_sys__Lstat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1186 ok(tests[i].err_code == err_code, "tr2_sys__Lstat(): test %d err_code expect: %d, got %d\n",
1187 i+1, tests[i].err_code, err_code);
1190 if(ret) {
1191 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1192 todo_wine ok(RemoveDirectoryA("tr2_test_dir/dir_link"), "expect tr2_test_dir/dir_link to exist\n");
1194 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1195 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1198 static void test_tr2_sys__Last_write_time(void)
1200 HANDLE file;
1201 int ret;
1202 __int64 last_write_time, newtime;
1203 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1204 ok(ret == 1, "tr2_sys__Make_dir() expect 1 got %d\n", ret);
1206 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1207 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1208 CloseHandle(file);
1210 last_write_time = p_tr2_sys__Last_write_time("tr2_test_dir/f1");
1211 newtime = last_write_time + 123456789;
1212 p_tr2_sys__Last_write_time_set("tr2_test_dir/f1", newtime);
1213 todo_wine ok(last_write_time == p_tr2_sys__Last_write_time("tr2_test_dir/f1"),
1214 "last_write_time before modfied should not equal to last_write_time %s\n",
1215 debugstr_longlong(last_write_time));
1217 errno = 0xdeadbeef;
1218 last_write_time = p_tr2_sys__Last_write_time("not_exist");
1219 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1220 ok(last_write_time == 0, "expect 0 got %s\n", debugstr_longlong(last_write_time));
1221 last_write_time = p_tr2_sys__Last_write_time(NULL);
1222 ok(last_write_time == 0, "expect 0 got %s\n", debugstr_longlong(last_write_time));
1224 p_tr2_sys__Last_write_time_set("not_exist", newtime);
1225 errno = 0xdeadbeef;
1226 p_tr2_sys__Last_write_time_set(NULL, newtime);
1227 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1229 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1230 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1231 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1234 static void test_tr2_sys__dir_operation(void)
1236 char *file_name, first_file_name[MAX_PATH], dest[MAX_PATH], longer_path[MAX_PATH];
1237 HANDLE file, result_handle;
1238 enum file_type type;
1239 int err, num_of_f1 = 0, num_of_f2 = 0, num_of_sub_dir = 0, num_of_other_files = 0;
1241 CreateDirectoryA("tr2_test_dir", NULL);
1242 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1243 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1244 CloseHandle(file);
1245 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1246 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1247 CloseHandle(file);
1248 CreateDirectoryA("tr2_test_dir/sub_dir", NULL);
1249 file = CreateFileA("tr2_test_dir/sub_dir/sub_f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1250 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1251 CloseHandle(file);
1253 memset(longer_path, 0, MAX_PATH);
1254 GetCurrentDirectoryA(MAX_PATH, longer_path);
1255 strcat(longer_path, "\\tr2_test_dir\\");
1256 while(lstrlenA(longer_path) < MAX_PATH-1)
1257 strcat(longer_path, "s");
1258 ok(lstrlenA(longer_path) == MAX_PATH-1, "tr2_sys__Open_dir(): expect MAX_PATH, got %d\n", lstrlenA(longer_path));
1259 memset(first_file_name, 0, MAX_PATH);
1260 type = err = 0xdeadbeef;
1261 result_handle = NULL;
1262 result_handle = p_tr2_sys__Open_dir(first_file_name, longer_path, &err, &type);
1263 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect NULL, got %p\n", result_handle);
1264 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1265 ok(err == ERROR_BAD_PATHNAME, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1266 ok((int)type == 0xdeadbeef, "tr2_sys__Open_dir(): expect 0xdeadbeef, got %d\n", type);
1268 memset(first_file_name, 0, MAX_PATH);
1269 memset(dest, 0, MAX_PATH);
1270 err = type = 0xdeadbeef;
1271 result_handle = NULL;
1272 result_handle = p_tr2_sys__Open_dir(first_file_name, "tr2_test_dir", &err, &type);
1273 ok(result_handle != NULL, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle);
1274 ok(err == ERROR_SUCCESS, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1275 file_name = first_file_name;
1276 while(*file_name) {
1277 if (!strcmp(file_name, "f1")) {
1278 ++num_of_f1;
1279 ok(type == regular_file, "expect regular_file, got %d\n", type);
1280 }else if(!strcmp(file_name, "f2")) {
1281 ++num_of_f2;
1282 ok(type == regular_file, "expect regular_file, got %d\n", type);
1283 }else if(!strcmp(file_name, "sub_dir")) {
1284 ++num_of_sub_dir;
1285 ok(type == directory_file, "expect directory_file, got %d\n", type);
1286 }else {
1287 ++num_of_other_files;
1289 file_name = p_tr2_sys__Read_dir(dest, result_handle, &type);
1291 p_tr2_sys__Close_dir(result_handle);
1292 ok(result_handle != NULL, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle);
1293 ok(num_of_f1 == 1, "found f1 %d times\n", num_of_f1);
1294 ok(num_of_f2 == 1, "found f2 %d times\n", num_of_f2);
1295 ok(num_of_sub_dir == 1, "found sub_dir %d times\n", num_of_sub_dir);
1296 ok(num_of_other_files == 0, "found %d other files\n", num_of_other_files);
1298 memset(first_file_name, 0, MAX_PATH);
1299 err = type = 0xdeadbeef;
1300 result_handle = file;
1301 result_handle = p_tr2_sys__Open_dir(first_file_name, "not_exist", &err, &type);
1302 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1303 todo_wine ok(err == ERROR_BAD_PATHNAME, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1304 ok((int)type == 0xdeadbeef, "tr2_sys__Open_dir(): expect: 0xdeadbeef, got %d\n", type);
1305 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1307 CreateDirectoryA("empty_dir", NULL);
1308 memset(first_file_name, 0, MAX_PATH);
1309 err = type = 0xdeadbeef;
1310 result_handle = file;
1311 result_handle = p_tr2_sys__Open_dir(first_file_name, "empty_dir", &err, &type);
1312 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1313 ok(err == ERROR_SUCCESS, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1314 ok(type == status_unknown, "tr2_sys__Open_dir(): expect: status_unknown, got %d\n", type);
1315 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1316 p_tr2_sys__Close_dir(result_handle);
1317 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1319 ok(RemoveDirectoryA("empty_dir"), "expect empty_dir to exist\n");
1320 ok(DeleteFileA("tr2_test_dir/sub_dir/sub_f1"), "expect tr2_test_dir/sub_dir/sub_f1 to exist\n");
1321 ok(RemoveDirectoryA("tr2_test_dir/sub_dir"), "expect tr2_test_dir/sub_dir to exist\n");
1322 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1323 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1324 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1327 static void test_tr2_sys__Link(void)
1329 int ret, i;
1330 HANDLE file, h1, h2;
1331 BY_HANDLE_FILE_INFORMATION info1, info2;
1332 char temp_path[MAX_PATH], current_path[MAX_PATH];
1333 LARGE_INTEGER file_size;
1334 struct {
1335 char const *existing_path;
1336 char const *new_path;
1337 MSVCP_bool fail_if_exists;
1338 int last_error;
1339 } tests[] = {
1340 { "f1", "f1_link", TRUE, ERROR_SUCCESS },
1341 { "f1", "tr2_test_dir\\f1_link", TRUE, ERROR_SUCCESS },
1342 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", TRUE, ERROR_SUCCESS },
1343 { "tr2_test_dir", "dir_link", TRUE, ERROR_ACCESS_DENIED },
1344 { NULL, "NULL_link", TRUE, ERROR_INVALID_PARAMETER },
1345 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER },
1346 { "not_exist", "not_exist_link", TRUE, ERROR_FILE_NOT_FOUND },
1347 { "f1", "not_exist_dir\\f1_link", TRUE, ERROR_PATH_NOT_FOUND }
1350 memset(current_path, 0, MAX_PATH);
1351 GetCurrentDirectoryA(MAX_PATH, current_path);
1352 memset(temp_path, 0, MAX_PATH);
1353 GetTempPathA(MAX_PATH, temp_path);
1354 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1356 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1357 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1358 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1359 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1360 file_size.QuadPart = 7;
1361 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1362 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1363 CloseHandle(file);
1365 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1366 errno = 0xdeadbeef;
1367 ret = p_tr2_sys__Link(tests[i].existing_path, tests[i].new_path);
1368 ok(ret == tests[i].last_error, "tr2_sys__Link(): test %d expect: %d, got %d\n",
1369 i+1, tests[i].last_error, ret);
1370 ok(errno == 0xdeadbeef, "tr2_sys__Link(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1371 if(ret == ERROR_SUCCESS)
1372 ok(p_tr2_sys__File_size(tests[i].existing_path) == p_tr2_sys__File_size(tests[i].new_path),
1373 "tr2_sys__Link(): test %d failed, two files' size are not equal\n", i+1);
1376 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1377 ok(p_tr2_sys__File_size("f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link") &&
1378 p_tr2_sys__File_size("tr2_test_dir/f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link_link"),
1379 "tr2_sys__Link(): expect links' size are equal, got %s\n", debugstr_longlong(p_tr2_sys__File_size("tr2_test_dir/f1_link_link")));
1380 ok(p_tr2_sys__File_size("f1_link") == 7, "tr2_sys__Link(): expect f1_link's size equals to 7, got %s\n", debugstr_longlong(p_tr2_sys__File_size("f1_link")));
1382 file = CreateFileA("f1_link", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1383 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1384 file_size.QuadPart = 20;
1385 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1386 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1387 CloseHandle(file);
1388 h1 = CreateFileA("f1_link", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1389 NULL, OPEN_EXISTING, 0, 0);
1390 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1391 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1392 CloseHandle(h1);
1393 h2 = CreateFileA("tr2_test_dir/f1_link", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1394 NULL, OPEN_EXISTING, 0, 0);
1395 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1396 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1397 CloseHandle(h2);
1398 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1399 && info1.nFileIndexLow == info2.nFileIndexLow,
1400 "tr2_sys__Link(): test %d expect two files equivalent\n", i+1);
1401 ok(p_tr2_sys__File_size("f1_link") == 20, "tr2_sys__Link(): expect f1_link's size equals to 20, got %s\n", debugstr_longlong(p_tr2_sys__File_size("f1_link")));
1403 ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1404 ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1405 ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1406 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1407 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1408 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1411 static int __cdecl thrd_thread(void *arg)
1413 _Thrd_t *thr = arg;
1415 *thr = p__Thrd_current();
1416 return 0x42;
1419 static void test_thrd(void)
1421 int ret, i, r;
1422 struct test {
1423 _Thrd_t a;
1424 _Thrd_t b;
1425 int r;
1427 const HANDLE hnd1 = (HANDLE)0xcccccccc;
1428 const HANDLE hnd2 = (HANDLE)0xdeadbeef;
1429 xtime xt, before, after;
1430 MSVCRT_long diff;
1431 _Thrd_t ta, tb;
1433 struct test testeq[] = {
1434 { {0, 0}, {0, 0}, 1 },
1435 { {0, 1}, {0, 0}, 0 },
1436 { {hnd1, 0}, {hnd1, 1}, 0 },
1437 { {hnd1, 0}, {hnd2, 0}, 1 }
1440 struct test testlt[] = {
1441 { {0, 0}, {0, 0}, 0 },
1442 { {0, 0}, {0, 1}, 1 },
1443 { {0, 1}, {0, 0}, 0 },
1444 { {hnd1, 0}, {hnd2, 0}, 0 },
1445 { {hnd1, 0}, {hnd2, 1}, 1 }
1448 /* test for equal */
1449 for(i=0; i<sizeof(testeq)/sizeof(testeq[0]); i++) {
1450 ret = p__Thrd_equal(testeq[i].a, testeq[i].b);
1451 ok(ret == testeq[i].r, "(%p %u) = (%p %u) expected %d, got %d\n",
1452 testeq[i].a.hnd, testeq[i].a.id, testeq[i].b.hnd, testeq[i].b.id, testeq[i].r, ret);
1455 /* test for less than */
1456 for(i=0; i<sizeof(testlt)/sizeof(testlt[0]); i++) {
1457 ret = p__Thrd_lt(testlt[i].a, testlt[i].b);
1458 ok(ret == testlt[i].r, "(%p %u) < (%p %u) expected %d, got %d\n",
1459 testlt[i].a.hnd, testlt[i].a.id, testlt[i].b.hnd, testlt[i].b.id, testlt[i].r, ret);
1462 /* test for sleep */
1463 if (0) /* crash on Windows */
1464 p__Thrd_sleep(NULL);
1465 p_xtime_get(&xt, 1);
1466 xt.sec += 2;
1467 p_xtime_get(&before, 1);
1468 p__Thrd_sleep(&xt);
1469 p_xtime_get(&after, 1);
1470 diff = p__Xtime_diff_to_millis2(&after, &before);
1471 ok(diff > 2000 - TIMEDELTA, "got %d\n", diff);
1473 /* test for current */
1474 ta = p__Thrd_current();
1475 tb = p__Thrd_current();
1476 ok(ta.id == tb.id, "got a %d b %d\n", ta.id, tb.id);
1477 ok(ta.id == GetCurrentThreadId(), "expected %d, got %d\n", GetCurrentThreadId(), ta.id);
1478 /* these can be different if new threads are created at same time */
1479 ok(ta.hnd == tb.hnd, "got a %p b %p\n", ta.hnd, tb.hnd);
1480 ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd);
1481 ok(!CloseHandle(tb.hnd), "handle %p not closed\n", tb.hnd);
1483 /* test for create/join */
1484 if (0) /* crash on Windows */
1486 p__Thrd_create(NULL, thrd_thread, NULL);
1487 p__Thrd_create(&ta, NULL, NULL);
1489 r = -1;
1490 ret = p__Thrd_create(&ta, thrd_thread, (void*)&tb);
1491 ok(!ret, "failed to create thread, got %d\n", ret);
1492 ret = p__Thrd_join(ta, &r);
1493 ok(!ret, "failed to join thread, got %d\n", ret);
1494 ok(ta.id == tb.id, "expected %d, got %d\n", ta.id, tb.id);
1495 ok(ta.hnd != tb.hnd, "same handles, got %p\n", ta.hnd);
1496 ok(r == 0x42, "expected 0x42, got %d\n", r);
1497 ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd);
1500 #define NUM_THREADS 10
1501 struct cndmtx
1503 HANDLE initialized;
1504 int started;
1505 int thread_no;
1507 _Cnd_t cnd;
1508 _Mtx_t mtx;
1509 BOOL timed_wait;
1512 static int __cdecl cnd_wait_thread(void *arg)
1514 struct cndmtx *cm = arg;
1515 int r;
1517 p__Mtx_lock(&cm->mtx);
1519 if(InterlockedIncrement(&cm->started) == cm->thread_no)
1520 SetEvent(cm->initialized);
1522 if(cm->timed_wait) {
1523 xtime xt;
1525 p_xtime_get(&xt, 1);
1526 xt.sec += 2;
1527 r = p__Cnd_timedwait(&cm->cnd, &cm->mtx, &xt);
1528 ok(!r, "timed wait failed\n");
1529 } else {
1530 r = p__Cnd_wait(&cm->cnd, &cm->mtx);
1531 ok(!r, "wait failed\n");
1534 p__Mtx_unlock(&cm->mtx);
1535 return 0;
1538 static void test_cnd(void)
1540 _Thrd_t threads[NUM_THREADS];
1541 xtime xt, before, after;
1542 MSVCRT_long diff;
1543 struct cndmtx cm;
1544 _Cnd_t cnd;
1545 _Mtx_t mtx;
1546 int r, i;
1548 r = p__Cnd_init(&cnd);
1549 ok(!r, "failed to init cnd\n");
1551 r = p__Mtx_init(&mtx, 0);
1552 ok(!r, "failed to init mtx\n");
1554 if (0) /* crash on Windows */
1556 p__Cnd_init(NULL);
1557 p__Cnd_wait(NULL, &mtx);
1558 p__Cnd_wait(&cnd, NULL);
1559 p__Cnd_timedwait(NULL, &mtx, &xt);
1560 p__Cnd_timedwait(&cnd, &mtx, &xt);
1562 p__Cnd_destroy(NULL);
1564 /* test _Cnd_signal/_Cnd_wait */
1565 cm.initialized = CreateEventW(NULL, FALSE, FALSE, NULL);
1566 cm.started = 0;
1567 cm.thread_no = 1;
1568 cm.cnd = cnd;
1569 cm.mtx = mtx;
1570 cm.timed_wait = FALSE;
1571 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
1573 WaitForSingleObject(cm.initialized, INFINITE);
1574 p__Mtx_lock(&mtx);
1575 p__Mtx_unlock(&mtx);
1577 r = p__Cnd_signal(&cm.cnd);
1578 ok(!r, "failed to signal\n");
1579 p__Thrd_join(threads[0], NULL);
1581 /* test _Cnd_timedwait time out */
1582 p__Mtx_lock(&mtx);
1583 p_xtime_get(&before, 1);
1584 xt = before;
1585 xt.sec += 1;
1586 r = p__Cnd_timedwait(&cnd, &mtx, &xt);
1587 p_xtime_get(&after, 1);
1588 p__Mtx_unlock(&mtx);
1590 diff = p__Xtime_diff_to_millis2(&after, &before);
1591 ok(r == 2, "should have timed out\n");
1592 ok(diff > 1000 - TIMEDELTA, "got %d\n", diff);
1594 /* test _Cnd_timedwait */
1595 cm.started = 0;
1596 cm.timed_wait = TRUE;
1597 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
1599 WaitForSingleObject(cm.initialized, INFINITE);
1600 p__Mtx_lock(&mtx);
1601 p__Mtx_unlock(&mtx);
1603 r = p__Cnd_signal(&cm.cnd);
1604 ok(!r, "failed to signal\n");
1605 p__Thrd_join(threads[0], NULL);
1607 /* test _Cnd_broadcast */
1608 cm.started = 0;
1609 cm.thread_no = NUM_THREADS;
1610 cm.timed_wait = FALSE;
1612 for(i = 0; i < cm.thread_no; i++)
1613 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
1615 WaitForSingleObject(cm.initialized, INFINITE);
1616 p__Mtx_lock(&mtx);
1617 p__Mtx_unlock(&mtx);
1619 r = p__Cnd_broadcast(&cnd);
1620 ok(!r, "failed to broadcast\n");
1621 for(i = 0; i < cm.thread_no; i++)
1622 p__Thrd_join(threads[i], NULL);
1624 /* test broadcast with _Cnd_destroy */
1625 cm.started = 0;
1626 for(i = 0; i < cm.thread_no; i++)
1627 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
1629 WaitForSingleObject(cm.initialized, INFINITE);
1630 p__Mtx_lock(&mtx);
1631 p__Mtx_unlock(&mtx);
1633 p__Cnd_destroy(&cnd);
1634 for(i = 0; i < cm.thread_no; i++)
1635 p__Thrd_join(threads[i], NULL);
1637 p__Mtx_destroy(&mtx);
1638 CloseHandle(cm.initialized);
1641 static struct {
1642 int value[2];
1643 const char* export_name;
1644 } vbtable_size_exports_list[] = {
1645 {{0x20, 0x20}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"},
1646 {{0x10, 0x10}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"},
1647 {{0x20, 0x20}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"},
1648 {{0x10, 0x10}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"},
1649 {{0x20, 0x20}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"},
1650 {{0x10, 0x10}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"},
1651 {{0x18, 0x18}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"},
1652 {{0x18, 0x18}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"},
1653 {{0x18, 0x18}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"},
1654 {{ 0x8, 0x10}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"},
1655 {{ 0x8, 0x10}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"},
1656 {{ 0x8, 0x10}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"},
1657 {{ 0x0, 0x0}, 0}
1660 static void test_vbtable_size_exports(void)
1662 int i;
1663 const int *p_vbtable;
1664 int arch_idx = (sizeof(void*) == 8);
1666 for (i = 0; vbtable_size_exports_list[i].export_name; i++)
1668 SET(p_vbtable, vbtable_size_exports_list[i].export_name);
1670 ok(p_vbtable[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable[0]);
1671 ok(p_vbtable[1] == vbtable_size_exports_list[i].value[arch_idx],
1672 "%d: %s[1] wrong, got 0x%x\n", i, vbtable_size_exports_list[i].export_name, p_vbtable[1]);
1676 START_TEST(msvcp120)
1678 if(!init()) return;
1679 test__Xtime_diff_to_millis2();
1680 test_xtime_get();
1681 test__Getcvt();
1682 test__Call_once();
1683 test__Do_call();
1684 test__Dtest();
1685 test__Dscale();
1686 test__FExp();
1688 test_tr2_sys__File_size();
1689 test_tr2_sys__Equivalent();
1690 test_tr2_sys__Current_get();
1691 test_tr2_sys__Current_set();
1692 test_tr2_sys__Make_dir();
1693 test_tr2_sys__Remove_dir();
1694 test_tr2_sys__Copy_file();
1695 test_tr2_sys__Rename();
1696 test_tr2_sys__Statvfs();
1697 test_tr2_sys__Stat();
1698 test_tr2_sys__Last_write_time();
1699 test_tr2_sys__dir_operation();
1700 test_tr2_sys__Link();
1702 test_thrd();
1703 test_cnd();
1705 test_vbtable_size_exports();
1707 FreeLibrary(msvcp);