include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / msvcp120 / tests / msvcp120.c
blobc7de814a3846b0f0b2457cee27e4640b73e48539
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, void *a );
119 static void * (WINAPI *call_thiscall_func3)( void *func, void *this, void *a, void *b );
120 static void * (WINAPI *call_thiscall_func4)( void *func, void *this, void *a, void *b, void *c );
121 static void * (WINAPI *call_thiscall_func5)( void *func, void *this, void *a, void *b, void *c, void *d );
122 static void * (WINAPI *call_thiscall_func6)( void *func, void *this, void *a, void *b, void *c, void *d, void *e );
123 static void * (WINAPI *call_thiscall_func7)( void *func, void *this, void *a, void *b, void *c, void *d, void *e, void *f );
125 static void init_thiscall_thunk(void)
127 struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
128 MEM_COMMIT, PAGE_EXECUTE_READWRITE );
129 thunk->pop_eax = 0x58; /* popl %eax */
130 thunk->pop_edx = 0x5a; /* popl %edx */
131 thunk->pop_ecx = 0x59; /* popl %ecx */
132 thunk->push_eax = 0x50; /* pushl %eax */
133 thunk->jmp_edx = 0xe2ff; /* jmp *%edx */
134 call_thiscall_func1 = (void *)thunk;
135 call_thiscall_func2 = (void *)thunk;
136 call_thiscall_func3 = (void *)thunk;
137 call_thiscall_func4 = (void *)thunk;
138 call_thiscall_func5 = (void *)thunk;
139 call_thiscall_func6 = (void *)thunk;
140 call_thiscall_func7 = (void *)thunk;
143 #define call_func1(func,_this) call_thiscall_func1(func,_this)
144 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(void*)(a))
145 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(void*)(a),(void*)(b))
146 #define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(void*)(a),(void*)(b),(void*)(c))
147 #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d))
148 #define call_func6(func,_this,a,b,c,d,e) call_thiscall_func6(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d),(void*)(e))
149 #define call_func7(func,_this,a,b,c,d,e,f) call_thiscall_func7(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d),(void*)(e),(void*)(f))
150 #else
152 #define init_thiscall_thunk()
153 #define call_func1(func,_this) func(_this)
154 #define call_func2(func,_this,a) func(_this,a)
155 #define call_func3(func,_this,a,b) func(_this,a,b)
156 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
157 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
158 #define call_func6(func,_this,a,b,c,d,e) func(_this,a,b,c,d,e)
159 #define call_func7(func,_this,a,b,c,d,e,f) func(_this,a,b,c,d,e,f)
160 #endif /* __i386__ */
162 typedef int MSVCRT_long;
163 typedef unsigned char MSVCP_bool;
165 /* xtime */
166 typedef struct {
167 __time64_t sec;
168 MSVCRT_long nsec;
169 } xtime;
171 typedef struct {
172 unsigned page;
173 int mb_max;
174 int unk;
175 BYTE isleadbyte[32];
176 } _Cvtvec;
178 struct space_info {
179 ULONGLONG capacity;
180 ULONGLONG free;
181 ULONGLONG available;
184 enum file_type {
185 status_unknown, file_not_found, regular_file, directory_file,
186 symlink_file, block_file, character_file, fifo_file, socket_file,
187 type_unknown
190 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
192 unsigned int diff = x > y ? x - y : y - x;
194 return diff <= max_diff;
197 static BOOL compare_float(float f, float g, unsigned int ulps)
199 int x = *(int *)&f;
200 int y = *(int *)&g;
202 if (x < 0)
203 x = INT_MIN - x;
204 if (y < 0)
205 y = INT_MIN - y;
207 return compare_uint(x, y, ulps);
210 static char* (__cdecl *p_setlocale)(int, const char*);
211 static int (__cdecl *p__setmbcp)(int);
212 static int (__cdecl *p__ismbblead)(unsigned int);
214 static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
215 static int (__cdecl *p_xtime_get)(xtime*, int);
216 static _Cvtvec (__cdecl *p__Getcvt)(void);
217 static void (CDECL *p__Call_once)(int *once, void (CDECL *func)(void));
218 static void (CDECL *p__Call_onceEx)(int *once, void (CDECL *func)(void*), void *argv);
219 static void (CDECL *p__Do_call)(void *this);
220 static short (__cdecl *p__Dtest)(double *d);
221 static short (__cdecl *p__Dscale)(double *d, int exp);
222 static short (__cdecl *p__FExp)(float *x, float y, int exp);
223 static const char* (__cdecl *p__Syserror_map)(int err);
225 /* filesystem */
226 static ULONGLONG(__cdecl *p_tr2_sys__File_size)(char const*);
227 static ULONGLONG(__cdecl *p_tr2_sys__File_size_wchar)(WCHAR const*);
228 static int (__cdecl *p_tr2_sys__Equivalent)(char const*, char const*);
229 static int (__cdecl *p_tr2_sys__Equivalent_wchar)(WCHAR const*, WCHAR const*);
230 static char* (__cdecl *p_tr2_sys__Current_get)(char *);
231 static WCHAR* (__cdecl *p_tr2_sys__Current_get_wchar)(WCHAR *);
232 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set)(char const*);
233 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set_wchar)(WCHAR const*);
234 static int (__cdecl *p_tr2_sys__Make_dir)(char const*);
235 static int (__cdecl *p_tr2_sys__Make_dir_wchar)(WCHAR const*);
236 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir)(char const*);
237 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir_wchar)(WCHAR const*);
238 static int (__cdecl *p_tr2_sys__Copy_file)(char const*, char const*, MSVCP_bool);
239 static int (__cdecl *p_tr2_sys__Copy_file_wchar)(WCHAR const*, WCHAR const*, MSVCP_bool);
240 static int (__cdecl *p_tr2_sys__Rename)(char const*, char const*);
241 static int (__cdecl *p_tr2_sys__Rename_wchar)(WCHAR const*, WCHAR const*);
242 static struct space_info* (__cdecl *p_tr2_sys__Statvfs)(struct space_info*, char const*);
243 static struct space_info* (__cdecl *p_tr2_sys__Statvfs_wchar)(struct space_info*, WCHAR const*);
244 static enum file_type (__cdecl *p_tr2_sys__Stat)(char const*, int *);
245 static enum file_type (__cdecl *p_tr2_sys__Stat_wchar)(WCHAR const*, int *);
246 static enum file_type (__cdecl *p_tr2_sys__Lstat)(char const*, int *);
247 static enum file_type (__cdecl *p_tr2_sys__Lstat_wchar)(WCHAR const*, int *);
248 static __int64 (__cdecl *p_tr2_sys__Last_write_time)(char const*);
249 static __int64 (__cdecl *p_tr2_sys__Last_write_time_wchar)(WCHAR const*);
250 static void (__cdecl *p_tr2_sys__Last_write_time_set)(char const*, __int64);
251 static void* (__cdecl *p_tr2_sys__Open_dir)(char*, char const*, int *, enum file_type*);
252 static char* (__cdecl *p_tr2_sys__Read_dir)(char*, void*, enum file_type*);
253 static void (__cdecl *p_tr2_sys__Close_dir)(void*);
254 static int (__cdecl *p_tr2_sys__Link)(char const*, char const*);
255 static int (__cdecl *p_tr2_sys__Symlink)(char const*, char const*);
256 static int (__cdecl *p_tr2_sys__Unlink)(char const*);
258 /* thrd */
259 typedef struct
261 HANDLE hnd;
262 DWORD id;
263 } _Thrd_t;
265 #define TIMEDELTA 250 /* 250 ms uncertainty allowed */
267 typedef int (__cdecl *_Thrd_start_t)(void*);
269 static int (__cdecl *p__Thrd_equal)(_Thrd_t, _Thrd_t);
270 static int (__cdecl *p__Thrd_lt)(_Thrd_t, _Thrd_t);
271 static void (__cdecl *p__Thrd_sleep)(const xtime*);
272 static _Thrd_t (__cdecl *p__Thrd_current)(void);
273 static int (__cdecl *p__Thrd_create)(_Thrd_t*, _Thrd_start_t, void*);
274 static int (__cdecl *p__Thrd_join)(_Thrd_t, int*);
275 static int (__cdecl *p__Thrd_detach)(_Thrd_t);
277 #ifdef __i386__
278 static ULONGLONG (__cdecl *p_i386_Thrd_current)(void);
279 static _Thrd_t __cdecl i386_Thrd_current(void)
281 union {
282 _Thrd_t thr;
283 ULONGLONG ull;
284 } r;
285 r.ull = p_i386_Thrd_current();
286 return r.thr;
288 #endif
290 /* mtx */
291 typedef struct cs_queue
293 struct cs_queue *next;
294 BOOL free;
295 int unknown;
296 } cs_queue;
298 typedef struct
300 ULONG_PTR unk_thread_id;
301 cs_queue unk_active;
302 void *unknown[2];
303 cs_queue *head;
304 void *tail;
305 } critical_section;
307 #define MTX_PLAIN 0x1
308 #define MTX_TRY 0x2
309 #define MTX_TIMED 0x4
310 #define MTX_RECURSIVE 0x100
311 typedef struct
313 DWORD flags;
314 critical_section cs;
315 DWORD thread_id;
316 DWORD count;
317 } *_Mtx_t;
319 static int (__cdecl *p__Mtx_init)(_Mtx_t*, int);
320 static void (__cdecl *p__Mtx_destroy)(_Mtx_t*);
321 static int (__cdecl *p__Mtx_lock)(_Mtx_t*);
322 static int (__cdecl *p__Mtx_unlock)(_Mtx_t*);
323 static int (__cdecl *p__Mtx_trylock)(_Mtx_t*);
325 /* cnd */
326 typedef void *_Cnd_t;
328 static int (__cdecl *p__Cnd_init)(_Cnd_t*);
329 static void (__cdecl *p__Cnd_destroy)(_Cnd_t*);
330 static int (__cdecl *p__Cnd_wait)(_Cnd_t*, _Mtx_t*);
331 static int (__cdecl *p__Cnd_timedwait)(_Cnd_t*, _Mtx_t*, const xtime*);
332 static int (__cdecl *p__Cnd_broadcast)(_Cnd_t*);
333 static int (__cdecl *p__Cnd_signal)(_Cnd_t*);
334 static void (__cdecl *p__Cnd_register_at_thread_exit)(_Cnd_t*, _Mtx_t*, int*);
335 static void (__cdecl *p__Cnd_unregister_at_thread_exit)(_Mtx_t*);
336 static void (__cdecl *p__Cnd_do_broadcast_at_thread_exit)(void);
338 /* _Pad */
339 typedef void (*vtable_ptr)(void);
341 typedef struct
343 const vtable_ptr *vtable;
344 _Cnd_t cnd;
345 _Mtx_t mtx;
346 MSVCP_bool launched;
347 } _Pad;
349 static _Pad* (__thiscall *p__Pad_ctor)(_Pad*);
350 static _Pad* (__thiscall *p__Pad_copy_ctor)(_Pad*, const _Pad*);
351 static void (__thiscall *p__Pad_dtor)(_Pad*);
352 static _Pad* (__thiscall *p__Pad_op_assign)(_Pad*, const _Pad*);
353 static void (__thiscall *p__Pad__Launch)(_Pad*, _Thrd_t*);
354 static void (__thiscall *p__Pad__Release)(_Pad*);
356 static void (__cdecl *p_threads__Mtx_new)(void **mtx);
357 static void (__cdecl *p_threads__Mtx_delete)(void *mtx);
358 static void (__cdecl *p_threads__Mtx_lock)(void *mtx);
359 static void (__cdecl *p_threads__Mtx_unlock)(void *mtx);
361 static BOOLEAN (WINAPI *pCreateSymbolicLinkA)(LPCSTR,LPCSTR,DWORD);
363 static size_t (__cdecl *p_vector_base_v4__Segment_index_of)(size_t);
365 typedef struct
367 const vtable_ptr *vtable;
368 void *data;
369 size_t alloc_count;
370 size_t item_size;
371 } queue_base_v4;
373 typedef struct
375 struct _Page *_Next;
376 size_t _Mask;
377 char data[1];
378 } _Page;
380 static queue_base_v4* (__thiscall *p_queue_base_v4_ctor)(queue_base_v4*, size_t);
381 static void (__thiscall *p_queue_base_v4_dtor)(queue_base_v4*);
382 static MSVCP_bool (__thiscall *p_queue_base_v4__Internal_empty)(queue_base_v4*);
383 static size_t (__thiscall *p_queue_base_v4__Internal_size)(queue_base_v4*);
384 static void (__thiscall *p_queue_base_v4__Internal_push)(queue_base_v4*, const void*);
385 static void (__thiscall *p_queue_base_v4__Internal_move_push)(queue_base_v4*, void*);
386 static MSVCP_bool (__thiscall *p_queue_base_v4__Internal_pop_if_present)(queue_base_v4*, void*);
387 static void (__thiscall *p_queue_base_v4__Internal_finish_clear)(queue_base_v4*);
389 typedef struct vector_base_v4
391 void* (__cdecl *allocator)(struct vector_base_v4*, size_t);
392 void *storage[3];
393 size_t first_block;
394 size_t early_size;
395 void **segment;
396 } vector_base_v4;
398 static void (__thiscall *p_vector_base_v4_dtor)(vector_base_v4*);
399 static size_t (__thiscall *p_vector_base_v4__Internal_capacity)(vector_base_v4*);
400 static void* (__thiscall *p_vector_base_v4__Internal_push_back)(
401 vector_base_v4*, size_t, size_t*);
402 static size_t (__thiscall *p_vector_base_v4__Internal_clear)(
403 vector_base_v4*, void (__cdecl*)(void*, size_t));
404 static void (__thiscall *p_vector_base_v4__Internal_copy)(
405 vector_base_v4*, vector_base_v4*, size_t, void (__cdecl*)(void*, const void*, size_t));
406 static void (__thiscall *p_vector_base_v4__Internal_assign)(
407 vector_base_v4*, vector_base_v4*, size_t, void (__cdecl*)(void*, size_t),
408 void (__cdecl*)(void*, const void*, size_t), void (__cdecl*)(void*, const void*, size_t));
409 static void (__thiscall *p_vector_base_v4__Internal_swap)(
410 vector_base_v4*, const vector_base_v4*);
411 static void* (__thiscall *p_vector_base_v4__Internal_compact)(
412 vector_base_v4*, size_t, void*, void (__cdecl*)(void*, size_t),
413 void (__cdecl*)(void*, const void*, size_t));
414 static size_t (__thiscall *p_vector_base_v4__Internal_grow_by)(
415 vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
416 static size_t (__thiscall *p_vector_base_v4__Internal_grow_to_at_least_with_result)(
417 vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
418 static void (__thiscall *p_vector_base_v4__Internal_reserve)(
419 vector_base_v4*, size_t, size_t, size_t);
420 static void (__thiscall *p_vector_base_v4__Internal_resize)(
421 vector_base_v4*, size_t, size_t, size_t, void (__cdecl*)(void*, size_t),
422 void (__cdecl *copy)(void*, const void*, size_t), const void*);
424 static const BYTE *p_byte_reverse_table;
426 static HMODULE msvcp;
427 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
428 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
429 static BOOL init(void)
431 HANDLE hdll;
433 msvcp = LoadLibraryA("msvcp120.dll");
434 if(!msvcp)
436 win_skip("msvcp120.dll not installed\n");
437 return FALSE;
440 SET(p__Xtime_diff_to_millis2,
441 "_Xtime_diff_to_millis2");
442 SET(p_xtime_get,
443 "xtime_get");
444 SET(p__Getcvt,
445 "_Getcvt");
446 SET(p__Call_once,
447 "_Call_once");
448 SET(p__Call_onceEx,
449 "_Call_onceEx");
450 SET(p__Do_call,
451 "_Do_call");
452 SET(p__Dtest,
453 "_Dtest");
454 SET(p__Dscale,
455 "_Dscale");
456 SET(p__FExp,
457 "_FExp");
458 if(sizeof(void*) == 8) { /* 64-bit initialization */
459 SET(p_tr2_sys__File_size,
460 "?_File_size@sys@tr2@std@@YA_KPEBD@Z");
461 SET(p_tr2_sys__File_size_wchar,
462 "?_File_size@sys@tr2@std@@YA_KPEB_W@Z");
463 SET(p_tr2_sys__Equivalent,
464 "?_Equivalent@sys@tr2@std@@YAHPEBD0@Z");
465 SET(p_tr2_sys__Equivalent_wchar,
466 "?_Equivalent@sys@tr2@std@@YAHPEB_W0@Z");
467 SET(p_tr2_sys__Current_get,
468 "?_Current_get@sys@tr2@std@@YAPEADAEAY0BAE@D@Z");
469 SET(p_tr2_sys__Current_get_wchar,
470 "?_Current_get@sys@tr2@std@@YAPEA_WAEAY0BAE@_W@Z");
471 SET(p_tr2_sys__Current_set,
472 "?_Current_set@sys@tr2@std@@YA_NPEBD@Z");
473 SET(p_tr2_sys__Current_set_wchar,
474 "?_Current_set@sys@tr2@std@@YA_NPEB_W@Z");
475 SET(p_tr2_sys__Make_dir,
476 "?_Make_dir@sys@tr2@std@@YAHPEBD@Z");
477 SET(p_tr2_sys__Make_dir_wchar,
478 "?_Make_dir@sys@tr2@std@@YAHPEB_W@Z");
479 SET(p_tr2_sys__Remove_dir,
480 "?_Remove_dir@sys@tr2@std@@YA_NPEBD@Z");
481 SET(p_tr2_sys__Remove_dir_wchar,
482 "?_Remove_dir@sys@tr2@std@@YA_NPEB_W@Z");
483 SET(p_tr2_sys__Copy_file,
484 "?_Copy_file@sys@tr2@std@@YAHPEBD0_N@Z");
485 SET(p_tr2_sys__Copy_file_wchar,
486 "?_Copy_file@sys@tr2@std@@YAHPEB_W0_N@Z");
487 SET(p_tr2_sys__Rename,
488 "?_Rename@sys@tr2@std@@YAHPEBD0@Z");
489 SET(p_tr2_sys__Rename_wchar,
490 "?_Rename@sys@tr2@std@@YAHPEB_W0@Z");
491 SET(p_tr2_sys__Statvfs,
492 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEBD@Z");
493 SET(p_tr2_sys__Statvfs_wchar,
494 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEB_W@Z");
495 SET(p_tr2_sys__Stat,
496 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
497 SET(p_tr2_sys__Stat_wchar,
498 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
499 SET(p_tr2_sys__Lstat,
500 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
501 SET(p_tr2_sys__Lstat_wchar,
502 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
503 SET(p_tr2_sys__Last_write_time,
504 "?_Last_write_time@sys@tr2@std@@YA_JPEBD@Z");
505 SET(p_tr2_sys__Last_write_time_wchar,
506 "?_Last_write_time@sys@tr2@std@@YA_JPEB_W@Z");
507 SET(p_tr2_sys__Last_write_time_set,
508 "?_Last_write_time@sys@tr2@std@@YAXPEBD_J@Z");
509 SET(p_tr2_sys__Open_dir,
510 "?_Open_dir@sys@tr2@std@@YAPEAXAEAY0BAE@DPEBDAEAHAEAW4file_type@123@@Z");
511 SET(p_tr2_sys__Read_dir,
512 "?_Read_dir@sys@tr2@std@@YAPEADAEAY0BAE@DPEAXAEAW4file_type@123@@Z");
513 SET(p_tr2_sys__Close_dir,
514 "?_Close_dir@sys@tr2@std@@YAXPEAX@Z");
515 SET(p_tr2_sys__Link,
516 "?_Link@sys@tr2@std@@YAHPEBD0@Z");
517 SET(p_tr2_sys__Symlink,
518 "?_Symlink@sys@tr2@std@@YAHPEBD0@Z");
519 SET(p_tr2_sys__Unlink,
520 "?_Unlink@sys@tr2@std@@YAHPEBD@Z");
521 SET(p__Thrd_current,
522 "_Thrd_current");
523 SET(p__Pad_ctor,
524 "??0_Pad@std@@QEAA@XZ");
525 SET(p__Pad_copy_ctor,
526 "??0_Pad@std@@QEAA@AEBV01@@Z");
527 SET(p__Pad_dtor,
528 "??1_Pad@std@@QEAA@XZ");
529 SET(p__Pad_op_assign,
530 "??4_Pad@std@@QEAAAEAV01@AEBV01@@Z");
531 SET(p__Pad__Launch,
532 "?_Launch@_Pad@std@@QEAAXPEAU_Thrd_imp_t@@@Z");
533 SET(p__Pad__Release,
534 "?_Release@_Pad@std@@QEAAXXZ");
535 SET(p_threads__Mtx_new,
536 "?_Mtx_new@threads@stdext@@YAXAEAPEAX@Z");
537 SET(p_threads__Mtx_delete,
538 "?_Mtx_delete@threads@stdext@@YAXPEAX@Z");
539 SET(p_threads__Mtx_lock,
540 "?_Mtx_lock@threads@stdext@@YAXPEAX@Z");
541 SET(p_threads__Mtx_unlock,
542 "?_Mtx_unlock@threads@stdext@@YAXPEAX@Z");
543 SET(p_vector_base_v4__Segment_index_of,
544 "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KA_K_K@Z");
545 SET(p_queue_base_v4_ctor,
546 "??0_Concurrent_queue_base_v4@details@Concurrency@@IEAA@_K@Z");
547 SET(p_queue_base_v4_dtor,
548 "??1_Concurrent_queue_base_v4@details@Concurrency@@MEAA@XZ");
549 SET(p_queue_base_v4__Internal_empty,
550 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_NXZ");
551 SET(p_queue_base_v4__Internal_size,
552 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_KXZ");
553 SET(p_queue_base_v4__Internal_push,
554 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEBX@Z");
555 SET(p_queue_base_v4__Internal_move_push,
556 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEAX@Z");
557 SET(p_queue_base_v4__Internal_pop_if_present,
558 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IEAA_NPEAX@Z");
559 SET(p_queue_base_v4__Internal_finish_clear,
560 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXXZ");
561 SET(p_vector_base_v4_dtor,
562 "??1_Concurrent_vector_base_v4@details@Concurrency@@IEAA@XZ");
563 SET(p_vector_base_v4__Internal_capacity,
564 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IEBA_KXZ");
565 SET(p_vector_base_v4__Internal_push_back,
566 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IEAAPEAX_KAEA_K@Z");
567 SET(p_vector_base_v4__Internal_clear,
568 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_KP6AXPEAX_K@Z@Z");
569 SET(p_vector_base_v4__Internal_copy,
570 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z");
571 SET(p_vector_base_v4__Internal_assign,
572 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z");
573 SET(p_vector_base_v4__Internal_swap,
574 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEAV123@@Z");
575 SET(p_vector_base_v4__Internal_compact,
576 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IEAAPEAX_KPEAXP6AX10@ZP6AX1PEBX0@Z@Z");
577 SET(p_vector_base_v4__Internal_grow_by,
578 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z");
579 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
580 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z");
581 SET(p_vector_base_v4__Internal_reserve,
582 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00@Z");
583 SET(p_vector_base_v4__Internal_resize,
584 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00P6AXPEAX0@ZP6AX1PEBX0@Z3@Z");
585 SET(p__Syserror_map,
586 "?_Syserror_map@std@@YAPEBDH@Z");
587 } else {
588 SET(p_tr2_sys__File_size,
589 "?_File_size@sys@tr2@std@@YA_KPBD@Z");
590 SET(p_tr2_sys__File_size_wchar,
591 "?_File_size@sys@tr2@std@@YA_KPB_W@Z");
592 SET(p_tr2_sys__Equivalent,
593 "?_Equivalent@sys@tr2@std@@YAHPBD0@Z");
594 SET(p_tr2_sys__Equivalent_wchar,
595 "?_Equivalent@sys@tr2@std@@YAHPB_W0@Z");
596 SET(p_tr2_sys__Current_get,
597 "?_Current_get@sys@tr2@std@@YAPADAAY0BAE@D@Z");
598 SET(p_tr2_sys__Current_get_wchar,
599 "?_Current_get@sys@tr2@std@@YAPA_WAAY0BAE@_W@Z");
600 SET(p_tr2_sys__Current_set,
601 "?_Current_set@sys@tr2@std@@YA_NPBD@Z");
602 SET(p_tr2_sys__Current_set_wchar,
603 "?_Current_set@sys@tr2@std@@YA_NPB_W@Z");
604 SET(p_tr2_sys__Make_dir,
605 "?_Make_dir@sys@tr2@std@@YAHPBD@Z");
606 SET(p_tr2_sys__Make_dir_wchar,
607 "?_Make_dir@sys@tr2@std@@YAHPB_W@Z");
608 SET(p_tr2_sys__Remove_dir,
609 "?_Remove_dir@sys@tr2@std@@YA_NPBD@Z");
610 SET(p_tr2_sys__Remove_dir_wchar,
611 "?_Remove_dir@sys@tr2@std@@YA_NPB_W@Z");
612 SET(p_tr2_sys__Copy_file,
613 "?_Copy_file@sys@tr2@std@@YAHPBD0_N@Z");
614 SET(p_tr2_sys__Copy_file_wchar,
615 "?_Copy_file@sys@tr2@std@@YAHPB_W0_N@Z");
616 SET(p_tr2_sys__Rename,
617 "?_Rename@sys@tr2@std@@YAHPBD0@Z");
618 SET(p_tr2_sys__Rename_wchar,
619 "?_Rename@sys@tr2@std@@YAHPB_W0@Z");
620 SET(p_tr2_sys__Statvfs,
621 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z");
622 SET(p_tr2_sys__Statvfs_wchar,
623 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PB_W@Z");
624 SET(p_tr2_sys__Stat,
625 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
626 SET(p_tr2_sys__Stat_wchar,
627 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
628 SET(p_tr2_sys__Lstat,
629 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
630 SET(p_tr2_sys__Lstat_wchar,
631 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
632 SET(p_tr2_sys__Last_write_time,
633 "?_Last_write_time@sys@tr2@std@@YA_JPBD@Z");
634 SET(p_tr2_sys__Last_write_time_wchar,
635 "?_Last_write_time@sys@tr2@std@@YA_JPB_W@Z");
636 SET(p_tr2_sys__Last_write_time_set,
637 "?_Last_write_time@sys@tr2@std@@YAXPBD_J@Z");
638 SET(p_tr2_sys__Open_dir,
639 "?_Open_dir@sys@tr2@std@@YAPAXAAY0BAE@DPBDAAHAAW4file_type@123@@Z");
640 SET(p_tr2_sys__Read_dir,
641 "?_Read_dir@sys@tr2@std@@YAPADAAY0BAE@DPAXAAW4file_type@123@@Z");
642 SET(p_tr2_sys__Close_dir,
643 "?_Close_dir@sys@tr2@std@@YAXPAX@Z");
644 SET(p_tr2_sys__Link,
645 "?_Link@sys@tr2@std@@YAHPBD0@Z");
646 SET(p_tr2_sys__Symlink,
647 "?_Symlink@sys@tr2@std@@YAHPBD0@Z");
648 SET(p_tr2_sys__Unlink,
649 "?_Unlink@sys@tr2@std@@YAHPBD@Z");
650 SET(p_threads__Mtx_new,
651 "?_Mtx_new@threads@stdext@@YAXAAPAX@Z");
652 SET(p_threads__Mtx_delete,
653 "?_Mtx_delete@threads@stdext@@YAXPAX@Z");
654 SET(p_threads__Mtx_lock,
655 "?_Mtx_lock@threads@stdext@@YAXPAX@Z");
656 SET(p_threads__Mtx_unlock,
657 "?_Mtx_unlock@threads@stdext@@YAXPAX@Z");
658 SET(p_vector_base_v4__Segment_index_of,
659 "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KAII@Z");
660 SET(p__Syserror_map,
661 "?_Syserror_map@std@@YAPBDH@Z");
662 #ifdef __i386__
663 SET(p_i386_Thrd_current,
664 "_Thrd_current");
665 p__Thrd_current = i386_Thrd_current;
666 SET(p__Pad_ctor,
667 "??0_Pad@std@@QAE@XZ");
668 SET(p__Pad_copy_ctor,
669 "??0_Pad@std@@QAE@ABV01@@Z");
670 SET(p__Pad_dtor,
671 "??1_Pad@std@@QAE@XZ");
672 SET(p__Pad_op_assign,
673 "??4_Pad@std@@QAEAAV01@ABV01@@Z");
674 SET(p__Pad__Launch,
675 "?_Launch@_Pad@std@@QAEXPAU_Thrd_imp_t@@@Z");
676 SET(p__Pad__Release,
677 "?_Release@_Pad@std@@QAEXXZ");
678 SET(p_queue_base_v4_ctor,
679 "??0_Concurrent_queue_base_v4@details@Concurrency@@IAE@I@Z");
680 SET(p_queue_base_v4_dtor,
681 "??1_Concurrent_queue_base_v4@details@Concurrency@@MAE@XZ");
682 SET(p_queue_base_v4__Internal_empty,
683 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBE_NXZ");
684 SET(p_queue_base_v4__Internal_size,
685 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBEIXZ");
686 SET(p_queue_base_v4__Internal_push,
687 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPBX@Z");
688 SET(p_queue_base_v4__Internal_move_push,
689 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPAX@Z");
690 SET(p_queue_base_v4__Internal_pop_if_present,
691 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAE_NPAX@Z");
692 SET(p_queue_base_v4__Internal_finish_clear,
693 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAEXXZ");
694 SET(p_vector_base_v4_dtor,
695 "??1_Concurrent_vector_base_v4@details@Concurrency@@IAE@XZ");
696 SET(p_vector_base_v4__Internal_capacity,
697 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IBEIXZ");
698 SET(p_vector_base_v4__Internal_push_back,
699 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IAEPAXIAAI@Z");
700 SET(p_vector_base_v4__Internal_clear,
701 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAEIP6AXPAXI@Z@Z");
702 SET(p_vector_base_v4__Internal_copy,
703 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IAEXABV123@IP6AXPAXPBXI@Z@Z");
704 SET(p_vector_base_v4__Internal_assign,
705 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z");
706 SET(p_vector_base_v4__Internal_swap,
707 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IAEXAAV123@@Z");
708 SET(p_vector_base_v4__Internal_compact,
709 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IAEPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z");
710 SET(p_vector_base_v4__Internal_grow_by,
711 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IAEIIIP6AXPAXPBXI@Z1@Z");
712 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
713 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IAEIIIP6AXPAXPBXI@Z1@Z");
714 SET(p_vector_base_v4__Internal_reserve,
715 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIII@Z");
716 SET(p_vector_base_v4__Internal_resize,
717 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z");
718 #else
719 SET(p__Thrd_current,
720 "_Thrd_current");
721 SET(p__Pad_ctor,
722 "??0_Pad@std@@QAA@XZ");
723 SET(p__Pad_copy_ctor,
724 "??0_Pad@std@@QAA@ABV01@@Z");
725 SET(p__Pad_dtor,
726 "??1_Pad@std@@QAA@XZ");
727 SET(p__Pad_op_assign,
728 "??4_Pad@std@@QAAAAV01@ABV01@@Z");
729 SET(p__Pad__Launch,
730 "?_Launch@_Pad@std@@QAAXPAU_Thrd_imp_t@@@Z");
731 SET(p__Pad__Release,
732 "?_Release@_Pad@std@@QAAXXZ");
733 SET(p_queue_base_v4_ctor,
734 "??0_Concurrent_queue_base_v4@details@Concurrency@@IAA@I@Z");
735 SET(p_queue_base_v4_dtor,
736 "??1_Concurrent_queue_base_v4@details@Concurrency@@MAA@XZ");
737 SET(p_queue_base_v4__Internal_empty,
738 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBA_NXZ");
739 SET(p_queue_base_v4__Internal_size,
740 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBAIXZ");
741 SET(p_queue_base_v4__Internal_push,
742 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPBX@Z");
743 SET(p_queue_base_v4__Internal_move_push,
744 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPAX@Z");
745 SET(p_queue_base_v4__Internal_pop_if_present,
746 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAA_NPAX@Z");
747 SET(p_queue_base_v4__Internal_finish_clear,
748 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAAXXZ");
749 SET(p_vector_base_v4_dtor,
750 "??1_Concurrent_vector_base_v4@details@Concurrency@@IAA@XZ");
751 SET(p_vector_base_v4__Internal_capacity,
752 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IBAIXZ");
753 SET(p_vector_base_v4__Internal_push_back,
754 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IAAPAXIAAI@Z");
755 SET(p_vector_base_v4__Internal_clear,
756 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAAIP6AXPAXI@Z@Z");
757 SET(p_vector_base_v4__Internal_copy,
758 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IAAXABV123@IP6AXPAXPBXI@Z@Z");
759 SET(p_vector_base_v4__Internal_assign,
760 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z");
761 SET(p_vector_base_v4__Internal_swap,
762 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IAAXAAV123@@Z");
763 SET(p_vector_base_v4__Internal_compact,
764 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IAAPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z");
765 SET(p_vector_base_v4__Internal_grow_by,
766 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IAAIIIP6AXPAXPBXI@Z1@Z");
767 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
768 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IAAIIIP6AXPAXPBXI@Z1@Z");
769 SET(p_vector_base_v4__Internal_reserve,
770 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAAXIII@Z");
771 SET(p_vector_base_v4__Internal_resize,
772 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAAXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z");
773 #endif
775 SET(p__Thrd_equal,
776 "_Thrd_equal");
777 SET(p__Thrd_lt,
778 "_Thrd_lt");
779 SET(p__Thrd_sleep,
780 "_Thrd_sleep");
781 SET(p__Thrd_create,
782 "_Thrd_create");
783 SET(p__Thrd_join,
784 "_Thrd_join");
785 SET(p__Thrd_detach,
786 "_Thrd_detach");
788 SET(p__Mtx_init,
789 "_Mtx_init");
790 SET(p__Mtx_destroy,
791 "_Mtx_destroy");
792 SET(p__Mtx_lock,
793 "_Mtx_lock");
794 SET(p__Mtx_unlock,
795 "_Mtx_unlock");
796 SET(p__Mtx_trylock,
797 "_Mtx_trylock");
799 SET(p__Cnd_init,
800 "_Cnd_init");
801 SET(p__Cnd_destroy,
802 "_Cnd_destroy");
803 SET(p__Cnd_wait,
804 "_Cnd_wait");
805 SET(p__Cnd_timedwait,
806 "_Cnd_timedwait");
807 SET(p__Cnd_broadcast,
808 "_Cnd_broadcast");
809 SET(p__Cnd_signal,
810 "_Cnd_signal");
811 SET(p__Cnd_register_at_thread_exit,
812 "_Cnd_register_at_thread_exit");
813 SET(p__Cnd_unregister_at_thread_exit,
814 "_Cnd_unregister_at_thread_exit");
815 SET(p__Cnd_do_broadcast_at_thread_exit,
816 "_Cnd_do_broadcast_at_thread_exit");
818 SET(p_byte_reverse_table, "?_Byte_reverse_table@details@Concurrency@@3QBEB");
820 hdll = GetModuleHandleA("msvcr120.dll");
821 p_setlocale = (void*)GetProcAddress(hdll, "setlocale");
822 p__setmbcp = (void*)GetProcAddress(hdll, "_setmbcp");
823 p__ismbblead = (void*)GetProcAddress(hdll, "_ismbblead");
825 hdll = GetModuleHandleA("kernel32.dll");
826 pCreateSymbolicLinkA = (void*)GetProcAddress(hdll, "CreateSymbolicLinkA");
828 init_thiscall_thunk();
829 return TRUE;
832 static void test__Xtime_diff_to_millis2(void)
834 struct {
835 __time64_t sec_before;
836 MSVCRT_long nsec_before;
837 __time64_t sec_after;
838 MSVCRT_long nsec_after;
839 MSVCRT_long expect;
840 } tests[] = {
841 {1, 0, 2, 0, 1000},
842 {0, 1000000000, 0, 2000000000, 1000},
843 {1, 100000000, 2, 100000000, 1000},
844 {1, 100000000, 1, 200000000, 100},
845 {0, 0, 0, 1000000000, 1000},
846 {0, 0, 0, 1200000000, 1200},
847 {0, 0, 0, 1230000000, 1230},
848 {0, 0, 0, 1234000000, 1234},
849 {0, 0, 0, 1234100000, 1235},
850 {0, 0, 0, 1234900000, 1235},
851 {0, 0, 0, 1234010000, 1235},
852 {0, 0, 0, 1234090000, 1235},
853 {0, 0, 0, 1234000001, 1235},
854 {0, 0, 0, 1234000009, 1235},
855 {0, 0, -1, 0, 0},
856 {1, 0, 0, 0, 0},
857 {0, 1000000000, 0, 0, 0},
858 {0x7FFFFFFF / 1000, 0, 0, 0, 0},
859 {2147484, 0, 0, 0, 0}, /* ceil(0x80000000 / 1000) */
860 {2147485, 0, 0, 0, 0}, /* ceil(0x80000000 / 1000) + 1*/
861 {0, 0, 0x7FFFFFFF / 1000, 0, 2147483000},
862 {0, 0, 0x7FFFFFFF / 1000, 647000000, 0x7FFFFFFF}, /* max */
863 {0, 0, 0x7FFFFFFF / 1000, 647000001, -2147483648}, /* overflow. */
864 {0, 0, 2147484, 0, -2147483296}, /* ceil(0x80000000 / 1000), overflow*/
865 {0, 0, 0, -10000000, 0},
866 {0, 0, -1, -100000000, 0},
867 {-1, 0, 0, 0, 1000},
868 {0, -100000000, 0, 0, 100},
869 {-1, -100000000, 0, 0, 1100},
870 {0, 0, -1, 2000000000, 1000},
871 {0, 0, -2, 2000000000, 0},
872 {0, 0, -2, 2100000000, 100},
873 {0, 0, _I64_MAX / 1000, 0, -808}, /* Still fits in a signed 64 bit number */
874 {0, 0, _I64_MAX / 1000, 1000000000, 192}, /* Overflows a signed 64 bit number */
875 {0, 0, (((ULONGLONG)0x80000000 << 32) | 0x1000) / 1000, 1000000000, 4192}, /* 64 bit overflow */
876 {_I64_MAX - 2, 0, _I64_MAX, 0, 2000}, /* Not an overflow */
877 {_I64_MAX, 0, _I64_MAX - 2, 0, 0}, /* Not an overflow */
879 /* October 11th 2017, 12:34:59 UTC */
880 {1507725144, 983274000, 0, 0, 0},
881 {0, 0, 1507725144, 983274000, 191624088},
882 {1507725144, 983274000, 1507725145, 983274000, 1000},
883 {1507725145, 983274000, 1507725145, 983274000, 0},
885 int i;
886 MSVCRT_long ret;
887 xtime t1, t2;
889 for(i = 0; i < ARRAY_SIZE(tests); ++ i)
891 t1.sec = tests[i].sec_before;
892 t1.nsec = tests[i].nsec_before;
893 t2.sec = tests[i].sec_after;
894 t2.nsec = tests[i].nsec_after;
895 ret = p__Xtime_diff_to_millis2(&t2, &t1);
896 ok(ret == tests[i].expect,
897 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
898 i, tests[i].expect, ret);
902 static void test_xtime_get(void)
904 static const MSVCRT_long tests[] = {1, 50, 100, 200, 500};
905 MSVCRT_long diff;
906 xtime before, after;
907 int i;
909 for(i = 0; i < ARRAY_SIZE(tests); i ++)
911 p_xtime_get(&before, 1);
912 Sleep(tests[i]);
913 p_xtime_get(&after, 1);
915 diff = p__Xtime_diff_to_millis2(&after, &before);
917 ok(diff >= tests[i],
918 "xtime_get() not functioning correctly, test: %d, expect: %d, got: %d\n",
919 i, tests[i], diff);
922 /* Test parameter and return value */
923 before.sec = 0xdeadbeef; before.nsec = 0xdeadbeef;
924 i = p_xtime_get(&before, 0);
925 ok(i == 0, "expect xtime_get() to return 0, got: %d\n", i);
926 ok(before.sec == 0xdeadbeef && before.nsec == 0xdeadbeef,
927 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
929 before.sec = 0xdeadbeef; before.nsec = 0xdeadbeef;
930 i = p_xtime_get(&before, 1);
931 ok(i == 1, "expect xtime_get() to return 1, got: %d\n", i);
932 ok(before.sec != 0xdeadbeef && before.nsec != 0xdeadbeef,
933 "xtime_get() should have modified the xtime struct with the given option\n");
936 static void test__Getcvt(void)
938 _Cvtvec cvtvec;
939 int i;
941 cvtvec = p__Getcvt();
942 ok(cvtvec.page == 0, "cvtvec.page = %d\n", cvtvec.page);
943 ok(cvtvec.mb_max == 1, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
944 todo_wine ok(cvtvec.unk == 1, "cvtvec.unk = %d\n", cvtvec.unk);
945 for(i=0; i<32; i++)
946 ok(cvtvec.isleadbyte[i] == 0, "cvtvec.isleadbyte[%d] = %x\n", i, cvtvec.isleadbyte[i]);
948 if(!p_setlocale(LC_ALL, ".936")) {
949 win_skip("_Getcvt tests\n");
950 return;
952 cvtvec = p__Getcvt();
953 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
954 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
955 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
956 for(i=0; i<32; i++) {
957 BYTE b = 0;
958 int j;
960 for(j=0; j<8; j++)
961 b |= (p__ismbblead(i*8+j) ? 1 : 0) << j;
962 ok(cvtvec.isleadbyte[i] ==b, "cvtvec.isleadbyte[%d] = %x (%x)\n", i, cvtvec.isleadbyte[i], b);
965 p__setmbcp(936);
966 cvtvec = p__Getcvt();
967 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
968 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
969 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
970 for(i=0; i<32; i++) {
971 BYTE b = 0;
972 int j;
974 for(j=0; j<8; j++)
975 b |= (p__ismbblead(i*8+j) ? 1 : 0) << j;
976 ok(cvtvec.isleadbyte[i] ==b, "cvtvec.isleadbyte[%d] = %x (%x)\n", i, cvtvec.isleadbyte[i], b);
980 static int cnt;
981 static int once;
983 static void __cdecl call_once_func(void)
985 ok(!once, "once != 0\n");
986 cnt += 0x10000;
989 static void __cdecl call_once_ex_func(void *arg)
991 int *i = arg;
993 ok(!once, "once != 0\n");
994 (*i)++;
997 static DWORD WINAPI call_once_thread(void *arg)
999 p__Call_once(&once, call_once_func);
1000 return 0;
1003 static DWORD WINAPI call_once_ex_thread(void *arg)
1005 p__Call_onceEx(&once, call_once_ex_func, &cnt);
1006 return 0;
1009 static void test__Call_once(void)
1011 HANDLE h[4];
1012 int i;
1014 for(i=0; i<4; i++)
1015 h[i] = CreateThread(NULL, 0, call_once_thread, &once, 0, NULL);
1016 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
1017 "error waiting for all threads to finish\n");
1018 ok(cnt == 0x10000, "cnt = %x\n", cnt);
1019 ok(once == 1, "once = %x\n", once);
1021 once = cnt = 0;
1022 for(i=0; i<4; i++)
1023 h[i] = CreateThread(NULL, 0, call_once_ex_thread, &once, 0, NULL);
1024 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
1025 "error waiting for all threads to finish\n");
1026 ok(cnt == 1, "cnt = %x\n", cnt);
1027 ok(once == 1, "once = %x\n", once);
1030 static void **vtbl_func0;
1031 #ifdef __i386__
1032 /* TODO: this should be a __thiscall function */
1033 static void __stdcall thiscall_func(void)
1035 cnt = 1;
1037 #else
1038 static void __cdecl thiscall_func(void *this)
1040 ok(this == &vtbl_func0, "incorrect this value\n");
1041 cnt = 1;
1043 #endif
1045 static void test__Do_call(void)
1047 void *pfunc = thiscall_func;
1049 cnt = 0;
1050 vtbl_func0 = &pfunc;
1051 p__Do_call(&vtbl_func0);
1052 ok(cnt == 1, "func was not called\n");
1055 static void test__Dtest(void)
1057 double d;
1058 short ret;
1060 d = 0;
1061 ret = p__Dtest(&d);
1062 ok(ret == FP_ZERO, "_Dtest(0) returned %x\n", ret);
1064 d = 1;
1065 ret = p__Dtest(&d);
1066 ok(ret == FP_NORMAL, "_Dtest(1) 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 = INFINITY;
1073 ret = p__Dtest(&d);
1074 ok(ret == FP_INFINITE, "_Dtest(INF) returned %x\n", ret);
1076 d = NAN;
1077 ret = p__Dtest(&d);
1078 ok(ret == FP_NAN, "_Dtest(NAN) returned %x\n", ret);
1081 static void test__Dscale(void)
1083 double d;
1084 short ret;
1086 d = 0;
1087 ret = p__Dscale(&d, 0);
1088 ok(d == 0, "d = %f\n", d);
1089 ok(ret == FP_ZERO, "ret = %x\n", ret);
1091 d = 0;
1092 ret = p__Dscale(&d, 1);
1093 ok(d == 0, "d = %f\n", d);
1094 ok(ret == FP_ZERO, "ret = %x\n", ret);
1096 d = 0;
1097 ret = p__Dscale(&d, -1);
1098 ok(d == 0, "d = %f\n", d);
1099 ok(ret == FP_ZERO, "ret = %x\n", ret);
1101 d = 1;
1102 ret = p__Dscale(&d, 0);
1103 ok(d == 1, "d = %f\n", d);
1104 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1106 d = 1;
1107 ret = p__Dscale(&d, 1);
1108 ok(d == 2, "d = %f\n", d);
1109 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1111 d = 1;
1112 ret = p__Dscale(&d, -1);
1113 ok(d == 0.5, "d = %f\n", d);
1114 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1116 d = 1;
1117 ret = p__Dscale(&d, -99999);
1118 ok(d == 0, "d = %f\n", d);
1119 ok(ret == FP_ZERO, "ret = %x\n", ret);
1121 d = 1;
1122 ret = p__Dscale(&d, 999999);
1123 ok(d == INFINITY, "d = %f\n", d);
1124 ok(ret == FP_INFINITE, "ret = %x\n", ret);
1126 d = NAN;
1127 ret = p__Dscale(&d, 1);
1128 ok(ret == FP_NAN, "ret = %x\n", ret);
1131 static void test__FExp(void)
1133 float d;
1134 short ret;
1136 d = 0;
1137 ret = p__FExp(&d, 0, 0);
1138 ok(d == 0, "d = %f\n", d);
1139 ok(ret == FP_ZERO, "ret = %x\n", ret);
1141 d = 0;
1142 ret = p__FExp(&d, 1, 0);
1143 ok(d == 1.0, "d = %f\n", d);
1144 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1146 d = 0;
1147 ret = p__FExp(&d, 1, 1);
1148 ok(d == 2.0, "d = %f\n", d);
1149 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1151 d = 0;
1152 ret = p__FExp(&d, 1, 2);
1153 ok(d == 4.0, "d = %f\n", d);
1154 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1156 d = 0;
1157 ret = p__FExp(&d, 10, 0);
1158 ok(d == 10.0, "d = %f\n", d);
1159 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1161 d = 1;
1162 ret = p__FExp(&d, 0, 0);
1163 ok(d == 0, "d = %f\n", d);
1164 ok(ret == FP_ZERO, "ret = %x\n", ret);
1166 d = 1;
1167 ret = p__FExp(&d, 1, 0);
1168 ok(compare_float(d, 2.7182817, 4), "d = %f\n", d);
1169 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1171 d = 9e20;
1172 ret = p__FExp(&d, 0, 0);
1173 ok(d == 0, "d = %f\n", d);
1174 ok(ret == FP_ZERO, "ret = %x\n", ret);
1176 d = 90;
1177 ret = p__FExp(&d, 1, 0);
1178 ok(ret == FP_INFINITE, "ret = %x\n", ret);
1180 d = 90;
1181 ret = p__FExp(&d, 1, -50);
1182 ok(compare_float(d, 1.0839359e+024, 4), "d = %g\n", d);
1183 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1186 static void test__Syserror_map(void)
1188 const char *r;
1190 r = p__Syserror_map(0);
1191 ok(!r, "_Syserror_map(0) returned %p\n", r);
1194 static void test_tr2_sys__File_size(void)
1196 ULONGLONG val;
1197 HANDLE file;
1198 LARGE_INTEGER file_size;
1199 CreateDirectoryA("tr2_test_dir", NULL);
1201 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1202 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1203 file_size.QuadPart = 7;
1204 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1205 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1206 CloseHandle(file);
1207 val = p_tr2_sys__File_size("tr2_test_dir/f1");
1208 ok(val == 7, "file_size is %s\n", wine_dbgstr_longlong(val));
1209 val = p_tr2_sys__File_size_wchar(L"tr2_test_dir/f1");
1210 ok(val == 7, "file_size is %s\n", wine_dbgstr_longlong(val));
1212 file = CreateFileA("tr2_test_dir/f2", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1213 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1214 CloseHandle(file);
1215 val = p_tr2_sys__File_size("tr2_test_dir/f2");
1216 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1218 val = p_tr2_sys__File_size("tr2_test_dir");
1219 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1221 errno = 0xdeadbeef;
1222 val = p_tr2_sys__File_size("tr2_test_dir/not_exists_file");
1223 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1224 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1226 errno = 0xdeadbeef;
1227 val = p_tr2_sys__File_size(NULL);
1228 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1229 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1231 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1232 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1233 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1236 static void test_tr2_sys__Equivalent(void)
1238 int val, i;
1239 HANDLE file;
1240 char temp_path[MAX_PATH], current_path[MAX_PATH];
1241 struct {
1242 char const *path1;
1243 char const *path2;
1244 int equivalent;
1245 } tests[] = {
1246 { NULL, NULL, -1 },
1247 { NULL, "f1", -1 },
1248 { "f1", NULL, -1 },
1249 { "f1", "tr2_test_dir", -1 },
1250 { "tr2_test_dir", "f1", -1 },
1251 { "tr2_test_dir", "tr2_test_dir", -1 },
1252 { "tr2_test_dir/./f1", "tr2_test_dir/f2", 0 },
1253 { "tr2_test_dir/f1" , "tr2_test_dir/f1", 1 },
1254 { "not_exists_file" , "tr2_test_dir/f1", 0 },
1255 { "tr2_test_dir\\f1" , "tr2_test_dir/./f1", 1 },
1256 { "not_exists_file" , "not_exists_file", -1 },
1257 { "tr2_test_dir/f1" , "not_exists_file", 0 },
1258 { "tr2_test_dir/../tr2_test_dir/f1", "tr2_test_dir/f1", 1 }
1261 GetCurrentDirectoryA(MAX_PATH, current_path);
1262 GetTempPathA(MAX_PATH, temp_path);
1263 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1264 CreateDirectoryA("tr2_test_dir", NULL);
1266 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1267 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1268 CloseHandle(file);
1269 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1270 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1271 CloseHandle(file);
1273 for(i=0; i<ARRAY_SIZE(tests); i++) {
1274 errno = 0xdeadbeef;
1275 val = p_tr2_sys__Equivalent(tests[i].path1, tests[i].path2);
1276 ok(tests[i].equivalent == val, "tr2_sys__Equivalent(): test %d expect: %d, got %d\n", i+1, tests[i].equivalent, val);
1277 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1280 val = p_tr2_sys__Equivalent_wchar(L"tr2_test_dir/f1", L"tr2_test_dir/f1");
1281 ok(val == 1, "tr2_sys__Equivalent(): expect: 1, got %d\n", val);
1282 val = p_tr2_sys__Equivalent_wchar(L"tr2_test_dir/f1", L"tr2_test_dir/f2");
1283 ok(val == 0, "tr2_sys__Equivalent(): expect: 0, got %d\n", val);
1284 val = p_tr2_sys__Equivalent_wchar(L"tr2_test_dir", L"tr2_test_dir");
1285 ok(val == -1, "tr2_sys__Equivalent(): expect: -1, got %d\n", val);
1287 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1288 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1289 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1290 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1293 static void test_tr2_sys__Current_get(void)
1295 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
1296 char *temp;
1297 WCHAR temp_path_wchar[MAX_PATH], current_path_wchar[MAX_PATH];
1298 WCHAR *temp_wchar;
1300 GetCurrentDirectoryA(MAX_PATH, origin_path);
1301 GetTempPathA(MAX_PATH, temp_path);
1303 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1304 temp = p_tr2_sys__Current_get(current_path);
1305 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1306 strcat(temp, "\\");
1307 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1309 GetTempPathW(MAX_PATH, temp_path_wchar);
1310 ok(SetCurrentDirectoryW(temp_path_wchar), "SetCurrentDirectoryW to temp_path_wchar failed\n");
1311 temp_wchar = p_tr2_sys__Current_get_wchar(current_path_wchar);
1312 ok(temp_wchar == current_path_wchar, "p_tr2_sys__Current_get_wchar returned different buffer\n");
1313 wcscat(temp_wchar, L"\\");
1314 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));
1316 ok(SetCurrentDirectoryA(origin_path), "SetCurrentDirectoryA to origin_path failed\n");
1317 temp = p_tr2_sys__Current_get(current_path);
1318 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1319 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
1322 static void test_tr2_sys__Current_set(void)
1324 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
1325 char *temp;
1327 GetTempPathA(MAX_PATH, temp_path);
1328 GetCurrentDirectoryA(MAX_PATH, origin_path);
1329 temp = p_tr2_sys__Current_get(origin_path);
1330 ok(temp == origin_path, "p_tr2_sys__Current_get returned different buffer\n");
1332 ok(p_tr2_sys__Current_set(temp_path), "p_tr2_sys__Current_set to temp_path failed\n");
1333 temp = p_tr2_sys__Current_get(current_path);
1334 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1335 strcat(temp, "\\");
1336 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1338 ok(p_tr2_sys__Current_set_wchar(L"./"), "p_tr2_sys__Current_set_wchar to temp_path failed\n");
1339 temp = p_tr2_sys__Current_get(current_path);
1340 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1341 strcat(temp, "\\");
1342 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1344 errno = 0xdeadbeef;
1345 ok(!p_tr2_sys__Current_set("not_exisist_dir"), "p_tr2_sys__Current_set to not_exist_dir succeed\n");
1346 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1348 errno = 0xdeadbeef;
1349 ok(!p_tr2_sys__Current_set("??invalid_name>>"), "p_tr2_sys__Current_set to ??invalid_name>> succeed\n");
1350 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1352 ok(p_tr2_sys__Current_set(origin_path), "p_tr2_sys__Current_set to origin_path failed\n");
1353 temp = p_tr2_sys__Current_get(current_path);
1354 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1355 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
1358 static void test_tr2_sys__Make_dir(void)
1360 int ret, i;
1361 struct {
1362 char const *path;
1363 int val;
1364 } tests[] = {
1365 { "tr2_test_dir", 1 },
1366 { "tr2_test_dir", 0 },
1367 { NULL, -1 },
1368 { "??invalid_name>>", -1 }
1371 for(i=0; i<ARRAY_SIZE(tests); i++) {
1372 errno = 0xdeadbeef;
1373 ret = p_tr2_sys__Make_dir(tests[i].path);
1374 ok(ret == tests[i].val, "tr2_sys__Make_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1375 ok(errno == 0xdeadbeef, "tr2_sys__Make_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1377 ret = p_tr2_sys__Make_dir_wchar(L"wd");
1378 ok(ret == 1, "tr2_sys__Make_dir(): expect: 1, got %d\n", ret);
1380 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1381 ok(p_tr2_sys__Remove_dir_wchar(L"wd"), "expect wd to exist\n");
1384 static void test_tr2_sys__Remove_dir(void)
1386 MSVCP_bool ret;
1387 int i;
1388 struct {
1389 char const *path;
1390 MSVCP_bool val;
1391 } tests[] = {
1392 { "tr2_test_dir", TRUE },
1393 { "tr2_test_dir", FALSE },
1394 { NULL, FALSE },
1395 { "??invalid_name>>", FALSE }
1398 ok(p_tr2_sys__Make_dir("tr2_test_dir"), "tr2_sys__Make_dir() failed\n");
1400 for(i=0; i<ARRAY_SIZE(tests); i++) {
1401 errno = 0xdeadbeef;
1402 ret = p_tr2_sys__Remove_dir(tests[i].path);
1403 ok(ret == tests[i].val, "test_tr2_sys__Remove_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1404 ok(errno == 0xdeadbeef, "test_tr2_sys__Remove_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1408 static void test_tr2_sys__Copy_file(void)
1410 HANDLE file;
1411 int ret, i;
1412 LARGE_INTEGER file_size;
1413 struct {
1414 char const *source;
1415 char const *dest;
1416 MSVCP_bool fail_if_exists;
1417 int last_error;
1418 int last_error2;
1419 } tests[] = {
1420 { "f1", "f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS },
1421 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS },
1422 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_FILE_EXISTS, ERROR_FILE_EXISTS },
1423 { "f1", "tr2_test_dir\\f1_copy", FALSE, ERROR_SUCCESS, ERROR_SUCCESS },
1424 { "tr2_test_dir", "f1", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
1425 { "tr2_test_dir", "tr2_test_dir_copy", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
1426 { NULL, "f1", TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER },
1427 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER },
1428 { "not_exist", "tr2_test_dir", TRUE, ERROR_FILE_NOT_FOUND, ERROR_FILE_NOT_FOUND },
1429 { "f1", "not_exist_dir\\f1_copy", TRUE, ERROR_PATH_NOT_FOUND, ERROR_FILE_NOT_FOUND },
1430 { "f1", "tr2_test_dir", TRUE, ERROR_ACCESS_DENIED, ERROR_FILE_EXISTS }
1433 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1434 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1435 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1436 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1437 file_size.QuadPart = 7;
1438 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1439 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1440 CloseHandle(file);
1442 for(i=0; i<ARRAY_SIZE(tests); i++) {
1443 errno = 0xdeadbeef;
1444 ret = p_tr2_sys__Copy_file(tests[i].source, tests[i].dest, tests[i].fail_if_exists);
1445 ok(ret == tests[i].last_error || ret == tests[i].last_error2,
1446 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n", i+1, tests[i].last_error, ret);
1447 ok(errno == 0xdeadbeef, "test_tr2_sys__Copy_file(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1448 if(ret == ERROR_SUCCESS)
1449 ok(p_tr2_sys__File_size(tests[i].source) == p_tr2_sys__File_size(tests[i].dest),
1450 "test_tr2_sys__Copy_file(): test %d failed, mismatched file sizes\n", i+1);
1452 ret = p_tr2_sys__Copy_file_wchar(L"f1", L"fw", TRUE);
1453 ok(ret == ERROR_SUCCESS, "test_tr2_sys__Copy_file_wchar() expect ERROR_SUCCESS, got %d\n", ret);
1455 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1456 ok(DeleteFileW(L"fw"), "expect fw to exist\n");
1457 ok(DeleteFileA("f1_copy"), "expect f1_copy to exist\n");
1458 ok(DeleteFileA("tr2_test_dir/f1_copy"), "expect tr2_test_dir/f1 to exist\n");
1459 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1460 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1463 static void test_tr2_sys__Rename(void)
1465 int ret, i;
1466 HANDLE file, h1, h2;
1467 BY_HANDLE_FILE_INFORMATION info1, info2;
1468 char temp_path[MAX_PATH], current_path[MAX_PATH];
1469 LARGE_INTEGER file_size;
1470 static const struct {
1471 char const *old_path;
1472 char const *new_path;
1473 int val;
1474 } tests[] = {
1475 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_SUCCESS },
1476 { "tr2_test_dir\\f1", NULL, ERROR_INVALID_PARAMETER },
1477 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND },
1478 { NULL, "tr2_test_dir\\NULL_rename", ERROR_INVALID_PARAMETER },
1479 { "tr2_test_dir\\f1_rename", "tr2_test_dir\\??invalid_name>>", ERROR_INVALID_NAME },
1480 { "tr2_test_dir\\not_exist_file", "tr2_test_dir\\not_exist_rename", ERROR_FILE_NOT_FOUND }
1482 static const struct {
1483 const WCHAR *old_path;
1484 const WCHAR *new_path;
1485 int val;
1486 } testsW[] = {
1487 { L"tr2_test_dir/f1", L"tr2_test_dir\\f1_rename", ERROR_SUCCESS },
1488 { L"tr2_test_dir/f1", NULL, ERROR_FILE_NOT_FOUND }, /* Differs from the A version */
1489 { L"tr2_test_dir/f1", L"tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND },
1490 { NULL, L"tr2_test_dir\\f1_rename2", ERROR_PATH_NOT_FOUND }, /* Differs from the A version */
1491 { L"tr2_test_dir\\f1_rename", L"tr2_test_dir\\??invalid>", ERROR_INVALID_NAME },
1492 { L"tr2_test_dir\\not_exist", L"tr2_test_dir\\not_exist2", ERROR_FILE_NOT_FOUND },
1493 { L"tr2_test_dir\\not_exist", L"tr2_test_dir\\??invalid>", ERROR_FILE_NOT_FOUND }
1496 GetCurrentDirectoryA(MAX_PATH, current_path);
1497 GetTempPathA(MAX_PATH, temp_path);
1498 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1499 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1501 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1502 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1503 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1504 CloseHandle(file);
1506 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1");
1507 ok(ERROR_SUCCESS == ret, "test_tr2_sys__Rename(): expect: ERROR_SUCCESS, got %d\n", ret);
1508 for(i=0; i<ARRAY_SIZE(tests); i++) {
1509 errno = 0xdeadbeef;
1510 if(tests[i].val == ERROR_SUCCESS) {
1511 h1 = CreateFileA(tests[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1512 NULL, OPEN_EXISTING, 0, 0);
1513 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1514 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1515 CloseHandle(h1);
1517 SetLastError(0xdeadbeef);
1518 ret = p_tr2_sys__Rename(tests[i].old_path, tests[i].new_path);
1519 ok(ret == tests[i].val, "test_tr2_sys__Rename(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1520 ok(errno == 0xdeadbeef, "test_tr2_sys__Rename(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1521 if(ret == ERROR_SUCCESS) {
1522 h2 = CreateFileA(tests[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1523 NULL, OPEN_EXISTING, 0, 0);
1524 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1525 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1526 CloseHandle(h2);
1527 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1528 && info1.nFileIndexLow == info2.nFileIndexLow,
1529 "test_tr2_sys__Rename(): test %d expect two files equivalent\n", i+1);
1533 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1534 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1535 file_size.QuadPart = 7;
1536 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1537 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1538 CloseHandle(file);
1539 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1_rename");
1540 ok(ret == ERROR_ALREADY_EXISTS, "test_tr2_sys__Rename(): expect: ERROR_ALREADY_EXISTS, got %d\n", ret);
1541 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")));
1542 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")));
1544 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1546 for(i=0; i<ARRAY_SIZE(testsW); i++) {
1547 errno = 0xdeadbeef;
1548 if(testsW[i].val == ERROR_SUCCESS) {
1549 h1 = CreateFileW(testsW[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1550 NULL, OPEN_EXISTING, 0, 0);
1551 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1552 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1553 CloseHandle(h1);
1555 SetLastError(0xdeadbeef);
1556 ret = p_tr2_sys__Rename_wchar(testsW[i].old_path, testsW[i].new_path);
1557 ok(ret == testsW[i].val, "test_tr2_sys__Rename_wchar(): test %d expect: %d, got %d\n", i+1, testsW[i].val, ret);
1558 ok(errno == 0xdeadbeef, "test_tr2_sys__Rename_wchar(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1559 if(ret == ERROR_SUCCESS) {
1560 h2 = CreateFileW(testsW[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1561 NULL, OPEN_EXISTING, 0, 0);
1562 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1563 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1564 CloseHandle(h2);
1565 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1566 && info1.nFileIndexLow == info2.nFileIndexLow,
1567 "test_tr2_sys__Rename_wchar(): test %d expect two files equivalent\n", i+1);
1571 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1572 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1573 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect %d got %d\n", 1, ret);
1574 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1577 static void test_tr2_sys__Statvfs(void)
1579 struct space_info info;
1580 char current_path[MAX_PATH];
1581 WCHAR current_path_wchar[MAX_PATH];
1583 p_tr2_sys__Current_get(current_path);
1584 p_tr2_sys__Current_get_wchar(current_path_wchar);
1586 p_tr2_sys__Statvfs(&info, current_path);
1587 ok(info.capacity >= info.free, "test_tr2_sys__Statvfs(): info.capacity < info.free\n");
1588 ok(info.free >= info.available, "test_tr2_sys__Statvfs(): info.free < info.available\n");
1590 p_tr2_sys__Statvfs_wchar(&info, current_path_wchar);
1591 ok(info.capacity >= info.free, "tr2_sys__Statvfs_wchar(): info.capacity < info.free\n");
1592 ok(info.free >= info.available, "tr2_sys__Statvfs_wchar(): info.free < info.available\n");
1594 p_tr2_sys__Statvfs(&info, NULL);
1595 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1596 0, wine_dbgstr_longlong(info.available));
1597 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1598 0, wine_dbgstr_longlong(info.capacity));
1599 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1600 0, wine_dbgstr_longlong(info.free));
1602 p_tr2_sys__Statvfs(&info, "not_exist");
1603 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1604 0, wine_dbgstr_longlong(info.available));
1605 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1606 0, wine_dbgstr_longlong(info.capacity));
1607 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1608 0, wine_dbgstr_longlong(info.free));
1611 static void test_tr2_sys__Stat(void)
1613 int i, err_code, ret;
1614 HANDLE file;
1615 enum file_type val;
1616 struct {
1617 char const *path;
1618 enum file_type ret;
1619 int err_code;
1620 int is_todo;
1621 } tests[] = {
1622 { NULL, status_unknown, ERROR_INVALID_PARAMETER, FALSE },
1623 { "tr2_test_dir", directory_file, ERROR_SUCCESS, FALSE },
1624 { "tr2_test_dir\\f1", regular_file, ERROR_SUCCESS, FALSE },
1625 { "tr2_test_dir\\not_exist_file ", file_not_found, ERROR_SUCCESS, FALSE },
1626 { "tr2_test_dir\\??invalid_name>>", file_not_found, ERROR_SUCCESS, FALSE },
1627 { "tr2_test_dir\\f1_link" , regular_file, ERROR_SUCCESS, TRUE },
1628 { "tr2_test_dir\\dir_link", directory_file, ERROR_SUCCESS, TRUE },
1631 CreateDirectoryA("tr2_test_dir", NULL);
1632 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1633 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1634 ok(CloseHandle(file), "CloseHandle\n");
1635 SetLastError(0xdeadbeef);
1636 ret = pCreateSymbolicLinkA ? pCreateSymbolicLinkA("tr2_test_dir/f1_link", "tr2_test_dir/f1", 0) : FALSE;
1637 if(!ret && (!pCreateSymbolicLinkA || GetLastError()==ERROR_PRIVILEGE_NOT_HELD||GetLastError()==ERROR_INVALID_FUNCTION)) {
1638 tests[5].ret = tests[6].ret = file_not_found;
1639 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1640 }else {
1641 ok(ret, "CreateSymbolicLinkA failed\n");
1642 ok(pCreateSymbolicLinkA("tr2_test_dir/dir_link", "tr2_test_dir", 1), "CreateSymbolicLinkA failed\n");
1645 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1646 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
1647 NMPWAIT_USE_DEFAULT_WAIT, NULL);
1648 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1649 err_code = 0xdeadbeef;
1650 val = p_tr2_sys__Stat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1651 todo_wine ok(regular_file == val, "tr2_sys__Stat(): expect: regular_file, got %d\n", val);
1652 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Stat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
1653 err_code = 0xdeadbeef;
1654 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1655 ok(status_unknown == val, "tr2_sys__Lstat(): expect: status_unknown, got %d\n", val);
1656 todo_wine ok(ERROR_PIPE_BUSY == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_PIPE_BUSY, got %d\n", err_code);
1657 ok(CloseHandle(file), "CloseHandle\n");
1658 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1659 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
1660 NMPWAIT_USE_DEFAULT_WAIT, NULL);
1661 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1662 err_code = 0xdeadbeef;
1663 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1664 todo_wine ok(regular_file == val, "tr2_sys__Lstat(): expect: regular_file, got %d\n", val);
1665 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
1666 ok(CloseHandle(file), "CloseHandle\n");
1668 for(i=0; i<ARRAY_SIZE(tests); i++) {
1669 err_code = 0xdeadbeef;
1670 val = p_tr2_sys__Stat(tests[i].path, &err_code);
1671 todo_wine_if(tests[i].is_todo)
1672 ok(tests[i].ret == val, "tr2_sys__Stat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1673 ok(tests[i].err_code == err_code, "tr2_sys__Stat(): test %d err_code expect: %d, got %d\n",
1674 i+1, tests[i].err_code, err_code);
1676 /* test tr2_sys__Lstat */
1677 err_code = 0xdeadbeef;
1678 val = p_tr2_sys__Lstat(tests[i].path, &err_code);
1679 todo_wine_if(tests[i].is_todo)
1680 ok(tests[i].ret == val, "tr2_sys__Lstat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1681 ok(tests[i].err_code == err_code, "tr2_sys__Lstat(): test %d err_code expect: %d, got %d\n",
1682 i+1, tests[i].err_code, err_code);
1685 err_code = 0xdeadbeef;
1686 val = p_tr2_sys__Stat_wchar(L"tr2_test_dir", &err_code);
1687 ok(directory_file == val, "tr2_sys__Stat_wchar() expect directory_file, got %d\n", val);
1688 ok(ERROR_SUCCESS == err_code, "tr2_sys__Stat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code);
1689 err_code = 0xdeadbeef;
1690 val = p_tr2_sys__Lstat_wchar(L"tr2_test_dir/f1", &err_code);
1691 ok(regular_file == val, "tr2_sys__Lstat_wchar() expect regular_file, got %d\n", val);
1692 ok(ERROR_SUCCESS == err_code, "tr2_sys__Lstat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code);
1694 if(ret) {
1695 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1696 todo_wine ok(RemoveDirectoryA("tr2_test_dir/dir_link"), "expect tr2_test_dir/dir_link to exist\n");
1698 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1699 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1702 static void test_tr2_sys__Last_write_time(void)
1704 HANDLE file;
1705 int ret;
1706 __int64 last_write_time, newtime;
1707 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1708 ok(ret == 1, "tr2_sys__Make_dir() expect 1 got %d\n", ret);
1710 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1711 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1712 CloseHandle(file);
1714 last_write_time = p_tr2_sys__Last_write_time("tr2_test_dir/f1");
1715 newtime = p_tr2_sys__Last_write_time_wchar(L"tr2_test_dir/f1");
1716 ok(last_write_time == newtime, "last_write_time = %s, newtime = %s\n",
1717 wine_dbgstr_longlong(last_write_time), wine_dbgstr_longlong(newtime));
1718 newtime = last_write_time + 123456789;
1719 p_tr2_sys__Last_write_time_set("tr2_test_dir/f1", newtime);
1720 todo_wine ok(last_write_time == p_tr2_sys__Last_write_time("tr2_test_dir/f1"),
1721 "last_write_time should have changed: %s\n",
1722 wine_dbgstr_longlong(last_write_time));
1724 errno = 0xdeadbeef;
1725 last_write_time = p_tr2_sys__Last_write_time("not_exist");
1726 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1727 ok(last_write_time == 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time));
1728 last_write_time = p_tr2_sys__Last_write_time(NULL);
1729 ok(last_write_time == 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time));
1731 p_tr2_sys__Last_write_time_set("not_exist", newtime);
1732 errno = 0xdeadbeef;
1733 p_tr2_sys__Last_write_time_set(NULL, newtime);
1734 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1736 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1737 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1738 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1741 static void test_tr2_sys__dir_operation(void)
1743 char *file_name, first_file_name[MAX_PATH], dest[MAX_PATH], longer_path[MAX_PATH];
1744 HANDLE file, result_handle;
1745 enum file_type type;
1746 int err, num_of_f1 = 0, num_of_f2 = 0, num_of_sub_dir = 0, num_of_other_files = 0;
1748 CreateDirectoryA("tr2_test_dir", NULL);
1749 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1750 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1751 CloseHandle(file);
1752 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1753 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1754 CloseHandle(file);
1755 CreateDirectoryA("tr2_test_dir/sub_dir", NULL);
1756 file = CreateFileA("tr2_test_dir/sub_dir/sub_f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1757 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1758 CloseHandle(file);
1760 GetCurrentDirectoryA(MAX_PATH, longer_path);
1761 strcat(longer_path, "\\tr2_test_dir\\");
1762 while(lstrlenA(longer_path) < MAX_PATH-1)
1763 strcat(longer_path, "s");
1764 ok(lstrlenA(longer_path) == MAX_PATH-1, "tr2_sys__Open_dir(): expect MAX_PATH, got %d\n", lstrlenA(longer_path));
1765 memset(first_file_name, 0xff, MAX_PATH);
1766 type = err = 0xdeadbeef;
1767 result_handle = NULL;
1768 result_handle = p_tr2_sys__Open_dir(first_file_name, longer_path, &err, &type);
1769 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect NULL, got %p\n", result_handle);
1770 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1771 ok(err == ERROR_BAD_PATHNAME, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1772 ok((int)type == 0xdeadbeef, "tr2_sys__Open_dir(): expect 0xdeadbeef, got %d\n", type);
1774 memset(first_file_name, 0xff, MAX_PATH);
1775 memset(dest, 0, MAX_PATH);
1776 type = err = 0xdeadbeef;
1777 result_handle = NULL;
1778 result_handle = p_tr2_sys__Open_dir(first_file_name, "tr2_test_dir", &err, &type);
1779 ok(result_handle != NULL, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle);
1780 ok(err == ERROR_SUCCESS, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1781 file_name = first_file_name;
1782 while(*file_name) {
1783 if (!strcmp(file_name, "f1")) {
1784 ++num_of_f1;
1785 ok(type == regular_file, "expect regular_file, got %d\n", type);
1786 }else if(!strcmp(file_name, "f2")) {
1787 ++num_of_f2;
1788 ok(type == regular_file, "expect regular_file, got %d\n", type);
1789 }else if(!strcmp(file_name, "sub_dir")) {
1790 ++num_of_sub_dir;
1791 ok(type == directory_file, "expect directory_file, got %d\n", type);
1792 }else {
1793 ++num_of_other_files;
1795 file_name = p_tr2_sys__Read_dir(dest, result_handle, &type);
1797 ok(type == status_unknown, "p_tr2_sys__Read_dir(): expect: status_unknown, got %d\n", type);
1798 p_tr2_sys__Close_dir(result_handle);
1799 ok(result_handle != NULL, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle);
1800 ok(num_of_f1 == 1, "found f1 %d times\n", num_of_f1);
1801 ok(num_of_f2 == 1, "found f2 %d times\n", num_of_f2);
1802 ok(num_of_sub_dir == 1, "found sub_dir %d times\n", num_of_sub_dir);
1803 ok(num_of_other_files == 0, "found %d other files\n", num_of_other_files);
1805 memset(first_file_name, 0xff, MAX_PATH);
1806 type = err = 0xdeadbeef;
1807 result_handle = file;
1808 result_handle = p_tr2_sys__Open_dir(first_file_name, "not_exist", &err, &type);
1809 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1810 ok(err == ERROR_BAD_PATHNAME, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1811 ok((int)type == 0xdeadbeef, "tr2_sys__Open_dir(): expect: 0xdeadbeef, got %d\n", type);
1812 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1814 CreateDirectoryA("empty_dir", NULL);
1815 memset(first_file_name, 0xff, MAX_PATH);
1816 type = err = 0xdeadbeef;
1817 result_handle = file;
1818 result_handle = p_tr2_sys__Open_dir(first_file_name, "empty_dir", &err, &type);
1819 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1820 ok(err == ERROR_SUCCESS, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1821 ok(type == status_unknown, "tr2_sys__Open_dir(): expect: status_unknown, got %d\n", type);
1822 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1823 p_tr2_sys__Close_dir(result_handle);
1824 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1826 ok(RemoveDirectoryA("empty_dir"), "expect empty_dir to exist\n");
1827 ok(DeleteFileA("tr2_test_dir/sub_dir/sub_f1"), "expect tr2_test_dir/sub_dir/sub_f1 to exist\n");
1828 ok(RemoveDirectoryA("tr2_test_dir/sub_dir"), "expect tr2_test_dir/sub_dir to exist\n");
1829 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1830 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1831 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1834 static void test_tr2_sys__Link(void)
1836 int ret, i;
1837 HANDLE file, h1, h2;
1838 BY_HANDLE_FILE_INFORMATION info1, info2;
1839 char temp_path[MAX_PATH], current_path[MAX_PATH];
1840 LARGE_INTEGER file_size;
1841 struct {
1842 char const *existing_path;
1843 char const *new_path;
1844 MSVCP_bool fail_if_exists;
1845 int last_error;
1846 } tests[] = {
1847 { "f1", "f1_link", TRUE, ERROR_SUCCESS },
1848 { "f1", "tr2_test_dir\\f1_link", TRUE, ERROR_SUCCESS },
1849 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", TRUE, ERROR_SUCCESS },
1850 { "tr2_test_dir", "dir_link", TRUE, ERROR_ACCESS_DENIED },
1851 { NULL, "NULL_link", TRUE, ERROR_INVALID_PARAMETER },
1852 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER },
1853 { "not_exist", "not_exist_link", TRUE, ERROR_FILE_NOT_FOUND },
1854 { "f1", "not_exist_dir\\f1_link", TRUE, ERROR_PATH_NOT_FOUND }
1857 GetCurrentDirectoryA(MAX_PATH, current_path);
1858 GetTempPathA(MAX_PATH, temp_path);
1859 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1861 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1862 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1863 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1864 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1865 file_size.QuadPart = 7;
1866 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1867 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1868 CloseHandle(file);
1870 for(i=0; i<ARRAY_SIZE(tests); i++) {
1871 errno = 0xdeadbeef;
1872 ret = p_tr2_sys__Link(tests[i].existing_path, tests[i].new_path);
1873 ok(ret == tests[i].last_error, "tr2_sys__Link(): test %d expect: %d, got %d\n",
1874 i+1, tests[i].last_error, ret);
1875 ok(errno == 0xdeadbeef, "tr2_sys__Link(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1876 if(ret == ERROR_SUCCESS)
1877 ok(p_tr2_sys__File_size(tests[i].existing_path) == p_tr2_sys__File_size(tests[i].new_path),
1878 "tr2_sys__Link(): test %d failed, mismatched file sizes\n", i+1);
1881 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1882 ok(p_tr2_sys__File_size("f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link") &&
1883 p_tr2_sys__File_size("tr2_test_dir/f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link_link"),
1884 "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")));
1885 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")));
1887 file = CreateFileA("f1_link", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1888 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1889 file_size.QuadPart = 20;
1890 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1891 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1892 CloseHandle(file);
1893 h1 = CreateFileA("f1_link", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1894 NULL, OPEN_EXISTING, 0, 0);
1895 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1896 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1897 CloseHandle(h1);
1898 h2 = CreateFileA("tr2_test_dir/f1_link", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1899 NULL, OPEN_EXISTING, 0, 0);
1900 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1901 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1902 CloseHandle(h2);
1903 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1904 && info1.nFileIndexLow == info2.nFileIndexLow,
1905 "tr2_sys__Link(): test %d expect two files equivalent\n", i+1);
1906 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")));
1908 ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1909 ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1910 ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1911 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1912 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1913 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1916 static void test_tr2_sys__Symlink(void)
1918 int ret, i;
1919 HANDLE file;
1920 LARGE_INTEGER file_size;
1921 struct {
1922 char const *existing_path;
1923 char const *new_path;
1924 int last_error;
1925 MSVCP_bool is_todo;
1926 } tests[] = {
1927 { "f1", "f1_link", ERROR_SUCCESS, FALSE },
1928 { "f1", "tr2_test_dir\\f1_link", ERROR_SUCCESS, FALSE },
1929 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", ERROR_SUCCESS, FALSE },
1930 { "tr2_test_dir", "dir_link", ERROR_SUCCESS, FALSE },
1931 { NULL, "NULL_link", ERROR_INVALID_PARAMETER, FALSE },
1932 { "f1", NULL, ERROR_INVALID_PARAMETER, FALSE },
1933 { "not_exist", "not_exist_link", ERROR_SUCCESS, FALSE },
1934 { "f1", "not_exist_dir\\f1_link", ERROR_PATH_NOT_FOUND, TRUE }
1937 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1938 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1939 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1940 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1941 file_size.QuadPart = 7;
1942 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1943 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1944 CloseHandle(file);
1946 for(i=0; i<ARRAY_SIZE(tests); i++) {
1947 errno = 0xdeadbeef;
1948 SetLastError(0xdeadbeef);
1949 ret = p_tr2_sys__Symlink(tests[i].existing_path, tests[i].new_path);
1950 if(!i && (ret==ERROR_PRIVILEGE_NOT_HELD || ret==ERROR_INVALID_FUNCTION || ret==ERROR_CALL_NOT_IMPLEMENTED)) {
1951 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1952 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1953 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1954 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1955 return;
1958 ok(errno == 0xdeadbeef, "tr2_sys__Symlink(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1959 todo_wine_if(tests[i].is_todo)
1960 ok(ret == tests[i].last_error, "tr2_sys__Symlink(): test %d expect: %d, got %d\n", i+1, tests[i].last_error, ret);
1961 if(ret == ERROR_SUCCESS)
1962 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)));
1965 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1966 todo_wine ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1967 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1968 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1969 todo_wine ok(DeleteFileA("not_exist_link"), "expect not_exist_link to exist\n");
1970 todo_wine ok(DeleteFileA("dir_link"), "expect dir_link to exist\n");
1971 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1972 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1975 static void test_tr2_sys__Unlink(void)
1977 char temp_path[MAX_PATH], current_path[MAX_PATH];
1978 int ret, i;
1979 HANDLE file;
1980 LARGE_INTEGER file_size;
1981 struct {
1982 char const *path;
1983 int last_error;
1984 MSVCP_bool is_todo;
1985 } tests[] = {
1986 { "tr2_test_dir\\f1_symlink", ERROR_SUCCESS, TRUE },
1987 { "tr2_test_dir\\f1_link", ERROR_SUCCESS, FALSE },
1988 { "tr2_test_dir\\f1", ERROR_SUCCESS, FALSE },
1989 { "tr2_test_dir", ERROR_ACCESS_DENIED, FALSE },
1990 { "not_exist", ERROR_FILE_NOT_FOUND, FALSE },
1991 { "not_exist_dir\\not_exist_file", ERROR_PATH_NOT_FOUND, FALSE },
1992 { NULL, ERROR_PATH_NOT_FOUND, FALSE }
1995 GetCurrentDirectoryA(MAX_PATH, current_path);
1996 GetTempPathA(MAX_PATH, temp_path);
1997 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1999 ret = p_tr2_sys__Make_dir("tr2_test_dir");
2000 ok(ret == 1, "tr2_sys__Make_dir(): expect 1 got %d\n", ret);
2001 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2002 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
2003 file_size.QuadPart = 7;
2004 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
2005 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
2006 CloseHandle(file);
2008 ret = p_tr2_sys__Symlink("tr2_test_dir/f1", "tr2_test_dir/f1_symlink");
2009 if(ret==ERROR_PRIVILEGE_NOT_HELD || ret==ERROR_INVALID_FUNCTION || ret==ERROR_CALL_NOT_IMPLEMENTED) {
2010 tests[0].last_error = ERROR_FILE_NOT_FOUND;
2011 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
2012 }else {
2013 ok(ret == ERROR_SUCCESS, "tr2_sys__Symlink(): expect: ERROR_SUCCESS, got %d\n", ret);
2015 ret = p_tr2_sys__Link("tr2_test_dir/f1", "tr2_test_dir/f1_link");
2016 ok(ret == ERROR_SUCCESS, "tr2_sys__Link(): expect: ERROR_SUCCESS, got %d\n", ret);
2018 for(i=0; i<ARRAY_SIZE(tests); i++) {
2019 errno = 0xdeadbeef;
2020 ret = p_tr2_sys__Unlink(tests[i].path);
2021 todo_wine_if(tests[i].is_todo)
2022 ok(ret == tests[i].last_error, "tr2_sys__Unlink(): test %d expect: %d, got %d\n",
2023 i+1, tests[i].last_error, ret);
2024 ok(errno == 0xdeadbeef, "tr2_sys__Unlink(): test %d errno expect: 0xdeadbeef, got %d\n", i+1, ret);
2027 ok(!DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 not to exist\n");
2028 ok(!DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link not to exist\n");
2029 ok(!DeleteFileA("tr2_test_dir/f1_symlink"), "expect tr2_test_dir/f1_symlink not to exist\n");
2030 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
2031 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
2033 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
2036 static int __cdecl thrd_thread(void *arg)
2038 _Thrd_t *thr = arg;
2040 if(thr)
2041 *thr = p__Thrd_current();
2042 return 0x42;
2045 static void test_thrd(void)
2047 int ret, i, r;
2048 struct test {
2049 _Thrd_t a;
2050 _Thrd_t b;
2051 int r;
2053 const HANDLE hnd1 = (HANDLE)0xcccccccc;
2054 const HANDLE hnd2 = (HANDLE)0xdeadbeef;
2055 xtime xt, before, after;
2056 MSVCRT_long diff;
2057 _Thrd_t ta, tb;
2059 struct test testeq[] = {
2060 { {0, 0}, {0, 0}, 1 },
2061 { {0, 1}, {0, 0}, 0 },
2062 { {hnd1, 0}, {hnd1, 1}, 0 },
2063 { {hnd1, 0}, {hnd2, 0}, 1 }
2066 struct test testlt[] = {
2067 { {0, 0}, {0, 0}, 0 },
2068 { {0, 0}, {0, 1}, 1 },
2069 { {0, 1}, {0, 0}, 0 },
2070 { {hnd1, 0}, {hnd2, 0}, 0 },
2071 { {hnd1, 0}, {hnd2, 1}, 1 }
2074 /* test for equal */
2075 for(i=0; i<ARRAY_SIZE(testeq); i++) {
2076 ret = p__Thrd_equal(testeq[i].a, testeq[i].b);
2077 ok(ret == testeq[i].r, "(%p %lu) = (%p %lu) expected %d, got %d\n",
2078 testeq[i].a.hnd, testeq[i].a.id, testeq[i].b.hnd, testeq[i].b.id, testeq[i].r, ret);
2081 /* test for less than */
2082 for(i=0; i<ARRAY_SIZE(testlt); i++) {
2083 ret = p__Thrd_lt(testlt[i].a, testlt[i].b);
2084 ok(ret == testlt[i].r, "(%p %lu) < (%p %lu) expected %d, got %d\n",
2085 testlt[i].a.hnd, testlt[i].a.id, testlt[i].b.hnd, testlt[i].b.id, testlt[i].r, ret);
2088 /* test for sleep */
2089 if (0) /* crash on Windows */
2090 p__Thrd_sleep(NULL);
2091 p_xtime_get(&xt, 1);
2092 xt.sec += 2;
2093 p_xtime_get(&before, 1);
2094 p__Thrd_sleep(&xt);
2095 p_xtime_get(&after, 1);
2096 diff = p__Xtime_diff_to_millis2(&after, &before);
2097 ok(diff > 2000 - TIMEDELTA, "got %d\n", diff);
2099 /* test for current */
2100 ta = p__Thrd_current();
2101 tb = p__Thrd_current();
2102 ok(ta.id == tb.id, "got a %ld b %ld\n", ta.id, tb.id);
2103 ok(ta.id == GetCurrentThreadId(), "expected %ld, got %ld\n", GetCurrentThreadId(), ta.id);
2104 /* the handles can be different if new threads are created at same time */
2105 ok(ta.hnd != NULL, "handle a is NULL\n");
2106 ok(tb.hnd != NULL, "handle b is NULL\n");
2107 ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd);
2108 ok(!CloseHandle(tb.hnd), "handle %p not closed\n", tb.hnd);
2110 /* test for create/join */
2111 if (0) /* crash on Windows */
2113 p__Thrd_create(NULL, thrd_thread, NULL);
2114 p__Thrd_create(&ta, NULL, NULL);
2116 r = -1;
2117 ret = p__Thrd_create(&ta, thrd_thread, (void*)&tb);
2118 ok(!ret, "failed to create thread, got %d\n", ret);
2119 ret = p__Thrd_join(ta, &r);
2120 ok(!ret, "failed to join thread, got %d\n", ret);
2121 ok(ta.id == tb.id, "expected %ld, got %ld\n", ta.id, tb.id);
2122 ok(ta.hnd != tb.hnd, "same handles, got %p\n", ta.hnd);
2123 ok(r == 0x42, "expected 0x42, got %d\n", r);
2124 ret = p__Thrd_detach(ta);
2125 ok(ret == 4, "_Thrd_detach should have failed with error 4, got %d\n", ret);
2127 ret = p__Thrd_create(&ta, thrd_thread, NULL);
2128 ok(!ret, "failed to create thread, got %d\n", ret);
2129 ret = p__Thrd_detach(ta);
2130 ok(!ret, "_Thrd_detach failed, got %d\n", ret);
2134 #define NUM_THREADS 10
2135 struct cndmtx
2137 HANDLE initialized;
2138 LONG started;
2139 int thread_no;
2141 _Cnd_t cnd;
2142 _Mtx_t mtx;
2143 BOOL timed_wait;
2146 static int __cdecl cnd_wait_thread(void *arg)
2148 struct cndmtx *cm = arg;
2149 int r;
2151 p__Mtx_lock(&cm->mtx);
2153 if(InterlockedIncrement(&cm->started) == cm->thread_no)
2154 SetEvent(cm->initialized);
2156 if(cm->timed_wait) {
2157 xtime xt;
2159 p_xtime_get(&xt, 1);
2160 xt.sec += 2;
2161 r = p__Cnd_timedwait(&cm->cnd, &cm->mtx, &xt);
2162 ok(!r, "timed wait failed\n");
2163 } else {
2164 r = p__Cnd_wait(&cm->cnd, &cm->mtx);
2165 ok(!r, "wait failed\n");
2168 p__Mtx_unlock(&cm->mtx);
2169 return 0;
2172 static void test_cnd(void)
2174 _Thrd_t threads[NUM_THREADS];
2175 xtime xt, before, after;
2176 MSVCRT_long diff;
2177 struct cndmtx cm;
2178 _Cnd_t cnd;
2179 _Mtx_t mtx;
2180 int r, i;
2182 r = p__Cnd_init(&cnd);
2183 ok(!r, "failed to init cnd\n");
2185 r = p__Mtx_init(&mtx, 0);
2186 ok(!r, "failed to init mtx\n");
2188 if (0) /* crash on Windows */
2190 p__Cnd_init(NULL);
2191 p__Cnd_wait(NULL, &mtx);
2192 p__Cnd_wait(&cnd, NULL);
2193 p__Cnd_timedwait(NULL, &mtx, &xt);
2194 p__Cnd_timedwait(&cnd, &mtx, &xt);
2196 p__Cnd_destroy(NULL);
2198 /* test _Cnd_signal/_Cnd_wait */
2199 cm.initialized = CreateEventW(NULL, FALSE, FALSE, NULL);
2200 cm.started = 0;
2201 cm.thread_no = 1;
2202 cm.cnd = cnd;
2203 cm.mtx = mtx;
2204 cm.timed_wait = FALSE;
2205 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2207 WaitForSingleObject(cm.initialized, INFINITE);
2208 p__Mtx_lock(&mtx);
2209 p__Mtx_unlock(&mtx);
2211 r = p__Cnd_signal(&cm.cnd);
2212 ok(!r, "failed to signal\n");
2213 p__Thrd_join(threads[0], NULL);
2215 /* test _Cnd_timedwait time out */
2216 p__Mtx_lock(&mtx);
2217 p_xtime_get(&before, 1);
2218 xt = before;
2219 xt.sec += 1;
2220 r = p__Cnd_timedwait(&cnd, &mtx, &xt);
2221 p_xtime_get(&after, 1);
2222 p__Mtx_unlock(&mtx);
2224 diff = p__Xtime_diff_to_millis2(&after, &before);
2225 ok(r == 2, "should have timed out\n");
2226 ok(diff > 1000 - TIMEDELTA, "got %d\n", diff);
2228 /* test _Cnd_timedwait */
2229 cm.started = 0;
2230 cm.timed_wait = TRUE;
2231 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2233 WaitForSingleObject(cm.initialized, INFINITE);
2234 p__Mtx_lock(&mtx);
2235 p__Mtx_unlock(&mtx);
2237 r = p__Cnd_signal(&cm.cnd);
2238 ok(!r, "failed to signal\n");
2239 p__Thrd_join(threads[0], NULL);
2241 /* test _Cnd_do_broadcast_at_thread_exit */
2242 cm.started = 0;
2243 cm.timed_wait = FALSE;
2244 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2246 WaitForSingleObject(cm.initialized, INFINITE);
2247 p__Mtx_lock(&mtx);
2249 r = 0xcafe;
2250 p__Cnd_unregister_at_thread_exit((_Mtx_t*)0xdeadbeef);
2251 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2252 ok(r == 0xcafe, "r = %x\n", r);
2253 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2254 p__Cnd_unregister_at_thread_exit(&mtx);
2255 p__Cnd_do_broadcast_at_thread_exit();
2256 ok(mtx->count == 1, "mtx.count = %ld\n", mtx->count);
2258 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2259 ok(r == 0xcafe, "r = %x\n", r);
2261 p__Cnd_do_broadcast_at_thread_exit();
2262 ok(r == 1, "r = %x\n", r);
2263 p__Thrd_join(threads[0], NULL);
2265 /* crash if _Cnd_do_broadcast_at_thread_exit is called on exit */
2266 p__Cnd_register_at_thread_exit((_Cnd_t*)0xdeadbeef, (_Mtx_t*)0xdeadbeef, (int*)0xdeadbeef);
2268 /* test _Cnd_broadcast */
2269 cm.started = 0;
2270 cm.thread_no = NUM_THREADS;
2272 for(i = 0; i < cm.thread_no; i++)
2273 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
2275 WaitForSingleObject(cm.initialized, INFINITE);
2276 p__Mtx_lock(&mtx);
2277 p__Mtx_unlock(&mtx);
2279 r = p__Cnd_broadcast(&cnd);
2280 ok(!r, "failed to broadcast\n");
2281 for(i = 0; i < cm.thread_no; i++)
2282 p__Thrd_join(threads[i], NULL);
2284 /* test broadcast with _Cnd_destroy */
2285 cm.started = 0;
2286 for(i = 0; i < cm.thread_no; i++)
2287 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
2289 WaitForSingleObject(cm.initialized, INFINITE);
2290 p__Mtx_lock(&mtx);
2291 p__Mtx_unlock(&mtx);
2293 p__Cnd_destroy(&cnd);
2294 for(i = 0; i < cm.thread_no; i++)
2295 p__Thrd_join(threads[i], NULL);
2297 p__Mtx_destroy(&mtx);
2298 CloseHandle(cm.initialized);
2301 static struct {
2302 int value[2];
2303 const char* export_name;
2304 } vbtable_size_exports_list[] = {
2305 {{0x20, 0x20}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"},
2306 {{0x10, 0x10}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"},
2307 {{0x20, 0x20}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"},
2308 {{0x10, 0x10}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"},
2309 {{0x20, 0x20}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"},
2310 {{0x10, 0x10}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"},
2311 {{0x18, 0x18}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"},
2312 {{0x18, 0x18}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"},
2313 {{0x18, 0x18}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"},
2314 {{ 0x8, 0x10}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"},
2315 {{ 0x8, 0x10}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"},
2316 {{ 0x8, 0x10}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"},
2317 {{ 0x0, 0x0}, 0}
2320 static void test_vbtable_size_exports(void)
2322 int i;
2323 const int *p_vbtable;
2324 int arch_idx = (sizeof(void*) == 8);
2326 for (i = 0; vbtable_size_exports_list[i].export_name; i++)
2328 SET(p_vbtable, vbtable_size_exports_list[i].export_name);
2330 ok(p_vbtable[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable[0]);
2331 ok(p_vbtable[1] == vbtable_size_exports_list[i].value[arch_idx],
2332 "%d: %s[1] wrong, got 0x%x\n", i, vbtable_size_exports_list[i].export_name, p_vbtable[1]);
2336 HANDLE _Pad__Launch_returned;
2337 _Pad pad;
2338 #ifdef __i386__
2339 /* TODO: this should be a __thiscall function */
2340 static unsigned int __stdcall vtbl_func__Go(void)
2341 #else
2342 static unsigned int __cdecl vtbl_func__Go(_Pad *this)
2343 #endif
2345 DWORD ret;
2347 ret = WaitForSingleObject(_Pad__Launch_returned, 100);
2348 ok(ret == WAIT_TIMEOUT, "WiatForSingleObject returned %lx\n", ret);
2349 ok(!pad.mtx->count, "pad.mtx.count = %ld\n", pad.mtx->count);
2350 ok(!pad.launched, "pad.launched = %x\n", pad.launched);
2351 call_func1(p__Pad__Release, &pad);
2352 ok(pad.launched, "pad.launched = %x\n", pad.launched);
2353 ret = WaitForSingleObject(_Pad__Launch_returned, 100);
2354 ok(ret == WAIT_OBJECT_0, "WiatForSingleObject returned %lx\n", ret);
2355 ok(pad.mtx->count == 1, "pad.mtx.count = %ld\n", pad.mtx->count);
2356 return 0;
2359 static void test__Pad(void)
2361 _Pad pad_copy;
2362 _Thrd_t thrd;
2363 vtable_ptr pfunc = (vtable_ptr)&vtbl_func__Go;
2365 _Pad__Launch_returned = CreateEventW(NULL, FALSE, FALSE, NULL);
2367 pad.vtable = (void*)1;
2368 pad.cnd = (void*)2;
2369 pad.mtx = (void*)3;
2370 pad.launched = TRUE;
2371 memset(&pad_copy, 0, sizeof(pad_copy));
2372 call_func2(p__Pad_copy_ctor, &pad_copy, &pad);
2373 ok(pad_copy.vtable != (void*)1, "pad_copy.vtable was not set\n");
2374 ok(pad_copy.cnd == (void*)2, "pad_copy.cnd = %p\n", pad_copy.cnd);
2375 ok(pad_copy.mtx == (void*)3, "pad_copy.mtx = %p\n", pad_copy.mtx);
2376 ok(pad_copy.launched, "pad_copy.launched = %x\n", pad_copy.launched);
2378 memset(&pad_copy, 0xde, sizeof(pad_copy));
2379 pad_copy.vtable = (void*)4;
2380 pad_copy.cnd = (void*)5;
2381 pad_copy.mtx = (void*)6;
2382 pad_copy.launched = FALSE;
2383 call_func2(p__Pad_op_assign, &pad_copy, &pad);
2384 ok(pad_copy.vtable == (void*)4, "pad_copy.vtable was set\n");
2385 ok(pad_copy.cnd == (void*)2, "pad_copy.cnd = %p\n", pad_copy.cnd);
2386 ok(pad_copy.mtx == (void*)3, "pad_copy.mtx = %p\n", pad_copy.mtx);
2387 ok(pad_copy.launched, "pad_copy.launched = %x\n", pad_copy.launched);
2389 call_func1(p__Pad_ctor, &pad);
2390 call_func2(p__Pad_copy_ctor, &pad_copy, &pad);
2391 ok(pad.vtable == pad_copy.vtable, "pad.vtable = %p, pad_copy.vtable = %p\n", pad.vtable, pad_copy.vtable);
2392 ok(pad.cnd == pad_copy.cnd, "pad.cnd = %p, pad_copy.cnd = %p\n", pad.cnd, pad_copy.cnd);
2393 ok(pad.mtx == pad_copy.mtx, "pad.mtx = %p, pad_copy.mtx = %p\n", pad.mtx, pad_copy.mtx);
2394 ok(pad.launched == pad_copy.launched, "pad.launched = %x, pad_copy.launched = %x\n", pad.launched, pad_copy.launched);
2395 call_func1(p__Pad_dtor, &pad);
2396 /* call_func1(p__Pad_dtor, &pad_copy); - copy constructor is broken, this causes a crash */
2398 memset(&pad, 0xfe, sizeof(pad));
2399 call_func1(p__Pad_ctor, &pad);
2400 ok(!pad.launched, "pad.launched = %x\n", pad.launched);
2401 ok(pad.mtx->count == 1, "pad.mtx.count = %ld\n", pad.mtx->count);
2403 pad.vtable = &pfunc;
2404 call_func2(p__Pad__Launch, &pad, &thrd);
2405 SetEvent(_Pad__Launch_returned);
2406 ok(!p__Thrd_join(thrd, NULL), "_Thrd_join failed\n");
2408 call_func1(p__Pad_dtor, &pad);
2409 CloseHandle(_Pad__Launch_returned);
2412 static void test__Mtx(void)
2415 static int flags[] =
2417 0, MTX_PLAIN, MTX_TRY, MTX_TIMED, MTX_RECURSIVE,
2418 MTX_PLAIN|MTX_TRY, MTX_PLAIN|MTX_RECURSIVE, MTX_PLAIN|0xbeef
2420 _Mtx_t mtx;
2421 int i, r, expect;
2423 for (i=0; i<ARRAY_SIZE(flags); i++)
2425 if (flags[i] == MTX_PLAIN || flags[i] & MTX_RECURSIVE)
2426 expect = 0;
2427 else
2428 expect = 3;
2430 r = p__Mtx_init(&mtx, flags[i]);
2431 ok(!r, "failed to init mtx (flags %x)\n", flags[i]);
2432 ok(mtx->thread_id == -1, "mtx.thread_id = %lx (flags %x)\n", mtx->thread_id, flags[i]);
2433 ok(mtx->count == 0, "mtx.count = %lu (flags %x)\n", mtx->count, flags[i]);
2435 r = p__Mtx_trylock(&mtx);
2436 ok(!r, "_Mtx_trylock returned %x (flags %x)\n", r, flags[i]);
2437 ok(mtx->thread_id == GetCurrentThreadId(), "mtx.thread_id = %lx (flags %x)\n", mtx->thread_id, flags[i]);
2438 ok(mtx->count == 1, "mtx.count = %lu (flags %x)\n", mtx->count, flags[i]);
2439 r = p__Mtx_trylock(&mtx);
2440 ok(r == expect, "_Mtx_trylock returned %x (flags %x)\n", r, flags[i]);
2441 ok(mtx->thread_id == GetCurrentThreadId(), "mtx.thread_id = %lx (flags %x)\n", mtx->thread_id, flags[i]);
2442 ok(mtx->count == r ? 1 : 2, "mtx.count = %lu, expected %u (flags %x)\n", mtx->count, r ? 1 : 2, flags[i]);
2443 if(!r) p__Mtx_unlock(&mtx);
2445 r = p__Mtx_lock(&mtx);
2446 ok(r == expect, "_Mtx_lock returned %x (flags %x)\n", r, flags[i]);
2447 ok(mtx->thread_id == GetCurrentThreadId(), "mtx.thread_id = %lx (flags %x)\n", mtx->thread_id, flags[i]);
2448 ok(mtx->count == r ? 1 : 2, "mtx.count = %lu, expected %u (flags %x)\n", mtx->count, r ? 1 : 2, flags[i]);
2449 if(!r) p__Mtx_unlock(&mtx);
2451 p__Mtx_unlock(&mtx);
2452 ok(mtx->thread_id == -1, "mtx.thread_id = %lx (flags %x)\n", mtx->thread_id, flags[i]);
2453 ok(mtx->count == 0, "mtx.count = %lu (flags %x)\n", mtx->count, flags[i]);
2454 p__Mtx_destroy(&mtx);
2458 static void test_threads__Mtx(void)
2460 void *mtx = NULL;
2462 p_threads__Mtx_new(&mtx);
2463 ok(mtx != NULL, "mtx == NULL\n");
2465 p_threads__Mtx_lock(mtx);
2466 p_threads__Mtx_lock(mtx);
2467 p_threads__Mtx_unlock(mtx);
2468 p_threads__Mtx_unlock(mtx);
2469 p_threads__Mtx_unlock(mtx);
2471 p_threads__Mtx_delete(mtx);
2474 static void test_vector_base_v4__Segment_index_of(void)
2476 size_t i;
2477 size_t ret;
2478 struct {
2479 size_t x;
2480 size_t expect;
2481 } tests[] = {
2482 {0, 0},
2483 {1, 0},
2484 {2, 1},
2485 {3, 1},
2486 {4, 2},
2487 {7, 2},
2488 {8, 3},
2489 {15, 3},
2490 {16, 4},
2491 {31, 4},
2492 {32, 5},
2493 {~0, 8*sizeof(void*)-1}
2496 for(i=0; i<ARRAY_SIZE(tests); i++) {
2497 ret = p_vector_base_v4__Segment_index_of(tests[i].x);
2498 ok(ret == tests[i].expect, "expected %ld, got %ld for %ld\n",
2499 (long)tests[i].expect, (long)ret, (long)tests[i].x);
2503 static HANDLE block_start, block_end;
2504 static BOOL block;
2506 static void __thiscall queue_char__Move_item(
2507 #ifndef __i386__
2508 queue_base_v4 *this,
2509 #endif
2510 _Page *dst, size_t idx, void *src)
2512 CHECK_EXPECT(queue_char__Move_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__Copy_item(
2522 #ifndef __i386__
2523 queue_base_v4 *this,
2524 #endif
2525 _Page *dst, size_t idx, const void *src)
2527 CHECK_EXPECT(queue_char__Copy_item);
2528 if(block) {
2529 block = FALSE;
2530 SetEvent(block_start);
2531 WaitForSingleObject(block_end, INFINITE);
2533 memcpy(dst->data + idx, src, sizeof(char));
2536 static void __thiscall queue_char__Assign_and_destroy_item(
2537 #ifndef __i386__
2538 queue_base_v4 *this,
2539 #endif
2540 void *dst, _Page *src, size_t idx)
2542 CHECK_EXPECT(queue_char__Assign_and_destroy_item);
2543 if(block) {
2544 block = FALSE;
2545 SetEvent(block_start);
2546 WaitForSingleObject(block_end, INFINITE);
2548 memcpy(dst, src->data + idx, sizeof(char));
2551 #ifndef __i386__
2552 static _Page* __thiscall queue_char__Allocate_page(queue_base_v4 *this)
2553 #else
2554 static _Page* __thiscall queue_char__Allocate_page(void)
2555 #endif
2557 CHECK_EXPECT(queue_char__Allocate_page);
2558 return malloc(sizeof(_Page) + sizeof(char[256]));
2561 static void __thiscall queue_char__Deallocate_page(
2562 #ifndef __i386__
2563 queue_base_v4 *this,
2564 #endif
2565 _Page *page)
2567 CHECK_EXPECT2(queue_char__Deallocate_page);
2568 free(page);
2571 static const void* queue_char_vtbl[] =
2573 queue_char__Move_item,
2574 queue_char__Copy_item,
2575 queue_char__Assign_and_destroy_item,
2576 NULL, /* dtor */
2577 queue_char__Allocate_page,
2578 queue_char__Deallocate_page
2581 static DWORD WINAPI queue_move_push_thread(void *arg)
2583 queue_base_v4 *queue = arg;
2584 char c = 'm';
2586 alloc_expect_struct();
2587 SET_EXPECT(queue_char__Allocate_page); /* ignore page allocations */
2588 SET_EXPECT(queue_char__Move_item);
2589 call_func2(p_queue_base_v4__Internal_move_push, queue, &c);
2590 CHECK_CALLED(queue_char__Move_item);
2591 free_expect_struct();
2592 return 0;
2595 static DWORD WINAPI queue_push_thread(void *arg)
2597 queue_base_v4 *queue = arg;
2598 char c = 'c';
2600 alloc_expect_struct();
2601 SET_EXPECT(queue_char__Copy_item);
2602 call_func2(p_queue_base_v4__Internal_push, queue, &c);
2603 CHECK_CALLED(queue_char__Copy_item);
2604 free_expect_struct();
2605 return 0;
2608 static DWORD WINAPI queue_pop_thread(void*arg)
2610 queue_base_v4 *queue = arg;
2611 char c;
2613 alloc_expect_struct();
2614 SET_EXPECT(queue_char__Assign_and_destroy_item);
2615 call_func2(p_queue_base_v4__Internal_pop_if_present, queue, &c);
2616 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2617 free_expect_struct();
2618 return 0;
2621 static void* __cdecl concurrent_vector_int_alloc(vector_base_v4 *this, size_t n)
2623 CHECK_EXPECT(concurrent_vector_int_alloc);
2624 vector_alloc_count++;
2625 return malloc(n*sizeof(int));
2628 static void __cdecl concurrent_vector_int_destroy(void *ptr, size_t n)
2630 CHECK_EXPECT2(concurrent_vector_int_destroy);
2631 ok(vector_elem_count >= n, "invalid destroy\n");
2632 vector_elem_count -= n;
2633 memset(ptr, 0xff, sizeof(int)*n);
2636 static void concurrent_vector_int_ctor(vector_base_v4 *this)
2638 memset(this, 0, sizeof(*this));
2639 this->allocator = concurrent_vector_int_alloc;
2640 this->segment = &this->storage[0];
2643 static void concurrent_vector_int_dtor(vector_base_v4 *this)
2645 size_t blocks;
2647 blocks = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2648 this, concurrent_vector_int_destroy);
2649 for(blocks--; blocks >= this->first_block; blocks--) {
2650 vector_alloc_count--;
2651 free(this->segment[blocks]);
2654 if(this->first_block) {
2655 vector_alloc_count--;
2656 free(this->segment[0]);
2659 call_func1(p_vector_base_v4_dtor, this);
2662 static void __cdecl concurrent_vector_int_copy(void *dst, const void *src, size_t n)
2664 CHECK_EXPECT2(concurrent_vector_int_copy);
2665 vector_elem_count += n;
2666 memcpy(dst, src, n*sizeof(int));
2669 static void __cdecl concurrent_vector_int_assign(void *dst, const void *src, size_t n)
2671 CHECK_EXPECT2(concurrent_vector_int_assign);
2672 memcpy(dst, src, n*sizeof(int));
2675 static void test_queue_base_v4(void)
2677 queue_base_v4 queue;
2678 HANDLE thread[2];
2679 MSVCP_bool b;
2680 size_t size;
2681 DWORD ret;
2682 int i;
2683 char c;
2685 block_start = CreateEventW(NULL, FALSE, FALSE, NULL);
2686 block_end = CreateEventW(NULL, FALSE, FALSE, NULL);
2688 call_func2(p_queue_base_v4_ctor, &queue, 0);
2689 ok(queue.data != NULL, "queue.data = NULL\n");
2690 ok(queue.alloc_count == 32, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2691 ok(queue.item_size == 0, "queue.item_size = %ld\n", (long)queue.item_size);
2692 call_func1(p_queue_base_v4_dtor, &queue);
2694 call_func2(p_queue_base_v4_ctor, &queue, 8);
2695 ok(queue.data != NULL, "queue.data = NULL\n");
2696 ok(queue.alloc_count == 32, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2697 ok(queue.item_size == 8, "queue.item_size = %ld\n", (long)queue.item_size);
2698 call_func1(p_queue_base_v4_dtor, &queue);
2700 call_func2(p_queue_base_v4_ctor, &queue, 16);
2701 ok(queue.data != NULL, "queue.data = NULL\n");
2702 ok(queue.alloc_count == 16, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2703 ok(queue.item_size == 16, "queue.item_size = %ld\n", (long)queue.item_size);
2704 b = (DWORD_PTR)call_func1(p_queue_base_v4__Internal_empty, &queue);
2705 ok(b, "queue is not empty\n");
2706 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2707 ok(!size, "size = %ld\n", (long)size);
2708 call_func1(p_queue_base_v4_dtor, &queue);
2710 call_func2(p_queue_base_v4_ctor, &queue, 1);
2711 queue.vtable = (void*)&queue_char_vtbl;
2713 for(i=0; i<8; i++) {
2714 SET_EXPECT(queue_char__Allocate_page);
2715 SET_EXPECT(queue_char__Copy_item);
2716 c = 'a'+i;
2717 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2718 CHECK_CALLED(queue_char__Allocate_page);
2719 CHECK_CALLED(queue_char__Copy_item);
2721 b = (MSVCP_bool)(DWORD_PTR)call_func1(p_queue_base_v4__Internal_empty, &queue);
2722 ok(!b, "queue is empty\n");
2723 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2724 ok(size == i+1, "size = %ld, expected %ld\n", (long)size, (long)i);
2727 SET_EXPECT(queue_char__Copy_item);
2728 c = 'a'+i;
2729 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2730 CHECK_CALLED(queue_char__Copy_item);
2732 for(i=0; i<9; i++) {
2733 SET_EXPECT(queue_char__Assign_and_destroy_item);
2734 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2735 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2736 ok(b, "pop returned false\n");
2737 ok(c == 'a'+i, "got '%c', expected '%c'\n", c, 'a'+i);
2739 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2740 ok(!b, "pop returned true\n");
2742 for(i=0; i<247; i++) {
2743 SET_EXPECT(queue_char__Copy_item);
2744 c = 'a'+i;
2745 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2746 CHECK_CALLED(queue_char__Copy_item);
2748 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2749 ok(size == i+1, "size = %ld, expected %ld\n", (long)size, (long)i);
2752 SET_EXPECT(queue_char__Allocate_page);
2753 SET_EXPECT(queue_char__Copy_item);
2754 c = 'a'+i;
2755 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2756 CHECK_CALLED(queue_char__Allocate_page);
2757 CHECK_CALLED(queue_char__Copy_item);
2759 for(i=0; i<239; i++) {
2760 SET_EXPECT(queue_char__Assign_and_destroy_item);
2761 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2762 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2763 ok(b, "pop returned false\n");
2764 ok(c == (char)('a'+i), "got '%c', expected '%c'\n", c, 'a'+i);
2767 SET_EXPECT(queue_char__Assign_and_destroy_item);
2768 SET_EXPECT(queue_char__Deallocate_page);
2769 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2770 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2771 CHECK_CALLED(queue_char__Deallocate_page);
2772 ok(b, "pop returned false\n");
2773 ok(c == (char)('a'+i), "got '%c', expected '%c'\n", c, 'a'+i);
2775 /* destructor doesn't clear the memory, _Internal_finish_clear needs to be called */
2776 SET_EXPECT(queue_char__Deallocate_page);
2777 call_func1(p_queue_base_v4__Internal_finish_clear, &queue);
2778 CHECK_CALLED(queue_char__Deallocate_page);
2780 call_func1(p_queue_base_v4_dtor, &queue);
2782 /* test parallel push */
2783 call_func2(p_queue_base_v4_ctor, &queue, 1);
2784 queue.vtable = (void*)&queue_char_vtbl;
2786 block = TRUE;
2787 thread[0] = CreateThread(NULL, 0, queue_move_push_thread, &queue, 0, NULL);
2788 WaitForSingleObject(block_start, INFINITE);
2790 c = 'a';
2791 for(i=0; i<7; i++) {
2792 SET_EXPECT(queue_char__Allocate_page);
2793 SET_EXPECT(queue_char__Copy_item);
2794 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2795 CHECK_CALLED(queue_char__Allocate_page);
2796 CHECK_CALLED(queue_char__Copy_item);
2799 thread[1] = CreateThread(NULL, 0, queue_push_thread, &queue, 0, NULL);
2800 ret = WaitForSingleObject(thread[1], 100);
2801 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %lx\n", ret);
2803 SetEvent(block_end);
2804 WaitForSingleObject(thread[0], INFINITE);
2805 WaitForSingleObject(thread[1], INFINITE);
2806 CloseHandle(thread[0]);
2807 CloseHandle(thread[1]);
2809 /* test parallel pop */
2810 block = TRUE;
2811 thread[0] = CreateThread(NULL, 0, queue_pop_thread, &queue, 0, NULL);
2812 WaitForSingleObject(block_start, INFINITE);
2814 for(i=0; i<7; i++) {
2815 SET_EXPECT(queue_char__Assign_and_destroy_item);
2816 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2817 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2818 ok(b, "pop returned false\n");
2819 ok(c == 'a', "got '%c', expected 'a'\n", c);
2822 thread[1] = CreateThread(NULL, 0, queue_pop_thread, &queue, 0, NULL);
2823 ret = WaitForSingleObject(thread[1], 100);
2824 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %lx\n", ret);
2826 SetEvent(block_end);
2827 WaitForSingleObject(thread[0], INFINITE);
2828 WaitForSingleObject(thread[1], INFINITE);
2829 CloseHandle(thread[0]);
2830 CloseHandle(thread[1]);
2832 /* test parallel push/pop */
2833 for(i=0; i<8; i++) {
2834 SET_EXPECT(queue_char__Copy_item);
2835 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2836 CHECK_CALLED(queue_char__Copy_item);
2839 block = TRUE;
2840 thread[0] = CreateThread(NULL, 0, queue_push_thread, &queue, 0, NULL);
2841 WaitForSingleObject(block_start, INFINITE);
2843 SET_EXPECT(queue_char__Assign_and_destroy_item);
2844 call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2845 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2847 SetEvent(block_end);
2848 WaitForSingleObject(thread[0], INFINITE);
2849 CloseHandle(thread[0]);
2851 for(i=0; i<8; i++) {
2852 SET_EXPECT(queue_char__Assign_and_destroy_item);
2853 call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2854 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2857 SET_EXPECT(queue_char__Deallocate_page);
2858 call_func1(p_queue_base_v4__Internal_finish_clear, &queue);
2859 CHECK_CALLED(queue_char__Deallocate_page);
2860 call_func1(p_queue_base_v4_dtor, &queue);
2862 CloseHandle(block_start);
2863 CloseHandle(block_end);
2866 static void test_vector_base_v4(void)
2868 vector_base_v4 vector, v2;
2869 size_t idx, size;
2870 compact_block b;
2871 int i, *data;
2873 concurrent_vector_int_ctor(&vector);
2875 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2876 ok(size == 0, "size of vector got %ld expected 0\n", (long)size);
2878 SET_EXPECT(concurrent_vector_int_alloc);
2879 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2880 if(!data) {
2881 skip("_Internal_push_back not yet implemented\n");
2882 return;
2884 CHECK_CALLED(concurrent_vector_int_alloc);
2885 ok(data != NULL, "_Internal_push_back returned NULL\n");
2886 ok(idx == 0, "idx got %ld expected %d\n", (long)idx, 0);
2887 vector_elem_count++;
2888 *data = 1;
2889 ok(data == vector.storage[0], "vector.storage[0] got %p expected %p\n",
2890 vector.storage[0], data);
2891 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2892 (long)vector.first_block);
2893 ok(vector.early_size == 1, "vector.early_size got %ld expected 1\n",
2894 (long)vector.early_size);
2895 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2896 vector.segment, vector.storage);
2897 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2898 ok(size == 2, "size of vector got %ld expected 2\n", (long)size);
2900 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2901 ok(data != NULL, "_Internal_push_back returned NULL\n");
2902 ok(idx == 1, "idx got %ld expected 1\n", (long)idx);
2903 vector_elem_count++;
2904 *data = 2;
2905 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2906 (long)vector.first_block);
2907 ok(vector.early_size == 2, "vector.early_size got %ld expected 2\n",
2908 (long)vector.early_size);
2910 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2911 ok(size == 2, "size of vector got %ld expected 2\n", (long)size);
2913 SET_EXPECT(concurrent_vector_int_alloc);
2914 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2915 CHECK_CALLED(concurrent_vector_int_alloc);
2916 ok(data != NULL, "_Internal_push_back returned NULL\n");
2917 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
2918 vector_elem_count++;
2919 *data = 3;
2920 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2921 vector.segment, vector.storage);
2922 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2923 (long)vector.first_block);
2924 ok(vector.early_size == 3, "vector.early_size got %ld expected 3\n",
2925 (long)vector.early_size);
2926 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2927 ok(size == 4, "size of vector got %ld expected %d\n", (long)size, 4);
2929 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2930 ok(data != NULL, "_Internal_push_back returned NULL\n");
2931 ok(idx == 3, "idx got %ld expected 3\n", (long)idx);
2932 vector_elem_count++;
2933 *data = 4;
2934 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2935 ok(size == 4, "size of vector got %ld expected 4\n", (long)size);
2937 SET_EXPECT(concurrent_vector_int_alloc);
2938 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2939 CHECK_CALLED(concurrent_vector_int_alloc);
2940 ok(data != NULL, "_Internal_push_back returned NULL\n");
2941 ok(idx == 4, "idx got %ld expected 4\n", (long)idx);
2942 vector_elem_count++;
2943 *data = 5;
2944 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2945 vector.segment, vector.storage);
2946 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2947 ok(size == 8, "size of vector got %ld expected 8\n", (long)size);
2949 concurrent_vector_int_ctor(&v2);
2950 SET_EXPECT(concurrent_vector_int_alloc);
2951 SET_EXPECT(concurrent_vector_int_copy);
2952 call_func4(p_vector_base_v4__Internal_copy, &v2, &vector,
2953 sizeof(int), concurrent_vector_int_copy);
2954 CHECK_CALLED(concurrent_vector_int_alloc);
2955 CHECK_CALLED(concurrent_vector_int_copy);
2956 ok(v2.first_block == 3, "v2.first_block got %ld expected 3\n",
2957 (long)v2.first_block);
2958 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
2959 (long)v2.early_size);
2960 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
2961 v2.segment, v2.storage);
2962 SET_EXPECT(concurrent_vector_int_destroy);
2963 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2964 &v2, concurrent_vector_int_destroy);
2965 CHECK_CALLED(concurrent_vector_int_destroy);
2966 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
2967 concurrent_vector_int_dtor(&v2);
2969 concurrent_vector_int_ctor(&v2);
2970 SET_EXPECT(concurrent_vector_int_alloc);
2971 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2972 CHECK_CALLED(concurrent_vector_int_alloc);
2973 ok(data != NULL, "_Internal_push_back returned NULL\n");
2974 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2975 ok(data != NULL, "_Internal_push_back returned NULL\n");
2976 SET_EXPECT(concurrent_vector_int_alloc);
2977 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2978 ok(data != NULL, "_Internal_push_back returned NULL\n");
2979 CHECK_CALLED(concurrent_vector_int_alloc);
2980 vector_elem_count += 3;
2981 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
2982 SET_EXPECT(concurrent_vector_int_assign);
2983 SET_EXPECT(concurrent_vector_int_copy);
2984 SET_EXPECT(concurrent_vector_int_alloc);
2985 call_func6(p_vector_base_v4__Internal_assign, &v2, &vector, sizeof(int),
2986 concurrent_vector_int_destroy, concurrent_vector_int_assign,
2987 concurrent_vector_int_copy);
2988 CHECK_CALLED(concurrent_vector_int_assign);
2989 CHECK_CALLED(concurrent_vector_int_copy);
2990 CHECK_CALLED(concurrent_vector_int_alloc);
2991 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n",
2992 (long)v2.first_block);
2993 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
2994 (long)v2.early_size);
2995 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
2996 v2.segment, v2.storage);
2997 SET_EXPECT(concurrent_vector_int_destroy);
2998 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2999 &v2, concurrent_vector_int_destroy);
3000 CHECK_CALLED(concurrent_vector_int_destroy);
3001 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
3002 concurrent_vector_int_dtor(&v2);
3004 concurrent_vector_int_ctor(&v2);
3005 SET_EXPECT(concurrent_vector_int_alloc);
3006 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3007 ok(data != NULL, "_Internal_push_back returned NULL\n");
3008 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3009 ok(data != NULL, "_Internal_push_back returned NULL\n");
3010 CHECK_CALLED(concurrent_vector_int_alloc);
3011 SET_EXPECT(concurrent_vector_int_alloc);
3012 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3013 ok(data != NULL, "_Internal_push_back returned NULL\n");
3014 CHECK_CALLED(concurrent_vector_int_alloc);
3015 vector_elem_count += 3;
3016 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
3017 call_func2(p_vector_base_v4__Internal_swap,
3018 &v2, &vector);
3019 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n",
3020 (long)v2.first_block);
3021 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
3022 (long)v2.early_size);
3023 ok(vector.early_size == 3, "vector.early_size got %ld expected 3\n",
3024 (long)vector.early_size);
3025 call_func2(p_vector_base_v4__Internal_swap,
3026 &v2, &vector);
3027 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n",
3028 (long)v2.early_size);
3029 ok(vector.early_size == 5, "vector.early_size got %ld expected 5\n",
3030 (long)vector.early_size);
3031 SET_EXPECT(concurrent_vector_int_destroy);
3032 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3033 &v2, concurrent_vector_int_destroy);
3034 CHECK_CALLED(concurrent_vector_int_destroy);
3035 ok(size == 2, "_Internal_clear returned %ld expected 2\n", (long)size);
3036 concurrent_vector_int_dtor(&v2);
3038 /* test for _Internal_compact */
3039 concurrent_vector_int_ctor(&v2);
3040 for(i=0; i<2; i++) {
3041 SET_EXPECT(concurrent_vector_int_alloc);
3042 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3043 CHECK_CALLED(concurrent_vector_int_alloc);
3044 ok(data != NULL, "_Internal_push_back returned NULL\n");
3045 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3046 ok(data != NULL, "_Internal_push_back returned NULL\n");
3047 vector_elem_count += 2;
3049 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3050 ok(v2.early_size == 4, "v2.early_size got %ld expected 4\n", (long)v2.early_size);
3051 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3052 v2.segment, v2.storage);
3053 memset(&b, 0xff, sizeof(b));
3054 SET_EXPECT(concurrent_vector_int_alloc);
3055 SET_EXPECT(concurrent_vector_int_copy);
3056 SET_EXPECT(concurrent_vector_int_destroy);
3057 data = call_func5(p_vector_base_v4__Internal_compact,
3058 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3059 concurrent_vector_int_copy);
3060 CHECK_CALLED(concurrent_vector_int_alloc);
3061 CHECK_CALLED(concurrent_vector_int_copy);
3062 CHECK_CALLED(concurrent_vector_int_destroy);
3063 ok(v2.first_block == 2, "v2.first_block got %ld expected 2\n", (long)v2.first_block);
3064 ok(v2.early_size == 4,"v2.early_size got %ld expected 4\n", (long)v2.early_size);
3065 ok(b.first_block == 1, "b.first_block got %ld expected 1\n", (long)b.first_block);
3066 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3067 v2.segment, v2.storage);
3068 for(i=0; i<2; i++){
3069 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3070 free(b.blocks[i]);
3071 vector_alloc_count--;
3073 for(; i<ARRAY_SIZE(b.blocks); i++)
3074 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3075 ok(b.size_check == -1, "b.size_check = %x\n", b.size_check);
3077 SET_EXPECT(concurrent_vector_int_alloc);
3078 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3079 CHECK_CALLED(concurrent_vector_int_alloc);
3080 ok(data != NULL, "_Internal_push_back returned NULL\n");
3081 for(i=0; i<3; i++){
3082 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3083 ok(data != NULL, "_Internal_push_back returned NULL\n");
3085 SET_EXPECT(concurrent_vector_int_alloc);
3086 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3087 CHECK_CALLED(concurrent_vector_int_alloc);
3088 ok(data != NULL, "_Internal_push_back returned NULL\n");
3089 vector_elem_count += 5;
3090 ok(v2.first_block == 2, "v2.first_block got %ld expected 2\n", (long)v2.first_block);
3091 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3092 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3093 for(i = 4;i < 32;i++)
3094 ok(v2.segment[i] == 0, "v2.segment[%d] got %p expected 0\n",
3095 i, v2.segment[i]);
3096 memset(&b, 0xff, sizeof(b));
3097 SET_EXPECT(concurrent_vector_int_alloc);
3098 SET_EXPECT(concurrent_vector_int_copy);
3099 SET_EXPECT(concurrent_vector_int_destroy);
3100 data = call_func5(p_vector_base_v4__Internal_compact,
3101 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3102 concurrent_vector_int_copy);
3103 CHECK_CALLED(concurrent_vector_int_alloc);
3104 CHECK_CALLED(concurrent_vector_int_copy);
3105 CHECK_CALLED(concurrent_vector_int_destroy);
3106 ok(v2.first_block == 4, "v2.first_block got %ld expected 4\n", (long)v2.first_block);
3107 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3108 ok(b.first_block == 2, "b.first_block got %ld expected 2\n", (long)b.first_block);
3109 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3110 for(i = 4;i < 32;i++)
3111 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3112 i, v2.segment[i]);
3113 for(i=0; i<4; i++){
3114 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3115 /* only b.blocks[0] and b.blocks[>=b.first_block] are used */
3116 if(i == b.first_block-1) continue;
3117 free(b.blocks[i]);
3118 vector_alloc_count--;
3120 for(; i<ARRAY_SIZE(b.blocks); i++)
3121 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3122 SET_EXPECT(concurrent_vector_int_alloc);
3123 call_func4(p_vector_base_v4__Internal_reserve,
3124 &v2, 17, sizeof(int), 32);
3125 CHECK_CALLED(concurrent_vector_int_alloc);
3126 data = call_func5(p_vector_base_v4__Internal_compact,
3127 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3128 concurrent_vector_int_copy);
3129 ok(v2.first_block == 4, "v2.first_block got %ld expected 4\n", (long)v2.first_block);
3130 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3131 ok(b.first_block == 4, "b.first_block got %ld expected 2\n", (long)b.first_block);
3132 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3133 for(i = 4; i < 32; i++)
3134 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3135 i, v2.segment[i]);
3136 for(i=0; i<4; i++)
3137 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3138 for(; i < 5; i++) {
3139 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3140 free(b.blocks[i]);
3141 vector_alloc_count--;
3143 for(; i<ARRAY_SIZE(b.blocks); i++)
3144 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3145 SET_EXPECT(concurrent_vector_int_destroy);
3146 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3147 &v2, concurrent_vector_int_destroy);
3148 CHECK_CALLED(concurrent_vector_int_destroy);
3149 ok(size == 4, "_Internal_clear returned %ld expected 4\n", (long)size);
3150 concurrent_vector_int_dtor(&v2);
3152 /* test for Internal_grow_by */
3153 concurrent_vector_int_ctor(&v2);
3154 SET_EXPECT(concurrent_vector_int_alloc);
3155 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3156 CHECK_CALLED(concurrent_vector_int_alloc);
3157 ok(data != NULL, "_Internal_push_back returned NULL\n");
3158 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3159 ok(data != NULL, "_Internal_push_back returned NULL\n");
3160 vector_elem_count += 2;
3161 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3162 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3163 i = 0;
3164 SET_EXPECT(concurrent_vector_int_alloc);
3165 SET_EXPECT(concurrent_vector_int_copy);
3166 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_by,
3167 &v2, 1, sizeof(int), concurrent_vector_int_copy, &i);
3168 CHECK_CALLED(concurrent_vector_int_alloc);
3169 CHECK_CALLED(concurrent_vector_int_copy);
3170 ok(idx == 2, "_Internal_grow_by returned %ld expected 2\n", (long)idx);
3171 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3172 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3173 SET_EXPECT(concurrent_vector_int_alloc);
3174 SET_EXPECT(concurrent_vector_int_copy);
3175 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_by,
3176 &v2, 2, sizeof(int), concurrent_vector_int_copy, &i);
3177 CHECK_CALLED(concurrent_vector_int_alloc);
3178 CHECK_CALLED(concurrent_vector_int_copy);
3179 ok(idx == 3, "_Internal_grow_by returned %ld expected 3\n", (long)idx);
3180 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3181 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n", (long)v2.early_size);
3182 SET_EXPECT(concurrent_vector_int_destroy);
3183 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3184 &v2, concurrent_vector_int_destroy);
3185 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
3186 CHECK_CALLED(concurrent_vector_int_destroy);
3187 concurrent_vector_int_dtor(&v2);
3189 /* test for Internal_grow_to_at_least_with_result */
3190 concurrent_vector_int_ctor(&v2);
3191 SET_EXPECT(concurrent_vector_int_alloc);
3192 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3193 CHECK_CALLED(concurrent_vector_int_alloc);
3194 ok(data != NULL, "_Internal_push_back returned NULL\n");
3195 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3196 ok(data != NULL, "_Internal_push_back returned NULL\n");
3197 vector_elem_count += 2;
3198 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3199 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3200 i = 0;
3201 SET_EXPECT(concurrent_vector_int_alloc);
3202 SET_EXPECT(concurrent_vector_int_copy);
3203 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result,
3204 &v2, 3, sizeof(int), concurrent_vector_int_copy, &i);
3205 CHECK_CALLED(concurrent_vector_int_alloc);
3206 CHECK_CALLED(concurrent_vector_int_copy);
3207 ok(idx == 2, "_Internal_grow_to_at_least_with_result returned %ld expected 2\n", (long)idx);
3208 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3209 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3210 i = 0;
3211 SET_EXPECT(concurrent_vector_int_alloc);
3212 SET_EXPECT(concurrent_vector_int_copy);
3213 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result,
3214 &v2, 5, sizeof(int), concurrent_vector_int_copy, &i);
3215 CHECK_CALLED(concurrent_vector_int_alloc);
3216 CHECK_CALLED(concurrent_vector_int_copy);
3217 ok(idx == 3, "_Internal_grow_to_at_least_with_result returned %ld expected 3\n", (long)idx);
3218 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3219 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n", (long)v2.early_size);
3220 SET_EXPECT(concurrent_vector_int_destroy);
3221 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3222 &v2, concurrent_vector_int_destroy);
3223 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
3224 CHECK_CALLED(concurrent_vector_int_destroy);
3225 concurrent_vector_int_dtor(&v2);
3227 /* test for _Internal_reserve */
3228 concurrent_vector_int_ctor(&v2);
3229 SET_EXPECT(concurrent_vector_int_alloc);
3230 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3231 CHECK_CALLED(concurrent_vector_int_alloc);
3232 ok(data != NULL, "_Internal_push_back returned NULL\n");
3233 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3234 ok(data != NULL, "_Internal_push_back returned NULL\n");
3235 vector_elem_count += 2;
3236 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3237 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3238 SET_EXPECT(concurrent_vector_int_alloc);
3239 call_func4(p_vector_base_v4__Internal_reserve,
3240 &v2, 3, sizeof(int), 4);
3241 CHECK_CALLED(concurrent_vector_int_alloc);
3242 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3243 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3244 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3245 v2.segment, v2.storage);
3246 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3247 ok(size == 4, "size of vector got %ld expected 4\n", (long)size);
3248 SET_EXPECT(concurrent_vector_int_alloc);
3249 call_func4(p_vector_base_v4__Internal_reserve,
3250 &v2, 5, sizeof(int), 8);
3251 CHECK_CALLED(concurrent_vector_int_alloc);
3252 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3253 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3254 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3255 v2.segment, v2.storage);
3256 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3257 ok(size == 8, "size of vector got %ld expected 8\n", (long)size);
3258 SET_EXPECT(concurrent_vector_int_alloc);
3259 call_func4(p_vector_base_v4__Internal_reserve,
3260 &v2, 9, sizeof(int), 16);
3261 CHECK_CALLED(concurrent_vector_int_alloc);
3262 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3263 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3264 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3265 for(i = 4;i < 32;i++)
3266 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3267 i, v2.segment[i]);
3268 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3269 ok(size == 16, "size of vector got %ld expected 8\n", (long)size);
3271 SET_EXPECT(concurrent_vector_int_destroy);
3272 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3273 &v2, concurrent_vector_int_destroy);
3274 ok(size == 4, "_Internal_clear returned %ld expected 4\n", (long)size);
3275 CHECK_CALLED(concurrent_vector_int_destroy);
3276 concurrent_vector_int_dtor(&v2);
3278 /* test for _Internal_resize */
3279 concurrent_vector_int_ctor(&v2);
3280 SET_EXPECT(concurrent_vector_int_alloc);
3281 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3282 CHECK_CALLED(concurrent_vector_int_alloc);
3283 ok(data != NULL, "_Internal_push_back returned NULL\n");
3284 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3285 ok(data != NULL, "_Internal_push_back returned NULL\n");
3286 vector_elem_count += 2;
3287 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3288 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3289 i = 0;
3290 SET_EXPECT(concurrent_vector_int_destroy);
3291 call_func7(p_vector_base_v4__Internal_resize,
3292 &v2, 1, sizeof(int), 4, concurrent_vector_int_destroy, concurrent_vector_int_copy, &i);
3293 CHECK_CALLED(concurrent_vector_int_destroy);
3294 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3295 ok(v2.early_size == 1, "v2.early_size got %ld expected 1\n", (long)v2.early_size);
3296 SET_EXPECT(concurrent_vector_int_alloc);
3297 SET_EXPECT(concurrent_vector_int_copy);
3298 call_func7(p_vector_base_v4__Internal_resize,
3299 &v2, 3, sizeof(int), 4, concurrent_vector_int_destroy, concurrent_vector_int_copy, &i);
3300 CHECK_CALLED(concurrent_vector_int_alloc);
3301 CHECK_CALLED(concurrent_vector_int_copy);
3302 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3303 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3304 SET_EXPECT(concurrent_vector_int_destroy);
3305 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3306 &v2, concurrent_vector_int_destroy);
3307 ok(size == 2, "_Internal_clear returned %ld expected 2\n", (long)size);
3308 CHECK_CALLED(concurrent_vector_int_destroy);
3309 concurrent_vector_int_dtor(&v2);
3311 SET_EXPECT(concurrent_vector_int_destroy);
3312 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3313 &vector, concurrent_vector_int_destroy);
3314 CHECK_CALLED(concurrent_vector_int_destroy);
3315 ok(size == 3, "_Internal_clear returned %ld\n", (long)size);
3316 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
3317 (long)vector.first_block);
3318 ok(vector.early_size == 0, "vector.early_size got %ld expected 0\n",
3319 (long)vector.early_size);
3320 concurrent_vector_int_dtor(&vector);
3322 ok(!vector_elem_count, "vector_elem_count = %d, expected 0\n", vector_elem_count);
3323 ok(!vector_alloc_count, "vector_alloc_count = %d, expected 0\n", vector_alloc_count);
3326 static BYTE byte_reverse(BYTE b)
3328 b = ((b & 0xf0) >> 4) | ((b & 0x0f) << 4);
3329 b = ((b & 0xcc) >> 2) | ((b & 0x33) << 2);
3330 b = ((b & 0xaa) >> 1) | ((b & 0x55) << 1);
3331 return b;
3334 static void test_data_exports(void)
3336 unsigned int i;
3338 ok(IsBadWritePtr((BYTE *)p_byte_reverse_table, 256), "byte_reverse_table is writeable.\n");
3339 for (i = 0; i < 256; ++i)
3341 ok(p_byte_reverse_table[i] == byte_reverse(i), "Got unexpected byte %#x, expected %#x.\n",
3342 p_byte_reverse_table[i], byte_reverse(i));
3346 START_TEST(msvcp120)
3348 if(!init()) return;
3349 expect_idx = TlsAlloc();
3350 ok(expect_idx != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
3351 alloc_expect_struct();
3353 test__Xtime_diff_to_millis2();
3354 test_xtime_get();
3355 test__Getcvt();
3356 test__Call_once();
3357 test__Do_call();
3358 test__Dtest();
3359 test__Dscale();
3360 test__FExp();
3361 test__Syserror_map();
3363 test_tr2_sys__File_size();
3364 test_tr2_sys__Equivalent();
3365 test_tr2_sys__Current_get();
3366 test_tr2_sys__Current_set();
3367 test_tr2_sys__Make_dir();
3368 test_tr2_sys__Remove_dir();
3369 test_tr2_sys__Copy_file();
3370 test_tr2_sys__Rename();
3371 test_tr2_sys__Statvfs();
3372 test_tr2_sys__Stat();
3373 test_tr2_sys__Last_write_time();
3374 test_tr2_sys__dir_operation();
3375 test_tr2_sys__Link();
3376 test_tr2_sys__Symlink();
3377 test_tr2_sys__Unlink();
3379 test_thrd();
3380 test_cnd();
3381 test__Pad();
3382 test__Mtx();
3383 test_threads__Mtx();
3385 test_vector_base_v4__Segment_index_of();
3386 test_queue_base_v4();
3387 test_vector_base_v4();
3389 test_vbtable_size_exports();
3391 test_data_exports();
3393 free_expect_struct();
3394 TlsFree(expect_idx);
3395 FreeLibrary(msvcp);