kernel32/tests: Add a couple of tests for write watches.
[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 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <windef.h>
25 #define _WIN32_WINNT 0x500
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         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, test_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         skip("some required slist entrypoints were not found, skipping tests\n");
224         return;
225     }
226
227     memset(&test_header, 0, sizeof(test_header));
228     memset(&slist_header, 0xFF, sizeof(slist_header));
229     pInitializeSListHead(&slist_header);
230     ok(memcmp(&test_header, &slist_header, sizeof(SLIST_HEADER)) == 0,
231         "InitializeSListHead didn't zero-fill list header\n");
232     size = pQueryDepthSList(&slist_header);
233     ok(size == 0, "initially created slist has size %d, expected 0\n", size);
234
235     item1.value = 1;
236     ok(pInterlockedPushEntrySList(&slist_header, &item1.entry) == NULL,
237         "previous entry in empty slist wasn't NULL\n");
238     size = pQueryDepthSList(&slist_header);
239     ok(size == 1, "slist with 1 item has size %d\n", size);
240
241     item2.value = 2;
242     entry = pInterlockedPushEntrySList(&slist_header, &item2.entry);
243     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
244     if (entry != NULL)
245     {
246         pitem = (struct item*) entry;
247         ok(pitem->value == 1, "previous entry in slist wasn't the one added\n");
248     }
249     size = pQueryDepthSList(&slist_header);
250     ok(size == 2, "slist with 2 items has size %d\n", size);
251
252     item3.value = 3;
253     entry = pInterlockedPushEntrySList(&slist_header, &item3.entry);
254     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
255     if (entry != NULL)
256     {
257         pitem = (struct item*) entry;
258         ok(pitem->value == 2, "previous entry in slist wasn't the one added\n");
259     }
260     size = pQueryDepthSList(&slist_header);
261     ok(size == 3, "slist with 3 items has size %d\n", size);
262
263     entry = pInterlockedPopEntrySList(&slist_header);
264     ok(entry != NULL, "entry shouldn't be NULL\n");
265     if (entry != NULL)
266     {
267         pitem = (struct item*) entry;
268         ok(pitem->value == 3, "unexpected entry removed\n");
269     }
270     size = pQueryDepthSList(&slist_header);
271     ok(size == 2, "slist with 2 items has size %d\n", size);
272
273     entry = pInterlockedFlushSList(&slist_header);
274     size = pQueryDepthSList(&slist_header);
275     ok(size == 0, "flushed slist should be empty, size is %d\n", size);
276     if (size == 0)
277     {
278         ok(pInterlockedPopEntrySList(&slist_header) == NULL,
279             "popping empty slist didn't return NULL\n");
280     }
281     ok(((struct item*)entry)->value == 2, "item 2 not in front of list\n");
282     ok(((struct item*)entry->Next)->value == 1, "item 1 not at the back of list\n");
283 }
284
285 static void test_event(void)
286 {
287     HANDLE handle, handle2;
288     SECURITY_ATTRIBUTES sa;
289     SECURITY_DESCRIPTOR sd;
290     ACL acl;
291
292     /* no sd */
293     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
294     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
295     CloseHandle(handle);
296
297     sa.nLength = sizeof(sa);
298     sa.lpSecurityDescriptor = &sd;
299     sa.bInheritHandle = FALSE;
300
301     InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
302
303     /* blank sd */
304     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
305     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
306     CloseHandle(handle);
307
308     /* sd with NULL dacl */
309     SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
310     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
311     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
312     CloseHandle(handle);
313
314     /* sd with empty dacl */
315     InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
316     SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
317     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
318     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
319     CloseHandle(handle);
320
321     /* test case sensitivity */
322
323     SetLastError(0xdeadbeef);
324     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
325     ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
326     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
327
328     SetLastError(0xdeadbeef);
329     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
330     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
331     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
332     CloseHandle( handle2 );
333
334     SetLastError(0xdeadbeef);
335     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
336     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
337     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
338     CloseHandle( handle2 );
339
340     SetLastError(0xdeadbeef);
341     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
342     ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
343     CloseHandle( handle2 );
344
345     SetLastError(0xdeadbeef);
346     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
347     ok( !handle2, "OpenEvent succeeded\n");
348     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
349         GetLastError() == ERROR_INVALID_NAME, /* win9x */
350         "wrong error %u\n", GetLastError());
351
352     CloseHandle( handle );
353 }
354
355 static void test_semaphore(void)
356 {
357     HANDLE handle, handle2;
358
359     /* test case sensitivity */
360
361     SetLastError(0xdeadbeef);
362     handle = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
363     ok(handle != NULL, "CreateSemaphore failed with error %u\n", GetLastError());
364     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
365
366     SetLastError(0xdeadbeef);
367     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
368     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
369     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
370     CloseHandle( handle2 );
371
372     SetLastError(0xdeadbeef);
373     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": TEST SEMAPHORE");
374     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
375     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
376     CloseHandle( handle2 );
377
378     SetLastError(0xdeadbeef);
379     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": Test Semaphore");
380     ok( handle2 != NULL, "OpenSemaphore failed with error %d\n", GetLastError());
381     CloseHandle( handle2 );
382
383     SetLastError(0xdeadbeef);
384     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": TEST SEMAPHORE");
385     ok( !handle2, "OpenSemaphore succeeded\n");
386     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
387         GetLastError() == ERROR_INVALID_NAME, /* win9x */
388         "wrong error %u\n", GetLastError());
389
390     CloseHandle( handle );
391 }
392
393 static void test_waitable_timer(void)
394 {
395     HANDLE handle, handle2;
396
397     if (!pCreateWaitableTimerA || !pOpenWaitableTimerA)
398     {
399         skip("{Create,Open}WaitableTimerA() is not available\n");
400         return;
401     }
402
403     /* test case sensitivity */
404
405     SetLastError(0xdeadbeef);
406     handle = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
407     ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
408     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
409
410     SetLastError(0xdeadbeef);
411     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
412     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
413     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
414     CloseHandle( handle2 );
415
416     SetLastError(0xdeadbeef);
417     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
418     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
419     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
420     CloseHandle( handle2 );
421
422     SetLastError(0xdeadbeef);
423     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
424     ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
425     CloseHandle( handle2 );
426
427     SetLastError(0xdeadbeef);
428     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
429     ok( !handle2, "OpenWaitableTimer succeeded\n");
430     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
431         GetLastError() == ERROR_INVALID_NAME, /* win98 */
432         "wrong error %u\n", GetLastError());
433
434     CloseHandle( handle );
435 }
436
437 static HANDLE sem = 0;
438
439 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
440 {
441     ReleaseSemaphore(sem, 1, NULL);
442 }
443
444 static BOOL (WINAPI *p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
445
446 static void test_iocp_callback(void)
447 {
448     char temp_path[MAX_PATH];
449     char filename[MAX_PATH];
450     DWORD ret;
451     BOOL retb;
452     static const char prefix[] = "pfx";
453     HANDLE hFile;
454     HMODULE hmod = GetModuleHandleA("kernel32.dll");
455     DWORD bytesWritten;
456     const char *buffer = "12345678123456781234567812345678";
457     OVERLAPPED overlapped;
458
459     p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
460     if(!p_BindIoCompletionCallback) {
461         skip("BindIoCompletionCallback not found in this DLL\n");
462         return;
463     }
464
465     sem = CreateSemaphore(NULL, 0, 1, NULL);
466     ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
467
468     ret = GetTempPathA(MAX_PATH, temp_path);
469     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
470     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
471
472     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
473     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
474
475     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
476                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
477     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
478
479     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
480     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
481     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
482
483     ret = CloseHandle(hFile);
484     ok( ret, "CloseHandle: error %d\n", GetLastError());
485     ret = DeleteFileA(filename);
486     ok( ret, "DeleteFileA: error %d\n", GetLastError());
487
488     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
489                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
490     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
491
492     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
493     ok(retb == TRUE, "BindIoCompletionCallback failed\n");
494
495     memset(&overlapped, 0, sizeof(overlapped));
496     retb = WriteFile(hFile, (const void *) buffer, 4, &bytesWritten, &overlapped);
497     ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
498
499     ret = WaitForSingleObject(sem, 5000);
500     ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
501     CloseHandle(sem);
502
503     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
504     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
505     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
506     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
507     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
508     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
509
510     ret = CloseHandle(hFile);
511     ok( ret, "CloseHandle: error %d\n", GetLastError());
512     ret = DeleteFileA(filename);
513     ok( ret, "DeleteFileA: error %d\n", GetLastError());
514
515     /* win2k3 requires the Flags parameter to be zero */
516     SetLastError(0xdeadbeef);
517     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
518                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
519     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
520     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
521     if (!retb)
522         ok(GetLastError() == ERROR_INVALID_PARAMETER,
523            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
524     else
525         ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
526     ret = CloseHandle(hFile);
527     ok( ret, "CloseHandle: error %d\n", GetLastError());
528     ret = DeleteFileA(filename);
529     ok( ret, "DeleteFileA: error %d\n", GetLastError());
530
531     retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
532     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
533     ok(GetLastError() == ERROR_INVALID_HANDLE ||
534        GetLastError() == ERROR_INVALID_PARAMETER, /* vista */
535        "Last error is %d\n", GetLastError());
536 }
537
538 static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut)
539 {
540     int *pn = (int *) p;
541     ok(timedOut, "Timer callbacks should always time out\n");
542     ++*pn;
543 }
544
545 struct timer_queue_data1
546 {
547     int num_calls;
548     int max_calls;
549     HANDLE q, t;
550 };
551
552 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
553 {
554     struct timer_queue_data1 *d = p;
555     ok(timedOut, "Timer callbacks should always time out\n");
556     if (d->t && ++d->num_calls == d->max_calls)
557     {
558         BOOL ret;
559         SetLastError(0xdeadbeef);
560         /* Note, XP SP2 does *not* do any deadlock checking, so passing
561            INVALID_HANDLE_VALUE here will just hang.  */
562         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
563         ok(!ret, "DeleteTimerQueueTimer\n");
564         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
565     }
566 }
567
568 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
569 {
570     struct timer_queue_data1 *d = p;
571     ok(timedOut, "Timer callbacks should always time out\n");
572     if (d->t && ++d->num_calls == d->max_calls)
573     {
574         /* Basically kill the timer since it won't have time to run
575            again.  */
576         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0);
577         ok(ret, "ChangeTimerQueueTimer\n");
578     }
579 }
580
581 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
582 {
583     struct timer_queue_data1 *d = p;
584     ok(timedOut, "Timer callbacks should always time out\n");
585     if (d->t)
586     {
587         /* This tests whether a timer gets flagged for deletion before
588            or after the callback runs.  If we start this timer with a
589            period of zero (run once), then ChangeTimerQueueTimer will
590            fail if the timer is already flagged.  Hence we really run
591            only once.  Otherwise we will run multiple times.  */
592         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50);
593         ok(ret, "ChangeTimerQueueTimer\n");
594         ++d->num_calls;
595     }
596 }
597
598 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
599 {
600     DWORD delay = (DWORD) p;
601     ok(timedOut, "Timer callbacks should always time out\n");
602     if (delay)
603         Sleep(delay);
604 }
605
606 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
607 {
608     struct timer_queue_data1 *d = p;
609     ok(timedOut, "Timer callbacks should always time out\n");
610     /* This tests an original implementation bug where a deleted timer may get
611        to run, but it is tricky to set up.  */
612     if (d->q && d->num_calls++ == 0)
613     {
614         /* First run: delete ourselves, then insert and remove a timer
615            that goes in front of us in the sorted timeout list.  Once
616            removed, we will still timeout at the faster timer's due time,
617            but this should be a no-op if we are bug-free.  There should
618            not be a second run.  We can test the value of num_calls later.  */
619         BOOL ret;
620         HANDLE t;
621
622         /* The delete will pend while we are in this callback.  */
623         SetLastError(0xdeadbeef);
624         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
625         ok(!ret, "DeleteTimerQueueTimer\n");
626         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
627
628         ret = pCreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
629         ok(ret, "CreateTimerQueueTimer\n");
630         ok(t != NULL, "CreateTimerQueueTimer\n");
631
632         ret = pDeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
633         ok(ret, "DeleteTimerQueueTimer\n");
634
635         /* Now we stay alive by hanging around in the callback.  */
636         Sleep(500);
637     }
638 }
639
640 static void test_timer_queue(void)
641 {
642     HANDLE q, t1, t2, t3, t4, t5;
643     int n1, n2, n3, n4, n5;
644     struct timer_queue_data1 d1, d2, d3, d4;
645     HANDLE e, et1, et2;
646     BOOL ret;
647
648     if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer
649         || !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer)
650     {
651         skip("TimerQueue API not present\n");
652         return;
653     }
654
655     /* Test asynchronous deletion of the queue. */
656     q = pCreateTimerQueue();
657     ok(q != NULL, "CreateTimerQueue\n");
658
659     SetLastError(0xdeadbeef);
660     ret = pDeleteTimerQueueEx(q, NULL);
661     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
662        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
663        GetLastError());
664
665     /* Test synchronous deletion of the queue and running timers. */
666     q = pCreateTimerQueue();
667     ok(q != NULL, "CreateTimerQueue\n");
668
669     /* Called once.  */
670     t1 = NULL;
671     n1 = 0;
672     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
673                                  0, 0);
674     ok(ret, "CreateTimerQueueTimer\n");
675     ok(t1 != NULL, "CreateTimerQueueTimer\n");
676
677     /* A slow one.  */
678     t2 = NULL;
679     n2 = 0;
680     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
681                                  100, 0);
682     ok(ret, "CreateTimerQueueTimer\n");
683     ok(t2 != NULL, "CreateTimerQueueTimer\n");
684
685     /* A fast one.  */
686     t3 = NULL;
687     n3 = 0;
688     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
689                                  10, 0);
690     ok(ret, "CreateTimerQueueTimer\n");
691     ok(t3 != NULL, "CreateTimerQueueTimer\n");
692
693     /* Start really late (it won't start).  */
694     t4 = NULL;
695     n4 = 0;
696     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
697                                  10, 0);
698     ok(ret, "CreateTimerQueueTimer\n");
699     ok(t4 != NULL, "CreateTimerQueueTimer\n");
700
701     /* Start soon, but delay so long it won't run again.  */
702     t5 = NULL;
703     n5 = 0;
704     ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
705                                  10000, 0);
706     ok(ret, "CreateTimerQueueTimer\n");
707     ok(t5 != NULL, "CreateTimerQueueTimer\n");
708
709     /* Give them a chance to do some work.  */
710     Sleep(500);
711
712     /* Test deleting a once-only timer.  */
713     ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
714     ok(ret, "DeleteTimerQueueTimer\n");
715
716     /* A periodic timer.  */
717     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
718     ok(ret, "DeleteTimerQueueTimer\n");
719
720     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
721     ok(ret, "DeleteTimerQueueEx\n");
722     ok(n1 == 1, "Timer callback 1\n");
723     ok(n2 < n3, "Timer callback 2 should be much slower than 3\n");
724     ok(n4 == 0, "Timer callback 4\n");
725     ok(n5 == 1, "Timer callback 5\n");
726
727     /* Test synchronous deletion of the timer/queue with event trigger. */
728     e = CreateEvent(NULL, TRUE, FALSE, NULL);
729     et1 = CreateEvent(NULL, TRUE, FALSE, NULL);
730     et2 = CreateEvent(NULL, TRUE, FALSE, NULL);
731     if (!e || !et1 || !et2)
732     {
733         skip("Failed to create timer queue descruction event\n");
734         return;
735     }
736
737     q = pCreateTimerQueue();
738     ok(q != NULL, "CreateTimerQueue\n");
739
740     /* Run once and finish quickly (should be done when we delete it).  */
741     t1 = NULL;
742     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
743     ok(ret, "CreateTimerQueueTimer\n");
744     ok(t1 != NULL, "CreateTimerQueueTimer\n");
745
746     /* Run once and finish slowly (shouldn't be done when we delete it).  */
747     t2 = NULL;
748     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
749                                  0, 0);
750     ok(ret, "CreateTimerQueueTimer\n");
751     ok(t2 != NULL, "CreateTimerQueueTimer\n");
752
753     /* Run once and finish quickly (should be done when we delete it).  */
754     t3 = NULL;
755     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
756     ok(ret, "CreateTimerQueueTimer\n");
757     ok(t3 != NULL, "CreateTimerQueueTimer\n");
758
759     /* Run once and finish slowly (shouldn't be done when we delete it).  */
760     t4 = NULL;
761     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
762                                  0, 0);
763     ok(ret, "CreateTimerQueueTimer\n");
764     ok(t4 != NULL, "CreateTimerQueueTimer\n");
765
766     /* Give them a chance to start.  */
767     Sleep(400);
768
769     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
770        even if the timer is finished.  */
771     SetLastError(0xdeadbeef);
772     ret = pDeleteTimerQueueTimer(q, t1, NULL);
773     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
774        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
775        GetLastError());
776
777     SetLastError(0xdeadbeef);
778     ret = pDeleteTimerQueueTimer(q, t2, NULL);
779     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
780     ok(GetLastError() == ERROR_IO_PENDING,
781        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
782        GetLastError());
783
784     SetLastError(0xdeadbeef);
785     ret = pDeleteTimerQueueTimer(q, t3, et1);
786     ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
787     ok(GetLastError() == 0xdeadbeef,
788        "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
789        GetLastError());
790     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
791        "Timer destruction event not triggered\n");
792
793     SetLastError(0xdeadbeef);
794     ret = pDeleteTimerQueueTimer(q, t4, et2);
795     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
796     ok(GetLastError() == ERROR_IO_PENDING,
797        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
798        GetLastError());
799     ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
800        "Timer destruction event not triggered\n");
801
802     SetLastError(0xdeadbeef);
803     ret = pDeleteTimerQueueEx(q, e);
804     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
805        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
806        GetLastError());
807     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
808        "Queue destruction event not triggered\n");
809     CloseHandle(e);
810
811     /* Test deleting/changing a timer in execution.  */
812     q = pCreateTimerQueue();
813     ok(q != NULL, "CreateTimerQueue\n");
814
815     /* Test changing a once-only timer before it fires (this is allowed,
816        whereas after it fires you cannot).  */
817     n1 = 0;
818     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
819                                  0, 0);
820     ok(ret, "CreateTimerQueueTimer\n");
821     ok(t1 != NULL, "CreateTimerQueueTimer\n");
822     ret = pChangeTimerQueueTimer(q, t1, 0, 0);
823     ok(ret, "ChangeTimerQueueTimer\n");
824
825     d2.t = t2 = NULL;
826     d2.num_calls = 0;
827     d2.max_calls = 3;
828     d2.q = q;
829     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
830                                  10, 0);
831     d2.t = t2;
832     ok(ret, "CreateTimerQueueTimer\n");
833     ok(t2 != NULL, "CreateTimerQueueTimer\n");
834
835     d3.t = t3 = NULL;
836     d3.num_calls = 0;
837     d3.max_calls = 4;
838     d3.q = q;
839     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
840                                  10, 0);
841     d3.t = t3;
842     ok(ret, "CreateTimerQueueTimer\n");
843     ok(t3 != NULL, "CreateTimerQueueTimer\n");
844
845     d4.t = t4 = NULL;
846     d4.num_calls = 0;
847     d4.q = q;
848     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
849                                  0, 0);
850     d4.t = t4;
851     ok(ret, "CreateTimerQueueTimer\n");
852     ok(t4 != NULL, "CreateTimerQueueTimer\n");
853
854     Sleep(500);
855
856     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
857     ok(ret, "DeleteTimerQueueEx\n");
858     ok(n1 == 1, "ChangeTimerQueueTimer\n");
859     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
860     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
861     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
862
863     /* Test an obscure bug that was in the original implementation.  */
864     q = pCreateTimerQueue();
865     ok(q != NULL, "CreateTimerQueue\n");
866
867     /* All the work is done in the callback.  */
868     d1.t = t1 = NULL;
869     d1.num_calls = 0;
870     d1.q = q;
871     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
872                                  100, WT_EXECUTELONGFUNCTION);
873     d1.t = t1;
874     ok(ret, "CreateTimerQueueTimer\n");
875     ok(t1 != NULL, "CreateTimerQueueTimer\n");
876
877     Sleep(750);
878
879     SetLastError(0xdeadbeef);
880     ret = pDeleteTimerQueueEx(q, NULL);
881     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
882        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
883        GetLastError());
884     ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
885
886     /* Test functions on the default timer queue.  */
887     t1 = NULL;
888     n1 = 0;
889     ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
890                                  1000, 0);
891     ok(ret, "CreateTimerQueueTimer, default queue\n");
892     ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
893
894     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
895     ok(ret, "ChangeTimerQueueTimer, default queue\n");
896
897     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
898     ok(ret, "DeleteTimerQueueTimer, default queue\n");
899
900     /* Try mixing default and non-default queues.  Apparently this works.  */
901     q = pCreateTimerQueue();
902     ok(q != NULL, "CreateTimerQueue\n");
903
904     t1 = NULL;
905     n1 = 0;
906     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000,
907                                  1000, 0);
908     ok(ret, "CreateTimerQueueTimer\n");
909     ok(t1 != NULL, "CreateTimerQueueTimer\n");
910
911     t2 = NULL;
912     n2 = 0;
913     ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000,
914                                  1000, 0);
915     ok(ret, "CreateTimerQueueTimer\n");
916     ok(t2 != NULL, "CreateTimerQueueTimer\n");
917
918     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
919     ok(ret, "ChangeTimerQueueTimer\n");
920
921     ret = pChangeTimerQueueTimer(q, t2, 2000, 2000);
922     ok(ret, "ChangeTimerQueueTimer\n");
923
924     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
925     ok(ret, "DeleteTimerQueueTimer\n");
926
927     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
928     ok(ret, "DeleteTimerQueueTimer\n");
929
930     /* Try to delete the default queue?  In any case: not allowed.  */
931     SetLastError(0xdeadbeef);
932     ret = pDeleteTimerQueueEx(NULL, NULL);
933     ok(!ret, "DeleteTimerQueueEx call was expected to fail\n");
934     ok(GetLastError() == ERROR_INVALID_HANDLE,
935        "DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n",
936        GetLastError());
937
938     SetLastError(0xdeadbeef);
939     ret = pDeleteTimerQueueEx(q, NULL);
940     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
941        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
942        GetLastError());
943 }
944
945 START_TEST(sync)
946 {
947     HMODULE hdll = GetModuleHandle("kernel32");
948     pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
949     pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
950     pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
951     pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
952     pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
953     pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
954     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
955
956     test_signalandwait();
957     test_mutex();
958     test_slist();
959     test_event();
960     test_semaphore();
961     test_waitable_timer();
962     test_iocp_callback();
963     test_timer_queue();
964 }