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"
28 static int vector_alloc_count
;
29 static int vector_elem_count
;
30 typedef struct blocks_to_free
{
32 void *blocks
[sizeof(void*)*8];
36 #define DEFINE_EXPECT(func) \
37 BOOL expect_ ## func, called_ ## func
39 struct expect_struct
{
40 DEFINE_EXPECT(queue_char__Allocate_page
);
41 DEFINE_EXPECT(queue_char__Deallocate_page
);
42 DEFINE_EXPECT(queue_char__Move_item
);
43 DEFINE_EXPECT(queue_char__Copy_item
);
44 DEFINE_EXPECT(queue_char__Assign_and_destroy_item
);
45 DEFINE_EXPECT(concurrent_vector_int_alloc
);
46 DEFINE_EXPECT(concurrent_vector_int_destroy
);
47 DEFINE_EXPECT(concurrent_vector_int_copy
);
48 DEFINE_EXPECT(concurrent_vector_int_assign
);
51 #define SET_EXPECT(func) \
53 struct expect_struct *p = TlsGetValue(expect_idx); \
54 ok(p != NULL, "expect_struct not initialized\n"); \
55 p->expect_ ## func = TRUE; \
58 #define CHECK_EXPECT2(func) \
60 struct expect_struct *p = TlsGetValue(expect_idx); \
61 ok(p != NULL, "expect_struct not initialized\n"); \
62 ok(p->expect_ ##func, "unexpected call " #func "\n"); \
63 p->called_ ## func = TRUE; \
66 #define CHECK_EXPECT(func) \
68 struct expect_struct *p = TlsGetValue(expect_idx); \
69 ok(p != NULL, "expect_struct not initialized\n"); \
70 CHECK_EXPECT2(func); \
71 p->expect_ ## func = FALSE; \
74 #define CHECK_CALLED(func) \
76 struct expect_struct *p = TlsGetValue(expect_idx); \
77 ok(p != NULL, "expect_struct not initialized\n"); \
78 ok(p->called_ ## func, "expected " #func "\n"); \
79 p->expect_ ## func = p->called_ ## func = FALSE; \
82 static void alloc_expect_struct(void)
84 struct expect_struct
*p
= malloc(sizeof(*p
));
85 memset(p
, 0, sizeof(*p
));
86 ok(TlsSetValue(expect_idx
, p
), "TlsSetValue failed\n");
89 static void free_expect_struct(void)
91 struct expect_struct
*p
= TlsGetValue(expect_idx
);
92 ok(TlsSetValue(expect_idx
, NULL
), "TlsSetValue failed\n");
98 #define __thiscall __stdcall
100 #define __thiscall __cdecl
103 /* Emulate a __thiscall */
106 #include "pshpack1.h"
107 struct thiscall_thunk
109 BYTE pop_eax
; /* popl %eax (ret addr) */
110 BYTE pop_edx
; /* popl %edx (func) */
111 BYTE pop_ecx
; /* popl %ecx (this) */
112 BYTE push_eax
; /* pushl %eax */
113 WORD jmp_edx
; /* jmp *%edx */
117 static void * (WINAPI
*call_thiscall_func1
)( void *func
, void *this );
118 static void * (WINAPI
*call_thiscall_func2
)( void *func
, void *this, void *a
);
119 static void * (WINAPI
*call_thiscall_func3
)( void *func
, void *this, void *a
, void *b
);
120 static void * (WINAPI
*call_thiscall_func4
)( void *func
, void *this, void *a
, void *b
, void *c
);
121 static void * (WINAPI
*call_thiscall_func5
)( void *func
, void *this, void *a
, void *b
, void *c
, void *d
);
122 static void * (WINAPI
*call_thiscall_func6
)( void *func
, void *this, void *a
, void *b
, void *c
, void *d
, void *e
);
123 static void * (WINAPI
*call_thiscall_func7
)( void *func
, void *this, void *a
, void *b
, void *c
, void *d
, void *e
, void *f
);
125 static void init_thiscall_thunk(void)
127 struct thiscall_thunk
*thunk
= VirtualAlloc( NULL
, sizeof(*thunk
),
128 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
129 thunk
->pop_eax
= 0x58; /* popl %eax */
130 thunk
->pop_edx
= 0x5a; /* popl %edx */
131 thunk
->pop_ecx
= 0x59; /* popl %ecx */
132 thunk
->push_eax
= 0x50; /* pushl %eax */
133 thunk
->jmp_edx
= 0xe2ff; /* jmp *%edx */
134 call_thiscall_func1
= (void *)thunk
;
135 call_thiscall_func2
= (void *)thunk
;
136 call_thiscall_func3
= (void *)thunk
;
137 call_thiscall_func4
= (void *)thunk
;
138 call_thiscall_func5
= (void *)thunk
;
139 call_thiscall_func6
= (void *)thunk
;
140 call_thiscall_func7
= (void *)thunk
;
143 #define call_func1(func,_this) call_thiscall_func1(func,_this)
144 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(void*)(a))
145 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(void*)(a),(void*)(b))
146 #define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(void*)(a),(void*)(b),(void*)(c))
147 #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d))
148 #define call_func6(func,_this,a,b,c,d,e) call_thiscall_func6(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d),(void*)(e))
149 #define call_func7(func,_this,a,b,c,d,e,f) call_thiscall_func7(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d),(void*)(e),(void*)(f))
152 #define init_thiscall_thunk()
153 #define call_func1(func,_this) func(_this)
154 #define call_func2(func,_this,a) func(_this,a)
155 #define call_func3(func,_this,a,b) func(_this,a,b)
156 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
157 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
158 #define call_func6(func,_this,a,b,c,d,e) func(_this,a,b,c,d,e)
159 #define call_func7(func,_this,a,b,c,d,e,f) func(_this,a,b,c,d,e,f)
160 #endif /* __i386__ */
162 typedef int MSVCRT_long
;
163 typedef unsigned char MSVCP_bool
;
185 status_unknown
, file_not_found
, regular_file
, directory_file
,
186 symlink_file
, block_file
, character_file
, fifo_file
, socket_file
,
190 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
200 if (abs(x
- y
) > ulps
)
206 static char* (__cdecl
*p_setlocale
)(int, const char*);
207 static int (__cdecl
*p__setmbcp
)(int);
208 static int (__cdecl
*p__ismbblead
)(unsigned int);
210 static MSVCRT_long (__cdecl
*p__Xtime_diff_to_millis2
)(const xtime
*, const xtime
*);
211 static int (__cdecl
*p_xtime_get
)(xtime
*, int);
212 static _Cvtvec (__cdecl
*p__Getcvt
)(void);
213 static void (CDECL
*p__Call_once
)(int *once
, void (CDECL
*func
)(void));
214 static void (CDECL
*p__Call_onceEx
)(int *once
, void (CDECL
*func
)(void*), void *argv
);
215 static void (CDECL
*p__Do_call
)(void *this);
216 static short (__cdecl
*p__Dtest
)(double *d
);
217 static short (__cdecl
*p__Dscale
)(double *d
, int exp
);
218 static short (__cdecl
*p__FExp
)(float *x
, float y
, int exp
);
219 static const char* (__cdecl
*p__Syserror_map
)(int err
);
222 static ULONGLONG(__cdecl
*p_tr2_sys__File_size
)(char const*);
223 static ULONGLONG(__cdecl
*p_tr2_sys__File_size_wchar
)(WCHAR
const*);
224 static int (__cdecl
*p_tr2_sys__Equivalent
)(char const*, char const*);
225 static int (__cdecl
*p_tr2_sys__Equivalent_wchar
)(WCHAR
const*, WCHAR
const*);
226 static char* (__cdecl
*p_tr2_sys__Current_get
)(char *);
227 static WCHAR
* (__cdecl
*p_tr2_sys__Current_get_wchar
)(WCHAR
*);
228 static MSVCP_bool (__cdecl
*p_tr2_sys__Current_set
)(char const*);
229 static MSVCP_bool (__cdecl
*p_tr2_sys__Current_set_wchar
)(WCHAR
const*);
230 static int (__cdecl
*p_tr2_sys__Make_dir
)(char const*);
231 static int (__cdecl
*p_tr2_sys__Make_dir_wchar
)(WCHAR
const*);
232 static MSVCP_bool (__cdecl
*p_tr2_sys__Remove_dir
)(char const*);
233 static MSVCP_bool (__cdecl
*p_tr2_sys__Remove_dir_wchar
)(WCHAR
const*);
234 static int (__cdecl
*p_tr2_sys__Copy_file
)(char const*, char const*, MSVCP_bool
);
235 static int (__cdecl
*p_tr2_sys__Copy_file_wchar
)(WCHAR
const*, WCHAR
const*, MSVCP_bool
);
236 static int (__cdecl
*p_tr2_sys__Rename
)(char const*, char const*);
237 static int (__cdecl
*p_tr2_sys__Rename_wchar
)(WCHAR
const*, WCHAR
const*);
238 static struct space_info
* (__cdecl
*p_tr2_sys__Statvfs
)(struct space_info
*, char const*);
239 static struct space_info
* (__cdecl
*p_tr2_sys__Statvfs_wchar
)(struct space_info
*, WCHAR
const*);
240 static enum file_type (__cdecl
*p_tr2_sys__Stat
)(char const*, int *);
241 static enum file_type (__cdecl
*p_tr2_sys__Stat_wchar
)(WCHAR
const*, int *);
242 static enum file_type (__cdecl
*p_tr2_sys__Lstat
)(char const*, int *);
243 static enum file_type (__cdecl
*p_tr2_sys__Lstat_wchar
)(WCHAR
const*, int *);
244 static __int64 (__cdecl
*p_tr2_sys__Last_write_time
)(char const*);
245 static __int64 (__cdecl
*p_tr2_sys__Last_write_time_wchar
)(WCHAR
const*);
246 static void (__cdecl
*p_tr2_sys__Last_write_time_set
)(char const*, __int64
);
247 static void* (__cdecl
*p_tr2_sys__Open_dir
)(char*, char const*, int *, enum file_type
*);
248 static char* (__cdecl
*p_tr2_sys__Read_dir
)(char*, void*, enum file_type
*);
249 static void (__cdecl
*p_tr2_sys__Close_dir
)(void*);
250 static int (__cdecl
*p_tr2_sys__Link
)(char const*, char const*);
251 static int (__cdecl
*p_tr2_sys__Symlink
)(char const*, char const*);
252 static int (__cdecl
*p_tr2_sys__Unlink
)(char const*);
261 #define TIMEDELTA 250 /* 250 ms uncertainty allowed */
263 typedef int (__cdecl
*_Thrd_start_t
)(void*);
265 static int (__cdecl
*p__Thrd_equal
)(_Thrd_t
, _Thrd_t
);
266 static int (__cdecl
*p__Thrd_lt
)(_Thrd_t
, _Thrd_t
);
267 static void (__cdecl
*p__Thrd_sleep
)(const xtime
*);
268 static _Thrd_t (__cdecl
*p__Thrd_current
)(void);
269 static int (__cdecl
*p__Thrd_create
)(_Thrd_t
*, _Thrd_start_t
, void*);
270 static int (__cdecl
*p__Thrd_join
)(_Thrd_t
, int*);
271 static int (__cdecl
*p__Thrd_detach
)(_Thrd_t
);
274 static ULONGLONG (__cdecl
*p_i386_Thrd_current
)(void);
275 static _Thrd_t __cdecl
i386_Thrd_current(void)
281 r
.ull
= p_i386_Thrd_current();
287 typedef struct cs_queue
289 struct cs_queue
*next
;
296 ULONG_PTR unk_thread_id
;
303 #define MTX_PLAIN 0x1
305 #define MTX_TIMED 0x4
306 #define MTX_RECURSIVE 0x100
315 static int (__cdecl
*p__Mtx_init
)(_Mtx_t
*, int);
316 static void (__cdecl
*p__Mtx_destroy
)(_Mtx_t
*);
317 static int (__cdecl
*p__Mtx_lock
)(_Mtx_t
*);
318 static int (__cdecl
*p__Mtx_unlock
)(_Mtx_t
*);
319 static int (__cdecl
*p__Mtx_trylock
)(_Mtx_t
*);
322 typedef void *_Cnd_t
;
324 static int (__cdecl
*p__Cnd_init
)(_Cnd_t
*);
325 static void (__cdecl
*p__Cnd_destroy
)(_Cnd_t
*);
326 static int (__cdecl
*p__Cnd_wait
)(_Cnd_t
*, _Mtx_t
*);
327 static int (__cdecl
*p__Cnd_timedwait
)(_Cnd_t
*, _Mtx_t
*, const xtime
*);
328 static int (__cdecl
*p__Cnd_broadcast
)(_Cnd_t
*);
329 static int (__cdecl
*p__Cnd_signal
)(_Cnd_t
*);
330 static void (__cdecl
*p__Cnd_register_at_thread_exit
)(_Cnd_t
*, _Mtx_t
*, int*);
331 static void (__cdecl
*p__Cnd_unregister_at_thread_exit
)(_Mtx_t
*);
332 static void (__cdecl
*p__Cnd_do_broadcast_at_thread_exit
)(void);
335 typedef void (*vtable_ptr
)(void);
339 const vtable_ptr
*vtable
;
345 static _Pad
* (__thiscall
*p__Pad_ctor
)(_Pad
*);
346 static _Pad
* (__thiscall
*p__Pad_copy_ctor
)(_Pad
*, const _Pad
*);
347 static void (__thiscall
*p__Pad_dtor
)(_Pad
*);
348 static _Pad
* (__thiscall
*p__Pad_op_assign
)(_Pad
*, const _Pad
*);
349 static void (__thiscall
*p__Pad__Launch
)(_Pad
*, _Thrd_t
*);
350 static void (__thiscall
*p__Pad__Release
)(_Pad
*);
352 static void (__cdecl
*p_threads__Mtx_new
)(void **mtx
);
353 static void (__cdecl
*p_threads__Mtx_delete
)(void *mtx
);
354 static void (__cdecl
*p_threads__Mtx_lock
)(void *mtx
);
355 static void (__cdecl
*p_threads__Mtx_unlock
)(void *mtx
);
357 static BOOLEAN (WINAPI
*pCreateSymbolicLinkA
)(LPCSTR
,LPCSTR
,DWORD
);
359 static size_t (__cdecl
*p_vector_base_v4__Segment_index_of
)(size_t);
363 const vtable_ptr
*vtable
;
376 static queue_base_v4
* (__thiscall
*p_queue_base_v4_ctor
)(queue_base_v4
*, size_t);
377 static void (__thiscall
*p_queue_base_v4_dtor
)(queue_base_v4
*);
378 static MSVCP_bool (__thiscall
*p_queue_base_v4__Internal_empty
)(queue_base_v4
*);
379 static size_t (__thiscall
*p_queue_base_v4__Internal_size
)(queue_base_v4
*);
380 static void (__thiscall
*p_queue_base_v4__Internal_push
)(queue_base_v4
*, const void*);
381 static void (__thiscall
*p_queue_base_v4__Internal_move_push
)(queue_base_v4
*, void*);
382 static MSVCP_bool (__thiscall
*p_queue_base_v4__Internal_pop_if_present
)(queue_base_v4
*, void*);
383 static void (__thiscall
*p_queue_base_v4__Internal_finish_clear
)(queue_base_v4
*);
385 typedef struct vector_base_v4
387 void* (__cdecl
*allocator
)(struct vector_base_v4
*, size_t);
394 static void (__thiscall
*p_vector_base_v4_dtor
)(vector_base_v4
*);
395 static size_t (__thiscall
*p_vector_base_v4__Internal_capacity
)(vector_base_v4
*);
396 static void* (__thiscall
*p_vector_base_v4__Internal_push_back
)(
397 vector_base_v4
*, size_t, size_t*);
398 static size_t (__thiscall
*p_vector_base_v4__Internal_clear
)(
399 vector_base_v4
*, void (__cdecl
*)(void*, size_t));
400 static void (__thiscall
*p_vector_base_v4__Internal_copy
)(
401 vector_base_v4
*, vector_base_v4
*, size_t, void (__cdecl
*)(void*, const void*, size_t));
402 static void (__thiscall
*p_vector_base_v4__Internal_assign
)(
403 vector_base_v4
*, vector_base_v4
*, size_t, void (__cdecl
*)(void*, size_t),
404 void (__cdecl
*)(void*, const void*, size_t), void (__cdecl
*)(void*, const void*, size_t));
405 static void (__thiscall
*p_vector_base_v4__Internal_swap
)(
406 vector_base_v4
*, const vector_base_v4
*);
407 static void* (__thiscall
*p_vector_base_v4__Internal_compact
)(
408 vector_base_v4
*, size_t, void*, void (__cdecl
*)(void*, size_t),
409 void (__cdecl
*)(void*, const void*, size_t));
410 static size_t (__thiscall
*p_vector_base_v4__Internal_grow_by
)(
411 vector_base_v4
*, size_t, size_t, void (__cdecl
*)(void*, const void*, size_t), const void *);
412 static size_t (__thiscall
*p_vector_base_v4__Internal_grow_to_at_least_with_result
)(
413 vector_base_v4
*, size_t, size_t, void (__cdecl
*)(void*, const void*, size_t), const void *);
414 static void (__thiscall
*p_vector_base_v4__Internal_reserve
)(
415 vector_base_v4
*, size_t, size_t, size_t);
416 static void (__thiscall
*p_vector_base_v4__Internal_resize
)(
417 vector_base_v4
*, size_t, size_t, size_t, void (__cdecl
*)(void*, size_t),
418 void (__cdecl
*copy
)(void*, const void*, size_t), const void*);
420 static const BYTE
*p_byte_reverse_table
;
422 static HMODULE msvcp
;
423 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
424 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
425 static BOOL
init(void)
429 msvcp
= LoadLibraryA("msvcp120.dll");
432 win_skip("msvcp120.dll not installed\n");
436 SET(p__Xtime_diff_to_millis2
,
437 "_Xtime_diff_to_millis2");
454 if(sizeof(void*) == 8) { /* 64-bit initialization */
455 SET(p_tr2_sys__File_size
,
456 "?_File_size@sys@tr2@std@@YA_KPEBD@Z");
457 SET(p_tr2_sys__File_size_wchar
,
458 "?_File_size@sys@tr2@std@@YA_KPEB_W@Z");
459 SET(p_tr2_sys__Equivalent
,
460 "?_Equivalent@sys@tr2@std@@YAHPEBD0@Z");
461 SET(p_tr2_sys__Equivalent_wchar
,
462 "?_Equivalent@sys@tr2@std@@YAHPEB_W0@Z");
463 SET(p_tr2_sys__Current_get
,
464 "?_Current_get@sys@tr2@std@@YAPEADAEAY0BAE@D@Z");
465 SET(p_tr2_sys__Current_get_wchar
,
466 "?_Current_get@sys@tr2@std@@YAPEA_WAEAY0BAE@_W@Z");
467 SET(p_tr2_sys__Current_set
,
468 "?_Current_set@sys@tr2@std@@YA_NPEBD@Z");
469 SET(p_tr2_sys__Current_set_wchar
,
470 "?_Current_set@sys@tr2@std@@YA_NPEB_W@Z");
471 SET(p_tr2_sys__Make_dir
,
472 "?_Make_dir@sys@tr2@std@@YAHPEBD@Z");
473 SET(p_tr2_sys__Make_dir_wchar
,
474 "?_Make_dir@sys@tr2@std@@YAHPEB_W@Z");
475 SET(p_tr2_sys__Remove_dir
,
476 "?_Remove_dir@sys@tr2@std@@YA_NPEBD@Z");
477 SET(p_tr2_sys__Remove_dir_wchar
,
478 "?_Remove_dir@sys@tr2@std@@YA_NPEB_W@Z");
479 SET(p_tr2_sys__Copy_file
,
480 "?_Copy_file@sys@tr2@std@@YAHPEBD0_N@Z");
481 SET(p_tr2_sys__Copy_file_wchar
,
482 "?_Copy_file@sys@tr2@std@@YAHPEB_W0_N@Z");
483 SET(p_tr2_sys__Rename
,
484 "?_Rename@sys@tr2@std@@YAHPEBD0@Z");
485 SET(p_tr2_sys__Rename_wchar
,
486 "?_Rename@sys@tr2@std@@YAHPEB_W0@Z");
487 SET(p_tr2_sys__Statvfs
,
488 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEBD@Z");
489 SET(p_tr2_sys__Statvfs_wchar
,
490 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEB_W@Z");
492 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
493 SET(p_tr2_sys__Stat_wchar
,
494 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
495 SET(p_tr2_sys__Lstat
,
496 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
497 SET(p_tr2_sys__Lstat_wchar
,
498 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
499 SET(p_tr2_sys__Last_write_time
,
500 "?_Last_write_time@sys@tr2@std@@YA_JPEBD@Z");
501 SET(p_tr2_sys__Last_write_time_wchar
,
502 "?_Last_write_time@sys@tr2@std@@YA_JPEB_W@Z");
503 SET(p_tr2_sys__Last_write_time_set
,
504 "?_Last_write_time@sys@tr2@std@@YAXPEBD_J@Z");
505 SET(p_tr2_sys__Open_dir
,
506 "?_Open_dir@sys@tr2@std@@YAPEAXAEAY0BAE@DPEBDAEAHAEAW4file_type@123@@Z");
507 SET(p_tr2_sys__Read_dir
,
508 "?_Read_dir@sys@tr2@std@@YAPEADAEAY0BAE@DPEAXAEAW4file_type@123@@Z");
509 SET(p_tr2_sys__Close_dir
,
510 "?_Close_dir@sys@tr2@std@@YAXPEAX@Z");
512 "?_Link@sys@tr2@std@@YAHPEBD0@Z");
513 SET(p_tr2_sys__Symlink
,
514 "?_Symlink@sys@tr2@std@@YAHPEBD0@Z");
515 SET(p_tr2_sys__Unlink
,
516 "?_Unlink@sys@tr2@std@@YAHPEBD@Z");
520 "??0_Pad@std@@QEAA@XZ");
521 SET(p__Pad_copy_ctor
,
522 "??0_Pad@std@@QEAA@AEBV01@@Z");
524 "??1_Pad@std@@QEAA@XZ");
525 SET(p__Pad_op_assign
,
526 "??4_Pad@std@@QEAAAEAV01@AEBV01@@Z");
528 "?_Launch@_Pad@std@@QEAAXPEAU_Thrd_imp_t@@@Z");
530 "?_Release@_Pad@std@@QEAAXXZ");
531 SET(p_threads__Mtx_new
,
532 "?_Mtx_new@threads@stdext@@YAXAEAPEAX@Z");
533 SET(p_threads__Mtx_delete
,
534 "?_Mtx_delete@threads@stdext@@YAXPEAX@Z");
535 SET(p_threads__Mtx_lock
,
536 "?_Mtx_lock@threads@stdext@@YAXPEAX@Z");
537 SET(p_threads__Mtx_unlock
,
538 "?_Mtx_unlock@threads@stdext@@YAXPEAX@Z");
539 SET(p_vector_base_v4__Segment_index_of
,
540 "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KA_K_K@Z");
541 SET(p_queue_base_v4_ctor
,
542 "??0_Concurrent_queue_base_v4@details@Concurrency@@IEAA@_K@Z");
543 SET(p_queue_base_v4_dtor
,
544 "??1_Concurrent_queue_base_v4@details@Concurrency@@MEAA@XZ");
545 SET(p_queue_base_v4__Internal_empty
,
546 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_NXZ");
547 SET(p_queue_base_v4__Internal_size
,
548 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_KXZ");
549 SET(p_queue_base_v4__Internal_push
,
550 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEBX@Z");
551 SET(p_queue_base_v4__Internal_move_push
,
552 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEAX@Z");
553 SET(p_queue_base_v4__Internal_pop_if_present
,
554 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IEAA_NPEAX@Z");
555 SET(p_queue_base_v4__Internal_finish_clear
,
556 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXXZ");
557 SET(p_vector_base_v4_dtor
,
558 "??1_Concurrent_vector_base_v4@details@Concurrency@@IEAA@XZ");
559 SET(p_vector_base_v4__Internal_capacity
,
560 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IEBA_KXZ");
561 SET(p_vector_base_v4__Internal_push_back
,
562 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IEAAPEAX_KAEA_K@Z");
563 SET(p_vector_base_v4__Internal_clear
,
564 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_KP6AXPEAX_K@Z@Z");
565 SET(p_vector_base_v4__Internal_copy
,
566 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z");
567 SET(p_vector_base_v4__Internal_assign
,
568 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z");
569 SET(p_vector_base_v4__Internal_swap
,
570 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEAV123@@Z");
571 SET(p_vector_base_v4__Internal_compact
,
572 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IEAAPEAX_KPEAXP6AX10@ZP6AX1PEBX0@Z@Z");
573 SET(p_vector_base_v4__Internal_grow_by
,
574 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z");
575 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result
,
576 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z");
577 SET(p_vector_base_v4__Internal_reserve
,
578 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00@Z");
579 SET(p_vector_base_v4__Internal_resize
,
580 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00P6AXPEAX0@ZP6AX1PEBX0@Z3@Z");
582 "?_Syserror_map@std@@YAPEBDH@Z");
584 SET(p_tr2_sys__File_size
,
585 "?_File_size@sys@tr2@std@@YA_KPBD@Z");
586 SET(p_tr2_sys__File_size_wchar
,
587 "?_File_size@sys@tr2@std@@YA_KPB_W@Z");
588 SET(p_tr2_sys__Equivalent
,
589 "?_Equivalent@sys@tr2@std@@YAHPBD0@Z");
590 SET(p_tr2_sys__Equivalent_wchar
,
591 "?_Equivalent@sys@tr2@std@@YAHPB_W0@Z");
592 SET(p_tr2_sys__Current_get
,
593 "?_Current_get@sys@tr2@std@@YAPADAAY0BAE@D@Z");
594 SET(p_tr2_sys__Current_get_wchar
,
595 "?_Current_get@sys@tr2@std@@YAPA_WAAY0BAE@_W@Z");
596 SET(p_tr2_sys__Current_set
,
597 "?_Current_set@sys@tr2@std@@YA_NPBD@Z");
598 SET(p_tr2_sys__Current_set_wchar
,
599 "?_Current_set@sys@tr2@std@@YA_NPB_W@Z");
600 SET(p_tr2_sys__Make_dir
,
601 "?_Make_dir@sys@tr2@std@@YAHPBD@Z");
602 SET(p_tr2_sys__Make_dir_wchar
,
603 "?_Make_dir@sys@tr2@std@@YAHPB_W@Z");
604 SET(p_tr2_sys__Remove_dir
,
605 "?_Remove_dir@sys@tr2@std@@YA_NPBD@Z");
606 SET(p_tr2_sys__Remove_dir_wchar
,
607 "?_Remove_dir@sys@tr2@std@@YA_NPB_W@Z");
608 SET(p_tr2_sys__Copy_file
,
609 "?_Copy_file@sys@tr2@std@@YAHPBD0_N@Z");
610 SET(p_tr2_sys__Copy_file_wchar
,
611 "?_Copy_file@sys@tr2@std@@YAHPB_W0_N@Z");
612 SET(p_tr2_sys__Rename
,
613 "?_Rename@sys@tr2@std@@YAHPBD0@Z");
614 SET(p_tr2_sys__Rename_wchar
,
615 "?_Rename@sys@tr2@std@@YAHPB_W0@Z");
616 SET(p_tr2_sys__Statvfs
,
617 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z");
618 SET(p_tr2_sys__Statvfs_wchar
,
619 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PB_W@Z");
621 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
622 SET(p_tr2_sys__Stat_wchar
,
623 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
624 SET(p_tr2_sys__Lstat
,
625 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
626 SET(p_tr2_sys__Lstat_wchar
,
627 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
628 SET(p_tr2_sys__Last_write_time
,
629 "?_Last_write_time@sys@tr2@std@@YA_JPBD@Z");
630 SET(p_tr2_sys__Last_write_time_wchar
,
631 "?_Last_write_time@sys@tr2@std@@YA_JPB_W@Z");
632 SET(p_tr2_sys__Last_write_time_set
,
633 "?_Last_write_time@sys@tr2@std@@YAXPBD_J@Z");
634 SET(p_tr2_sys__Open_dir
,
635 "?_Open_dir@sys@tr2@std@@YAPAXAAY0BAE@DPBDAAHAAW4file_type@123@@Z");
636 SET(p_tr2_sys__Read_dir
,
637 "?_Read_dir@sys@tr2@std@@YAPADAAY0BAE@DPAXAAW4file_type@123@@Z");
638 SET(p_tr2_sys__Close_dir
,
639 "?_Close_dir@sys@tr2@std@@YAXPAX@Z");
641 "?_Link@sys@tr2@std@@YAHPBD0@Z");
642 SET(p_tr2_sys__Symlink
,
643 "?_Symlink@sys@tr2@std@@YAHPBD0@Z");
644 SET(p_tr2_sys__Unlink
,
645 "?_Unlink@sys@tr2@std@@YAHPBD@Z");
646 SET(p_threads__Mtx_new
,
647 "?_Mtx_new@threads@stdext@@YAXAAPAX@Z");
648 SET(p_threads__Mtx_delete
,
649 "?_Mtx_delete@threads@stdext@@YAXPAX@Z");
650 SET(p_threads__Mtx_lock
,
651 "?_Mtx_lock@threads@stdext@@YAXPAX@Z");
652 SET(p_threads__Mtx_unlock
,
653 "?_Mtx_unlock@threads@stdext@@YAXPAX@Z");
654 SET(p_vector_base_v4__Segment_index_of
,
655 "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KAII@Z");
657 "?_Syserror_map@std@@YAPBDH@Z");
659 SET(p_i386_Thrd_current
,
661 p__Thrd_current
= i386_Thrd_current
;
663 "??0_Pad@std@@QAE@XZ");
664 SET(p__Pad_copy_ctor
,
665 "??0_Pad@std@@QAE@ABV01@@Z");
667 "??1_Pad@std@@QAE@XZ");
668 SET(p__Pad_op_assign
,
669 "??4_Pad@std@@QAEAAV01@ABV01@@Z");
671 "?_Launch@_Pad@std@@QAEXPAU_Thrd_imp_t@@@Z");
673 "?_Release@_Pad@std@@QAEXXZ");
674 SET(p_queue_base_v4_ctor
,
675 "??0_Concurrent_queue_base_v4@details@Concurrency@@IAE@I@Z");
676 SET(p_queue_base_v4_dtor
,
677 "??1_Concurrent_queue_base_v4@details@Concurrency@@MAE@XZ");
678 SET(p_queue_base_v4__Internal_empty
,
679 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBE_NXZ");
680 SET(p_queue_base_v4__Internal_size
,
681 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBEIXZ");
682 SET(p_queue_base_v4__Internal_push
,
683 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPBX@Z");
684 SET(p_queue_base_v4__Internal_move_push
,
685 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPAX@Z");
686 SET(p_queue_base_v4__Internal_pop_if_present
,
687 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAE_NPAX@Z");
688 SET(p_queue_base_v4__Internal_finish_clear
,
689 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAEXXZ");
690 SET(p_vector_base_v4_dtor
,
691 "??1_Concurrent_vector_base_v4@details@Concurrency@@IAE@XZ");
692 SET(p_vector_base_v4__Internal_capacity
,
693 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IBEIXZ");
694 SET(p_vector_base_v4__Internal_push_back
,
695 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IAEPAXIAAI@Z");
696 SET(p_vector_base_v4__Internal_clear
,
697 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAEIP6AXPAXI@Z@Z");
698 SET(p_vector_base_v4__Internal_copy
,
699 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IAEXABV123@IP6AXPAXPBXI@Z@Z");
700 SET(p_vector_base_v4__Internal_assign
,
701 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z");
702 SET(p_vector_base_v4__Internal_swap
,
703 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IAEXAAV123@@Z");
704 SET(p_vector_base_v4__Internal_compact
,
705 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IAEPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z");
706 SET(p_vector_base_v4__Internal_grow_by
,
707 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IAEIIIP6AXPAXPBXI@Z1@Z");
708 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result
,
709 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IAEIIIP6AXPAXPBXI@Z1@Z");
710 SET(p_vector_base_v4__Internal_reserve
,
711 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIII@Z");
712 SET(p_vector_base_v4__Internal_resize
,
713 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z");
718 "??0_Pad@std@@QAA@XZ");
719 SET(p__Pad_copy_ctor
,
720 "??0_Pad@std@@QAA@ABV01@@Z");
722 "??1_Pad@std@@QAA@XZ");
723 SET(p__Pad_op_assign
,
724 "??4_Pad@std@@QAAAAV01@ABV01@@Z");
726 "?_Launch@_Pad@std@@QAAXPAU_Thrd_imp_t@@@Z");
728 "?_Release@_Pad@std@@QAAXXZ");
729 SET(p_queue_base_v4_ctor
,
730 "??0_Concurrent_queue_base_v4@details@Concurrency@@IAA@I@Z");
731 SET(p_queue_base_v4_dtor
,
732 "??1_Concurrent_queue_base_v4@details@Concurrency@@MAA@XZ");
733 SET(p_queue_base_v4__Internal_empty
,
734 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBA_NXZ");
735 SET(p_queue_base_v4__Internal_size
,
736 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBAIXZ");
737 SET(p_queue_base_v4__Internal_push
,
738 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPBX@Z");
739 SET(p_queue_base_v4__Internal_move_push
,
740 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPAX@Z");
741 SET(p_queue_base_v4__Internal_pop_if_present
,
742 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAA_NPAX@Z");
743 SET(p_queue_base_v4__Internal_finish_clear
,
744 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAAXXZ");
745 SET(p_vector_base_v4_dtor
,
746 "??1_Concurrent_vector_base_v4@details@Concurrency@@IAA@XZ");
747 SET(p_vector_base_v4__Internal_capacity
,
748 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IBAIXZ");
749 SET(p_vector_base_v4__Internal_push_back
,
750 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IAAPAXIAAI@Z");
751 SET(p_vector_base_v4__Internal_clear
,
752 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAAIP6AXPAXI@Z@Z");
753 SET(p_vector_base_v4__Internal_copy
,
754 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IAAXABV123@IP6AXPAXPBXI@Z@Z");
755 SET(p_vector_base_v4__Internal_assign
,
756 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z");
757 SET(p_vector_base_v4__Internal_swap
,
758 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IAAXAAV123@@Z");
759 SET(p_vector_base_v4__Internal_compact
,
760 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IAAPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z");
761 SET(p_vector_base_v4__Internal_grow_by
,
762 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IAAIIIP6AXPAXPBXI@Z1@Z");
763 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result
,
764 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IAAIIIP6AXPAXPBXI@Z1@Z");
765 SET(p_vector_base_v4__Internal_reserve
,
766 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAAXIII@Z");
767 SET(p_vector_base_v4__Internal_resize
,
768 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z");
801 SET(p__Cnd_timedwait
,
803 SET(p__Cnd_broadcast
,
807 SET(p__Cnd_register_at_thread_exit
,
808 "_Cnd_register_at_thread_exit");
809 SET(p__Cnd_unregister_at_thread_exit
,
810 "_Cnd_unregister_at_thread_exit");
811 SET(p__Cnd_do_broadcast_at_thread_exit
,
812 "_Cnd_do_broadcast_at_thread_exit");
814 SET(p_byte_reverse_table
, "?_Byte_reverse_table@details@Concurrency@@3QBEB");
816 hdll
= GetModuleHandleA("msvcr120.dll");
817 p_setlocale
= (void*)GetProcAddress(hdll
, "setlocale");
818 p__setmbcp
= (void*)GetProcAddress(hdll
, "_setmbcp");
819 p__ismbblead
= (void*)GetProcAddress(hdll
, "_ismbblead");
821 hdll
= GetModuleHandleA("kernel32.dll");
822 pCreateSymbolicLinkA
= (void*)GetProcAddress(hdll
, "CreateSymbolicLinkA");
824 init_thiscall_thunk();
828 static void test__Xtime_diff_to_millis2(void)
831 __time64_t sec_before
;
832 MSVCRT_long nsec_before
;
833 __time64_t sec_after
;
834 MSVCRT_long nsec_after
;
838 {0, 1000000000, 0, 2000000000, 1000},
839 {1, 100000000, 2, 100000000, 1000},
840 {1, 100000000, 1, 200000000, 100},
841 {0, 0, 0, 1000000000, 1000},
842 {0, 0, 0, 1200000000, 1200},
843 {0, 0, 0, 1230000000, 1230},
844 {0, 0, 0, 1234000000, 1234},
845 {0, 0, 0, 1234100000, 1235},
846 {0, 0, 0, 1234900000, 1235},
847 {0, 0, 0, 1234010000, 1235},
848 {0, 0, 0, 1234090000, 1235},
849 {0, 0, 0, 1234000001, 1235},
850 {0, 0, 0, 1234000009, 1235},
853 {0, 1000000000, 0, 0, 0},
854 {0x7FFFFFFF / 1000, 0, 0, 0, 0},
855 {2147484, 0, 0, 0, 0}, /* ceil(0x80000000 / 1000) */
856 {2147485, 0, 0, 0, 0}, /* ceil(0x80000000 / 1000) + 1*/
857 {0, 0, 0x7FFFFFFF / 1000, 0, 2147483000},
858 {0, 0, 0x7FFFFFFF / 1000, 647000000, 0x7FFFFFFF}, /* max */
859 {0, 0, 0x7FFFFFFF / 1000, 647000001, -2147483648}, /* overflow. */
860 {0, 0, 2147484, 0, -2147483296}, /* ceil(0x80000000 / 1000), overflow*/
861 {0, 0, 0, -10000000, 0},
862 {0, 0, -1, -100000000, 0},
864 {0, -100000000, 0, 0, 100},
865 {-1, -100000000, 0, 0, 1100},
866 {0, 0, -1, 2000000000, 1000},
867 {0, 0, -2, 2000000000, 0},
868 {0, 0, -2, 2100000000, 100},
869 {0, 0, _I64_MAX
/ 1000, 0, -808}, /* Still fits in a signed 64 bit number */
870 {0, 0, _I64_MAX
/ 1000, 1000000000, 192}, /* Overflows a signed 64 bit number */
871 {0, 0, (((ULONGLONG
)0x80000000 << 32) | 0x1000) / 1000, 1000000000, 4192}, /* 64 bit overflow */
872 {_I64_MAX
- 2, 0, _I64_MAX
, 0, 2000}, /* Not an overflow */
873 {_I64_MAX
, 0, _I64_MAX
- 2, 0, 0}, /* Not an overflow */
875 /* October 11th 2017, 12:34:59 UTC */
876 {1507725144, 983274000, 0, 0, 0},
877 {0, 0, 1507725144, 983274000, 191624088},
878 {1507725144, 983274000, 1507725145, 983274000, 1000},
879 {1507725145, 983274000, 1507725145, 983274000, 0},
885 for(i
= 0; i
< ARRAY_SIZE(tests
); ++ i
)
887 t1
.sec
= tests
[i
].sec_before
;
888 t1
.nsec
= tests
[i
].nsec_before
;
889 t2
.sec
= tests
[i
].sec_after
;
890 t2
.nsec
= tests
[i
].nsec_after
;
891 ret
= p__Xtime_diff_to_millis2(&t2
, &t1
);
892 ok(ret
== tests
[i
].expect
,
893 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
894 i
, tests
[i
].expect
, ret
);
898 static void test_xtime_get(void)
900 static const MSVCRT_long tests
[] = {1, 50, 100, 200, 500};
905 for(i
= 0; i
< ARRAY_SIZE(tests
); i
++)
907 p_xtime_get(&before
, 1);
909 p_xtime_get(&after
, 1);
911 diff
= p__Xtime_diff_to_millis2(&after
, &before
);
914 "xtime_get() not functioning correctly, test: %d, expect: %d, got: %d\n",
918 /* Test parameter and return value */
919 before
.sec
= 0xdeadbeef; before
.nsec
= 0xdeadbeef;
920 i
= p_xtime_get(&before
, 0);
921 ok(i
== 0, "expect xtime_get() to return 0, got: %d\n", i
);
922 ok(before
.sec
== 0xdeadbeef && before
.nsec
== 0xdeadbeef,
923 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
925 before
.sec
= 0xdeadbeef; before
.nsec
= 0xdeadbeef;
926 i
= p_xtime_get(&before
, 1);
927 ok(i
== 1, "expect xtime_get() to return 1, got: %d\n", i
);
928 ok(before
.sec
!= 0xdeadbeef && before
.nsec
!= 0xdeadbeef,
929 "xtime_get() should have modified the xtime struct with the given option\n");
932 static void test__Getcvt(void)
937 cvtvec
= p__Getcvt();
938 ok(cvtvec
.page
== 0, "cvtvec.page = %d\n", cvtvec
.page
);
939 ok(cvtvec
.mb_max
== 1, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
940 todo_wine
ok(cvtvec
.unk
== 1, "cvtvec.unk = %d\n", cvtvec
.unk
);
942 ok(cvtvec
.isleadbyte
[i
] == 0, "cvtvec.isleadbyte[%d] = %x\n", i
, cvtvec
.isleadbyte
[i
]);
944 if(!p_setlocale(LC_ALL
, ".936")) {
945 win_skip("_Getcvt tests\n");
948 cvtvec
= p__Getcvt();
949 ok(cvtvec
.page
== 936, "cvtvec.page = %d\n", cvtvec
.page
);
950 ok(cvtvec
.mb_max
== 2, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
951 ok(cvtvec
.unk
== 0, "cvtvec.unk = %d\n", cvtvec
.unk
);
952 for(i
=0; i
<32; i
++) {
957 b
|= (p__ismbblead(i
*8+j
) ? 1 : 0) << j
;
958 ok(cvtvec
.isleadbyte
[i
] ==b
, "cvtvec.isleadbyte[%d] = %x (%x)\n", i
, cvtvec
.isleadbyte
[i
], b
);
962 cvtvec
= p__Getcvt();
963 ok(cvtvec
.page
== 936, "cvtvec.page = %d\n", cvtvec
.page
);
964 ok(cvtvec
.mb_max
== 2, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
965 ok(cvtvec
.unk
== 0, "cvtvec.unk = %d\n", cvtvec
.unk
);
966 for(i
=0; i
<32; i
++) {
971 b
|= (p__ismbblead(i
*8+j
) ? 1 : 0) << j
;
972 ok(cvtvec
.isleadbyte
[i
] ==b
, "cvtvec.isleadbyte[%d] = %x (%x)\n", i
, cvtvec
.isleadbyte
[i
], b
);
979 static void __cdecl
call_once_func(void)
981 ok(!once
, "once != 0\n");
985 static void __cdecl
call_once_ex_func(void *arg
)
989 ok(!once
, "once != 0\n");
993 static DWORD WINAPI
call_once_thread(void *arg
)
995 p__Call_once(&once
, call_once_func
);
999 static DWORD WINAPI
call_once_ex_thread(void *arg
)
1001 p__Call_onceEx(&once
, call_once_ex_func
, &cnt
);
1005 static void test__Call_once(void)
1011 h
[i
] = CreateThread(NULL
, 0, call_once_thread
, &once
, 0, NULL
);
1012 ok(WaitForMultipleObjects(4, h
, TRUE
, INFINITE
) == WAIT_OBJECT_0
,
1013 "error waiting for all threads to finish\n");
1014 ok(cnt
== 0x10000, "cnt = %x\n", cnt
);
1015 ok(once
== 1, "once = %x\n", once
);
1019 h
[i
] = CreateThread(NULL
, 0, call_once_ex_thread
, &once
, 0, NULL
);
1020 ok(WaitForMultipleObjects(4, h
, TRUE
, INFINITE
) == WAIT_OBJECT_0
,
1021 "error waiting for all threads to finish\n");
1022 ok(cnt
== 1, "cnt = %x\n", cnt
);
1023 ok(once
== 1, "once = %x\n", once
);
1026 static void **vtbl_func0
;
1028 /* TODO: this should be a __thiscall function */
1029 static void __stdcall
thiscall_func(void)
1034 static void __cdecl
thiscall_func(void *this)
1036 ok(this == &vtbl_func0
, "incorrect this value\n");
1041 static void test__Do_call(void)
1043 void *pfunc
= thiscall_func
;
1046 vtbl_func0
= &pfunc
;
1047 p__Do_call(&vtbl_func0
);
1048 ok(cnt
== 1, "func was not called\n");
1051 static void test__Dtest(void)
1058 ok(ret
== FP_ZERO
, "_Dtest(0) returned %x\n", ret
);
1062 ok(ret
== FP_NORMAL
, "_Dtest(1) returned %x\n", ret
);
1066 ok(ret
== FP_NORMAL
, "_Dtest(-1) returned %x\n", ret
);
1070 ok(ret
== FP_INFINITE
, "_Dtest(INF) returned %x\n", ret
);
1074 ok(ret
== FP_NAN
, "_Dtest(NAN) returned %x\n", ret
);
1077 static void test__Dscale(void)
1083 ret
= p__Dscale(&d
, 0);
1084 ok(d
== 0, "d = %f\n", d
);
1085 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
1088 ret
= p__Dscale(&d
, 1);
1089 ok(d
== 0, "d = %f\n", d
);
1090 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
1093 ret
= p__Dscale(&d
, -1);
1094 ok(d
== 0, "d = %f\n", d
);
1095 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
1098 ret
= p__Dscale(&d
, 0);
1099 ok(d
== 1, "d = %f\n", d
);
1100 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1103 ret
= p__Dscale(&d
, 1);
1104 ok(d
== 2, "d = %f\n", d
);
1105 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1108 ret
= p__Dscale(&d
, -1);
1109 ok(d
== 0.5, "d = %f\n", d
);
1110 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1113 ret
= p__Dscale(&d
, -99999);
1114 ok(d
== 0, "d = %f\n", d
);
1115 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
1118 ret
= p__Dscale(&d
, 999999);
1119 ok(d
== INFINITY
, "d = %f\n", d
);
1120 ok(ret
== FP_INFINITE
, "ret = %x\n", ret
);
1123 ret
= p__Dscale(&d
, 1);
1124 ok(ret
== FP_NAN
, "ret = %x\n", ret
);
1127 static void test__FExp(void)
1133 ret
= p__FExp(&d
, 0, 0);
1134 ok(d
== 0, "d = %f\n", d
);
1135 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
1138 ret
= p__FExp(&d
, 1, 0);
1139 ok(d
== 1.0, "d = %f\n", d
);
1140 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1143 ret
= p__FExp(&d
, 1, 1);
1144 ok(d
== 2.0, "d = %f\n", d
);
1145 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1148 ret
= p__FExp(&d
, 1, 2);
1149 ok(d
== 4.0, "d = %f\n", d
);
1150 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1153 ret
= p__FExp(&d
, 10, 0);
1154 ok(d
== 10.0, "d = %f\n", d
);
1155 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1158 ret
= p__FExp(&d
, 0, 0);
1159 ok(d
== 0, "d = %f\n", d
);
1160 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
1163 ret
= p__FExp(&d
, 1, 0);
1164 ok(compare_float(d
, 2.7182817, 4), "d = %f\n", d
);
1165 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1168 ret
= p__FExp(&d
, 0, 0);
1169 ok(d
== 0, "d = %f\n", d
);
1170 ok(ret
== FP_ZERO
, "ret = %x\n", ret
);
1173 ret
= p__FExp(&d
, 1, 0);
1174 ok(ret
== FP_INFINITE
, "ret = %x\n", ret
);
1177 ret
= p__FExp(&d
, 1, -50);
1178 ok(compare_float(d
, 1.0839359e+024, 4), "d = %g\n", d
);
1179 ok(ret
== FP_NORMAL
, "ret = %x\n", ret
);
1182 static void test__Syserror_map(void)
1186 r
= p__Syserror_map(0);
1187 ok(!r
, "_Syserror_map(0) returned %p\n", r
);
1190 static void test_tr2_sys__File_size(void)
1194 LARGE_INTEGER file_size
;
1195 CreateDirectoryA("tr2_test_dir", NULL
);
1197 file
= CreateFileA("tr2_test_dir/f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1198 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1199 file_size
.QuadPart
= 7;
1200 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1201 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1203 val
= p_tr2_sys__File_size("tr2_test_dir/f1");
1204 ok(val
== 7, "file_size is %s\n", wine_dbgstr_longlong(val
));
1205 val
= p_tr2_sys__File_size_wchar(L
"tr2_test_dir/f1");
1206 ok(val
== 7, "file_size is %s\n", wine_dbgstr_longlong(val
));
1208 file
= CreateFileA("tr2_test_dir/f2", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1209 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1211 val
= p_tr2_sys__File_size("tr2_test_dir/f2");
1212 ok(val
== 0, "file_size is %s\n", wine_dbgstr_longlong(val
));
1214 val
= p_tr2_sys__File_size("tr2_test_dir");
1215 ok(val
== 0, "file_size is %s\n", wine_dbgstr_longlong(val
));
1218 val
= p_tr2_sys__File_size("tr2_test_dir/not_exists_file");
1219 ok(val
== 0, "file_size is %s\n", wine_dbgstr_longlong(val
));
1220 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1223 val
= p_tr2_sys__File_size(NULL
);
1224 ok(val
== 0, "file_size is %s\n", wine_dbgstr_longlong(val
));
1225 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1227 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1228 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1229 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1232 static void test_tr2_sys__Equivalent(void)
1236 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
1245 { "f1", "tr2_test_dir", -1 },
1246 { "tr2_test_dir", "f1", -1 },
1247 { "tr2_test_dir", "tr2_test_dir", -1 },
1248 { "tr2_test_dir/./f1", "tr2_test_dir/f2", 0 },
1249 { "tr2_test_dir/f1" , "tr2_test_dir/f1", 1 },
1250 { "not_exists_file" , "tr2_test_dir/f1", 0 },
1251 { "tr2_test_dir\\f1" , "tr2_test_dir/./f1", 1 },
1252 { "not_exists_file" , "not_exists_file", -1 },
1253 { "tr2_test_dir/f1" , "not_exists_file", 0 },
1254 { "tr2_test_dir/../tr2_test_dir/f1", "tr2_test_dir/f1", 1 }
1257 GetCurrentDirectoryA(MAX_PATH
, current_path
);
1258 GetTempPathA(MAX_PATH
, temp_path
);
1259 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
1260 CreateDirectoryA("tr2_test_dir", NULL
);
1262 file
= CreateFileA("tr2_test_dir/f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1263 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1265 file
= CreateFileA("tr2_test_dir/f2", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1266 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1269 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
1271 val
= p_tr2_sys__Equivalent(tests
[i
].path1
, tests
[i
].path2
);
1272 ok(tests
[i
].equivalent
== val
, "tr2_sys__Equivalent(): test %d expect: %d, got %d\n", i
+1, tests
[i
].equivalent
, val
);
1273 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1276 val
= p_tr2_sys__Equivalent_wchar(L
"tr2_test_dir/f1", L
"tr2_test_dir/f1");
1277 ok(val
== 1, "tr2_sys__Equivalent(): expect: 1, got %d\n", val
);
1278 val
= p_tr2_sys__Equivalent_wchar(L
"tr2_test_dir/f1", L
"tr2_test_dir/f2");
1279 ok(val
== 0, "tr2_sys__Equivalent(): expect: 0, got %d\n", val
);
1280 val
= p_tr2_sys__Equivalent_wchar(L
"tr2_test_dir", L
"tr2_test_dir");
1281 ok(val
== -1, "tr2_sys__Equivalent(): expect: -1, got %d\n", val
);
1283 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1284 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1285 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1286 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
1289 static void test_tr2_sys__Current_get(void)
1291 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
], origin_path
[MAX_PATH
];
1293 WCHAR temp_path_wchar
[MAX_PATH
], current_path_wchar
[MAX_PATH
];
1296 GetCurrentDirectoryA(MAX_PATH
, origin_path
);
1297 GetTempPathA(MAX_PATH
, temp_path
);
1299 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
1300 temp
= p_tr2_sys__Current_get(current_path
);
1301 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1303 ok(!strcmp(temp_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path
, current_path
);
1305 GetTempPathW(MAX_PATH
, temp_path_wchar
);
1306 ok(SetCurrentDirectoryW(temp_path_wchar
), "SetCurrentDirectoryW to temp_path_wchar failed\n");
1307 temp_wchar
= p_tr2_sys__Current_get_wchar(current_path_wchar
);
1308 ok(temp_wchar
== current_path_wchar
, "p_tr2_sys__Current_get_wchar returned different buffer\n");
1309 wcscat(temp_wchar
, L
"\\");
1310 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
));
1312 ok(SetCurrentDirectoryA(origin_path
), "SetCurrentDirectoryA to origin_path failed\n");
1313 temp
= p_tr2_sys__Current_get(current_path
);
1314 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1315 ok(!strcmp(origin_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path
, current_path
);
1318 static void test_tr2_sys__Current_set(void)
1320 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
], origin_path
[MAX_PATH
];
1323 GetTempPathA(MAX_PATH
, temp_path
);
1324 GetCurrentDirectoryA(MAX_PATH
, origin_path
);
1325 temp
= p_tr2_sys__Current_get(origin_path
);
1326 ok(temp
== origin_path
, "p_tr2_sys__Current_get returned different buffer\n");
1328 ok(p_tr2_sys__Current_set(temp_path
), "p_tr2_sys__Current_set to temp_path failed\n");
1329 temp
= p_tr2_sys__Current_get(current_path
);
1330 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1332 ok(!strcmp(temp_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path
, current_path
);
1334 ok(p_tr2_sys__Current_set_wchar(L
"./"), "p_tr2_sys__Current_set_wchar to temp_path failed\n");
1335 temp
= p_tr2_sys__Current_get(current_path
);
1336 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1338 ok(!strcmp(temp_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path
, current_path
);
1341 ok(!p_tr2_sys__Current_set("not_exisist_dir"), "p_tr2_sys__Current_set to not_exist_dir succeed\n");
1342 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1345 ok(!p_tr2_sys__Current_set("??invalid_name>>"), "p_tr2_sys__Current_set to ??invalid_name>> succeed\n");
1346 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1348 ok(p_tr2_sys__Current_set(origin_path
), "p_tr2_sys__Current_set to origin_path failed\n");
1349 temp
= p_tr2_sys__Current_get(current_path
);
1350 ok(temp
== current_path
, "p_tr2_sys__Current_get returned different buffer\n");
1351 ok(!strcmp(origin_path
, current_path
), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path
, current_path
);
1354 static void test_tr2_sys__Make_dir(void)
1361 { "tr2_test_dir", 1 },
1362 { "tr2_test_dir", 0 },
1364 { "??invalid_name>>", -1 }
1367 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
1369 ret
= p_tr2_sys__Make_dir(tests
[i
].path
);
1370 ok(ret
== tests
[i
].val
, "tr2_sys__Make_dir(): test %d expect: %d, got %d\n", i
+1, tests
[i
].val
, ret
);
1371 ok(errno
== 0xdeadbeef, "tr2_sys__Make_dir(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1373 ret
= p_tr2_sys__Make_dir_wchar(L
"wd");
1374 ok(ret
== 1, "tr2_sys__Make_dir(): expect: 1, got %d\n", ret
);
1376 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1377 ok(p_tr2_sys__Remove_dir_wchar(L
"wd"), "expect wd to exist\n");
1380 static void test_tr2_sys__Remove_dir(void)
1388 { "tr2_test_dir", TRUE
},
1389 { "tr2_test_dir", FALSE
},
1391 { "??invalid_name>>", FALSE
}
1394 ok(p_tr2_sys__Make_dir("tr2_test_dir"), "tr2_sys__Make_dir() failed\n");
1396 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
1398 ret
= p_tr2_sys__Remove_dir(tests
[i
].path
);
1399 ok(ret
== tests
[i
].val
, "test_tr2_sys__Remove_dir(): test %d expect: %d, got %d\n", i
+1, tests
[i
].val
, ret
);
1400 ok(errno
== 0xdeadbeef, "test_tr2_sys__Remove_dir(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1404 static void test_tr2_sys__Copy_file(void)
1408 LARGE_INTEGER file_size
;
1412 MSVCP_bool fail_if_exists
;
1416 { "f1", "f1_copy", TRUE
, ERROR_SUCCESS
, ERROR_SUCCESS
},
1417 { "f1", "tr2_test_dir\\f1_copy", TRUE
, ERROR_SUCCESS
, ERROR_SUCCESS
},
1418 { "f1", "tr2_test_dir\\f1_copy", TRUE
, ERROR_FILE_EXISTS
, ERROR_FILE_EXISTS
},
1419 { "f1", "tr2_test_dir\\f1_copy", FALSE
, ERROR_SUCCESS
, ERROR_SUCCESS
},
1420 { "tr2_test_dir", "f1", TRUE
, ERROR_ACCESS_DENIED
, ERROR_ACCESS_DENIED
},
1421 { "tr2_test_dir", "tr2_test_dir_copy", TRUE
, ERROR_ACCESS_DENIED
, ERROR_ACCESS_DENIED
},
1422 { NULL
, "f1", TRUE
, ERROR_INVALID_PARAMETER
, ERROR_INVALID_PARAMETER
},
1423 { "f1", NULL
, TRUE
, ERROR_INVALID_PARAMETER
, ERROR_INVALID_PARAMETER
},
1424 { "not_exist", "tr2_test_dir", TRUE
, ERROR_FILE_NOT_FOUND
, ERROR_FILE_NOT_FOUND
},
1425 { "f1", "not_exist_dir\\f1_copy", TRUE
, ERROR_PATH_NOT_FOUND
, ERROR_FILE_NOT_FOUND
},
1426 { "f1", "tr2_test_dir", TRUE
, ERROR_ACCESS_DENIED
, ERROR_FILE_EXISTS
}
1429 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1430 ok(ret
== 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1431 file
= CreateFileA("f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1432 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1433 file_size
.QuadPart
= 7;
1434 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1435 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1438 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
1440 ret
= p_tr2_sys__Copy_file(tests
[i
].source
, tests
[i
].dest
, tests
[i
].fail_if_exists
);
1441 ok(ret
== tests
[i
].last_error
|| ret
== tests
[i
].last_error2
,
1442 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n", i
+1, tests
[i
].last_error
, ret
);
1443 ok(errno
== 0xdeadbeef, "test_tr2_sys__Copy_file(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1444 if(ret
== ERROR_SUCCESS
)
1445 ok(p_tr2_sys__File_size(tests
[i
].source
) == p_tr2_sys__File_size(tests
[i
].dest
),
1446 "test_tr2_sys__Copy_file(): test %d failed, mismatched file sizes\n", i
+1);
1448 ret
= p_tr2_sys__Copy_file_wchar(L
"f1", L
"fw", TRUE
);
1449 ok(ret
== ERROR_SUCCESS
, "test_tr2_sys__Copy_file_wchar() expect ERROR_SUCCESS, got %d\n", ret
);
1451 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1452 ok(DeleteFileW(L
"fw"), "expect fw to exist\n");
1453 ok(DeleteFileA("f1_copy"), "expect f1_copy to exist\n");
1454 ok(DeleteFileA("tr2_test_dir/f1_copy"), "expect tr2_test_dir/f1 to exist\n");
1455 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1456 ok(ret
== 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1459 static void test_tr2_sys__Rename(void)
1462 HANDLE file
, h1
, h2
;
1463 BY_HANDLE_FILE_INFORMATION info1
, info2
;
1464 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
1465 LARGE_INTEGER file_size
;
1466 static const struct {
1467 char const *old_path
;
1468 char const *new_path
;
1471 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_SUCCESS
},
1472 { "tr2_test_dir\\f1", NULL
, ERROR_INVALID_PARAMETER
},
1473 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND
},
1474 { NULL
, "tr2_test_dir\\NULL_rename", ERROR_INVALID_PARAMETER
},
1475 { "tr2_test_dir\\f1_rename", "tr2_test_dir\\??invalid_name>>", ERROR_INVALID_NAME
},
1476 { "tr2_test_dir\\not_exist_file", "tr2_test_dir\\not_exist_rename", ERROR_FILE_NOT_FOUND
}
1478 static const struct {
1479 const WCHAR
*old_path
;
1480 const WCHAR
*new_path
;
1483 { L
"tr2_test_dir/f1", L
"tr2_test_dir\\f1_rename", ERROR_SUCCESS
},
1484 { L
"tr2_test_dir/f1", NULL
, ERROR_FILE_NOT_FOUND
}, /* Differs from the A version */
1485 { L
"tr2_test_dir/f1", L
"tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND
},
1486 { NULL
, L
"tr2_test_dir\\f1_rename2", ERROR_PATH_NOT_FOUND
}, /* Differs from the A version */
1487 { L
"tr2_test_dir\\f1_rename", L
"tr2_test_dir\\??invalid>", ERROR_INVALID_NAME
},
1488 { L
"tr2_test_dir\\not_exist", L
"tr2_test_dir\\not_exist2", ERROR_FILE_NOT_FOUND
},
1489 { L
"tr2_test_dir\\not_exist", L
"tr2_test_dir\\??invalid>", ERROR_FILE_NOT_FOUND
}
1492 GetCurrentDirectoryA(MAX_PATH
, current_path
);
1493 GetTempPathA(MAX_PATH
, temp_path
);
1494 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
1495 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1497 ok(ret
== 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1498 file
= CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1499 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1502 ret
= p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1");
1503 ok(ERROR_SUCCESS
== ret
, "test_tr2_sys__Rename(): expect: ERROR_SUCCESS, got %d\n", ret
);
1504 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
1506 if(tests
[i
].val
== ERROR_SUCCESS
) {
1507 h1
= CreateFileA(tests
[i
].old_path
, 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1508 NULL
, OPEN_EXISTING
, 0, 0);
1509 ok(h1
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1510 ok(GetFileInformationByHandle(h1
, &info1
), "GetFileInformationByHandle failed\n");
1513 SetLastError(0xdeadbeef);
1514 ret
= p_tr2_sys__Rename(tests
[i
].old_path
, tests
[i
].new_path
);
1515 ok(ret
== tests
[i
].val
, "test_tr2_sys__Rename(): test %d expect: %d, got %d\n", i
+1, tests
[i
].val
, ret
);
1516 ok(errno
== 0xdeadbeef, "test_tr2_sys__Rename(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1517 if(ret
== ERROR_SUCCESS
) {
1518 h2
= CreateFileA(tests
[i
].new_path
, 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1519 NULL
, OPEN_EXISTING
, 0, 0);
1520 ok(h2
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1521 ok(GetFileInformationByHandle(h2
, &info2
), "GetFileInformationByHandle failed\n");
1523 ok(info1
.nFileIndexHigh
== info2
.nFileIndexHigh
1524 && info1
.nFileIndexLow
== info2
.nFileIndexLow
,
1525 "test_tr2_sys__Rename(): test %d expect two files equivalent\n", i
+1);
1529 file
= CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1530 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1531 file_size
.QuadPart
= 7;
1532 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1533 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1535 ret
= p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1_rename");
1536 ok(ret
== ERROR_ALREADY_EXISTS
, "test_tr2_sys__Rename(): expect: ERROR_ALREADY_EXISTS, got %d\n", ret
);
1537 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")));
1538 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")));
1540 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1542 for(i
=0; i
<ARRAY_SIZE(testsW
); i
++) {
1544 if(testsW
[i
].val
== ERROR_SUCCESS
) {
1545 h1
= CreateFileW(testsW
[i
].old_path
, 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1546 NULL
, OPEN_EXISTING
, 0, 0);
1547 ok(h1
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1548 ok(GetFileInformationByHandle(h1
, &info1
), "GetFileInformationByHandle failed\n");
1551 SetLastError(0xdeadbeef);
1552 ret
= p_tr2_sys__Rename_wchar(testsW
[i
].old_path
, testsW
[i
].new_path
);
1553 ok(ret
== testsW
[i
].val
, "test_tr2_sys__Rename_wchar(): test %d expect: %d, got %d\n", i
+1, testsW
[i
].val
, ret
);
1554 ok(errno
== 0xdeadbeef, "test_tr2_sys__Rename_wchar(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1555 if(ret
== ERROR_SUCCESS
) {
1556 h2
= CreateFileW(testsW
[i
].new_path
, 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1557 NULL
, OPEN_EXISTING
, 0, 0);
1558 ok(h2
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1559 ok(GetFileInformationByHandle(h2
, &info2
), "GetFileInformationByHandle failed\n");
1561 ok(info1
.nFileIndexHigh
== info2
.nFileIndexHigh
1562 && info1
.nFileIndexLow
== info2
.nFileIndexLow
,
1563 "test_tr2_sys__Rename_wchar(): test %d expect two files equivalent\n", i
+1);
1567 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1568 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1569 ok(ret
== 1, "test_tr2_sys__Remove_dir(): expect %d got %d\n", 1, ret
);
1570 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
1573 static void test_tr2_sys__Statvfs(void)
1575 struct space_info info
;
1576 char current_path
[MAX_PATH
];
1577 WCHAR current_path_wchar
[MAX_PATH
];
1579 p_tr2_sys__Current_get(current_path
);
1580 p_tr2_sys__Current_get_wchar(current_path_wchar
);
1582 p_tr2_sys__Statvfs(&info
, current_path
);
1583 ok(info
.capacity
>= info
.free
, "test_tr2_sys__Statvfs(): info.capacity < info.free\n");
1584 ok(info
.free
>= info
.available
, "test_tr2_sys__Statvfs(): info.free < info.available\n");
1586 p_tr2_sys__Statvfs_wchar(&info
, current_path_wchar
);
1587 ok(info
.capacity
>= info
.free
, "tr2_sys__Statvfs_wchar(): info.capacity < info.free\n");
1588 ok(info
.free
>= info
.available
, "tr2_sys__Statvfs_wchar(): info.free < info.available\n");
1590 p_tr2_sys__Statvfs(&info
, NULL
);
1591 ok(info
.available
== 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1592 0, wine_dbgstr_longlong(info
.available
));
1593 ok(info
.capacity
== 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1594 0, wine_dbgstr_longlong(info
.capacity
));
1595 ok(info
.free
== 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1596 0, wine_dbgstr_longlong(info
.free
));
1598 p_tr2_sys__Statvfs(&info
, "not_exist");
1599 ok(info
.available
== 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1600 0, wine_dbgstr_longlong(info
.available
));
1601 ok(info
.capacity
== 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1602 0, wine_dbgstr_longlong(info
.capacity
));
1603 ok(info
.free
== 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1604 0, wine_dbgstr_longlong(info
.free
));
1607 static void test_tr2_sys__Stat(void)
1609 int i
, err_code
, ret
;
1618 { NULL
, status_unknown
, ERROR_INVALID_PARAMETER
, FALSE
},
1619 { "tr2_test_dir", directory_file
, ERROR_SUCCESS
, FALSE
},
1620 { "tr2_test_dir\\f1", regular_file
, ERROR_SUCCESS
, FALSE
},
1621 { "tr2_test_dir\\not_exist_file ", file_not_found
, ERROR_SUCCESS
, FALSE
},
1622 { "tr2_test_dir\\??invalid_name>>", file_not_found
, ERROR_SUCCESS
, FALSE
},
1623 { "tr2_test_dir\\f1_link" , regular_file
, ERROR_SUCCESS
, TRUE
},
1624 { "tr2_test_dir\\dir_link", directory_file
, ERROR_SUCCESS
, TRUE
},
1627 CreateDirectoryA("tr2_test_dir", NULL
);
1628 file
= CreateFileA("tr2_test_dir/f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1629 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1630 ok(CloseHandle(file
), "CloseHandle\n");
1631 SetLastError(0xdeadbeef);
1632 ret
= pCreateSymbolicLinkA
? pCreateSymbolicLinkA("tr2_test_dir/f1_link", "tr2_test_dir/f1", 0) : FALSE
;
1633 if(!ret
&& (!pCreateSymbolicLinkA
|| GetLastError()==ERROR_PRIVILEGE_NOT_HELD
||GetLastError()==ERROR_INVALID_FUNCTION
)) {
1634 tests
[5].ret
= tests
[6].ret
= file_not_found
;
1635 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1637 ok(ret
, "CreateSymbolicLinkA failed\n");
1638 ok(pCreateSymbolicLinkA("tr2_test_dir/dir_link", "tr2_test_dir", 1), "CreateSymbolicLinkA failed\n");
1641 file
= CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1642 PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
, 2, 1024, 1024,
1643 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1644 ok(file
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1645 err_code
= 0xdeadbeef;
1646 val
= p_tr2_sys__Stat("\\\\.\\PiPe\\tests_pipe.c", &err_code
);
1647 todo_wine
ok(regular_file
== val
, "tr2_sys__Stat(): expect: regular_file, got %d\n", val
);
1648 todo_wine
ok(ERROR_SUCCESS
== err_code
, "tr2_sys__Stat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code
);
1649 err_code
= 0xdeadbeef;
1650 val
= p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code
);
1651 ok(status_unknown
== val
, "tr2_sys__Lstat(): expect: status_unknown, got %d\n", val
);
1652 todo_wine
ok(ERROR_PIPE_BUSY
== err_code
, "tr2_sys__Lstat(): err_code expect: ERROR_PIPE_BUSY, got %d\n", err_code
);
1653 ok(CloseHandle(file
), "CloseHandle\n");
1654 file
= CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1655 PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
, 2, 1024, 1024,
1656 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1657 ok(file
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1658 err_code
= 0xdeadbeef;
1659 val
= p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code
);
1660 todo_wine
ok(regular_file
== val
, "tr2_sys__Lstat(): expect: regular_file, got %d\n", val
);
1661 todo_wine
ok(ERROR_SUCCESS
== err_code
, "tr2_sys__Lstat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code
);
1662 ok(CloseHandle(file
), "CloseHandle\n");
1664 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
1665 err_code
= 0xdeadbeef;
1666 val
= p_tr2_sys__Stat(tests
[i
].path
, &err_code
);
1667 todo_wine_if(tests
[i
].is_todo
)
1668 ok(tests
[i
].ret
== val
, "tr2_sys__Stat(): test %d expect: %d, got %d\n", i
+1, tests
[i
].ret
, val
);
1669 ok(tests
[i
].err_code
== err_code
, "tr2_sys__Stat(): test %d err_code expect: %d, got %d\n",
1670 i
+1, tests
[i
].err_code
, err_code
);
1672 /* test tr2_sys__Lstat */
1673 err_code
= 0xdeadbeef;
1674 val
= p_tr2_sys__Lstat(tests
[i
].path
, &err_code
);
1675 todo_wine_if(tests
[i
].is_todo
)
1676 ok(tests
[i
].ret
== val
, "tr2_sys__Lstat(): test %d expect: %d, got %d\n", i
+1, tests
[i
].ret
, val
);
1677 ok(tests
[i
].err_code
== err_code
, "tr2_sys__Lstat(): test %d err_code expect: %d, got %d\n",
1678 i
+1, tests
[i
].err_code
, err_code
);
1681 err_code
= 0xdeadbeef;
1682 val
= p_tr2_sys__Stat_wchar(L
"tr2_test_dir", &err_code
);
1683 ok(directory_file
== val
, "tr2_sys__Stat_wchar() expect directory_file, got %d\n", val
);
1684 ok(ERROR_SUCCESS
== err_code
, "tr2_sys__Stat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code
);
1685 err_code
= 0xdeadbeef;
1686 val
= p_tr2_sys__Lstat_wchar(L
"tr2_test_dir/f1", &err_code
);
1687 ok(regular_file
== val
, "tr2_sys__Lstat_wchar() expect regular_file, got %d\n", val
);
1688 ok(ERROR_SUCCESS
== err_code
, "tr2_sys__Lstat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code
);
1691 todo_wine
ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1692 todo_wine
ok(RemoveDirectoryA("tr2_test_dir/dir_link"), "expect tr2_test_dir/dir_link to exist\n");
1694 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1695 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1698 static void test_tr2_sys__Last_write_time(void)
1702 __int64 last_write_time
, newtime
;
1703 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1704 ok(ret
== 1, "tr2_sys__Make_dir() expect 1 got %d\n", ret
);
1706 file
= CreateFileA("tr2_test_dir/f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1707 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1710 last_write_time
= p_tr2_sys__Last_write_time("tr2_test_dir/f1");
1711 newtime
= p_tr2_sys__Last_write_time_wchar(L
"tr2_test_dir/f1");
1712 ok(last_write_time
== newtime
, "last_write_time = %s, newtime = %s\n",
1713 wine_dbgstr_longlong(last_write_time
), wine_dbgstr_longlong(newtime
));
1714 newtime
= last_write_time
+ 123456789;
1715 p_tr2_sys__Last_write_time_set("tr2_test_dir/f1", newtime
);
1716 todo_wine
ok(last_write_time
== p_tr2_sys__Last_write_time("tr2_test_dir/f1"),
1717 "last_write_time should have changed: %s\n",
1718 wine_dbgstr_longlong(last_write_time
));
1721 last_write_time
= p_tr2_sys__Last_write_time("not_exist");
1722 ok(errno
== 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno
);
1723 ok(last_write_time
== 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time
));
1724 last_write_time
= p_tr2_sys__Last_write_time(NULL
);
1725 ok(last_write_time
== 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time
));
1727 p_tr2_sys__Last_write_time_set("not_exist", newtime
);
1729 p_tr2_sys__Last_write_time_set(NULL
, newtime
);
1730 ok(errno
== 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno
);
1732 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1733 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1734 ok(ret
== 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1737 static void test_tr2_sys__dir_operation(void)
1739 char *file_name
, first_file_name
[MAX_PATH
], dest
[MAX_PATH
], longer_path
[MAX_PATH
];
1740 HANDLE file
, result_handle
;
1741 enum file_type type
;
1742 int err
, num_of_f1
= 0, num_of_f2
= 0, num_of_sub_dir
= 0, num_of_other_files
= 0;
1744 CreateDirectoryA("tr2_test_dir", NULL
);
1745 file
= CreateFileA("tr2_test_dir/f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1746 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1748 file
= CreateFileA("tr2_test_dir/f2", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1749 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1751 CreateDirectoryA("tr2_test_dir/sub_dir", NULL
);
1752 file
= CreateFileA("tr2_test_dir/sub_dir/sub_f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1753 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1756 GetCurrentDirectoryA(MAX_PATH
, longer_path
);
1757 strcat(longer_path
, "\\tr2_test_dir\\");
1758 while(lstrlenA(longer_path
) < MAX_PATH
-1)
1759 strcat(longer_path
, "s");
1760 ok(lstrlenA(longer_path
) == MAX_PATH
-1, "tr2_sys__Open_dir(): expect MAX_PATH, got %d\n", lstrlenA(longer_path
));
1761 memset(first_file_name
, 0xff, MAX_PATH
);
1762 type
= err
= 0xdeadbeef;
1763 result_handle
= NULL
;
1764 result_handle
= p_tr2_sys__Open_dir(first_file_name
, longer_path
, &err
, &type
);
1765 ok(result_handle
== NULL
, "tr2_sys__Open_dir(): expect NULL, got %p\n", result_handle
);
1766 ok(!*first_file_name
, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name
);
1767 ok(err
== ERROR_BAD_PATHNAME
, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err
);
1768 ok((int)type
== 0xdeadbeef, "tr2_sys__Open_dir(): expect 0xdeadbeef, got %d\n", type
);
1770 memset(first_file_name
, 0xff, MAX_PATH
);
1771 memset(dest
, 0, MAX_PATH
);
1772 type
= err
= 0xdeadbeef;
1773 result_handle
= NULL
;
1774 result_handle
= p_tr2_sys__Open_dir(first_file_name
, "tr2_test_dir", &err
, &type
);
1775 ok(result_handle
!= NULL
, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle
);
1776 ok(err
== ERROR_SUCCESS
, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err
);
1777 file_name
= first_file_name
;
1779 if (!strcmp(file_name
, "f1")) {
1781 ok(type
== regular_file
, "expect regular_file, got %d\n", type
);
1782 }else if(!strcmp(file_name
, "f2")) {
1784 ok(type
== regular_file
, "expect regular_file, got %d\n", type
);
1785 }else if(!strcmp(file_name
, "sub_dir")) {
1787 ok(type
== directory_file
, "expect directory_file, got %d\n", type
);
1789 ++num_of_other_files
;
1791 file_name
= p_tr2_sys__Read_dir(dest
, result_handle
, &type
);
1793 ok(type
== status_unknown
, "p_tr2_sys__Read_dir(): expect: status_unknown, got %d\n", type
);
1794 p_tr2_sys__Close_dir(result_handle
);
1795 ok(result_handle
!= NULL
, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle
);
1796 ok(num_of_f1
== 1, "found f1 %d times\n", num_of_f1
);
1797 ok(num_of_f2
== 1, "found f2 %d times\n", num_of_f2
);
1798 ok(num_of_sub_dir
== 1, "found sub_dir %d times\n", num_of_sub_dir
);
1799 ok(num_of_other_files
== 0, "found %d other files\n", num_of_other_files
);
1801 memset(first_file_name
, 0xff, MAX_PATH
);
1802 type
= err
= 0xdeadbeef;
1803 result_handle
= file
;
1804 result_handle
= p_tr2_sys__Open_dir(first_file_name
, "not_exist", &err
, &type
);
1805 ok(result_handle
== NULL
, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle
);
1806 ok(err
== ERROR_BAD_PATHNAME
, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err
);
1807 ok((int)type
== 0xdeadbeef, "tr2_sys__Open_dir(): expect: 0xdeadbeef, got %d\n", type
);
1808 ok(!*first_file_name
, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name
);
1810 CreateDirectoryA("empty_dir", NULL
);
1811 memset(first_file_name
, 0xff, MAX_PATH
);
1812 type
= err
= 0xdeadbeef;
1813 result_handle
= file
;
1814 result_handle
= p_tr2_sys__Open_dir(first_file_name
, "empty_dir", &err
, &type
);
1815 ok(result_handle
== NULL
, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle
);
1816 ok(err
== ERROR_SUCCESS
, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err
);
1817 ok(type
== status_unknown
, "tr2_sys__Open_dir(): expect: status_unknown, got %d\n", type
);
1818 ok(!*first_file_name
, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name
);
1819 p_tr2_sys__Close_dir(result_handle
);
1820 ok(result_handle
== NULL
, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle
);
1822 ok(RemoveDirectoryA("empty_dir"), "expect empty_dir to exist\n");
1823 ok(DeleteFileA("tr2_test_dir/sub_dir/sub_f1"), "expect tr2_test_dir/sub_dir/sub_f1 to exist\n");
1824 ok(RemoveDirectoryA("tr2_test_dir/sub_dir"), "expect tr2_test_dir/sub_dir to exist\n");
1825 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1826 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1827 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1830 static void test_tr2_sys__Link(void)
1833 HANDLE file
, h1
, h2
;
1834 BY_HANDLE_FILE_INFORMATION info1
, info2
;
1835 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
1836 LARGE_INTEGER file_size
;
1838 char const *existing_path
;
1839 char const *new_path
;
1840 MSVCP_bool fail_if_exists
;
1843 { "f1", "f1_link", TRUE
, ERROR_SUCCESS
},
1844 { "f1", "tr2_test_dir\\f1_link", TRUE
, ERROR_SUCCESS
},
1845 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", TRUE
, ERROR_SUCCESS
},
1846 { "tr2_test_dir", "dir_link", TRUE
, ERROR_ACCESS_DENIED
},
1847 { NULL
, "NULL_link", TRUE
, ERROR_INVALID_PARAMETER
},
1848 { "f1", NULL
, TRUE
, ERROR_INVALID_PARAMETER
},
1849 { "not_exist", "not_exist_link", TRUE
, ERROR_FILE_NOT_FOUND
},
1850 { "f1", "not_exist_dir\\f1_link", TRUE
, ERROR_PATH_NOT_FOUND
}
1853 GetCurrentDirectoryA(MAX_PATH
, current_path
);
1854 GetTempPathA(MAX_PATH
, temp_path
);
1855 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
1857 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1858 ok(ret
== 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1859 file
= CreateFileA("f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1860 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1861 file_size
.QuadPart
= 7;
1862 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1863 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1866 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
1868 ret
= p_tr2_sys__Link(tests
[i
].existing_path
, tests
[i
].new_path
);
1869 ok(ret
== tests
[i
].last_error
, "tr2_sys__Link(): test %d expect: %d, got %d\n",
1870 i
+1, tests
[i
].last_error
, ret
);
1871 ok(errno
== 0xdeadbeef, "tr2_sys__Link(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1872 if(ret
== ERROR_SUCCESS
)
1873 ok(p_tr2_sys__File_size(tests
[i
].existing_path
) == p_tr2_sys__File_size(tests
[i
].new_path
),
1874 "tr2_sys__Link(): test %d failed, mismatched file sizes\n", i
+1);
1877 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1878 ok(p_tr2_sys__File_size("f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link") &&
1879 p_tr2_sys__File_size("tr2_test_dir/f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link_link"),
1880 "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")));
1881 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")));
1883 file
= CreateFileA("f1_link", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1884 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1885 file_size
.QuadPart
= 20;
1886 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1887 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1889 h1
= CreateFileA("f1_link", 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1890 NULL
, OPEN_EXISTING
, 0, 0);
1891 ok(h1
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1892 ok(GetFileInformationByHandle(h1
, &info1
), "GetFileInformationByHandle failed\n");
1894 h2
= CreateFileA("tr2_test_dir/f1_link", 0, FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1895 NULL
, OPEN_EXISTING
, 0, 0);
1896 ok(h2
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1897 ok(GetFileInformationByHandle(h2
, &info2
), "GetFileInformationByHandle failed\n");
1899 ok(info1
.nFileIndexHigh
== info2
.nFileIndexHigh
1900 && info1
.nFileIndexLow
== info2
.nFileIndexLow
,
1901 "tr2_sys__Link(): test %d expect two files equivalent\n", i
+1);
1902 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")));
1904 ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1905 ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1906 ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1907 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1908 ok(ret
== 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1909 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
1912 static void test_tr2_sys__Symlink(void)
1916 LARGE_INTEGER file_size
;
1918 char const *existing_path
;
1919 char const *new_path
;
1923 { "f1", "f1_link", ERROR_SUCCESS
, FALSE
},
1924 { "f1", "tr2_test_dir\\f1_link", ERROR_SUCCESS
, FALSE
},
1925 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", ERROR_SUCCESS
, FALSE
},
1926 { "tr2_test_dir", "dir_link", ERROR_SUCCESS
, FALSE
},
1927 { NULL
, "NULL_link", ERROR_INVALID_PARAMETER
, FALSE
},
1928 { "f1", NULL
, ERROR_INVALID_PARAMETER
, FALSE
},
1929 { "not_exist", "not_exist_link", ERROR_SUCCESS
, FALSE
},
1930 { "f1", "not_exist_dir\\f1_link", ERROR_PATH_NOT_FOUND
, TRUE
}
1933 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1934 ok(ret
== 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1935 file
= CreateFileA("f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1936 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1937 file_size
.QuadPart
= 7;
1938 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
1939 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
1942 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
1944 SetLastError(0xdeadbeef);
1945 ret
= p_tr2_sys__Symlink(tests
[i
].existing_path
, tests
[i
].new_path
);
1946 if(!i
&& (ret
==ERROR_PRIVILEGE_NOT_HELD
|| ret
==ERROR_INVALID_FUNCTION
|| ret
==ERROR_CALL_NOT_IMPLEMENTED
)) {
1947 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1948 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1949 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1950 ok(ret
== 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1954 ok(errno
== 0xdeadbeef, "tr2_sys__Symlink(): test %d errno expect 0xdeadbeef, got %d\n", i
+1, errno
);
1955 todo_wine_if(tests
[i
].is_todo
)
1956 ok(ret
== tests
[i
].last_error
, "tr2_sys__Symlink(): test %d expect: %d, got %d\n", i
+1, tests
[i
].last_error
, ret
);
1957 if(ret
== ERROR_SUCCESS
)
1958 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
)));
1961 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1962 todo_wine
ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1963 todo_wine
ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1964 todo_wine
ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1965 todo_wine
ok(DeleteFileA("not_exist_link"), "expect not_exist_link to exist\n");
1966 todo_wine
ok(DeleteFileA("dir_link"), "expect dir_link to exist\n");
1967 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
1968 ok(ret
== 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
1971 static void test_tr2_sys__Unlink(void)
1973 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
1976 LARGE_INTEGER file_size
;
1982 { "tr2_test_dir\\f1_symlink", ERROR_SUCCESS
, TRUE
},
1983 { "tr2_test_dir\\f1_link", ERROR_SUCCESS
, FALSE
},
1984 { "tr2_test_dir\\f1", ERROR_SUCCESS
, FALSE
},
1985 { "tr2_test_dir", ERROR_ACCESS_DENIED
, FALSE
},
1986 { "not_exist", ERROR_FILE_NOT_FOUND
, FALSE
},
1987 { "not_exist_dir\\not_exist_file", ERROR_PATH_NOT_FOUND
, FALSE
},
1988 { NULL
, ERROR_PATH_NOT_FOUND
, FALSE
}
1991 GetCurrentDirectoryA(MAX_PATH
, current_path
);
1992 GetTempPathA(MAX_PATH
, temp_path
);
1993 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
1995 ret
= p_tr2_sys__Make_dir("tr2_test_dir");
1996 ok(ret
== 1, "tr2_sys__Make_dir(): expect 1 got %d\n", ret
);
1997 file
= CreateFileA("tr2_test_dir/f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1998 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
1999 file_size
.QuadPart
= 7;
2000 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
2001 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
2004 ret
= p_tr2_sys__Symlink("tr2_test_dir/f1", "tr2_test_dir/f1_symlink");
2005 if(ret
==ERROR_PRIVILEGE_NOT_HELD
|| ret
==ERROR_INVALID_FUNCTION
|| ret
==ERROR_CALL_NOT_IMPLEMENTED
) {
2006 tests
[0].last_error
= ERROR_FILE_NOT_FOUND
;
2007 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
2009 ok(ret
== ERROR_SUCCESS
, "tr2_sys__Symlink(): expect: ERROR_SUCCESS, got %d\n", ret
);
2011 ret
= p_tr2_sys__Link("tr2_test_dir/f1", "tr2_test_dir/f1_link");
2012 ok(ret
== ERROR_SUCCESS
, "tr2_sys__Link(): expect: ERROR_SUCCESS, got %d\n", ret
);
2014 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
2016 ret
= p_tr2_sys__Unlink(tests
[i
].path
);
2017 todo_wine_if(tests
[i
].is_todo
)
2018 ok(ret
== tests
[i
].last_error
, "tr2_sys__Unlink(): test %d expect: %d, got %d\n",
2019 i
+1, tests
[i
].last_error
, ret
);
2020 ok(errno
== 0xdeadbeef, "tr2_sys__Unlink(): test %d errno expect: 0xdeadbeef, got %d\n", i
+1, ret
);
2023 ok(!DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 not to exist\n");
2024 ok(!DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link not to exist\n");
2025 ok(!DeleteFileA("tr2_test_dir/f1_symlink"), "expect tr2_test_dir/f1_symlink not to exist\n");
2026 ret
= p_tr2_sys__Remove_dir("tr2_test_dir");
2027 ok(ret
== 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret
);
2029 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
2032 static int __cdecl
thrd_thread(void *arg
)
2037 *thr
= p__Thrd_current();
2041 static void test_thrd(void)
2049 const HANDLE hnd1
= (HANDLE
)0xcccccccc;
2050 const HANDLE hnd2
= (HANDLE
)0xdeadbeef;
2051 xtime xt
, before
, after
;
2055 struct test testeq
[] = {
2056 { {0, 0}, {0, 0}, 1 },
2057 { {0, 1}, {0, 0}, 0 },
2058 { {hnd1
, 0}, {hnd1
, 1}, 0 },
2059 { {hnd1
, 0}, {hnd2
, 0}, 1 }
2062 struct test testlt
[] = {
2063 { {0, 0}, {0, 0}, 0 },
2064 { {0, 0}, {0, 1}, 1 },
2065 { {0, 1}, {0, 0}, 0 },
2066 { {hnd1
, 0}, {hnd2
, 0}, 0 },
2067 { {hnd1
, 0}, {hnd2
, 1}, 1 }
2070 /* test for equal */
2071 for(i
=0; i
<ARRAY_SIZE(testeq
); i
++) {
2072 ret
= p__Thrd_equal(testeq
[i
].a
, testeq
[i
].b
);
2073 ok(ret
== testeq
[i
].r
, "(%p %lu) = (%p %lu) expected %d, got %d\n",
2074 testeq
[i
].a
.hnd
, testeq
[i
].a
.id
, testeq
[i
].b
.hnd
, testeq
[i
].b
.id
, testeq
[i
].r
, ret
);
2077 /* test for less than */
2078 for(i
=0; i
<ARRAY_SIZE(testlt
); i
++) {
2079 ret
= p__Thrd_lt(testlt
[i
].a
, testlt
[i
].b
);
2080 ok(ret
== testlt
[i
].r
, "(%p %lu) < (%p %lu) expected %d, got %d\n",
2081 testlt
[i
].a
.hnd
, testlt
[i
].a
.id
, testlt
[i
].b
.hnd
, testlt
[i
].b
.id
, testlt
[i
].r
, ret
);
2084 /* test for sleep */
2085 if (0) /* crash on Windows */
2086 p__Thrd_sleep(NULL
);
2087 p_xtime_get(&xt
, 1);
2089 p_xtime_get(&before
, 1);
2091 p_xtime_get(&after
, 1);
2092 diff
= p__Xtime_diff_to_millis2(&after
, &before
);
2093 ok(diff
> 2000 - TIMEDELTA
, "got %d\n", diff
);
2095 /* test for current */
2096 ta
= p__Thrd_current();
2097 tb
= p__Thrd_current();
2098 ok(ta
.id
== tb
.id
, "got a %ld b %ld\n", ta
.id
, tb
.id
);
2099 ok(ta
.id
== GetCurrentThreadId(), "expected %ld, got %ld\n", GetCurrentThreadId(), ta
.id
);
2100 /* the handles can be different if new threads are created at same time */
2101 ok(ta
.hnd
!= NULL
, "handle a is NULL\n");
2102 ok(tb
.hnd
!= NULL
, "handle b is NULL\n");
2103 ok(!CloseHandle(ta
.hnd
), "handle %p not closed\n", ta
.hnd
);
2104 ok(!CloseHandle(tb
.hnd
), "handle %p not closed\n", tb
.hnd
);
2106 /* test for create/join */
2107 if (0) /* crash on Windows */
2109 p__Thrd_create(NULL
, thrd_thread
, NULL
);
2110 p__Thrd_create(&ta
, NULL
, NULL
);
2113 ret
= p__Thrd_create(&ta
, thrd_thread
, (void*)&tb
);
2114 ok(!ret
, "failed to create thread, got %d\n", ret
);
2115 ret
= p__Thrd_join(ta
, &r
);
2116 ok(!ret
, "failed to join thread, got %d\n", ret
);
2117 ok(ta
.id
== tb
.id
, "expected %ld, got %ld\n", ta
.id
, tb
.id
);
2118 ok(ta
.hnd
!= tb
.hnd
, "same handles, got %p\n", ta
.hnd
);
2119 ok(r
== 0x42, "expected 0x42, got %d\n", r
);
2120 ret
= p__Thrd_detach(ta
);
2121 ok(ret
== 4, "_Thrd_detach should have failed with error 4, got %d\n", ret
);
2123 ret
= p__Thrd_create(&ta
, thrd_thread
, NULL
);
2124 ok(!ret
, "failed to create thread, got %d\n", ret
);
2125 ret
= p__Thrd_detach(ta
);
2126 ok(!ret
, "_Thrd_detach failed, got %d\n", ret
);
2130 #define NUM_THREADS 10
2142 static int __cdecl
cnd_wait_thread(void *arg
)
2144 struct cndmtx
*cm
= arg
;
2147 p__Mtx_lock(&cm
->mtx
);
2149 if(InterlockedIncrement(&cm
->started
) == cm
->thread_no
)
2150 SetEvent(cm
->initialized
);
2152 if(cm
->timed_wait
) {
2155 p_xtime_get(&xt
, 1);
2157 r
= p__Cnd_timedwait(&cm
->cnd
, &cm
->mtx
, &xt
);
2158 ok(!r
, "timed wait failed\n");
2160 r
= p__Cnd_wait(&cm
->cnd
, &cm
->mtx
);
2161 ok(!r
, "wait failed\n");
2164 p__Mtx_unlock(&cm
->mtx
);
2168 static void test_cnd(void)
2170 _Thrd_t threads
[NUM_THREADS
];
2171 xtime xt
, before
, after
;
2178 r
= p__Cnd_init(&cnd
);
2179 ok(!r
, "failed to init cnd\n");
2181 r
= p__Mtx_init(&mtx
, 0);
2182 ok(!r
, "failed to init mtx\n");
2184 if (0) /* crash on Windows */
2187 p__Cnd_wait(NULL
, &mtx
);
2188 p__Cnd_wait(&cnd
, NULL
);
2189 p__Cnd_timedwait(NULL
, &mtx
, &xt
);
2190 p__Cnd_timedwait(&cnd
, &mtx
, &xt
);
2192 p__Cnd_destroy(NULL
);
2194 /* test _Cnd_signal/_Cnd_wait */
2195 cm
.initialized
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2200 cm
.timed_wait
= FALSE
;
2201 p__Thrd_create(&threads
[0], cnd_wait_thread
, (void*)&cm
);
2203 WaitForSingleObject(cm
.initialized
, INFINITE
);
2205 p__Mtx_unlock(&mtx
);
2207 r
= p__Cnd_signal(&cm
.cnd
);
2208 ok(!r
, "failed to signal\n");
2209 p__Thrd_join(threads
[0], NULL
);
2211 /* test _Cnd_timedwait time out */
2213 p_xtime_get(&before
, 1);
2216 r
= p__Cnd_timedwait(&cnd
, &mtx
, &xt
);
2217 p_xtime_get(&after
, 1);
2218 p__Mtx_unlock(&mtx
);
2220 diff
= p__Xtime_diff_to_millis2(&after
, &before
);
2221 ok(r
== 2, "should have timed out\n");
2222 ok(diff
> 1000 - TIMEDELTA
, "got %d\n", diff
);
2224 /* test _Cnd_timedwait */
2226 cm
.timed_wait
= TRUE
;
2227 p__Thrd_create(&threads
[0], cnd_wait_thread
, (void*)&cm
);
2229 WaitForSingleObject(cm
.initialized
, INFINITE
);
2231 p__Mtx_unlock(&mtx
);
2233 r
= p__Cnd_signal(&cm
.cnd
);
2234 ok(!r
, "failed to signal\n");
2235 p__Thrd_join(threads
[0], NULL
);
2237 /* test _Cnd_do_broadcast_at_thread_exit */
2239 cm
.timed_wait
= FALSE
;
2240 p__Thrd_create(&threads
[0], cnd_wait_thread
, (void*)&cm
);
2242 WaitForSingleObject(cm
.initialized
, INFINITE
);
2246 p__Cnd_unregister_at_thread_exit((_Mtx_t
*)0xdeadbeef);
2247 p__Cnd_register_at_thread_exit(&cnd
, &mtx
, &r
);
2248 ok(r
== 0xcafe, "r = %x\n", r
);
2249 p__Cnd_register_at_thread_exit(&cnd
, &mtx
, &r
);
2250 p__Cnd_unregister_at_thread_exit(&mtx
);
2251 p__Cnd_do_broadcast_at_thread_exit();
2252 ok(mtx
->count
== 1, "mtx.count = %ld\n", mtx
->count
);
2254 p__Cnd_register_at_thread_exit(&cnd
, &mtx
, &r
);
2255 ok(r
== 0xcafe, "r = %x\n", r
);
2257 p__Cnd_do_broadcast_at_thread_exit();
2258 ok(r
== 1, "r = %x\n", r
);
2259 p__Thrd_join(threads
[0], NULL
);
2261 /* crash if _Cnd_do_broadcast_at_thread_exit is called on exit */
2262 p__Cnd_register_at_thread_exit((_Cnd_t
*)0xdeadbeef, (_Mtx_t
*)0xdeadbeef, (int*)0xdeadbeef);
2264 /* test _Cnd_broadcast */
2266 cm
.thread_no
= NUM_THREADS
;
2268 for(i
= 0; i
< cm
.thread_no
; i
++)
2269 p__Thrd_create(&threads
[i
], cnd_wait_thread
, (void*)&cm
);
2271 WaitForSingleObject(cm
.initialized
, INFINITE
);
2273 p__Mtx_unlock(&mtx
);
2275 r
= p__Cnd_broadcast(&cnd
);
2276 ok(!r
, "failed to broadcast\n");
2277 for(i
= 0; i
< cm
.thread_no
; i
++)
2278 p__Thrd_join(threads
[i
], NULL
);
2280 /* test broadcast with _Cnd_destroy */
2282 for(i
= 0; i
< cm
.thread_no
; i
++)
2283 p__Thrd_create(&threads
[i
], cnd_wait_thread
, (void*)&cm
);
2285 WaitForSingleObject(cm
.initialized
, INFINITE
);
2287 p__Mtx_unlock(&mtx
);
2289 p__Cnd_destroy(&cnd
);
2290 for(i
= 0; i
< cm
.thread_no
; i
++)
2291 p__Thrd_join(threads
[i
], NULL
);
2293 p__Mtx_destroy(&mtx
);
2294 CloseHandle(cm
.initialized
);
2299 const char* export_name
;
2300 } vbtable_size_exports_list
[] = {
2301 {{0x20, 0x20}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"},
2302 {{0x10, 0x10}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"},
2303 {{0x20, 0x20}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"},
2304 {{0x10, 0x10}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"},
2305 {{0x20, 0x20}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"},
2306 {{0x10, 0x10}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"},
2307 {{0x18, 0x18}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"},
2308 {{0x18, 0x18}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"},
2309 {{0x18, 0x18}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"},
2310 {{ 0x8, 0x10}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"},
2311 {{ 0x8, 0x10}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"},
2312 {{ 0x8, 0x10}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"},
2316 static void test_vbtable_size_exports(void)
2319 const int *p_vbtable
;
2320 int arch_idx
= (sizeof(void*) == 8);
2322 for (i
= 0; vbtable_size_exports_list
[i
].export_name
; i
++)
2324 SET(p_vbtable
, vbtable_size_exports_list
[i
].export_name
);
2326 ok(p_vbtable
[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable
[0]);
2327 ok(p_vbtable
[1] == vbtable_size_exports_list
[i
].value
[arch_idx
],
2328 "%d: %s[1] wrong, got 0x%x\n", i
, vbtable_size_exports_list
[i
].export_name
, p_vbtable
[1]);
2332 HANDLE _Pad__Launch_returned
;
2335 /* TODO: this should be a __thiscall function */
2336 static unsigned int __stdcall
vtbl_func__Go(void)
2338 static unsigned int __cdecl
vtbl_func__Go(_Pad
*this)
2343 ret
= WaitForSingleObject(_Pad__Launch_returned
, 100);
2344 ok(ret
== WAIT_TIMEOUT
, "WiatForSingleObject returned %lx\n", ret
);
2345 ok(!pad
.mtx
->count
, "pad.mtx.count = %ld\n", pad
.mtx
->count
);
2346 ok(!pad
.launched
, "pad.launched = %x\n", pad
.launched
);
2347 call_func1(p__Pad__Release
, &pad
);
2348 ok(pad
.launched
, "pad.launched = %x\n", pad
.launched
);
2349 ret
= WaitForSingleObject(_Pad__Launch_returned
, 100);
2350 ok(ret
== WAIT_OBJECT_0
, "WiatForSingleObject returned %lx\n", ret
);
2351 ok(pad
.mtx
->count
== 1, "pad.mtx.count = %ld\n", pad
.mtx
->count
);
2355 static void test__Pad(void)
2359 vtable_ptr pfunc
= (vtable_ptr
)&vtbl_func__Go
;
2361 _Pad__Launch_returned
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2363 pad
.vtable
= (void*)1;
2366 pad
.launched
= TRUE
;
2367 memset(&pad_copy
, 0, sizeof(pad_copy
));
2368 call_func2(p__Pad_copy_ctor
, &pad_copy
, &pad
);
2369 ok(pad_copy
.vtable
!= (void*)1, "pad_copy.vtable was not set\n");
2370 ok(pad_copy
.cnd
== (void*)2, "pad_copy.cnd = %p\n", pad_copy
.cnd
);
2371 ok(pad_copy
.mtx
== (void*)3, "pad_copy.mtx = %p\n", pad_copy
.mtx
);
2372 ok(pad_copy
.launched
, "pad_copy.launched = %x\n", pad_copy
.launched
);
2374 memset(&pad_copy
, 0xde, sizeof(pad_copy
));
2375 pad_copy
.vtable
= (void*)4;
2376 pad_copy
.cnd
= (void*)5;
2377 pad_copy
.mtx
= (void*)6;
2378 pad_copy
.launched
= FALSE
;
2379 call_func2(p__Pad_op_assign
, &pad_copy
, &pad
);
2380 ok(pad_copy
.vtable
== (void*)4, "pad_copy.vtable was set\n");
2381 ok(pad_copy
.cnd
== (void*)2, "pad_copy.cnd = %p\n", pad_copy
.cnd
);
2382 ok(pad_copy
.mtx
== (void*)3, "pad_copy.mtx = %p\n", pad_copy
.mtx
);
2383 ok(pad_copy
.launched
, "pad_copy.launched = %x\n", pad_copy
.launched
);
2385 call_func1(p__Pad_ctor
, &pad
);
2386 call_func2(p__Pad_copy_ctor
, &pad_copy
, &pad
);
2387 ok(pad
.vtable
== pad_copy
.vtable
, "pad.vtable = %p, pad_copy.vtable = %p\n", pad
.vtable
, pad_copy
.vtable
);
2388 ok(pad
.cnd
== pad_copy
.cnd
, "pad.cnd = %p, pad_copy.cnd = %p\n", pad
.cnd
, pad_copy
.cnd
);
2389 ok(pad
.mtx
== pad_copy
.mtx
, "pad.mtx = %p, pad_copy.mtx = %p\n", pad
.mtx
, pad_copy
.mtx
);
2390 ok(pad
.launched
== pad_copy
.launched
, "pad.launched = %x, pad_copy.launched = %x\n", pad
.launched
, pad_copy
.launched
);
2391 call_func1(p__Pad_dtor
, &pad
);
2392 /* call_func1(p__Pad_dtor, &pad_copy); - copy constructor is broken, this causes a crash */
2394 memset(&pad
, 0xfe, sizeof(pad
));
2395 call_func1(p__Pad_ctor
, &pad
);
2396 ok(!pad
.launched
, "pad.launched = %x\n", pad
.launched
);
2397 ok(pad
.mtx
->count
== 1, "pad.mtx.count = %ld\n", pad
.mtx
->count
);
2399 pad
.vtable
= &pfunc
;
2400 call_func2(p__Pad__Launch
, &pad
, &thrd
);
2401 SetEvent(_Pad__Launch_returned
);
2402 ok(!p__Thrd_join(thrd
, NULL
), "_Thrd_join failed\n");
2404 call_func1(p__Pad_dtor
, &pad
);
2405 CloseHandle(_Pad__Launch_returned
);
2408 static void test__Mtx(void)
2411 static int flags
[] =
2413 0, MTX_PLAIN
, MTX_TRY
, MTX_TIMED
, MTX_RECURSIVE
,
2414 MTX_PLAIN
|MTX_TRY
, MTX_PLAIN
|MTX_RECURSIVE
, MTX_PLAIN
|0xbeef
2419 for (i
=0; i
<ARRAY_SIZE(flags
); i
++)
2421 if (flags
[i
] == MTX_PLAIN
|| flags
[i
] & MTX_RECURSIVE
)
2426 r
= p__Mtx_init(&mtx
, flags
[i
]);
2427 ok(!r
, "failed to init mtx (flags %x)\n", flags
[i
]);
2429 r
= p__Mtx_trylock(&mtx
);
2430 ok(!r
, "_Mtx_trylock returned %x (flags %x)\n", r
, flags
[i
]);
2431 r
= p__Mtx_trylock(&mtx
);
2432 ok(r
== expect
, "_Mtx_trylock returned %x (flags %x)\n", r
, flags
[i
]);
2433 if(!r
) p__Mtx_unlock(&mtx
);
2435 r
= p__Mtx_lock(&mtx
);
2436 ok(r
== expect
, "_Mtx_lock returned %x (flags %x)\n", r
, flags
[i
]);
2437 if(!r
) p__Mtx_unlock(&mtx
);
2439 p__Mtx_unlock(&mtx
);
2440 p__Mtx_destroy(&mtx
);
2444 static void test_threads__Mtx(void)
2448 p_threads__Mtx_new(&mtx
);
2449 ok(mtx
!= NULL
, "mtx == NULL\n");
2451 p_threads__Mtx_lock(mtx
);
2452 p_threads__Mtx_lock(mtx
);
2453 p_threads__Mtx_unlock(mtx
);
2454 p_threads__Mtx_unlock(mtx
);
2455 p_threads__Mtx_unlock(mtx
);
2457 p_threads__Mtx_delete(mtx
);
2460 static void test_vector_base_v4__Segment_index_of(void)
2479 {~0, 8*sizeof(void*)-1}
2482 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
2483 ret
= p_vector_base_v4__Segment_index_of(tests
[i
].x
);
2484 ok(ret
== tests
[i
].expect
, "expected %ld, got %ld for %ld\n",
2485 (long)tests
[i
].expect
, (long)ret
, (long)tests
[i
].x
);
2489 static HANDLE block_start
, block_end
;
2492 static void __thiscall
queue_char__Move_item(
2494 queue_base_v4
*this,
2496 _Page
*dst
, size_t idx
, void *src
)
2498 CHECK_EXPECT(queue_char__Move_item
);
2501 SetEvent(block_start
);
2502 WaitForSingleObject(block_end
, INFINITE
);
2504 memcpy(dst
->data
+ idx
, src
, sizeof(char));
2507 static void __thiscall
queue_char__Copy_item(
2509 queue_base_v4
*this,
2511 _Page
*dst
, size_t idx
, const void *src
)
2513 CHECK_EXPECT(queue_char__Copy_item
);
2516 SetEvent(block_start
);
2517 WaitForSingleObject(block_end
, INFINITE
);
2519 memcpy(dst
->data
+ idx
, src
, sizeof(char));
2522 static void __thiscall
queue_char__Assign_and_destroy_item(
2524 queue_base_v4
*this,
2526 void *dst
, _Page
*src
, size_t idx
)
2528 CHECK_EXPECT(queue_char__Assign_and_destroy_item
);
2531 SetEvent(block_start
);
2532 WaitForSingleObject(block_end
, INFINITE
);
2534 memcpy(dst
, src
->data
+ idx
, sizeof(char));
2538 static _Page
* __thiscall
queue_char__Allocate_page(queue_base_v4
*this)
2540 static _Page
* __thiscall
queue_char__Allocate_page(void)
2543 CHECK_EXPECT(queue_char__Allocate_page
);
2544 return malloc(sizeof(_Page
) + sizeof(char[256]));
2547 static void __thiscall
queue_char__Deallocate_page(
2549 queue_base_v4
*this,
2553 CHECK_EXPECT2(queue_char__Deallocate_page
);
2557 static const void* queue_char_vtbl
[] =
2559 queue_char__Move_item
,
2560 queue_char__Copy_item
,
2561 queue_char__Assign_and_destroy_item
,
2563 queue_char__Allocate_page
,
2564 queue_char__Deallocate_page
2567 static DWORD WINAPI
queue_move_push_thread(void *arg
)
2569 queue_base_v4
*queue
= arg
;
2572 alloc_expect_struct();
2573 SET_EXPECT(queue_char__Allocate_page
); /* ignore page allocations */
2574 SET_EXPECT(queue_char__Move_item
);
2575 call_func2(p_queue_base_v4__Internal_move_push
, queue
, &c
);
2576 CHECK_CALLED(queue_char__Move_item
);
2577 free_expect_struct();
2581 static DWORD WINAPI
queue_push_thread(void *arg
)
2583 queue_base_v4
*queue
= arg
;
2586 alloc_expect_struct();
2587 SET_EXPECT(queue_char__Copy_item
);
2588 call_func2(p_queue_base_v4__Internal_push
, queue
, &c
);
2589 CHECK_CALLED(queue_char__Copy_item
);
2590 free_expect_struct();
2594 static DWORD WINAPI
queue_pop_thread(void*arg
)
2596 queue_base_v4
*queue
= arg
;
2599 alloc_expect_struct();
2600 SET_EXPECT(queue_char__Assign_and_destroy_item
);
2601 call_func2(p_queue_base_v4__Internal_pop_if_present
, queue
, &c
);
2602 CHECK_CALLED(queue_char__Assign_and_destroy_item
);
2603 free_expect_struct();
2607 static void* __cdecl
concurrent_vector_int_alloc(vector_base_v4
*this, size_t n
)
2609 CHECK_EXPECT(concurrent_vector_int_alloc
);
2610 vector_alloc_count
++;
2611 return malloc(n
*sizeof(int));
2614 static void __cdecl
concurrent_vector_int_destroy(void *ptr
, size_t n
)
2616 CHECK_EXPECT2(concurrent_vector_int_destroy
);
2617 ok(vector_elem_count
>= n
, "invalid destroy\n");
2618 vector_elem_count
-= n
;
2619 memset(ptr
, 0xff, sizeof(int)*n
);
2622 static void concurrent_vector_int_ctor(vector_base_v4
*this)
2624 memset(this, 0, sizeof(*this));
2625 this->allocator
= concurrent_vector_int_alloc
;
2626 this->segment
= &this->storage
[0];
2629 static void concurrent_vector_int_dtor(vector_base_v4
*this)
2633 blocks
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
2634 this, concurrent_vector_int_destroy
);
2635 for(blocks
--; blocks
>= this->first_block
; blocks
--) {
2636 vector_alloc_count
--;
2637 free(this->segment
[blocks
]);
2640 if(this->first_block
) {
2641 vector_alloc_count
--;
2642 free(this->segment
[0]);
2645 call_func1(p_vector_base_v4_dtor
, this);
2648 static void __cdecl
concurrent_vector_int_copy(void *dst
, const void *src
, size_t n
)
2650 CHECK_EXPECT2(concurrent_vector_int_copy
);
2651 vector_elem_count
+= n
;
2652 memcpy(dst
, src
, n
*sizeof(int));
2655 static void __cdecl
concurrent_vector_int_assign(void *dst
, const void *src
, size_t n
)
2657 CHECK_EXPECT2(concurrent_vector_int_assign
);
2658 memcpy(dst
, src
, n
*sizeof(int));
2661 static void test_queue_base_v4(void)
2663 queue_base_v4 queue
;
2671 block_start
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2672 block_end
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2674 call_func2(p_queue_base_v4_ctor
, &queue
, 0);
2675 ok(queue
.data
!= NULL
, "queue.data = NULL\n");
2676 ok(queue
.alloc_count
== 32, "queue.alloc_count = %ld\n", (long)queue
.alloc_count
);
2677 ok(queue
.item_size
== 0, "queue.item_size = %ld\n", (long)queue
.item_size
);
2678 call_func1(p_queue_base_v4_dtor
, &queue
);
2680 call_func2(p_queue_base_v4_ctor
, &queue
, 8);
2681 ok(queue
.data
!= NULL
, "queue.data = NULL\n");
2682 ok(queue
.alloc_count
== 32, "queue.alloc_count = %ld\n", (long)queue
.alloc_count
);
2683 ok(queue
.item_size
== 8, "queue.item_size = %ld\n", (long)queue
.item_size
);
2684 call_func1(p_queue_base_v4_dtor
, &queue
);
2686 call_func2(p_queue_base_v4_ctor
, &queue
, 16);
2687 ok(queue
.data
!= NULL
, "queue.data = NULL\n");
2688 ok(queue
.alloc_count
== 16, "queue.alloc_count = %ld\n", (long)queue
.alloc_count
);
2689 ok(queue
.item_size
== 16, "queue.item_size = %ld\n", (long)queue
.item_size
);
2690 b
= (DWORD_PTR
)call_func1(p_queue_base_v4__Internal_empty
, &queue
);
2691 ok(b
, "queue is not empty\n");
2692 size
= (size_t)call_func1(p_queue_base_v4__Internal_size
, &queue
);
2693 ok(!size
, "size = %ld\n", (long)size
);
2694 call_func1(p_queue_base_v4_dtor
, &queue
);
2696 call_func2(p_queue_base_v4_ctor
, &queue
, 1);
2697 queue
.vtable
= (void*)&queue_char_vtbl
;
2699 for(i
=0; i
<8; i
++) {
2700 SET_EXPECT(queue_char__Allocate_page
);
2701 SET_EXPECT(queue_char__Copy_item
);
2703 call_func2(p_queue_base_v4__Internal_push
, &queue
, &c
);
2704 CHECK_CALLED(queue_char__Allocate_page
);
2705 CHECK_CALLED(queue_char__Copy_item
);
2707 b
= (MSVCP_bool
)(DWORD_PTR
)call_func1(p_queue_base_v4__Internal_empty
, &queue
);
2708 ok(!b
, "queue is empty\n");
2709 size
= (size_t)call_func1(p_queue_base_v4__Internal_size
, &queue
);
2710 ok(size
== i
+1, "size = %ld, expected %ld\n", (long)size
, (long)i
);
2713 SET_EXPECT(queue_char__Copy_item
);
2715 call_func2(p_queue_base_v4__Internal_push
, &queue
, &c
);
2716 CHECK_CALLED(queue_char__Copy_item
);
2718 for(i
=0; i
<9; i
++) {
2719 SET_EXPECT(queue_char__Assign_and_destroy_item
);
2720 b
= (DWORD_PTR
)call_func2(p_queue_base_v4__Internal_pop_if_present
, &queue
, &c
);
2721 CHECK_CALLED(queue_char__Assign_and_destroy_item
);
2722 ok(b
, "pop returned false\n");
2723 ok(c
== 'a'+i
, "got '%c', expected '%c'\n", c
, 'a'+i
);
2725 b
= (DWORD_PTR
)call_func2(p_queue_base_v4__Internal_pop_if_present
, &queue
, &c
);
2726 ok(!b
, "pop returned true\n");
2728 for(i
=0; i
<247; i
++) {
2729 SET_EXPECT(queue_char__Copy_item
);
2731 call_func2(p_queue_base_v4__Internal_push
, &queue
, &c
);
2732 CHECK_CALLED(queue_char__Copy_item
);
2734 size
= (size_t)call_func1(p_queue_base_v4__Internal_size
, &queue
);
2735 ok(size
== i
+1, "size = %ld, expected %ld\n", (long)size
, (long)i
);
2738 SET_EXPECT(queue_char__Allocate_page
);
2739 SET_EXPECT(queue_char__Copy_item
);
2741 call_func2(p_queue_base_v4__Internal_push
, &queue
, &c
);
2742 CHECK_CALLED(queue_char__Allocate_page
);
2743 CHECK_CALLED(queue_char__Copy_item
);
2745 for(i
=0; i
<239; i
++) {
2746 SET_EXPECT(queue_char__Assign_and_destroy_item
);
2747 b
= (DWORD_PTR
)call_func2(p_queue_base_v4__Internal_pop_if_present
, &queue
, &c
);
2748 CHECK_CALLED(queue_char__Assign_and_destroy_item
);
2749 ok(b
, "pop returned false\n");
2750 ok(c
== (char)('a'+i
), "got '%c', expected '%c'\n", c
, 'a'+i
);
2753 SET_EXPECT(queue_char__Assign_and_destroy_item
);
2754 SET_EXPECT(queue_char__Deallocate_page
);
2755 b
= (DWORD_PTR
)call_func2(p_queue_base_v4__Internal_pop_if_present
, &queue
, &c
);
2756 CHECK_CALLED(queue_char__Assign_and_destroy_item
);
2757 CHECK_CALLED(queue_char__Deallocate_page
);
2758 ok(b
, "pop returned false\n");
2759 ok(c
== (char)('a'+i
), "got '%c', expected '%c'\n", c
, 'a'+i
);
2761 /* destructor doesn't clear the memory, _Internal_finish_clear needs to be called */
2762 SET_EXPECT(queue_char__Deallocate_page
);
2763 call_func1(p_queue_base_v4__Internal_finish_clear
, &queue
);
2764 CHECK_CALLED(queue_char__Deallocate_page
);
2766 call_func1(p_queue_base_v4_dtor
, &queue
);
2768 /* test parallel push */
2769 call_func2(p_queue_base_v4_ctor
, &queue
, 1);
2770 queue
.vtable
= (void*)&queue_char_vtbl
;
2773 thread
[0] = CreateThread(NULL
, 0, queue_move_push_thread
, &queue
, 0, NULL
);
2774 WaitForSingleObject(block_start
, INFINITE
);
2777 for(i
=0; i
<7; i
++) {
2778 SET_EXPECT(queue_char__Allocate_page
);
2779 SET_EXPECT(queue_char__Copy_item
);
2780 call_func2(p_queue_base_v4__Internal_push
, &queue
, &c
);
2781 CHECK_CALLED(queue_char__Allocate_page
);
2782 CHECK_CALLED(queue_char__Copy_item
);
2785 thread
[1] = CreateThread(NULL
, 0, queue_push_thread
, &queue
, 0, NULL
);
2786 ret
= WaitForSingleObject(thread
[1], 100);
2787 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", ret
);
2789 SetEvent(block_end
);
2790 WaitForSingleObject(thread
[0], INFINITE
);
2791 WaitForSingleObject(thread
[1], INFINITE
);
2792 CloseHandle(thread
[0]);
2793 CloseHandle(thread
[1]);
2795 /* test parallel pop */
2797 thread
[0] = CreateThread(NULL
, 0, queue_pop_thread
, &queue
, 0, NULL
);
2798 WaitForSingleObject(block_start
, INFINITE
);
2800 for(i
=0; i
<7; i
++) {
2801 SET_EXPECT(queue_char__Assign_and_destroy_item
);
2802 b
= (DWORD_PTR
)call_func2(p_queue_base_v4__Internal_pop_if_present
, &queue
, &c
);
2803 CHECK_CALLED(queue_char__Assign_and_destroy_item
);
2804 ok(b
, "pop returned false\n");
2805 ok(c
== 'a', "got '%c', expected 'a'\n", c
);
2808 thread
[1] = CreateThread(NULL
, 0, queue_pop_thread
, &queue
, 0, NULL
);
2809 ret
= WaitForSingleObject(thread
[1], 100);
2810 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", ret
);
2812 SetEvent(block_end
);
2813 WaitForSingleObject(thread
[0], INFINITE
);
2814 WaitForSingleObject(thread
[1], INFINITE
);
2815 CloseHandle(thread
[0]);
2816 CloseHandle(thread
[1]);
2818 /* test parallel push/pop */
2819 for(i
=0; i
<8; i
++) {
2820 SET_EXPECT(queue_char__Copy_item
);
2821 call_func2(p_queue_base_v4__Internal_push
, &queue
, &c
);
2822 CHECK_CALLED(queue_char__Copy_item
);
2826 thread
[0] = CreateThread(NULL
, 0, queue_push_thread
, &queue
, 0, NULL
);
2827 WaitForSingleObject(block_start
, INFINITE
);
2829 SET_EXPECT(queue_char__Assign_and_destroy_item
);
2830 call_func2(p_queue_base_v4__Internal_pop_if_present
, &queue
, &c
);
2831 CHECK_CALLED(queue_char__Assign_and_destroy_item
);
2833 SetEvent(block_end
);
2834 WaitForSingleObject(thread
[0], INFINITE
);
2835 CloseHandle(thread
[0]);
2837 for(i
=0; i
<8; i
++) {
2838 SET_EXPECT(queue_char__Assign_and_destroy_item
);
2839 call_func2(p_queue_base_v4__Internal_pop_if_present
, &queue
, &c
);
2840 CHECK_CALLED(queue_char__Assign_and_destroy_item
);
2843 SET_EXPECT(queue_char__Deallocate_page
);
2844 call_func1(p_queue_base_v4__Internal_finish_clear
, &queue
);
2845 CHECK_CALLED(queue_char__Deallocate_page
);
2846 call_func1(p_queue_base_v4_dtor
, &queue
);
2848 CloseHandle(block_start
);
2849 CloseHandle(block_end
);
2852 static void test_vector_base_v4(void)
2854 vector_base_v4 vector
, v2
;
2859 concurrent_vector_int_ctor(&vector
);
2861 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &vector
);
2862 ok(size
== 0, "size of vector got %ld expected 0\n", (long)size
);
2864 SET_EXPECT(concurrent_vector_int_alloc
);
2865 data
= call_func3(p_vector_base_v4__Internal_push_back
, &vector
, sizeof(int), &idx
);
2867 skip("_Internal_push_back not yet implemented\n");
2870 CHECK_CALLED(concurrent_vector_int_alloc
);
2871 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2872 ok(idx
== 0, "idx got %ld expected %d\n", (long)idx
, 0);
2873 vector_elem_count
++;
2875 ok(data
== vector
.storage
[0], "vector.storage[0] got %p expected %p\n",
2876 vector
.storage
[0], data
);
2877 ok(vector
.first_block
== 1, "vector.first_block got %ld expected 1\n",
2878 (long)vector
.first_block
);
2879 ok(vector
.early_size
== 1, "vector.early_size got %ld expected 1\n",
2880 (long)vector
.early_size
);
2881 ok(vector
.segment
== vector
.storage
, "vector.segment got %p expected %p\n",
2882 vector
.segment
, vector
.storage
);
2883 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &vector
);
2884 ok(size
== 2, "size of vector got %ld expected 2\n", (long)size
);
2886 data
= call_func3(p_vector_base_v4__Internal_push_back
, &vector
, sizeof(int), &idx
);
2887 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2888 ok(idx
== 1, "idx got %ld expected 1\n", (long)idx
);
2889 vector_elem_count
++;
2891 ok(vector
.first_block
== 1, "vector.first_block got %ld expected 1\n",
2892 (long)vector
.first_block
);
2893 ok(vector
.early_size
== 2, "vector.early_size got %ld expected 2\n",
2894 (long)vector
.early_size
);
2896 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &vector
);
2897 ok(size
== 2, "size of vector got %ld expected 2\n", (long)size
);
2899 SET_EXPECT(concurrent_vector_int_alloc
);
2900 data
= call_func3(p_vector_base_v4__Internal_push_back
, &vector
, sizeof(int), &idx
);
2901 CHECK_CALLED(concurrent_vector_int_alloc
);
2902 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2903 ok(idx
== 2, "idx got %ld expected 2\n", (long)idx
);
2904 vector_elem_count
++;
2906 ok(vector
.segment
== vector
.storage
, "vector.segment got %p expected %p\n",
2907 vector
.segment
, vector
.storage
);
2908 ok(vector
.first_block
== 1, "vector.first_block got %ld expected 1\n",
2909 (long)vector
.first_block
);
2910 ok(vector
.early_size
== 3, "vector.early_size got %ld expected 3\n",
2911 (long)vector
.early_size
);
2912 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &vector
);
2913 ok(size
== 4, "size of vector got %ld expected %d\n", (long)size
, 4);
2915 data
= call_func3(p_vector_base_v4__Internal_push_back
, &vector
, sizeof(int), &idx
);
2916 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2917 ok(idx
== 3, "idx got %ld expected 3\n", (long)idx
);
2918 vector_elem_count
++;
2920 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &vector
);
2921 ok(size
== 4, "size of vector got %ld expected 4\n", (long)size
);
2923 SET_EXPECT(concurrent_vector_int_alloc
);
2924 data
= call_func3(p_vector_base_v4__Internal_push_back
, &vector
, sizeof(int), &idx
);
2925 CHECK_CALLED(concurrent_vector_int_alloc
);
2926 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2927 ok(idx
== 4, "idx got %ld expected 4\n", (long)idx
);
2928 vector_elem_count
++;
2930 ok(vector
.segment
== vector
.storage
, "vector.segment got %p expected %p\n",
2931 vector
.segment
, vector
.storage
);
2932 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &vector
);
2933 ok(size
== 8, "size of vector got %ld expected 8\n", (long)size
);
2935 concurrent_vector_int_ctor(&v2
);
2936 SET_EXPECT(concurrent_vector_int_alloc
);
2937 SET_EXPECT(concurrent_vector_int_copy
);
2938 call_func4(p_vector_base_v4__Internal_copy
, &v2
, &vector
,
2939 sizeof(int), concurrent_vector_int_copy
);
2940 CHECK_CALLED(concurrent_vector_int_alloc
);
2941 CHECK_CALLED(concurrent_vector_int_copy
);
2942 ok(v2
.first_block
== 3, "v2.first_block got %ld expected 3\n",
2943 (long)v2
.first_block
);
2944 ok(v2
.early_size
== 5, "v2.early_size got %ld expected 5\n",
2945 (long)v2
.early_size
);
2946 ok(v2
.segment
== v2
.storage
, "v2.segment got %p expected %p\n",
2947 v2
.segment
, v2
.storage
);
2948 SET_EXPECT(concurrent_vector_int_destroy
);
2949 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
2950 &v2
, concurrent_vector_int_destroy
);
2951 CHECK_CALLED(concurrent_vector_int_destroy
);
2952 ok(size
== 3, "_Internal_clear returned %ld expected 3\n", (long)size
);
2953 concurrent_vector_int_dtor(&v2
);
2955 concurrent_vector_int_ctor(&v2
);
2956 SET_EXPECT(concurrent_vector_int_alloc
);
2957 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
2958 CHECK_CALLED(concurrent_vector_int_alloc
);
2959 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2960 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
2961 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2962 SET_EXPECT(concurrent_vector_int_alloc
);
2963 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
2964 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2965 CHECK_CALLED(concurrent_vector_int_alloc
);
2966 vector_elem_count
+= 3;
2967 ok(idx
== 2, "idx got %ld expected 2\n", (long)idx
);
2968 SET_EXPECT(concurrent_vector_int_assign
);
2969 SET_EXPECT(concurrent_vector_int_copy
);
2970 SET_EXPECT(concurrent_vector_int_alloc
);
2971 call_func6(p_vector_base_v4__Internal_assign
, &v2
, &vector
, sizeof(int),
2972 concurrent_vector_int_destroy
, concurrent_vector_int_assign
,
2973 concurrent_vector_int_copy
);
2974 CHECK_CALLED(concurrent_vector_int_assign
);
2975 CHECK_CALLED(concurrent_vector_int_copy
);
2976 CHECK_CALLED(concurrent_vector_int_alloc
);
2977 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n",
2978 (long)v2
.first_block
);
2979 ok(v2
.early_size
== 5, "v2.early_size got %ld expected 5\n",
2980 (long)v2
.early_size
);
2981 ok(v2
.segment
== v2
.storage
, "v2.segment got %p expected %p\n",
2982 v2
.segment
, v2
.storage
);
2983 SET_EXPECT(concurrent_vector_int_destroy
);
2984 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
2985 &v2
, concurrent_vector_int_destroy
);
2986 CHECK_CALLED(concurrent_vector_int_destroy
);
2987 ok(size
== 3, "_Internal_clear returned %ld expected 3\n", (long)size
);
2988 concurrent_vector_int_dtor(&v2
);
2990 concurrent_vector_int_ctor(&v2
);
2991 SET_EXPECT(concurrent_vector_int_alloc
);
2992 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
2993 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2994 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
2995 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
2996 CHECK_CALLED(concurrent_vector_int_alloc
);
2997 SET_EXPECT(concurrent_vector_int_alloc
);
2998 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
2999 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3000 CHECK_CALLED(concurrent_vector_int_alloc
);
3001 vector_elem_count
+= 3;
3002 ok(idx
== 2, "idx got %ld expected 2\n", (long)idx
);
3003 call_func2(p_vector_base_v4__Internal_swap
,
3005 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n",
3006 (long)v2
.first_block
);
3007 ok(v2
.early_size
== 5, "v2.early_size got %ld expected 5\n",
3008 (long)v2
.early_size
);
3009 ok(vector
.early_size
== 3, "vector.early_size got %ld expected 3\n",
3010 (long)vector
.early_size
);
3011 call_func2(p_vector_base_v4__Internal_swap
,
3013 ok(v2
.early_size
== 3, "v2.early_size got %ld expected 3\n",
3014 (long)v2
.early_size
);
3015 ok(vector
.early_size
== 5, "vector.early_size got %ld expected 5\n",
3016 (long)vector
.early_size
);
3017 SET_EXPECT(concurrent_vector_int_destroy
);
3018 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
3019 &v2
, concurrent_vector_int_destroy
);
3020 CHECK_CALLED(concurrent_vector_int_destroy
);
3021 ok(size
== 2, "_Internal_clear returned %ld expected 2\n", (long)size
);
3022 concurrent_vector_int_dtor(&v2
);
3024 /* test for _Internal_compact */
3025 concurrent_vector_int_ctor(&v2
);
3026 for(i
=0; i
<2; i
++) {
3027 SET_EXPECT(concurrent_vector_int_alloc
);
3028 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3029 CHECK_CALLED(concurrent_vector_int_alloc
);
3030 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3031 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3032 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3033 vector_elem_count
+= 2;
3035 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3036 ok(v2
.early_size
== 4, "v2.early_size got %ld expected 4\n", (long)v2
.early_size
);
3037 ok(v2
.segment
== v2
.storage
, "v2.segment got %p expected %p\n",
3038 v2
.segment
, v2
.storage
);
3039 memset(&b
, 0xff, sizeof(b
));
3040 SET_EXPECT(concurrent_vector_int_alloc
);
3041 SET_EXPECT(concurrent_vector_int_copy
);
3042 SET_EXPECT(concurrent_vector_int_destroy
);
3043 data
= call_func5(p_vector_base_v4__Internal_compact
,
3044 &v2
, sizeof(int), &b
, concurrent_vector_int_destroy
,
3045 concurrent_vector_int_copy
);
3046 CHECK_CALLED(concurrent_vector_int_alloc
);
3047 CHECK_CALLED(concurrent_vector_int_copy
);
3048 CHECK_CALLED(concurrent_vector_int_destroy
);
3049 ok(v2
.first_block
== 2, "v2.first_block got %ld expected 2\n", (long)v2
.first_block
);
3050 ok(v2
.early_size
== 4,"v2.early_size got %ld expected 4\n", (long)v2
.early_size
);
3051 ok(b
.first_block
== 1, "b.first_block got %ld expected 1\n", (long)b
.first_block
);
3052 ok(v2
.segment
== v2
.storage
, "v2.segment got %p expected %p\n",
3053 v2
.segment
, v2
.storage
);
3055 ok(b
.blocks
[i
] != NULL
, "b.blocks[%d] got NULL\n", i
);
3057 vector_alloc_count
--;
3059 for(; i
<ARRAY_SIZE(b
.blocks
); i
++)
3060 ok(!b
.blocks
[i
], "b.blocks[%d] != NULL\n", i
);
3061 ok(b
.size_check
== -1, "b.size_check = %x\n", b
.size_check
);
3063 SET_EXPECT(concurrent_vector_int_alloc
);
3064 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3065 CHECK_CALLED(concurrent_vector_int_alloc
);
3066 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3068 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3069 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3071 SET_EXPECT(concurrent_vector_int_alloc
);
3072 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3073 CHECK_CALLED(concurrent_vector_int_alloc
);
3074 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3075 vector_elem_count
+= 5;
3076 ok(v2
.first_block
== 2, "v2.first_block got %ld expected 2\n", (long)v2
.first_block
);
3077 ok(v2
.early_size
== 9, "v2.early_size got %ld expected 9\n", (long)v2
.early_size
);
3078 ok(v2
.segment
!= v2
.storage
, "v2.segment got %p expected %p\n", v2
.segment
, v2
.storage
);
3079 for(i
= 4;i
< 32;i
++)
3080 ok(v2
.segment
[i
] == 0, "v2.segment[%d] got %p expected 0\n",
3082 memset(&b
, 0xff, sizeof(b
));
3083 SET_EXPECT(concurrent_vector_int_alloc
);
3084 SET_EXPECT(concurrent_vector_int_copy
);
3085 SET_EXPECT(concurrent_vector_int_destroy
);
3086 data
= call_func5(p_vector_base_v4__Internal_compact
,
3087 &v2
, sizeof(int), &b
, concurrent_vector_int_destroy
,
3088 concurrent_vector_int_copy
);
3089 CHECK_CALLED(concurrent_vector_int_alloc
);
3090 CHECK_CALLED(concurrent_vector_int_copy
);
3091 CHECK_CALLED(concurrent_vector_int_destroy
);
3092 ok(v2
.first_block
== 4, "v2.first_block got %ld expected 4\n", (long)v2
.first_block
);
3093 ok(v2
.early_size
== 9, "v2.early_size got %ld expected 9\n", (long)v2
.early_size
);
3094 ok(b
.first_block
== 2, "b.first_block got %ld expected 2\n", (long)b
.first_block
);
3095 ok(v2
.segment
!= v2
.storage
, "v2.segment got %p expected %p\n", v2
.segment
, v2
.storage
);
3096 for(i
= 4;i
< 32;i
++)
3097 ok(v2
.segment
[i
] == 0, "v2.segment[%d] got %p\n",
3100 ok(b
.blocks
[i
] != NULL
, "b.blocks[%d] got NULL\n", i
);
3101 /* only b.blocks[0] and b.blocks[>=b.first_block] are used */
3102 if(i
== b
.first_block
-1) continue;
3104 vector_alloc_count
--;
3106 for(; i
<ARRAY_SIZE(b
.blocks
); i
++)
3107 ok(!b
.blocks
[i
], "b.blocks[%d] != NULL\n", i
);
3108 SET_EXPECT(concurrent_vector_int_alloc
);
3109 call_func4(p_vector_base_v4__Internal_reserve
,
3110 &v2
, 17, sizeof(int), 32);
3111 CHECK_CALLED(concurrent_vector_int_alloc
);
3112 data
= call_func5(p_vector_base_v4__Internal_compact
,
3113 &v2
, sizeof(int), &b
, concurrent_vector_int_destroy
,
3114 concurrent_vector_int_copy
);
3115 ok(v2
.first_block
== 4, "v2.first_block got %ld expected 4\n", (long)v2
.first_block
);
3116 ok(v2
.early_size
== 9, "v2.early_size got %ld expected 9\n", (long)v2
.early_size
);
3117 ok(b
.first_block
== 4, "b.first_block got %ld expected 2\n", (long)b
.first_block
);
3118 ok(v2
.segment
!= v2
.storage
, "v2.segment got %p expected %p\n", v2
.segment
, v2
.storage
);
3119 for(i
= 4; i
< 32; i
++)
3120 ok(v2
.segment
[i
] == 0, "v2.segment[%d] got %p\n",
3123 ok(!b
.blocks
[i
], "b.blocks[%d] != NULL\n", i
);
3125 ok(b
.blocks
[i
] != NULL
, "b.blocks[%d] got NULL\n", i
);
3127 vector_alloc_count
--;
3129 for(; i
<ARRAY_SIZE(b
.blocks
); i
++)
3130 ok(!b
.blocks
[i
], "b.blocks[%d] != NULL\n", i
);
3131 SET_EXPECT(concurrent_vector_int_destroy
);
3132 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
3133 &v2
, concurrent_vector_int_destroy
);
3134 CHECK_CALLED(concurrent_vector_int_destroy
);
3135 ok(size
== 4, "_Internal_clear returned %ld expected 4\n", (long)size
);
3136 concurrent_vector_int_dtor(&v2
);
3138 /* test for Internal_grow_by */
3139 concurrent_vector_int_ctor(&v2
);
3140 SET_EXPECT(concurrent_vector_int_alloc
);
3141 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3142 CHECK_CALLED(concurrent_vector_int_alloc
);
3143 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3144 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3145 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3146 vector_elem_count
+= 2;
3147 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3148 ok(v2
.early_size
== 2, "v2.early_size got %ld expected 2\n", (long)v2
.early_size
);
3150 SET_EXPECT(concurrent_vector_int_alloc
);
3151 SET_EXPECT(concurrent_vector_int_copy
);
3152 idx
= (size_t)call_func5(p_vector_base_v4__Internal_grow_by
,
3153 &v2
, 1, sizeof(int), concurrent_vector_int_copy
, &i
);
3154 CHECK_CALLED(concurrent_vector_int_alloc
);
3155 CHECK_CALLED(concurrent_vector_int_copy
);
3156 ok(idx
== 2, "_Internal_grow_by returned %ld expected 2\n", (long)idx
);
3157 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3158 ok(v2
.early_size
== 3, "v2.early_size got %ld expected 3\n", (long)v2
.early_size
);
3159 SET_EXPECT(concurrent_vector_int_alloc
);
3160 SET_EXPECT(concurrent_vector_int_copy
);
3161 idx
= (size_t)call_func5(p_vector_base_v4__Internal_grow_by
,
3162 &v2
, 2, sizeof(int), concurrent_vector_int_copy
, &i
);
3163 CHECK_CALLED(concurrent_vector_int_alloc
);
3164 CHECK_CALLED(concurrent_vector_int_copy
);
3165 ok(idx
== 3, "_Internal_grow_by returned %ld expected 3\n", (long)idx
);
3166 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3167 ok(v2
.early_size
== 5, "v2.early_size got %ld expected 5\n", (long)v2
.early_size
);
3168 SET_EXPECT(concurrent_vector_int_destroy
);
3169 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
3170 &v2
, concurrent_vector_int_destroy
);
3171 ok(size
== 3, "_Internal_clear returned %ld expected 3\n", (long)size
);
3172 CHECK_CALLED(concurrent_vector_int_destroy
);
3173 concurrent_vector_int_dtor(&v2
);
3175 /* test for Internal_grow_to_at_least_with_result */
3176 concurrent_vector_int_ctor(&v2
);
3177 SET_EXPECT(concurrent_vector_int_alloc
);
3178 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3179 CHECK_CALLED(concurrent_vector_int_alloc
);
3180 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3181 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3182 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3183 vector_elem_count
+= 2;
3184 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3185 ok(v2
.early_size
== 2, "v2.early_size got %ld expected 2\n", (long)v2
.early_size
);
3187 SET_EXPECT(concurrent_vector_int_alloc
);
3188 SET_EXPECT(concurrent_vector_int_copy
);
3189 idx
= (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result
,
3190 &v2
, 3, sizeof(int), concurrent_vector_int_copy
, &i
);
3191 CHECK_CALLED(concurrent_vector_int_alloc
);
3192 CHECK_CALLED(concurrent_vector_int_copy
);
3193 ok(idx
== 2, "_Internal_grow_to_at_least_with_result returned %ld expected 2\n", (long)idx
);
3194 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3195 ok(v2
.early_size
== 3, "v2.early_size got %ld expected 3\n", (long)v2
.early_size
);
3197 SET_EXPECT(concurrent_vector_int_alloc
);
3198 SET_EXPECT(concurrent_vector_int_copy
);
3199 idx
= (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result
,
3200 &v2
, 5, sizeof(int), concurrent_vector_int_copy
, &i
);
3201 CHECK_CALLED(concurrent_vector_int_alloc
);
3202 CHECK_CALLED(concurrent_vector_int_copy
);
3203 ok(idx
== 3, "_Internal_grow_to_at_least_with_result returned %ld expected 3\n", (long)idx
);
3204 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3205 ok(v2
.early_size
== 5, "v2.early_size got %ld expected 5\n", (long)v2
.early_size
);
3206 SET_EXPECT(concurrent_vector_int_destroy
);
3207 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
3208 &v2
, concurrent_vector_int_destroy
);
3209 ok(size
== 3, "_Internal_clear returned %ld expected 3\n", (long)size
);
3210 CHECK_CALLED(concurrent_vector_int_destroy
);
3211 concurrent_vector_int_dtor(&v2
);
3213 /* test for _Internal_reserve */
3214 concurrent_vector_int_ctor(&v2
);
3215 SET_EXPECT(concurrent_vector_int_alloc
);
3216 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3217 CHECK_CALLED(concurrent_vector_int_alloc
);
3218 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3219 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3220 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3221 vector_elem_count
+= 2;
3222 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3223 ok(v2
.early_size
== 2, "v2.early_size got %ld expected 2\n", (long)v2
.early_size
);
3224 SET_EXPECT(concurrent_vector_int_alloc
);
3225 call_func4(p_vector_base_v4__Internal_reserve
,
3226 &v2
, 3, sizeof(int), 4);
3227 CHECK_CALLED(concurrent_vector_int_alloc
);
3228 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3229 ok(v2
.early_size
== 2, "v2.early_size got %ld expected 2\n", (long)v2
.early_size
);
3230 ok(v2
.segment
== v2
.storage
, "v2.segment got %p expected %p\n",
3231 v2
.segment
, v2
.storage
);
3232 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &v2
);
3233 ok(size
== 4, "size of vector got %ld expected 4\n", (long)size
);
3234 SET_EXPECT(concurrent_vector_int_alloc
);
3235 call_func4(p_vector_base_v4__Internal_reserve
,
3236 &v2
, 5, sizeof(int), 8);
3237 CHECK_CALLED(concurrent_vector_int_alloc
);
3238 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3239 ok(v2
.early_size
== 2, "v2.early_size got %ld expected 2\n", (long)v2
.early_size
);
3240 ok(v2
.segment
== v2
.storage
, "v2.segment got %p expected %p\n",
3241 v2
.segment
, v2
.storage
);
3242 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &v2
);
3243 ok(size
== 8, "size of vector got %ld expected 8\n", (long)size
);
3244 SET_EXPECT(concurrent_vector_int_alloc
);
3245 call_func4(p_vector_base_v4__Internal_reserve
,
3246 &v2
, 9, sizeof(int), 16);
3247 CHECK_CALLED(concurrent_vector_int_alloc
);
3248 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3249 ok(v2
.early_size
== 2, "v2.early_size got %ld expected 2\n", (long)v2
.early_size
);
3250 ok(v2
.segment
!= v2
.storage
, "v2.segment got %p expected %p\n", v2
.segment
, v2
.storage
);
3251 for(i
= 4;i
< 32;i
++)
3252 ok(v2
.segment
[i
] == 0, "v2.segment[%d] got %p\n",
3254 size
= (size_t)call_func1(p_vector_base_v4__Internal_capacity
, &v2
);
3255 ok(size
== 16, "size of vector got %ld expected 8\n", (long)size
);
3257 SET_EXPECT(concurrent_vector_int_destroy
);
3258 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
3259 &v2
, concurrent_vector_int_destroy
);
3260 ok(size
== 4, "_Internal_clear returned %ld expected 4\n", (long)size
);
3261 CHECK_CALLED(concurrent_vector_int_destroy
);
3262 concurrent_vector_int_dtor(&v2
);
3264 /* test for _Internal_resize */
3265 concurrent_vector_int_ctor(&v2
);
3266 SET_EXPECT(concurrent_vector_int_alloc
);
3267 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3268 CHECK_CALLED(concurrent_vector_int_alloc
);
3269 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3270 data
= call_func3(p_vector_base_v4__Internal_push_back
, &v2
, sizeof(int), &idx
);
3271 ok(data
!= NULL
, "_Internal_push_back returned NULL\n");
3272 vector_elem_count
+= 2;
3273 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3274 ok(v2
.early_size
== 2, "v2.early_size got %ld expected 2\n", (long)v2
.early_size
);
3276 SET_EXPECT(concurrent_vector_int_destroy
);
3277 call_func7(p_vector_base_v4__Internal_resize
,
3278 &v2
, 1, sizeof(int), 4, concurrent_vector_int_destroy
, concurrent_vector_int_copy
, &i
);
3279 CHECK_CALLED(concurrent_vector_int_destroy
);
3280 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3281 ok(v2
.early_size
== 1, "v2.early_size got %ld expected 1\n", (long)v2
.early_size
);
3282 SET_EXPECT(concurrent_vector_int_alloc
);
3283 SET_EXPECT(concurrent_vector_int_copy
);
3284 call_func7(p_vector_base_v4__Internal_resize
,
3285 &v2
, 3, sizeof(int), 4, concurrent_vector_int_destroy
, concurrent_vector_int_copy
, &i
);
3286 CHECK_CALLED(concurrent_vector_int_alloc
);
3287 CHECK_CALLED(concurrent_vector_int_copy
);
3288 ok(v2
.first_block
== 1, "v2.first_block got %ld expected 1\n", (long)v2
.first_block
);
3289 ok(v2
.early_size
== 3, "v2.early_size got %ld expected 3\n", (long)v2
.early_size
);
3290 SET_EXPECT(concurrent_vector_int_destroy
);
3291 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
3292 &v2
, concurrent_vector_int_destroy
);
3293 ok(size
== 2, "_Internal_clear returned %ld expected 2\n", (long)size
);
3294 CHECK_CALLED(concurrent_vector_int_destroy
);
3295 concurrent_vector_int_dtor(&v2
);
3297 SET_EXPECT(concurrent_vector_int_destroy
);
3298 size
= (size_t)call_func2(p_vector_base_v4__Internal_clear
,
3299 &vector
, concurrent_vector_int_destroy
);
3300 CHECK_CALLED(concurrent_vector_int_destroy
);
3301 ok(size
== 3, "_Internal_clear returned %ld\n", (long)size
);
3302 ok(vector
.first_block
== 1, "vector.first_block got %ld expected 1\n",
3303 (long)vector
.first_block
);
3304 ok(vector
.early_size
== 0, "vector.early_size got %ld expected 0\n",
3305 (long)vector
.early_size
);
3306 concurrent_vector_int_dtor(&vector
);
3308 ok(!vector_elem_count
, "vector_elem_count = %d, expected 0\n", vector_elem_count
);
3309 ok(!vector_alloc_count
, "vector_alloc_count = %d, expected 0\n", vector_alloc_count
);
3312 static BYTE
byte_reverse(BYTE b
)
3314 b
= ((b
& 0xf0) >> 4) | ((b
& 0x0f) << 4);
3315 b
= ((b
& 0xcc) >> 2) | ((b
& 0x33) << 2);
3316 b
= ((b
& 0xaa) >> 1) | ((b
& 0x55) << 1);
3320 static void test_data_exports(void)
3324 ok(IsBadWritePtr((BYTE
*)p_byte_reverse_table
, 256), "byte_reverse_table is writeable.\n");
3325 for (i
= 0; i
< 256; ++i
)
3327 ok(p_byte_reverse_table
[i
] == byte_reverse(i
), "Got unexpected byte %#x, expected %#x.\n",
3328 p_byte_reverse_table
[i
], byte_reverse(i
));
3332 START_TEST(msvcp120
)
3335 expect_idx
= TlsAlloc();
3336 ok(expect_idx
!= TLS_OUT_OF_INDEXES
, "TlsAlloc failed\n");
3337 alloc_expect_struct();
3339 test__Xtime_diff_to_millis2();
3347 test__Syserror_map();
3349 test_tr2_sys__File_size();
3350 test_tr2_sys__Equivalent();
3351 test_tr2_sys__Current_get();
3352 test_tr2_sys__Current_set();
3353 test_tr2_sys__Make_dir();
3354 test_tr2_sys__Remove_dir();
3355 test_tr2_sys__Copy_file();
3356 test_tr2_sys__Rename();
3357 test_tr2_sys__Statvfs();
3358 test_tr2_sys__Stat();
3359 test_tr2_sys__Last_write_time();
3360 test_tr2_sys__dir_operation();
3361 test_tr2_sys__Link();
3362 test_tr2_sys__Symlink();
3363 test_tr2_sys__Unlink();
3369 test_threads__Mtx();
3371 test_vector_base_v4__Segment_index_of();
3372 test_queue_base_v4();
3373 test_vector_base_v4();
3375 test_vbtable_size_exports();
3377 test_data_exports();
3379 free_expect_struct();
3380 TlsFree(expect_idx
);