msvcp: Add _Dscale implementation.
[wine/multimedia.git] / dlls / msvcp120 / tests / msvcp120.c
blob358c4087eb64c1b3449c7835220dbcd35ff3c9cd
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>
23 #include "wine/test.h"
24 #include "winbase.h"
26 static inline float __port_infinity(void)
28 static const unsigned __inf_bytes = 0x7f800000;
29 return *(const float *)&__inf_bytes;
31 #define INFINITY __port_infinity()
33 static inline float __port_nan(void)
35 static const unsigned __nan_bytes = 0x7fc00000;
36 return *(const float *)&__nan_bytes;
38 #define NAN __port_nan()
40 typedef int MSVCRT_long;
41 typedef unsigned char MSVCP_bool;
43 /* xtime */
44 typedef struct {
45 __time64_t sec;
46 MSVCRT_long nsec;
47 } xtime;
49 typedef struct {
50 unsigned page;
51 int mb_max;
52 int unk;
53 BYTE isleadbyte[32];
54 } _Cvtvec;
56 struct space_info {
57 ULONGLONG capacity;
58 ULONGLONG free;
59 ULONGLONG available;
62 enum file_type {
63 status_unknown, file_not_found, regular_file, directory_file,
64 symlink_file, block_file, character_file, fifo_file, socket_file,
65 type_unknown
68 static inline const char* debugstr_longlong(ULONGLONG ll)
70 static char string[17];
71 if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
72 sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
73 else
74 sprintf(string, "%lx", (unsigned long)ll);
75 return string;
78 static char* (__cdecl *p_setlocale)(int, const char*);
79 static int (__cdecl *p__setmbcp)(int);
80 static int (__cdecl *p_isleadbyte)(int);
82 static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
83 static int (__cdecl *p_xtime_get)(xtime*, int);
84 static _Cvtvec* (__cdecl *p__Getcvt)(_Cvtvec*);
85 static void (CDECL *p__Call_once)(int *once, void (CDECL *func)(void));
86 static void (CDECL *p__Call_onceEx)(int *once, void (CDECL *func)(void*), void *argv);
87 static void (CDECL *p__Do_call)(void *this);
88 static short (__cdecl *p__Dtest)(double *d);
89 static short (__cdecl *p__Dscale)(double *d, int exp);
91 /* filesystem */
92 static ULONGLONG(__cdecl *p_tr2_sys__File_size)(char const*);
93 static ULONGLONG(__cdecl *p_tr2_sys__File_size_wchar)(WCHAR const*);
94 static int (__cdecl *p_tr2_sys__Equivalent)(char const*, char const*);
95 static int (__cdecl *p_tr2_sys__Equivalent_wchar)(WCHAR const*, WCHAR const*);
96 static char* (__cdecl *p_tr2_sys__Current_get)(char *);
97 static WCHAR* (__cdecl *p_tr2_sys__Current_get_wchar)(WCHAR *);
98 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set)(char const*);
99 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set_wchar)(WCHAR const*);
100 static int (__cdecl *p_tr2_sys__Make_dir)(char const*);
101 static int (__cdecl *p_tr2_sys__Make_dir_wchar)(WCHAR const*);
102 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir)(char const*);
103 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir_wchar)(WCHAR const*);
104 static int (__cdecl *p_tr2_sys__Copy_file)(char const*, char const*, MSVCP_bool);
105 static int (__cdecl *p_tr2_sys__Copy_file_wchar)(WCHAR const*, WCHAR const*, MSVCP_bool);
106 static int (__cdecl *p_tr2_sys__Rename)(char const*, char const*);
107 static int (__cdecl *p_tr2_sys__Rename_wchar)(WCHAR const*, WCHAR const*);
108 static struct space_info (__cdecl *p_tr2_sys__Statvfs)(char const*);
109 static struct space_info (__cdecl *p_tr2_sys__Statvfs_wchar)(WCHAR const*);
110 static enum file_type (__cdecl *p_tr2_sys__Stat)(char const*, int *);
111 static enum file_type (__cdecl *p_tr2_sys__Lstat)(char const*, int *);
112 static __int64 (__cdecl *p_tr2_sys__Last_write_time)(char const*);
113 static void (__cdecl *p_tr2_sys__Last_write_time_set)(char const*, __int64);
115 static HMODULE msvcp;
116 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
117 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
118 static BOOL init(void)
120 HANDLE msvcr;
122 msvcp = LoadLibraryA("msvcp120.dll");
123 if(!msvcp)
125 win_skip("msvcp120.dll not installed\n");
126 return FALSE;
129 SET(p__Xtime_diff_to_millis2,
130 "_Xtime_diff_to_millis2");
131 SET(p_xtime_get,
132 "xtime_get");
133 SET(p__Getcvt,
134 "_Getcvt");
135 SET(p__Call_once,
136 "_Call_once");
137 SET(p__Call_onceEx,
138 "_Call_onceEx");
139 SET(p__Do_call,
140 "_Do_call");
141 SET(p__Dtest,
142 "_Dtest");
143 SET(p__Dscale,
144 "_Dscale");
145 if(sizeof(void*) == 8) { /* 64-bit initialization */
146 SET(p_tr2_sys__File_size,
147 "?_File_size@sys@tr2@std@@YA_KPEBD@Z");
148 SET(p_tr2_sys__File_size_wchar,
149 "?_File_size@sys@tr2@std@@YA_KPEB_W@Z");
150 SET(p_tr2_sys__Equivalent,
151 "?_Equivalent@sys@tr2@std@@YAHPEBD0@Z");
152 SET(p_tr2_sys__Equivalent_wchar,
153 "?_Equivalent@sys@tr2@std@@YAHPEB_W0@Z");
154 SET(p_tr2_sys__Current_get,
155 "?_Current_get@sys@tr2@std@@YAPEADAEAY0BAE@D@Z");
156 SET(p_tr2_sys__Current_get_wchar,
157 "?_Current_get@sys@tr2@std@@YAPEA_WAEAY0BAE@_W@Z");
158 SET(p_tr2_sys__Current_set,
159 "?_Current_set@sys@tr2@std@@YA_NPEBD@Z");
160 SET(p_tr2_sys__Current_set_wchar,
161 "?_Current_set@sys@tr2@std@@YA_NPEB_W@Z");
162 SET(p_tr2_sys__Make_dir,
163 "?_Make_dir@sys@tr2@std@@YAHPEBD@Z");
164 SET(p_tr2_sys__Make_dir_wchar,
165 "?_Make_dir@sys@tr2@std@@YAHPEB_W@Z");
166 SET(p_tr2_sys__Remove_dir,
167 "?_Remove_dir@sys@tr2@std@@YA_NPEBD@Z");
168 SET(p_tr2_sys__Remove_dir_wchar,
169 "?_Remove_dir@sys@tr2@std@@YA_NPEB_W@Z");
170 SET(p_tr2_sys__Copy_file,
171 "?_Copy_file@sys@tr2@std@@YAHPEBD0_N@Z");
172 SET(p_tr2_sys__Copy_file_wchar,
173 "?_Copy_file@sys@tr2@std@@YAHPEB_W0_N@Z");
174 SET(p_tr2_sys__Rename,
175 "?_Rename@sys@tr2@std@@YAHPEBD0@Z");
176 SET(p_tr2_sys__Rename_wchar,
177 "?_Rename@sys@tr2@std@@YAHPEB_W0@Z");
178 SET(p_tr2_sys__Statvfs,
179 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEBD@Z");
180 SET(p_tr2_sys__Statvfs_wchar,
181 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEB_W@Z");
182 SET(p_tr2_sys__Stat,
183 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
184 SET(p_tr2_sys__Lstat,
185 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
186 SET(p_tr2_sys__Last_write_time,
187 "?_Last_write_time@sys@tr2@std@@YA_JPEBD@Z");
188 SET(p_tr2_sys__Last_write_time_set,
189 "?_Last_write_time@sys@tr2@std@@YAXPEBD_J@Z");
190 } else {
191 SET(p_tr2_sys__File_size,
192 "?_File_size@sys@tr2@std@@YA_KPBD@Z");
193 SET(p_tr2_sys__File_size_wchar,
194 "?_File_size@sys@tr2@std@@YA_KPB_W@Z");
195 SET(p_tr2_sys__Equivalent,
196 "?_Equivalent@sys@tr2@std@@YAHPBD0@Z");
197 SET(p_tr2_sys__Equivalent_wchar,
198 "?_Equivalent@sys@tr2@std@@YAHPB_W0@Z");
199 SET(p_tr2_sys__Current_get,
200 "?_Current_get@sys@tr2@std@@YAPADAAY0BAE@D@Z");
201 SET(p_tr2_sys__Current_get_wchar,
202 "?_Current_get@sys@tr2@std@@YAPA_WAAY0BAE@_W@Z");
203 SET(p_tr2_sys__Current_set,
204 "?_Current_set@sys@tr2@std@@YA_NPBD@Z");
205 SET(p_tr2_sys__Current_set_wchar,
206 "?_Current_set@sys@tr2@std@@YA_NPB_W@Z");
207 SET(p_tr2_sys__Make_dir,
208 "?_Make_dir@sys@tr2@std@@YAHPBD@Z");
209 SET(p_tr2_sys__Make_dir_wchar,
210 "?_Make_dir@sys@tr2@std@@YAHPB_W@Z");
211 SET(p_tr2_sys__Remove_dir,
212 "?_Remove_dir@sys@tr2@std@@YA_NPBD@Z");
213 SET(p_tr2_sys__Remove_dir_wchar,
214 "?_Remove_dir@sys@tr2@std@@YA_NPB_W@Z");
215 SET(p_tr2_sys__Copy_file,
216 "?_Copy_file@sys@tr2@std@@YAHPBD0_N@Z");
217 SET(p_tr2_sys__Copy_file_wchar,
218 "?_Copy_file@sys@tr2@std@@YAHPB_W0_N@Z");
219 SET(p_tr2_sys__Rename,
220 "?_Rename@sys@tr2@std@@YAHPBD0@Z");
221 SET(p_tr2_sys__Rename_wchar,
222 "?_Rename@sys@tr2@std@@YAHPB_W0@Z");
223 SET(p_tr2_sys__Statvfs,
224 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z");
225 SET(p_tr2_sys__Statvfs_wchar,
226 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PB_W@Z");
227 SET(p_tr2_sys__Stat,
228 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
229 SET(p_tr2_sys__Lstat,
230 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
231 SET(p_tr2_sys__Last_write_time,
232 "?_Last_write_time@sys@tr2@std@@YA_JPBD@Z");
233 SET(p_tr2_sys__Last_write_time_set,
234 "?_Last_write_time@sys@tr2@std@@YAXPBD_J@Z");
237 msvcr = GetModuleHandleA("msvcr120.dll");
238 p_setlocale = (void*)GetProcAddress(msvcr, "setlocale");
239 p__setmbcp = (void*)GetProcAddress(msvcr, "_setmbcp");
240 p_isleadbyte = (void*)GetProcAddress(msvcr, "isleadbyte");
241 return TRUE;
244 static void test__Xtime_diff_to_millis2(void)
246 struct {
247 __time64_t sec_before;
248 MSVCRT_long nsec_before;
249 __time64_t sec_after;
250 MSVCRT_long nsec_after;
251 MSVCRT_long expect;
252 } tests[] = {
253 {1, 0, 2, 0, 1000},
254 {0, 1000000000, 0, 2000000000, 1000},
255 {1, 100000000, 2, 100000000, 1000},
256 {1, 100000000, 1, 200000000, 100},
257 {0, 0, 0, 1000000000, 1000},
258 {0, 0, 0, 1200000000, 1200},
259 {0, 0, 0, 1230000000, 1230},
260 {0, 0, 0, 1234000000, 1234},
261 {0, 0, 0, 1234100000, 1235},
262 {0, 0, 0, 1234900000, 1235},
263 {0, 0, 0, 1234010000, 1235},
264 {0, 0, 0, 1234090000, 1235},
265 {0, 0, 0, 1234000001, 1235},
266 {0, 0, 0, 1234000009, 1235},
267 {0, 0, -1, 0, 0},
268 {0, 0, 0, -10000000, 0},
269 {0, 0, -1, -100000000, 0},
270 {-1, 0, 0, 0, 1000},
271 {0, -100000000, 0, 0, 100},
272 {-1, -100000000, 0, 0, 1100},
273 {0, 0, -1, 2000000000, 1000},
274 {0, 0, -2, 2000000000, 0},
275 {0, 0, -2, 2100000000, 100}
277 int i;
278 MSVCRT_long ret;
279 xtime t1, t2;
281 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); ++ i)
283 t1.sec = tests[i].sec_before;
284 t1.nsec = tests[i].nsec_before;
285 t2.sec = tests[i].sec_after;
286 t2.nsec = tests[i].nsec_after;
287 ret = p__Xtime_diff_to_millis2(&t2, &t1);
288 ok(ret == tests[i].expect,
289 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
290 i, tests[i].expect, ret);
294 static void test_xtime_get(void)
296 static const MSVCRT_long tests[] = {1, 50, 100, 200, 500};
297 MSVCRT_long diff;
298 xtime before, after;
299 int i;
301 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i ++)
303 p_xtime_get(&before, 1);
304 Sleep(tests[i]);
305 p_xtime_get(&after, 1);
307 diff = p__Xtime_diff_to_millis2(&after, &before);
309 ok(diff >= tests[i],
310 "xtime_get() not functioning correctly, test: %d, expect: ge %d, got: %d\n",
311 i, tests[i], diff);
314 /* Test parameter and return value */
315 before.sec = 0xdeadbeef, before.nsec = 0xdeadbeef;
316 i = p_xtime_get(&before, 0);
317 ok(i == 0, "expect xtime_get() to return 0, got: %d\n", i);
318 ok(before.sec == 0xdeadbeef && before.nsec == 0xdeadbeef,
319 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
321 before.sec = 0xdeadbeef, before.nsec = 0xdeadbeef;
322 i = p_xtime_get(&before, 1);
323 ok(i == 1, "expect xtime_get() to return 1, got: %d\n", i);
324 ok(before.sec != 0xdeadbeef && before.nsec != 0xdeadbeef,
325 "xtime_get() should have modified the xtime struct with the given option\n");
328 static void test__Getcvt(void)
330 _Cvtvec cvtvec;
331 int i;
333 p__Getcvt(&cvtvec);
334 ok(cvtvec.page == 0, "cvtvec.page = %d\n", cvtvec.page);
335 ok(cvtvec.mb_max == 1, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
336 todo_wine ok(cvtvec.unk == 1, "cvtvec.unk = %d\n", cvtvec.unk);
337 for(i=0; i<32; i++)
338 ok(cvtvec.isleadbyte[i] == 0, "cvtvec.isleadbyte[%d] = %x\n", i, cvtvec.isleadbyte[i]);
340 if(!p_setlocale(LC_ALL, ".936")) {
341 win_skip("_Getcvt tests\n");
342 return;
344 p__Getcvt(&cvtvec);
345 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
346 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
347 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
348 for(i=0; i<32; i++)
349 ok(cvtvec.isleadbyte[i] == 0, "cvtvec.isleadbyte[%d] = %x\n", i, cvtvec.isleadbyte[i]);
351 p__setmbcp(936);
352 p__Getcvt(&cvtvec);
353 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
354 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
355 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
356 for(i=0; i<32; i++) {
357 BYTE b = 0;
358 int j;
360 for(j=0; j<8; j++)
361 b |= (p_isleadbyte(i*8+j) ? 1 : 0) << j;
362 ok(cvtvec.isleadbyte[i] ==b, "cvtvec.isleadbyte[%d] = %x (%x)\n", i, cvtvec.isleadbyte[i], b);
366 static int cnt;
367 static int once;
369 static void __cdecl call_once_func(void)
371 ok(!once, "once != 0\n");
372 cnt += 0x10000;
375 static void __cdecl call_once_ex_func(void *arg)
377 int *i = arg;
379 ok(!once, "once != 0\n");
380 (*i)++;
383 static DWORD WINAPI call_once_thread(void *arg)
385 p__Call_once(&once, call_once_func);
386 return 0;
389 static DWORD WINAPI call_once_ex_thread(void *arg)
391 p__Call_onceEx(&once, call_once_ex_func, &cnt);
392 return 0;
395 static void test__Call_once(void)
397 HANDLE h[4];
398 int i;
400 for(i=0; i<4; i++)
401 h[i] = CreateThread(NULL, 0, call_once_thread, &once, 0, NULL);
402 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
403 "error waiting for all threads to finish\n");
404 ok(cnt == 0x10000, "cnt = %x\n", cnt);
405 ok(once == 1, "once = %x\n", once);
407 once = cnt = 0;
408 for(i=0; i<4; i++)
409 h[i] = CreateThread(NULL, 0, call_once_ex_thread, &once, 0, NULL);
410 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
411 "error waiting for all threads to finish\n");
412 ok(cnt == 1, "cnt = %x\n", cnt);
413 ok(once == 1, "once = %x\n", once);
416 static void **vtbl_func0;
417 #ifdef __i386__
418 /* TODO: this should be a __thiscall function */
419 static void __stdcall thiscall_func(void)
421 cnt = 1;
423 #else
424 static void __cdecl thiscall_func(void *this)
426 ok(this == &vtbl_func0, "incorrect this value\n");
427 cnt = 1;
429 #endif
431 static void test__Do_call(void)
433 void *pfunc = thiscall_func;
435 cnt = 0;
436 vtbl_func0 = &pfunc;
437 p__Do_call(&vtbl_func0);
438 ok(cnt == 1, "func was not called\n");
441 static void test__Dtest(void)
443 double d;
444 short ret;
446 d = 0;
447 ret = p__Dtest(&d);
448 ok(ret == FP_ZERO, "_Dtest(0) returned %x\n", ret);
450 d = 1;
451 ret = p__Dtest(&d);
452 ok(ret == FP_NORMAL, "_Dtest(1) returned %x\n", ret);
454 d = -1;
455 ret = p__Dtest(&d);
456 ok(ret == FP_NORMAL, "_Dtest(-1) returned %x\n", ret);
458 d = INFINITY;
459 ret = p__Dtest(&d);
460 ok(ret == FP_INFINITE, "_Dtest(INF) returned %x\n", ret);
462 d = NAN;
463 ret = p__Dtest(&d);
464 ok(ret == FP_NAN, "_Dtest(NAN) returned %x\n", ret);
467 static void test__Dscale(void)
469 double d;
470 short ret;
472 d = 0;
473 ret = p__Dscale(&d, 0);
474 ok(d == 0, "d = %f\n", d);
475 ok(ret == FP_ZERO, "ret = %x\n", ret);
477 d = 0;
478 ret = p__Dscale(&d, 1);
479 ok(d == 0, "d = %f\n", d);
480 ok(ret == FP_ZERO, "ret = %x\n", ret);
482 d = 0;
483 ret = p__Dscale(&d, -1);
484 ok(d == 0, "d = %f\n", d);
485 ok(ret == FP_ZERO, "ret = %x\n", ret);
487 d = 1;
488 ret = p__Dscale(&d, 0);
489 ok(d == 1, "d = %f\n", d);
490 ok(ret == FP_NORMAL, "ret = %x\n", ret);
492 d = 1;
493 ret = p__Dscale(&d, 1);
494 ok(d == 2, "d = %f\n", d);
495 ok(ret == FP_NORMAL, "ret = %x\n", ret);
497 d = 1;
498 ret = p__Dscale(&d, -1);
499 ok(d == 0.5, "d = %f\n", d);
500 ok(ret == FP_NORMAL, "ret = %x\n", ret);
502 d = 1;
503 ret = p__Dscale(&d, -99999);
504 ok(d == 0, "d = %f\n", d);
505 ok(ret == FP_ZERO, "ret = %x\n", ret);
507 d = 1;
508 ret = p__Dscale(&d, 999999);
509 ok(d == INFINITY, "d = %f\n", d);
510 ok(ret == FP_INFINITE, "ret = %x\n", ret);
512 d = NAN;
513 ret = p__Dscale(&d, 1);
514 ok(ret == FP_NAN, "ret = %x\n", ret);
517 static void test_tr2_sys__File_size(void)
519 ULONGLONG val;
520 HANDLE file;
521 LARGE_INTEGER file_size;
522 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
523 CreateDirectoryA("tr2_test_dir", NULL);
525 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
526 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
527 file_size.QuadPart = 7;
528 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
529 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
530 CloseHandle(file);
531 val = p_tr2_sys__File_size("tr2_test_dir/f1");
532 ok(val == 7, "file_size is %s\n", debugstr_longlong(val));
533 val = p_tr2_sys__File_size_wchar(testW);
534 ok(val == 7, "file_size is %s\n", debugstr_longlong(val));
536 file = CreateFileA("tr2_test_dir/f2", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
537 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
538 CloseHandle(file);
539 val = p_tr2_sys__File_size("tr2_test_dir/f2");
540 ok(val == 0, "file_size is %s\n", debugstr_longlong(val));
542 val = p_tr2_sys__File_size("tr2_test_dir");
543 ok(val == 0, "file_size is %s\n", debugstr_longlong(val));
545 errno = 0xdeadbeef;
546 val = p_tr2_sys__File_size("tr2_test_dir/not_exists_file");
547 ok(val == 0, "file_size is %s\n", debugstr_longlong(val));
548 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
550 errno = 0xdeadbeef;
551 val = p_tr2_sys__File_size(NULL);
552 ok(val == 0, "file_size is %s\n", debugstr_longlong(val));
553 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
555 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
556 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
557 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
560 static void test_tr2_sys__Equivalent(void)
562 int val, i;
563 HANDLE file;
564 char temp_path[MAX_PATH], current_path[MAX_PATH];
565 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
566 WCHAR testW2[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','2',0};
567 struct {
568 char const *path1;
569 char const *path2;
570 int equivalent;
571 } tests[] = {
572 { NULL, NULL, -1 },
573 { NULL, "f1", -1 },
574 { "f1", NULL, -1 },
575 { "f1", "tr2_test_dir", -1 },
576 { "tr2_test_dir", "f1", -1 },
577 { "tr2_test_dir", "tr2_test_dir", -1 },
578 { "tr2_test_dir/./f1", "tr2_test_dir/f2", 0 },
579 { "tr2_test_dir/f1" , "tr2_test_dir/f1", 1 },
580 { "not_exists_file" , "tr2_test_dir/f1", 0 },
581 { "tr2_test_dir\\f1" , "tr2_test_dir/./f1", 1 },
582 { "not_exists_file" , "not_exists_file", -1 },
583 { "tr2_test_dir/f1" , "not_exists_file", 0 },
584 { "tr2_test_dir/../tr2_test_dir/f1", "tr2_test_dir/f1", 1 }
587 memset(current_path, 0, MAX_PATH);
588 GetCurrentDirectoryA(MAX_PATH, current_path);
589 memset(temp_path, 0, MAX_PATH);
590 GetTempPathA(MAX_PATH, temp_path);
591 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
592 CreateDirectoryA("tr2_test_dir", NULL);
594 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
595 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
596 CloseHandle(file);
597 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
598 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
599 CloseHandle(file);
601 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
602 errno = 0xdeadbeef;
603 val = p_tr2_sys__Equivalent(tests[i].path1, tests[i].path2);
604 ok(tests[i].equivalent == val, "tr2_sys__Equivalent(): test %d expect: %d, got %d\n", i+1, tests[i].equivalent, val);
605 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
608 val = p_tr2_sys__Equivalent_wchar(testW, testW);
609 ok(val == 1, "tr2_sys__Equivalent(): expect: 1, got %d\n", val);
610 val = p_tr2_sys__Equivalent_wchar(testW, testW2);
611 ok(val == 0, "tr2_sys__Equivalent(): expect: 0, got %d\n", val);
613 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
614 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
615 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
616 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
619 static void test_tr2_sys__Current_get(void)
621 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
622 char *temp;
623 WCHAR temp_path_wchar[MAX_PATH], current_path_wchar[MAX_PATH];
624 WCHAR *temp_wchar;
625 memset(origin_path, 0, MAX_PATH);
626 GetCurrentDirectoryA(MAX_PATH, origin_path);
627 memset(temp_path, 0, MAX_PATH);
628 GetTempPathA(MAX_PATH, temp_path);
630 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
631 memset(current_path, 0, MAX_PATH);
632 temp = p_tr2_sys__Current_get(current_path);
633 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
634 temp[strlen(temp)] = '\\';
635 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
637 GetTempPathW(MAX_PATH, temp_path_wchar);
638 ok(SetCurrentDirectoryW(temp_path_wchar), "SetCurrentDirectoryW to temp_path_wchar failed\n");
639 memset(current_path_wchar, 0, MAX_PATH);
640 temp_wchar = p_tr2_sys__Current_get_wchar(current_path_wchar);
641 ok(temp_wchar == current_path_wchar, "p_tr2_sys__Current_get_wchar returned different buffer\n");
642 temp_wchar[wcslen(temp_wchar)] = '\\';
643 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));
645 ok(SetCurrentDirectoryA(origin_path), "SetCurrentDirectoryA to origin_path failed\n");
646 memset(current_path, 0, MAX_PATH);
647 temp = p_tr2_sys__Current_get(current_path);
648 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
649 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
652 static void test_tr2_sys__Current_set(void)
654 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
655 char *temp;
656 WCHAR testW[] = {'.','/',0};
657 memset(temp_path, 0, MAX_PATH);
658 GetTempPathA(MAX_PATH, temp_path);
659 memset(origin_path, 0, MAX_PATH);
660 GetCurrentDirectoryA(MAX_PATH, origin_path);
661 temp = p_tr2_sys__Current_get(origin_path);
662 ok(temp == origin_path, "p_tr2_sys__Current_get returned different buffer\n");
664 ok(p_tr2_sys__Current_set(temp_path), "p_tr2_sys__Current_set to temp_path failed\n");
665 memset(current_path, 0, MAX_PATH);
666 temp = p_tr2_sys__Current_get(current_path);
667 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
668 temp[strlen(temp)] = '\\';
669 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
671 ok(p_tr2_sys__Current_set_wchar(testW), "p_tr2_sys__Current_set_wchar to temp_path failed\n");
672 memset(current_path, 0, MAX_PATH);
673 temp = p_tr2_sys__Current_get(current_path);
674 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
675 temp[strlen(temp)] = '\\';
676 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
678 errno = 0xdeadbeef;
679 ok(!p_tr2_sys__Current_set("not_exisist_dir"), "p_tr2_sys__Current_set to not_exist_dir succeed\n");
680 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
682 errno = 0xdeadbeef;
683 ok(!p_tr2_sys__Current_set("??invalid_name>>"), "p_tr2_sys__Current_set to ??invalid_name>> succeed\n");
684 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
686 ok(p_tr2_sys__Current_set(origin_path), "p_tr2_sys__Current_set to origin_path failed\n");
687 memset(current_path, 0, MAX_PATH);
688 temp = p_tr2_sys__Current_get(current_path);
689 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
690 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
693 static void test_tr2_sys__Make_dir(void)
695 int ret, i;
696 WCHAR testW[] = {'w','d',0};
697 struct {
698 char const *path;
699 int val;
700 } tests[] = {
701 { "tr2_test_dir", 1 },
702 { "tr2_test_dir", 0 },
703 { NULL, -1 },
704 { "??invalid_name>>", -1 }
707 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
708 errno = 0xdeadbeef;
709 ret = p_tr2_sys__Make_dir(tests[i].path);
710 ok(ret == tests[i].val, "tr2_sys__Make_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
711 ok(errno == 0xdeadbeef, "tr2_sys__Make_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
713 ret = p_tr2_sys__Make_dir_wchar(testW);
714 ok(ret == 1, "tr2_sys__Make_dir(): expect: 1, got %d\n", ret);
716 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
717 ok(p_tr2_sys__Remove_dir_wchar(testW), "expect wd to exist\n");
720 static void test_tr2_sys__Remove_dir(void)
722 MSVCP_bool ret;
723 int i;
724 struct {
725 char const *path;
726 MSVCP_bool val;
727 } tests[] = {
728 { "tr2_test_dir", TRUE },
729 { "tr2_test_dir", FALSE },
730 { NULL, FALSE },
731 { "??invalid_name>>", FALSE }
734 ok(p_tr2_sys__Make_dir("tr2_test_dir"), "tr2_sys__Make_dir() failed\n");
736 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
737 errno = 0xdeadbeef;
738 ret = p_tr2_sys__Remove_dir(tests[i].path);
739 ok(ret == tests[i].val, "test_tr2_sys__Remove_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
740 ok(errno == 0xdeadbeef, "test_tr2_sys__Remove_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
744 static void test_tr2_sys__Copy_file(void)
746 HANDLE file;
747 int ret, i;
748 LARGE_INTEGER file_size;
749 WCHAR testW[] = {'f','1',0}, testW2[] = {'f','w',0};
750 struct {
751 char const *source;
752 char const *dest;
753 MSVCP_bool fail_if_exists;
754 int last_error;
755 int last_error2;
756 MSVCP_bool is_todo;
757 } tests[] = {
758 { "f1", "f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
759 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
760 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_FILE_EXISTS, ERROR_FILE_EXISTS, FALSE },
761 { "f1", "tr2_test_dir\\f1_copy", FALSE, ERROR_SUCCESS, ERROR_SUCCESS, FALSE },
762 { "tr2_test_dir", "f1", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED, FALSE },
763 { "tr2_test_dir", "tr2_test_dir_copy", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED, FALSE },
764 { NULL, "f1", TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER, TRUE },
765 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER, TRUE },
766 { "not_exist", "tr2_test_dir", TRUE, ERROR_FILE_NOT_FOUND, ERROR_FILE_NOT_FOUND, FALSE },
767 { "f1", "not_exist_dir\\f1_copy", TRUE, ERROR_PATH_NOT_FOUND, ERROR_FILE_NOT_FOUND, FALSE },
768 { "f1", "tr2_test_dir", TRUE, ERROR_ACCESS_DENIED, ERROR_FILE_EXISTS, FALSE }
771 ret = p_tr2_sys__Make_dir("tr2_test_dir");
772 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
773 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
774 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
775 file_size.QuadPart = 7;
776 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
777 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
778 CloseHandle(file);
780 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
781 errno = 0xdeadbeef;
782 ret = p_tr2_sys__Copy_file(tests[i].source, tests[i].dest, tests[i].fail_if_exists);
783 if(tests[i].is_todo)
784 todo_wine ok(ret == tests[i].last_error || ret == tests[i].last_error2,
785 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n",
786 i+1, tests[i].last_error, ret);
787 else
788 ok(ret == tests[i].last_error || ret == tests[i].last_error2,
789 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n",
790 i+1, tests[i].last_error, ret);
791 ok(errno == 0xdeadbeef, "test_tr2_sys__Copy_file(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
792 if(ret == ERROR_SUCCESS)
793 ok(p_tr2_sys__File_size(tests[i].source) == p_tr2_sys__File_size(tests[i].dest),
794 "test_tr2_sys__Copy_file(): test %d failed, two files' size are not equal\n", i+1);
796 ret = p_tr2_sys__Copy_file_wchar(testW, testW2, TRUE);
797 ok(ret == ERROR_SUCCESS, "test_tr2_sys__Copy_file_wchar() expect ERROR_SUCCESS, got %d\n", ret);
799 ok(DeleteFileA("f1"), "expect f1 to exist\n");
800 ok(DeleteFileW(testW2), "expect fw to exist\n");
801 ok(DeleteFileA("f1_copy"), "expect f1_copy to exist\n");
802 ok(DeleteFileA("tr2_test_dir/f1_copy"), "expect tr2_test_dir/f1 to exist\n");
803 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
804 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
807 static void test_tr2_sys__Rename(void)
809 int ret, i;
810 HANDLE file, h1, h2;
811 BY_HANDLE_FILE_INFORMATION info1, info2;
812 char temp_path[MAX_PATH], current_path[MAX_PATH];
813 LARGE_INTEGER file_size;
814 WCHAR testW[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
815 WCHAR testW2[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','w',0};
816 struct {
817 char const *old_path;
818 char const *new_path;
819 int val;
820 } tests[] = {
821 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_SUCCESS },
822 { "tr2_test_dir\\f1", NULL, ERROR_INVALID_PARAMETER },
823 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND },
824 { NULL, "tr2_test_dir\\NULL_rename", ERROR_INVALID_PARAMETER },
825 { "tr2_test_dir\\f1_rename", "tr2_test_dir\\??invalid_name>>", ERROR_INVALID_NAME },
826 { "tr2_test_dir\\not_exist_file", "tr2_test_dir\\not_exist_rename", ERROR_FILE_NOT_FOUND }
829 memset(current_path, 0, MAX_PATH);
830 GetCurrentDirectoryA(MAX_PATH, current_path);
831 memset(temp_path, 0, MAX_PATH);
832 GetTempPathA(MAX_PATH, temp_path);
833 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
834 ret = p_tr2_sys__Make_dir("tr2_test_dir");
836 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
837 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
838 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
839 CloseHandle(file);
841 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1");
842 todo_wine ok(ERROR_SUCCESS == ret, "test_tr2_sys__Rename(): expect: ERROR_SUCCESS, got %d\n", ret);
843 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
844 errno = 0xdeadbeef;
845 if(tests[i].val == ERROR_SUCCESS) {
846 h1 = CreateFileA(tests[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
847 NULL, OPEN_EXISTING, 0, 0);
848 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
849 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
850 CloseHandle(h1);
852 SetLastError(0xdeadbeef);
853 ret = p_tr2_sys__Rename(tests[i].old_path, tests[i].new_path);
854 ok(ret == tests[i].val, "test_tr2_sys__Rename(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
855 ok(errno == 0xdeadbeef, "test_tr2_sys__Rename(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
856 if(ret == ERROR_SUCCESS) {
857 h2 = CreateFileA(tests[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
858 NULL, OPEN_EXISTING, 0, 0);
859 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
860 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
861 CloseHandle(h2);
862 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
863 && info1.nFileIndexLow == info2.nFileIndexLow,
864 "test_tr2_sys__Rename(): test %d expect two files equivalent\n", i+1);
868 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
869 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
870 file_size.QuadPart = 7;
871 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
872 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
873 CloseHandle(file);
874 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1_rename");
875 ok(ret == ERROR_ALREADY_EXISTS, "test_tr2_sys__Rename(): expect: ERROR_ALREADY_EXISTS, got %d\n", ret);
876 ok(p_tr2_sys__File_size("tr2_test_dir\\f1") == 7, "test_tr2_sys__Rename(): expect: 7, got %s\n", debugstr_longlong(p_tr2_sys__File_size("tr2_test_dir\\f1")));
877 ok(p_tr2_sys__File_size("tr2_test_dir\\f1_rename") == 0, "test_tr2_sys__Rename(): expect: 0, got %s\n",debugstr_longlong(p_tr2_sys__File_size("tr2_test_dir\\f1_rename")));
878 ret = p_tr2_sys__Rename_wchar(testW, testW2);
879 ok(ret == ERROR_SUCCESS, "tr2_sys__Rename_wchar(): expect: ERROR_SUCCESS, got %d\n", ret);
881 ok(DeleteFileW(testW2), "expect fw to exist\n");
882 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
883 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
884 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect %d got %d\n", 1, ret);
885 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
888 static void test_tr2_sys__Statvfs(void)
890 struct space_info info;
891 char current_path[MAX_PATH];
892 WCHAR current_path_wchar[MAX_PATH];
893 memset(current_path, 0, MAX_PATH);
894 p_tr2_sys__Current_get(current_path);
895 memset(current_path_wchar, 0, MAX_PATH);
896 p_tr2_sys__Current_get_wchar(current_path_wchar);
898 info = p_tr2_sys__Statvfs(current_path);
899 ok(info.capacity >= info.free, "test_tr2_sys__Statvfs(): info.capacity < info.free\n");
900 ok(info.free >= info.available, "test_tr2_sys__Statvfs(): info.free < info.available\n");
902 info = p_tr2_sys__Statvfs_wchar(current_path_wchar);
903 ok(info.capacity >= info.free, "tr2_sys__Statvfs_wchar(): info.capacity < info.free\n");
904 ok(info.free >= info.available, "tr2_sys__Statvfs_wchar(): info.free < info.available\n");
906 info = p_tr2_sys__Statvfs(NULL);
907 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
908 0, debugstr_longlong(info.available));
909 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
910 0, debugstr_longlong(info.capacity));
911 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
912 0, debugstr_longlong(info.free));
914 info = p_tr2_sys__Statvfs("not_exist");
915 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
916 0, debugstr_longlong(info.available));
917 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
918 0, debugstr_longlong(info.capacity));
919 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
920 0, debugstr_longlong(info.free));
923 static void test_tr2_sys__Stat(void)
925 int i, err_code, ret;
926 HANDLE file;
927 enum file_type val;
928 struct {
929 char const *path;
930 enum file_type ret;
931 int err_code;
932 int is_todo;
933 } tests[] = {
934 { NULL, status_unknown, ERROR_INVALID_PARAMETER, FALSE },
935 { "tr2_test_dir", directory_file, ERROR_SUCCESS, FALSE },
936 { "tr2_test_dir\\f1", regular_file, ERROR_SUCCESS, FALSE },
937 { "tr2_test_dir\\not_exist_file ", file_not_found, ERROR_SUCCESS, FALSE },
938 { "tr2_test_dir\\??invalid_name>>", file_not_found, ERROR_SUCCESS, FALSE },
939 { "tr2_test_dir\\f1_link" , regular_file, ERROR_SUCCESS, TRUE },
940 { "tr2_test_dir\\dir_link", directory_file, ERROR_SUCCESS, TRUE },
943 CreateDirectoryA("tr2_test_dir", NULL);
944 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
945 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
946 ok(CloseHandle(file), "CloseHandle\n");
947 SetLastError(0xdeadbeef);
948 ret = CreateSymbolicLinkA("tr2_test_dir/f1_link", "tr2_test_dir/f1", 0);
949 if(!ret && (GetLastError()==ERROR_PRIVILEGE_NOT_HELD||GetLastError()==ERROR_INVALID_FUNCTION)) {
950 tests[5].ret = tests[6].ret = file_not_found;
951 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
952 }else {
953 ok(ret, "CreateSymbolicLinkA failed\n");
954 ok(CreateSymbolicLinkA("tr2_test_dir/dir_link", "tr2_test_dir", 1), "CreateSymbolicLinkA failed\n");
957 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
958 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
959 NMPWAIT_USE_DEFAULT_WAIT, NULL);
960 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
961 err_code = 0xdeadbeef;
962 val = p_tr2_sys__Stat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
963 todo_wine ok(regular_file == val, "tr2_sys__Stat(): expect: regular_file, got %d\n", val);
964 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Stat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
965 err_code = 0xdeadbeef;
966 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
967 ok(status_unknown == val, "tr2_sys__Lstat(): expect: status_unknown, got %d\n", val);
968 todo_wine ok(ERROR_PIPE_BUSY == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_PIPE_BUSY, got %d\n", err_code);
969 ok(CloseHandle(file), "CloseHandle\n");
970 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
971 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
972 NMPWAIT_USE_DEFAULT_WAIT, NULL);
973 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
974 err_code = 0xdeadbeef;
975 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
976 todo_wine ok(regular_file == val, "tr2_sys__Lstat(): expect: regular_file, got %d\n", val);
977 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
978 ok(CloseHandle(file), "CloseHandle\n");
980 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
981 err_code = 0xdeadbeef;
982 val = p_tr2_sys__Stat(tests[i].path, &err_code);
983 if(tests[i].is_todo)
984 todo_wine ok(tests[i].ret == val, "tr2_sys__Stat(): test %d expect: %d, got %d\n",
985 i+1, tests[i].ret, val);
986 else
987 ok(tests[i].ret == val, "tr2_sys__Stat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
988 ok(tests[i].err_code == err_code, "tr2_sys__Stat(): test %d err_code expect: %d, got %d\n",
989 i+1, tests[i].err_code, err_code);
991 /* test tr2_sys__Lstat */
992 err_code = 0xdeadbeef;
993 val = p_tr2_sys__Lstat(tests[i].path, &err_code);
994 if(tests[i].is_todo)
995 todo_wine ok(tests[i].ret == val, "tr2_sys__Lstat(): test %d expect: %d, got %d\n",
996 i+1, tests[i].ret, val);
997 else
998 ok(tests[i].ret == val, "tr2_sys__Lstat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1000 ok(tests[i].err_code == err_code, "tr2_sys__Lstat(): test %d err_code expect: %d, got %d\n",
1001 i+1, tests[i].err_code, err_code);
1004 if(ret) {
1005 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1006 todo_wine ok(RemoveDirectoryA("tr2_test_dir/dir_link"), "expect tr2_test_dir/dir_link to exist\n");
1008 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1009 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1012 static void test_tr2_sys__Last_write_time(void)
1014 HANDLE file;
1015 int ret;
1016 __int64 last_write_time, newtime;
1017 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1018 ok(ret == 1, "tr2_sys__Make_dir() expect 1 got %d\n", ret);
1020 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1021 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1022 CloseHandle(file);
1024 last_write_time = p_tr2_sys__Last_write_time("tr2_test_dir/f1");
1025 newtime = last_write_time + 123456789;
1026 p_tr2_sys__Last_write_time_set("tr2_test_dir/f1", newtime);
1027 todo_wine ok(last_write_time == p_tr2_sys__Last_write_time("tr2_test_dir/f1"),
1028 "last_write_time before modfied should not equal to last_write_time %s\n",
1029 debugstr_longlong(last_write_time));
1031 errno = 0xdeadbeef;
1032 last_write_time = p_tr2_sys__Last_write_time("not_exist");
1033 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1034 ok(last_write_time == 0, "expect 0 got %s\n", debugstr_longlong(last_write_time));
1035 last_write_time = p_tr2_sys__Last_write_time(NULL);
1036 ok(last_write_time == 0, "expect 0 got %s\n", debugstr_longlong(last_write_time));
1038 p_tr2_sys__Last_write_time_set("not_exist", newtime);
1039 errno = 0xdeadbeef;
1040 p_tr2_sys__Last_write_time_set(NULL, newtime);
1041 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1043 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1044 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1045 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1048 START_TEST(msvcp120)
1050 if(!init()) return;
1051 test__Xtime_diff_to_millis2();
1052 test_xtime_get();
1053 test__Getcvt();
1054 test__Call_once();
1055 test__Do_call();
1056 test__Dtest();
1057 test__Dscale();
1059 test_tr2_sys__File_size();
1060 test_tr2_sys__Equivalent();
1061 test_tr2_sys__Current_get();
1062 test_tr2_sys__Current_set();
1063 test_tr2_sys__Make_dir();
1064 test_tr2_sys__Remove_dir();
1065 test_tr2_sys__Copy_file();
1066 test_tr2_sys__Rename();
1067 test_tr2_sys__Statvfs();
1068 test_tr2_sys__Stat();
1069 test_tr2_sys__Last_write_time();
1070 FreeLibrary(msvcp);