winmm: Add a WARNing when winejoystick.drv is missing.
[wine.git] / dlls / msvcp120 / tests / msvcp120.c
blobac38aa61a0c5651eba116673153dc18a14ccdfce
1 /*
2 * Copyright 2014 Yifu Wang for ESRI
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <locale.h>
20 #include <stdio.h>
21 #include <math.h>
22 #include <limits.h>
24 #include "wine/test.h"
25 #include "winbase.h"
27 DWORD expect_idx;
28 static int vector_alloc_count;
29 static int vector_elem_count;
30 typedef struct blocks_to_free{
31 size_t first_block;
32 void *blocks[sizeof(void*)*8];
33 int size_check;
34 }compact_block;
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) \
52 do { \
53 struct expect_struct *p = TlsGetValue(expect_idx); \
54 ok(p != NULL, "expect_struct not initialized\n"); \
55 p->expect_ ## func = TRUE; \
56 }while(0)
58 #define CHECK_EXPECT2(func) \
59 do { \
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; \
64 }while(0)
66 #define CHECK_EXPECT(func) \
67 do { \
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; \
72 }while(0)
74 #define CHECK_CALLED(func) \
75 do { \
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; \
80 }while(0)
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");
93 free(p);
96 #undef __thiscall
97 #ifdef __i386__
98 #define __thiscall __stdcall
99 #else
100 #define __thiscall __cdecl
101 #endif
103 /* Emulate a __thiscall */
104 #ifdef __i386__
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 */
115 #include "poppack.h"
117 static void * (WINAPI *call_thiscall_func1)( void *func, void *this );
118 static void * (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a );
119 static void * (WINAPI *call_thiscall_func3)( void *func, void *this, const void *a,
120 const void *b );
121 static void * (WINAPI *call_thiscall_func4)( void *func, void *this, const void *a,
122 const void *b, const void *c );
123 static void * (WINAPI *call_thiscall_func5)( void *func, void *this, const void *a,
124 const void *b, const void *c, const void *d );
125 static void * (WINAPI *call_thiscall_func6)( void *func, void *this, const void *a,
126 const void *b, const void *c, const void *d, const void *e );
127 static void * (WINAPI *call_thiscall_func7)( void *func, void *this, const void *a,
128 const void *b, const void *c, const void *d, const void *e, const void *f );
130 static void init_thiscall_thunk(void)
132 struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
133 MEM_COMMIT, PAGE_EXECUTE_READWRITE );
134 thunk->pop_eax = 0x58; /* popl %eax */
135 thunk->pop_edx = 0x5a; /* popl %edx */
136 thunk->pop_ecx = 0x59; /* popl %ecx */
137 thunk->push_eax = 0x50; /* pushl %eax */
138 thunk->jmp_edx = 0xe2ff; /* jmp *%edx */
139 call_thiscall_func1 = (void *)thunk;
140 call_thiscall_func2 = (void *)thunk;
141 call_thiscall_func3 = (void *)thunk;
142 call_thiscall_func4 = (void *)thunk;
143 call_thiscall_func5 = (void *)thunk;
144 call_thiscall_func6 = (void *)thunk;
145 call_thiscall_func7 = (void *)thunk;
148 #define call_func1(func,_this) call_thiscall_func1(func,_this)
149 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a))
150 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)(a),\
151 (const void*)(b))
152 #define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)(a),\
153 (const void*)(b),(const void*)(c))
154 #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),\
155 (const void*)(b),(const void*)(c),(const void*)(d))
156 #define call_func6(func,_this,a,b,c,d,e) call_thiscall_func6(func,_this,(const void*)(a),\
157 (const void*)(b),(const void*)(c),(const void*)(d),(const void*)(e))
158 #define call_func7(func,_this,a,b,c,d,e,f) call_thiscall_func7(func,_this,(const void*)(a),\
159 (const void*)(b),(const void*)(c),(const void*)(d),(const void*)(e),(const void*)(f))
160 #else
162 #define init_thiscall_thunk()
163 #define call_func1(func,_this) func(_this)
164 #define call_func2(func,_this,a) func(_this,a)
165 #define call_func3(func,_this,a,b) func(_this,a,b)
166 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
167 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
168 #define call_func6(func,_this,a,b,c,d,e) func(_this,a,b,c,d,e)
169 #define call_func7(func,_this,a,b,c,d,e,f) func(_this,a,b,c,d,e,f)
170 #endif /* __i386__ */
172 static inline float __port_infinity(void)
174 static const unsigned __inf_bytes = 0x7f800000;
175 return *(const float *)&__inf_bytes;
177 #define INFINITY __port_infinity()
179 static inline float __port_nan(void)
181 static const unsigned __nan_bytes = 0x7fc00000;
182 return *(const float *)&__nan_bytes;
184 #define NAN __port_nan()
186 typedef int MSVCRT_long;
187 typedef unsigned char MSVCP_bool;
189 /* xtime */
190 typedef struct {
191 __time64_t sec;
192 MSVCRT_long nsec;
193 } xtime;
195 typedef struct {
196 unsigned page;
197 int mb_max;
198 int unk;
199 BYTE isleadbyte[32];
200 } _Cvtvec;
202 struct space_info {
203 ULONGLONG capacity;
204 ULONGLONG free;
205 ULONGLONG available;
208 enum file_type {
209 status_unknown, file_not_found, regular_file, directory_file,
210 symlink_file, block_file, character_file, fifo_file, socket_file,
211 type_unknown
214 static BOOL compare_float(float f, float g, unsigned int ulps)
216 int x = *(int *)&f;
217 int y = *(int *)&g;
219 if (x < 0)
220 x = INT_MIN - x;
221 if (y < 0)
222 y = INT_MIN - y;
224 if (abs(x - y) > ulps)
225 return FALSE;
227 return TRUE;
230 static char* (__cdecl *p_setlocale)(int, const char*);
231 static int (__cdecl *p__setmbcp)(int);
232 static int (__cdecl *p__ismbblead)(unsigned int);
234 static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
235 static int (__cdecl *p_xtime_get)(xtime*, int);
236 static _Cvtvec* (__cdecl *p__Getcvt)(_Cvtvec*);
237 static void (CDECL *p__Call_once)(int *once, void (CDECL *func)(void));
238 static void (CDECL *p__Call_onceEx)(int *once, void (CDECL *func)(void*), void *argv);
239 static void (CDECL *p__Do_call)(void *this);
240 static short (__cdecl *p__Dtest)(double *d);
241 static short (__cdecl *p__Dscale)(double *d, int exp);
242 static short (__cdecl *p__FExp)(float *x, float y, int exp);
244 /* filesystem */
245 static ULONGLONG(__cdecl *p_tr2_sys__File_size)(char const*);
246 static ULONGLONG(__cdecl *p_tr2_sys__File_size_wchar)(WCHAR const*);
247 static int (__cdecl *p_tr2_sys__Equivalent)(char const*, char const*);
248 static int (__cdecl *p_tr2_sys__Equivalent_wchar)(WCHAR const*, WCHAR const*);
249 static char* (__cdecl *p_tr2_sys__Current_get)(char *);
250 static WCHAR* (__cdecl *p_tr2_sys__Current_get_wchar)(WCHAR *);
251 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set)(char const*);
252 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set_wchar)(WCHAR const*);
253 static int (__cdecl *p_tr2_sys__Make_dir)(char const*);
254 static int (__cdecl *p_tr2_sys__Make_dir_wchar)(WCHAR const*);
255 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir)(char const*);
256 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir_wchar)(WCHAR const*);
257 static int (__cdecl *p_tr2_sys__Copy_file)(char const*, char const*, MSVCP_bool);
258 static int (__cdecl *p_tr2_sys__Copy_file_wchar)(WCHAR const*, WCHAR const*, MSVCP_bool);
259 static int (__cdecl *p_tr2_sys__Rename)(char const*, char const*);
260 static int (__cdecl *p_tr2_sys__Rename_wchar)(WCHAR const*, WCHAR const*);
261 static struct space_info* (__cdecl *p_tr2_sys__Statvfs)(struct space_info*, char const*);
262 static struct space_info* (__cdecl *p_tr2_sys__Statvfs_wchar)(struct space_info*, WCHAR const*);
263 static enum file_type (__cdecl *p_tr2_sys__Stat)(char const*, int *);
264 static enum file_type (__cdecl *p_tr2_sys__Stat_wchar)(WCHAR const*, int *);
265 static enum file_type (__cdecl *p_tr2_sys__Lstat)(char const*, int *);
266 static enum file_type (__cdecl *p_tr2_sys__Lstat_wchar)(WCHAR const*, int *);
267 static __int64 (__cdecl *p_tr2_sys__Last_write_time)(char const*);
268 static __int64 (__cdecl *p_tr2_sys__Last_write_time_wchar)(WCHAR const*);
269 static void (__cdecl *p_tr2_sys__Last_write_time_set)(char const*, __int64);
270 static void* (__cdecl *p_tr2_sys__Open_dir)(char*, char const*, int *, enum file_type*);
271 static char* (__cdecl *p_tr2_sys__Read_dir)(char*, void*, enum file_type*);
272 static void (__cdecl *p_tr2_sys__Close_dir)(void*);
273 static int (__cdecl *p_tr2_sys__Link)(char const*, char const*);
274 static int (__cdecl *p_tr2_sys__Symlink)(char const*, char const*);
275 static int (__cdecl *p_tr2_sys__Unlink)(char const*);
277 /* thrd */
278 typedef struct
280 HANDLE hnd;
281 DWORD id;
282 } _Thrd_t;
284 #define TIMEDELTA 250 /* 250 ms uncertainty allowed */
286 typedef int (__cdecl *_Thrd_start_t)(void*);
288 static int (__cdecl *p__Thrd_equal)(_Thrd_t, _Thrd_t);
289 static int (__cdecl *p__Thrd_lt)(_Thrd_t, _Thrd_t);
290 static void (__cdecl *p__Thrd_sleep)(const xtime*);
291 static _Thrd_t (__cdecl *p__Thrd_current)(void);
292 static int (__cdecl *p__Thrd_create)(_Thrd_t*, _Thrd_start_t, void*);
293 static int (__cdecl *p__Thrd_join)(_Thrd_t, int*);
294 static int (__cdecl *p__Thrd_detach)(_Thrd_t);
296 #ifdef __i386__
297 static ULONGLONG (__cdecl *p_i386_Thrd_current)(void);
298 static _Thrd_t __cdecl i386_Thrd_current(void)
300 union {
301 _Thrd_t thr;
302 ULONGLONG ull;
303 } r;
304 r.ull = p_i386_Thrd_current();
305 return r.thr;
307 #endif
309 /* mtx */
310 typedef struct cs_queue
312 struct cs_queue *next;
313 BOOL free;
314 int unknown;
315 } cs_queue;
317 typedef struct
319 ULONG_PTR unk_thread_id;
320 cs_queue unk_active;
321 void *unknown[2];
322 cs_queue *head;
323 void *tail;
324 } critical_section;
326 typedef struct
328 DWORD flags;
329 critical_section cs;
330 DWORD thread_id;
331 DWORD count;
332 } *_Mtx_t;
334 static int (__cdecl *p__Mtx_init)(_Mtx_t*, int);
335 static void (__cdecl *p__Mtx_destroy)(_Mtx_t*);
336 static int (__cdecl *p__Mtx_lock)(_Mtx_t*);
337 static int (__cdecl *p__Mtx_unlock)(_Mtx_t*);
339 /* cnd */
340 typedef void *_Cnd_t;
342 static int (__cdecl *p__Cnd_init)(_Cnd_t*);
343 static void (__cdecl *p__Cnd_destroy)(_Cnd_t*);
344 static int (__cdecl *p__Cnd_wait)(_Cnd_t*, _Mtx_t*);
345 static int (__cdecl *p__Cnd_timedwait)(_Cnd_t*, _Mtx_t*, const xtime*);
346 static int (__cdecl *p__Cnd_broadcast)(_Cnd_t*);
347 static int (__cdecl *p__Cnd_signal)(_Cnd_t*);
348 static void (__cdecl *p__Cnd_register_at_thread_exit)(_Cnd_t*, _Mtx_t*, int*);
349 static void (__cdecl *p__Cnd_unregister_at_thread_exit)(_Mtx_t*);
350 static void (__cdecl *p__Cnd_do_broadcast_at_thread_exit)(void);
352 /* _Pad */
353 typedef void (*vtable_ptr)(void);
355 typedef struct
357 const vtable_ptr *vtable;
358 _Cnd_t cnd;
359 _Mtx_t mtx;
360 MSVCP_bool launched;
361 } _Pad;
363 static _Pad* (__thiscall *p__Pad_ctor)(_Pad*);
364 static _Pad* (__thiscall *p__Pad_copy_ctor)(_Pad*, const _Pad*);
365 static void (__thiscall *p__Pad_dtor)(_Pad*);
366 static _Pad* (__thiscall *p__Pad_op_assign)(_Pad*, const _Pad*);
367 static void (__thiscall *p__Pad__Launch)(_Pad*, _Thrd_t*);
368 static void (__thiscall *p__Pad__Release)(_Pad*);
370 static void (__cdecl *p_threads__Mtx_new)(void **mtx);
371 static void (__cdecl *p_threads__Mtx_delete)(void *mtx);
372 static void (__cdecl *p_threads__Mtx_lock)(void *mtx);
373 static void (__cdecl *p_threads__Mtx_unlock)(void *mtx);
375 static BOOLEAN (WINAPI *pCreateSymbolicLinkA)(LPCSTR,LPCSTR,DWORD);
377 static size_t (__cdecl *p_vector_base_v4__Segment_index_of)(size_t);
379 typedef struct
381 const vtable_ptr *vtable;
382 void *data;
383 size_t alloc_count;
384 size_t item_size;
385 } queue_base_v4;
387 typedef struct
389 struct _Page *_Next;
390 size_t _Mask;
391 char data[1];
392 } _Page;
394 static queue_base_v4* (__thiscall *p_queue_base_v4_ctor)(queue_base_v4*, size_t);
395 static void (__thiscall *p_queue_base_v4_dtor)(queue_base_v4*);
396 static MSVCP_bool (__thiscall *p_queue_base_v4__Internal_empty)(queue_base_v4*);
397 static size_t (__thiscall *p_queue_base_v4__Internal_size)(queue_base_v4*);
398 static void (__thiscall *p_queue_base_v4__Internal_push)(queue_base_v4*, const void*);
399 static void (__thiscall *p_queue_base_v4__Internal_move_push)(queue_base_v4*, void*);
400 static MSVCP_bool (__thiscall *p_queue_base_v4__Internal_pop_if_present)(queue_base_v4*, void*);
401 static void (__thiscall *p_queue_base_v4__Internal_finish_clear)(queue_base_v4*);
403 typedef struct vector_base_v4
405 void* (__cdecl *allocator)(struct vector_base_v4*, size_t);
406 void *storage[3];
407 size_t first_block;
408 size_t early_size;
409 void **segment;
410 } vector_base_v4;
412 static void (__thiscall *p_vector_base_v4_dtor)(vector_base_v4*);
413 static size_t (__thiscall *p_vector_base_v4__Internal_capacity)(vector_base_v4*);
414 static void* (__thiscall *p_vector_base_v4__Internal_push_back)(
415 vector_base_v4*, size_t, size_t*);
416 static size_t (__thiscall *p_vector_base_v4__Internal_clear)(
417 vector_base_v4*, void (__cdecl*)(void*, size_t));
418 static void (__thiscall *p_vector_base_v4__Internal_copy)(
419 vector_base_v4*, vector_base_v4*, size_t, void (__cdecl*)(void*, const void*, size_t));
420 static void (__thiscall *p_vector_base_v4__Internal_assign)(
421 vector_base_v4*, vector_base_v4*, size_t, void (__cdecl*)(void*, size_t),
422 void (__cdecl*)(void*, const void*, size_t), void (__cdecl*)(void*, const void*, size_t));
423 static void (__thiscall *p_vector_base_v4__Internal_swap)(
424 vector_base_v4*, const vector_base_v4*);
425 static void* (__thiscall *p_vector_base_v4__Internal_compact)(
426 vector_base_v4*, size_t, void*, void (__cdecl*)(void*, size_t),
427 void (__cdecl*)(void*, const void*, size_t));
428 static size_t (__thiscall *p_vector_base_v4__Internal_grow_by)(
429 vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
430 static size_t (__thiscall *p_vector_base_v4__Internal_grow_to_at_least_with_result)(
431 vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
432 static void (__thiscall *p_vector_base_v4__Internal_reserve)(
433 vector_base_v4*, size_t, size_t, size_t);
434 static void (__thiscall *p_vector_base_v4__Internal_resize)(
435 vector_base_v4*, size_t, size_t, size_t, void (__cdecl*)(void*, size_t),
436 void (__cdecl *copy)(void*, const void*, size_t), const void*);
438 static HMODULE msvcp;
439 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
440 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
441 static BOOL init(void)
443 HANDLE hdll;
445 msvcp = LoadLibraryA("msvcp120.dll");
446 if(!msvcp)
448 win_skip("msvcp120.dll not installed\n");
449 return FALSE;
452 SET(p__Xtime_diff_to_millis2,
453 "_Xtime_diff_to_millis2");
454 SET(p_xtime_get,
455 "xtime_get");
456 SET(p__Getcvt,
457 "_Getcvt");
458 SET(p__Call_once,
459 "_Call_once");
460 SET(p__Call_onceEx,
461 "_Call_onceEx");
462 SET(p__Do_call,
463 "_Do_call");
464 SET(p__Dtest,
465 "_Dtest");
466 SET(p__Dscale,
467 "_Dscale");
468 SET(p__FExp,
469 "_FExp");
470 if(sizeof(void*) == 8) { /* 64-bit initialization */
471 SET(p_tr2_sys__File_size,
472 "?_File_size@sys@tr2@std@@YA_KPEBD@Z");
473 SET(p_tr2_sys__File_size_wchar,
474 "?_File_size@sys@tr2@std@@YA_KPEB_W@Z");
475 SET(p_tr2_sys__Equivalent,
476 "?_Equivalent@sys@tr2@std@@YAHPEBD0@Z");
477 SET(p_tr2_sys__Equivalent_wchar,
478 "?_Equivalent@sys@tr2@std@@YAHPEB_W0@Z");
479 SET(p_tr2_sys__Current_get,
480 "?_Current_get@sys@tr2@std@@YAPEADAEAY0BAE@D@Z");
481 SET(p_tr2_sys__Current_get_wchar,
482 "?_Current_get@sys@tr2@std@@YAPEA_WAEAY0BAE@_W@Z");
483 SET(p_tr2_sys__Current_set,
484 "?_Current_set@sys@tr2@std@@YA_NPEBD@Z");
485 SET(p_tr2_sys__Current_set_wchar,
486 "?_Current_set@sys@tr2@std@@YA_NPEB_W@Z");
487 SET(p_tr2_sys__Make_dir,
488 "?_Make_dir@sys@tr2@std@@YAHPEBD@Z");
489 SET(p_tr2_sys__Make_dir_wchar,
490 "?_Make_dir@sys@tr2@std@@YAHPEB_W@Z");
491 SET(p_tr2_sys__Remove_dir,
492 "?_Remove_dir@sys@tr2@std@@YA_NPEBD@Z");
493 SET(p_tr2_sys__Remove_dir_wchar,
494 "?_Remove_dir@sys@tr2@std@@YA_NPEB_W@Z");
495 SET(p_tr2_sys__Copy_file,
496 "?_Copy_file@sys@tr2@std@@YAHPEBD0_N@Z");
497 SET(p_tr2_sys__Copy_file_wchar,
498 "?_Copy_file@sys@tr2@std@@YAHPEB_W0_N@Z");
499 SET(p_tr2_sys__Rename,
500 "?_Rename@sys@tr2@std@@YAHPEBD0@Z");
501 SET(p_tr2_sys__Rename_wchar,
502 "?_Rename@sys@tr2@std@@YAHPEB_W0@Z");
503 SET(p_tr2_sys__Statvfs,
504 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEBD@Z");
505 SET(p_tr2_sys__Statvfs_wchar,
506 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEB_W@Z");
507 SET(p_tr2_sys__Stat,
508 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
509 SET(p_tr2_sys__Stat_wchar,
510 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
511 SET(p_tr2_sys__Lstat,
512 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
513 SET(p_tr2_sys__Lstat_wchar,
514 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
515 SET(p_tr2_sys__Last_write_time,
516 "?_Last_write_time@sys@tr2@std@@YA_JPEBD@Z");
517 SET(p_tr2_sys__Last_write_time_wchar,
518 "?_Last_write_time@sys@tr2@std@@YA_JPEB_W@Z");
519 SET(p_tr2_sys__Last_write_time_set,
520 "?_Last_write_time@sys@tr2@std@@YAXPEBD_J@Z");
521 SET(p_tr2_sys__Open_dir,
522 "?_Open_dir@sys@tr2@std@@YAPEAXAEAY0BAE@DPEBDAEAHAEAW4file_type@123@@Z");
523 SET(p_tr2_sys__Read_dir,
524 "?_Read_dir@sys@tr2@std@@YAPEADAEAY0BAE@DPEAXAEAW4file_type@123@@Z");
525 SET(p_tr2_sys__Close_dir,
526 "?_Close_dir@sys@tr2@std@@YAXPEAX@Z");
527 SET(p_tr2_sys__Link,
528 "?_Link@sys@tr2@std@@YAHPEBD0@Z");
529 SET(p_tr2_sys__Symlink,
530 "?_Symlink@sys@tr2@std@@YAHPEBD0@Z");
531 SET(p_tr2_sys__Unlink,
532 "?_Unlink@sys@tr2@std@@YAHPEBD@Z");
533 SET(p__Thrd_current,
534 "_Thrd_current");
535 SET(p__Pad_ctor,
536 "??0_Pad@std@@QEAA@XZ");
537 SET(p__Pad_copy_ctor,
538 "??0_Pad@std@@QEAA@AEBV01@@Z");
539 SET(p__Pad_dtor,
540 "??1_Pad@std@@QEAA@XZ");
541 SET(p__Pad_op_assign,
542 "??4_Pad@std@@QEAAAEAV01@AEBV01@@Z");
543 SET(p__Pad__Launch,
544 "?_Launch@_Pad@std@@QEAAXPEAU_Thrd_imp_t@@@Z");
545 SET(p__Pad__Release,
546 "?_Release@_Pad@std@@QEAAXXZ");
547 SET(p_threads__Mtx_new,
548 "?_Mtx_new@threads@stdext@@YAXAEAPEAX@Z");
549 SET(p_threads__Mtx_delete,
550 "?_Mtx_delete@threads@stdext@@YAXPEAX@Z");
551 SET(p_threads__Mtx_lock,
552 "?_Mtx_lock@threads@stdext@@YAXPEAX@Z");
553 SET(p_threads__Mtx_unlock,
554 "?_Mtx_unlock@threads@stdext@@YAXPEAX@Z");
555 SET(p_vector_base_v4__Segment_index_of,
556 "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KA_K_K@Z");
557 SET(p_queue_base_v4_ctor,
558 "??0_Concurrent_queue_base_v4@details@Concurrency@@IEAA@_K@Z");
559 SET(p_queue_base_v4_dtor,
560 "??1_Concurrent_queue_base_v4@details@Concurrency@@MEAA@XZ");
561 SET(p_queue_base_v4__Internal_empty,
562 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_NXZ");
563 SET(p_queue_base_v4__Internal_size,
564 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_KXZ");
565 SET(p_queue_base_v4__Internal_push,
566 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEBX@Z");
567 SET(p_queue_base_v4__Internal_move_push,
568 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEAX@Z");
569 SET(p_queue_base_v4__Internal_pop_if_present,
570 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IEAA_NPEAX@Z");
571 SET(p_queue_base_v4__Internal_finish_clear,
572 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXXZ");
573 SET(p_vector_base_v4_dtor,
574 "??1_Concurrent_vector_base_v4@details@Concurrency@@IEAA@XZ");
575 SET(p_vector_base_v4__Internal_capacity,
576 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IEBA_KXZ");
577 SET(p_vector_base_v4__Internal_push_back,
578 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IEAAPEAX_KAEA_K@Z");
579 SET(p_vector_base_v4__Internal_clear,
580 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_KP6AXPEAX_K@Z@Z");
581 SET(p_vector_base_v4__Internal_copy,
582 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z");
583 SET(p_vector_base_v4__Internal_assign,
584 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z");
585 SET(p_vector_base_v4__Internal_swap,
586 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEAV123@@Z");
587 SET(p_vector_base_v4__Internal_compact,
588 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IEAAPEAX_KPEAXP6AX10@ZP6AX1PEBX0@Z@Z");
589 SET(p_vector_base_v4__Internal_grow_by,
590 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z");
591 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
592 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z");
593 SET(p_vector_base_v4__Internal_reserve,
594 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00@Z");
595 SET(p_vector_base_v4__Internal_resize,
596 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00P6AXPEAX0@ZP6AX1PEBX0@Z3@Z");
597 } else {
598 SET(p_tr2_sys__File_size,
599 "?_File_size@sys@tr2@std@@YA_KPBD@Z");
600 SET(p_tr2_sys__File_size_wchar,
601 "?_File_size@sys@tr2@std@@YA_KPB_W@Z");
602 SET(p_tr2_sys__Equivalent,
603 "?_Equivalent@sys@tr2@std@@YAHPBD0@Z");
604 SET(p_tr2_sys__Equivalent_wchar,
605 "?_Equivalent@sys@tr2@std@@YAHPB_W0@Z");
606 SET(p_tr2_sys__Current_get,
607 "?_Current_get@sys@tr2@std@@YAPADAAY0BAE@D@Z");
608 SET(p_tr2_sys__Current_get_wchar,
609 "?_Current_get@sys@tr2@std@@YAPA_WAAY0BAE@_W@Z");
610 SET(p_tr2_sys__Current_set,
611 "?_Current_set@sys@tr2@std@@YA_NPBD@Z");
612 SET(p_tr2_sys__Current_set_wchar,
613 "?_Current_set@sys@tr2@std@@YA_NPB_W@Z");
614 SET(p_tr2_sys__Make_dir,
615 "?_Make_dir@sys@tr2@std@@YAHPBD@Z");
616 SET(p_tr2_sys__Make_dir_wchar,
617 "?_Make_dir@sys@tr2@std@@YAHPB_W@Z");
618 SET(p_tr2_sys__Remove_dir,
619 "?_Remove_dir@sys@tr2@std@@YA_NPBD@Z");
620 SET(p_tr2_sys__Remove_dir_wchar,
621 "?_Remove_dir@sys@tr2@std@@YA_NPB_W@Z");
622 SET(p_tr2_sys__Copy_file,
623 "?_Copy_file@sys@tr2@std@@YAHPBD0_N@Z");
624 SET(p_tr2_sys__Copy_file_wchar,
625 "?_Copy_file@sys@tr2@std@@YAHPB_W0_N@Z");
626 SET(p_tr2_sys__Rename,
627 "?_Rename@sys@tr2@std@@YAHPBD0@Z");
628 SET(p_tr2_sys__Rename_wchar,
629 "?_Rename@sys@tr2@std@@YAHPB_W0@Z");
630 SET(p_tr2_sys__Statvfs,
631 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z");
632 SET(p_tr2_sys__Statvfs_wchar,
633 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PB_W@Z");
634 SET(p_tr2_sys__Stat,
635 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
636 SET(p_tr2_sys__Stat_wchar,
637 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
638 SET(p_tr2_sys__Lstat,
639 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
640 SET(p_tr2_sys__Lstat_wchar,
641 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
642 SET(p_tr2_sys__Last_write_time,
643 "?_Last_write_time@sys@tr2@std@@YA_JPBD@Z");
644 SET(p_tr2_sys__Last_write_time_wchar,
645 "?_Last_write_time@sys@tr2@std@@YA_JPB_W@Z");
646 SET(p_tr2_sys__Last_write_time_set,
647 "?_Last_write_time@sys@tr2@std@@YAXPBD_J@Z");
648 SET(p_tr2_sys__Open_dir,
649 "?_Open_dir@sys@tr2@std@@YAPAXAAY0BAE@DPBDAAHAAW4file_type@123@@Z");
650 SET(p_tr2_sys__Read_dir,
651 "?_Read_dir@sys@tr2@std@@YAPADAAY0BAE@DPAXAAW4file_type@123@@Z");
652 SET(p_tr2_sys__Close_dir,
653 "?_Close_dir@sys@tr2@std@@YAXPAX@Z");
654 SET(p_tr2_sys__Link,
655 "?_Link@sys@tr2@std@@YAHPBD0@Z");
656 SET(p_tr2_sys__Symlink,
657 "?_Symlink@sys@tr2@std@@YAHPBD0@Z");
658 SET(p_tr2_sys__Unlink,
659 "?_Unlink@sys@tr2@std@@YAHPBD@Z");
660 SET(p_threads__Mtx_new,
661 "?_Mtx_new@threads@stdext@@YAXAAPAX@Z");
662 SET(p_threads__Mtx_delete,
663 "?_Mtx_delete@threads@stdext@@YAXPAX@Z");
664 SET(p_threads__Mtx_lock,
665 "?_Mtx_lock@threads@stdext@@YAXPAX@Z");
666 SET(p_threads__Mtx_unlock,
667 "?_Mtx_unlock@threads@stdext@@YAXPAX@Z");
668 SET(p_vector_base_v4__Segment_index_of,
669 "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KAII@Z");
670 #ifdef __i386__
671 SET(p_i386_Thrd_current,
672 "_Thrd_current");
673 p__Thrd_current = i386_Thrd_current;
674 SET(p__Pad_ctor,
675 "??0_Pad@std@@QAE@XZ");
676 SET(p__Pad_copy_ctor,
677 "??0_Pad@std@@QAE@ABV01@@Z");
678 SET(p__Pad_dtor,
679 "??1_Pad@std@@QAE@XZ");
680 SET(p__Pad_op_assign,
681 "??4_Pad@std@@QAEAAV01@ABV01@@Z");
682 SET(p__Pad__Launch,
683 "?_Launch@_Pad@std@@QAEXPAU_Thrd_imp_t@@@Z");
684 SET(p__Pad__Release,
685 "?_Release@_Pad@std@@QAEXXZ");
686 SET(p_queue_base_v4_ctor,
687 "??0_Concurrent_queue_base_v4@details@Concurrency@@IAE@I@Z");
688 SET(p_queue_base_v4_dtor,
689 "??1_Concurrent_queue_base_v4@details@Concurrency@@MAE@XZ");
690 SET(p_queue_base_v4__Internal_empty,
691 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBE_NXZ");
692 SET(p_queue_base_v4__Internal_size,
693 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBEIXZ");
694 SET(p_queue_base_v4__Internal_push,
695 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPBX@Z");
696 SET(p_queue_base_v4__Internal_move_push,
697 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPAX@Z");
698 SET(p_queue_base_v4__Internal_pop_if_present,
699 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAE_NPAX@Z");
700 SET(p_queue_base_v4__Internal_finish_clear,
701 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAEXXZ");
702 SET(p_vector_base_v4_dtor,
703 "??1_Concurrent_vector_base_v4@details@Concurrency@@IAE@XZ");
704 SET(p_vector_base_v4__Internal_capacity,
705 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IBEIXZ");
706 SET(p_vector_base_v4__Internal_push_back,
707 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IAEPAXIAAI@Z");
708 SET(p_vector_base_v4__Internal_clear,
709 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAEIP6AXPAXI@Z@Z");
710 SET(p_vector_base_v4__Internal_copy,
711 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IAEXABV123@IP6AXPAXPBXI@Z@Z");
712 SET(p_vector_base_v4__Internal_assign,
713 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z");
714 SET(p_vector_base_v4__Internal_swap,
715 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IAEXAAV123@@Z");
716 SET(p_vector_base_v4__Internal_compact,
717 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IAEPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z");
718 SET(p_vector_base_v4__Internal_grow_by,
719 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IAEIIIP6AXPAXPBXI@Z1@Z");
720 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
721 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IAEIIIP6AXPAXPBXI@Z1@Z");
722 SET(p_vector_base_v4__Internal_reserve,
723 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIII@Z");
724 SET(p_vector_base_v4__Internal_resize,
725 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z");
726 #else
727 SET(p__Thrd_current,
728 "_Thrd_current");
729 SET(p__Pad_ctor,
730 "??0_Pad@std@@QAA@XZ");
731 SET(p__Pad_copy_ctor,
732 "??0_Pad@std@@QAA@ABV01@@Z");
733 SET(p__Pad_dtor,
734 "??1_Pad@std@@QAA@XZ");
735 SET(p__Pad_op_assign,
736 "??4_Pad@std@@QAAAAV01@ABV01@@Z");
737 SET(p__Pad__Launch,
738 "?_Launch@_Pad@std@@QAAXPAU_Thrd_imp_t@@@Z");
739 SET(p__Pad__Release,
740 "?_Release@_Pad@std@@QAAXXZ");
741 SET(p_queue_base_v4_ctor,
742 "??0_Concurrent_queue_base_v4@details@Concurrency@@IAA@I@Z");
743 SET(p_queue_base_v4_dtor,
744 "??1_Concurrent_queue_base_v4@details@Concurrency@@MAA@XZ");
745 SET(p_queue_base_v4__Internal_empty,
746 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBA_NXZ");
747 SET(p_queue_base_v4__Internal_size,
748 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBAIXZ");
749 SET(p_queue_base_v4__Internal_push,
750 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPBX@Z");
751 SET(p_queue_base_v4__Internal_move_push,
752 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPAX@Z");
753 SET(p_queue_base_v4__Internal_pop_if_present,
754 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAA_NPAX@Z");
755 SET(p_queue_base_v4__Internal_finish_clear,
756 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAAXXZ");
757 SET(p_vector_base_v4_dtor,
758 "??1_Concurrent_vector_base_v4@details@Concurrency@@IAA@XZ");
759 SET(p_vector_base_v4__Internal_capacity,
760 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IBAIXZ");
761 SET(p_vector_base_v4__Internal_push_back,
762 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IAAPAXIAAI@Z");
763 SET(p_vector_base_v4__Internal_clear,
764 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAAIP6AXPAXI@Z@Z");
765 SET(p_vector_base_v4__Internal_copy,
766 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IAAXABV123@IP6AXPAXPBXI@Z@Z");
767 SET(p_vector_base_v4__Internal_assign,
768 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z");
769 SET(p_vector_base_v4__Internal_swap,
770 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IAAXAAV123@@Z");
771 SET(p_vector_base_v4__Internal_compact,
772 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IAAPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z");
773 SET(p_vector_base_v4__Internal_grow_by,
774 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IAAIIIP6AXPAXPBXI@Z1@Z");
775 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
776 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IAAIIIP6AXPAXPBXI@Z1@Z");
777 SET(p_vector_base_v4__Internal_reserve,
778 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAAXIII@Z");
779 SET(p_vector_base_v4__Internal_resize,
780 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z");
781 #endif
783 SET(p__Thrd_equal,
784 "_Thrd_equal");
785 SET(p__Thrd_lt,
786 "_Thrd_lt");
787 SET(p__Thrd_sleep,
788 "_Thrd_sleep");
789 SET(p__Thrd_create,
790 "_Thrd_create");
791 SET(p__Thrd_join,
792 "_Thrd_join");
793 SET(p__Thrd_detach,
794 "_Thrd_detach");
796 SET(p__Mtx_init,
797 "_Mtx_init");
798 SET(p__Mtx_destroy,
799 "_Mtx_destroy");
800 SET(p__Mtx_lock,
801 "_Mtx_lock");
802 SET(p__Mtx_unlock,
803 "_Mtx_unlock");
805 SET(p__Cnd_init,
806 "_Cnd_init");
807 SET(p__Cnd_destroy,
808 "_Cnd_destroy");
809 SET(p__Cnd_wait,
810 "_Cnd_wait");
811 SET(p__Cnd_timedwait,
812 "_Cnd_timedwait");
813 SET(p__Cnd_broadcast,
814 "_Cnd_broadcast");
815 SET(p__Cnd_signal,
816 "_Cnd_signal");
817 SET(p__Cnd_register_at_thread_exit,
818 "_Cnd_register_at_thread_exit");
819 SET(p__Cnd_unregister_at_thread_exit,
820 "_Cnd_unregister_at_thread_exit");
821 SET(p__Cnd_do_broadcast_at_thread_exit,
822 "_Cnd_do_broadcast_at_thread_exit");
824 hdll = GetModuleHandleA("msvcr120.dll");
825 p_setlocale = (void*)GetProcAddress(hdll, "setlocale");
826 p__setmbcp = (void*)GetProcAddress(hdll, "_setmbcp");
827 p__ismbblead = (void*)GetProcAddress(hdll, "_ismbblead");
829 hdll = GetModuleHandleA("kernel32.dll");
830 pCreateSymbolicLinkA = (void*)GetProcAddress(hdll, "CreateSymbolicLinkA");
832 init_thiscall_thunk();
833 return TRUE;
836 static void test__Xtime_diff_to_millis2(void)
838 struct {
839 __time64_t sec_before;
840 MSVCRT_long nsec_before;
841 __time64_t sec_after;
842 MSVCRT_long nsec_after;
843 MSVCRT_long expect;
844 } tests[] = {
845 {1, 0, 2, 0, 1000},
846 {0, 1000000000, 0, 2000000000, 1000},
847 {1, 100000000, 2, 100000000, 1000},
848 {1, 100000000, 1, 200000000, 100},
849 {0, 0, 0, 1000000000, 1000},
850 {0, 0, 0, 1200000000, 1200},
851 {0, 0, 0, 1230000000, 1230},
852 {0, 0, 0, 1234000000, 1234},
853 {0, 0, 0, 1234100000, 1235},
854 {0, 0, 0, 1234900000, 1235},
855 {0, 0, 0, 1234010000, 1235},
856 {0, 0, 0, 1234090000, 1235},
857 {0, 0, 0, 1234000001, 1235},
858 {0, 0, 0, 1234000009, 1235},
859 {0, 0, -1, 0, 0},
860 {1, 0, 0, 0, 0},
861 {0, 1000000000, 0, 0, 0},
862 {0x7FFFFFFF / 1000, 0, 0, 0, 0},
863 {2147484, 0, 0, 0, 0}, /* ceil(0x80000000 / 1000) */
864 {2147485, 0, 0, 0, 0}, /* ceil(0x80000000 / 1000) + 1*/
865 {0, 0, 0x7FFFFFFF / 1000, 0, 2147483000},
866 {0, 0, 0x7FFFFFFF / 1000, 647000000, 0x7FFFFFFF}, /* max */
867 {0, 0, 0x7FFFFFFF / 1000, 647000001, -2147483648}, /* overflow. */
868 {0, 0, 2147484, 0, -2147483296}, /* ceil(0x80000000 / 1000), overflow*/
869 {0, 0, 0, -10000000, 0},
870 {0, 0, -1, -100000000, 0},
871 {-1, 0, 0, 0, 1000},
872 {0, -100000000, 0, 0, 100},
873 {-1, -100000000, 0, 0, 1100},
874 {0, 0, -1, 2000000000, 1000},
875 {0, 0, -2, 2000000000, 0},
876 {0, 0, -2, 2100000000, 100},
877 {0, 0, _I64_MAX / 1000, 0, -808}, /* Still fits in a signed 64 bit number */
878 {0, 0, _I64_MAX / 1000, 1000000000, 192}, /* Overflows a signed 64 bit number */
879 {0, 0, (((ULONGLONG)0x80000000 << 32) | 0x1000) / 1000, 1000000000, 4192}, /* 64 bit overflow */
880 {_I64_MAX - 2, 0, _I64_MAX, 0, 2000}, /* Not an overflow */
881 {_I64_MAX, 0, _I64_MAX - 2, 0, 0}, /* Not an overflow */
883 /* October 11th 2017, 12:34:59 UTC */
884 {1507725144, 983274000, 0, 0, 0},
885 {0, 0, 1507725144, 983274000, 191624088},
886 {1507725144, 983274000, 1507725145, 983274000, 1000},
887 {1507725145, 983274000, 1507725145, 983274000, 0},
889 int i;
890 MSVCRT_long ret;
891 xtime t1, t2;
893 for(i = 0; i < ARRAY_SIZE(tests); ++ i)
895 t1.sec = tests[i].sec_before;
896 t1.nsec = tests[i].nsec_before;
897 t2.sec = tests[i].sec_after;
898 t2.nsec = tests[i].nsec_after;
899 ret = p__Xtime_diff_to_millis2(&t2, &t1);
900 ok(ret == tests[i].expect,
901 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
902 i, tests[i].expect, ret);
906 static void test_xtime_get(void)
908 static const MSVCRT_long tests[] = {1, 50, 100, 200, 500};
909 MSVCRT_long diff;
910 xtime before, after;
911 int i;
913 for(i = 0; i < ARRAY_SIZE(tests); i ++)
915 p_xtime_get(&before, 1);
916 Sleep(tests[i]);
917 p_xtime_get(&after, 1);
919 diff = p__Xtime_diff_to_millis2(&after, &before);
921 ok(diff >= tests[i],
922 "xtime_get() not functioning correctly, test: %d, expect: %d, got: %d\n",
923 i, tests[i], diff);
926 /* Test parameter and return value */
927 before.sec = 0xdeadbeef, before.nsec = 0xdeadbeef;
928 i = p_xtime_get(&before, 0);
929 ok(i == 0, "expect xtime_get() to return 0, got: %d\n", i);
930 ok(before.sec == 0xdeadbeef && before.nsec == 0xdeadbeef,
931 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
933 before.sec = 0xdeadbeef, before.nsec = 0xdeadbeef;
934 i = p_xtime_get(&before, 1);
935 ok(i == 1, "expect xtime_get() to return 1, got: %d\n", i);
936 ok(before.sec != 0xdeadbeef && before.nsec != 0xdeadbeef,
937 "xtime_get() should have modified the xtime struct with the given option\n");
940 static void test__Getcvt(void)
942 _Cvtvec cvtvec;
943 int i;
945 p__Getcvt(&cvtvec);
946 ok(cvtvec.page == 0, "cvtvec.page = %d\n", cvtvec.page);
947 ok(cvtvec.mb_max == 1, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
948 todo_wine ok(cvtvec.unk == 1, "cvtvec.unk = %d\n", cvtvec.unk);
949 for(i=0; i<32; i++)
950 ok(cvtvec.isleadbyte[i] == 0, "cvtvec.isleadbyte[%d] = %x\n", i, cvtvec.isleadbyte[i]);
952 if(!p_setlocale(LC_ALL, ".936")) {
953 win_skip("_Getcvt tests\n");
954 return;
956 p__Getcvt(&cvtvec);
957 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
958 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
959 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
960 for(i=0; i<32; i++) {
961 BYTE b = 0;
962 int j;
964 for(j=0; j<8; j++)
965 b |= (p__ismbblead(i*8+j) ? 1 : 0) << j;
966 ok(cvtvec.isleadbyte[i] ==b, "cvtvec.isleadbyte[%d] = %x (%x)\n", i, cvtvec.isleadbyte[i], b);
969 p__setmbcp(936);
970 p__Getcvt(&cvtvec);
971 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
972 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
973 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
974 for(i=0; i<32; i++) {
975 BYTE b = 0;
976 int j;
978 for(j=0; j<8; j++)
979 b |= (p__ismbblead(i*8+j) ? 1 : 0) << j;
980 ok(cvtvec.isleadbyte[i] ==b, "cvtvec.isleadbyte[%d] = %x (%x)\n", i, cvtvec.isleadbyte[i], b);
984 static int cnt;
985 static int once;
987 static void __cdecl call_once_func(void)
989 ok(!once, "once != 0\n");
990 cnt += 0x10000;
993 static void __cdecl call_once_ex_func(void *arg)
995 int *i = arg;
997 ok(!once, "once != 0\n");
998 (*i)++;
1001 static DWORD WINAPI call_once_thread(void *arg)
1003 p__Call_once(&once, call_once_func);
1004 return 0;
1007 static DWORD WINAPI call_once_ex_thread(void *arg)
1009 p__Call_onceEx(&once, call_once_ex_func, &cnt);
1010 return 0;
1013 static void test__Call_once(void)
1015 HANDLE h[4];
1016 int i;
1018 for(i=0; i<4; i++)
1019 h[i] = CreateThread(NULL, 0, call_once_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 == 0x10000, "cnt = %x\n", cnt);
1023 ok(once == 1, "once = %x\n", once);
1025 once = cnt = 0;
1026 for(i=0; i<4; i++)
1027 h[i] = CreateThread(NULL, 0, call_once_ex_thread, &once, 0, NULL);
1028 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
1029 "error waiting for all threads to finish\n");
1030 ok(cnt == 1, "cnt = %x\n", cnt);
1031 ok(once == 1, "once = %x\n", once);
1034 static void **vtbl_func0;
1035 #ifdef __i386__
1036 /* TODO: this should be a __thiscall function */
1037 static void __stdcall thiscall_func(void)
1039 cnt = 1;
1041 #else
1042 static void __cdecl thiscall_func(void *this)
1044 ok(this == &vtbl_func0, "incorrect this value\n");
1045 cnt = 1;
1047 #endif
1049 static void test__Do_call(void)
1051 void *pfunc = thiscall_func;
1053 cnt = 0;
1054 vtbl_func0 = &pfunc;
1055 p__Do_call(&vtbl_func0);
1056 ok(cnt == 1, "func was not called\n");
1059 static void test__Dtest(void)
1061 double d;
1062 short ret;
1064 d = 0;
1065 ret = p__Dtest(&d);
1066 ok(ret == FP_ZERO, "_Dtest(0) returned %x\n", ret);
1068 d = 1;
1069 ret = p__Dtest(&d);
1070 ok(ret == FP_NORMAL, "_Dtest(1) returned %x\n", ret);
1072 d = -1;
1073 ret = p__Dtest(&d);
1074 ok(ret == FP_NORMAL, "_Dtest(-1) returned %x\n", ret);
1076 d = INFINITY;
1077 ret = p__Dtest(&d);
1078 ok(ret == FP_INFINITE, "_Dtest(INF) returned %x\n", ret);
1080 d = NAN;
1081 ret = p__Dtest(&d);
1082 ok(ret == FP_NAN, "_Dtest(NAN) returned %x\n", ret);
1085 static void test__Dscale(void)
1087 double d;
1088 short ret;
1090 d = 0;
1091 ret = p__Dscale(&d, 0);
1092 ok(d == 0, "d = %f\n", d);
1093 ok(ret == FP_ZERO, "ret = %x\n", ret);
1095 d = 0;
1096 ret = p__Dscale(&d, 1);
1097 ok(d == 0, "d = %f\n", d);
1098 ok(ret == FP_ZERO, "ret = %x\n", ret);
1100 d = 0;
1101 ret = p__Dscale(&d, -1);
1102 ok(d == 0, "d = %f\n", d);
1103 ok(ret == FP_ZERO, "ret = %x\n", ret);
1105 d = 1;
1106 ret = p__Dscale(&d, 0);
1107 ok(d == 1, "d = %f\n", d);
1108 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1110 d = 1;
1111 ret = p__Dscale(&d, 1);
1112 ok(d == 2, "d = %f\n", d);
1113 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1115 d = 1;
1116 ret = p__Dscale(&d, -1);
1117 ok(d == 0.5, "d = %f\n", d);
1118 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1120 d = 1;
1121 ret = p__Dscale(&d, -99999);
1122 ok(d == 0, "d = %f\n", d);
1123 ok(ret == FP_ZERO, "ret = %x\n", ret);
1125 d = 1;
1126 ret = p__Dscale(&d, 999999);
1127 ok(d == INFINITY, "d = %f\n", d);
1128 ok(ret == FP_INFINITE, "ret = %x\n", ret);
1130 d = NAN;
1131 ret = p__Dscale(&d, 1);
1132 ok(ret == FP_NAN, "ret = %x\n", ret);
1135 static void test__FExp(void)
1137 float d;
1138 short ret;
1140 d = 0;
1141 ret = p__FExp(&d, 0, 0);
1142 ok(d == 0, "d = %f\n", d);
1143 ok(ret == FP_ZERO, "ret = %x\n", ret);
1145 d = 0;
1146 ret = p__FExp(&d, 1, 0);
1147 ok(d == 1.0, "d = %f\n", d);
1148 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1150 d = 0;
1151 ret = p__FExp(&d, 1, 1);
1152 ok(d == 2.0, "d = %f\n", d);
1153 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1155 d = 0;
1156 ret = p__FExp(&d, 1, 2);
1157 ok(d == 4.0, "d = %f\n", d);
1158 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1160 d = 0;
1161 ret = p__FExp(&d, 10, 0);
1162 ok(d == 10.0, "d = %f\n", d);
1163 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1165 d = 1;
1166 ret = p__FExp(&d, 0, 0);
1167 ok(d == 0, "d = %f\n", d);
1168 ok(ret == FP_ZERO, "ret = %x\n", ret);
1170 d = 1;
1171 ret = p__FExp(&d, 1, 0);
1172 ok(compare_float(d, 2.7182817, 4), "d = %f\n", d);
1173 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1175 d = 9e20;
1176 ret = p__FExp(&d, 0, 0);
1177 ok(d == 0, "d = %f\n", d);
1178 ok(ret == FP_ZERO, "ret = %x\n", ret);
1180 d = 90;
1181 ret = p__FExp(&d, 1, 0);
1182 ok(ret == FP_INFINITE, "ret = %x\n", ret);
1184 d = 90;
1185 ret = p__FExp(&d, 1, -50);
1186 ok(compare_float(d, 1.0839359e+024, 4), "d = %g\n", d);
1187 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1190 static void test_tr2_sys__File_size(void)
1192 ULONGLONG val;
1193 HANDLE file;
1194 LARGE_INTEGER file_size;
1195 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
1196 CreateDirectoryA("tr2_test_dir", NULL);
1198 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1199 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1200 file_size.QuadPart = 7;
1201 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1202 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1203 CloseHandle(file);
1204 val = p_tr2_sys__File_size("tr2_test_dir/f1");
1205 ok(val == 7, "file_size is %s\n", wine_dbgstr_longlong(val));
1206 val = p_tr2_sys__File_size_wchar(testW);
1207 ok(val == 7, "file_size is %s\n", wine_dbgstr_longlong(val));
1209 file = CreateFileA("tr2_test_dir/f2", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1210 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1211 CloseHandle(file);
1212 val = p_tr2_sys__File_size("tr2_test_dir/f2");
1213 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1215 val = p_tr2_sys__File_size("tr2_test_dir");
1216 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1218 errno = 0xdeadbeef;
1219 val = p_tr2_sys__File_size("tr2_test_dir/not_exists_file");
1220 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1221 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1223 errno = 0xdeadbeef;
1224 val = p_tr2_sys__File_size(NULL);
1225 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1226 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1228 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1229 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1230 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1233 static void test_tr2_sys__Equivalent(void)
1235 int val, i;
1236 HANDLE file;
1237 char temp_path[MAX_PATH], current_path[MAX_PATH];
1238 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
1239 WCHAR testW2[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','2',0};
1240 struct {
1241 char const *path1;
1242 char const *path2;
1243 int equivalent;
1244 } tests[] = {
1245 { NULL, NULL, -1 },
1246 { NULL, "f1", -1 },
1247 { "f1", NULL, -1 },
1248 { "f1", "tr2_test_dir", -1 },
1249 { "tr2_test_dir", "f1", -1 },
1250 { "tr2_test_dir", "tr2_test_dir", -1 },
1251 { "tr2_test_dir/./f1", "tr2_test_dir/f2", 0 },
1252 { "tr2_test_dir/f1" , "tr2_test_dir/f1", 1 },
1253 { "not_exists_file" , "tr2_test_dir/f1", 0 },
1254 { "tr2_test_dir\\f1" , "tr2_test_dir/./f1", 1 },
1255 { "not_exists_file" , "not_exists_file", -1 },
1256 { "tr2_test_dir/f1" , "not_exists_file", 0 },
1257 { "tr2_test_dir/../tr2_test_dir/f1", "tr2_test_dir/f1", 1 }
1260 memset(current_path, 0, MAX_PATH);
1261 GetCurrentDirectoryA(MAX_PATH, current_path);
1262 memset(temp_path, 0, MAX_PATH);
1263 GetTempPathA(MAX_PATH, temp_path);
1264 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1265 CreateDirectoryA("tr2_test_dir", NULL);
1267 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1268 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1269 CloseHandle(file);
1270 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1271 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1272 CloseHandle(file);
1274 for(i=0; i<ARRAY_SIZE(tests); i++) {
1275 errno = 0xdeadbeef;
1276 val = p_tr2_sys__Equivalent(tests[i].path1, tests[i].path2);
1277 ok(tests[i].equivalent == val, "tr2_sys__Equivalent(): test %d expect: %d, got %d\n", i+1, tests[i].equivalent, val);
1278 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1281 val = p_tr2_sys__Equivalent_wchar(testW, testW);
1282 ok(val == 1, "tr2_sys__Equivalent(): expect: 1, got %d\n", val);
1283 val = p_tr2_sys__Equivalent_wchar(testW, testW2);
1284 ok(val == 0, "tr2_sys__Equivalent(): expect: 0, got %d\n", val);
1286 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1287 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1288 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1289 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1292 static void test_tr2_sys__Current_get(void)
1294 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
1295 char *temp;
1296 WCHAR temp_path_wchar[MAX_PATH], current_path_wchar[MAX_PATH];
1297 WCHAR *temp_wchar;
1298 memset(origin_path, 0, MAX_PATH);
1299 GetCurrentDirectoryA(MAX_PATH, origin_path);
1300 memset(temp_path, 0, MAX_PATH);
1301 GetTempPathA(MAX_PATH, temp_path);
1303 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1304 memset(current_path, 0, MAX_PATH);
1305 temp = p_tr2_sys__Current_get(current_path);
1306 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1307 temp[strlen(temp)] = '\\';
1308 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1310 GetTempPathW(MAX_PATH, temp_path_wchar);
1311 ok(SetCurrentDirectoryW(temp_path_wchar), "SetCurrentDirectoryW to temp_path_wchar failed\n");
1312 memset(current_path_wchar, 0, MAX_PATH);
1313 temp_wchar = p_tr2_sys__Current_get_wchar(current_path_wchar);
1314 ok(temp_wchar == current_path_wchar, "p_tr2_sys__Current_get_wchar returned different buffer\n");
1315 temp_wchar[wcslen(temp_wchar)] = '\\';
1316 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));
1318 ok(SetCurrentDirectoryA(origin_path), "SetCurrentDirectoryA to origin_path failed\n");
1319 memset(current_path, 0, MAX_PATH);
1320 temp = p_tr2_sys__Current_get(current_path);
1321 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1322 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
1325 static void test_tr2_sys__Current_set(void)
1327 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
1328 char *temp;
1329 WCHAR testW[] = {'.','/',0};
1330 memset(temp_path, 0, MAX_PATH);
1331 GetTempPathA(MAX_PATH, temp_path);
1332 memset(origin_path, 0, MAX_PATH);
1333 GetCurrentDirectoryA(MAX_PATH, origin_path);
1334 temp = p_tr2_sys__Current_get(origin_path);
1335 ok(temp == origin_path, "p_tr2_sys__Current_get returned different buffer\n");
1337 ok(p_tr2_sys__Current_set(temp_path), "p_tr2_sys__Current_set to temp_path failed\n");
1338 memset(current_path, 0, MAX_PATH);
1339 temp = p_tr2_sys__Current_get(current_path);
1340 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1341 temp[strlen(temp)] = '\\';
1342 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1344 ok(p_tr2_sys__Current_set_wchar(testW), "p_tr2_sys__Current_set_wchar to temp_path failed\n");
1345 memset(current_path, 0, MAX_PATH);
1346 temp = p_tr2_sys__Current_get(current_path);
1347 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1348 temp[strlen(temp)] = '\\';
1349 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1351 errno = 0xdeadbeef;
1352 ok(!p_tr2_sys__Current_set("not_exisist_dir"), "p_tr2_sys__Current_set to not_exist_dir succeed\n");
1353 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1355 errno = 0xdeadbeef;
1356 ok(!p_tr2_sys__Current_set("??invalid_name>>"), "p_tr2_sys__Current_set to ??invalid_name>> succeed\n");
1357 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1359 ok(p_tr2_sys__Current_set(origin_path), "p_tr2_sys__Current_set to origin_path failed\n");
1360 memset(current_path, 0, MAX_PATH);
1361 temp = p_tr2_sys__Current_get(current_path);
1362 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1363 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
1366 static void test_tr2_sys__Make_dir(void)
1368 int ret, i;
1369 WCHAR testW[] = {'w','d',0};
1370 struct {
1371 char const *path;
1372 int val;
1373 } tests[] = {
1374 { "tr2_test_dir", 1 },
1375 { "tr2_test_dir", 0 },
1376 { NULL, -1 },
1377 { "??invalid_name>>", -1 }
1380 for(i=0; i<ARRAY_SIZE(tests); i++) {
1381 errno = 0xdeadbeef;
1382 ret = p_tr2_sys__Make_dir(tests[i].path);
1383 ok(ret == tests[i].val, "tr2_sys__Make_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1384 ok(errno == 0xdeadbeef, "tr2_sys__Make_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1386 ret = p_tr2_sys__Make_dir_wchar(testW);
1387 ok(ret == 1, "tr2_sys__Make_dir(): expect: 1, got %d\n", ret);
1389 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1390 ok(p_tr2_sys__Remove_dir_wchar(testW), "expect wd to exist\n");
1393 static void test_tr2_sys__Remove_dir(void)
1395 MSVCP_bool ret;
1396 int i;
1397 struct {
1398 char const *path;
1399 MSVCP_bool val;
1400 } tests[] = {
1401 { "tr2_test_dir", TRUE },
1402 { "tr2_test_dir", FALSE },
1403 { NULL, FALSE },
1404 { "??invalid_name>>", FALSE }
1407 ok(p_tr2_sys__Make_dir("tr2_test_dir"), "tr2_sys__Make_dir() failed\n");
1409 for(i=0; i<ARRAY_SIZE(tests); i++) {
1410 errno = 0xdeadbeef;
1411 ret = p_tr2_sys__Remove_dir(tests[i].path);
1412 ok(ret == tests[i].val, "test_tr2_sys__Remove_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1413 ok(errno == 0xdeadbeef, "test_tr2_sys__Remove_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1417 static void test_tr2_sys__Copy_file(void)
1419 HANDLE file;
1420 int ret, i;
1421 LARGE_INTEGER file_size;
1422 WCHAR testW[] = {'f','1',0}, testW2[] = {'f','w',0};
1423 struct {
1424 char const *source;
1425 char const *dest;
1426 MSVCP_bool fail_if_exists;
1427 int last_error;
1428 int last_error2;
1429 MSVCP_bool is_todo;
1430 } tests[] = {
1431 { "f1", "f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
1432 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
1433 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_FILE_EXISTS, ERROR_FILE_EXISTS, FALSE },
1434 { "f1", "tr2_test_dir\\f1_copy", FALSE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
1435 { "tr2_test_dir", "f1", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED, FALSE },
1436 { "tr2_test_dir", "tr2_test_dir_copy", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED, FALSE },
1437 { NULL, "f1", TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER, TRUE },
1438 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER, TRUE },
1439 { "not_exist", "tr2_test_dir", TRUE, ERROR_FILE_NOT_FOUND, ERROR_FILE_NOT_FOUND, FALSE },
1440 { "f1", "not_exist_dir\\f1_copy", TRUE, ERROR_PATH_NOT_FOUND, ERROR_FILE_NOT_FOUND, FALSE },
1441 { "f1", "tr2_test_dir", TRUE, ERROR_ACCESS_DENIED, ERROR_FILE_EXISTS, FALSE }
1444 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1445 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1446 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1447 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1448 file_size.QuadPart = 7;
1449 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1450 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1451 CloseHandle(file);
1453 for(i=0; i<ARRAY_SIZE(tests); i++) {
1454 errno = 0xdeadbeef;
1455 ret = p_tr2_sys__Copy_file(tests[i].source, tests[i].dest, tests[i].fail_if_exists);
1456 todo_wine_if(tests[i].is_todo)
1457 ok(ret == tests[i].last_error || ret == tests[i].last_error2,
1458 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n", i+1, tests[i].last_error, ret);
1459 ok(errno == 0xdeadbeef, "test_tr2_sys__Copy_file(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1460 if(ret == ERROR_SUCCESS)
1461 ok(p_tr2_sys__File_size(tests[i].source) == p_tr2_sys__File_size(tests[i].dest),
1462 "test_tr2_sys__Copy_file(): test %d failed, two files' size are not equal\n", i+1);
1464 ret = p_tr2_sys__Copy_file_wchar(testW, testW2, TRUE);
1465 ok(ret == ERROR_SUCCESS, "test_tr2_sys__Copy_file_wchar() expect ERROR_SUCCESS, got %d\n", ret);
1467 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1468 ok(DeleteFileW(testW2), "expect fw to exist\n");
1469 ok(DeleteFileA("f1_copy"), "expect f1_copy to exist\n");
1470 ok(DeleteFileA("tr2_test_dir/f1_copy"), "expect tr2_test_dir/f1 to exist\n");
1471 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1472 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1475 static void test_tr2_sys__Rename(void)
1477 int ret, i;
1478 HANDLE file, h1, h2;
1479 BY_HANDLE_FILE_INFORMATION info1, info2;
1480 char temp_path[MAX_PATH], current_path[MAX_PATH];
1481 LARGE_INTEGER file_size;
1482 static const WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
1483 static const struct {
1484 char const *old_path;
1485 char const *new_path;
1486 int val;
1487 } tests[] = {
1488 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_SUCCESS },
1489 { "tr2_test_dir\\f1", NULL, ERROR_INVALID_PARAMETER },
1490 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND },
1491 { NULL, "tr2_test_dir\\NULL_rename", ERROR_INVALID_PARAMETER },
1492 { "tr2_test_dir\\f1_rename", "tr2_test_dir\\??invalid_name>>", ERROR_INVALID_NAME },
1493 { "tr2_test_dir\\not_exist_file", "tr2_test_dir\\not_exist_rename", ERROR_FILE_NOT_FOUND }
1495 static const WCHAR f1_renameW[] =
1496 {'t','r','2','_','t','e','s','t','_','d','i','r','\\','f','1','_','r','e','n','a','m','e',0};
1497 static const WCHAR f1_rename2W[] =
1498 {'t','r','2','_','t','e','s','t','_','d','i','r','\\','f','1','_','r','e','n','a','m','e','2',0};
1499 static const WCHAR not_existW[] =
1500 {'t','r','2','_','t','e','s','t','_','d','i','r','\\','n','o','t','_','e','x','i','s','t',0};
1501 static const WCHAR not_exist2W[] =
1502 {'t','r','2','_','t','e','s','t','_','d','i','r','\\','n','o','t','_','e','x','i','s','t','2',0};
1503 static const WCHAR invalidW[] =
1504 {'t','r','2','_','t','e','s','t','_','d','i','r','\\','?','?','i','n','v','a','l','i','d','>',0};
1505 static const struct {
1506 const WCHAR *old_path;
1507 const WCHAR *new_path;
1508 int val;
1509 } testsW[] = {
1510 { testW, f1_renameW, ERROR_SUCCESS },
1511 { testW, NULL, ERROR_FILE_NOT_FOUND }, /* Differs from the A version */
1512 { testW, f1_renameW, ERROR_FILE_NOT_FOUND },
1513 { NULL, f1_rename2W, ERROR_PATH_NOT_FOUND }, /* Differs from the A version */
1514 { f1_renameW, invalidW, ERROR_INVALID_NAME },
1515 { not_existW, not_exist2W, ERROR_FILE_NOT_FOUND },
1516 { not_existW, invalidW, ERROR_FILE_NOT_FOUND }
1519 memset(current_path, 0, MAX_PATH);
1520 GetCurrentDirectoryA(MAX_PATH, current_path);
1521 memset(temp_path, 0, MAX_PATH);
1522 GetTempPathA(MAX_PATH, temp_path);
1523 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1524 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1526 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1527 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1528 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1529 CloseHandle(file);
1531 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1");
1532 ok(ERROR_SUCCESS == ret, "test_tr2_sys__Rename(): expect: ERROR_SUCCESS, got %d\n", ret);
1533 for(i=0; i<ARRAY_SIZE(tests); i++) {
1534 errno = 0xdeadbeef;
1535 if(tests[i].val == ERROR_SUCCESS) {
1536 h1 = CreateFileA(tests[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1537 NULL, OPEN_EXISTING, 0, 0);
1538 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1539 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1540 CloseHandle(h1);
1542 SetLastError(0xdeadbeef);
1543 ret = p_tr2_sys__Rename(tests[i].old_path, tests[i].new_path);
1544 ok(ret == tests[i].val, "test_tr2_sys__Rename(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1545 ok(errno == 0xdeadbeef, "test_tr2_sys__Rename(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1546 if(ret == ERROR_SUCCESS) {
1547 h2 = CreateFileA(tests[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1548 NULL, OPEN_EXISTING, 0, 0);
1549 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1550 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1551 CloseHandle(h2);
1552 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1553 && info1.nFileIndexLow == info2.nFileIndexLow,
1554 "test_tr2_sys__Rename(): test %d expect two files equivalent\n", i+1);
1558 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1559 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1560 file_size.QuadPart = 7;
1561 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1562 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1563 CloseHandle(file);
1564 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1_rename");
1565 ok(ret == ERROR_ALREADY_EXISTS, "test_tr2_sys__Rename(): expect: ERROR_ALREADY_EXISTS, got %d\n", ret);
1566 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")));
1567 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")));
1569 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1571 for(i=0; i<ARRAY_SIZE(testsW); i++) {
1572 errno = 0xdeadbeef;
1573 if(testsW[i].val == ERROR_SUCCESS) {
1574 h1 = CreateFileW(testsW[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1575 NULL, OPEN_EXISTING, 0, 0);
1576 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1577 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1578 CloseHandle(h1);
1580 SetLastError(0xdeadbeef);
1581 ret = p_tr2_sys__Rename_wchar(testsW[i].old_path, testsW[i].new_path);
1582 ok(ret == testsW[i].val, "test_tr2_sys__Rename_wchar(): test %d expect: %d, got %d\n", i+1, testsW[i].val, ret);
1583 ok(errno == 0xdeadbeef, "test_tr2_sys__Rename_wchar(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1584 if(ret == ERROR_SUCCESS) {
1585 h2 = CreateFileW(testsW[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1586 NULL, OPEN_EXISTING, 0, 0);
1587 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1588 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1589 CloseHandle(h2);
1590 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1591 && info1.nFileIndexLow == info2.nFileIndexLow,
1592 "test_tr2_sys__Rename_wchar(): test %d expect two files equivalent\n", i+1);
1596 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1597 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1598 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect %d got %d\n", 1, ret);
1599 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1602 static void test_tr2_sys__Statvfs(void)
1604 struct space_info info;
1605 char current_path[MAX_PATH];
1606 WCHAR current_path_wchar[MAX_PATH];
1607 memset(current_path, 0, MAX_PATH);
1608 p_tr2_sys__Current_get(current_path);
1609 memset(current_path_wchar, 0, MAX_PATH);
1610 p_tr2_sys__Current_get_wchar(current_path_wchar);
1612 p_tr2_sys__Statvfs(&info, current_path);
1613 ok(info.capacity >= info.free, "test_tr2_sys__Statvfs(): info.capacity < info.free\n");
1614 ok(info.free >= info.available, "test_tr2_sys__Statvfs(): info.free < info.available\n");
1616 p_tr2_sys__Statvfs_wchar(&info, current_path_wchar);
1617 ok(info.capacity >= info.free, "tr2_sys__Statvfs_wchar(): info.capacity < info.free\n");
1618 ok(info.free >= info.available, "tr2_sys__Statvfs_wchar(): info.free < info.available\n");
1620 p_tr2_sys__Statvfs(&info, NULL);
1621 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1622 0, wine_dbgstr_longlong(info.available));
1623 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1624 0, wine_dbgstr_longlong(info.capacity));
1625 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1626 0, wine_dbgstr_longlong(info.free));
1628 p_tr2_sys__Statvfs(&info, "not_exist");
1629 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1630 0, wine_dbgstr_longlong(info.available));
1631 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1632 0, wine_dbgstr_longlong(info.capacity));
1633 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1634 0, wine_dbgstr_longlong(info.free));
1637 static void test_tr2_sys__Stat(void)
1639 int i, err_code, ret;
1640 HANDLE file;
1641 enum file_type val;
1642 struct {
1643 char const *path;
1644 enum file_type ret;
1645 int err_code;
1646 int is_todo;
1647 } tests[] = {
1648 { NULL, status_unknown, ERROR_INVALID_PARAMETER, FALSE },
1649 { "tr2_test_dir", directory_file, ERROR_SUCCESS, FALSE },
1650 { "tr2_test_dir\\f1", regular_file, ERROR_SUCCESS, FALSE },
1651 { "tr2_test_dir\\not_exist_file ", file_not_found, ERROR_SUCCESS, FALSE },
1652 { "tr2_test_dir\\??invalid_name>>", file_not_found, ERROR_SUCCESS, FALSE },
1653 { "tr2_test_dir\\f1_link" , regular_file, ERROR_SUCCESS, TRUE },
1654 { "tr2_test_dir\\dir_link", directory_file, ERROR_SUCCESS, TRUE },
1656 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r',0};
1657 WCHAR testW2[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
1659 CreateDirectoryA("tr2_test_dir", NULL);
1660 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1661 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1662 ok(CloseHandle(file), "CloseHandle\n");
1663 SetLastError(0xdeadbeef);
1664 ret = pCreateSymbolicLinkA ? pCreateSymbolicLinkA("tr2_test_dir/f1_link", "tr2_test_dir/f1", 0) : FALSE;
1665 if(!ret && (!pCreateSymbolicLinkA || GetLastError()==ERROR_PRIVILEGE_NOT_HELD||GetLastError()==ERROR_INVALID_FUNCTION)) {
1666 tests[5].ret = tests[6].ret = file_not_found;
1667 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1668 }else {
1669 ok(ret, "CreateSymbolicLinkA failed\n");
1670 ok(pCreateSymbolicLinkA("tr2_test_dir/dir_link", "tr2_test_dir", 1), "CreateSymbolicLinkA failed\n");
1673 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1674 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
1675 NMPWAIT_USE_DEFAULT_WAIT, NULL);
1676 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1677 err_code = 0xdeadbeef;
1678 val = p_tr2_sys__Stat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1679 todo_wine ok(regular_file == val, "tr2_sys__Stat(): expect: regular_file, got %d\n", val);
1680 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Stat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
1681 err_code = 0xdeadbeef;
1682 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1683 ok(status_unknown == val, "tr2_sys__Lstat(): expect: status_unknown, got %d\n", val);
1684 todo_wine ok(ERROR_PIPE_BUSY == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_PIPE_BUSY, got %d\n", err_code);
1685 ok(CloseHandle(file), "CloseHandle\n");
1686 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1687 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
1688 NMPWAIT_USE_DEFAULT_WAIT, NULL);
1689 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1690 err_code = 0xdeadbeef;
1691 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1692 todo_wine ok(regular_file == val, "tr2_sys__Lstat(): expect: regular_file, got %d\n", val);
1693 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
1694 ok(CloseHandle(file), "CloseHandle\n");
1696 for(i=0; i<ARRAY_SIZE(tests); i++) {
1697 err_code = 0xdeadbeef;
1698 val = p_tr2_sys__Stat(tests[i].path, &err_code);
1699 todo_wine_if(tests[i].is_todo)
1700 ok(tests[i].ret == val, "tr2_sys__Stat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1701 ok(tests[i].err_code == err_code, "tr2_sys__Stat(): test %d err_code expect: %d, got %d\n",
1702 i+1, tests[i].err_code, err_code);
1704 /* test tr2_sys__Lstat */
1705 err_code = 0xdeadbeef;
1706 val = p_tr2_sys__Lstat(tests[i].path, &err_code);
1707 todo_wine_if(tests[i].is_todo)
1708 ok(tests[i].ret == val, "tr2_sys__Lstat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1709 ok(tests[i].err_code == err_code, "tr2_sys__Lstat(): test %d err_code expect: %d, got %d\n",
1710 i+1, tests[i].err_code, err_code);
1713 err_code = 0xdeadbeef;
1714 val = p_tr2_sys__Stat_wchar(testW, &err_code);
1715 ok(directory_file == val, "tr2_sys__Stat_wchar() expect directory_file, got %d\n", val);
1716 ok(ERROR_SUCCESS == err_code, "tr2_sys__Stat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code);
1717 err_code = 0xdeadbeef;
1718 val = p_tr2_sys__Lstat_wchar(testW2, &err_code);
1719 ok(regular_file == val, "tr2_sys__Lstat_wchar() expect regular_file, got %d\n", val);
1720 ok(ERROR_SUCCESS == err_code, "tr2_sys__Lstat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code);
1722 if(ret) {
1723 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1724 todo_wine ok(RemoveDirectoryA("tr2_test_dir/dir_link"), "expect tr2_test_dir/dir_link to exist\n");
1726 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1727 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1730 static void test_tr2_sys__Last_write_time(void)
1732 HANDLE file;
1733 int ret;
1734 __int64 last_write_time, newtime;
1735 static const WCHAR fileW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
1736 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1737 ok(ret == 1, "tr2_sys__Make_dir() expect 1 got %d\n", ret);
1739 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1740 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1741 CloseHandle(file);
1743 last_write_time = p_tr2_sys__Last_write_time("tr2_test_dir/f1");
1744 newtime = p_tr2_sys__Last_write_time_wchar(fileW);
1745 ok(last_write_time == newtime, "last_write_time = %s, newtime = %s\n",
1746 wine_dbgstr_longlong(last_write_time), wine_dbgstr_longlong(newtime));
1747 newtime = last_write_time + 123456789;
1748 p_tr2_sys__Last_write_time_set("tr2_test_dir/f1", newtime);
1749 todo_wine ok(last_write_time == p_tr2_sys__Last_write_time("tr2_test_dir/f1"),
1750 "last_write_time should have changed: %s\n",
1751 wine_dbgstr_longlong(last_write_time));
1753 errno = 0xdeadbeef;
1754 last_write_time = p_tr2_sys__Last_write_time("not_exist");
1755 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1756 ok(last_write_time == 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time));
1757 last_write_time = p_tr2_sys__Last_write_time(NULL);
1758 ok(last_write_time == 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time));
1760 p_tr2_sys__Last_write_time_set("not_exist", newtime);
1761 errno = 0xdeadbeef;
1762 p_tr2_sys__Last_write_time_set(NULL, newtime);
1763 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1765 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1766 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1767 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1770 static void test_tr2_sys__dir_operation(void)
1772 char *file_name, first_file_name[MAX_PATH], dest[MAX_PATH], longer_path[MAX_PATH];
1773 HANDLE file, result_handle;
1774 enum file_type type;
1775 int err, num_of_f1 = 0, num_of_f2 = 0, num_of_sub_dir = 0, num_of_other_files = 0;
1777 CreateDirectoryA("tr2_test_dir", NULL);
1778 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1779 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1780 CloseHandle(file);
1781 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1782 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1783 CloseHandle(file);
1784 CreateDirectoryA("tr2_test_dir/sub_dir", NULL);
1785 file = CreateFileA("tr2_test_dir/sub_dir/sub_f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1786 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1787 CloseHandle(file);
1789 memset(longer_path, 0, MAX_PATH);
1790 GetCurrentDirectoryA(MAX_PATH, longer_path);
1791 strcat(longer_path, "\\tr2_test_dir\\");
1792 while(lstrlenA(longer_path) < MAX_PATH-1)
1793 strcat(longer_path, "s");
1794 ok(lstrlenA(longer_path) == MAX_PATH-1, "tr2_sys__Open_dir(): expect MAX_PATH, got %d\n", lstrlenA(longer_path));
1795 memset(first_file_name, 0, MAX_PATH);
1796 type = err = 0xdeadbeef;
1797 result_handle = NULL;
1798 result_handle = p_tr2_sys__Open_dir(first_file_name, longer_path, &err, &type);
1799 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect NULL, got %p\n", result_handle);
1800 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1801 ok(err == ERROR_BAD_PATHNAME, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1802 ok((int)type == 0xdeadbeef, "tr2_sys__Open_dir(): expect 0xdeadbeef, got %d\n", type);
1804 memset(first_file_name, 0, MAX_PATH);
1805 memset(dest, 0, MAX_PATH);
1806 err = type = 0xdeadbeef;
1807 result_handle = NULL;
1808 result_handle = p_tr2_sys__Open_dir(first_file_name, "tr2_test_dir", &err, &type);
1809 ok(result_handle != NULL, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle);
1810 ok(err == ERROR_SUCCESS, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1811 file_name = first_file_name;
1812 while(*file_name) {
1813 if (!strcmp(file_name, "f1")) {
1814 ++num_of_f1;
1815 ok(type == regular_file, "expect regular_file, got %d\n", type);
1816 }else if(!strcmp(file_name, "f2")) {
1817 ++num_of_f2;
1818 ok(type == regular_file, "expect regular_file, got %d\n", type);
1819 }else if(!strcmp(file_name, "sub_dir")) {
1820 ++num_of_sub_dir;
1821 ok(type == directory_file, "expect directory_file, got %d\n", type);
1822 }else {
1823 ++num_of_other_files;
1825 file_name = p_tr2_sys__Read_dir(dest, result_handle, &type);
1827 ok(type == status_unknown, "p_tr2_sys__Read_dir(): expect: status_unknown, got %d\n", type);
1828 p_tr2_sys__Close_dir(result_handle);
1829 ok(result_handle != NULL, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle);
1830 ok(num_of_f1 == 1, "found f1 %d times\n", num_of_f1);
1831 ok(num_of_f2 == 1, "found f2 %d times\n", num_of_f2);
1832 ok(num_of_sub_dir == 1, "found sub_dir %d times\n", num_of_sub_dir);
1833 ok(num_of_other_files == 0, "found %d other files\n", num_of_other_files);
1835 memset(first_file_name, 0, MAX_PATH);
1836 err = type = 0xdeadbeef;
1837 result_handle = file;
1838 result_handle = p_tr2_sys__Open_dir(first_file_name, "not_exist", &err, &type);
1839 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1840 todo_wine ok(err == ERROR_BAD_PATHNAME, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1841 ok((int)type == 0xdeadbeef, "tr2_sys__Open_dir(): expect: 0xdeadbeef, got %d\n", type);
1842 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1844 CreateDirectoryA("empty_dir", NULL);
1845 memset(first_file_name, 0, MAX_PATH);
1846 err = type = 0xdeadbeef;
1847 result_handle = file;
1848 result_handle = p_tr2_sys__Open_dir(first_file_name, "empty_dir", &err, &type);
1849 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1850 ok(err == ERROR_SUCCESS, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1851 ok(type == status_unknown, "tr2_sys__Open_dir(): expect: status_unknown, got %d\n", type);
1852 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1853 p_tr2_sys__Close_dir(result_handle);
1854 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1856 ok(RemoveDirectoryA("empty_dir"), "expect empty_dir to exist\n");
1857 ok(DeleteFileA("tr2_test_dir/sub_dir/sub_f1"), "expect tr2_test_dir/sub_dir/sub_f1 to exist\n");
1858 ok(RemoveDirectoryA("tr2_test_dir/sub_dir"), "expect tr2_test_dir/sub_dir to exist\n");
1859 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1860 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1861 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1864 static void test_tr2_sys__Link(void)
1866 int ret, i;
1867 HANDLE file, h1, h2;
1868 BY_HANDLE_FILE_INFORMATION info1, info2;
1869 char temp_path[MAX_PATH], current_path[MAX_PATH];
1870 LARGE_INTEGER file_size;
1871 struct {
1872 char const *existing_path;
1873 char const *new_path;
1874 MSVCP_bool fail_if_exists;
1875 int last_error;
1876 } tests[] = {
1877 { "f1", "f1_link", TRUE, ERROR_SUCCESS },
1878 { "f1", "tr2_test_dir\\f1_link", TRUE, ERROR_SUCCESS },
1879 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", TRUE, ERROR_SUCCESS },
1880 { "tr2_test_dir", "dir_link", TRUE, ERROR_ACCESS_DENIED },
1881 { NULL, "NULL_link", TRUE, ERROR_INVALID_PARAMETER },
1882 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER },
1883 { "not_exist", "not_exist_link", TRUE, ERROR_FILE_NOT_FOUND },
1884 { "f1", "not_exist_dir\\f1_link", TRUE, ERROR_PATH_NOT_FOUND }
1887 memset(current_path, 0, MAX_PATH);
1888 GetCurrentDirectoryA(MAX_PATH, current_path);
1889 memset(temp_path, 0, MAX_PATH);
1890 GetTempPathA(MAX_PATH, temp_path);
1891 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1893 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1894 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1895 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1896 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1897 file_size.QuadPart = 7;
1898 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1899 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1900 CloseHandle(file);
1902 for(i=0; i<ARRAY_SIZE(tests); i++) {
1903 errno = 0xdeadbeef;
1904 ret = p_tr2_sys__Link(tests[i].existing_path, tests[i].new_path);
1905 ok(ret == tests[i].last_error, "tr2_sys__Link(): test %d expect: %d, got %d\n",
1906 i+1, tests[i].last_error, ret);
1907 ok(errno == 0xdeadbeef, "tr2_sys__Link(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1908 if(ret == ERROR_SUCCESS)
1909 ok(p_tr2_sys__File_size(tests[i].existing_path) == p_tr2_sys__File_size(tests[i].new_path),
1910 "tr2_sys__Link(): test %d failed, two files' size are not equal\n", i+1);
1913 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1914 ok(p_tr2_sys__File_size("f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link") &&
1915 p_tr2_sys__File_size("tr2_test_dir/f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link_link"),
1916 "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")));
1917 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")));
1919 file = CreateFileA("f1_link", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1920 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1921 file_size.QuadPart = 20;
1922 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1923 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1924 CloseHandle(file);
1925 h1 = CreateFileA("f1_link", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1926 NULL, OPEN_EXISTING, 0, 0);
1927 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1928 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1929 CloseHandle(h1);
1930 h2 = CreateFileA("tr2_test_dir/f1_link", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1931 NULL, OPEN_EXISTING, 0, 0);
1932 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1933 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1934 CloseHandle(h2);
1935 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1936 && info1.nFileIndexLow == info2.nFileIndexLow,
1937 "tr2_sys__Link(): test %d expect two files equivalent\n", i+1);
1938 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")));
1940 ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1941 ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1942 ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1943 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1944 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1945 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1948 static void test_tr2_sys__Symlink(void)
1950 int ret, i;
1951 HANDLE file;
1952 LARGE_INTEGER file_size;
1953 struct {
1954 char const *existing_path;
1955 char const *new_path;
1956 int last_error;
1957 MSVCP_bool is_todo;
1958 } tests[] = {
1959 { "f1", "f1_link", ERROR_SUCCESS, FALSE },
1960 { "f1", "tr2_test_dir\\f1_link", ERROR_SUCCESS, FALSE },
1961 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", ERROR_SUCCESS, FALSE },
1962 { "tr2_test_dir", "dir_link", ERROR_SUCCESS, FALSE },
1963 { NULL, "NULL_link", ERROR_INVALID_PARAMETER, FALSE },
1964 { "f1", NULL, ERROR_INVALID_PARAMETER, FALSE },
1965 { "not_exist", "not_exist_link", ERROR_SUCCESS, FALSE },
1966 { "f1", "not_exist_dir\\f1_link", ERROR_PATH_NOT_FOUND, TRUE }
1969 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1970 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1971 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1972 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1973 file_size.QuadPart = 7;
1974 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1975 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1976 CloseHandle(file);
1978 for(i=0; i<ARRAY_SIZE(tests); i++) {
1979 errno = 0xdeadbeef;
1980 SetLastError(0xdeadbeef);
1981 ret = p_tr2_sys__Symlink(tests[i].existing_path, tests[i].new_path);
1982 if(!i && (ret==ERROR_PRIVILEGE_NOT_HELD || ret==ERROR_INVALID_FUNCTION || ret==ERROR_CALL_NOT_IMPLEMENTED)) {
1983 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1984 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1985 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1986 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1987 return;
1990 ok(errno == 0xdeadbeef, "tr2_sys__Symlink(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1991 todo_wine_if(tests[i].is_todo)
1992 ok(ret == tests[i].last_error, "tr2_sys__Symlink(): test %d expect: %d, got %d\n", i+1, tests[i].last_error, ret);
1993 if(ret == ERROR_SUCCESS)
1994 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)));
1997 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1998 todo_wine ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1999 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
2000 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
2001 todo_wine ok(DeleteFileA("not_exist_link"), "expect not_exist_link to exist\n");
2002 todo_wine ok(DeleteFileA("dir_link"), "expect dir_link to exist\n");
2003 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
2004 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
2007 static void test_tr2_sys__Unlink(void)
2009 char temp_path[MAX_PATH], current_path[MAX_PATH];
2010 int ret, i;
2011 HANDLE file;
2012 LARGE_INTEGER file_size;
2013 struct {
2014 char const *path;
2015 int last_error;
2016 MSVCP_bool is_todo;
2017 } tests[] = {
2018 { "tr2_test_dir\\f1_symlink", ERROR_SUCCESS, TRUE },
2019 { "tr2_test_dir\\f1_link", ERROR_SUCCESS, FALSE },
2020 { "tr2_test_dir\\f1", ERROR_SUCCESS, FALSE },
2021 { "tr2_test_dir", ERROR_ACCESS_DENIED, FALSE },
2022 { "not_exist", ERROR_FILE_NOT_FOUND, FALSE },
2023 { "not_exist_dir\\not_exist_file", ERROR_PATH_NOT_FOUND, FALSE },
2024 { NULL, ERROR_PATH_NOT_FOUND, FALSE }
2027 GetCurrentDirectoryA(MAX_PATH, current_path);
2028 GetTempPathA(MAX_PATH, temp_path);
2029 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
2031 ret = p_tr2_sys__Make_dir("tr2_test_dir");
2032 ok(ret == 1, "tr2_sys__Make_dir(): expect 1 got %d\n", ret);
2033 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2034 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
2035 file_size.QuadPart = 7;
2036 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
2037 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
2038 CloseHandle(file);
2040 ret = p_tr2_sys__Symlink("tr2_test_dir/f1", "tr2_test_dir/f1_symlink");
2041 if(ret==ERROR_PRIVILEGE_NOT_HELD || ret==ERROR_INVALID_FUNCTION || ret==ERROR_CALL_NOT_IMPLEMENTED) {
2042 tests[0].last_error = ERROR_FILE_NOT_FOUND;
2043 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
2044 }else {
2045 ok(ret == ERROR_SUCCESS, "tr2_sys__Symlink(): expect: ERROR_SUCCESS, got %d\n", ret);
2047 ret = p_tr2_sys__Link("tr2_test_dir/f1", "tr2_test_dir/f1_link");
2048 ok(ret == ERROR_SUCCESS, "tr2_sys__Link(): expect: ERROR_SUCCESS, got %d\n", ret);
2050 for(i=0; i<ARRAY_SIZE(tests); i++) {
2051 errno = 0xdeadbeef;
2052 ret = p_tr2_sys__Unlink(tests[i].path);
2053 todo_wine_if(tests[i].is_todo)
2054 ok(ret == tests[i].last_error, "tr2_sys__Unlink(): test %d expect: %d, got %d\n",
2055 i+1, tests[i].last_error, ret);
2056 ok(errno == 0xdeadbeef, "tr2_sys__Unlink(): test %d errno expect: 0xdeadbeef, got %d\n", i+1, ret);
2059 ok(!DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 not to exist\n");
2060 ok(!DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link not to exist\n");
2061 ok(!DeleteFileA("tr2_test_dir/f1_symlink"), "expect tr2_test_dir/f1_symlink not to exist\n");
2062 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
2063 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
2065 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
2068 static int __cdecl thrd_thread(void *arg)
2070 _Thrd_t *thr = arg;
2072 if(thr)
2073 *thr = p__Thrd_current();
2074 return 0x42;
2077 static void test_thrd(void)
2079 int ret, i, r;
2080 struct test {
2081 _Thrd_t a;
2082 _Thrd_t b;
2083 int r;
2085 const HANDLE hnd1 = (HANDLE)0xcccccccc;
2086 const HANDLE hnd2 = (HANDLE)0xdeadbeef;
2087 xtime xt, before, after;
2088 MSVCRT_long diff;
2089 _Thrd_t ta, tb;
2091 struct test testeq[] = {
2092 { {0, 0}, {0, 0}, 1 },
2093 { {0, 1}, {0, 0}, 0 },
2094 { {hnd1, 0}, {hnd1, 1}, 0 },
2095 { {hnd1, 0}, {hnd2, 0}, 1 }
2098 struct test testlt[] = {
2099 { {0, 0}, {0, 0}, 0 },
2100 { {0, 0}, {0, 1}, 1 },
2101 { {0, 1}, {0, 0}, 0 },
2102 { {hnd1, 0}, {hnd2, 0}, 0 },
2103 { {hnd1, 0}, {hnd2, 1}, 1 }
2106 /* test for equal */
2107 for(i=0; i<ARRAY_SIZE(testeq); i++) {
2108 ret = p__Thrd_equal(testeq[i].a, testeq[i].b);
2109 ok(ret == testeq[i].r, "(%p %u) = (%p %u) expected %d, got %d\n",
2110 testeq[i].a.hnd, testeq[i].a.id, testeq[i].b.hnd, testeq[i].b.id, testeq[i].r, ret);
2113 /* test for less than */
2114 for(i=0; i<ARRAY_SIZE(testlt); i++) {
2115 ret = p__Thrd_lt(testlt[i].a, testlt[i].b);
2116 ok(ret == testlt[i].r, "(%p %u) < (%p %u) expected %d, got %d\n",
2117 testlt[i].a.hnd, testlt[i].a.id, testlt[i].b.hnd, testlt[i].b.id, testlt[i].r, ret);
2120 /* test for sleep */
2121 if (0) /* crash on Windows */
2122 p__Thrd_sleep(NULL);
2123 p_xtime_get(&xt, 1);
2124 xt.sec += 2;
2125 p_xtime_get(&before, 1);
2126 p__Thrd_sleep(&xt);
2127 p_xtime_get(&after, 1);
2128 diff = p__Xtime_diff_to_millis2(&after, &before);
2129 ok(diff > 2000 - TIMEDELTA, "got %d\n", diff);
2131 /* test for current */
2132 ta = p__Thrd_current();
2133 tb = p__Thrd_current();
2134 ok(ta.id == tb.id, "got a %d b %d\n", ta.id, tb.id);
2135 ok(ta.id == GetCurrentThreadId(), "expected %d, got %d\n", GetCurrentThreadId(), ta.id);
2136 /* these can be different if new threads are created at same time */
2137 ok(ta.hnd == tb.hnd, "got a %p b %p\n", ta.hnd, tb.hnd);
2138 ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd);
2139 ok(!CloseHandle(tb.hnd), "handle %p not closed\n", tb.hnd);
2141 /* test for create/join */
2142 if (0) /* crash on Windows */
2144 p__Thrd_create(NULL, thrd_thread, NULL);
2145 p__Thrd_create(&ta, NULL, NULL);
2147 r = -1;
2148 ret = p__Thrd_create(&ta, thrd_thread, (void*)&tb);
2149 ok(!ret, "failed to create thread, got %d\n", ret);
2150 ret = p__Thrd_join(ta, &r);
2151 ok(!ret, "failed to join thread, got %d\n", ret);
2152 ok(ta.id == tb.id, "expected %d, got %d\n", ta.id, tb.id);
2153 ok(ta.hnd != tb.hnd, "same handles, got %p\n", ta.hnd);
2154 ok(r == 0x42, "expected 0x42, got %d\n", r);
2155 ret = p__Thrd_detach(ta);
2156 ok(ret == 4, "_Thrd_detach should have failed with error 4, got %d\n", ret);
2158 ret = p__Thrd_create(&ta, thrd_thread, NULL);
2159 ok(!ret, "failed to create thread, got %d\n", ret);
2160 ret = p__Thrd_detach(ta);
2161 ok(!ret, "_Thrd_detach failed, got %d\n", ret);
2165 #define NUM_THREADS 10
2166 struct cndmtx
2168 HANDLE initialized;
2169 int started;
2170 int thread_no;
2172 _Cnd_t cnd;
2173 _Mtx_t mtx;
2174 BOOL timed_wait;
2177 static int __cdecl cnd_wait_thread(void *arg)
2179 struct cndmtx *cm = arg;
2180 int r;
2182 p__Mtx_lock(&cm->mtx);
2184 if(InterlockedIncrement(&cm->started) == cm->thread_no)
2185 SetEvent(cm->initialized);
2187 if(cm->timed_wait) {
2188 xtime xt;
2190 p_xtime_get(&xt, 1);
2191 xt.sec += 2;
2192 r = p__Cnd_timedwait(&cm->cnd, &cm->mtx, &xt);
2193 ok(!r, "timed wait failed\n");
2194 } else {
2195 r = p__Cnd_wait(&cm->cnd, &cm->mtx);
2196 ok(!r, "wait failed\n");
2199 p__Mtx_unlock(&cm->mtx);
2200 return 0;
2203 static void test_cnd(void)
2205 _Thrd_t threads[NUM_THREADS];
2206 xtime xt, before, after;
2207 MSVCRT_long diff;
2208 struct cndmtx cm;
2209 _Cnd_t cnd;
2210 _Mtx_t mtx;
2211 int r, i;
2213 r = p__Cnd_init(&cnd);
2214 ok(!r, "failed to init cnd\n");
2216 r = p__Mtx_init(&mtx, 0);
2217 ok(!r, "failed to init mtx\n");
2219 if (0) /* crash on Windows */
2221 p__Cnd_init(NULL);
2222 p__Cnd_wait(NULL, &mtx);
2223 p__Cnd_wait(&cnd, NULL);
2224 p__Cnd_timedwait(NULL, &mtx, &xt);
2225 p__Cnd_timedwait(&cnd, &mtx, &xt);
2227 p__Cnd_destroy(NULL);
2229 /* test _Cnd_signal/_Cnd_wait */
2230 cm.initialized = CreateEventW(NULL, FALSE, FALSE, NULL);
2231 cm.started = 0;
2232 cm.thread_no = 1;
2233 cm.cnd = cnd;
2234 cm.mtx = mtx;
2235 cm.timed_wait = FALSE;
2236 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2238 WaitForSingleObject(cm.initialized, INFINITE);
2239 p__Mtx_lock(&mtx);
2240 p__Mtx_unlock(&mtx);
2242 r = p__Cnd_signal(&cm.cnd);
2243 ok(!r, "failed to signal\n");
2244 p__Thrd_join(threads[0], NULL);
2246 /* test _Cnd_timedwait time out */
2247 p__Mtx_lock(&mtx);
2248 p_xtime_get(&before, 1);
2249 xt = before;
2250 xt.sec += 1;
2251 r = p__Cnd_timedwait(&cnd, &mtx, &xt);
2252 p_xtime_get(&after, 1);
2253 p__Mtx_unlock(&mtx);
2255 diff = p__Xtime_diff_to_millis2(&after, &before);
2256 ok(r == 2, "should have timed out\n");
2257 ok(diff > 1000 - TIMEDELTA, "got %d\n", diff);
2259 /* test _Cnd_timedwait */
2260 cm.started = 0;
2261 cm.timed_wait = TRUE;
2262 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2264 WaitForSingleObject(cm.initialized, INFINITE);
2265 p__Mtx_lock(&mtx);
2266 p__Mtx_unlock(&mtx);
2268 r = p__Cnd_signal(&cm.cnd);
2269 ok(!r, "failed to signal\n");
2270 p__Thrd_join(threads[0], NULL);
2272 /* test _Cnd_do_broadcast_at_thread_exit */
2273 cm.started = 0;
2274 cm.timed_wait = FALSE;
2275 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2277 WaitForSingleObject(cm.initialized, INFINITE);
2278 p__Mtx_lock(&mtx);
2280 r = 0xcafe;
2281 p__Cnd_unregister_at_thread_exit((_Mtx_t*)0xdeadbeef);
2282 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2283 ok(r == 0xcafe, "r = %x\n", r);
2284 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2285 p__Cnd_unregister_at_thread_exit(&mtx);
2286 p__Cnd_do_broadcast_at_thread_exit();
2287 ok(mtx->count == 1, "mtx.count = %d\n", mtx->count);
2289 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2290 ok(r == 0xcafe, "r = %x\n", r);
2292 p__Cnd_do_broadcast_at_thread_exit();
2293 ok(r == 1, "r = %x\n", r);
2294 p__Thrd_join(threads[0], NULL);
2296 /* crash if _Cnd_do_broadcast_at_thread_exit is called on exit */
2297 p__Cnd_register_at_thread_exit((_Cnd_t*)0xdeadbeef, (_Mtx_t*)0xdeadbeef, (int*)0xdeadbeef);
2299 /* test _Cnd_broadcast */
2300 cm.started = 0;
2301 cm.thread_no = NUM_THREADS;
2303 for(i = 0; i < cm.thread_no; i++)
2304 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
2306 WaitForSingleObject(cm.initialized, INFINITE);
2307 p__Mtx_lock(&mtx);
2308 p__Mtx_unlock(&mtx);
2310 r = p__Cnd_broadcast(&cnd);
2311 ok(!r, "failed to broadcast\n");
2312 for(i = 0; i < cm.thread_no; i++)
2313 p__Thrd_join(threads[i], NULL);
2315 /* test broadcast with _Cnd_destroy */
2316 cm.started = 0;
2317 for(i = 0; i < cm.thread_no; i++)
2318 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
2320 WaitForSingleObject(cm.initialized, INFINITE);
2321 p__Mtx_lock(&mtx);
2322 p__Mtx_unlock(&mtx);
2324 p__Cnd_destroy(&cnd);
2325 for(i = 0; i < cm.thread_no; i++)
2326 p__Thrd_join(threads[i], NULL);
2328 p__Mtx_destroy(&mtx);
2329 CloseHandle(cm.initialized);
2332 static struct {
2333 int value[2];
2334 const char* export_name;
2335 } vbtable_size_exports_list[] = {
2336 {{0x20, 0x20}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"},
2337 {{0x10, 0x10}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"},
2338 {{0x20, 0x20}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"},
2339 {{0x10, 0x10}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"},
2340 {{0x20, 0x20}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"},
2341 {{0x10, 0x10}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"},
2342 {{0x18, 0x18}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"},
2343 {{0x18, 0x18}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"},
2344 {{0x18, 0x18}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"},
2345 {{ 0x8, 0x10}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"},
2346 {{ 0x8, 0x10}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"},
2347 {{ 0x8, 0x10}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"},
2348 {{ 0x0, 0x0}, 0}
2351 static void test_vbtable_size_exports(void)
2353 int i;
2354 const int *p_vbtable;
2355 int arch_idx = (sizeof(void*) == 8);
2357 for (i = 0; vbtable_size_exports_list[i].export_name; i++)
2359 SET(p_vbtable, vbtable_size_exports_list[i].export_name);
2361 ok(p_vbtable[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable[0]);
2362 ok(p_vbtable[1] == vbtable_size_exports_list[i].value[arch_idx],
2363 "%d: %s[1] wrong, got 0x%x\n", i, vbtable_size_exports_list[i].export_name, p_vbtable[1]);
2367 HANDLE _Pad__Launch_returned;
2368 _Pad pad;
2369 #ifdef __i386__
2370 /* TODO: this should be a __thiscall function */
2371 static unsigned int __stdcall vtbl_func__Go(void)
2372 #else
2373 static unsigned int __cdecl vtbl_func__Go(_Pad *this)
2374 #endif
2376 DWORD ret;
2378 ret = WaitForSingleObject(_Pad__Launch_returned, 100);
2379 ok(ret == WAIT_TIMEOUT, "WiatForSingleObject returned %x\n", ret);
2380 ok(!pad.mtx->count, "pad.mtx.count = %d\n", pad.mtx->count);
2381 ok(!pad.launched, "pad.launched = %x\n", pad.launched);
2382 call_func1(p__Pad__Release, &pad);
2383 ok(pad.launched, "pad.launched = %x\n", pad.launched);
2384 ret = WaitForSingleObject(_Pad__Launch_returned, 100);
2385 ok(ret == WAIT_OBJECT_0, "WiatForSingleObject returned %x\n", ret);
2386 ok(pad.mtx->count == 1, "pad.mtx.count = %d\n", pad.mtx->count);
2387 return 0;
2390 static void test__Pad(void)
2392 _Pad pad_copy;
2393 _Thrd_t thrd;
2394 vtable_ptr pfunc = (vtable_ptr)&vtbl_func__Go;
2396 _Pad__Launch_returned = CreateEventW(NULL, FALSE, FALSE, NULL);
2398 pad.vtable = (void*)1;
2399 pad.cnd = (void*)2;
2400 pad.mtx = (void*)3;
2401 pad.launched = TRUE;
2402 memset(&pad_copy, 0, sizeof(pad_copy));
2403 call_func2(p__Pad_copy_ctor, &pad_copy, &pad);
2404 ok(pad_copy.vtable != (void*)1, "pad_copy.vtable was not set\n");
2405 ok(pad_copy.cnd == (void*)2, "pad_copy.cnd = %p\n", pad_copy.cnd);
2406 ok(pad_copy.mtx == (void*)3, "pad_copy.mtx = %p\n", pad_copy.mtx);
2407 ok(pad_copy.launched, "pad_copy.launched = %x\n", pad_copy.launched);
2409 memset(&pad_copy, 0xde, sizeof(pad_copy));
2410 pad_copy.vtable = (void*)4;
2411 pad_copy.cnd = (void*)5;
2412 pad_copy.mtx = (void*)6;
2413 pad_copy.launched = FALSE;
2414 call_func2(p__Pad_op_assign, &pad_copy, &pad);
2415 ok(pad_copy.vtable == (void*)4, "pad_copy.vtable was set\n");
2416 ok(pad_copy.cnd == (void*)2, "pad_copy.cnd = %p\n", pad_copy.cnd);
2417 ok(pad_copy.mtx == (void*)3, "pad_copy.mtx = %p\n", pad_copy.mtx);
2418 ok(pad_copy.launched, "pad_copy.launched = %x\n", pad_copy.launched);
2420 call_func1(p__Pad_ctor, &pad);
2421 call_func2(p__Pad_copy_ctor, &pad_copy, &pad);
2422 ok(pad.vtable == pad_copy.vtable, "pad.vtable = %p, pad_copy.vtable = %p\n", pad.vtable, pad_copy.vtable);
2423 ok(pad.cnd == pad_copy.cnd, "pad.cnd = %p, pad_copy.cnd = %p\n", pad.cnd, pad_copy.cnd);
2424 ok(pad.mtx == pad_copy.mtx, "pad.mtx = %p, pad_copy.mtx = %p\n", pad.mtx, pad_copy.mtx);
2425 ok(pad.launched == pad_copy.launched, "pad.launched = %x, pad_copy.launched = %x\n", pad.launched, pad_copy.launched);
2426 call_func1(p__Pad_dtor, &pad);
2427 /* call_func1(p__Pad_dtor, &pad_copy); - copy constructor is broken, this causes a crash */
2429 memset(&pad, 0xfe, sizeof(pad));
2430 call_func1(p__Pad_ctor, &pad);
2431 ok(!pad.launched, "pad.launched = %x\n", pad.launched);
2432 ok(pad.mtx->count == 1, "pad.mtx.count = %d\n", pad.mtx->count);
2434 pad.vtable = &pfunc;
2435 call_func2(p__Pad__Launch, &pad, &thrd);
2436 SetEvent(_Pad__Launch_returned);
2437 ok(!p__Thrd_join(thrd, NULL), "_Thrd_join failed\n");
2439 call_func1(p__Pad_dtor, &pad);
2440 CloseHandle(_Pad__Launch_returned);
2443 static void test_threads__Mtx(void)
2445 void *mtx = NULL;
2447 p_threads__Mtx_new(&mtx);
2448 ok(mtx != NULL, "mtx == NULL\n");
2450 p_threads__Mtx_lock(mtx);
2451 p_threads__Mtx_lock(mtx);
2452 p_threads__Mtx_unlock(mtx);
2453 p_threads__Mtx_unlock(mtx);
2454 p_threads__Mtx_unlock(mtx);
2456 p_threads__Mtx_delete(mtx);
2459 static void test_vector_base_v4__Segment_index_of(void)
2461 size_t i;
2462 size_t ret;
2463 struct {
2464 size_t x;
2465 size_t expect;
2466 } tests[] = {
2467 {0, 0},
2468 {1, 0},
2469 {2, 1},
2470 {3, 1},
2471 {4, 2},
2472 {7, 2},
2473 {8, 3},
2474 {15, 3},
2475 {16, 4},
2476 {31, 4},
2477 {32, 5},
2478 {~0, 8*sizeof(void*)-1}
2481 for(i=0; i<ARRAY_SIZE(tests); i++) {
2482 ret = p_vector_base_v4__Segment_index_of(tests[i].x);
2483 ok(ret == tests[i].expect, "expected %ld, got %ld for %ld\n",
2484 (long)tests[i].expect, (long)ret, (long)tests[i].x);
2488 static HANDLE block_start, block_end;
2489 static BOOL block;
2491 static void __thiscall queue_char__Move_item(
2492 #ifndef __i386__
2493 queue_base_v4 *this,
2494 #endif
2495 _Page *dst, size_t idx, void *src)
2497 CHECK_EXPECT(queue_char__Move_item);
2498 if(block) {
2499 block = FALSE;
2500 SetEvent(block_start);
2501 WaitForSingleObject(block_end, INFINITE);
2503 memcpy(dst->data + idx, src, sizeof(char));
2506 static void __thiscall queue_char__Copy_item(
2507 #ifndef __i386__
2508 queue_base_v4 *this,
2509 #endif
2510 _Page *dst, size_t idx, const void *src)
2512 CHECK_EXPECT(queue_char__Copy_item);
2513 if(block) {
2514 block = FALSE;
2515 SetEvent(block_start);
2516 WaitForSingleObject(block_end, INFINITE);
2518 memcpy(dst->data + idx, src, sizeof(char));
2521 static void __thiscall queue_char__Assign_and_destroy_item(
2522 #ifndef __i386__
2523 queue_base_v4 *this,
2524 #endif
2525 void *dst, _Page *src, size_t idx)
2527 CHECK_EXPECT(queue_char__Assign_and_destroy_item);
2528 if(block) {
2529 block = FALSE;
2530 SetEvent(block_start);
2531 WaitForSingleObject(block_end, INFINITE);
2533 memcpy(dst, src->data + idx, sizeof(char));
2536 #ifndef __i386__
2537 static _Page* __thiscall queue_char__Allocate_page(queue_base_v4 *this)
2538 #else
2539 static _Page* __thiscall queue_char__Allocate_page(void)
2540 #endif
2542 CHECK_EXPECT(queue_char__Allocate_page);
2543 return malloc(sizeof(_Page) + sizeof(char[256]));
2546 static void __thiscall queue_char__Deallocate_page(
2547 #ifndef __i386__
2548 queue_base_v4 *this,
2549 #endif
2550 _Page *page)
2552 CHECK_EXPECT2(queue_char__Deallocate_page);
2553 free(page);
2556 static const void* queue_char_vtbl[] =
2558 queue_char__Move_item,
2559 queue_char__Copy_item,
2560 queue_char__Assign_and_destroy_item,
2561 NULL, /* dtor */
2562 queue_char__Allocate_page,
2563 queue_char__Deallocate_page
2566 static DWORD WINAPI queue_move_push_thread(void *arg)
2568 queue_base_v4 *queue = arg;
2569 char c = 'm';
2571 alloc_expect_struct();
2572 SET_EXPECT(queue_char__Allocate_page); /* ignore page allocations */
2573 SET_EXPECT(queue_char__Move_item);
2574 call_func2(p_queue_base_v4__Internal_move_push, queue, &c);
2575 CHECK_CALLED(queue_char__Move_item);
2576 free_expect_struct();
2577 return 0;
2580 static DWORD WINAPI queue_push_thread(void *arg)
2582 queue_base_v4 *queue = arg;
2583 char c = 'c';
2585 alloc_expect_struct();
2586 SET_EXPECT(queue_char__Copy_item);
2587 call_func2(p_queue_base_v4__Internal_push, queue, &c);
2588 CHECK_CALLED(queue_char__Copy_item);
2589 free_expect_struct();
2590 return 0;
2593 static DWORD WINAPI queue_pop_thread(void*arg)
2595 queue_base_v4 *queue = arg;
2596 char c;
2598 alloc_expect_struct();
2599 SET_EXPECT(queue_char__Assign_and_destroy_item);
2600 call_func2(p_queue_base_v4__Internal_pop_if_present, queue, &c);
2601 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2602 free_expect_struct();
2603 return 0;
2606 static void* __cdecl concurrent_vector_int_alloc(vector_base_v4 *this, size_t n)
2608 CHECK_EXPECT(concurrent_vector_int_alloc);
2609 vector_alloc_count++;
2610 return malloc(n*sizeof(int));
2613 static void __cdecl concurrent_vector_int_destroy(void *ptr, size_t n)
2615 CHECK_EXPECT2(concurrent_vector_int_destroy);
2616 ok(vector_elem_count >= n, "invalid destroy\n");
2617 vector_elem_count -= n;
2618 memset(ptr, 0xff, sizeof(int)*n);
2621 static void concurrent_vector_int_ctor(vector_base_v4 *this)
2623 memset(this, 0, sizeof(*this));
2624 this->allocator = concurrent_vector_int_alloc;
2625 this->segment = &this->storage[0];
2628 static void concurrent_vector_int_dtor(vector_base_v4 *this)
2630 size_t blocks;
2632 blocks = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2633 this, concurrent_vector_int_destroy);
2634 for(blocks--; blocks >= this->first_block; blocks--) {
2635 vector_alloc_count--;
2636 free(this->segment[blocks]);
2639 if(this->first_block) {
2640 vector_alloc_count--;
2641 free(this->segment[0]);
2644 call_func1(p_vector_base_v4_dtor, this);
2647 static void __cdecl concurrent_vector_int_copy(void *dst, const void *src, size_t n)
2649 CHECK_EXPECT2(concurrent_vector_int_copy);
2650 vector_elem_count += n;
2651 memcpy(dst, src, n*sizeof(int));
2654 static void __cdecl concurrent_vector_int_assign(void *dst, const void *src, size_t n)
2656 CHECK_EXPECT2(concurrent_vector_int_assign);
2657 memcpy(dst, src, n*sizeof(int));
2660 static void test_queue_base_v4(void)
2662 queue_base_v4 queue;
2663 HANDLE thread[2];
2664 MSVCP_bool b;
2665 size_t size;
2666 DWORD ret;
2667 int i;
2668 char c;
2670 block_start = CreateEventW(NULL, FALSE, FALSE, NULL);
2671 block_end = CreateEventW(NULL, FALSE, FALSE, NULL);
2673 call_func2(p_queue_base_v4_ctor, &queue, 0);
2674 ok(queue.data != NULL, "queue.data = NULL\n");
2675 ok(queue.alloc_count == 32, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2676 ok(queue.item_size == 0, "queue.item_size = %ld\n", (long)queue.item_size);
2677 call_func1(p_queue_base_v4_dtor, &queue);
2679 call_func2(p_queue_base_v4_ctor, &queue, 8);
2680 ok(queue.data != NULL, "queue.data = NULL\n");
2681 ok(queue.alloc_count == 32, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2682 ok(queue.item_size == 8, "queue.item_size = %ld\n", (long)queue.item_size);
2683 call_func1(p_queue_base_v4_dtor, &queue);
2685 call_func2(p_queue_base_v4_ctor, &queue, 16);
2686 ok(queue.data != NULL, "queue.data = NULL\n");
2687 ok(queue.alloc_count == 16, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2688 ok(queue.item_size == 16, "queue.item_size = %ld\n", (long)queue.item_size);
2689 b = (DWORD_PTR)call_func1(p_queue_base_v4__Internal_empty, &queue);
2690 ok(b, "queue is not empty\n");
2691 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2692 ok(!size, "size = %ld\n", (long)size);
2693 call_func1(p_queue_base_v4_dtor, &queue);
2695 call_func2(p_queue_base_v4_ctor, &queue, 1);
2696 queue.vtable = (void*)&queue_char_vtbl;
2698 for(i=0; i<8; i++) {
2699 SET_EXPECT(queue_char__Allocate_page);
2700 SET_EXPECT(queue_char__Copy_item);
2701 c = 'a'+i;
2702 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2703 CHECK_CALLED(queue_char__Allocate_page);
2704 CHECK_CALLED(queue_char__Copy_item);
2706 b = (MSVCP_bool)(DWORD_PTR)call_func1(p_queue_base_v4__Internal_empty, &queue);
2707 ok(!b, "queue is empty\n");
2708 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2709 ok(size == i+1, "size = %ld, expected %ld\n", (long)size, (long)i);
2712 SET_EXPECT(queue_char__Copy_item);
2713 c = 'a'+i;
2714 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2715 CHECK_CALLED(queue_char__Copy_item);
2717 for(i=0; i<9; i++) {
2718 SET_EXPECT(queue_char__Assign_and_destroy_item);
2719 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2720 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2721 ok(b, "pop returned false\n");
2722 ok(c == 'a'+i, "got '%c', expected '%c'\n", c, 'a'+i);
2724 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2725 ok(!b, "pop returned true\n");
2727 for(i=0; i<247; i++) {
2728 SET_EXPECT(queue_char__Copy_item);
2729 c = 'a'+i;
2730 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2731 CHECK_CALLED(queue_char__Copy_item);
2733 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2734 ok(size == i+1, "size = %ld, expected %ld\n", (long)size, (long)i);
2737 SET_EXPECT(queue_char__Allocate_page);
2738 SET_EXPECT(queue_char__Copy_item);
2739 c = 'a'+i;
2740 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2741 CHECK_CALLED(queue_char__Allocate_page);
2742 CHECK_CALLED(queue_char__Copy_item);
2744 for(i=0; i<239; i++) {
2745 SET_EXPECT(queue_char__Assign_and_destroy_item);
2746 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2747 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2748 ok(b, "pop returned false\n");
2749 ok(c == (char)('a'+i), "got '%c', expected '%c'\n", c, 'a'+i);
2752 SET_EXPECT(queue_char__Assign_and_destroy_item);
2753 SET_EXPECT(queue_char__Deallocate_page);
2754 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2755 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2756 CHECK_CALLED(queue_char__Deallocate_page);
2757 ok(b, "pop returned false\n");
2758 ok(c == (char)('a'+i), "got '%c', expected '%c'\n", c, 'a'+i);
2760 /* destructor doesn't clear the memory, _Internal_finish_clear needs to be called */
2761 SET_EXPECT(queue_char__Deallocate_page);
2762 call_func1(p_queue_base_v4__Internal_finish_clear, &queue);
2763 CHECK_CALLED(queue_char__Deallocate_page);
2765 call_func1(p_queue_base_v4_dtor, &queue);
2767 /* test parallel push */
2768 call_func2(p_queue_base_v4_ctor, &queue, 1);
2769 queue.vtable = (void*)&queue_char_vtbl;
2771 block = TRUE;
2772 thread[0] = CreateThread(NULL, 0, queue_move_push_thread, &queue, 0, NULL);
2773 WaitForSingleObject(block_start, INFINITE);
2775 c = 'a';
2776 for(i=0; i<7; i++) {
2777 SET_EXPECT(queue_char__Allocate_page);
2778 SET_EXPECT(queue_char__Copy_item);
2779 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2780 CHECK_CALLED(queue_char__Allocate_page);
2781 CHECK_CALLED(queue_char__Copy_item);
2784 thread[1] = CreateThread(NULL, 0, queue_push_thread, &queue, 0, NULL);
2785 ret = WaitForSingleObject(thread[1], 100);
2786 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", ret);
2788 SetEvent(block_end);
2789 WaitForSingleObject(thread[0], INFINITE);
2790 WaitForSingleObject(thread[1], INFINITE);
2791 CloseHandle(thread[0]);
2792 CloseHandle(thread[1]);
2794 /* test parallel pop */
2795 block = TRUE;
2796 thread[0] = CreateThread(NULL, 0, queue_pop_thread, &queue, 0, NULL);
2797 WaitForSingleObject(block_start, INFINITE);
2799 for(i=0; i<7; i++) {
2800 SET_EXPECT(queue_char__Assign_and_destroy_item);
2801 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2802 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2803 ok(b, "pop returned false\n");
2804 ok(c == 'a', "got '%c', expected 'a'\n", c);
2807 thread[1] = CreateThread(NULL, 0, queue_pop_thread, &queue, 0, NULL);
2808 ret = WaitForSingleObject(thread[1], 100);
2809 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", ret);
2811 SetEvent(block_end);
2812 WaitForSingleObject(thread[0], INFINITE);
2813 WaitForSingleObject(thread[1], INFINITE);
2814 CloseHandle(thread[0]);
2815 CloseHandle(thread[1]);
2817 /* test parallel push/pop */
2818 for(i=0; i<8; i++) {
2819 SET_EXPECT(queue_char__Copy_item);
2820 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2821 CHECK_CALLED(queue_char__Copy_item);
2824 block = TRUE;
2825 thread[0] = CreateThread(NULL, 0, queue_push_thread, &queue, 0, NULL);
2826 WaitForSingleObject(block_start, INFINITE);
2828 SET_EXPECT(queue_char__Assign_and_destroy_item);
2829 call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2830 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2832 SetEvent(block_end);
2833 WaitForSingleObject(thread[0], INFINITE);
2834 CloseHandle(thread[0]);
2836 for(i=0; i<8; i++) {
2837 SET_EXPECT(queue_char__Assign_and_destroy_item);
2838 call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2839 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2842 SET_EXPECT(queue_char__Deallocate_page);
2843 call_func1(p_queue_base_v4__Internal_finish_clear, &queue);
2844 CHECK_CALLED(queue_char__Deallocate_page);
2845 call_func1(p_queue_base_v4_dtor, &queue);
2847 CloseHandle(block_start);
2848 CloseHandle(block_end);
2851 static void test_vector_base_v4(void)
2853 vector_base_v4 vector, v2;
2854 size_t idx, size;
2855 compact_block b;
2856 int i, *data;
2858 concurrent_vector_int_ctor(&vector);
2860 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2861 ok(size == 0, "size of vector got %ld expected 0\n", (long)size);
2863 SET_EXPECT(concurrent_vector_int_alloc);
2864 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2865 if(!data) {
2866 skip("_Internal_push_back not yet implemented\n");
2867 return;
2869 CHECK_CALLED(concurrent_vector_int_alloc);
2870 ok(data != NULL, "_Internal_push_back returned NULL\n");
2871 ok(idx == 0, "idx got %ld expected %d\n", (long)idx, 0);
2872 vector_elem_count++;
2873 *data = 1;
2874 ok(data == vector.storage[0], "vector.storage[0] got %p expected %p\n",
2875 vector.storage[0], data);
2876 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2877 (long)vector.first_block);
2878 ok(vector.early_size == 1, "vector.early_size got %ld expected 1\n",
2879 (long)vector.early_size);
2880 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2881 vector.segment, vector.storage);
2882 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2883 ok(size == 2, "size of vector got %ld expected 2\n", (long)size);
2885 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2886 ok(data != NULL, "_Internal_push_back returned NULL\n");
2887 ok(idx == 1, "idx got %ld expected 1\n", (long)idx);
2888 vector_elem_count++;
2889 *data = 2;
2890 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2891 (long)vector.first_block);
2892 ok(vector.early_size == 2, "vector.early_size got %ld expected 2\n",
2893 (long)vector.early_size);
2895 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2896 ok(size == 2, "size of vector got %ld expected 2\n", (long)size);
2898 SET_EXPECT(concurrent_vector_int_alloc);
2899 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2900 CHECK_CALLED(concurrent_vector_int_alloc);
2901 ok(data != NULL, "_Internal_push_back returned NULL\n");
2902 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
2903 vector_elem_count++;
2904 *data = 3;
2905 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2906 vector.segment, vector.storage);
2907 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2908 (long)vector.first_block);
2909 ok(vector.early_size == 3, "vector.early_size got %ld expected 3\n",
2910 (long)vector.early_size);
2911 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2912 ok(size == 4, "size of vector got %ld expected %d\n", (long)size, 4);
2914 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2915 ok(data != NULL, "_Internal_push_back returned NULL\n");
2916 ok(idx == 3, "idx got %ld expected 3\n", (long)idx);
2917 vector_elem_count++;
2918 *data = 4;
2919 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2920 ok(size == 4, "size of vector got %ld expected 4\n", (long)size);
2922 SET_EXPECT(concurrent_vector_int_alloc);
2923 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2924 CHECK_CALLED(concurrent_vector_int_alloc);
2925 ok(data != NULL, "_Internal_push_back returned NULL\n");
2926 ok(idx == 4, "idx got %ld expected 4\n", (long)idx);
2927 vector_elem_count++;
2928 *data = 5;
2929 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2930 vector.segment, vector.storage);
2931 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2932 ok(size == 8, "size of vector got %ld expected 8\n", (long)size);
2934 concurrent_vector_int_ctor(&v2);
2935 SET_EXPECT(concurrent_vector_int_alloc);
2936 SET_EXPECT(concurrent_vector_int_copy);
2937 call_func4(p_vector_base_v4__Internal_copy, &v2, &vector,
2938 sizeof(int), concurrent_vector_int_copy);
2939 CHECK_CALLED(concurrent_vector_int_alloc);
2940 CHECK_CALLED(concurrent_vector_int_copy);
2941 ok(v2.first_block == 3, "v2.first_block got %ld expected 3\n",
2942 (long)v2.first_block);
2943 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
2944 (long)v2.early_size);
2945 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
2946 v2.segment, v2.storage);
2947 SET_EXPECT(concurrent_vector_int_destroy);
2948 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2949 &v2, concurrent_vector_int_destroy);
2950 CHECK_CALLED(concurrent_vector_int_destroy);
2951 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
2952 concurrent_vector_int_dtor(&v2);
2954 concurrent_vector_int_ctor(&v2);
2955 SET_EXPECT(concurrent_vector_int_alloc);
2956 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2957 CHECK_CALLED(concurrent_vector_int_alloc);
2958 ok(data != NULL, "_Internal_push_back returned NULL\n");
2959 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2960 ok(data != NULL, "_Internal_push_back returned NULL\n");
2961 SET_EXPECT(concurrent_vector_int_alloc);
2962 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2963 ok(data != NULL, "_Internal_push_back returned NULL\n");
2964 CHECK_CALLED(concurrent_vector_int_alloc);
2965 vector_elem_count += 3;
2966 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
2967 SET_EXPECT(concurrent_vector_int_assign);
2968 SET_EXPECT(concurrent_vector_int_copy);
2969 SET_EXPECT(concurrent_vector_int_alloc);
2970 call_func6(p_vector_base_v4__Internal_assign, &v2, &vector, sizeof(int),
2971 concurrent_vector_int_destroy, concurrent_vector_int_assign,
2972 concurrent_vector_int_copy);
2973 CHECK_CALLED(concurrent_vector_int_assign);
2974 CHECK_CALLED(concurrent_vector_int_copy);
2975 CHECK_CALLED(concurrent_vector_int_alloc);
2976 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n",
2977 (long)v2.first_block);
2978 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
2979 (long)v2.early_size);
2980 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
2981 v2.segment, v2.storage);
2982 SET_EXPECT(concurrent_vector_int_destroy);
2983 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2984 &v2, concurrent_vector_int_destroy);
2985 CHECK_CALLED(concurrent_vector_int_destroy);
2986 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
2987 concurrent_vector_int_dtor(&v2);
2989 concurrent_vector_int_ctor(&v2);
2990 SET_EXPECT(concurrent_vector_int_alloc);
2991 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2992 ok(data != NULL, "_Internal_push_back returned NULL\n");
2993 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2994 ok(data != NULL, "_Internal_push_back returned NULL\n");
2995 CHECK_CALLED(concurrent_vector_int_alloc);
2996 SET_EXPECT(concurrent_vector_int_alloc);
2997 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2998 ok(data != NULL, "_Internal_push_back returned NULL\n");
2999 CHECK_CALLED(concurrent_vector_int_alloc);
3000 vector_elem_count += 3;
3001 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
3002 call_func2(p_vector_base_v4__Internal_swap,
3003 &v2, &vector);
3004 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n",
3005 (long)v2.first_block);
3006 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
3007 (long)v2.early_size);
3008 ok(vector.early_size == 3, "vector.early_size got %ld expected 3\n",
3009 (long)vector.early_size);
3010 call_func2(p_vector_base_v4__Internal_swap,
3011 &v2, &vector);
3012 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n",
3013 (long)v2.early_size);
3014 ok(vector.early_size == 5, "vector.early_size got %ld expected 5\n",
3015 (long)vector.early_size);
3016 SET_EXPECT(concurrent_vector_int_destroy);
3017 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3018 &v2, concurrent_vector_int_destroy);
3019 CHECK_CALLED(concurrent_vector_int_destroy);
3020 ok(size == 2, "_Internal_clear returned %ld expected 2\n", (long)size);
3021 concurrent_vector_int_dtor(&v2);
3023 /* test for _Internal_compact */
3024 concurrent_vector_int_ctor(&v2);
3025 for(i=0; i<2; i++) {
3026 SET_EXPECT(concurrent_vector_int_alloc);
3027 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3028 CHECK_CALLED(concurrent_vector_int_alloc);
3029 ok(data != NULL, "_Internal_push_back returned NULL\n");
3030 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3031 ok(data != NULL, "_Internal_push_back returned NULL\n");
3032 vector_elem_count += 2;
3034 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3035 ok(v2.early_size == 4, "v2.early_size got %ld expected 4\n", (long)v2.early_size);
3036 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3037 v2.segment, v2.storage);
3038 memset(&b, 0xff, sizeof(b));
3039 SET_EXPECT(concurrent_vector_int_alloc);
3040 SET_EXPECT(concurrent_vector_int_copy);
3041 SET_EXPECT(concurrent_vector_int_destroy);
3042 data = call_func5(p_vector_base_v4__Internal_compact,
3043 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3044 concurrent_vector_int_copy);
3045 CHECK_CALLED(concurrent_vector_int_alloc);
3046 CHECK_CALLED(concurrent_vector_int_copy);
3047 CHECK_CALLED(concurrent_vector_int_destroy);
3048 ok(v2.first_block == 2, "v2.first_block got %ld expected 2\n", (long)v2.first_block);
3049 ok(v2.early_size == 4,"v2.early_size got %ld expected 4\n", (long)v2.early_size);
3050 ok(b.first_block == 1, "b.first_block got %ld expected 1\n", (long)b.first_block);
3051 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3052 v2.segment, v2.storage);
3053 for(i=0; i<2; i++){
3054 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3055 free(b.blocks[i]);
3056 vector_alloc_count--;
3058 for(; i<ARRAY_SIZE(b.blocks); i++)
3059 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3060 ok(b.size_check == -1, "b.size_check = %x\n", b.size_check);
3062 SET_EXPECT(concurrent_vector_int_alloc);
3063 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3064 CHECK_CALLED(concurrent_vector_int_alloc);
3065 ok(data != NULL, "_Internal_push_back returned NULL\n");
3066 for(i=0; i<3; i++){
3067 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3068 ok(data != NULL, "_Internal_push_back returned NULL\n");
3070 SET_EXPECT(concurrent_vector_int_alloc);
3071 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3072 CHECK_CALLED(concurrent_vector_int_alloc);
3073 ok(data != NULL, "_Internal_push_back returned NULL\n");
3074 vector_elem_count += 5;
3075 ok(v2.first_block == 2, "v2.first_block got %ld expected 2\n", (long)v2.first_block);
3076 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3077 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3078 for(i = 4;i < 32;i++)
3079 ok(v2.segment[i] == 0, "v2.segment[%d] got %p expected 0\n",
3080 i, v2.segment[i]);
3081 memset(&b, 0xff, sizeof(b));
3082 SET_EXPECT(concurrent_vector_int_alloc);
3083 SET_EXPECT(concurrent_vector_int_copy);
3084 SET_EXPECT(concurrent_vector_int_destroy);
3085 data = call_func5(p_vector_base_v4__Internal_compact,
3086 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3087 concurrent_vector_int_copy);
3088 CHECK_CALLED(concurrent_vector_int_alloc);
3089 CHECK_CALLED(concurrent_vector_int_copy);
3090 CHECK_CALLED(concurrent_vector_int_destroy);
3091 ok(v2.first_block == 4, "v2.first_block got %ld expected 4\n", (long)v2.first_block);
3092 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3093 ok(b.first_block == 2, "b.first_block got %ld expected 2\n", (long)b.first_block);
3094 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3095 for(i = 4;i < 32;i++)
3096 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3097 i, v2.segment[i]);
3098 for(i=0; i<4; i++){
3099 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3100 /* only b.blocks[0] and b.blocks[>=b.first_block] are used */
3101 if(i == b.first_block-1) continue;
3102 free(b.blocks[i]);
3103 vector_alloc_count--;
3105 for(; i<ARRAY_SIZE(b.blocks); i++)
3106 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3107 SET_EXPECT(concurrent_vector_int_alloc);
3108 call_func4(p_vector_base_v4__Internal_reserve,
3109 &v2, 17, sizeof(int), 32);
3110 CHECK_CALLED(concurrent_vector_int_alloc);
3111 data = call_func5(p_vector_base_v4__Internal_compact,
3112 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3113 concurrent_vector_int_copy);
3114 ok(v2.first_block == 4, "v2.first_block got %ld expected 4\n", (long)v2.first_block);
3115 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3116 ok(b.first_block == 4, "b.first_block got %ld expected 2\n", (long)b.first_block);
3117 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3118 for(i = 4; i < 32; i++)
3119 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3120 i, v2.segment[i]);
3121 for(i=0; i<4; i++)
3122 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3123 for(; i < 5; i++) {
3124 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3125 free(b.blocks[i]);
3126 vector_alloc_count--;
3128 for(; i<ARRAY_SIZE(b.blocks); i++)
3129 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3130 SET_EXPECT(concurrent_vector_int_destroy);
3131 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3132 &v2, concurrent_vector_int_destroy);
3133 CHECK_CALLED(concurrent_vector_int_destroy);
3134 ok(size == 4, "_Internal_clear returned %ld expected 4\n", (long)size);
3135 concurrent_vector_int_dtor(&v2);
3137 /* test for Internal_grow_by */
3138 concurrent_vector_int_ctor(&v2);
3139 SET_EXPECT(concurrent_vector_int_alloc);
3140 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3141 CHECK_CALLED(concurrent_vector_int_alloc);
3142 ok(data != NULL, "_Internal_push_back returned NULL\n");
3143 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3144 ok(data != NULL, "_Internal_push_back returned NULL\n");
3145 vector_elem_count += 2;
3146 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3147 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3148 i = 0;
3149 SET_EXPECT(concurrent_vector_int_alloc);
3150 SET_EXPECT(concurrent_vector_int_copy);
3151 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_by,
3152 &v2, 1, sizeof(int), concurrent_vector_int_copy, &i);
3153 CHECK_CALLED(concurrent_vector_int_alloc);
3154 CHECK_CALLED(concurrent_vector_int_copy);
3155 ok(idx == 2, "_Internal_grow_by returned %ld expected 2\n", (long)idx);
3156 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3157 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3158 SET_EXPECT(concurrent_vector_int_alloc);
3159 SET_EXPECT(concurrent_vector_int_copy);
3160 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_by,
3161 &v2, 2, sizeof(int), concurrent_vector_int_copy, &i);
3162 CHECK_CALLED(concurrent_vector_int_alloc);
3163 CHECK_CALLED(concurrent_vector_int_copy);
3164 ok(idx == 3, "_Internal_grow_by returned %ld expected 3\n", (long)idx);
3165 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3166 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n", (long)v2.early_size);
3167 SET_EXPECT(concurrent_vector_int_destroy);
3168 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3169 &v2, concurrent_vector_int_destroy);
3170 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
3171 CHECK_CALLED(concurrent_vector_int_destroy);
3172 concurrent_vector_int_dtor(&v2);
3174 /* test for Internal_grow_to_at_least_with_result */
3175 concurrent_vector_int_ctor(&v2);
3176 SET_EXPECT(concurrent_vector_int_alloc);
3177 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3178 CHECK_CALLED(concurrent_vector_int_alloc);
3179 ok(data != NULL, "_Internal_push_back returned NULL\n");
3180 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3181 ok(data != NULL, "_Internal_push_back returned NULL\n");
3182 vector_elem_count += 2;
3183 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3184 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3185 i = 0;
3186 SET_EXPECT(concurrent_vector_int_alloc);
3187 SET_EXPECT(concurrent_vector_int_copy);
3188 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result,
3189 &v2, 3, sizeof(int), concurrent_vector_int_copy, &i);
3190 CHECK_CALLED(concurrent_vector_int_alloc);
3191 CHECK_CALLED(concurrent_vector_int_copy);
3192 ok(idx == 2, "_Internal_grow_to_at_least_with_result returned %ld expected 2\n", (long)idx);
3193 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3194 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3195 i = 0;
3196 SET_EXPECT(concurrent_vector_int_alloc);
3197 SET_EXPECT(concurrent_vector_int_copy);
3198 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result,
3199 &v2, 5, sizeof(int), concurrent_vector_int_copy, &i);
3200 CHECK_CALLED(concurrent_vector_int_alloc);
3201 CHECK_CALLED(concurrent_vector_int_copy);
3202 ok(idx == 3, "_Internal_grow_to_at_least_with_result returned %ld expected 3\n", (long)idx);
3203 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3204 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n", (long)v2.early_size);
3205 SET_EXPECT(concurrent_vector_int_destroy);
3206 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3207 &v2, concurrent_vector_int_destroy);
3208 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
3209 CHECK_CALLED(concurrent_vector_int_destroy);
3210 concurrent_vector_int_dtor(&v2);
3212 /* test for _Internal_reserve */
3213 concurrent_vector_int_ctor(&v2);
3214 SET_EXPECT(concurrent_vector_int_alloc);
3215 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3216 CHECK_CALLED(concurrent_vector_int_alloc);
3217 ok(data != NULL, "_Internal_push_back returned NULL\n");
3218 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3219 ok(data != NULL, "_Internal_push_back returned NULL\n");
3220 vector_elem_count += 2;
3221 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3222 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3223 SET_EXPECT(concurrent_vector_int_alloc);
3224 call_func4(p_vector_base_v4__Internal_reserve,
3225 &v2, 3, sizeof(int), 4);
3226 CHECK_CALLED(concurrent_vector_int_alloc);
3227 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3228 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3229 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3230 v2.segment, v2.storage);
3231 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3232 ok(size == 4, "size of vector got %ld expected 4\n", (long)size);
3233 SET_EXPECT(concurrent_vector_int_alloc);
3234 call_func4(p_vector_base_v4__Internal_reserve,
3235 &v2, 5, sizeof(int), 8);
3236 CHECK_CALLED(concurrent_vector_int_alloc);
3237 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3238 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3239 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3240 v2.segment, v2.storage);
3241 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3242 ok(size == 8, "size of vector got %ld expected 8\n", (long)size);
3243 SET_EXPECT(concurrent_vector_int_alloc);
3244 call_func4(p_vector_base_v4__Internal_reserve,
3245 &v2, 9, sizeof(int), 16);
3246 CHECK_CALLED(concurrent_vector_int_alloc);
3247 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3248 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3249 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3250 for(i = 4;i < 32;i++)
3251 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3252 i, v2.segment[i]);
3253 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3254 ok(size == 16, "size of vector got %ld expected 8\n", (long)size);
3256 SET_EXPECT(concurrent_vector_int_destroy);
3257 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3258 &v2, concurrent_vector_int_destroy);
3259 ok(size == 4, "_Internal_clear returned %ld expected 4\n", (long)size);
3260 CHECK_CALLED(concurrent_vector_int_destroy);
3261 concurrent_vector_int_dtor(&v2);
3263 /* test for _Internal_resize */
3264 concurrent_vector_int_ctor(&v2);
3265 SET_EXPECT(concurrent_vector_int_alloc);
3266 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3267 CHECK_CALLED(concurrent_vector_int_alloc);
3268 ok(data != NULL, "_Internal_push_back returned NULL\n");
3269 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3270 ok(data != NULL, "_Internal_push_back returned NULL\n");
3271 vector_elem_count += 2;
3272 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3273 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3274 i = 0;
3275 SET_EXPECT(concurrent_vector_int_destroy);
3276 call_func7(p_vector_base_v4__Internal_resize,
3277 &v2, 1, sizeof(int), 4, concurrent_vector_int_destroy, concurrent_vector_int_copy, &i);
3278 CHECK_CALLED(concurrent_vector_int_destroy);
3279 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3280 ok(v2.early_size == 1, "v2.early_size got %ld expected 1\n", (long)v2.early_size);
3281 SET_EXPECT(concurrent_vector_int_alloc);
3282 SET_EXPECT(concurrent_vector_int_copy);
3283 call_func7(p_vector_base_v4__Internal_resize,
3284 &v2, 3, sizeof(int), 4, concurrent_vector_int_destroy, concurrent_vector_int_copy, &i);
3285 CHECK_CALLED(concurrent_vector_int_alloc);
3286 CHECK_CALLED(concurrent_vector_int_copy);
3287 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3288 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3289 SET_EXPECT(concurrent_vector_int_destroy);
3290 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3291 &v2, concurrent_vector_int_destroy);
3292 ok(size == 2, "_Internal_clear returned %ld expected 2\n", (long)size);
3293 CHECK_CALLED(concurrent_vector_int_destroy);
3294 concurrent_vector_int_dtor(&v2);
3296 SET_EXPECT(concurrent_vector_int_destroy);
3297 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3298 &vector, concurrent_vector_int_destroy);
3299 CHECK_CALLED(concurrent_vector_int_destroy);
3300 ok(size == 3, "_Internal_clear returned %ld\n", (long)size);
3301 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
3302 (long)vector.first_block);
3303 ok(vector.early_size == 0, "vector.early_size got %ld expected 0\n",
3304 (long)vector.early_size);
3305 concurrent_vector_int_dtor(&vector);
3307 ok(!vector_elem_count, "vector_elem_count = %d, expected 0\n", vector_elem_count);
3308 ok(!vector_alloc_count, "vector_alloc_count = %d, expected 0\n", vector_alloc_count);
3311 START_TEST(msvcp120)
3313 if(!init()) return;
3314 expect_idx = TlsAlloc();
3315 ok(expect_idx != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
3316 alloc_expect_struct();
3318 test__Xtime_diff_to_millis2();
3319 test_xtime_get();
3320 test__Getcvt();
3321 test__Call_once();
3322 test__Do_call();
3323 test__Dtest();
3324 test__Dscale();
3325 test__FExp();
3327 test_tr2_sys__File_size();
3328 test_tr2_sys__Equivalent();
3329 test_tr2_sys__Current_get();
3330 test_tr2_sys__Current_set();
3331 test_tr2_sys__Make_dir();
3332 test_tr2_sys__Remove_dir();
3333 test_tr2_sys__Copy_file();
3334 test_tr2_sys__Rename();
3335 test_tr2_sys__Statvfs();
3336 test_tr2_sys__Stat();
3337 test_tr2_sys__Last_write_time();
3338 test_tr2_sys__dir_operation();
3339 test_tr2_sys__Link();
3340 test_tr2_sys__Symlink();
3341 test_tr2_sys__Unlink();
3343 test_thrd();
3344 test_cnd();
3345 test__Pad();
3346 test_threads__Mtx();
3348 test_vector_base_v4__Segment_index_of();
3349 test_queue_base_v4();
3350 test_vector_base_v4();
3352 test_vbtable_size_exports();
3354 free_expect_struct();
3355 TlsFree(expect_idx);
3356 FreeLibrary(msvcp);