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
24 #include "wine/test.h"
29 #define __thiscall __stdcall
31 #define __thiscall __cdecl
34 /* Emulate a __thiscall */
40 BYTE pop_eax
; /* popl %eax (ret addr) */
41 BYTE pop_edx
; /* popl %edx (func) */
42 BYTE pop_ecx
; /* popl %ecx (this) */
43 BYTE push_eax
; /* pushl %eax */
44 WORD jmp_edx
; /* jmp *%edx */
48 static void * (WINAPI
*call_thiscall_func1
)( void *func
, void *this );
49 static void * (WINAPI
*call_thiscall_func2
)( void *func
, void *this, const void *a
);
51 static void init_thiscall_thunk(void)
53 struct thiscall_thunk
*thunk
= VirtualAlloc( NULL
, sizeof(*thunk
),
54 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
55 thunk
->pop_eax
= 0x58; /* popl %eax */
56 thunk
->pop_edx
= 0x5a; /* popl %edx */
57 thunk
->pop_ecx
= 0x59; /* popl %ecx */
58 thunk
->push_eax
= 0x50; /* pushl %eax */
59 thunk
->jmp_edx
= 0xe2ff; /* jmp *%edx */
60 call_thiscall_func1
= (void *)thunk
;
61 call_thiscall_func2
= (void *)thunk
;
64 #define call_func1(func,_this) call_thiscall_func1(func,_this)
65 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a))
69 #define init_thiscall_thunk()
70 #define call_func1(func,_this) func(_this)
71 #define call_func2(func,_this,a) func(_this,a)
75 static inline float __port_infinity(void)
77 static const unsigned __inf_bytes
= 0x7f800000;
78 return *(const float *)&__inf_bytes
;
80 #define INFINITY __port_infinity()
82 static inline float __port_nan(void)
84 static const unsigned __nan_bytes
= 0x7fc00000;
85 return *(const float *)&__nan_bytes
;
87 #define NAN __port_nan()
89 typedef int MSVCRT_long
;
90 typedef unsigned char MSVCP_bool
;
112 status_unknown
, file_not_found
, regular_file
, directory_file
,
113 symlink_file
, block_file
, character_file
, fifo_file
, socket_file
,
117 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
127 if (abs(x
- y
) > ulps
)
133 static char* (__cdecl
*p_setlocale
)(int, const char*);
134 static int (__cdecl
*p__setmbcp
)(int);
135 static int (__cdecl
*p_isleadbyte
)(int);
137 static MSVCRT_long (__cdecl
*p__Xtime_diff_to_millis2
)(const xtime
*, const xtime
*);
138 static int (__cdecl
*p_xtime_get
)(xtime
*, int);
139 static _Cvtvec
* (__cdecl
*p__Getcvt
)(_Cvtvec
*);
140 static void (CDECL
*p__Call_once
)(int *once
, void (CDECL
*func
)(void));
141 static void (CDECL
*p__Call_onceEx
)(int *once
, void (CDECL
*func
)(void*), void *argv
);
142 static void (CDECL
*p__Do_call
)(void *this);
143 static short (__cdecl
*p__Dtest
)(double *d
);
144 static short (__cdecl
*p__Dscale
)(double *d
, int exp
);
145 static short (__cdecl
*p__FExp
)(float *x
, float y
, int exp
);
148 static ULONGLONG(__cdecl
*p_tr2_sys__File_size
)(char const*);
149 static ULONGLONG(__cdecl
*p_tr2_sys__File_size_wchar
)(WCHAR
const*);
150 static int (__cdecl
*p_tr2_sys__Equivalent
)(char const*, char const*);
151 static int (__cdecl
*p_tr2_sys__Equivalent_wchar
)(WCHAR
const*, WCHAR
const*);
152 static char* (__cdecl
*p_tr2_sys__Current_get
)(char *);
153 static WCHAR
* (__cdecl
*p_tr2_sys__Current_get_wchar
)(WCHAR
*);
154 static MSVCP_bool (__cdecl
*p_tr2_sys__Current_set
)(char const*);
155 static MSVCP_bool (__cdecl
*p_tr2_sys__Current_set_wchar
)(WCHAR
const*);
156 static int (__cdecl
*p_tr2_sys__Make_dir
)(char const*);
157 static int (__cdecl
*p_tr2_sys__Make_dir_wchar
)(WCHAR
const*);
158 static MSVCP_bool (__cdecl
*p_tr2_sys__Remove_dir
)(char const*);
159 static MSVCP_bool (__cdecl
*p_tr2_sys__Remove_dir_wchar
)(WCHAR
const*);
160 static int (__cdecl
*p_tr2_sys__Copy_file
)(char const*, char const*, MSVCP_bool
);
161 static int (__cdecl
*p_tr2_sys__Copy_file_wchar
)(WCHAR
const*, WCHAR
const*, MSVCP_bool
);
162 static int (__cdecl
*p_tr2_sys__Rename
)(char const*, char const*);
163 static int (__cdecl
*p_tr2_sys__Rename_wchar
)(WCHAR
const*, WCHAR
const*);
164 static struct space_info
* (__cdecl
*p_tr2_sys__Statvfs
)(struct space_info
*, char const*);
165 static struct space_info
* (__cdecl
*p_tr2_sys__Statvfs_wchar
)(struct space_info
*, WCHAR
const*);
166 static enum file_type (__cdecl
*p_tr2_sys__Stat
)(char const*, int *);
167 static enum file_type (__cdecl
*p_tr2_sys__Stat_wchar
)(WCHAR
const*, int *);
168 static enum file_type (__cdecl
*p_tr2_sys__Lstat
)(char const*, int *);
169 static enum file_type (__cdecl
*p_tr2_sys__Lstat_wchar
)(WCHAR
const*, int *);
170 static __int64 (__cdecl
*p_tr2_sys__Last_write_time
)(char const*);
171 static void (__cdecl
*p_tr2_sys__Last_write_time_set
)(char const*, __int64
);
172 static void* (__cdecl
*p_tr2_sys__Open_dir
)(char*, char const*, int *, enum file_type
*);
173 static char* (__cdecl
*p_tr2_sys__Read_dir
)(char*, void*, enum file_type
*);
174 static void (__cdecl
*p_tr2_sys__Close_dir
)(void*);
175 static int (__cdecl
*p_tr2_sys__Link
)(char const*, char const*);
176 static int (__cdecl
*p_tr2_sys__Symlink
)(char const*, char const*);
177 static int (__cdecl
*p_tr2_sys__Unlink
)(char const*);
186 #define TIMEDELTA 250 /* 250 ms uncertainty allowed */
188 typedef int (__cdecl
*_Thrd_start_t
)(void*);
190 static int (__cdecl
*p__Thrd_equal
)(_Thrd_t
, _Thrd_t
);
191 static int (__cdecl
*p__Thrd_lt
)(_Thrd_t
, _Thrd_t
);
192 static void (__cdecl
*p__Thrd_sleep
)(const xtime
*);
193 static _Thrd_t (__cdecl
*p__Thrd_current
)(void);
194 static int (__cdecl
*p__Thrd_create
)(_Thrd_t
*, _Thrd_start_t
, void*);
195 static int (__cdecl
*p__Thrd_join
)(_Thrd_t
, int*);
196 static int (__cdecl
*p__Thrd_detach
)(_Thrd_t
);
199 static ULONGLONG (__cdecl
*p_i386_Thrd_current
)(void);
200 static _Thrd_t __cdecl
i386_Thrd_current(void)
206 r
.ull
= p_i386_Thrd_current();
212 typedef struct cs_queue
214 struct cs_queue
*next
;
221 ULONG_PTR unk_thread_id
;
236 static int (__cdecl
*p__Mtx_init
)(_Mtx_t
*, int);
237 static void (__cdecl
*p__Mtx_destroy
)(_Mtx_t
*);
238 static int (__cdecl
*p__Mtx_lock
)(_Mtx_t
*);
239 static int (__cdecl
*p__Mtx_unlock
)(_Mtx_t
*);
242 typedef void *_Cnd_t
;
244 static int (__cdecl
*p__Cnd_init
)(_Cnd_t
*);
245 static void (__cdecl
*p__Cnd_destroy
)(_Cnd_t
*);
246 static int (__cdecl
*p__Cnd_wait
)(_Cnd_t
*, _Mtx_t
*);
247 static int (__cdecl
*p__Cnd_timedwait
)(_Cnd_t
*, _Mtx_t
*, const xtime
*);
248 static int (__cdecl
*p__Cnd_broadcast
)(_Cnd_t
*);
249 static int (__cdecl
*p__Cnd_signal
)(_Cnd_t
*);
250 static void (__cdecl
*p__Cnd_register_at_thread_exit
)(_Cnd_t
*, _Mtx_t
*, int*);
251 static void (__cdecl
*p__Cnd_unregister_at_thread_exit
)(_Mtx_t
*);
252 static void (__cdecl
*p__Cnd_do_broadcast_at_thread_exit
)(void);
255 typedef void (*vtable_ptr
)(void);
259 const vtable_ptr
*vtable
;
265 static _Pad
* (__thiscall
*p__Pad_ctor
)(_Pad
*);
266 static _Pad
* (__thiscall
*p__Pad_copy_ctor
)(_Pad
*, const _Pad
*);
267 static void (__thiscall
*p__Pad_dtor
)(_Pad
*);
268 static _Pad
* (__thiscall
*p__Pad_op_assign
)(_Pad
*, const _Pad
*);
269 static void (__thiscall
*p__Pad__Launch
)(_Pad
*, _Thrd_t
*);
270 static void (__thiscall
*p__Pad__Release
)(_Pad
*);
272 static void (__cdecl
*p_threads__Mtx_new
)(void **mtx
);
273 static void (__cdecl
*p_threads__Mtx_delete
)(void *mtx
);
274 static void (__cdecl
*p_threads__Mtx_lock
)(void *mtx
);
275 static void (__cdecl
*p_threads__Mtx_unlock
)(void *mtx
);
277 static BOOLEAN (WINAPI
*pCreateSymbolicLinkA
)(LPCSTR
,LPCSTR
,DWORD
);
279 static HMODULE msvcp
;
280 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
281 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
282 static BOOL
init(void)
286 msvcp
= LoadLibraryA("msvcp120.dll");
289 win_skip("msvcp120.dll not installed\n");
293 SET(p__Xtime_diff_to_millis2
,
294 "_Xtime_diff_to_millis2");
311 if(sizeof(void*) == 8) { /* 64-bit initialization */
312 SET(p_tr2_sys__File_size
,
313 "?_File_size@sys@tr2@std@@YA_KPEBD@Z");
314 SET(p_tr2_sys__File_size_wchar
,
315 "?_File_size@sys@tr2@std@@YA_KPEB_W@Z");
316 SET(p_tr2_sys__Equivalent
,
317 "?_Equivalent@sys@tr2@std@@YAHPEBD0@Z");
318 SET(p_tr2_sys__Equivalent_wchar
,
319 "?_Equivalent@sys@tr2@std@@YAHPEB_W0@Z");
320 SET(p_tr2_sys__Current_get
,
321 "?_Current_get@sys@tr2@std@@YAPEADAEAY0BAE@D@Z");
322 SET(p_tr2_sys__Current_get_wchar
,
323 "?_Current_get@sys@tr2@std@@YAPEA_WAEAY0BAE@_W@Z");
324 SET(p_tr2_sys__Current_set
,
325 "?_Current_set@sys@tr2@std@@YA_NPEBD@Z");
326 SET(p_tr2_sys__Current_set_wchar
,
327 "?_Current_set@sys@tr2@std@@YA_NPEB_W@Z");
328 SET(p_tr2_sys__Make_dir
,
329 "?_Make_dir@sys@tr2@std@@YAHPEBD@Z");
330 SET(p_tr2_sys__Make_dir_wchar
,
331 "?_Make_dir@sys@tr2@std@@YAHPEB_W@Z");
332 SET(p_tr2_sys__Remove_dir
,
333 "?_Remove_dir@sys@tr2@std@@YA_NPEBD@Z");
334 SET(p_tr2_sys__Remove_dir_wchar
,
335 "?_Remove_dir@sys@tr2@std@@YA_NPEB_W@Z");
336 SET(p_tr2_sys__Copy_file
,
337 "?_Copy_file@sys@tr2@std@@YAHPEBD0_N@Z");
338 SET(p_tr2_sys__Copy_file_wchar
,
339 "?_Copy_file@sys@tr2@std@@YAHPEB_W0_N@Z");
340 SET(p_tr2_sys__Rename
,
341 "?_Rename@sys@tr2@std@@YAHPEBD0@Z");
342 SET(p_tr2_sys__Rename_wchar
,
343 "?_Rename@sys@tr2@std@@YAHPEB_W0@Z");
344 SET(p_tr2_sys__Statvfs
,
345 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEBD@Z");
346 SET(p_tr2_sys__Statvfs_wchar
,
347 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEB_W@Z");
349 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
350 SET(p_tr2_sys__Stat_wchar
,
351 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
352 SET(p_tr2_sys__Lstat
,
353 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
354 SET(p_tr2_sys__Lstat_wchar
,
355 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
356 SET(p_tr2_sys__Last_write_time
,
357 "?_Last_write_time@sys@tr2@std@@YA_JPEBD@Z");
358 SET(p_tr2_sys__Last_write_time_set
,
359 "?_Last_write_time@sys@tr2@std@@YAXPEBD_J@Z");
360 SET(p_tr2_sys__Open_dir
,
361 "?_Open_dir@sys@tr2@std@@YAPEAXAEAY0BAE@DPEBDAEAHAEAW4file_type@123@@Z");
362 SET(p_tr2_sys__Read_dir
,
363 "?_Read_dir@sys@tr2@std@@YAPEADAEAY0BAE@DPEAXAEAW4file_type@123@@Z");
364 SET(p_tr2_sys__Close_dir
,
365 "?_Close_dir@sys@tr2@std@@YAXPEAX@Z");
367 "?_Link@sys@tr2@std@@YAHPEBD0@Z");
368 SET(p_tr2_sys__Symlink
,
369 "?_Symlink@sys@tr2@std@@YAHPEBD0@Z");
370 SET(p_tr2_sys__Unlink
,
371 "?_Unlink@sys@tr2@std@@YAHPEBD@Z");
375 "??0_Pad@std@@QEAA@XZ");
376 SET(p__Pad_copy_ctor
,
377 "??0_Pad@std@@QEAA@AEBV01@@Z");
379 "??1_Pad@std@@QEAA@XZ");
380 SET(p__Pad_op_assign
,
381 "??4_Pad@std@@QEAAAEAV01@AEBV01@@Z");
383 "?_Launch@_Pad@std@@QEAAXPEAU_Thrd_imp_t@@@Z");
385 "?_Release@_Pad@std@@QEAAXXZ");
386 SET(p_threads__Mtx_new
,
387 "?_Mtx_new@threads@stdext@@YAXAEAPEAX@Z");
388 SET(p_threads__Mtx_delete
,
389 "?_Mtx_delete@threads@stdext@@YAXPEAX@Z");
390 SET(p_threads__Mtx_lock
,
391 "?_Mtx_lock@threads@stdext@@YAXPEAX@Z");
392 SET(p_threads__Mtx_unlock
,
393 "?_Mtx_unlock@threads@stdext@@YAXPEAX@Z");
395 SET(p_tr2_sys__File_size
,
396 "?_File_size@sys@tr2@std@@YA_KPBD@Z");
397 SET(p_tr2_sys__File_size_wchar
,
398 "?_File_size@sys@tr2@std@@YA_KPB_W@Z");
399 SET(p_tr2_sys__Equivalent
,
400 "?_Equivalent@sys@tr2@std@@YAHPBD0@Z");
401 SET(p_tr2_sys__Equivalent_wchar
,
402 "?_Equivalent@sys@tr2@std@@YAHPB_W0@Z");
403 SET(p_tr2_sys__Current_get
,
404 "?_Current_get@sys@tr2@std@@YAPADAAY0BAE@D@Z");
405 SET(p_tr2_sys__Current_get_wchar
,
406 "?_Current_get@sys@tr2@std@@YAPA_WAAY0BAE@_W@Z");
407 SET(p_tr2_sys__Current_set
,
408 "?_Current_set@sys@tr2@std@@YA_NPBD@Z");
409 SET(p_tr2_sys__Current_set_wchar
,
410 "?_Current_set@sys@tr2@std@@YA_NPB_W@Z");
411 SET(p_tr2_sys__Make_dir
,
412 "?_Make_dir@sys@tr2@std@@YAHPBD@Z");
413 SET(p_tr2_sys__Make_dir_wchar
,
414 "?_Make_dir@sys@tr2@std@@YAHPB_W@Z");
415 SET(p_tr2_sys__Remove_dir
,
416 "?_Remove_dir@sys@tr2@std@@YA_NPBD@Z");
417 SET(p_tr2_sys__Remove_dir_wchar
,
418 "?_Remove_dir@sys@tr2@std@@YA_NPB_W@Z");
419 SET(p_tr2_sys__Copy_file
,
420 "?_Copy_file@sys@tr2@std@@YAHPBD0_N@Z");
421 SET(p_tr2_sys__Copy_file_wchar
,
422 "?_Copy_file@sys@tr2@std@@YAHPB_W0_N@Z");
423 SET(p_tr2_sys__Rename
,
424 "?_Rename@sys@tr2@std@@YAHPBD0@Z");
425 SET(p_tr2_sys__Rename_wchar
,
426 "?_Rename@sys@tr2@std@@YAHPB_W0@Z");
427 SET(p_tr2_sys__Statvfs
,
428 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z");
429 SET(p_tr2_sys__Statvfs_wchar
,
430 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PB_W@Z");
432 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
433 SET(p_tr2_sys__Stat_wchar
,
434 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
435 SET(p_tr2_sys__Lstat
,
436 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
437 SET(p_tr2_sys__Lstat_wchar
,
438 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
439 SET(p_tr2_sys__Last_write_time
,
440 "?_Last_write_time@sys@tr2@std@@YA_JPBD@Z");
441 SET(p_tr2_sys__Last_write_time_set
,
442 "?_Last_write_time@sys@tr2@std@@YAXPBD_J@Z");
443 SET(p_tr2_sys__Open_dir
,
444 "?_Open_dir@sys@tr2@std@@YAPAXAAY0BAE@DPBDAAHAAW4file_type@123@@Z");
445 SET(p_tr2_sys__Read_dir
,
446 "?_Read_dir@sys@tr2@std@@YAPADAAY0BAE@DPAXAAW4file_type@123@@Z");
447 SET(p_tr2_sys__Close_dir
,
448 "?_Close_dir@sys@tr2@std@@YAXPAX@Z");
450 "?_Link@sys@tr2@std@@YAHPBD0@Z");
451 SET(p_tr2_sys__Symlink
,
452 "?_Symlink@sys@tr2@std@@YAHPBD0@Z");
453 SET(p_tr2_sys__Unlink
,
454 "?_Unlink@sys@tr2@std@@YAHPBD@Z");
455 SET(p_threads__Mtx_new
,
456 "?_Mtx_new@threads@stdext@@YAXAAPAX@Z");
457 SET(p_threads__Mtx_delete
,
458 "?_Mtx_delete@threads@stdext@@YAXPAX@Z");
459 SET(p_threads__Mtx_lock
,
460 "?_Mtx_lock@threads@stdext@@YAXPAX@Z");
461 SET(p_threads__Mtx_unlock
,
462 "?_Mtx_unlock@threads@stdext@@YAXPAX@Z");
464 SET(p_i386_Thrd_current
,
466 p__Thrd_current
= i386_Thrd_current
;
468 "??0_Pad@std@@QAE@XZ");
469 SET(p__Pad_copy_ctor
,
470 "??0_Pad@std@@QAE@ABV01@@Z");
472 "??1_Pad@std@@QAE@XZ");
473 SET(p__Pad_op_assign
,
474 "??4_Pad@std@@QAEAAV01@ABV01@@Z");
476 "?_Launch@_Pad@std@@QAEXPAU_Thrd_imp_t@@@Z");
478 "?_Release@_Pad@std@@QAEXXZ");
483 "??0_Pad@std@@QAA@XZ");
484 SET(p__Pad_copy_ctor
,
485 "??0_Pad@std@@QAA@ABV01@@Z");
487 "??1_Pad@std@@QAA@XZ");
488 SET(p__Pad_op_assign
,
489 "??4_Pad@std@@QAAAAV01@ABV01@@Z");
491 "?_Launch@_Pad@std@@QAAXPAU_Thrd_imp_t@@@Z");
493 "?_Release@_Pad@std@@QAAXXZ");
524 SET(p__Cnd_timedwait
,
526 SET(p__Cnd_broadcast
,
530 SET(p__Cnd_register_at_thread_exit
,
531 "_Cnd_register_at_thread_exit");
532 SET(p__Cnd_unregister_at_thread_exit
,
533 "_Cnd_unregister_at_thread_exit");
534 SET(p__Cnd_do_broadcast_at_thread_exit
,
535 "_Cnd_do_broadcast_at_thread_exit");
537 hdll
= GetModuleHandleA("msvcr120.dll");
538 p_setlocale
= (void*)GetProcAddress(hdll
, "setlocale");
539 p__setmbcp
= (void*)GetProcAddress(hdll
, "_setmbcp");
540 p_isleadbyte
= (void*)GetProcAddress(hdll
, "isleadbyte");
542 hdll
= GetModuleHandleA("kernel32.dll");
543 pCreateSymbolicLinkA
= (void*)GetProcAddress(hdll
, "CreateSymbolicLinkA");
545 init_thiscall_thunk();
549 static void test__Xtime_diff_to_millis2(void)
552 __time64_t sec_before
;
553 MSVCRT_long nsec_before
;
554 __time64_t sec_after
;
555 MSVCRT_long nsec_after
;
559 {0, 1000000000, 0, 2000000000, 1000},
560 {1, 100000000, 2, 100000000, 1000},
561 {1, 100000000, 1, 200000000, 100},
562 {0, 0, 0, 1000000000, 1000},
563 {0, 0, 0, 1200000000, 1200},
564 {0, 0, 0, 1230000000, 1230},
565 {0, 0, 0, 1234000000, 1234},
566 {0, 0, 0, 1234100000, 1235},
567 {0, 0, 0, 1234900000, 1235},
568 {0, 0, 0, 1234010000, 1235},
569 {0, 0, 0, 1234090000, 1235},
570 {0, 0, 0, 1234000001, 1235},
571 {0, 0, 0, 1234000009, 1235},
573 {0, 0, 0, -10000000, 0},
574 {0, 0, -1, -100000000, 0},
576 {0, -100000000, 0, 0, 100},
577 {-1, -100000000, 0, 0, 1100},
578 {0, 0, -1, 2000000000, 1000},
579 {0, 0, -2, 2000000000, 0},
580 {0, 0, -2, 2100000000, 100}
586 for(i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); ++ i
)
588 t1
.sec
= tests
[i
].sec_before
;
589 t1
.nsec
= tests
[i
].nsec_before
;
590 t2
.sec
= tests
[i
].sec_after
;
591 t2
.nsec
= tests
[i
].nsec_after
;
592 ret
= p__Xtime_diff_to_millis2(&t2
, &t1
);
593 ok(ret
== tests
[i
].expect
,
594 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
595 i
, tests
[i
].expect
, ret
);
599 static void test_xtime_get(void)
601 static const MSVCRT_long tests
[] = {1, 50, 100, 200, 500};
606 for(i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); i
++)
608 p_xtime_get(&before
, 1);
610 p_xtime_get(&after
, 1);
612 diff
= p__Xtime_diff_to_millis2(&after
, &before
);
615 "xtime_get() not functioning correctly, test: %d, expect: %d, got: %d\n",
619 /* Test parameter and return value */
620 before
.sec
= 0xdeadbeef, before
.nsec
= 0xdeadbeef;
621 i
= p_xtime_get(&before
, 0);
622 ok(i
== 0, "expect xtime_get() to return 0, got: %d\n", i
);
623 ok(before
.sec
== 0xdeadbeef && before
.nsec
== 0xdeadbeef,
624 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
626 before
.sec
= 0xdeadbeef, before
.nsec
= 0xdeadbeef;
627 i
= p_xtime_get(&before
, 1);
628 ok(i
== 1, "expect xtime_get() to return 1, got: %d\n", i
);
629 ok(before
.sec
!= 0xdeadbeef && before
.nsec
!= 0xdeadbeef,
630 "xtime_get() should have modified the xtime struct with the given option\n");
633 static void test__Getcvt(void)
639 ok(cvtvec
.page
== 0, "cvtvec.page = %d\n", cvtvec
.page
);
640 ok(cvtvec
.mb_max
== 1, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
641 todo_wine
ok(cvtvec
.unk
== 1, "cvtvec.unk = %d\n", cvtvec
.unk
);
643 ok(cvtvec
.isleadbyte
[i
] == 0, "cvtvec.isleadbyte[%d] = %x\n", i
, cvtvec
.isleadbyte
[i
]);
645 if(!p_setlocale(LC_ALL
, ".936")) {
646 win_skip("_Getcvt tests\n");
650 ok(cvtvec
.page
== 936, "cvtvec.page = %d\n", cvtvec
.page
);
651 ok(cvtvec
.mb_max
== 2, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
652 ok(cvtvec
.unk
== 0, "cvtvec.unk = %d\n", cvtvec
.unk
);
654 ok(cvtvec
.isleadbyte
[i
] == 0, "cvtvec.isleadbyte[%d] = %x\n", i
, cvtvec
.isleadbyte
[i
]);
658 ok(cvtvec
.page
== 936, "cvtvec.page = %d\n", cvtvec
.page
);
659 ok(cvtvec
.mb_max
== 2, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
660 ok(cvtvec
.unk
== 0, "cvtvec.unk = %d\n", cvtvec
.unk
);
661 for(i
=0; i
<32; i
++) {
666 b
|= (p_isleadbyte(i
*8+j
) ? 1 : 0) << j
;
667 ok(cvtvec
.isleadbyte
[i
] ==b
, "cvtvec.isleadbyte[%d] = %x (%x)\n", i
, cvtvec
.isleadbyte
[i
], b
);
674 static void __cdecl
call_once_func(void)
676 ok(!once
, "once != 0\n");
680 static void __cdecl
call_once_ex_func(void *arg
)
684 ok(!once
, "once != 0\n");
688 static DWORD WINAPI
call_once_thread(void *arg
)
690 p__Call_once(&once
, call_once_func
);
694 static DWORD WINAPI
call_once_ex_thread(void *arg
)
696 p__Call_onceEx(&once
, call_once_ex_func
, &cnt
);
700 static void test__Call_once(void)
706 h
[i
] = CreateThread(NULL
, 0, call_once_thread
, &once
, 0, NULL
);
707 ok(WaitForMultipleObjects(4, h
, TRUE
, INFINITE
) == WAIT_OBJECT_0
,
708 "error waiting for all threads to finish\n");
709 ok(cnt
== 0x10000, "cnt = %x\n", cnt
);
710 ok(once
== 1, "once = %x\n", once
);
714 h
[i
] = CreateThread(NULL
, 0, call_once_ex_thread
, &once
, 0, NULL
);
715 ok(WaitForMultipleObjects(4, h
, TRUE
, INFINITE
) == WAIT_OBJECT_0
,
716 "error waiting for all threads to finish\n");
717 ok(cnt
== 1, "cnt = %x\n", cnt
);
718 ok(once
== 1, "once = %x\n", once
);
721 static void **vtbl_func0
;
723 /* TODO: this should be a __thiscall function */
724 static void __stdcall
thiscall_func(void)
729 static void __cdecl
thiscall_func(void *this)
731 ok(this == &vtbl_func0
, "incorrect this value\n");
736 static void test__Do_call(void)
738 void *pfunc
= thiscall_func
;
742 p__Do_call(&vtbl_func0
);
743 ok(cnt
== 1, "func was not called\n");
746 static void test__Dtest(void)
753 ok(ret
== FP_ZERO
, "_Dtest(0) returned %x\n", ret
);
757 ok(ret
== FP_NORMAL
, "_Dtest(1) returned %x\n", ret
);
761 ok(ret
== FP_NORMAL
, "_Dtest(-1) returned %x\n", ret
);
765 ok(ret
== FP_INFINITE
, "_Dtest(INF) returned %x\n", ret
);
769 ok(ret
== FP_NAN
, "_Dtest(NAN) returned %x\n", ret
);
772 static void test__Dscale(void)
778 ret
= p__Dscale(&d
, 0);
779 ok(d
== 0, "d = %f\n", d
);
780 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
783 ret
= p__Dscale(&d
, 1);
784 ok(d
== 0, "d = %f\n", d
);
785 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
788 ret
= p__Dscale(&d
, -1);
789 ok(d
== 0, "d = %f\n", d
);
790 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
793 ret
= p__Dscale(&d
, 0);
794 ok(d
== 1, "d = %f\n", d
);
795 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
798 ret
= p__Dscale(&d
, 1);
799 ok(d
== 2, "d = %f\n", d
);
800 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
803 ret
= p__Dscale(&d
, -1);
804 ok(d
== 0.5, "d = %f\n", d
);
805 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
808 ret
= p__Dscale(&d
, -99999);
809 ok(d
== 0, "d = %f\n", d
);
810 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
813 ret
= p__Dscale(&d
, 999999);
814 ok(d
== INFINITY
, "d = %f\n", d
);
815 ok(ret
== FP_INFINITE
, "ret = %x\n", ret
);
818 ret
= p__Dscale(&d
, 1);
819 ok(ret
== FP_NAN
, "ret = %x\n", ret
);
822 static void test__FExp(void)
828 ret
= p__FExp(&d
, 0, 0);
829 ok(d
== 0, "d = %f\n", d
);
830 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
833 ret
= p__FExp(&d
, 1, 0);
834 ok(d
== 1.0, "d = %f\n", d
);
835 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
838 ret
= p__FExp(&d
, 1, 1);
839 ok(d
== 2.0, "d = %f\n", d
);
840 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
843 ret
= p__FExp(&d
, 1, 2);
844 ok(d
== 4.0, "d = %f\n", d
);
845 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
848 ret
= p__FExp(&d
, 10, 0);
849 ok(d
== 10.0, "d = %f\n", d
);
850 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
853 ret
= p__FExp(&d
, 0, 0);
854 ok(d
== 0, "d = %f\n", d
);
855 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
858 ret
= p__FExp(&d
, 1, 0);
859 ok(compare_float(d
, 2.7182817, 4), "d = %f\n", d
);
860 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
863 ret
= p__FExp(&d
, 0, 0);
864 ok(d
== 0, "d = %f\n", d
);
865 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
868 ret
= p__FExp(&d
, 1, 0);
869 ok(ret
== FP_INFINITE
, "ret = %x\n", ret
);
872 ret
= p__FExp(&d
, 1, -50);
873 ok(compare_float(d
, 1.0839359e+024, 4), "d = %g\n", d
);
874 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
877 static void test_tr2_sys__File_size(void)
881 LARGE_INTEGER file_size
;
882 WCHAR testW
[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
883 CreateDirectoryA("tr2_test_dir", NULL
);
885 file
= CreateFileA("tr2_test_dir/f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
886 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
887 file_size
.QuadPart
= 7;
888 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
889 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
891 val
= p_tr2_sys__File_size("tr2_test_dir/f1");
892 ok(val
== 7, "file_size is %s\n", wine_dbgstr_longlong(val
));
893 val
= p_tr2_sys__File_size_wchar(testW
);
894 ok(val
== 7, "file_size is %s\n", wine_dbgstr_longlong(val
));
896 file
= CreateFileA("tr2_test_dir/f2", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
897 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
899 val
= p_tr2_sys__File_size("tr2_test_dir/f2");
900 ok(val
== 0, "file_size is %s\n", wine_dbgstr_longlong(val
));
902 val
= p_tr2_sys__File_size("tr2_test_dir");
903 ok(val
== 0, "file_size is %s\n", wine_dbgstr_longlong(val
));
906 val
= p_tr2_sys__File_size("tr2_test_dir/not_exists_file");
907 ok(val
== 0, "file_size is %s\n", wine_dbgstr_longlong(val
));
908 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
911 val
= p_tr2_sys__File_size(NULL
);
912 ok(val
== 0, "file_size is %s\n", wine_dbgstr_longlong(val
));
913 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
915 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
916 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
917 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
920 static void test_tr2_sys__Equivalent(void)
924 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
925 WCHAR testW
[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
926 WCHAR testW2
[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','2',0};
935 { "f1", "tr2_test_dir", -1 },
936 { "tr2_test_dir", "f1", -1 },
937 { "tr2_test_dir", "tr2_test_dir", -1 },
938 { "tr2_test_dir/./f1", "tr2_test_dir/f2", 0 },
939 { "tr2_test_dir/f1" , "tr2_test_dir/f1", 1 },
940 { "not_exists_file" , "tr2_test_dir/f1", 0 },
941 { "tr2_test_dir\\f1" , "tr2_test_dir/./f1", 1 },
942 { "not_exists_file" , "not_exists_file", -1 },
943 { "tr2_test_dir/f1" , "not_exists_file", 0 },
944 { "tr2_test_dir/../tr2_test_dir/f1", "tr2_test_dir/f1", 1 }
947 memset(current_path
, 0, MAX_PATH
);
948 GetCurrentDirectoryA(MAX_PATH
, current_path
);
949 memset(temp_path
, 0, MAX_PATH
);
950 GetTempPathA(MAX_PATH
, temp_path
);
951 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
952 CreateDirectoryA("tr2_test_dir", NULL
);
954 file
= CreateFileA("tr2_test_dir/f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
955 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
957 file
= CreateFileA("tr2_test_dir/f2", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
958 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
961 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
963 val
= p_tr2_sys__Equivalent(tests
[i
].path1
, tests
[i
].path2
);
964 ok(tests
[i
].equivalent
== val
, "tr2_sys__Equivalent(): test %d expect: %d, got %d\n", i
+1, tests
[i
].equivalent
, val
);
965 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
968 val
= p_tr2_sys__Equivalent_wchar(testW
, testW
);
969 ok(val
== 1, "tr2_sys__Equivalent(): expect: 1, got %d\n", val
);
970 val
= p_tr2_sys__Equivalent_wchar(testW
, testW2
);
971 ok(val
== 0, "tr2_sys__Equivalent(): expect: 0, got %d\n", val
);
973 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
974 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
975 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
976 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
979 static void test_tr2_sys__Current_get(void)
981 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
], origin_path
[MAX_PATH
];
983 WCHAR temp_path_wchar
[MAX_PATH
], current_path_wchar
[MAX_PATH
];
985 memset(origin_path
, 0, MAX_PATH
);
986 GetCurrentDirectoryA(MAX_PATH
, origin_path
);
987 memset(temp_path
, 0, MAX_PATH
);
988 GetTempPathA(MAX_PATH
, temp_path
);
990 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
991 memset(current_path
, 0, MAX_PATH
);
992 temp
= p_tr2_sys__Current_get(current_path
);
993 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
994 temp
[strlen(temp
)] = '\\';
995 ok(!strcmp(temp_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path
, current_path
);
997 GetTempPathW(MAX_PATH
, temp_path_wchar
);
998 ok(SetCurrentDirectoryW(temp_path_wchar
), "SetCurrentDirectoryW to temp_path_wchar failed\n");
999 memset(current_path_wchar
, 0, MAX_PATH
);
1000 temp_wchar
= p_tr2_sys__Current_get_wchar(current_path_wchar
);
1001 ok(temp_wchar
== current_path_wchar
, "p_tr2_sys__Current_get_wchar returned different buffer\n");
1002 temp_wchar
[wcslen(temp_wchar
)] = '\\';
1003 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
));
1005 ok(SetCurrentDirectoryA(origin_path
), "SetCurrentDirectoryA to origin_path failed\n");
1006 memset(current_path
, 0, MAX_PATH
);
1007 temp
= p_tr2_sys__Current_get(current_path
);
1008 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1009 ok(!strcmp(origin_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path
, current_path
);
1012 static void test_tr2_sys__Current_set(void)
1014 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
], origin_path
[MAX_PATH
];
1016 WCHAR testW
[] = {'.','/',0};
1017 memset(temp_path
, 0, MAX_PATH
);
1018 GetTempPathA(MAX_PATH
, temp_path
);
1019 memset(origin_path
, 0, MAX_PATH
);
1020 GetCurrentDirectoryA(MAX_PATH
, origin_path
);
1021 temp
= p_tr2_sys__Current_get(origin_path
);
1022 ok(temp
== origin_path
, "p_tr2_sys__Current_get returned different buffer\n");
1024 ok(p_tr2_sys__Current_set(temp_path
), "p_tr2_sys__Current_set to temp_path failed\n");
1025 memset(current_path
, 0, MAX_PATH
);
1026 temp
= p_tr2_sys__Current_get(current_path
);
1027 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1028 temp
[strlen(temp
)] = '\\';
1029 ok(!strcmp(temp_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path
, current_path
);
1031 ok(p_tr2_sys__Current_set_wchar(testW
), "p_tr2_sys__Current_set_wchar to temp_path failed\n");
1032 memset(current_path
, 0, MAX_PATH
);
1033 temp
= p_tr2_sys__Current_get(current_path
);
1034 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1035 temp
[strlen(temp
)] = '\\';
1036 ok(!strcmp(temp_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path
, current_path
);
1039 ok(!p_tr2_sys__Current_set("not_exisist_dir"), "p_tr2_sys__Current_set to not_exist_dir succeed\n");
1040 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1043 ok(!p_tr2_sys__Current_set("??invalid_name>>"), "p_tr2_sys__Current_set to ??invalid_name>> succeed\n");
1044 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1046 ok(p_tr2_sys__Current_set(origin_path
), "p_tr2_sys__Current_set to origin_path failed\n");
1047 memset(current_path
, 0, MAX_PATH
);
1048 temp
= p_tr2_sys__Current_get(current_path
);
1049 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1050 ok(!strcmp(origin_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path
, current_path
);
1053 static void test_tr2_sys__Make_dir(void)
1056 WCHAR testW
[] = {'w','d',0};
1061 { "tr2_test_dir", 1 },
1062 { "tr2_test_dir", 0 },
1064 { "??invalid_name>>", -1 }
1067 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
1069 ret
= p_tr2_sys__Make_dir(tests
[i
].path
);
1070 ok(ret
== tests
[i
].val
, "tr2_sys__Make_dir(): test %d expect: %d, got %d\n", i
+1, tests
[i
].val
, ret
);
1071 ok(errno
== 0xdeadbeef, "tr2_sys__Make_dir(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1073 ret
= p_tr2_sys__Make_dir_wchar(testW
);
1074 ok(ret
== 1, "tr2_sys__Make_dir(): expect: 1, got %d\n", ret
);
1076 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1077 ok(p_tr2_sys__Remove_dir_wchar(testW
), "expect wd to exist\n");
1080 static void test_tr2_sys__Remove_dir(void)
1088 { "tr2_test_dir", TRUE
},
1089 { "tr2_test_dir", FALSE
},
1091 { "??invalid_name>>", FALSE
}
1094 ok(p_tr2_sys__Make_dir("tr2_test_dir"), "tr2_sys__Make_dir() failed\n");
1096 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
1098 ret
= p_tr2_sys__Remove_dir(tests
[i
].path
);
1099 ok(ret
== tests
[i
].val
, "test_tr2_sys__Remove_dir(): test %d expect: %d, got %d\n", i
+1, tests
[i
].val
, ret
);
1100 ok(errno
== 0xdeadbeef, "test_tr2_sys__Remove_dir(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1104 static void test_tr2_sys__Copy_file(void)
1108 LARGE_INTEGER file_size
;
1109 WCHAR testW
[] = {'f','1',0}, testW2
[] = {'f','w',0};
1113 MSVCP_bool fail_if_exists
;
1118 { "f1", "f1_copy", TRUE
, ERROR_SUCCESS
, ERROR_SUCCESS
, FALSE
},
1119 { "f1", "tr2_test_dir\\f1_copy", TRUE
, ERROR_SUCCESS
, ERROR_SUCCESS
, FALSE
},
1120 { "f1", "tr2_test_dir\\f1_copy", TRUE
, ERROR_FILE_EXISTS
, ERROR_FILE_EXISTS
, FALSE
},
1121 { "f1", "tr2_test_dir\\f1_copy", FALSE
, ERROR_SUCCESS
, ERROR_SUCCESS
, FALSE
},
1122 { "tr2_test_dir", "f1", TRUE
, ERROR_ACCESS_DENIED
, ERROR_ACCESS_DENIED
, FALSE
},
1123 { "tr2_test_dir", "tr2_test_dir_copy", TRUE
, ERROR_ACCESS_DENIED
, ERROR_ACCESS_DENIED
, FALSE
},
1124 { NULL
, "f1", TRUE
, ERROR_INVALID_PARAMETER
, ERROR_INVALID_PARAMETER
, TRUE
},
1125 { "f1", NULL
, TRUE
, ERROR_INVALID_PARAMETER
, ERROR_INVALID_PARAMETER
, TRUE
},
1126 { "not_exist", "tr2_test_dir", TRUE
, ERROR_FILE_NOT_FOUND
, ERROR_FILE_NOT_FOUND
, FALSE
},
1127 { "f1", "not_exist_dir\\f1_copy", TRUE
, ERROR_PATH_NOT_FOUND
, ERROR_FILE_NOT_FOUND
, FALSE
},
1128 { "f1", "tr2_test_dir", TRUE
, ERROR_ACCESS_DENIED
, ERROR_FILE_EXISTS
, FALSE
}
1131 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1132 ok(ret
== 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1133 file
= CreateFileA("f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1134 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1135 file_size
.QuadPart
= 7;
1136 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1137 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1140 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
1142 ret
= p_tr2_sys__Copy_file(tests
[i
].source
, tests
[i
].dest
, tests
[i
].fail_if_exists
);
1143 todo_wine_if(tests
[i
].is_todo
)
1144 ok(ret
== tests
[i
].last_error
|| ret
== tests
[i
].last_error2
,
1145 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n", i
+1, tests
[i
].last_error
, ret
);
1146 ok(errno
== 0xdeadbeef, "test_tr2_sys__Copy_file(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1147 if(ret
== ERROR_SUCCESS
)
1148 ok(p_tr2_sys__File_size(tests
[i
].source
) == p_tr2_sys__File_size(tests
[i
].dest
),
1149 "test_tr2_sys__Copy_file(): test %d failed, two files' size are not equal\n", i
+1);
1151 ret
= p_tr2_sys__Copy_file_wchar(testW
, testW2
, TRUE
);
1152 ok(ret
== ERROR_SUCCESS
, "test_tr2_sys__Copy_file_wchar() expect ERROR_SUCCESS, got %d\n", ret
);
1154 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1155 ok(DeleteFileW(testW2
), "expect fw to exist\n");
1156 ok(DeleteFileA("f1_copy"), "expect f1_copy to exist\n");
1157 ok(DeleteFileA("tr2_test_dir/f1_copy"), "expect tr2_test_dir/f1 to exist\n");
1158 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1159 ok(ret
== 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1162 static void test_tr2_sys__Rename(void)
1165 HANDLE file
, h1
, h2
;
1166 BY_HANDLE_FILE_INFORMATION info1
, info2
;
1167 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
1168 LARGE_INTEGER file_size
;
1169 WCHAR testW
[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
1170 WCHAR testW2
[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','w',0};
1172 char const *old_path
;
1173 char const *new_path
;
1176 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_SUCCESS
},
1177 { "tr2_test_dir\\f1", NULL
, ERROR_INVALID_PARAMETER
},
1178 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND
},
1179 { NULL
, "tr2_test_dir\\NULL_rename", ERROR_INVALID_PARAMETER
},
1180 { "tr2_test_dir\\f1_rename", "tr2_test_dir\\??invalid_name>>", ERROR_INVALID_NAME
},
1181 { "tr2_test_dir\\not_exist_file", "tr2_test_dir\\not_exist_rename", ERROR_FILE_NOT_FOUND
}
1184 memset(current_path
, 0, MAX_PATH
);
1185 GetCurrentDirectoryA(MAX_PATH
, current_path
);
1186 memset(temp_path
, 0, MAX_PATH
);
1187 GetTempPathA(MAX_PATH
, temp_path
);
1188 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
1189 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1191 ok(ret
== 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1192 file
= CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1193 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1196 ret
= p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1");
1197 todo_wine
ok(ERROR_SUCCESS
== ret
, "test_tr2_sys__Rename(): expect: ERROR_SUCCESS, got %d\n", ret
);
1198 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
1200 if(tests
[i
].val
== ERROR_SUCCESS
) {
1201 h1
= CreateFileA(tests
[i
].old_path
, 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1202 NULL
, OPEN_EXISTING
, 0, 0);
1203 ok(h1
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1204 ok(GetFileInformationByHandle(h1
, &info1
), "GetFileInformationByHandle failed\n");
1207 SetLastError(0xdeadbeef);
1208 ret
= p_tr2_sys__Rename(tests
[i
].old_path
, tests
[i
].new_path
);
1209 ok(ret
== tests
[i
].val
, "test_tr2_sys__Rename(): test %d expect: %d, got %d\n", i
+1, tests
[i
].val
, ret
);
1210 ok(errno
== 0xdeadbeef, "test_tr2_sys__Rename(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1211 if(ret
== ERROR_SUCCESS
) {
1212 h2
= CreateFileA(tests
[i
].new_path
, 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1213 NULL
, OPEN_EXISTING
, 0, 0);
1214 ok(h2
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1215 ok(GetFileInformationByHandle(h2
, &info2
), "GetFileInformationByHandle failed\n");
1217 ok(info1
.nFileIndexHigh
== info2
.nFileIndexHigh
1218 && info1
.nFileIndexLow
== info2
.nFileIndexLow
,
1219 "test_tr2_sys__Rename(): test %d expect two files equivalent\n", i
+1);
1223 file
= CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1224 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1225 file_size
.QuadPart
= 7;
1226 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1227 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1229 ret
= p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1_rename");
1230 ok(ret
== ERROR_ALREADY_EXISTS
, "test_tr2_sys__Rename(): expect: ERROR_ALREADY_EXISTS, got %d\n", ret
);
1231 ok(p_tr2_sys__File_size("tr2_test_dir\\f1") == 7, "test_tr2_sys__Rename(): expect: 7, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size("tr2_test_dir\\f1")));
1232 ok(p_tr2_sys__File_size("tr2_test_dir\\f1_rename") == 0, "test_tr2_sys__Rename(): expect: 0, got %s\n",wine_dbgstr_longlong(p_tr2_sys__File_size("tr2_test_dir\\f1_rename")));
1233 ret
= p_tr2_sys__Rename_wchar(testW
, testW2
);
1234 ok(ret
== ERROR_SUCCESS
, "tr2_sys__Rename_wchar(): expect: ERROR_SUCCESS, got %d\n", ret
);
1236 ok(DeleteFileW(testW2
), "expect fw to exist\n");
1237 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1238 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1239 ok(ret
== 1, "test_tr2_sys__Remove_dir(): expect %d got %d\n", 1, ret
);
1240 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
1243 static void test_tr2_sys__Statvfs(void)
1245 struct space_info info
;
1246 char current_path
[MAX_PATH
];
1247 WCHAR current_path_wchar
[MAX_PATH
];
1248 memset(current_path
, 0, MAX_PATH
);
1249 p_tr2_sys__Current_get(current_path
);
1250 memset(current_path_wchar
, 0, MAX_PATH
);
1251 p_tr2_sys__Current_get_wchar(current_path_wchar
);
1253 p_tr2_sys__Statvfs(&info
, current_path
);
1254 ok(info
.capacity
>= info
.free
, "test_tr2_sys__Statvfs(): info.capacity < info.free\n");
1255 ok(info
.free
>= info
.available
, "test_tr2_sys__Statvfs(): info.free < info.available\n");
1257 p_tr2_sys__Statvfs_wchar(&info
, current_path_wchar
);
1258 ok(info
.capacity
>= info
.free
, "tr2_sys__Statvfs_wchar(): info.capacity < info.free\n");
1259 ok(info
.free
>= info
.available
, "tr2_sys__Statvfs_wchar(): info.free < info.available\n");
1261 p_tr2_sys__Statvfs(&info
, NULL
);
1262 ok(info
.available
== 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1263 0, wine_dbgstr_longlong(info
.available
));
1264 ok(info
.capacity
== 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1265 0, wine_dbgstr_longlong(info
.capacity
));
1266 ok(info
.free
== 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1267 0, wine_dbgstr_longlong(info
.free
));
1269 p_tr2_sys__Statvfs(&info
, "not_exist");
1270 ok(info
.available
== 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1271 0, wine_dbgstr_longlong(info
.available
));
1272 ok(info
.capacity
== 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1273 0, wine_dbgstr_longlong(info
.capacity
));
1274 ok(info
.free
== 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1275 0, wine_dbgstr_longlong(info
.free
));
1278 static void test_tr2_sys__Stat(void)
1280 int i
, err_code
, ret
;
1289 { NULL
, status_unknown
, ERROR_INVALID_PARAMETER
, FALSE
},
1290 { "tr2_test_dir", directory_file
, ERROR_SUCCESS
, FALSE
},
1291 { "tr2_test_dir\\f1", regular_file
, ERROR_SUCCESS
, FALSE
},
1292 { "tr2_test_dir\\not_exist_file ", file_not_found
, ERROR_SUCCESS
, FALSE
},
1293 { "tr2_test_dir\\??invalid_name>>", file_not_found
, ERROR_SUCCESS
, FALSE
},
1294 { "tr2_test_dir\\f1_link" , regular_file
, ERROR_SUCCESS
, TRUE
},
1295 { "tr2_test_dir\\dir_link", directory_file
, ERROR_SUCCESS
, TRUE
},
1297 WCHAR testW
[] = {'t','r','2','_','t','e','s','t','_','d','i','r',0};
1298 WCHAR testW2
[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
1300 CreateDirectoryA("tr2_test_dir", NULL
);
1301 file
= CreateFileA("tr2_test_dir/f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1302 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1303 ok(CloseHandle(file
), "CloseHandle\n");
1304 SetLastError(0xdeadbeef);
1305 ret
= pCreateSymbolicLinkA
? pCreateSymbolicLinkA("tr2_test_dir/f1_link", "tr2_test_dir/f1", 0) : FALSE
;
1306 if(!ret
&& (!pCreateSymbolicLinkA
|| GetLastError()==ERROR_PRIVILEGE_NOT_HELD
||GetLastError()==ERROR_INVALID_FUNCTION
)) {
1307 tests
[5].ret
= tests
[6].ret
= file_not_found
;
1308 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1310 ok(ret
, "CreateSymbolicLinkA failed\n");
1311 ok(pCreateSymbolicLinkA("tr2_test_dir/dir_link", "tr2_test_dir", 1), "CreateSymbolicLinkA failed\n");
1314 file
= CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1315 PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
, 2, 1024, 1024,
1316 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1317 ok(file
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1318 err_code
= 0xdeadbeef;
1319 val
= p_tr2_sys__Stat("\\\\.\\PiPe\\tests_pipe.c", &err_code
);
1320 todo_wine
ok(regular_file
== val
, "tr2_sys__Stat(): expect: regular_file, got %d\n", val
);
1321 todo_wine
ok(ERROR_SUCCESS
== err_code
, "tr2_sys__Stat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code
);
1322 err_code
= 0xdeadbeef;
1323 val
= p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code
);
1324 ok(status_unknown
== val
, "tr2_sys__Lstat(): expect: status_unknown, got %d\n", val
);
1325 todo_wine
ok(ERROR_PIPE_BUSY
== err_code
, "tr2_sys__Lstat(): err_code expect: ERROR_PIPE_BUSY, got %d\n", err_code
);
1326 ok(CloseHandle(file
), "CloseHandle\n");
1327 file
= CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1328 PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
, 2, 1024, 1024,
1329 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1330 ok(file
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1331 err_code
= 0xdeadbeef;
1332 val
= p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code
);
1333 todo_wine
ok(regular_file
== val
, "tr2_sys__Lstat(): expect: regular_file, got %d\n", val
);
1334 todo_wine
ok(ERROR_SUCCESS
== err_code
, "tr2_sys__Lstat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code
);
1335 ok(CloseHandle(file
), "CloseHandle\n");
1337 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
1338 err_code
= 0xdeadbeef;
1339 val
= p_tr2_sys__Stat(tests
[i
].path
, &err_code
);
1340 todo_wine_if(tests
[i
].is_todo
)
1341 ok(tests
[i
].ret
== val
, "tr2_sys__Stat(): test %d expect: %d, got %d\n", i
+1, tests
[i
].ret
, val
);
1342 ok(tests
[i
].err_code
== err_code
, "tr2_sys__Stat(): test %d err_code expect: %d, got %d\n",
1343 i
+1, tests
[i
].err_code
, err_code
);
1345 /* test tr2_sys__Lstat */
1346 err_code
= 0xdeadbeef;
1347 val
= p_tr2_sys__Lstat(tests
[i
].path
, &err_code
);
1348 todo_wine_if(tests
[i
].is_todo
)
1349 ok(tests
[i
].ret
== val
, "tr2_sys__Lstat(): test %d expect: %d, got %d\n", i
+1, tests
[i
].ret
, val
);
1350 ok(tests
[i
].err_code
== err_code
, "tr2_sys__Lstat(): test %d err_code expect: %d, got %d\n",
1351 i
+1, tests
[i
].err_code
, err_code
);
1354 err_code
= 0xdeadbeef;
1355 val
= p_tr2_sys__Stat_wchar(testW
, &err_code
);
1356 ok(directory_file
== val
, "tr2_sys__Stat_wchar() expect directory_file, got %d\n", val
);
1357 ok(ERROR_SUCCESS
== err_code
, "tr2_sys__Stat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code
);
1358 err_code
= 0xdeadbeef;
1359 val
= p_tr2_sys__Lstat_wchar(testW2
, &err_code
);
1360 ok(regular_file
== val
, "tr2_sys__Lstat_wchar() expect regular_file, got %d\n", val
);
1361 ok(ERROR_SUCCESS
== err_code
, "tr2_sys__Lstat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code
);
1364 todo_wine
ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1365 todo_wine
ok(RemoveDirectoryA("tr2_test_dir/dir_link"), "expect tr2_test_dir/dir_link to exist\n");
1367 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1368 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1371 static void test_tr2_sys__Last_write_time(void)
1375 __int64 last_write_time
, newtime
;
1376 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1377 ok(ret
== 1, "tr2_sys__Make_dir() expect 1 got %d\n", ret
);
1379 file
= CreateFileA("tr2_test_dir/f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1380 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1383 last_write_time
= p_tr2_sys__Last_write_time("tr2_test_dir/f1");
1384 newtime
= last_write_time
+ 123456789;
1385 p_tr2_sys__Last_write_time_set("tr2_test_dir/f1", newtime
);
1386 todo_wine
ok(last_write_time
== p_tr2_sys__Last_write_time("tr2_test_dir/f1"),
1387 "last_write_time should have changed: %s\n",
1388 wine_dbgstr_longlong(last_write_time
));
1391 last_write_time
= p_tr2_sys__Last_write_time("not_exist");
1392 ok(errno
== 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno
);
1393 ok(last_write_time
== 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time
));
1394 last_write_time
= p_tr2_sys__Last_write_time(NULL
);
1395 ok(last_write_time
== 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time
));
1397 p_tr2_sys__Last_write_time_set("not_exist", newtime
);
1399 p_tr2_sys__Last_write_time_set(NULL
, newtime
);
1400 ok(errno
== 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno
);
1402 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1403 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1404 ok(ret
== 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1407 static void test_tr2_sys__dir_operation(void)
1409 char *file_name
, first_file_name
[MAX_PATH
], dest
[MAX_PATH
], longer_path
[MAX_PATH
];
1410 HANDLE file
, result_handle
;
1411 enum file_type type
;
1412 int err
, num_of_f1
= 0, num_of_f2
= 0, num_of_sub_dir
= 0, num_of_other_files
= 0;
1414 CreateDirectoryA("tr2_test_dir", NULL
);
1415 file
= CreateFileA("tr2_test_dir/f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1416 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1418 file
= CreateFileA("tr2_test_dir/f2", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1419 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1421 CreateDirectoryA("tr2_test_dir/sub_dir", NULL
);
1422 file
= CreateFileA("tr2_test_dir/sub_dir/sub_f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1423 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1426 memset(longer_path
, 0, MAX_PATH
);
1427 GetCurrentDirectoryA(MAX_PATH
, longer_path
);
1428 strcat(longer_path
, "\\tr2_test_dir\\");
1429 while(lstrlenA(longer_path
) < MAX_PATH
-1)
1430 strcat(longer_path
, "s");
1431 ok(lstrlenA(longer_path
) == MAX_PATH
-1, "tr2_sys__Open_dir(): expect MAX_PATH, got %d\n", lstrlenA(longer_path
));
1432 memset(first_file_name
, 0, MAX_PATH
);
1433 type
= err
= 0xdeadbeef;
1434 result_handle
= NULL
;
1435 result_handle
= p_tr2_sys__Open_dir(first_file_name
, longer_path
, &err
, &type
);
1436 ok(result_handle
== NULL
, "tr2_sys__Open_dir(): expect NULL, got %p\n", result_handle
);
1437 ok(!*first_file_name
, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name
);
1438 ok(err
== ERROR_BAD_PATHNAME
, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err
);
1439 ok((int)type
== 0xdeadbeef, "tr2_sys__Open_dir(): expect 0xdeadbeef, got %d\n", type
);
1441 memset(first_file_name
, 0, MAX_PATH
);
1442 memset(dest
, 0, MAX_PATH
);
1443 err
= type
= 0xdeadbeef;
1444 result_handle
= NULL
;
1445 result_handle
= p_tr2_sys__Open_dir(first_file_name
, "tr2_test_dir", &err
, &type
);
1446 ok(result_handle
!= NULL
, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle
);
1447 ok(err
== ERROR_SUCCESS
, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err
);
1448 file_name
= first_file_name
;
1450 if (!strcmp(file_name
, "f1")) {
1452 ok(type
== regular_file
, "expect regular_file, got %d\n", type
);
1453 }else if(!strcmp(file_name
, "f2")) {
1455 ok(type
== regular_file
, "expect regular_file, got %d\n", type
);
1456 }else if(!strcmp(file_name
, "sub_dir")) {
1458 ok(type
== directory_file
, "expect directory_file, got %d\n", type
);
1460 ++num_of_other_files
;
1462 file_name
= p_tr2_sys__Read_dir(dest
, result_handle
, &type
);
1464 ok(type
== status_unknown
, "p_tr2_sys__Read_dir(): expect: status_unknown, got %d\n", type
);
1465 p_tr2_sys__Close_dir(result_handle
);
1466 ok(result_handle
!= NULL
, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle
);
1467 ok(num_of_f1
== 1, "found f1 %d times\n", num_of_f1
);
1468 ok(num_of_f2
== 1, "found f2 %d times\n", num_of_f2
);
1469 ok(num_of_sub_dir
== 1, "found sub_dir %d times\n", num_of_sub_dir
);
1470 ok(num_of_other_files
== 0, "found %d other files\n", num_of_other_files
);
1472 memset(first_file_name
, 0, MAX_PATH
);
1473 err
= type
= 0xdeadbeef;
1474 result_handle
= file
;
1475 result_handle
= p_tr2_sys__Open_dir(first_file_name
, "not_exist", &err
, &type
);
1476 ok(result_handle
== NULL
, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle
);
1477 todo_wine
ok(err
== ERROR_BAD_PATHNAME
, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err
);
1478 ok((int)type
== 0xdeadbeef, "tr2_sys__Open_dir(): expect: 0xdeadbeef, got %d\n", type
);
1479 ok(!*first_file_name
, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name
);
1481 CreateDirectoryA("empty_dir", NULL
);
1482 memset(first_file_name
, 0, MAX_PATH
);
1483 err
= type
= 0xdeadbeef;
1484 result_handle
= file
;
1485 result_handle
= p_tr2_sys__Open_dir(first_file_name
, "empty_dir", &err
, &type
);
1486 ok(result_handle
== NULL
, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle
);
1487 ok(err
== ERROR_SUCCESS
, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err
);
1488 ok(type
== status_unknown
, "tr2_sys__Open_dir(): expect: status_unknown, got %d\n", type
);
1489 ok(!*first_file_name
, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name
);
1490 p_tr2_sys__Close_dir(result_handle
);
1491 ok(result_handle
== NULL
, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle
);
1493 ok(RemoveDirectoryA("empty_dir"), "expect empty_dir to exist\n");
1494 ok(DeleteFileA("tr2_test_dir/sub_dir/sub_f1"), "expect tr2_test_dir/sub_dir/sub_f1 to exist\n");
1495 ok(RemoveDirectoryA("tr2_test_dir/sub_dir"), "expect tr2_test_dir/sub_dir to exist\n");
1496 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1497 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1498 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1501 static void test_tr2_sys__Link(void)
1504 HANDLE file
, h1
, h2
;
1505 BY_HANDLE_FILE_INFORMATION info1
, info2
;
1506 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
1507 LARGE_INTEGER file_size
;
1509 char const *existing_path
;
1510 char const *new_path
;
1511 MSVCP_bool fail_if_exists
;
1514 { "f1", "f1_link", TRUE
, ERROR_SUCCESS
},
1515 { "f1", "tr2_test_dir\\f1_link", TRUE
, ERROR_SUCCESS
},
1516 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", TRUE
, ERROR_SUCCESS
},
1517 { "tr2_test_dir", "dir_link", TRUE
, ERROR_ACCESS_DENIED
},
1518 { NULL
, "NULL_link", TRUE
, ERROR_INVALID_PARAMETER
},
1519 { "f1", NULL
, TRUE
, ERROR_INVALID_PARAMETER
},
1520 { "not_exist", "not_exist_link", TRUE
, ERROR_FILE_NOT_FOUND
},
1521 { "f1", "not_exist_dir\\f1_link", TRUE
, ERROR_PATH_NOT_FOUND
}
1524 memset(current_path
, 0, MAX_PATH
);
1525 GetCurrentDirectoryA(MAX_PATH
, current_path
);
1526 memset(temp_path
, 0, MAX_PATH
);
1527 GetTempPathA(MAX_PATH
, temp_path
);
1528 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
1530 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1531 ok(ret
== 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1532 file
= CreateFileA("f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1533 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1534 file_size
.QuadPart
= 7;
1535 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1536 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1539 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
1541 ret
= p_tr2_sys__Link(tests
[i
].existing_path
, tests
[i
].new_path
);
1542 ok(ret
== tests
[i
].last_error
, "tr2_sys__Link(): test %d expect: %d, got %d\n",
1543 i
+1, tests
[i
].last_error
, ret
);
1544 ok(errno
== 0xdeadbeef, "tr2_sys__Link(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1545 if(ret
== ERROR_SUCCESS
)
1546 ok(p_tr2_sys__File_size(tests
[i
].existing_path
) == p_tr2_sys__File_size(tests
[i
].new_path
),
1547 "tr2_sys__Link(): test %d failed, two files' size are not equal\n", i
+1);
1550 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1551 ok(p_tr2_sys__File_size("f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link") &&
1552 p_tr2_sys__File_size("tr2_test_dir/f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link_link"),
1553 "tr2_sys__Link(): expect links' size are equal, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size("tr2_test_dir/f1_link_link")));
1554 ok(p_tr2_sys__File_size("f1_link") == 7, "tr2_sys__Link(): expect f1_link's size equals to 7, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size("f1_link")));
1556 file
= CreateFileA("f1_link", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1557 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1558 file_size
.QuadPart
= 20;
1559 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1560 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1562 h1
= CreateFileA("f1_link", 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1563 NULL
, OPEN_EXISTING
, 0, 0);
1564 ok(h1
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1565 ok(GetFileInformationByHandle(h1
, &info1
), "GetFileInformationByHandle failed\n");
1567 h2
= CreateFileA("tr2_test_dir/f1_link", 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1568 NULL
, OPEN_EXISTING
, 0, 0);
1569 ok(h2
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1570 ok(GetFileInformationByHandle(h2
, &info2
), "GetFileInformationByHandle failed\n");
1572 ok(info1
.nFileIndexHigh
== info2
.nFileIndexHigh
1573 && info1
.nFileIndexLow
== info2
.nFileIndexLow
,
1574 "tr2_sys__Link(): test %d expect two files equivalent\n", i
+1);
1575 ok(p_tr2_sys__File_size("f1_link") == 20, "tr2_sys__Link(): expect f1_link's size equals to 20, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size("f1_link")));
1577 ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1578 ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1579 ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1580 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1581 ok(ret
== 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1582 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
1585 static void test_tr2_sys__Symlink(void)
1589 LARGE_INTEGER file_size
;
1591 char const *existing_path
;
1592 char const *new_path
;
1596 { "f1", "f1_link", ERROR_SUCCESS
, FALSE
},
1597 { "f1", "tr2_test_dir\\f1_link", ERROR_SUCCESS
, FALSE
},
1598 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", ERROR_SUCCESS
, FALSE
},
1599 { "tr2_test_dir", "dir_link", ERROR_SUCCESS
, FALSE
},
1600 { NULL
, "NULL_link", ERROR_INVALID_PARAMETER
, FALSE
},
1601 { "f1", NULL
, ERROR_INVALID_PARAMETER
, FALSE
},
1602 { "not_exist", "not_exist_link", ERROR_SUCCESS
, FALSE
},
1603 { "f1", "not_exist_dir\\f1_link", ERROR_PATH_NOT_FOUND
, TRUE
}
1606 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1607 ok(ret
== 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1608 file
= CreateFileA("f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1609 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1610 file_size
.QuadPart
= 7;
1611 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1612 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1615 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
1617 SetLastError(0xdeadbeef);
1618 ret
= p_tr2_sys__Symlink(tests
[i
].existing_path
, tests
[i
].new_path
);
1619 if(!i
&& (ret
==ERROR_PRIVILEGE_NOT_HELD
|| ret
==ERROR_INVALID_FUNCTION
|| ret
==ERROR_CALL_NOT_IMPLEMENTED
)) {
1620 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1621 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1622 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1623 ok(ret
== 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1627 ok(errno
== 0xdeadbeef, "tr2_sys__Symlink(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1628 todo_wine_if(tests
[i
].is_todo
)
1629 ok(ret
== tests
[i
].last_error
, "tr2_sys__Symlink(): test %d expect: %d, got %d\n", i
+1, tests
[i
].last_error
, ret
);
1630 if(ret
== ERROR_SUCCESS
)
1631 ok(p_tr2_sys__File_size(tests
[i
].new_path
) == 0, "tr2_sys__Symlink(): expect 0, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size(tests
[i
].new_path
)));
1634 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1635 todo_wine
ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1636 todo_wine
ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1637 todo_wine
ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1638 todo_wine
ok(DeleteFileA("not_exist_link"), "expect not_exist_link to exist\n");
1639 todo_wine
ok(DeleteFileA("dir_link"), "expect dir_link to exist\n");
1640 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1641 ok(ret
== 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1644 static void test_tr2_sys__Unlink(void)
1646 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
1649 LARGE_INTEGER file_size
;
1655 { "tr2_test_dir\\f1_symlink", ERROR_SUCCESS
, TRUE
},
1656 { "tr2_test_dir\\f1_link", ERROR_SUCCESS
, FALSE
},
1657 { "tr2_test_dir\\f1", ERROR_SUCCESS
, FALSE
},
1658 { "tr2_test_dir", ERROR_ACCESS_DENIED
, FALSE
},
1659 { "not_exist", ERROR_FILE_NOT_FOUND
, FALSE
},
1660 { "not_exist_dir\\not_exist_file", ERROR_PATH_NOT_FOUND
, FALSE
},
1661 { NULL
, ERROR_PATH_NOT_FOUND
, FALSE
}
1664 GetCurrentDirectoryA(MAX_PATH
, current_path
);
1665 GetTempPathA(MAX_PATH
, temp_path
);
1666 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
1668 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1669 ok(ret
== 1, "tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1670 file
= CreateFileA("tr2_test_dir/f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1671 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1672 file_size
.QuadPart
= 7;
1673 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1674 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1677 ret
= p_tr2_sys__Symlink("tr2_test_dir/f1", "tr2_test_dir/f1_symlink");
1678 if(ret
==ERROR_PRIVILEGE_NOT_HELD
|| ret
==ERROR_INVALID_FUNCTION
|| ret
==ERROR_CALL_NOT_IMPLEMENTED
) {
1679 tests
[0].last_error
= ERROR_FILE_NOT_FOUND
;
1680 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1682 ok(ret
== ERROR_SUCCESS
, "tr2_sys__Symlink(): expect: ERROR_SUCCESS, got %d\n", ret
);
1684 ret
= p_tr2_sys__Link("tr2_test_dir/f1", "tr2_test_dir/f1_link");
1685 ok(ret
== ERROR_SUCCESS
, "tr2_sys__Link(): expect: ERROR_SUCCESS, got %d\n", ret
);
1687 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
1689 ret
= p_tr2_sys__Unlink(tests
[i
].path
);
1690 todo_wine_if(tests
[i
].is_todo
)
1691 ok(ret
== tests
[i
].last_error
, "tr2_sys__Unlink(): test %d expect: %d, got %d\n",
1692 i
+1, tests
[i
].last_error
, ret
);
1693 ok(errno
== 0xdeadbeef, "tr2_sys__Unlink(): test %d errno expect: 0xdeadbeef, got %d\n", i
+1, ret
);
1696 ok(!DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 not to exist\n");
1697 ok(!DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link not to exist\n");
1698 ok(!DeleteFileA("tr2_test_dir/f1_symlink"), "expect tr2_test_dir/f1_symlink not to exist\n");
1699 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1700 ok(ret
== 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1702 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
1705 static int __cdecl
thrd_thread(void *arg
)
1710 *thr
= p__Thrd_current();
1714 static void test_thrd(void)
1722 const HANDLE hnd1
= (HANDLE
)0xcccccccc;
1723 const HANDLE hnd2
= (HANDLE
)0xdeadbeef;
1724 xtime xt
, before
, after
;
1728 struct test testeq
[] = {
1729 { {0, 0}, {0, 0}, 1 },
1730 { {0, 1}, {0, 0}, 0 },
1731 { {hnd1
, 0}, {hnd1
, 1}, 0 },
1732 { {hnd1
, 0}, {hnd2
, 0}, 1 }
1735 struct test testlt
[] = {
1736 { {0, 0}, {0, 0}, 0 },
1737 { {0, 0}, {0, 1}, 1 },
1738 { {0, 1}, {0, 0}, 0 },
1739 { {hnd1
, 0}, {hnd2
, 0}, 0 },
1740 { {hnd1
, 0}, {hnd2
, 1}, 1 }
1743 /* test for equal */
1744 for(i
=0; i
<sizeof(testeq
)/sizeof(testeq
[0]); i
++) {
1745 ret
= p__Thrd_equal(testeq
[i
].a
, testeq
[i
].b
);
1746 ok(ret
== testeq
[i
].r
, "(%p %u) = (%p %u) expected %d, got %d\n",
1747 testeq
[i
].a
.hnd
, testeq
[i
].a
.id
, testeq
[i
].b
.hnd
, testeq
[i
].b
.id
, testeq
[i
].r
, ret
);
1750 /* test for less than */
1751 for(i
=0; i
<sizeof(testlt
)/sizeof(testlt
[0]); i
++) {
1752 ret
= p__Thrd_lt(testlt
[i
].a
, testlt
[i
].b
);
1753 ok(ret
== testlt
[i
].r
, "(%p %u) < (%p %u) expected %d, got %d\n",
1754 testlt
[i
].a
.hnd
, testlt
[i
].a
.id
, testlt
[i
].b
.hnd
, testlt
[i
].b
.id
, testlt
[i
].r
, ret
);
1757 /* test for sleep */
1758 if (0) /* crash on Windows */
1759 p__Thrd_sleep(NULL
);
1760 p_xtime_get(&xt
, 1);
1762 p_xtime_get(&before
, 1);
1764 p_xtime_get(&after
, 1);
1765 diff
= p__Xtime_diff_to_millis2(&after
, &before
);
1766 ok(diff
> 2000 - TIMEDELTA
, "got %d\n", diff
);
1768 /* test for current */
1769 ta
= p__Thrd_current();
1770 tb
= p__Thrd_current();
1771 ok(ta
.id
== tb
.id
, "got a %d b %d\n", ta
.id
, tb
.id
);
1772 ok(ta
.id
== GetCurrentThreadId(), "expected %d, got %d\n", GetCurrentThreadId(), ta
.id
);
1773 /* these can be different if new threads are created at same time */
1774 ok(ta
.hnd
== tb
.hnd
, "got a %p b %p\n", ta
.hnd
, tb
.hnd
);
1775 ok(!CloseHandle(ta
.hnd
), "handle %p not closed\n", ta
.hnd
);
1776 ok(!CloseHandle(tb
.hnd
), "handle %p not closed\n", tb
.hnd
);
1778 /* test for create/join */
1779 if (0) /* crash on Windows */
1781 p__Thrd_create(NULL
, thrd_thread
, NULL
);
1782 p__Thrd_create(&ta
, NULL
, NULL
);
1785 ret
= p__Thrd_create(&ta
, thrd_thread
, (void*)&tb
);
1786 ok(!ret
, "failed to create thread, got %d\n", ret
);
1787 ret
= p__Thrd_join(ta
, &r
);
1788 ok(!ret
, "failed to join thread, got %d\n", ret
);
1789 ok(ta
.id
== tb
.id
, "expected %d, got %d\n", ta
.id
, tb
.id
);
1790 ok(ta
.hnd
!= tb
.hnd
, "same handles, got %p\n", ta
.hnd
);
1791 ok(r
== 0x42, "expected 0x42, got %d\n", r
);
1792 ret
= p__Thrd_detach(ta
);
1793 ok(ret
== 4, "_Thrd_detach should have failed with error 4, got %d\n", ret
);
1795 ret
= p__Thrd_create(&ta
, thrd_thread
, NULL
);
1796 ok(!ret
, "failed to create thread, got %d\n", ret
);
1797 ret
= p__Thrd_detach(ta
);
1798 ok(!ret
, "_Thrd_detach failed, got %d\n", ret
);
1802 #define NUM_THREADS 10
1814 static int __cdecl
cnd_wait_thread(void *arg
)
1816 struct cndmtx
*cm
= arg
;
1819 p__Mtx_lock(&cm
->mtx
);
1821 if(InterlockedIncrement(&cm
->started
) == cm
->thread_no
)
1822 SetEvent(cm
->initialized
);
1824 if(cm
->timed_wait
) {
1827 p_xtime_get(&xt
, 1);
1829 r
= p__Cnd_timedwait(&cm
->cnd
, &cm
->mtx
, &xt
);
1830 ok(!r
, "timed wait failed\n");
1832 r
= p__Cnd_wait(&cm
->cnd
, &cm
->mtx
);
1833 ok(!r
, "wait failed\n");
1836 p__Mtx_unlock(&cm
->mtx
);
1840 static void test_cnd(void)
1842 _Thrd_t threads
[NUM_THREADS
];
1843 xtime xt
, before
, after
;
1850 r
= p__Cnd_init(&cnd
);
1851 ok(!r
, "failed to init cnd\n");
1853 r
= p__Mtx_init(&mtx
, 0);
1854 ok(!r
, "failed to init mtx\n");
1856 if (0) /* crash on Windows */
1859 p__Cnd_wait(NULL
, &mtx
);
1860 p__Cnd_wait(&cnd
, NULL
);
1861 p__Cnd_timedwait(NULL
, &mtx
, &xt
);
1862 p__Cnd_timedwait(&cnd
, &mtx
, &xt
);
1864 p__Cnd_destroy(NULL
);
1866 /* test _Cnd_signal/_Cnd_wait */
1867 cm
.initialized
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1872 cm
.timed_wait
= FALSE
;
1873 p__Thrd_create(&threads
[0], cnd_wait_thread
, (void*)&cm
);
1875 WaitForSingleObject(cm
.initialized
, INFINITE
);
1877 p__Mtx_unlock(&mtx
);
1879 r
= p__Cnd_signal(&cm
.cnd
);
1880 ok(!r
, "failed to signal\n");
1881 p__Thrd_join(threads
[0], NULL
);
1883 /* test _Cnd_timedwait time out */
1885 p_xtime_get(&before
, 1);
1888 r
= p__Cnd_timedwait(&cnd
, &mtx
, &xt
);
1889 p_xtime_get(&after
, 1);
1890 p__Mtx_unlock(&mtx
);
1892 diff
= p__Xtime_diff_to_millis2(&after
, &before
);
1893 ok(r
== 2, "should have timed out\n");
1894 ok(diff
> 1000 - TIMEDELTA
, "got %d\n", diff
);
1896 /* test _Cnd_timedwait */
1898 cm
.timed_wait
= TRUE
;
1899 p__Thrd_create(&threads
[0], cnd_wait_thread
, (void*)&cm
);
1901 WaitForSingleObject(cm
.initialized
, INFINITE
);
1903 p__Mtx_unlock(&mtx
);
1905 r
= p__Cnd_signal(&cm
.cnd
);
1906 ok(!r
, "failed to signal\n");
1907 p__Thrd_join(threads
[0], NULL
);
1909 /* test _Cnd_do_broadcast_at_thread_exit */
1911 cm
.timed_wait
= FALSE
;
1912 p__Thrd_create(&threads
[0], cnd_wait_thread
, (void*)&cm
);
1914 WaitForSingleObject(cm
.initialized
, INFINITE
);
1918 p__Cnd_unregister_at_thread_exit((_Mtx_t
*)0xdeadbeef);
1919 p__Cnd_register_at_thread_exit(&cnd
, &mtx
, &r
);
1920 ok(r
== 0xcafe, "r = %x\n", r
);
1921 p__Cnd_register_at_thread_exit(&cnd
, &mtx
, &r
);
1922 p__Cnd_unregister_at_thread_exit(&mtx
);
1923 p__Cnd_do_broadcast_at_thread_exit();
1924 ok(mtx
->count
== 1, "mtx.count = %d\n", mtx
->count
);
1926 p__Cnd_register_at_thread_exit(&cnd
, &mtx
, &r
);
1927 ok(r
== 0xcafe, "r = %x\n", r
);
1929 p__Cnd_do_broadcast_at_thread_exit();
1930 ok(r
== 1, "r = %x\n", r
);
1931 p__Thrd_join(threads
[0], NULL
);
1933 /* crash if _Cnd_do_broadcast_at_thread_exit is called on exit */
1934 p__Cnd_register_at_thread_exit((_Cnd_t
*)0xdeadbeef, (_Mtx_t
*)0xdeadbeef, (int*)0xdeadbeef);
1936 /* test _Cnd_broadcast */
1938 cm
.thread_no
= NUM_THREADS
;
1940 for(i
= 0; i
< cm
.thread_no
; i
++)
1941 p__Thrd_create(&threads
[i
], cnd_wait_thread
, (void*)&cm
);
1943 WaitForSingleObject(cm
.initialized
, INFINITE
);
1945 p__Mtx_unlock(&mtx
);
1947 r
= p__Cnd_broadcast(&cnd
);
1948 ok(!r
, "failed to broadcast\n");
1949 for(i
= 0; i
< cm
.thread_no
; i
++)
1950 p__Thrd_join(threads
[i
], NULL
);
1952 /* test broadcast with _Cnd_destroy */
1954 for(i
= 0; i
< cm
.thread_no
; i
++)
1955 p__Thrd_create(&threads
[i
], cnd_wait_thread
, (void*)&cm
);
1957 WaitForSingleObject(cm
.initialized
, INFINITE
);
1959 p__Mtx_unlock(&mtx
);
1961 p__Cnd_destroy(&cnd
);
1962 for(i
= 0; i
< cm
.thread_no
; i
++)
1963 p__Thrd_join(threads
[i
], NULL
);
1965 p__Mtx_destroy(&mtx
);
1966 CloseHandle(cm
.initialized
);
1971 const char* export_name
;
1972 } vbtable_size_exports_list
[] = {
1973 {{0x20, 0x20}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"},
1974 {{0x10, 0x10}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"},
1975 {{0x20, 0x20}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"},
1976 {{0x10, 0x10}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"},
1977 {{0x20, 0x20}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"},
1978 {{0x10, 0x10}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"},
1979 {{0x18, 0x18}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"},
1980 {{0x18, 0x18}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"},
1981 {{0x18, 0x18}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"},
1982 {{ 0x8, 0x10}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"},
1983 {{ 0x8, 0x10}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"},
1984 {{ 0x8, 0x10}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"},
1988 static void test_vbtable_size_exports(void)
1991 const int *p_vbtable
;
1992 int arch_idx
= (sizeof(void*) == 8);
1994 for (i
= 0; vbtable_size_exports_list
[i
].export_name
; i
++)
1996 SET(p_vbtable
, vbtable_size_exports_list
[i
].export_name
);
1998 ok(p_vbtable
[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable
[0]);
1999 ok(p_vbtable
[1] == vbtable_size_exports_list
[i
].value
[arch_idx
],
2000 "%d: %s[1] wrong, got 0x%x\n", i
, vbtable_size_exports_list
[i
].export_name
, p_vbtable
[1]);
2004 HANDLE _Pad__Launch_returned
;
2007 /* TODO: this should be a __thiscall function */
2008 static unsigned int __stdcall
vtbl_func__Go(void)
2010 static unsigned int __cdecl
vtbl_func__Go(_Pad
*this)
2015 ret
= WaitForSingleObject(_Pad__Launch_returned
, 100);
2016 ok(ret
== WAIT_TIMEOUT
, "WiatForSingleObject returned %x\n", ret
);
2017 ok(!pad
.mtx
->count
, "pad.mtx.count = %d\n", pad
.mtx
->count
);
2018 ok(!pad
.launched
, "pad.launched = %x\n", pad
.launched
);
2019 call_func1(p__Pad__Release
, &pad
);
2020 ok(pad
.launched
, "pad.launched = %x\n", pad
.launched
);
2021 ret
= WaitForSingleObject(_Pad__Launch_returned
, 100);
2022 ok(ret
== WAIT_OBJECT_0
, "WiatForSingleObject returned %x\n", ret
);
2023 ok(pad
.mtx
->count
== 1, "pad.mtx.count = %d\n", pad
.mtx
->count
);
2027 static void test__Pad(void)
2031 vtable_ptr pfunc
= (vtable_ptr
)&vtbl_func__Go
;
2033 _Pad__Launch_returned
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2035 pad
.vtable
= (void*)1;
2038 pad
.launched
= TRUE
;
2039 memset(&pad_copy
, 0, sizeof(pad_copy
));
2040 call_func2(p__Pad_copy_ctor
, &pad_copy
, &pad
);
2041 ok(pad_copy
.vtable
!= (void*)1, "pad_copy.vtable was not set\n");
2042 ok(pad_copy
.cnd
== (void*)2, "pad_copy.cnd = %p\n", pad_copy
.cnd
);
2043 ok(pad_copy
.mtx
== (void*)3, "pad_copy.mtx = %p\n", pad_copy
.mtx
);
2044 ok(pad_copy
.launched
, "pad_copy.launched = %x\n", pad_copy
.launched
);
2046 memset(&pad_copy
, 0xde, sizeof(pad_copy
));
2047 pad_copy
.vtable
= (void*)4;
2048 pad_copy
.cnd
= (void*)5;
2049 pad_copy
.mtx
= (void*)6;
2050 pad_copy
.launched
= FALSE
;
2051 call_func2(p__Pad_op_assign
, &pad_copy
, &pad
);
2052 ok(pad_copy
.vtable
== (void*)4, "pad_copy.vtable was set\n");
2053 ok(pad_copy
.cnd
== (void*)2, "pad_copy.cnd = %p\n", pad_copy
.cnd
);
2054 ok(pad_copy
.mtx
== (void*)3, "pad_copy.mtx = %p\n", pad_copy
.mtx
);
2055 ok(pad_copy
.launched
, "pad_copy.launched = %x\n", pad_copy
.launched
);
2057 call_func1(p__Pad_ctor
, &pad
);
2058 call_func2(p__Pad_copy_ctor
, &pad_copy
, &pad
);
2059 ok(pad
.vtable
== pad_copy
.vtable
, "pad.vtable = %p, pad_copy.vtable = %p\n", pad
.vtable
, pad_copy
.vtable
);
2060 ok(pad
.cnd
== pad_copy
.cnd
, "pad.cnd = %p, pad_copy.cnd = %p\n", pad
.cnd
, pad_copy
.cnd
);
2061 ok(pad
.mtx
== pad_copy
.mtx
, "pad.mtx = %p, pad_copy.mtx = %p\n", pad
.mtx
, pad_copy
.mtx
);
2062 ok(pad
.launched
== pad_copy
.launched
, "pad.launched = %x, pad_copy.launched = %x\n", pad
.launched
, pad_copy
.launched
);
2063 call_func1(p__Pad_dtor
, &pad
);
2064 /* call_func1(p__Pad_dtor, &pad_copy); - copy constructor is broken, this causes a crash */
2066 memset(&pad
, 0xfe, sizeof(pad
));
2067 call_func1(p__Pad_ctor
, &pad
);
2068 ok(!pad
.launched
, "pad.launched = %x\n", pad
.launched
);
2069 ok(pad
.mtx
->count
== 1, "pad.mtx.count = %d\n", pad
.mtx
->count
);
2071 pad
.vtable
= &pfunc
;
2072 call_func2(p__Pad__Launch
, &pad
, &thrd
);
2073 SetEvent(_Pad__Launch_returned
);
2074 ok(!p__Thrd_join(thrd
, NULL
), "_Thrd_join failed\n");
2076 call_func1(p__Pad_dtor
, &pad
);
2077 CloseHandle(_Pad__Launch_returned
);
2080 static void test_threads__Mtx(void)
2084 p_threads__Mtx_new(&mtx
);
2085 ok(mtx
!= NULL
, "mtx == NULL\n");
2087 p_threads__Mtx_lock(mtx
);
2088 p_threads__Mtx_lock(mtx
);
2089 p_threads__Mtx_unlock(mtx
);
2090 p_threads__Mtx_unlock(mtx
);
2091 p_threads__Mtx_unlock(mtx
);
2093 p_threads__Mtx_delete(mtx
);
2096 START_TEST(msvcp120
)
2099 test__Xtime_diff_to_millis2();
2108 test_tr2_sys__File_size();
2109 test_tr2_sys__Equivalent();
2110 test_tr2_sys__Current_get();
2111 test_tr2_sys__Current_set();
2112 test_tr2_sys__Make_dir();
2113 test_tr2_sys__Remove_dir();
2114 test_tr2_sys__Copy_file();
2115 test_tr2_sys__Rename();
2116 test_tr2_sys__Statvfs();
2117 test_tr2_sys__Stat();
2118 test_tr2_sys__Last_write_time();
2119 test_tr2_sys__dir_operation();
2120 test_tr2_sys__Link();
2121 test_tr2_sys__Symlink();
2122 test_tr2_sys__Unlink();
2127 test_threads__Mtx();
2129 test_vbtable_size_exports();