include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / msvcp140 / tests / msvcp140.c
blobfaf4c214801605b0428b61efb826d9fc31ed4cbc
1 /*
2 * Copyright 2016 Daniel Lehman
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 <errno.h>
20 #include <stdio.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winnls.h"
26 #include "wine/test.h"
27 #include "winbase.h"
29 #define SECSPERDAY 86400
30 /* 1601 to 1970 is 369 years plus 89 leap days */
31 #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
32 #define TICKSPERSEC 10000000
33 #define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)
35 #define DEFINE_EXPECT(func) \
36 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
38 #define SET_EXPECT(func) \
39 do { \
40 expect_ ## func = TRUE; \
41 errno = 0xdeadbeef; \
42 }while(0)
44 #define CHECK_EXPECT2(func) \
45 do { \
46 ok(expect_ ##func, "unexpected call " #func "\n"); \
47 called_ ## func = TRUE; \
48 }while(0)
50 #define CHECK_EXPECT(func) \
51 do { \
52 CHECK_EXPECT2(func); \
53 expect_ ## func = FALSE; \
54 }while(0)
56 #define CHECK_CALLED(func) \
57 do { \
58 ok(called_ ## func, "expected " #func "\n"); \
59 expect_ ## func = called_ ## func = FALSE; \
60 }while(0)
62 #ifdef _WIN64
63 DEFINE_EXPECT(function_do_call);
64 DEFINE_EXPECT(function_do_clean);
65 #endif
67 #undef __thiscall
68 #ifdef __i386__
69 #define __thiscall __stdcall
70 #else
71 #define __thiscall __cdecl
72 #endif
74 /* Emulate a __thiscall */
75 #ifdef __i386__
77 #include "pshpack1.h"
78 struct thiscall_thunk
80 BYTE pop_eax; /* popl %eax (ret addr) */
81 BYTE pop_edx; /* popl %edx (func) */
82 BYTE pop_ecx; /* popl %ecx (this) */
83 BYTE push_eax; /* pushl %eax */
84 WORD jmp_edx; /* jmp *%edx */
86 #include "poppack.h"
88 static void * (WINAPI *call_thiscall_func1)( void *func, void *this );
89 static void * (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a );
91 static void init_thiscall_thunk(void)
93 struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
94 MEM_COMMIT, PAGE_EXECUTE_READWRITE );
95 thunk->pop_eax = 0x58; /* popl %eax */
96 thunk->pop_edx = 0x5a; /* popl %edx */
97 thunk->pop_ecx = 0x59; /* popl %ecx */
98 thunk->push_eax = 0x50; /* pushl %eax */
99 thunk->jmp_edx = 0xe2ff; /* jmp *%edx */
100 call_thiscall_func1 = (void *)thunk;
101 call_thiscall_func2 = (void *)thunk;
104 #define call_func1(func,_this) call_thiscall_func1(func,_this)
105 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,a)
107 #else
109 #define init_thiscall_thunk()
110 #define call_func1(func,_this) func(_this)
111 #define call_func2(func,_this,a) func(_this,a)
113 #endif /* __i386__ */
114 typedef unsigned char MSVCP_bool;
116 typedef struct {
117 void *unk0;
118 BYTE unk1;
119 } task_continuation_context;
121 typedef struct {
122 void *unused;
123 } _ContextCallback;
125 typedef struct {
126 const void *vtable;
127 void (__cdecl *func)(void);
128 int unk[4];
129 void *unk2[3];
130 void *this;
131 } function_void_cdecl_void;
133 typedef struct {
134 void *task;
135 MSVCP_bool scheduled;
136 MSVCP_bool started;
137 } _TaskEventLogger;
139 typedef struct {
140 PTP_WORK work;
141 void (__cdecl *callback)(void*);
142 void *arg;
143 } _Threadpool_chore;
145 typedef struct
147 HANDLE hnd;
148 DWORD id;
149 } _Thrd_t;
151 typedef struct cs_queue
153 void *ctx;
154 struct cs_queue *next;
155 BOOL free;
156 int unknown;
157 } cs_queue;
159 typedef struct
161 cs_queue unk_active;
162 void *unknown[2];
163 cs_queue *head;
164 void *tail;
165 } critical_section;
167 typedef struct
169 DWORD flags;
170 critical_section cs;
171 ULONG_PTR unknown;
172 DWORD thread_id;
173 DWORD count;
174 } *_Mtx_t;
176 typedef void *_Cnd_t;
178 typedef struct {
179 __time64_t sec;
180 int nsec;
181 } xtime;
183 typedef int (__cdecl *_Thrd_start_t)(void*);
185 enum file_type {
186 file_not_found = -1,
187 none_file,
188 regular_file,
189 directory_file,
190 symlink_file,
191 block_file,
192 character_file,
193 fifo_file,
194 socket_file,
195 status_unknown
198 static unsigned int (__cdecl *p__Thrd_id)(void);
199 static MSVCP_bool (__cdecl *p__Task_impl_base__IsNonBlockingThread)(void);
200 static task_continuation_context* (__thiscall *p_task_continuation_context_ctor)(task_continuation_context*);
201 static void (__thiscall *p__ContextCallback__Assign)(_ContextCallback*, void*);
202 static void (__thiscall *p__ContextCallback__CallInContext)(const _ContextCallback*, function_void_cdecl_void, MSVCP_bool);
203 static void (__thiscall *p__ContextCallback__Capture)(_ContextCallback*);
204 static void (__thiscall *p__ContextCallback__Reset)(_ContextCallback*);
205 static MSVCP_bool (__cdecl *p__ContextCallback__IsCurrentOriginSTA)(_ContextCallback*);
206 static void (__thiscall *p__TaskEventLogger__LogCancelTask)(_TaskEventLogger*);
207 static void (__thiscall *p__TaskEventLogger__LogScheduleTask)(_TaskEventLogger*, MSVCP_bool);
208 static void (__thiscall *p__TaskEventLogger__LogTaskCompleted)(_TaskEventLogger*);
209 static void (__thiscall *p__TaskEventLogger__LogTaskExecutionCompleted)(_TaskEventLogger*);
210 static void (__thiscall *p__TaskEventLogger__LogWorkItemCompleted)(_TaskEventLogger*);
211 static void (__thiscall *p__TaskEventLogger__LogWorkItemStarted)(_TaskEventLogger*);
212 static int (__cdecl *p__Schedule_chore)(_Threadpool_chore*);
213 static int (__cdecl *p__Reschedule_chore)(const _Threadpool_chore*);
214 static void (__cdecl *p__Release_chore)(_Threadpool_chore*);
215 static int (__cdecl *p__Mtx_init)(_Mtx_t*, int);
216 static void (__cdecl *p__Mtx_destroy)(_Mtx_t);
217 static int (__cdecl *p__Mtx_lock)(_Mtx_t);
218 static int (__cdecl *p__Mtx_unlock)(_Mtx_t);
219 static int (__cdecl *p__Cnd_init)(_Cnd_t*);
220 static void (__cdecl *p__Cnd_destroy)(_Cnd_t);
221 static int (__cdecl *p__Cnd_wait)(_Cnd_t, _Mtx_t);
222 static int (__cdecl *p__Cnd_timedwait)(_Cnd_t, _Mtx_t, const xtime*);
223 static int (__cdecl *p__Cnd_broadcast)(_Cnd_t);
224 static int (__cdecl *p__Cnd_signal)(_Cnd_t);
225 static int (__cdecl *p__Thrd_create)(_Thrd_t*, _Thrd_start_t, void*);
226 static int (__cdecl *p__Thrd_join)(_Thrd_t, int*);
227 static int (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
228 static int (__cdecl *p_xtime_get)(xtime*, int);
230 static void (__cdecl *p_Close_dir)(void*);
231 static DWORD (__cdecl *p_Copy_file)(WCHAR const *, WCHAR const *);
232 static MSVCP_bool (__cdecl *p_Current_get)(WCHAR *);
233 static MSVCP_bool (__cdecl *p_Current_set)(WCHAR const *);
234 static int (__cdecl *p_Equivalent)(WCHAR const*, WCHAR const*);
235 static ULONGLONG (__cdecl *p_File_size)(WCHAR const *);
236 static int (__cdecl *p_Resize)(const WCHAR *, UINT64);
237 static __int64 (__cdecl *p_Last_write_time)(WCHAR const*);
238 static void (__cdecl *p_Set_last_write_time)(WCHAR const*, __int64);
239 static int (__cdecl *p_Link)(WCHAR const*, WCHAR const*);
240 static enum file_type (__cdecl *p_Lstat)(WCHAR const *, int *);
241 static int (__cdecl *p_Make_dir)(WCHAR const*);
242 static void* (__cdecl *p_Open_dir)(WCHAR*, WCHAR const*, int *, enum file_type*);
243 static WCHAR* (__cdecl *p_Read_dir)(WCHAR*, void*, enum file_type*);
244 static MSVCP_bool (__cdecl *p_Remove_dir)(WCHAR const*);
245 static int (__cdecl *p_Rename)(WCHAR const*, WCHAR const*);
246 static enum file_type (__cdecl *p_Stat)(WCHAR const *, int *);
247 static int (__cdecl *p_Symlink)(WCHAR const*, WCHAR const*);
248 static WCHAR* (__cdecl *p_Temp_get)(WCHAR *);
249 static int (__cdecl *p_To_byte)(const WCHAR *src, char *dst);
250 static int (__cdecl *p_To_wide)(const char *src, WCHAR *dst);
251 static int (__cdecl *p_Unlink)(WCHAR const*);
252 static ULONG (__cdecl *p__Winerror_message)(ULONG, char*, ULONG);
253 static int (__cdecl *p__Winerror_map)(int);
254 static const char* (__cdecl *p__Syserror_map)(int err);
256 static BOOLEAN (WINAPI *pCreateSymbolicLinkW)(const WCHAR *, const WCHAR *, DWORD);
258 static HMODULE msvcp;
259 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
260 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
261 static BOOL init(void)
263 HANDLE hdll;
265 msvcp = LoadLibraryA("msvcp140.dll");
266 if(!msvcp)
268 win_skip("msvcp140.dll not installed\n");
269 return FALSE;
272 SET(p__Thrd_id, "_Thrd_id");
273 SET(p__Task_impl_base__IsNonBlockingThread, "?_IsNonBlockingThread@_Task_impl_base@details@Concurrency@@SA_NXZ");
274 SET(p__ContextCallback__IsCurrentOriginSTA, "?_IsCurrentOriginSTA@_ContextCallback@details@Concurrency@@CA_NXZ");
275 SET(p__Winerror_map, "?_Winerror_map@std@@YAHH@Z");
277 if(sizeof(void*) == 8) { /* 64-bit initialization */
278 SET(p_task_continuation_context_ctor, "??0task_continuation_context@Concurrency@@AEAA@XZ");
279 SET(p__ContextCallback__Assign, "?_Assign@_ContextCallback@details@Concurrency@@AEAAXPEAX@Z");
280 SET(p__ContextCallback__CallInContext, "?_CallInContext@_ContextCallback@details@Concurrency@@QEBAXV?$function@$$A6AXXZ@std@@_N@Z");
281 SET(p__ContextCallback__Capture, "?_Capture@_ContextCallback@details@Concurrency@@AEAAXXZ");
282 SET(p__ContextCallback__Reset, "?_Reset@_ContextCallback@details@Concurrency@@AEAAXXZ");
283 SET(p__TaskEventLogger__LogCancelTask, "?_LogCancelTask@_TaskEventLogger@details@Concurrency@@QEAAXXZ");
284 SET(p__TaskEventLogger__LogScheduleTask, "?_LogScheduleTask@_TaskEventLogger@details@Concurrency@@QEAAX_N@Z");
285 SET(p__TaskEventLogger__LogTaskCompleted, "?_LogTaskCompleted@_TaskEventLogger@details@Concurrency@@QEAAXXZ");
286 SET(p__TaskEventLogger__LogTaskExecutionCompleted, "?_LogTaskExecutionCompleted@_TaskEventLogger@details@Concurrency@@QEAAXXZ");
287 SET(p__TaskEventLogger__LogWorkItemCompleted, "?_LogWorkItemCompleted@_TaskEventLogger@details@Concurrency@@QEAAXXZ");
288 SET(p__TaskEventLogger__LogWorkItemStarted, "?_LogWorkItemStarted@_TaskEventLogger@details@Concurrency@@QEAAXXZ");
289 SET(p__Schedule_chore, "?_Schedule_chore@details@Concurrency@@YAHPEAU_Threadpool_chore@12@@Z");
290 SET(p__Reschedule_chore, "?_Reschedule_chore@details@Concurrency@@YAHPEBU_Threadpool_chore@12@@Z");
291 SET(p__Release_chore, "?_Release_chore@details@Concurrency@@YAXPEAU_Threadpool_chore@12@@Z");
292 SET(p__Winerror_message, "?_Winerror_message@std@@YAKKPEADK@Z");
293 SET(p__Syserror_map, "?_Syserror_map@std@@YAPEBDH@Z");
294 } else {
295 #ifdef __arm__
296 SET(p_task_continuation_context_ctor, "??0task_continuation_context@Concurrency@@AAA@XZ");
297 SET(p__ContextCallback__Assign, "?_Assign@_ContextCallback@details@Concurrency@@AAAXPAX@Z");
298 SET(p__ContextCallback__CallInContext, "?_CallInContext@_ContextCallback@details@Concurrency@@QBAXV?$function@$$A6AXXZ@std@@_N@Z");
299 SET(p__ContextCallback__Capture, "?_Capture@_ContextCallback@details@Concurrency@@AAAXXZ");
300 SET(p__ContextCallback__Reset, "?_Reset@_ContextCallback@details@Concurrency@@AAAXXZ");
301 SET(p__TaskEventLogger__LogCancelTask, "?_LogCancelTask@_TaskEventLogger@details@Concurrency@@QAAXXZ");
302 SET(p__TaskEventLogger__LogScheduleTask, "?_LogScheduleTask@_TaskEventLogger@details@Concurrency@@QAAX_N@Z@Z");
303 SET(p__TaskEventLogger__LogTaskCompleted, "?_LogTaskCompleted@_TaskEventLogger@details@Concurrency@@QAAXXZ");
304 SET(p__TaskEventLogger__LogTaskExecutionCompleted, "?_LogTaskExecutionCompleted@_TaskEventLogger@details@Concurrency@@QAAXXZ");
305 SET(p__TaskEventLogger__LogWorkItemCompleted, "?_LogWorkItemCompleted@_TaskEventLogger@details@Concurrency@@QAAXXZ");
306 SET(p__TaskEventLogger__LogWorkItemStarted, "?_LogWorkItemStarted@_TaskEventLogger@details@Concurrency@@QAAXXZ");
307 #else
308 SET(p_task_continuation_context_ctor, "??0task_continuation_context@Concurrency@@AAE@XZ");
309 SET(p__ContextCallback__Assign, "?_Assign@_ContextCallback@details@Concurrency@@AAEXPAX@Z");
310 SET(p__ContextCallback__CallInContext, "?_CallInContext@_ContextCallback@details@Concurrency@@QBEXV?$function@$$A6AXXZ@std@@_N@Z");
311 SET(p__ContextCallback__Capture, "?_Capture@_ContextCallback@details@Concurrency@@AAEXXZ");
312 SET(p__ContextCallback__Reset, "?_Reset@_ContextCallback@details@Concurrency@@AAEXXZ");
313 SET(p__TaskEventLogger__LogCancelTask, "?_LogCancelTask@_TaskEventLogger@details@Concurrency@@QAEXXZ");
314 SET(p__TaskEventLogger__LogScheduleTask, "?_LogScheduleTask@_TaskEventLogger@details@Concurrency@@QAEX_N@Z");
315 SET(p__TaskEventLogger__LogTaskCompleted, "?_LogTaskCompleted@_TaskEventLogger@details@Concurrency@@QAEXXZ");
316 SET(p__TaskEventLogger__LogTaskExecutionCompleted, "?_LogTaskExecutionCompleted@_TaskEventLogger@details@Concurrency@@QAEXXZ");
317 SET(p__TaskEventLogger__LogWorkItemCompleted, "?_LogWorkItemCompleted@_TaskEventLogger@details@Concurrency@@QAEXXZ");
318 SET(p__TaskEventLogger__LogWorkItemStarted, "?_LogWorkItemStarted@_TaskEventLogger@details@Concurrency@@QAEXXZ");
319 #endif
320 SET(p__Schedule_chore, "?_Schedule_chore@details@Concurrency@@YAHPAU_Threadpool_chore@12@@Z");
321 SET(p__Reschedule_chore, "?_Reschedule_chore@details@Concurrency@@YAHPBU_Threadpool_chore@12@@Z");
322 SET(p__Release_chore, "?_Release_chore@details@Concurrency@@YAXPAU_Threadpool_chore@12@@Z");
323 SET(p__Winerror_message, "?_Winerror_message@std@@YAKKPADK@Z");
324 SET(p__Syserror_map, "?_Syserror_map@std@@YAPBDH@Z");
327 SET(p__Mtx_init, "_Mtx_init");
328 SET(p__Mtx_destroy, "_Mtx_destroy");
329 SET(p__Mtx_lock, "_Mtx_lock");
330 SET(p__Mtx_unlock, "_Mtx_unlock");
331 SET(p__Cnd_init, "_Cnd_init");
332 SET(p__Cnd_destroy, "_Cnd_destroy");
333 SET(p__Cnd_wait, "_Cnd_wait");
334 SET(p__Cnd_timedwait, "_Cnd_timedwait");
335 SET(p__Cnd_broadcast, "_Cnd_broadcast");
336 SET(p__Cnd_signal, "_Cnd_signal");
337 SET(p__Thrd_create, "_Thrd_create");
338 SET(p__Thrd_join, "_Thrd_join");
339 SET(p__Xtime_diff_to_millis2, "_Xtime_diff_to_millis2");
340 SET(p_xtime_get, "xtime_get");
342 SET(p_Close_dir, "_Close_dir");
343 SET(p_Copy_file, "_Copy_file");
344 SET(p_Current_get, "_Current_get");
345 SET(p_Current_set, "_Current_set");
346 SET(p_Equivalent, "_Equivalent");
347 SET(p_File_size, "_File_size");
348 SET(p_Resize, "_Resize");
349 SET(p_Last_write_time, "_Last_write_time");
350 SET(p_Set_last_write_time, "_Set_last_write_time");
351 SET(p_Link, "_Link");
352 SET(p_Lstat, "_Lstat");
353 SET(p_Make_dir, "_Make_dir");
354 SET(p_Open_dir, "_Open_dir");
355 SET(p_Read_dir, "_Read_dir");
356 SET(p_Remove_dir, "_Remove_dir");
357 SET(p_Rename, "_Rename");
358 SET(p_Stat, "_Stat");
359 SET(p_Symlink, "_Symlink");
360 SET(p_Temp_get, "_Temp_get");
361 SET(p_To_byte, "_To_byte");
362 SET(p_To_wide, "_To_wide");
363 SET(p_Unlink, "_Unlink");
365 hdll = GetModuleHandleA("kernel32.dll");
366 pCreateSymbolicLinkW = (void*)GetProcAddress(hdll, "CreateSymbolicLinkW");
368 init_thiscall_thunk();
369 return TRUE;
372 static void test_thrd(void)
374 ok(p__Thrd_id() == GetCurrentThreadId(),
375 "expected same id, got _Thrd_id %u GetCurrentThreadId %lu\n",
376 p__Thrd_id(), GetCurrentThreadId());
379 static void test__Task_impl_base__IsNonBlockingThread(void)
381 ok(!p__Task_impl_base__IsNonBlockingThread(), "_IsNonBlockingThread() returned true\n");
384 static struct {
385 int value[2];
386 const char* export_name;
387 } vbtable_size_exports_list[] = {
388 {{0x20, 0x20}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"},
389 {{0x10, 0x10}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"},
390 {{0x20, 0x20}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"},
391 {{0x10, 0x10}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"},
392 {{0x20, 0x20}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"},
393 {{0x10, 0x10}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"},
394 {{0x18, 0x18}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"},
395 {{0x18, 0x18}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"},
396 {{0x18, 0x18}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"},
397 {{ 0x8, 0x10}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"},
398 {{ 0x8, 0x10}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"},
399 {{ 0x8, 0x10}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"},
400 {{ 0x0, 0x0}, 0}
403 static void test_vbtable_size_exports(void)
405 int i;
406 const int *p_vbtable;
407 int arch_idx = (sizeof(void*) == 8);
409 for (i = 0; vbtable_size_exports_list[i].export_name; i++)
411 SET(p_vbtable, vbtable_size_exports_list[i].export_name);
413 ok(p_vbtable[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable[0]);
414 ok(p_vbtable[1] == vbtable_size_exports_list[i].value[arch_idx],
415 "%d: %s[1] wrong, got 0x%x\n", i, vbtable_size_exports_list[i].export_name, p_vbtable[1]);
419 static void test_task_continuation_context(void)
421 task_continuation_context tcc;
423 memset(&tcc, 0xff, sizeof(tcc));
424 call_func1(p_task_continuation_context_ctor, &tcc);
425 ok(!tcc.unk0, "tcc.unk0 != NULL (%p)\n", tcc.unk0);
426 ok(!tcc.unk1, "tcc.unk1 != 0 (%x)\n", tcc.unk1);
429 #ifdef _WIN64
430 static void __cdecl function_do_call(void *this)
432 CHECK_EXPECT(function_do_call);
435 static void __cdecl function_do_clean(void *this, MSVCP_bool b)
437 CHECK_EXPECT(function_do_clean);
438 ok(b, "b == FALSE\n");
440 #endif
442 static void test__ContextCallback(void)
444 _ContextCallback cc = {0};
445 void *v = (void*)0xdeadbeef;
446 #ifdef _WIN64
447 void* function_vtbl[] = {
448 NULL,
449 NULL,
450 (void*)function_do_call,
451 NULL,
452 (void*)function_do_clean,
453 NULL
455 function_void_cdecl_void function = { function_vtbl, NULL, {0}, {NULL}, &function };
456 function_void_cdecl_void function2 = { NULL, NULL, {0}, {NULL}, &function };
457 #endif
459 call_func2(p__ContextCallback__Assign, &cc, v);
460 ok(!cc.unused, "cc.unused = %p\n", cc.unused);
461 call_func1(p__ContextCallback__Reset, &cc);
462 ok(!cc.unused, "cc.unused = %p\n", cc.unused);
463 call_func1(p__ContextCallback__Capture, &cc);
464 ok(!cc.unused, "cc.unused = %p\n", cc.unused);
465 ok(!p__ContextCallback__IsCurrentOriginSTA(&cc), "IsCurrentOriginSTA returned TRUE\n");
467 cc.unused = v;
468 call_func2(p__ContextCallback__Assign, &cc, NULL);
469 ok(cc.unused == v, "cc.unused = %p\n", cc.unused);
470 call_func1(p__ContextCallback__Reset, &cc);
471 ok(cc.unused == v, "cc.unused = %p\n", cc.unused);
472 call_func1(p__ContextCallback__Capture, &cc);
473 ok(cc.unused == v, "cc.unused = %p\n", cc.unused);
474 ok(!p__ContextCallback__IsCurrentOriginSTA(&cc), "IsCurrentOriginSTA returned TRUE\n");
475 ok(cc.unused == v, "cc.unused = %p\n", cc.unused);
477 #ifdef _WIN64
478 SET_EXPECT(function_do_call);
479 SET_EXPECT(function_do_clean);
480 p__ContextCallback__CallInContext(&cc, function, FALSE);
481 CHECK_CALLED(function_do_call);
482 CHECK_CALLED(function_do_clean);
484 SET_EXPECT(function_do_call);
485 SET_EXPECT(function_do_clean);
486 p__ContextCallback__CallInContext(&cc, function, TRUE);
487 CHECK_CALLED(function_do_call);
488 CHECK_CALLED(function_do_clean);
490 SET_EXPECT(function_do_call);
491 SET_EXPECT(function_do_clean);
492 p__ContextCallback__CallInContext(&cc, function2, FALSE);
493 CHECK_CALLED(function_do_call);
494 CHECK_CALLED(function_do_clean);
496 SET_EXPECT(function_do_call);
497 SET_EXPECT(function_do_clean);
498 p__ContextCallback__CallInContext(&cc, function2, TRUE);
499 CHECK_CALLED(function_do_call);
500 CHECK_CALLED(function_do_clean);
501 #endif
504 static void test__TaskEventLogger(void)
506 _TaskEventLogger logger;
507 memset(&logger, 0, sizeof(logger));
509 call_func1(p__TaskEventLogger__LogCancelTask, &logger);
510 ok(!logger.task, "logger.task = %p\n", logger.task);
511 ok(!logger.scheduled, "logger.scheduled = %x\n", logger.scheduled);
512 ok(!logger.started, "logger.started = %x\n", logger.started);
514 call_func2(p__TaskEventLogger__LogScheduleTask, &logger, FALSE);
515 ok(!logger.task, "logger.task = %p\n", logger.task);
516 ok(!logger.scheduled, "logger.scheduled = %x\n", logger.scheduled);
517 ok(!logger.started, "logger.started = %x\n", logger.started);
519 call_func1(p__TaskEventLogger__LogTaskCompleted, &logger);
520 ok(!logger.task, "logger.task = %p\n", logger.task);
521 ok(!logger.scheduled, "logger.scheduled = %x\n", logger.scheduled);
522 ok(!logger.started, "logger.started = %x\n", logger.started);
524 call_func1(p__TaskEventLogger__LogTaskExecutionCompleted, &logger);
525 ok(!logger.task, "logger.task = %p\n", logger.task);
526 ok(!logger.scheduled, "logger.scheduled = %x\n", logger.scheduled);
527 ok(!logger.started, "logger.started = %x\n", logger.started);
529 call_func1(p__TaskEventLogger__LogWorkItemCompleted, &logger);
530 ok(!logger.task, "logger.task = %p\n", logger.task);
531 ok(!logger.scheduled, "logger.scheduled = %x\n", logger.scheduled);
532 ok(!logger.started, "logger.started = %x\n", logger.started);
534 call_func1(p__TaskEventLogger__LogWorkItemStarted, &logger);
535 ok(!logger.task, "logger.task = %p\n", logger.task);
536 ok(!logger.scheduled, "logger.scheduled = %x\n", logger.scheduled);
537 ok(!logger.started, "logger.started = %x\n", logger.started);
539 logger.task = (void*)0xdeadbeef;
540 logger.scheduled = TRUE;
541 logger.started = TRUE;
543 call_func1(p__TaskEventLogger__LogCancelTask, &logger);
544 ok(logger.task == (void*)0xdeadbeef, "logger.task = %p\n", logger.task);
545 ok(logger.scheduled, "logger.scheduled = FALSE\n");
546 ok(logger.started, "logger.started = FALSE\n");
548 call_func2(p__TaskEventLogger__LogScheduleTask, &logger, FALSE);
549 ok(logger.task == (void*)0xdeadbeef, "logger.task = %p\n", logger.task);
550 ok(logger.scheduled, "logger.scheduled = FALSE\n");
551 ok(logger.started, "logger.started = FALSE\n");
553 call_func1(p__TaskEventLogger__LogTaskCompleted, &logger);
554 ok(logger.task == (void*)0xdeadbeef, "logger.task = %p\n", logger.task);
555 ok(logger.scheduled, "logger.scheduled = FALSE\n");
556 ok(logger.started, "logger.started = FALSE\n");
558 call_func1(p__TaskEventLogger__LogTaskExecutionCompleted, &logger);
559 ok(logger.task == (void*)0xdeadbeef, "logger.task = %p\n", logger.task);
560 ok(logger.scheduled, "logger.scheduled = FALSE\n");
561 ok(logger.started, "logger.started = FALSE\n");
563 call_func1(p__TaskEventLogger__LogWorkItemCompleted, &logger);
564 ok(logger.task == (void*)0xdeadbeef, "logger.task = %p\n", logger.task);
565 ok(logger.scheduled, "logger.scheduled = FALSE\n");
566 ok(logger.started, "logger.started = FALSE\n");
568 call_func1(p__TaskEventLogger__LogWorkItemStarted, &logger);
569 ok(logger.task == (void*)0xdeadbeef, "logger.task = %p\n", logger.task);
570 ok(logger.scheduled, "logger.scheduled = FALSE\n");
571 ok(logger.started, "logger.started = FALSE\n");
574 static void __cdecl chore_callback(void *arg)
576 HANDLE event = arg;
577 SetEvent(event);
580 static void test_chore(void)
582 HANDLE event = CreateEventW(NULL, FALSE, FALSE, NULL);
583 _Threadpool_chore chore, old_chore;
584 DWORD wait;
585 int ret;
587 memset(&chore, 0, sizeof(chore));
588 ret = p__Schedule_chore(&chore);
589 ok(!ret, "_Schedule_chore returned %d\n", ret);
590 ok(chore.work != NULL, "chore.work == NULL\n");
591 ok(!chore.callback, "chore.callback != NULL\n");
592 p__Release_chore(&chore);
594 chore.work = NULL;
595 chore.callback = chore_callback;
596 chore.arg = event;
597 ret = p__Schedule_chore(&chore);
598 ok(!ret, "_Schedule_chore returned %d\n", ret);
599 ok(chore.work != NULL, "chore.work == NULL\n");
600 ok(chore.callback == chore_callback, "chore.callback = %p, expected %p\n", chore.callback, chore_callback);
601 ok(chore.arg == event, "chore.arg = %p, expected %p\n", chore.arg, event);
602 wait = WaitForSingleObject(event, 500);
603 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", wait);
605 if(!GetProcAddress(GetModuleHandleA("kernel32"), "CreateThreadpoolWork"))
607 win_skip("_Reschedule_chore not supported\n");
608 p__Release_chore(&chore);
609 CloseHandle(event);
610 return;
613 old_chore = chore;
614 ret = p__Schedule_chore(&chore);
615 ok(!ret, "_Schedule_chore returned %d\n", ret);
616 ok(old_chore.work != chore.work, "new threadpool work was not created\n");
617 p__Release_chore(&old_chore);
618 wait = WaitForSingleObject(event, 500);
619 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", wait);
621 ret = p__Reschedule_chore(&chore);
622 ok(!ret, "_Reschedule_chore returned %d\n", ret);
623 wait = WaitForSingleObject(event, 500);
624 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", wait);
626 p__Release_chore(&chore);
627 ok(!chore.work, "chore.work != NULL\n");
628 ok(chore.callback == chore_callback, "chore.callback = %p, expected %p\n", chore.callback, chore_callback);
629 ok(chore.arg == event, "chore.arg = %p, expected %p\n", chore.arg, event);
630 p__Release_chore(&chore);
632 CloseHandle(event);
635 static void test_to_byte(void)
637 static const WCHAR *tests[] = {L"TEST", L"\x9580\x9581\x9582\x9583"};
639 char dst[MAX_PATH + 4] = "ABC\0XXXXXXX";
640 char compare[MAX_PATH + 4] = "ABC\0XXXXXXX";
641 int ret,expected;
642 unsigned int i, j;
643 WCHAR longstr[MAX_PATH + 3];
645 ret = p_To_byte(NULL, NULL);
646 ok(!ret, "Got unexpected result %d\n", ret);
647 ret = p_To_byte(tests[0], NULL);
648 ok(!ret, "Got unexpected result %d\n", ret);
649 ret = p_To_byte(NULL, dst);
650 ok(!ret, "Got unexpected result %d\n", ret);
652 ok(!memcmp(dst, compare, sizeof(compare)), "Destination was modified: %s\n", dst);
654 for (i = 0; i < ARRAY_SIZE(tests); ++i)
656 ret = p_To_byte(tests[i], dst);
657 expected = WideCharToMultiByte(CP_ACP, 0, tests[i], -1, compare, ARRAY_SIZE(compare), NULL, NULL);
658 ok(ret == expected, "Got unexpected result %d, expected %d, test case %u\n", ret, expected, i);
659 ok(!memcmp(dst, compare, sizeof(compare)), "Got unexpected output %s, test case %u\n", dst, i);
662 /* Output length is limited to MAX_PATH.*/
663 for (i = MAX_PATH - 2; i < MAX_PATH + 2; ++i)
665 for (j = 0; j < i; j++)
666 longstr[j] = 'A';
667 longstr[i] = 0;
668 memset(dst, 0xff, sizeof(dst));
669 memset(compare, 0xff, sizeof(compare));
671 ret = p_To_byte(longstr, dst);
672 expected = WideCharToMultiByte(CP_ACP, 0, longstr, -1, compare, MAX_PATH, NULL, NULL);
673 ok(ret == expected, "Got unexpected result %d, expected %d, length %u\n", ret, expected, i);
674 ok(!memcmp(dst, compare, sizeof(compare)), "Got unexpected output %s, length %u\n", dst, i);
678 static void test_to_wide(void)
680 /* öäü߀Ÿ.A.B in cp1252, the two . are an undefined value and delete.
681 * With a different system codepage it will produce different results, so do not hardcode the
682 * expected output but convert it with MultiByteToWideChar. */
683 static const char special_input[] = {0xf6, 0xe4, 0xfc, 0xdf, 0x80, 0x9f, 0x81, 0x41, 0x7f, 0x42, 0};
684 static const char *tests[] = {"Testtest", special_input};
685 WCHAR dst[MAX_PATH + 4] = {'A', 'B', 'C', 0, 'X', 'X', 'X', 'X', 'X', 'X', 'X'};
686 WCHAR compare[MAX_PATH + 4] = {'A', 'B', 'C', 0, 'X', 'X', 'X', 'X', 'X', 'X', 'X'};
687 int ret, expected;
688 unsigned int i;
689 char longstr[MAX_PATH + 3];
691 ret = p_To_wide(NULL, NULL);
692 ok(!ret, "Got unexpected result %d\n", ret);
693 ret = p_To_wide(tests[0], NULL);
694 ok(!ret, "Got unexpected result %d\n", ret);
695 ret = p_To_wide(NULL, dst);
696 ok(!ret, "Got unexpected result %d\n", ret);
697 ok(!memcmp(dst, compare, sizeof(compare)), "Destination was modified: %s\n", wine_dbgstr_w(dst));
699 for (i = 0; i < ARRAY_SIZE(tests); ++i)
701 ret = p_To_wide(tests[i], dst);
702 expected = MultiByteToWideChar(CP_ACP, 0, tests[i], -1, compare, ARRAY_SIZE(compare));
703 ok(ret == expected, "Got unexpected result %d, expected %d, test case %u\n", ret, expected, i);
704 ok(!memcmp(dst, compare, sizeof(compare)), "Got unexpected output %s, test case %u\n",
705 wine_dbgstr_w(dst), i);
708 /* Output length is limited to MAX_PATH.*/
709 for (i = MAX_PATH - 2; i < MAX_PATH + 2; ++i)
711 memset(longstr, 'A', sizeof(longstr));
712 longstr[i] = 0;
713 memset(dst, 0xff, sizeof(dst));
714 memset(compare, 0xff, sizeof(compare));
716 ret = p_To_wide(longstr, dst);
717 expected = MultiByteToWideChar(CP_ACP, 0, longstr, -1, compare, MAX_PATH);
718 ok(ret == expected, "Got unexpected result %d, expected %d, length %u\n", ret, expected, i);
719 ok(!memcmp(dst, compare, sizeof(compare)), "Got unexpected output %s, length %u\n",
720 wine_dbgstr_w(dst), i);
724 static void test_File_size(void)
726 ULONGLONG val;
727 HANDLE file;
728 LARGE_INTEGER file_size;
729 WCHAR temp_path[MAX_PATH], origin_path[MAX_PATH];
730 int r;
732 GetCurrentDirectoryW(MAX_PATH, origin_path);
733 GetTempPathW(MAX_PATH, temp_path);
734 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
736 CreateDirectoryW(L"wine_test_dir", NULL);
738 file = CreateFileW(L"wine_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
739 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
740 file_size.QuadPart = 7;
741 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
742 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
743 CloseHandle(file);
744 val = p_File_size(L"wine_test_dir/f1");
745 ok(val == 7, "file_size is %s\n", wine_dbgstr_longlong(val));
747 file = CreateFileW(L"wine_test_dir/f2", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
748 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
749 CloseHandle(file);
750 val = p_File_size(L"wine_test_dir/f2");
751 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
753 val = p_File_size(L"wine_test_dir");
754 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
756 errno = 0xdeadbeef;
757 val = p_File_size(L"wine_test_dir/ne");
758 ok(val == ~(ULONGLONG)0, "file_size is %s\n", wine_dbgstr_longlong(val));
759 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
761 errno = 0xdeadbeef;
762 val = p_File_size(NULL);
763 ok(val == ~(ULONGLONG)0, "file_size is %s\n", wine_dbgstr_longlong(val));
764 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
766 r = p_Resize(L"wine_test_dir/f1", 1000);
767 ok(!r, "p_Resize returned %d\n", r);
768 val = p_File_size(L"wine_test_dir/f1");
769 ok(val == 1000, "file_size is %s\n", wine_dbgstr_longlong(val));
771 r = p_Resize(L"wine_test_dir/f1", 100);
772 ok(!r, "p_Resize returned %d\n", r);
773 val = p_File_size(L"wine_test_dir/f1");
774 ok(val == 100, "file_size is %s\n", wine_dbgstr_longlong(val));
776 r = p_Resize(L"wine_test_dir/f1", 0);
777 ok(!r, "p_Resize returned %d\n", r);
778 val = p_File_size(L"wine_test_dir/f1");
779 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
781 ok(DeleteFileW(L"wine_test_dir/f1"), "expect wine_test_dir/f1 to exist\n");
783 r = p_Resize(L"wine_test_dir/f1", 0);
784 ok(r == ERROR_FILE_NOT_FOUND, "p_Resize returned %d\n", r);
786 ok(DeleteFileW(L"wine_test_dir/f2"), "expect wine_test_dir/f2 to exist\n");
787 ok(RemoveDirectoryW(L"wine_test_dir"), "expect wine_test_dir to exist\n");
788 ok(SetCurrentDirectoryW(origin_path), "SetCurrentDirectoryW to origin_path failed\n");
791 static void test_Current_get(void)
793 WCHAR temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
794 BOOL ret;
796 GetCurrentDirectoryW(MAX_PATH, origin_path);
797 GetTempPathW(MAX_PATH, temp_path);
799 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
800 ret = p_Current_get(current_path);
801 ok(ret == TRUE, "p_Current_get returned %u\n", ret);
802 wcscat(current_path, L"\\");
803 ok(!wcscmp(temp_path, current_path), "p_Current_get(): expect: %s, got %s\n",
804 wine_dbgstr_w(temp_path), wine_dbgstr_w(current_path));
806 ok(SetCurrentDirectoryW(origin_path), "SetCurrentDirectoryW to origin_path failed\n");
807 ret = p_Current_get(current_path);
808 ok(ret == TRUE, "p_Current_get returned %u\n", ret);
809 ok(!wcscmp(origin_path, current_path), "p_Current_get(): expect: %s, got %s\n",
810 wine_dbgstr_w(origin_path), wine_dbgstr_w(current_path));
813 static void test_Current_set(void)
815 WCHAR temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
816 MSVCP_bool ret;
818 GetTempPathW(MAX_PATH, temp_path);
819 GetCurrentDirectoryW(MAX_PATH, origin_path);
821 ok(p_Current_set(temp_path), "p_Current_set to temp_path failed\n");
822 ret = p_Current_get(current_path);
823 ok(ret == TRUE, "p_Current_get returned %u\n", ret);
824 wcscat(current_path, L"\\");
825 ok(!wcscmp(temp_path, current_path), "p_Current_get(): expect: %s, got %s\n",
826 wine_dbgstr_w(temp_path), wine_dbgstr_w(current_path));
828 ok(p_Current_set(L"./"), "p_Current_set to temp_path failed\n");
829 ret = p_Current_get(current_path);
830 ok(ret == TRUE, "p_Current_get returned %u\n", ret);
831 wcscat(current_path, L"\\");
832 ok(!wcscmp(temp_path, current_path), "p_Current_get(): expect: %s, got %s\n",
833 wine_dbgstr_w(temp_path), wine_dbgstr_w(current_path));
835 errno = 0xdeadbeef;
836 ok(!p_Current_set(L"not_exist_dir"), "p_Current_set to not_exist_dir succeed\n");
837 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
839 errno = 0xdeadbeef;
840 ok(!p_Current_set(L"??invalid_name>>"), "p_Current_set to ??invalid_name>> succeed\n");
841 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
843 ok(p_Current_set(origin_path), "p_Current_set to origin_path failed\n");
844 ret = p_Current_get(current_path);
845 ok(ret == TRUE, "p_Current_get returned %u\n", ret);
846 ok(!wcscmp(origin_path, current_path), "p_Current_get(): expect: %s, got %s\n",
847 wine_dbgstr_w(origin_path), wine_dbgstr_w(current_path));
850 static void test_Stat(void)
852 int i, perms, expected_perms, ret;
853 HANDLE file;
854 DWORD attr;
855 enum file_type val;
856 WCHAR sys_path[MAX_PATH], origin_path[MAX_PATH], temp_path[MAX_PATH];
857 struct {
858 WCHAR const *path;
859 enum file_type ret;
860 int perms;
861 int is_todo;
862 } tests[] = {
863 { NULL, file_not_found, 0xdeadbeef, FALSE },
864 { L"wine_test_dir", directory_file, 0777, FALSE },
865 { L"wine_test_dir/f1", regular_file, 0777, FALSE },
866 { L"wine_test_dir/f2", regular_file, 0555, FALSE },
867 { L"wine_test_dir/ne", file_not_found, 0xdeadbeef, FALSE },
868 { L"wine_test_dir\\??invalid_name>>", file_not_found, 0xdeadbeef, FALSE },
869 { L"wine_test_dir\\f1_link", regular_file, 0777, TRUE },
870 { L"wine_test_dir\\dir_link", directory_file, 0777, TRUE },
873 GetCurrentDirectoryW(MAX_PATH, origin_path);
874 GetTempPathW(MAX_PATH, temp_path);
875 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
877 CreateDirectoryW(L"wine_test_dir", NULL);
879 file = CreateFileW(L"wine_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
880 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
881 ok(CloseHandle(file), "CloseHandle\n");
883 file = CreateFileW(L"wine_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
884 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
885 ok(CloseHandle(file), "CloseHandle\n");
886 SetFileAttributesW(L"wine_test_dir/f2", FILE_ATTRIBUTE_READONLY);
888 SetLastError(0xdeadbeef);
889 ret = pCreateSymbolicLinkW && pCreateSymbolicLinkW(
890 L"wine_test_dir\\f1_link", L"wine_test_dir/f1", 0);
891 if(!ret && (!pCreateSymbolicLinkW || GetLastError()==ERROR_PRIVILEGE_NOT_HELD
892 || GetLastError()==ERROR_INVALID_FUNCTION)) {
893 tests[6].ret = tests[7].ret = file_not_found;
894 tests[6].perms = tests[7].perms = 0xdeadbeef;
895 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
896 }else {
897 ok(ret, "CreateSymbolicLinkW failed\n");
898 ok(pCreateSymbolicLinkW(L"wine_test_dir\\dir_link", L"wine_test_dir", 1),
899 "CreateSymbolicLinkW failed\n");
902 file = CreateNamedPipeW(L"\\\\.\\PiPe\\tests_pipe.c",
903 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
904 NMPWAIT_USE_DEFAULT_WAIT, NULL);
905 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
906 perms = 0xdeadbeef;
907 val = p_Stat(L"\\\\.\\PiPe\\tests_pipe.c", &perms);
908 todo_wine ok(regular_file == val, "_Stat(): expect: regular, got %d\n", val);
909 todo_wine ok(0777 == perms, "_Stat(): perms expect: 0777, got 0%o\n", perms);
910 perms = 0xdeadbeef;
911 val = p_Lstat(L"\\\\.\\PiPe\\tests_pipe.c", &perms);
912 ok(status_unknown == val, "_Lstat(): expect: unknown, got %d\n", val);
913 ok(0xdeadbeef == perms, "_Lstat(): perms expect: 0xdeadbeef, got %x\n", perms);
914 ok(CloseHandle(file), "CloseHandle\n");
915 file = CreateNamedPipeW(L"\\\\.\\PiPe\\tests_pipe.c",
916 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
917 NMPWAIT_USE_DEFAULT_WAIT, NULL);
918 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
919 perms = 0xdeadbeef;
920 val = p_Lstat(L"\\\\.\\PiPe\\tests_pipe.c", &perms);
921 todo_wine ok(regular_file == val, "_Lstat(): expect: regular, got %d\n", val);
922 todo_wine ok(0777 == perms, "_Lstat(): perms expect: 0777, got 0%o\n", perms);
923 ok(CloseHandle(file), "CloseHandle\n");
925 for(i=0; i<ARRAY_SIZE(tests); i++) {
926 perms = 0xdeadbeef;
927 val = p_Stat(tests[i].path, &perms);
928 todo_wine_if(tests[i].is_todo) {
929 ok(tests[i].ret == val, "_Stat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
930 ok(tests[i].perms == perms, "_Stat(): test %d perms expect: 0%o, got 0%o\n",
931 i+1, tests[i].perms, perms);
933 val = p_Stat(tests[i].path, NULL);
934 todo_wine_if(tests[i].is_todo)
935 ok(tests[i].ret == val, "_Stat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
937 /* test _Lstat */
938 perms = 0xdeadbeef;
939 val = p_Lstat(tests[i].path, &perms);
940 todo_wine_if(tests[i].is_todo) {
941 ok(tests[i].ret == val, "_Lstat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
942 ok(tests[i].perms == perms, "_Lstat(): test %d perms expect: 0%o, got 0%o\n",
943 i+1, tests[i].perms, perms);
945 val = p_Lstat(tests[i].path, NULL);
946 todo_wine_if(tests[i].is_todo)
947 ok(tests[i].ret == val, "_Lstat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
950 GetSystemDirectoryW(sys_path, MAX_PATH);
951 attr = GetFileAttributesW(sys_path);
952 expected_perms = (attr & FILE_ATTRIBUTE_READONLY) ? 0555 : 0777;
953 perms = 0xdeadbeef;
954 val = p_Stat(sys_path, &perms);
955 ok(directory_file == val, "_Stat(): expect: regular, got %d\n", val);
956 ok(perms == expected_perms, "_Stat(): perms expect: 0%o, got 0%o\n", expected_perms, perms);
958 if(ret) {
959 todo_wine ok(DeleteFileW(L"wine_test_dir\\f1_link"),
960 "expect wine_test_dir/f1_link to exist\n");
961 todo_wine ok(RemoveDirectoryW(L"wine_test_dir\\dir_link"),
962 "expect wine_test_dir/dir_link to exist\n");
964 ok(DeleteFileW(L"wine_test_dir/f1"), "expect wine_test_dir/f1 to exist\n");
965 SetFileAttributesW(L"wine_test_dir/f2", FILE_ATTRIBUTE_NORMAL);
966 ok(DeleteFileW(L"wine_test_dir/f2"), "expect wine_test_dir/f2 to exist\n");
967 ok(RemoveDirectoryW(L"wine_test_dir"), "expect wine_test_dir to exist\n");
969 ok(SetCurrentDirectoryW(origin_path), "SetCurrentDirectoryW to origin_path failed\n");
972 static void test_dir_operation(void)
974 WCHAR *file_name, first_file_name[MAX_PATH], dest[MAX_PATH], longer_path[MAX_PATH];
975 WCHAR origin_path[MAX_PATH], temp_path[MAX_PATH];
976 HANDLE file, result_handle;
977 enum file_type type;
978 int err, num_of_f1 = 0, num_of_f2 = 0, num_of_sub_dir = 0, num_of_other_files = 0;
980 GetCurrentDirectoryW(MAX_PATH, origin_path);
981 GetTempPathW(MAX_PATH, temp_path);
982 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
984 CreateDirectoryW(L"wine_test_dir", NULL);
985 file = CreateFileW(L"wine_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
986 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
987 CloseHandle(file);
988 file = CreateFileW(L"wine_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
989 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
990 CloseHandle(file);
991 CreateDirectoryW(L"wine_test_dir/sub_dir", NULL);
992 file = CreateFileW(L"wine_test_dir/sub_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
993 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
994 CloseHandle(file);
996 memcpy(longer_path, temp_path, sizeof(longer_path));
997 wcscat(longer_path, L"\\wine_test_dir\\");
998 while(lstrlenW(longer_path) < MAX_PATH-1)
999 wcscat(longer_path, L"s");
1000 memset(first_file_name, 0xff, sizeof(first_file_name));
1001 type = err = 0xdeadbeef;
1002 result_handle = NULL;
1003 result_handle = p_Open_dir(first_file_name, longer_path, &err, &type);
1004 ok(result_handle == NULL, "_Open_dir(): expect NULL, got %p\n", result_handle);
1005 ok(!*first_file_name, "_Open_dir(): expect: 0, got %s\n", wine_dbgstr_w(first_file_name));
1006 ok(err == ERROR_BAD_PATHNAME, "_Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1007 ok((int)type == 0xdeadbeef, "_Open_dir(): expect 0xdeadbeef, got %d\n", type);
1009 memset(first_file_name, 0xff, sizeof(first_file_name));
1010 memset(dest, 0, sizeof(dest));
1011 err = type = 0xdeadbeef;
1012 result_handle = NULL;
1013 result_handle = p_Open_dir(first_file_name, L"wine_test_dir", &err, &type);
1014 ok(result_handle != NULL, "_Open_dir(): expect: not NULL, got %p\n", result_handle);
1015 ok(err == ERROR_SUCCESS, "_Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1016 file_name = first_file_name;
1017 while(*file_name) {
1018 if (!wcscmp(file_name, L"f1")) {
1019 ++num_of_f1;
1020 ok(type == regular_file, "expect regular_file, got %d\n", type);
1021 }else if(!wcscmp(file_name, L"f2")) {
1022 ++num_of_f2;
1023 ok(type == regular_file, "expect regular_file, got %d\n", type);
1024 }else if(!wcscmp(file_name, L"sub_dir")) {
1025 ++num_of_sub_dir;
1026 ok(type == directory_file, "expect directory_file, got %d\n", type);
1027 }else {
1028 ++num_of_other_files;
1030 file_name = p_Read_dir(dest, result_handle, &type);
1032 ok(type == status_unknown, "_Read_dir(): expect: status_unknown, got %d\n", type);
1033 p_Close_dir(result_handle);
1034 ok(result_handle != NULL, "_Open_dir(): expect: not NULL, got %p\n", result_handle);
1035 ok(num_of_f1 == 1, "found f1 %d times\n", num_of_f1);
1036 ok(num_of_f2 == 1, "found f2 %d times\n", num_of_f2);
1037 ok(num_of_sub_dir == 1, "found sub_dir %d times\n", num_of_sub_dir);
1038 ok(num_of_other_files == 0, "found %d other files\n", num_of_other_files);
1040 memset(first_file_name, 0xff, sizeof(first_file_name));
1041 err = type = 0xdeadbeef;
1042 result_handle = file;
1043 result_handle = p_Open_dir(first_file_name, L"not_exist", &err, &type);
1044 ok(result_handle == NULL, "_Open_dir(): expect: NULL, got %p\n", result_handle);
1045 ok(err == ERROR_BAD_PATHNAME, "_Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1046 ok((int)type == 0xdeadbeef, "_Open_dir(): expect: 0xdeadbeef, got %d\n", type);
1047 ok(!*first_file_name, "_Open_dir(): expect: 0, got %s\n", wine_dbgstr_w(first_file_name));
1049 CreateDirectoryW(L"empty_dir", NULL);
1050 memset(first_file_name, 0xff, sizeof(first_file_name));
1051 err = type = 0xdeadbeef;
1052 result_handle = file;
1053 result_handle = p_Open_dir(first_file_name, L"empty_dir", &err, &type);
1054 ok(result_handle == NULL, "_Open_dir(): expect: NULL, got %p\n", result_handle);
1055 ok(err == ERROR_SUCCESS, "_Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1056 ok(type == status_unknown, "_Open_dir(): expect: status_unknown, got %d\n", type);
1057 ok(!*first_file_name, "_Open_dir(): expect: 0, got %s\n", wine_dbgstr_w(first_file_name));
1058 p_Close_dir(result_handle);
1059 ok(result_handle == NULL, "_Open_dir(): expect: NULL, got %p\n", result_handle);
1061 ok(RemoveDirectoryW(L"empty_dir"), "expect empty_dir to exist\n");
1062 ok(DeleteFileW(L"wine_test_dir/sub_dir/f1"), "expect wine_test_dir/sub_dir/sub_f1 to exist\n");
1063 ok(RemoveDirectoryW(L"wine_test_dir/sub_dir"), "expect wine_test_dir/sub_dir to exist\n");
1064 ok(DeleteFileW(L"wine_test_dir/f1"), "expect wine_test_dir/f1 to exist\n");
1065 ok(DeleteFileW(L"wine_test_dir/f2"), "expect wine_test_dir/f2 to exist\n");
1066 ok(RemoveDirectoryW(L"wine_test_dir"), "expect wine_test_dir to exist\n");
1068 ok(SetCurrentDirectoryW(origin_path), "SetCurrentDirectoryW to origin_path failed\n");
1071 static void test_Unlink(void)
1073 WCHAR temp_path[MAX_PATH], current_path[MAX_PATH];
1074 int ret, i;
1075 HANDLE file;
1076 LARGE_INTEGER file_size;
1077 struct {
1078 WCHAR const *path;
1079 int last_error;
1080 MSVCP_bool is_todo;
1081 } tests[] = {
1082 { L"wine_test_dir\\f1_symlink", ERROR_SUCCESS, TRUE },
1083 { L"wine_test_dir\\f1_link", ERROR_SUCCESS, FALSE },
1084 { L"wine_test_dir\\f1", ERROR_SUCCESS, FALSE },
1085 { L"wine_test_dir", ERROR_ACCESS_DENIED, FALSE },
1086 { L"not_exist", ERROR_FILE_NOT_FOUND, FALSE },
1087 { L"not_exist_dir\\not_exist_file", ERROR_PATH_NOT_FOUND, FALSE },
1088 { NULL, ERROR_PATH_NOT_FOUND, FALSE }
1091 GetCurrentDirectoryW(MAX_PATH, current_path);
1092 GetTempPathW(MAX_PATH, temp_path);
1093 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
1095 ret = p_Make_dir(L"wine_test_dir");
1096 ok(ret == 1, "_Make_dir(): expect 1 got %d\n", ret);
1097 file = CreateFileW(L"wine_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1098 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1099 file_size.QuadPart = 7;
1100 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1101 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1102 CloseHandle(file);
1104 ret = p_Symlink(L"wine_test_dir\\f1", L"wine_test_dir\\f1_symlink");
1105 if(ret==ERROR_PRIVILEGE_NOT_HELD || ret==ERROR_INVALID_FUNCTION || ret==ERROR_CALL_NOT_IMPLEMENTED) {
1106 tests[0].last_error = ERROR_FILE_NOT_FOUND;
1107 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1108 }else {
1109 ok(ret == ERROR_SUCCESS, "_Symlink(): expect: ERROR_SUCCESS, got %d\n", ret);
1111 ret = p_Link(L"wine_test_dir\\f1", L"wine_test_dir\\f1_link");
1112 ok(ret == ERROR_SUCCESS, "_Link(): expect: ERROR_SUCCESS, got %d\n", ret);
1114 for(i=0; i<ARRAY_SIZE(tests); i++) {
1115 errno = 0xdeadbeef;
1116 ret = p_Unlink(tests[i].path);
1117 todo_wine_if(tests[i].is_todo)
1118 ok(ret == tests[i].last_error, "_Unlink(): test %d expect: %d, got %d\n",
1119 i+1, tests[i].last_error, ret);
1120 ok(errno == 0xdeadbeef, "_Unlink(): test %d errno expect: 0xdeadbeef, got %d\n", i+1, ret);
1123 ok(!DeleteFileW(L"wine_test_dir\\f1"), "expect wine_test_dir/f1 not to exist\n");
1124 ok(!DeleteFileW(L"wine_test_dir\\f1_link"), "expect wine_test_dir/f1_link not to exist\n");
1125 ok(!DeleteFileW(L"wine_test_dir\\f1_symlink"), "expect wine_test_dir/f1_symlink not to exist\n");
1126 ret = p_Remove_dir(L"wine_test_dir");
1127 ok(ret == 1, "_Remove_dir(): expect 1 got %d\n", ret);
1129 ok(SetCurrentDirectoryW(current_path), "SetCurrentDirectoryW failed\n");
1132 static void test_Temp_get(void)
1134 WCHAR path[MAX_PATH + 1], temp_path[MAX_PATH];
1135 WCHAR *retval;
1136 DWORD len;
1138 GetTempPathW(ARRAY_SIZE(temp_path), temp_path);
1140 /* This crashes on Windows, the input pointer is not validated. */
1141 if (0)
1143 retval = p_Temp_get(NULL);
1144 ok(!retval, "_Temp_get(): Got %p\n", retval);
1147 memset(path, 0xaa, sizeof(path));
1148 retval = p_Temp_get(path);
1149 ok(retval == path, "_Temp_get(): Got %p, expected %p\n", retval, path);
1150 ok(!wcscmp(path, temp_path), "Expected path %s, got %s\n", wine_dbgstr_w(temp_path), wine_dbgstr_w(path));
1151 len = wcslen(path);
1152 todo_wine ok(path[len + 1] == 0xaaaa, "Too many bytes were zeroed - %x\n", path[len + 1]);
1155 static void test_Rename(void)
1157 int ret, i;
1158 HANDLE file, h1, h2;
1159 BY_HANDLE_FILE_INFORMATION info1, info2;
1160 WCHAR temp_path[MAX_PATH], current_path[MAX_PATH];
1161 LARGE_INTEGER file_size;
1162 static const struct {
1163 const WCHAR *old_path;
1164 const WCHAR *new_path;
1165 int val;
1166 } tests[] = {
1167 { L"wine_test_dir\\f1", L"wine_test_dir\\f1_rename", ERROR_SUCCESS },
1168 { L"wine_test_dir\\f1", NULL, ERROR_FILE_NOT_FOUND },
1169 { L"wine_test_dir\\f1", L"wine_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND },
1170 { NULL, L"wine_test_dir\\f1_rename2", ERROR_PATH_NOT_FOUND },
1171 { L"wine_test_dir\\f1_rename", L"wine_test_dir\\??invalid>", ERROR_INVALID_NAME },
1172 { L"wine_test_dir\\not_exist2", L"wine_test_dir\\not_exist2", ERROR_FILE_NOT_FOUND },
1173 { L"wine_test_dir\\not_exist2", L"wine_test_dir\\??invalid>", ERROR_FILE_NOT_FOUND }
1176 GetCurrentDirectoryW(MAX_PATH, current_path);
1177 GetTempPathW(MAX_PATH, temp_path);
1178 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
1179 ret = p_Make_dir(L"wine_test_dir");
1181 ok(ret == 1, "_Make_dir(): expect 1 got %d\n", ret);
1182 file = CreateFileW(L"wine_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1183 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1184 CloseHandle(file);
1186 ret = p_Rename(L"wine_test_dir\\f1", L"wine_test_dir\\f1");
1187 ok(ERROR_SUCCESS == ret, "_Rename(): expect: ERROR_SUCCESS, got %d\n", ret);
1188 for(i=0; i<ARRAY_SIZE(tests); i++) {
1189 errno = 0xdeadbeef;
1190 if(tests[i].val == ERROR_SUCCESS) {
1191 h1 = CreateFileW(tests[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1192 NULL, OPEN_EXISTING, 0, 0);
1193 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1194 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1195 CloseHandle(h1);
1197 SetLastError(0xdeadbeef);
1198 ret = p_Rename(tests[i].old_path, tests[i].new_path);
1199 ok(ret == tests[i].val, "_Rename(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1200 ok(errno == 0xdeadbeef, "_Rename(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1201 if(ret == ERROR_SUCCESS) {
1202 h2 = CreateFileW(tests[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1203 NULL, OPEN_EXISTING, 0, 0);
1204 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1205 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1206 CloseHandle(h2);
1207 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1208 && info1.nFileIndexLow == info2.nFileIndexLow,
1209 "_Rename(): test %d expect two files equivalent\n", i+1);
1213 file = CreateFileW(L"wine_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1214 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1215 file_size.QuadPart = 7;
1216 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1217 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1218 CloseHandle(file);
1219 ret = p_Rename(L"wine_test_dir\\f1", L"wine_test_dir\\f1_rename");
1220 ok(ret == ERROR_ALREADY_EXISTS, "_Rename(): expect: ERROR_ALREADY_EXISTS, got %d\n", ret);
1221 ok(p_File_size(L"wine_test_dir\\f1") == 7, "_Rename(): expect: 7, got %s\n",
1222 wine_dbgstr_longlong(p_File_size(L"wine_test_dir\\f1")));
1223 ok(p_File_size(L"wine_test_dir\\f1_rename") == 0, "_Rename(): expect: 0, got %s\n",
1224 wine_dbgstr_longlong(p_File_size(L"wine_test_dir\\f1_rename")));
1226 ok(DeleteFileW(L"wine_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1227 ok(DeleteFileW(L"wine_test_dir\\f1"), "expect f1 to exist\n");
1228 ret = p_Remove_dir(L"wine_test_dir");
1229 ok(ret == 1, "_Remove_dir(): expect %d got %d\n", 1, ret);
1230 ok(SetCurrentDirectoryW(current_path), "SetCurrentDirectoryW failed\n");
1233 static void test_Last_write_time(void)
1235 HANDLE file;
1236 int ret;
1237 FILETIME lwt;
1238 __int64 last_write_time, newtime, margin_of_error = 10 * TICKSPERSEC;
1239 WCHAR temp_path[MAX_PATH], origin_path[MAX_PATH];
1241 GetCurrentDirectoryW(ARRAY_SIZE(origin_path), origin_path);
1242 GetTempPathW(ARRAY_SIZE(temp_path), temp_path);
1243 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
1245 ret = p_Make_dir(L"wine_test_dir");
1246 ok(ret == 1, "_Make_dir() expect 1 got %d\n", ret);
1248 file = CreateFileW(L"wine_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1249 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1250 CloseHandle(file);
1252 last_write_time = p_Last_write_time(L"wine_test_dir\\f1");
1253 newtime = last_write_time + 222222;
1254 p_Set_last_write_time(L"wine_test_dir\\f1", newtime);
1255 ok(last_write_time != p_Last_write_time(L"wine_test_dir\\f1"),
1256 "last_write_time should have changed: %s\n",
1257 wine_dbgstr_longlong(last_write_time));
1259 /* test the formula */
1260 file = CreateFileW(L"wine_test_dir\\f1", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1261 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
1262 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1263 ok(GetFileTime(file, 0, 0, &lwt), "GetFileTime failed\n");
1264 CloseHandle(file);
1265 last_write_time = (((__int64)lwt.dwHighDateTime)<< 32) + lwt.dwLowDateTime;
1266 last_write_time -= TICKS_1601_TO_1970;
1267 ok(newtime-margin_of_error<=last_write_time && last_write_time<=newtime+margin_of_error,
1268 "don't fit the formula, last_write_time is %s expected %s\n",
1269 wine_dbgstr_longlong(newtime), wine_dbgstr_longlong(last_write_time));
1271 newtime = 0;
1272 p_Set_last_write_time(L"wine_test_dir\\f1", newtime);
1273 newtime = p_Last_write_time(L"wine_test_dir\\f1");
1274 file = CreateFileW(L"wine_test_dir\\f1", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1275 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
1276 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1277 ok(GetFileTime(file, 0, 0, &lwt), "GetFileTime failed\n");
1278 CloseHandle(file);
1279 last_write_time = (((__int64)lwt.dwHighDateTime)<< 32) + lwt.dwLowDateTime;
1280 last_write_time -= TICKS_1601_TO_1970;
1281 ok(newtime-margin_of_error<=last_write_time && last_write_time<=newtime+margin_of_error,
1282 "don't fit the formula, last_write_time is %s expected %s\n",
1283 wine_dbgstr_longlong(newtime), wine_dbgstr_longlong(last_write_time));
1285 newtime = 123456789;
1286 p_Set_last_write_time(L"wine_test_dir\\f1", newtime);
1287 newtime = p_Last_write_time(L"wine_test_dir\\f1");
1288 file = CreateFileW(L"wine_test_dir\\f1", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1289 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
1290 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1291 ok(GetFileTime(file, 0, 0, &lwt), "GetFileTime failed\n");
1292 CloseHandle(file);
1293 last_write_time = (((__int64)lwt.dwHighDateTime)<< 32) + lwt.dwLowDateTime;
1294 last_write_time -= TICKS_1601_TO_1970;
1295 ok(newtime-margin_of_error<=last_write_time && last_write_time<=newtime+margin_of_error,
1296 "don't fit the formula, last_write_time is %s expected %s\n",
1297 wine_dbgstr_longlong(newtime), wine_dbgstr_longlong(last_write_time));
1299 errno = 0xdeadbeef;
1300 last_write_time = p_Last_write_time(L"wine_test_dir\\not_exist");
1301 ok(errno == 0xdeadbeef, "_Set_last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1302 ok(last_write_time == -1, "expect -1 got %s\n", wine_dbgstr_longlong(last_write_time));
1303 last_write_time = p_Last_write_time(NULL);
1304 ok(last_write_time == -1, "expect -1 got %s\n", wine_dbgstr_longlong(last_write_time));
1306 errno = 0xdeadbeef;
1307 p_Set_last_write_time(L"wine_test_dir\\not_exist", newtime);
1308 ok(errno == 0xdeadbeef, "_Set_last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1309 p_Set_last_write_time(NULL, newtime);
1310 ok(errno == 0xdeadbeef, "_Set_last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1312 ok(DeleteFileW(L"wine_test_dir\\f1"), "expect wine_test_dir/f1 to exist\n");
1313 ret = p_Remove_dir(L"wine_test_dir");
1314 ok(ret == 1, "p_Remove_dir(): expect 1 got %d\n", ret);
1315 ok(SetCurrentDirectoryW(origin_path), "SetCurrentDirectoryW to origin_path failed\n");
1318 static void test__Winerror_message(void)
1320 char buf[256], buf_fm[256];
1321 ULONG ret, ret_fm;
1323 ret_fm = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1324 NULL, 0, 0, buf_fm, sizeof(buf_fm), NULL);
1326 memset(buf, 'a', sizeof(buf));
1327 ret = p__Winerror_message(0, buf, sizeof(buf));
1328 ok(ret == ret_fm || (ret_fm > 2 && buf_fm[ret_fm - 1] == '\n' &&
1329 buf_fm[ret_fm - 2] == '\r' && ret + 2 == ret_fm),
1330 "ret = %lu, expected %lu\n", ret, ret_fm);
1331 ok(!strncmp(buf, buf_fm, ret), "buf = %s, expected %s\n", buf, buf_fm);
1333 memset(buf, 'a', sizeof(buf));
1334 ret = p__Winerror_message(0, buf, 2);
1335 ok(!ret, "ret = %lu\n", ret);
1336 ok(buf[0] == 'a', "buf = %s\n", buf);
1339 static void test__Winerror_map(void)
1341 static struct {
1342 int winerr, doserr;
1343 BOOL broken;
1344 int broken_doserr;
1345 } tests[] = {
1346 {ERROR_INVALID_FUNCTION, ENOSYS}, {ERROR_FILE_NOT_FOUND, ENOENT},
1347 {ERROR_PATH_NOT_FOUND, ENOENT}, {ERROR_TOO_MANY_OPEN_FILES, EMFILE},
1348 {ERROR_ACCESS_DENIED, EACCES}, {ERROR_INVALID_HANDLE, EINVAL},
1349 {ERROR_NOT_ENOUGH_MEMORY, ENOMEM}, {ERROR_INVALID_ACCESS, EACCES},
1350 {ERROR_OUTOFMEMORY, ENOMEM}, {ERROR_INVALID_DRIVE, ENODEV},
1351 {ERROR_CURRENT_DIRECTORY, EACCES}, {ERROR_NOT_SAME_DEVICE, EXDEV},
1352 {ERROR_WRITE_PROTECT, EACCES}, {ERROR_BAD_UNIT, ENODEV},
1353 {ERROR_NOT_READY, EAGAIN}, {ERROR_SEEK, EIO}, {ERROR_WRITE_FAULT, EIO},
1354 {ERROR_READ_FAULT, EIO}, {ERROR_SHARING_VIOLATION, EACCES},
1355 {ERROR_LOCK_VIOLATION, ENOLCK}, {ERROR_HANDLE_DISK_FULL, ENOSPC},
1356 {ERROR_NOT_SUPPORTED, ENOTSUP, TRUE}, {ERROR_DEV_NOT_EXIST, ENODEV},
1357 {ERROR_FILE_EXISTS, EEXIST}, {ERROR_CANNOT_MAKE, EACCES},
1358 {ERROR_INVALID_PARAMETER, EINVAL, TRUE}, {ERROR_OPEN_FAILED, EIO},
1359 {ERROR_BUFFER_OVERFLOW, ENAMETOOLONG}, {ERROR_DISK_FULL, ENOSPC},
1360 {ERROR_INVALID_NAME, ENOENT, TRUE, EINVAL}, {ERROR_NEGATIVE_SEEK, EINVAL},
1361 {ERROR_BUSY_DRIVE, EBUSY}, {ERROR_DIR_NOT_EMPTY, ENOTEMPTY},
1362 {ERROR_BUSY, EBUSY}, {ERROR_ALREADY_EXISTS, EEXIST},
1363 {ERROR_LOCKED, ENOLCK}, {ERROR_DIRECTORY, EINVAL},
1364 {ERROR_OPERATION_ABORTED, ECANCELED}, {ERROR_NOACCESS, EACCES},
1365 {ERROR_CANTOPEN, EIO}, {ERROR_CANTREAD, EIO}, {ERROR_CANTWRITE, EIO},
1366 {ERROR_RETRY, EAGAIN}, {ERROR_OPEN_FILES, EBUSY},
1367 {ERROR_DEVICE_IN_USE, EBUSY}, {ERROR_REPARSE_TAG_INVALID, EINVAL, TRUE},
1368 {WSAEINTR, EINTR}, {WSAEBADF, EBADF}, {WSAEACCES, EACCES},
1369 {WSAEFAULT, EFAULT}, {WSAEINVAL, EINVAL}, {WSAEMFILE, EMFILE},
1370 {WSAEWOULDBLOCK, EWOULDBLOCK}, {WSAEINPROGRESS, EINPROGRESS},
1371 {WSAEALREADY, EALREADY}, {WSAENOTSOCK, ENOTSOCK},
1372 {WSAEDESTADDRREQ, EDESTADDRREQ}, {WSAEMSGSIZE, EMSGSIZE},
1373 {WSAEPROTOTYPE, EPROTOTYPE}, {WSAENOPROTOOPT, ENOPROTOOPT},
1374 {WSAEPROTONOSUPPORT, EPROTONOSUPPORT}, {WSAEOPNOTSUPP, EOPNOTSUPP},
1375 {WSAEAFNOSUPPORT, EAFNOSUPPORT}, {WSAEADDRINUSE, EADDRINUSE},
1376 {WSAEADDRNOTAVAIL, EADDRNOTAVAIL}, {WSAENETDOWN, ENETDOWN},
1377 {WSAENETUNREACH, ENETUNREACH}, {WSAENETRESET, ENETRESET},
1378 {WSAECONNABORTED, ECONNABORTED}, {WSAECONNRESET, ECONNRESET},
1379 {WSAENOBUFS, ENOBUFS}, {WSAEISCONN, EISCONN}, {WSAENOTCONN, ENOTCONN},
1380 {WSAETIMEDOUT, ETIMEDOUT}, {WSAECONNREFUSED, ECONNREFUSED},
1381 {WSAENAMETOOLONG, ENAMETOOLONG}, {WSAEHOSTUNREACH, EHOSTUNREACH}
1383 int i, ret;
1385 for(i=0; i<ARRAY_SIZE(tests); i++)
1387 ret = p__Winerror_map(tests[i].winerr);
1388 ok(ret == tests[i].doserr || broken(tests[i].broken && ret == tests[i].broken_doserr),
1389 "_Winerror_map(%d) returned %d, expected %d\n",
1390 tests[i].winerr, ret, tests[i].doserr);
1394 static void test__Syserror_map(void)
1396 const char *r1, *r2;
1398 r1 = p__Syserror_map(0);
1399 ok(r1 != NULL, "_Syserror_map(0) returned NULL\n");
1400 r1 = p__Syserror_map(1233);
1401 ok(r1 != NULL, "_Syserror_map(1233) returned NULL\n");
1402 r2 = p__Syserror_map(1234);
1403 ok(r2 != NULL, "_Syserror_map(1234) returned NULL\n");
1404 ok(r1 == r2, "r1 = %p(%s), r2 = %p(%s)\n", r1, r1, r2, r2);
1407 static void test_Equivalent(void)
1409 int val, i;
1410 HANDLE file;
1411 WCHAR temp_path[MAX_PATH], current_path[MAX_PATH];
1412 static const struct {
1413 const WCHAR *path1;
1414 const WCHAR *path2;
1415 int equivalent;
1416 } tests[] = {
1417 { NULL, NULL, -1 },
1418 { NULL, L"wine_test_dir/f1", 0 },
1419 { L"wine_test_dir/f1", NULL, 0 },
1420 { L"wine_test_dir/f1", L"wine_test_dir", 0 },
1421 { L"wine_test_dir", L"wine_test_dir/f1", 0 },
1422 { L"wine_test_dir/./f1", L"wine_test_dir/f2", 0 },
1423 { L"wine_test_dir/f1", L"wine_test_dir/f1", 1 },
1424 { L"not_exists_file", L"wine_test_dir/f1", 0 },
1425 { L"wine_test_dir\\f1", L"wine_test_dir/./f1", 1 },
1426 { L"not_exists_file", L"not_exists_file", -1 },
1427 { L"wine_test_dir/f1", L"not_exists_file", 0 },
1428 { L"wine_test_dir/../wine_test_dir/f1", L"wine_test_dir/f1", 1 }
1431 GetCurrentDirectoryW(MAX_PATH, current_path);
1432 GetTempPathW(MAX_PATH, temp_path);
1433 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
1434 CreateDirectoryW(L"wine_test_dir", NULL);
1436 file = CreateFileW(L"wine_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1437 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1438 CloseHandle(file);
1439 file = CreateFileW(L"wine_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1440 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1441 CloseHandle(file);
1443 for(i=0; i<ARRAY_SIZE(tests); i++) {
1444 errno = 0xdeadbeef;
1445 val = p_Equivalent(tests[i].path1, tests[i].path2);
1446 ok(tests[i].equivalent == val, "_Equivalent(): test %d expect: %d, got %d\n", i+1, tests[i].equivalent, val);
1447 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1450 errno = 0xdeadbeef;
1451 val = p_Equivalent(L"wine_test_dir", L"wine_test_dir");
1452 ok(val == 1 || broken(val == -1), "_Equivalent() returned %d, expected %d\n", val, 1);
1453 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1455 ok(DeleteFileW(L"wine_test_dir/f1"), "expect wine_test_dir/f1 to exist\n");
1456 ok(DeleteFileW(L"wine_test_dir/f2"), "expect wine_test_dir/f2 to exist\n");
1457 ok(p_Remove_dir(L"wine_test_dir"), "expect wine_test_dir to exist\n");
1458 ok(SetCurrentDirectoryW(current_path), "SetCurrentDirectoryW failed\n");
1461 #define NUM_THREADS 10
1462 #define TIMEDELTA 250 /* 250 ms uncertainty allowed */
1463 struct cndmtx
1465 HANDLE initialized;
1466 LONG started;
1467 int thread_no;
1469 _Cnd_t cnd;
1470 _Mtx_t mtx;
1471 BOOL timed_wait;
1474 static int __cdecl cnd_wait_thread(void *arg)
1476 struct cndmtx *cm = arg;
1477 int r;
1479 p__Mtx_lock(cm->mtx);
1481 if(InterlockedIncrement(&cm->started) == cm->thread_no)
1482 SetEvent(cm->initialized);
1484 if(cm->timed_wait) {
1485 xtime xt;
1487 p_xtime_get(&xt, 1);
1488 xt.sec += 2;
1489 r = p__Cnd_timedwait(cm->cnd, cm->mtx, &xt);
1490 ok(!r, "timed wait failed\n");
1491 } else {
1492 r = p__Cnd_wait(cm->cnd, cm->mtx);
1493 ok(!r, "wait failed\n");
1496 p__Mtx_unlock(cm->mtx);
1497 return 0;
1500 static void test_cnd(void)
1502 _Thrd_t threads[NUM_THREADS];
1503 xtime xt, before, after;
1504 struct cndmtx cm;
1505 int r, i, diff;
1506 _Cnd_t cnd;
1507 _Mtx_t mtx;
1509 r = p__Cnd_init(&cnd);
1510 ok(!r, "failed to init cnd\n");
1512 r = p__Mtx_init(&mtx, 0);
1513 ok(!r, "failed to init mtx\n");
1515 p__Cnd_destroy(NULL);
1517 /* test _Cnd_signal/_Cnd_wait */
1518 cm.initialized = CreateEventW(NULL, FALSE, FALSE, NULL);
1519 cm.started = 0;
1520 cm.thread_no = 1;
1521 cm.cnd = cnd;
1522 cm.mtx = mtx;
1523 cm.timed_wait = FALSE;
1524 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
1526 WaitForSingleObject(cm.initialized, INFINITE);
1527 p__Mtx_lock(mtx);
1528 p__Mtx_unlock(mtx);
1530 r = p__Cnd_signal(cm.cnd);
1531 ok(!r, "failed to signal\n");
1532 p__Thrd_join(threads[0], NULL);
1534 /* test _Cnd_timedwait time out */
1535 p__Mtx_lock(mtx);
1536 p_xtime_get(&before, 1);
1537 xt = before;
1538 xt.sec += 1;
1539 /* try to avoid failures on spurious wakeup */
1540 p__Cnd_timedwait(cnd, mtx, &xt);
1541 r = p__Cnd_timedwait(cnd, mtx, &xt);
1542 p_xtime_get(&after, 1);
1543 p__Mtx_unlock(mtx);
1545 diff = p__Xtime_diff_to_millis2(&after, &before);
1546 ok(r == 2, "should have timed out\n");
1547 ok(diff > 1000 - TIMEDELTA, "got %d\n", diff);
1549 /* test _Cnd_timedwait */
1550 cm.started = 0;
1551 cm.timed_wait = TRUE;
1552 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
1554 WaitForSingleObject(cm.initialized, INFINITE);
1555 p__Mtx_lock(mtx);
1556 p__Mtx_unlock(mtx);
1558 r = p__Cnd_signal(cm.cnd);
1559 ok(!r, "failed to signal\n");
1560 p__Thrd_join(threads[0], NULL);
1562 /* test _Cnd_broadcast */
1563 cm.started = 0;
1564 cm.thread_no = NUM_THREADS;
1566 for(i = 0; i < cm.thread_no; i++)
1567 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
1569 WaitForSingleObject(cm.initialized, INFINITE);
1570 p__Mtx_lock(mtx);
1571 p__Mtx_unlock(mtx);
1573 r = p__Cnd_broadcast(cnd);
1574 ok(!r, "failed to broadcast\n");
1575 for(i = 0; i < cm.thread_no; i++)
1576 p__Thrd_join(threads[i], NULL);
1578 p__Cnd_destroy(cnd);
1579 p__Mtx_destroy(mtx);
1580 CloseHandle(cm.initialized);
1583 static void test_Copy_file(void)
1585 WCHAR origin_path[MAX_PATH], temp_path[MAX_PATH];
1586 HANDLE file;
1587 DWORD ret;
1589 GetCurrentDirectoryW(MAX_PATH, origin_path);
1590 GetTempPathW(MAX_PATH, temp_path);
1591 ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
1593 CreateDirectoryW(L"wine_test_dir", NULL);
1595 file = CreateFileW(L"wine_test_dir/f1", 0, 0, NULL, CREATE_NEW, 0, NULL);
1596 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1597 ok(CloseHandle(file), "CloseHandle\n");
1599 file = CreateFileW(L"wine_test_dir/f2", 0, 0, NULL, CREATE_NEW, 0, NULL);
1600 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1601 ok(CloseHandle(file), "CloseHandle\n");
1602 SetFileAttributesW(L"wine_test_dir/f2", FILE_ATTRIBUTE_READONLY);
1604 ok(CreateDirectoryW(L"wine_test_dir/d1", NULL) || GetLastError() == ERROR_ALREADY_EXISTS,
1605 "CreateDirectoryW failed.\n");
1607 SetLastError(0xdeadbeef);
1608 ret = p_Copy_file(L"wine_test_dir/f1", L"wine_test_dir/d1");
1609 ok(ret == ERROR_ACCESS_DENIED, "Got unexpected ret %lu.\n", ret);
1610 ok(GetLastError() == ret, "Got unexpected err %lu.\n", GetLastError());
1612 SetLastError(0xdeadbeef);
1613 ret = p_Copy_file(L"wine_test_dir/f1", L"wine_test_dir/f2");
1614 ok(ret == ERROR_ACCESS_DENIED, "Got unexpected ret %lu.\n", ret);
1615 ok(GetLastError() == ret, "Got unexpected err %lu.\n", GetLastError());
1617 SetLastError(0xdeadbeef);
1618 ret = p_Copy_file(L"wine_test_dir/f1", L"wine_test_dir/f3");
1619 ok(ret == ERROR_SUCCESS, "Got unexpected ret %lu.\n", ret);
1620 ok(GetLastError() == ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* some win8 machines */,
1621 "Got unexpected err %lu.\n", GetLastError());
1623 SetLastError(0xdeadbeef);
1624 ret = p_Copy_file(L"wine_test_dir/f1", L"wine_test_dir/f3");
1625 ok(ret == ERROR_SUCCESS, "Got unexpected ret %lu.\n", ret);
1626 ok(GetLastError() == ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* some win8 machines */,
1627 "Got unexpected err %lu.\n", GetLastError());
1629 SetLastError(0xdeadbeef);
1630 ret = p_Copy_file(L"wine_test_dir/missing", L"wine_test_dir/f3");
1631 ok(ret == ERROR_FILE_NOT_FOUND, "Got unexpected ret %lu.\n", ret);
1632 ok(GetLastError() == ret, "Got unexpected err %lu.\n", GetLastError());
1634 ok(RemoveDirectoryW(L"wine_test_dir/d1"), "expect wine_test_dir to exist\n");
1635 ok(DeleteFileW(L"wine_test_dir/f1"), "expect wine_test_dir/f1 to exist\n");
1636 SetFileAttributesW(L"wine_test_dir/f2", FILE_ATTRIBUTE_NORMAL);
1637 ok(DeleteFileW(L"wine_test_dir/f2"), "expect wine_test_dir/f2 to exist\n");
1638 ok(DeleteFileW(L"wine_test_dir/f3"), "expect wine_test_dir/f3 to exist\n");
1639 ok(RemoveDirectoryW(L"wine_test_dir"), "expect wine_test_dir to exist\n");
1641 ok(SetCurrentDirectoryW(origin_path), "SetCurrentDirectoryW to origin_path failed\n");
1644 static void test__Mtx(void)
1646 _Mtx_t mtx = NULL;
1647 int r;
1649 r = p__Mtx_init(&mtx, 0);
1650 ok(!r, "failed to init mtx\n");
1652 ok(mtx->thread_id == -1, "mtx.thread_id = %lx\n", mtx->thread_id);
1653 ok(mtx->count == 0, "mtx.count = %lx\n", mtx->count);
1654 p__Mtx_lock(mtx);
1655 ok(mtx->thread_id == GetCurrentThreadId(), "mtx.thread_id = %lx\n", mtx->thread_id);
1656 ok(mtx->count == 1, "mtx.count = %lx\n", mtx->count);
1657 p__Mtx_lock(mtx);
1658 ok(mtx->thread_id == GetCurrentThreadId(), "mtx.thread_id = %lx\n", mtx->thread_id);
1659 ok(mtx->count == 1, "mtx.count = %lx\n", mtx->count);
1660 p__Mtx_unlock(mtx);
1661 ok(mtx->thread_id == -1, "mtx.thread_id = %lx\n", mtx->thread_id);
1662 ok(mtx->count == 0, "mtx.count = %lx\n", mtx->count);
1663 p__Mtx_unlock(mtx);
1664 ok(mtx->thread_id == -1, "mtx.thread_id = %lx\n", mtx->thread_id);
1665 ok(mtx->count == -1, "mtx.count = %lx\n", mtx->count);
1666 p__Mtx_unlock(mtx);
1667 ok(mtx->thread_id == -1, "mtx.thread_id = %lx\n", mtx->thread_id);
1668 ok(mtx->count == -2, "mtx.count = %lx\n", mtx->count);
1670 p__Mtx_destroy(mtx);
1673 START_TEST(msvcp140)
1675 if(!init()) return;
1676 test_thrd();
1677 test__Task_impl_base__IsNonBlockingThread();
1678 test_vbtable_size_exports();
1679 test_task_continuation_context();
1680 test__ContextCallback();
1681 test__TaskEventLogger();
1682 test_chore();
1683 test_to_byte();
1684 test_to_wide();
1685 test_File_size();
1686 test_Current_get();
1687 test_Current_set();
1688 test_Stat();
1689 test_dir_operation();
1690 test_Unlink();
1691 test_Temp_get();
1692 test_Rename();
1693 test_Last_write_time();
1694 test__Winerror_message();
1695 test__Winerror_map();
1696 test__Syserror_map();
1697 test_Equivalent();
1698 test_cnd();
1699 test_Copy_file();
1700 test__Mtx();
1701 FreeLibrary(msvcp);