server: Connect named pipe synchronously when overlapped param is NULL.
[wine] / dlls / kernel32 / tests / sync.c
1 /*
2  * Synchronization tests
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_WINNT 0x500
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <windef.h>
26 #include <winbase.h>
27
28 #include "wine/test.h"
29
30 static BOOL   (WINAPI *pChangeTimerQueueTimer)(HANDLE, HANDLE, ULONG, ULONG);
31 static HANDLE (WINAPI *pCreateTimerQueue)(void);
32 static BOOL   (WINAPI *pCreateTimerQueueTimer)(PHANDLE, HANDLE, WAITORTIMERCALLBACK,
33                                                PVOID, DWORD, DWORD, ULONG);
34 static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*,BOOL,LPCSTR);
35 static BOOL   (WINAPI *pDeleteTimerQueueEx)(HANDLE, HANDLE);
36 static BOOL   (WINAPI *pDeleteTimerQueueTimer)(HANDLE, HANDLE, HANDLE);
37 static HANDLE (WINAPI *pOpenWaitableTimerA)(DWORD,BOOL,LPCSTR);
38
39 static void test_signalandwait(void)
40 {
41     DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL);
42     HMODULE kernel32;
43     DWORD r;
44     int i;
45     HANDLE event[2], maxevents[MAXIMUM_WAIT_OBJECTS], semaphore[2], file;
46
47     kernel32 = GetModuleHandle("kernel32");
48     pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait");
49
50     if (!pSignalObjectAndWait)
51         return;
52
53     /* invalid parameters */
54     r = pSignalObjectAndWait(NULL, NULL, 0, 0);
55     if (r == ERROR_INVALID_FUNCTION)
56     {
57         win_skip("SignalObjectAndWait is not implemented\n");
58         return; /* Win98/ME */
59     }
60     ok( r == WAIT_FAILED, "should fail\n");
61
62     event[0] = CreateEvent(NULL, 0, 0, NULL);
63     event[1] = CreateEvent(NULL, 1, 1, NULL);
64
65     ok( event[0] && event[1], "failed to create event flags\n");
66
67     r = pSignalObjectAndWait(event[0], NULL, 0, FALSE);
68     ok( r == WAIT_FAILED, "should fail\n");
69
70     r = pSignalObjectAndWait(NULL, event[0], 0, FALSE);
71     ok( r == WAIT_FAILED, "should fail\n");
72
73
74     /* valid parameters */
75     r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
76     ok( r == WAIT_OBJECT_0, "should succeed\n");
77
78     /* event[0] is now signalled */
79     r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
80     ok( r == WAIT_OBJECT_0, "should succeed\n");
81
82     /* event[0] is not signalled */
83     r = WaitForSingleObject(event[0], 0);
84     ok( r == WAIT_TIMEOUT, "event was signalled\n");
85
86     r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
87     ok( r == WAIT_OBJECT_0, "should succeed\n");
88
89     /* clear event[1] and check for a timeout */
90     ok(ResetEvent(event[1]), "failed to clear event[1]\n");
91     r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
92     ok( r == WAIT_TIMEOUT, "should timeout\n");
93
94     CloseHandle(event[0]);
95     CloseHandle(event[1]);
96
97     /* create the maximum number of events and make sure 
98      * we can wait on that many */
99     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
100     {
101         maxevents[i] = CreateEvent(NULL, 1, 1, NULL);
102         ok( maxevents[i] != 0, "should create enough events\n");
103     }
104     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, 0, 0);
105     ok( r != WAIT_FAILED && r != WAIT_TIMEOUT, "should succeed\n");
106
107     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
108         if (maxevents[i]) CloseHandle(maxevents[i]);
109
110     /* semaphores */
111     semaphore[0] = CreateSemaphore( NULL, 0, 1, NULL );
112     semaphore[1] = CreateSemaphore( NULL, 1, 1, NULL );
113     ok( semaphore[0] && semaphore[1], "failed to create semaphore\n");
114
115     r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
116     ok( r == WAIT_OBJECT_0, "should succeed\n");
117
118     r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
119     ok( r == WAIT_FAILED, "should fail\n");
120
121     r = ReleaseSemaphore(semaphore[0],1,NULL);
122     ok( r == FALSE, "should fail\n");
123
124     r = ReleaseSemaphore(semaphore[1],1,NULL);
125     ok( r == TRUE, "should succeed\n");
126
127     CloseHandle(semaphore[0]);
128     CloseHandle(semaphore[1]);
129
130     /* try a registry key */
131     file = CreateFile("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 
132         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
133     r = pSignalObjectAndWait(file, file, 0, FALSE);
134     ok( r == WAIT_FAILED, "should fail\n");
135     ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n");
136     CloseHandle(file);
137 }
138
139 static void test_mutex(void)
140 {
141     DWORD wait_ret;
142     BOOL ret;
143     HANDLE hCreated;
144     HANDLE hOpened;
145
146     hCreated = CreateMutex(NULL, FALSE, "WineTestMutex");
147     ok(hCreated != NULL, "CreateMutex failed with error %d\n", GetLastError());
148     wait_ret = WaitForSingleObject(hCreated, INFINITE);
149     ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error 0x%08x\n", wait_ret);
150
151     /* yes, opening with just READ_CONTROL access allows us to successfully
152      * call ReleaseMutex */
153     hOpened = OpenMutex(READ_CONTROL, FALSE, "WineTestMutex");
154     ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
155     ret = ReleaseMutex(hOpened);
156     todo_wine ok(ret, "ReleaseMutex failed with error %d\n", GetLastError());
157     ret = ReleaseMutex(hCreated);
158     todo_wine ok(!ret && (GetLastError() == ERROR_NOT_OWNER),
159         "ReleaseMutex should have failed with ERROR_NOT_OWNER instead of %d\n", GetLastError());
160
161     /* test case sensitivity */
162
163     SetLastError(0xdeadbeef);
164     hOpened = OpenMutex(READ_CONTROL, FALSE, "WINETESTMUTEX");
165     ok(!hOpened, "OpenMutex succeeded\n");
166     ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
167        GetLastError() == ERROR_INVALID_NAME, /* win9x */
168        "wrong error %u\n", GetLastError());
169
170     SetLastError(0xdeadbeef);
171     hOpened = OpenMutex(READ_CONTROL, FALSE, "winetestmutex");
172     ok(!hOpened, "OpenMutex succeeded\n");
173     ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
174        GetLastError() == ERROR_INVALID_NAME, /* win9x */
175        "wrong error %u\n", GetLastError());
176
177     SetLastError(0xdeadbeef);
178     hOpened = CreateMutex(NULL, FALSE, "WineTestMutex");
179     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
180     ok(GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
181     CloseHandle(hOpened);
182
183     SetLastError(0xdeadbeef);
184     hOpened = CreateMutex(NULL, FALSE, "WINETESTMUTEX");
185     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
186     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
187     CloseHandle(hOpened);
188
189     CloseHandle(hCreated);
190 }
191
192 static void test_slist(void)
193 {
194     struct item
195     {
196         SLIST_ENTRY entry;
197         int value;
198     } item1, item2, item3, *pitem;
199
200     SLIST_HEADER slist_header;
201     PSLIST_ENTRY entry;
202     USHORT size;
203
204     VOID (WINAPI *pInitializeSListHead)(PSLIST_HEADER);
205     USHORT (WINAPI *pQueryDepthSList)(PSLIST_HEADER);
206     PSLIST_ENTRY (WINAPI *pInterlockedFlushSList)(PSLIST_HEADER);
207     PSLIST_ENTRY (WINAPI *pInterlockedPopEntrySList)(PSLIST_HEADER);
208     PSLIST_ENTRY (WINAPI *pInterlockedPushEntrySList)(PSLIST_HEADER,PSLIST_ENTRY);
209     HMODULE kernel32;
210
211     kernel32 = GetModuleHandle("KERNEL32.DLL");
212     pInitializeSListHead = (void*) GetProcAddress(kernel32, "InitializeSListHead");
213     pQueryDepthSList = (void*) GetProcAddress(kernel32, "QueryDepthSList");
214     pInterlockedFlushSList = (void*) GetProcAddress(kernel32, "InterlockedFlushSList");
215     pInterlockedPopEntrySList = (void*) GetProcAddress(kernel32, "InterlockedPopEntrySList");
216     pInterlockedPushEntrySList = (void*) GetProcAddress(kernel32, "InterlockedPushEntrySList");
217     if (pInitializeSListHead == NULL ||
218         pQueryDepthSList == NULL ||
219         pInterlockedFlushSList == NULL ||
220         pInterlockedPopEntrySList == NULL ||
221         pInterlockedPushEntrySList == NULL)
222     {
223         win_skip("some required slist entrypoints were not found, skipping tests\n");
224         return;
225     }
226
227     memset(&slist_header, 0xFF, sizeof(slist_header));
228     pInitializeSListHead(&slist_header);
229     size = pQueryDepthSList(&slist_header);
230     ok(size == 0, "initially created slist has size %d, expected 0\n", size);
231
232     item1.value = 1;
233     ok(pInterlockedPushEntrySList(&slist_header, &item1.entry) == NULL,
234         "previous entry in empty slist wasn't NULL\n");
235     size = pQueryDepthSList(&slist_header);
236     ok(size == 1, "slist with 1 item has size %d\n", size);
237
238     item2.value = 2;
239     entry = pInterlockedPushEntrySList(&slist_header, &item2.entry);
240     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
241     if (entry != NULL)
242     {
243         pitem = (struct item*) entry;
244         ok(pitem->value == 1, "previous entry in slist wasn't the one added\n");
245     }
246     size = pQueryDepthSList(&slist_header);
247     ok(size == 2, "slist with 2 items has size %d\n", size);
248
249     item3.value = 3;
250     entry = pInterlockedPushEntrySList(&slist_header, &item3.entry);
251     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
252     if (entry != NULL)
253     {
254         pitem = (struct item*) entry;
255         ok(pitem->value == 2, "previous entry in slist wasn't the one added\n");
256     }
257     size = pQueryDepthSList(&slist_header);
258     ok(size == 3, "slist with 3 items has size %d\n", size);
259
260     entry = pInterlockedPopEntrySList(&slist_header);
261     ok(entry != NULL, "entry shouldn't be NULL\n");
262     if (entry != NULL)
263     {
264         pitem = (struct item*) entry;
265         ok(pitem->value == 3, "unexpected entry removed\n");
266     }
267     size = pQueryDepthSList(&slist_header);
268     ok(size == 2, "slist with 2 items has size %d\n", size);
269
270     entry = pInterlockedFlushSList(&slist_header);
271     size = pQueryDepthSList(&slist_header);
272     ok(size == 0, "flushed slist should be empty, size is %d\n", size);
273     if (size == 0)
274     {
275         ok(pInterlockedPopEntrySList(&slist_header) == NULL,
276             "popping empty slist didn't return NULL\n");
277     }
278     ok(((struct item*)entry)->value == 2, "item 2 not in front of list\n");
279     ok(((struct item*)entry->Next)->value == 1, "item 1 not at the back of list\n");
280 }
281
282 static void test_event(void)
283 {
284     HANDLE handle, handle2;
285     SECURITY_ATTRIBUTES sa;
286     SECURITY_DESCRIPTOR sd;
287     ACL acl;
288
289     /* no sd */
290     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
291     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
292     CloseHandle(handle);
293
294     sa.nLength = sizeof(sa);
295     sa.lpSecurityDescriptor = &sd;
296     sa.bInheritHandle = FALSE;
297
298     InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
299
300     /* blank sd */
301     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
302     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
303     CloseHandle(handle);
304
305     /* sd with NULL dacl */
306     SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
307     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
308     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
309     CloseHandle(handle);
310
311     /* sd with empty dacl */
312     InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
313     SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
314     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
315     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
316     CloseHandle(handle);
317
318     /* test case sensitivity */
319
320     SetLastError(0xdeadbeef);
321     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
322     ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
323     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
324
325     SetLastError(0xdeadbeef);
326     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
327     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
328     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
329     CloseHandle( handle2 );
330
331     SetLastError(0xdeadbeef);
332     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
333     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
334     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
335     CloseHandle( handle2 );
336
337     SetLastError(0xdeadbeef);
338     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
339     ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
340     CloseHandle( handle2 );
341
342     SetLastError(0xdeadbeef);
343     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
344     ok( !handle2, "OpenEvent succeeded\n");
345     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
346         GetLastError() == ERROR_INVALID_NAME, /* win9x */
347         "wrong error %u\n", GetLastError());
348
349     CloseHandle( handle );
350 }
351
352 static void test_semaphore(void)
353 {
354     HANDLE handle, handle2;
355
356     /* test case sensitivity */
357
358     SetLastError(0xdeadbeef);
359     handle = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
360     ok(handle != NULL, "CreateSemaphore failed with error %u\n", GetLastError());
361     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
362
363     SetLastError(0xdeadbeef);
364     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
365     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
366     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
367     CloseHandle( handle2 );
368
369     SetLastError(0xdeadbeef);
370     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": TEST SEMAPHORE");
371     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
372     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
373     CloseHandle( handle2 );
374
375     SetLastError(0xdeadbeef);
376     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": Test Semaphore");
377     ok( handle2 != NULL, "OpenSemaphore failed with error %d\n", GetLastError());
378     CloseHandle( handle2 );
379
380     SetLastError(0xdeadbeef);
381     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": TEST SEMAPHORE");
382     ok( !handle2, "OpenSemaphore succeeded\n");
383     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
384         GetLastError() == ERROR_INVALID_NAME, /* win9x */
385         "wrong error %u\n", GetLastError());
386
387     CloseHandle( handle );
388 }
389
390 static void test_waitable_timer(void)
391 {
392     HANDLE handle, handle2;
393
394     if (!pCreateWaitableTimerA || !pOpenWaitableTimerA)
395     {
396         win_skip("{Create,Open}WaitableTimerA() is not available\n");
397         return;
398     }
399
400     /* test case sensitivity */
401
402     SetLastError(0xdeadbeef);
403     handle = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
404     ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
405     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
406
407     SetLastError(0xdeadbeef);
408     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
409     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
410     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
411     CloseHandle( handle2 );
412
413     SetLastError(0xdeadbeef);
414     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
415     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
416     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
417     CloseHandle( handle2 );
418
419     SetLastError(0xdeadbeef);
420     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
421     ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
422     CloseHandle( handle2 );
423
424     SetLastError(0xdeadbeef);
425     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
426     ok( !handle2, "OpenWaitableTimer succeeded\n");
427     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
428         GetLastError() == ERROR_INVALID_NAME, /* win98 */
429         "wrong error %u\n", GetLastError());
430
431     CloseHandle( handle );
432 }
433
434 static HANDLE sem = 0;
435
436 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
437 {
438     ReleaseSemaphore(sem, 1, NULL);
439 }
440
441 static BOOL (WINAPI *p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
442
443 static void test_iocp_callback(void)
444 {
445     char temp_path[MAX_PATH];
446     char filename[MAX_PATH];
447     DWORD ret;
448     BOOL retb;
449     static const char prefix[] = "pfx";
450     HANDLE hFile;
451     HMODULE hmod = GetModuleHandleA("kernel32.dll");
452     DWORD bytesWritten;
453     const char *buffer = "12345678123456781234567812345678";
454     OVERLAPPED overlapped;
455
456     p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
457     if(!p_BindIoCompletionCallback) {
458         win_skip("BindIoCompletionCallback not found in this DLL\n");
459         return;
460     }
461
462     sem = CreateSemaphore(NULL, 0, 1, NULL);
463     ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
464
465     ret = GetTempPathA(MAX_PATH, temp_path);
466     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
467     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
468
469     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
470     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
471
472     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
473                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
474     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
475
476     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
477     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
478     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
479
480     ret = CloseHandle(hFile);
481     ok( ret, "CloseHandle: error %d\n", GetLastError());
482     ret = DeleteFileA(filename);
483     ok( ret, "DeleteFileA: error %d\n", GetLastError());
484
485     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
486                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
487     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
488
489     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
490     ok(retb == TRUE, "BindIoCompletionCallback failed\n");
491
492     memset(&overlapped, 0, sizeof(overlapped));
493     retb = WriteFile(hFile, buffer, 4, &bytesWritten, &overlapped);
494     ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
495
496     ret = WaitForSingleObject(sem, 5000);
497     ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
498     CloseHandle(sem);
499
500     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
501     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
502     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
503     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
504     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
505     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
506
507     ret = CloseHandle(hFile);
508     ok( ret, "CloseHandle: error %d\n", GetLastError());
509     ret = DeleteFileA(filename);
510     ok( ret, "DeleteFileA: error %d\n", GetLastError());
511
512     /* win2k3 requires the Flags parameter to be zero */
513     SetLastError(0xdeadbeef);
514     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
515                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
516     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
517     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
518     if (!retb)
519         ok(GetLastError() == ERROR_INVALID_PARAMETER,
520            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
521     else
522         ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
523     ret = CloseHandle(hFile);
524     ok( ret, "CloseHandle: error %d\n", GetLastError());
525     ret = DeleteFileA(filename);
526     ok( ret, "DeleteFileA: error %d\n", GetLastError());
527
528     retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
529     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
530     ok(GetLastError() == ERROR_INVALID_HANDLE ||
531        GetLastError() == ERROR_INVALID_PARAMETER, /* vista */
532        "Last error is %d\n", GetLastError());
533 }
534
535 static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut)
536 {
537     int *pn = p;
538     ok(timedOut, "Timer callbacks should always time out\n");
539     ++*pn;
540 }
541
542 struct timer_queue_data1
543 {
544     int num_calls;
545     int max_calls;
546     HANDLE q, t;
547 };
548
549 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
550 {
551     struct timer_queue_data1 *d = p;
552     ok(timedOut, "Timer callbacks should always time out\n");
553     if (d->t && ++d->num_calls == d->max_calls)
554     {
555         BOOL ret;
556         SetLastError(0xdeadbeef);
557         /* Note, XP SP2 does *not* do any deadlock checking, so passing
558            INVALID_HANDLE_VALUE here will just hang.  */
559         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
560         ok(!ret, "DeleteTimerQueueTimer\n");
561         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
562     }
563 }
564
565 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
566 {
567     struct timer_queue_data1 *d = p;
568     ok(timedOut, "Timer callbacks should always time out\n");
569     if (d->t && ++d->num_calls == d->max_calls)
570     {
571         /* Basically kill the timer since it won't have time to run
572            again.  */
573         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0);
574         ok(ret, "ChangeTimerQueueTimer\n");
575     }
576 }
577
578 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
579 {
580     struct timer_queue_data1 *d = p;
581     ok(timedOut, "Timer callbacks should always time out\n");
582     if (d->t)
583     {
584         /* This tests whether a timer gets flagged for deletion before
585            or after the callback runs.  If we start this timer with a
586            period of zero (run once), then ChangeTimerQueueTimer will
587            fail if the timer is already flagged.  Hence we really run
588            only once.  Otherwise we will run multiple times.  */
589         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50);
590         ok(ret, "ChangeTimerQueueTimer\n");
591         ++d->num_calls;
592     }
593 }
594
595 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
596 {
597     DWORD_PTR delay = (DWORD_PTR) p;
598     ok(timedOut, "Timer callbacks should always time out\n");
599     if (delay)
600         Sleep(delay);
601 }
602
603 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
604 {
605     struct timer_queue_data1 *d = p;
606     ok(timedOut, "Timer callbacks should always time out\n");
607     /* This tests an original implementation bug where a deleted timer may get
608        to run, but it is tricky to set up.  */
609     if (d->q && d->num_calls++ == 0)
610     {
611         /* First run: delete ourselves, then insert and remove a timer
612            that goes in front of us in the sorted timeout list.  Once
613            removed, we will still timeout at the faster timer's due time,
614            but this should be a no-op if we are bug-free.  There should
615            not be a second run.  We can test the value of num_calls later.  */
616         BOOL ret;
617         HANDLE t;
618
619         /* The delete will pend while we are in this callback.  */
620         SetLastError(0xdeadbeef);
621         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
622         ok(!ret, "DeleteTimerQueueTimer\n");
623         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
624
625         ret = pCreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
626         ok(ret, "CreateTimerQueueTimer\n");
627         ok(t != NULL, "CreateTimerQueueTimer\n");
628
629         ret = pDeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
630         ok(ret, "DeleteTimerQueueTimer\n");
631
632         /* Now we stay alive by hanging around in the callback.  */
633         Sleep(500);
634     }
635 }
636
637 static void test_timer_queue(void)
638 {
639     HANDLE q, t1, t2, t3, t4, t5;
640     int n1, n2, n3, n4, n5;
641     struct timer_queue_data1 d1, d2, d3, d4;
642     HANDLE e, et1, et2;
643     BOOL ret;
644
645     if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer
646         || !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer)
647     {
648         win_skip("TimerQueue API not present\n");
649         return;
650     }
651
652     /* Test asynchronous deletion of the queue. */
653     q = pCreateTimerQueue();
654     ok(q != NULL, "CreateTimerQueue\n");
655
656     SetLastError(0xdeadbeef);
657     ret = pDeleteTimerQueueEx(q, NULL);
658     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
659        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
660        GetLastError());
661
662     /* Test synchronous deletion of the queue and running timers. */
663     q = pCreateTimerQueue();
664     ok(q != NULL, "CreateTimerQueue\n");
665
666     /* Called once.  */
667     t1 = NULL;
668     n1 = 0;
669     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
670                                  0, 0);
671     ok(ret, "CreateTimerQueueTimer\n");
672     ok(t1 != NULL, "CreateTimerQueueTimer\n");
673
674     /* A slow one.  */
675     t2 = NULL;
676     n2 = 0;
677     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
678                                  100, 0);
679     ok(ret, "CreateTimerQueueTimer\n");
680     ok(t2 != NULL, "CreateTimerQueueTimer\n");
681
682     /* A fast one.  */
683     t3 = NULL;
684     n3 = 0;
685     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
686                                  10, 0);
687     ok(ret, "CreateTimerQueueTimer\n");
688     ok(t3 != NULL, "CreateTimerQueueTimer\n");
689
690     /* Start really late (it won't start).  */
691     t4 = NULL;
692     n4 = 0;
693     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
694                                  10, 0);
695     ok(ret, "CreateTimerQueueTimer\n");
696     ok(t4 != NULL, "CreateTimerQueueTimer\n");
697
698     /* Start soon, but delay so long it won't run again.  */
699     t5 = NULL;
700     n5 = 0;
701     ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
702                                  10000, 0);
703     ok(ret, "CreateTimerQueueTimer\n");
704     ok(t5 != NULL, "CreateTimerQueueTimer\n");
705
706     /* Give them a chance to do some work.  */
707     Sleep(500);
708
709     /* Test deleting a once-only timer.  */
710     ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
711     ok(ret, "DeleteTimerQueueTimer\n");
712
713     /* A periodic timer.  */
714     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
715     ok(ret, "DeleteTimerQueueTimer\n");
716
717     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
718     ok(ret, "DeleteTimerQueueEx\n");
719     ok(n1 == 1, "Timer callback 1\n");
720     ok(n2 < n3, "Timer callback 2 should be much slower than 3\n");
721     ok(n4 == 0, "Timer callback 4\n");
722     ok(n5 == 1, "Timer callback 5\n");
723
724     /* Test synchronous deletion of the timer/queue with event trigger. */
725     e = CreateEvent(NULL, TRUE, FALSE, NULL);
726     et1 = CreateEvent(NULL, TRUE, FALSE, NULL);
727     et2 = CreateEvent(NULL, TRUE, FALSE, NULL);
728     if (!e || !et1 || !et2)
729     {
730         skip("Failed to create timer queue descruction event\n");
731         return;
732     }
733
734     q = pCreateTimerQueue();
735     ok(q != NULL, "CreateTimerQueue\n");
736
737     /* Run once and finish quickly (should be done when we delete it).  */
738     t1 = NULL;
739     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
740     ok(ret, "CreateTimerQueueTimer\n");
741     ok(t1 != NULL, "CreateTimerQueueTimer\n");
742
743     /* Run once and finish slowly (shouldn't be done when we delete it).  */
744     t2 = NULL;
745     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
746                                  0, 0);
747     ok(ret, "CreateTimerQueueTimer\n");
748     ok(t2 != NULL, "CreateTimerQueueTimer\n");
749
750     /* Run once and finish quickly (should be done when we delete it).  */
751     t3 = NULL;
752     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
753     ok(ret, "CreateTimerQueueTimer\n");
754     ok(t3 != NULL, "CreateTimerQueueTimer\n");
755
756     /* Run once and finish slowly (shouldn't be done when we delete it).  */
757     t4 = NULL;
758     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
759                                  0, 0);
760     ok(ret, "CreateTimerQueueTimer\n");
761     ok(t4 != NULL, "CreateTimerQueueTimer\n");
762
763     /* Give them a chance to start.  */
764     Sleep(400);
765
766     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
767        even if the timer is finished.  */
768     SetLastError(0xdeadbeef);
769     ret = pDeleteTimerQueueTimer(q, t1, NULL);
770     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
771        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
772        GetLastError());
773
774     SetLastError(0xdeadbeef);
775     ret = pDeleteTimerQueueTimer(q, t2, NULL);
776     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
777     ok(GetLastError() == ERROR_IO_PENDING,
778        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
779        GetLastError());
780
781     SetLastError(0xdeadbeef);
782     ret = pDeleteTimerQueueTimer(q, t3, et1);
783     ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
784     ok(GetLastError() == 0xdeadbeef,
785        "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
786        GetLastError());
787     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
788        "Timer destruction event not triggered\n");
789
790     SetLastError(0xdeadbeef);
791     ret = pDeleteTimerQueueTimer(q, t4, et2);
792     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
793     ok(GetLastError() == ERROR_IO_PENDING,
794        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
795        GetLastError());
796     ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
797        "Timer destruction event not triggered\n");
798
799     SetLastError(0xdeadbeef);
800     ret = pDeleteTimerQueueEx(q, e);
801     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
802        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
803        GetLastError());
804     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
805        "Queue destruction event not triggered\n");
806     CloseHandle(e);
807
808     /* Test deleting/changing a timer in execution.  */
809     q = pCreateTimerQueue();
810     ok(q != NULL, "CreateTimerQueue\n");
811
812     /* Test changing a once-only timer before it fires (this is allowed,
813        whereas after it fires you cannot).  */
814     n1 = 0;
815     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
816                                  0, 0);
817     ok(ret, "CreateTimerQueueTimer\n");
818     ok(t1 != NULL, "CreateTimerQueueTimer\n");
819     ret = pChangeTimerQueueTimer(q, t1, 0, 0);
820     ok(ret, "ChangeTimerQueueTimer\n");
821
822     d2.t = t2 = NULL;
823     d2.num_calls = 0;
824     d2.max_calls = 3;
825     d2.q = q;
826     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
827                                  10, 0);
828     d2.t = t2;
829     ok(ret, "CreateTimerQueueTimer\n");
830     ok(t2 != NULL, "CreateTimerQueueTimer\n");
831
832     d3.t = t3 = NULL;
833     d3.num_calls = 0;
834     d3.max_calls = 4;
835     d3.q = q;
836     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
837                                  10, 0);
838     d3.t = t3;
839     ok(ret, "CreateTimerQueueTimer\n");
840     ok(t3 != NULL, "CreateTimerQueueTimer\n");
841
842     d4.t = t4 = NULL;
843     d4.num_calls = 0;
844     d4.q = q;
845     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
846                                  0, 0);
847     d4.t = t4;
848     ok(ret, "CreateTimerQueueTimer\n");
849     ok(t4 != NULL, "CreateTimerQueueTimer\n");
850
851     Sleep(500);
852
853     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
854     ok(ret, "DeleteTimerQueueEx\n");
855     ok(n1 == 1, "ChangeTimerQueueTimer\n");
856     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
857     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
858     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
859
860     /* Test an obscure bug that was in the original implementation.  */
861     q = pCreateTimerQueue();
862     ok(q != NULL, "CreateTimerQueue\n");
863
864     /* All the work is done in the callback.  */
865     d1.t = t1 = NULL;
866     d1.num_calls = 0;
867     d1.q = q;
868     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
869                                  100, WT_EXECUTELONGFUNCTION);
870     d1.t = t1;
871     ok(ret, "CreateTimerQueueTimer\n");
872     ok(t1 != NULL, "CreateTimerQueueTimer\n");
873
874     Sleep(750);
875
876     SetLastError(0xdeadbeef);
877     ret = pDeleteTimerQueueEx(q, NULL);
878     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
879        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
880        GetLastError());
881     ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
882
883     /* Test functions on the default timer queue.  */
884     t1 = NULL;
885     n1 = 0;
886     ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
887                                  1000, 0);
888     ok(ret, "CreateTimerQueueTimer, default queue\n");
889     ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
890
891     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
892     ok(ret, "ChangeTimerQueueTimer, default queue\n");
893
894     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
895     ok(ret, "DeleteTimerQueueTimer, default queue\n");
896
897     /* Try mixing default and non-default queues.  Apparently this works.  */
898     q = pCreateTimerQueue();
899     ok(q != NULL, "CreateTimerQueue\n");
900
901     t1 = NULL;
902     n1 = 0;
903     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000,
904                                  1000, 0);
905     ok(ret, "CreateTimerQueueTimer\n");
906     ok(t1 != NULL, "CreateTimerQueueTimer\n");
907
908     t2 = NULL;
909     n2 = 0;
910     ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000,
911                                  1000, 0);
912     ok(ret, "CreateTimerQueueTimer\n");
913     ok(t2 != NULL, "CreateTimerQueueTimer\n");
914
915     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
916     ok(ret, "ChangeTimerQueueTimer\n");
917
918     ret = pChangeTimerQueueTimer(q, t2, 2000, 2000);
919     ok(ret, "ChangeTimerQueueTimer\n");
920
921     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
922     ok(ret, "DeleteTimerQueueTimer\n");
923
924     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
925     ok(ret, "DeleteTimerQueueTimer\n");
926
927     /* Try to delete the default queue?  In any case: not allowed.  */
928     SetLastError(0xdeadbeef);
929     ret = pDeleteTimerQueueEx(NULL, NULL);
930     ok(!ret, "DeleteTimerQueueEx call was expected to fail\n");
931     ok(GetLastError() == ERROR_INVALID_HANDLE,
932        "DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n",
933        GetLastError());
934
935     SetLastError(0xdeadbeef);
936     ret = pDeleteTimerQueueEx(q, NULL);
937     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
938        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
939        GetLastError());
940 }
941
942 START_TEST(sync)
943 {
944     HMODULE hdll = GetModuleHandle("kernel32");
945     pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
946     pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
947     pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
948     pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
949     pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
950     pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
951     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
952
953     test_signalandwait();
954     test_mutex();
955     test_slist();
956     test_event();
957     test_semaphore();
958     test_waitable_timer();
959     test_iocp_callback();
960     test_timer_queue();
961 }