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
22 #include "wine/test.h"
25 typedef int MSVCRT_long
;
40 static inline const char* debugstr_longlong(ULONGLONG ll
)
42 static char string
[17];
43 if (sizeof(ll
) > sizeof(unsigned long) && ll
>> 32)
44 sprintf(string
, "%lx%08lx", (unsigned long)(ll
>> 32), (unsigned long)ll
);
46 sprintf(string
, "%lx", (unsigned long)ll
);
50 static char* (__cdecl
*p_setlocale
)(int, const char*);
51 static int (__cdecl
*p__setmbcp
)(int);
52 static int (__cdecl
*p_isleadbyte
)(int);
54 static MSVCRT_long (__cdecl
*p__Xtime_diff_to_millis2
)(const xtime
*, const xtime
*);
55 static int (__cdecl
*p_xtime_get
)(xtime
*, int);
56 static _Cvtvec
* (__cdecl
*p__Getcvt
)(_Cvtvec
*);
57 static void (CDECL
*p__Call_once
)(int *once
, void (CDECL
*func
)(void));
58 static void (CDECL
*p__Call_onceEx
)(int *once
, void (CDECL
*func
)(void*), void *argv
);
59 static void (CDECL
*p__Do_call
)(void *this);
62 static ULONGLONG(__cdecl
*p_tr2_sys__File_size
)(char const*);
63 static int (__cdecl
*p_tr2_sys__Equivalent
)(char const*, char const*);
66 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
67 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
68 static BOOL
init(void)
72 msvcp
= LoadLibraryA("msvcp120.dll");
75 win_skip("msvcp120.dll not installed\n");
79 SET(p__Xtime_diff_to_millis2
,
80 "_Xtime_diff_to_millis2");
91 if(sizeof(void*) == 8) { /* 64-bit initialization */
92 SET(p_tr2_sys__File_size
,
93 "?_File_size@sys@tr2@std@@YA_KPEBD@Z");
94 SET(p_tr2_sys__Equivalent
,
95 "?_Equivalent@sys@tr2@std@@YAHPEBD0@Z");
97 SET(p_tr2_sys__File_size
,
98 "?_File_size@sys@tr2@std@@YA_KPBD@Z");
99 SET(p_tr2_sys__Equivalent
,
100 "?_Equivalent@sys@tr2@std@@YAHPBD0@Z");
103 msvcr
= GetModuleHandleA("msvcr120.dll");
104 p_setlocale
= (void*)GetProcAddress(msvcr
, "setlocale");
105 p__setmbcp
= (void*)GetProcAddress(msvcr
, "_setmbcp");
106 p_isleadbyte
= (void*)GetProcAddress(msvcr
, "isleadbyte");
110 static void test__Xtime_diff_to_millis2(void)
113 __time64_t sec_before
;
114 MSVCRT_long nsec_before
;
115 __time64_t sec_after
;
116 MSVCRT_long nsec_after
;
120 {0, 1000000000, 0, 2000000000, 1000},
121 {1, 100000000, 2, 100000000, 1000},
122 {1, 100000000, 1, 200000000, 100},
123 {0, 0, 0, 1000000000, 1000},
124 {0, 0, 0, 1200000000, 1200},
125 {0, 0, 0, 1230000000, 1230},
126 {0, 0, 0, 1234000000, 1234},
127 {0, 0, 0, 1234100000, 1235},
128 {0, 0, 0, 1234900000, 1235},
129 {0, 0, 0, 1234010000, 1235},
130 {0, 0, 0, 1234090000, 1235},
131 {0, 0, 0, 1234000001, 1235},
132 {0, 0, 0, 1234000009, 1235},
134 {0, 0, 0, -10000000, 0},
135 {0, 0, -1, -100000000, 0},
137 {0, -100000000, 0, 0, 100},
138 {-1, -100000000, 0, 0, 1100},
139 {0, 0, -1, 2000000000, 1000},
140 {0, 0, -2, 2000000000, 0},
141 {0, 0, -2, 2100000000, 100}
147 for(i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); ++ i
)
149 t1
.sec
= tests
[i
].sec_before
;
150 t1
.nsec
= tests
[i
].nsec_before
;
151 t2
.sec
= tests
[i
].sec_after
;
152 t2
.nsec
= tests
[i
].nsec_after
;
153 ret
= p__Xtime_diff_to_millis2(&t2
, &t1
);
154 ok(ret
== tests
[i
].expect
,
155 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
156 i
, tests
[i
].expect
, ret
);
160 static void test_xtime_get(void)
162 static const MSVCRT_long tests
[] = {1, 50, 100, 200, 500};
167 for(i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); i
++)
169 p_xtime_get(&before
, 1);
171 p_xtime_get(&after
, 1);
173 diff
= p__Xtime_diff_to_millis2(&after
, &before
);
176 "xtime_get() not functioning correctly, test: %d, expect: ge %d, got: %d\n",
180 /* Test parameter and return value */
181 before
.sec
= 0xdeadbeef, before
.nsec
= 0xdeadbeef;
182 i
= p_xtime_get(&before
, 0);
183 ok(i
== 0, "expect xtime_get() to return 0, got: %d\n", i
);
184 ok(before
.sec
== 0xdeadbeef && before
.nsec
== 0xdeadbeef,
185 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
187 before
.sec
= 0xdeadbeef, before
.nsec
= 0xdeadbeef;
188 i
= p_xtime_get(&before
, 1);
189 ok(i
== 1, "expect xtime_get() to return 1, got: %d\n", i
);
190 ok(before
.sec
!= 0xdeadbeef && before
.nsec
!= 0xdeadbeef,
191 "xtime_get() should have modified the xtime struct with the given option\n");
194 static void test__Getcvt(void)
200 ok(cvtvec
.page
== 0, "cvtvec.page = %d\n", cvtvec
.page
);
201 ok(cvtvec
.mb_max
== 1, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
202 todo_wine
ok(cvtvec
.unk
== 1, "cvtvec.unk = %d\n", cvtvec
.unk
);
204 ok(cvtvec
.isleadbyte
[i
] == 0, "cvtvec.isleadbyte[%d] = %x\n", i
, cvtvec
.isleadbyte
[i
]);
206 if(!p_setlocale(LC_ALL
, ".936")) {
207 win_skip("_Getcvt tests\n");
211 ok(cvtvec
.page
== 936, "cvtvec.page = %d\n", cvtvec
.page
);
212 ok(cvtvec
.mb_max
== 2, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
213 ok(cvtvec
.unk
== 0, "cvtvec.unk = %d\n", cvtvec
.unk
);
215 ok(cvtvec
.isleadbyte
[i
] == 0, "cvtvec.isleadbyte[%d] = %x\n", i
, cvtvec
.isleadbyte
[i
]);
219 ok(cvtvec
.page
== 936, "cvtvec.page = %d\n", cvtvec
.page
);
220 ok(cvtvec
.mb_max
== 2, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
221 ok(cvtvec
.unk
== 0, "cvtvec.unk = %d\n", cvtvec
.unk
);
222 for(i
=0; i
<32; i
++) {
227 b
|= (p_isleadbyte(i
*8+j
) ? 1 : 0) << j
;
228 ok(cvtvec
.isleadbyte
[i
] ==b
, "cvtvec.isleadbyte[%d] = %x (%x)\n", i
, cvtvec
.isleadbyte
[i
], b
);
235 static void __cdecl
call_once_func(void)
237 ok(!once
, "once != 0\n");
241 static void __cdecl
call_once_ex_func(void *arg
)
245 ok(!once
, "once != 0\n");
249 static DWORD WINAPI
call_once_thread(void *arg
)
251 p__Call_once(&once
, call_once_func
);
255 static DWORD WINAPI
call_once_ex_thread(void *arg
)
257 p__Call_onceEx(&once
, call_once_ex_func
, &cnt
);
261 static void test__Call_once(void)
267 h
[i
] = CreateThread(NULL
, 0, call_once_thread
, &once
, 0, NULL
);
268 ok(WaitForMultipleObjects(4, h
, TRUE
, INFINITE
) == WAIT_OBJECT_0
,
269 "error waiting for all threads to finish\n");
270 ok(cnt
== 0x10000, "cnt = %x\n", cnt
);
271 ok(once
== 1, "once = %x\n", once
);
275 h
[i
] = CreateThread(NULL
, 0, call_once_ex_thread
, &once
, 0, NULL
);
276 ok(WaitForMultipleObjects(4, h
, TRUE
, INFINITE
) == WAIT_OBJECT_0
,
277 "error waiting for all threads to finish\n");
278 ok(cnt
== 1, "cnt = %x\n", cnt
);
279 ok(once
== 1, "once = %x\n", once
);
282 static void **vtbl_func0
;
284 /* TODO: this should be a __thiscall function */
285 static void __stdcall
thiscall_func(void)
290 static void __cdecl
thiscall_func(void *this)
292 ok(this == &vtbl_func0
, "incorrect this value\n");
297 static void test__Do_call(void)
299 void *pfunc
= thiscall_func
;
303 p__Do_call(&vtbl_func0
);
304 ok(cnt
== 1, "func was not called\n");
307 static void test_tr2_sys__File_size(void)
311 LARGE_INTEGER file_size
= {{7, 0}};
312 CreateDirectoryA("tr2_test_dir", NULL
);
314 file
= CreateFileA("tr2_test_dir/f1", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
315 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
316 ok(SetFilePointerEx(file
, file_size
, NULL
, FILE_BEGIN
), "SetFilePointerEx failed\n");
317 ok(SetEndOfFile(file
), "SetEndOfFile failed\n");
319 val
= p_tr2_sys__File_size("tr2_test_dir/f1");
320 ok(val
== 7, "file_size is %s\n", debugstr_longlong(val
));
322 file
= CreateFileA("tr2_test_dir/f2", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
323 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
325 val
= p_tr2_sys__File_size("tr2_test_dir/f2");
326 ok(val
== 0, "file_size is %s\n", debugstr_longlong(val
));
328 val
= p_tr2_sys__File_size("tr2_test_dir");
329 ok(val
== 0, "file_size is %s\n", debugstr_longlong(val
));
332 val
= p_tr2_sys__File_size("tr2_test_dir/not_exists_file");
333 ok(val
== 0, "file_size is %s\n", debugstr_longlong(val
));
334 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
337 val
= p_tr2_sys__File_size(NULL
);
338 ok(val
== 0, "file_size is %s\n", debugstr_longlong(val
));
339 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
341 ok(DeleteFileA("tr2_test_dir/f1"), "Expected tr2_test_dir/f1 to exist\n");
342 ok(DeleteFileA("tr2_test_dir/f2"), "Expected tr2_test_dir/f2 to exist\n");
343 ok(RemoveDirectoryA("tr2_test_dir"), "Expected tr2_test_dir to exist\n");
346 static void test_tr2_sys__Equivalent(void)
350 char temp_path
[MAX_PATH
], current_path
[MAX_PATH
];
359 { "f1", "tr2_test_dir", -1 },
360 { "tr2_test_dir", "f1", -1 },
361 { "tr2_test_dir", "tr2_test_dir", -1 },
362 { "tr2_test_dir/./f1", "tr2_test_dir/f2", 0 },
363 { "tr2_test_dir/f1" , "tr2_test_dir/f1", 1 },
364 { "not_exists_file" , "tr2_test_dir/f1", 0 },
365 { "tr2_test_dir\\f1" , "tr2_test_dir/./f1", 1 },
366 { "not_exists_file" , "not_exists_file", -1 },
367 { "tr2_test_dir/f1" , "not_exists_file", 0 },
368 { "tr2_test_dir/../tr2_test_dir/f1", "tr2_test_dir/f1", 1 }
371 memset(current_path
, 0, MAX_PATH
);
372 GetCurrentDirectoryA(MAX_PATH
, current_path
);
373 memset(temp_path
, 0, MAX_PATH
);
374 GetTempPathA(MAX_PATH
, temp_path
);
375 ok(SetCurrentDirectoryA(temp_path
), "SetCurrentDirectoryA to temp_path failed\n");
376 CreateDirectoryA("tr2_test_dir", NULL
);
378 file
= CreateFileA("tr2_test_dir/f1", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
379 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
381 file
= CreateFileA("tr2_test_dir/f2", 0, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
382 ok(file
!= INVALID_HANDLE_VALUE
, "create file failed: INVALID_HANDLE_VALUE\n");
385 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
387 val
= p_tr2_sys__Equivalent(tests
[i
].path1
, tests
[i
].path2
);
388 ok(tests
[i
].equivalent
== val
, "tr2_sys__Equivalent(): test %d expect: %d, got %d\n", i
+1, tests
[i
].equivalent
, val
);
389 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
392 ok(DeleteFileA("tr2_test_dir/f1"), "Expected tr2_test_dir/f1 to exist\n");
393 ok(DeleteFileA("tr2_test_dir/f2"), "Expected tr2_test_dir/f2 to exist\n");
394 ok(RemoveDirectoryA("tr2_test_dir"), "Expected tr2_test_dir to exist\n");
395 ok(SetCurrentDirectoryA(current_path
), "SetCurrentDirectoryA failed\n");
401 test__Xtime_diff_to_millis2();
407 test_tr2_sys__File_size();
408 test_tr2_sys__Equivalent();