mshtml: Added IHTMLElement::get_offsetHeight implementation.
[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         trace("SignalObjectAndWait not implemented, skipping tests\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, "wrong error %u\n", GetLastError());
431
432     CloseHandle( handle );
433 }
434
435 static HANDLE sem = 0;
436
437 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
438 {
439     ReleaseSemaphore(sem, 1, NULL);
440 }
441
442 static BOOL (WINAPI *p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
443
444 static void test_iocp_callback(void)
445 {
446     char temp_path[MAX_PATH];
447     char filename[MAX_PATH];
448     DWORD ret;
449     BOOL retb;
450     static const char prefix[] = "pfx";
451     HANDLE hFile;
452     HMODULE hmod = GetModuleHandleA("kernel32.dll");
453     DWORD bytesWritten;
454     const char *buffer = "12345678123456781234567812345678";
455     OVERLAPPED overlapped;
456
457     p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
458     if(!p_BindIoCompletionCallback) {
459         skip("BindIoCompletionCallback not found in this DLL\n");
460         return;
461     }
462
463     sem = CreateSemaphore(NULL, 0, 1, NULL);
464     ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
465
466     ret = GetTempPathA(MAX_PATH, temp_path);
467     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
468     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
469
470     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
471     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
472
473     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
474                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
475     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
476
477     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
478     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
479     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
480
481     ret = CloseHandle(hFile);
482     ok( ret, "CloseHandle: error %d\n", GetLastError());
483     ret = DeleteFileA(filename);
484     ok( ret, "DeleteFileA: error %d\n", GetLastError());
485
486     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
487                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
488     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
489
490     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
491     ok(retb == TRUE, "BindIoCompletionCallback failed\n");
492
493     memset(&overlapped, 0, sizeof(overlapped));
494     retb = WriteFile(hFile, (const void *) buffer, 4, &bytesWritten, &overlapped);
495     ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
496
497     ret = WaitForSingleObject(sem, 5000);
498     ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
499     CloseHandle(sem);
500
501     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
502     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
503     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
504     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
505     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
506     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
507
508     ret = CloseHandle(hFile);
509     ok( ret, "CloseHandle: error %d\n", GetLastError());
510     ret = DeleteFileA(filename);
511     ok( ret, "DeleteFileA: error %d\n", GetLastError());
512
513     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
514                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
515     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
516     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
517     ok(retb == TRUE, "BindIoCompletionCallback failed with a NULL callback(first time set)\n");
518     ret = CloseHandle(hFile);
519     ok( ret, "CloseHandle: error %d\n", GetLastError());
520     ret = DeleteFileA(filename);
521     ok( ret, "DeleteFileA: error %d\n", GetLastError());
522
523     /* win2k3 requires the Flags parameter to be zero */
524     SetLastError(0xdeadbeef);
525     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
526                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
527     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
528     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
529     if (!retb)
530         ok(GetLastError() == ERROR_INVALID_PARAMETER,
531            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
532     else
533         ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
534     ret = CloseHandle(hFile);
535     ok( ret, "CloseHandle: error %d\n", GetLastError());
536     ret = DeleteFileA(filename);
537     ok( ret, "DeleteFileA: error %d\n", GetLastError());
538
539     retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
540     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
541     ok(GetLastError() == ERROR_INVALID_HANDLE, "Last error is %d\n", GetLastError());
542 }
543
544 static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut)
545 {
546     int *pn = (int *) p;
547     ok(timedOut, "Timer callbacks should always time out\n");
548     ++*pn;
549 }
550
551 struct timer_queue_data1
552 {
553     int num_calls;
554     int max_calls;
555     HANDLE q, t;
556 };
557
558 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
559 {
560     struct timer_queue_data1 *d = p;
561     ok(timedOut, "Timer callbacks should always time out\n");
562     if (d->t && ++d->num_calls == d->max_calls)
563     {
564         BOOL ret;
565         SetLastError(0xdeadbeef);
566         /* Note, XP SP2 does *not* do any deadlock checking, so passing
567            INVALID_HANDLE_VALUE here will just hang.  */
568         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
569         ok(!ret, "DeleteTimerQueueTimer\n");
570         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
571     }
572 }
573
574 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
575 {
576     struct timer_queue_data1 *d = p;
577     ok(timedOut, "Timer callbacks should always time out\n");
578     if (d->t && ++d->num_calls == d->max_calls)
579     {
580         /* Basically kill the timer since it won't have time to run
581            again.  */
582         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0);
583         ok(ret, "ChangeTimerQueueTimer\n");
584     }
585 }
586
587 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
588 {
589     struct timer_queue_data1 *d = p;
590     ok(timedOut, "Timer callbacks should always time out\n");
591     if (d->t)
592     {
593         /* This tests whether a timer gets flagged for deletion before
594            or after the callback runs.  If we start this timer with a
595            period of zero (run once), then ChangeTimerQueueTimer will
596            fail if the timer is already flagged.  Hence we really run
597            only once.  Otherwise we will run multiple times.  */
598         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50);
599         ok(ret, "ChangeTimerQueueTimer\n");
600         ++d->num_calls;
601     }
602 }
603
604 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
605 {
606     DWORD delay = (DWORD) p;
607     ok(timedOut, "Timer callbacks should always time out\n");
608     if (delay)
609         Sleep(delay);
610 }
611
612 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
613 {
614     struct timer_queue_data1 *d = p;
615     ok(timedOut, "Timer callbacks should always time out\n");
616     /* This tests an original implementation bug where a deleted timer may get
617        to run, but it is tricky to set up.  */
618     if (d->q && d->num_calls++ == 0)
619     {
620         /* First run: delete ourselves, then insert and remove a timer
621            that goes in front of us in the sorted timeout list.  Once
622            removed, we will still timeout at the faster timer's due time,
623            but this should be a no-op if we are bug-free.  There should
624            not be a second run.  We can test the value of num_calls later.  */
625         BOOL ret;
626         HANDLE t;
627
628         /* The delete will pend while we are in this callback.  */
629         SetLastError(0xdeadbeef);
630         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
631         ok(!ret, "DeleteTimerQueueTimer\n");
632         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
633
634         ret = pCreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
635         ok(ret, "CreateTimerQueueTimer\n");
636         ok(t != NULL, "CreateTimerQueueTimer\n");
637
638         ret = pDeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
639         ok(ret, "DeleteTimerQueueTimer\n");
640
641         /* Now we stay alive by hanging around in the callback.  */
642         Sleep(500);
643     }
644 }
645
646 static void test_timer_queue(void)
647 {
648     HANDLE q, t1, t2, t3, t4, t5;
649     int n1, n2, n3, n4, n5;
650     struct timer_queue_data1 d1, d2, d3, d4;
651     HANDLE e, et1, et2;
652     BOOL ret;
653
654     if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer
655         || !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer)
656     {
657         skip("TimerQueue API not present\n");
658         return;
659     }
660
661     /* Test asynchronous deletion of the queue. */
662     q = pCreateTimerQueue();
663     ok(q != NULL, "CreateTimerQueue\n");
664
665     SetLastError(0xdeadbeef);
666     ret = pDeleteTimerQueueEx(q, NULL);
667     ok(!ret, "DeleteTimerQueueEx\n");
668     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
669
670     /* Test synchronous deletion of the queue and running timers. */
671     q = pCreateTimerQueue();
672     ok(q != NULL, "CreateTimerQueue\n");
673
674     /* Called once.  */
675     t1 = NULL;
676     n1 = 0;
677     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
678                                  0, 0);
679     ok(ret, "CreateTimerQueueTimer\n");
680     ok(t1 != NULL, "CreateTimerQueueTimer\n");
681
682     /* A slow one.  */
683     t2 = NULL;
684     n2 = 0;
685     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
686                                  100, 0);
687     ok(ret, "CreateTimerQueueTimer\n");
688     ok(t2 != NULL, "CreateTimerQueueTimer\n");
689
690     /* A fast one.  */
691     t3 = NULL;
692     n3 = 0;
693     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
694                                  10, 0);
695     ok(ret, "CreateTimerQueueTimer\n");
696     ok(t3 != NULL, "CreateTimerQueueTimer\n");
697
698     /* Start really late (it won't start).  */
699     t4 = NULL;
700     n4 = 0;
701     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
702                                  10, 0);
703     ok(ret, "CreateTimerQueueTimer\n");
704     ok(t4 != NULL, "CreateTimerQueueTimer\n");
705
706     /* Start soon, but delay so long it won't run again.  */
707     t5 = NULL;
708     n5 = 0;
709     ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
710                                  10000, 0);
711     ok(ret, "CreateTimerQueueTimer\n");
712     ok(t5 != NULL, "CreateTimerQueueTimer\n");
713
714     /* Give them a chance to do some work.  */
715     Sleep(500);
716
717     /* Test deleting a once-only timer.  */
718     ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
719     ok(ret, "DeleteTimerQueueTimer\n");
720
721     /* A periodic timer.  */
722     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
723     ok(ret, "DeleteTimerQueueTimer\n");
724
725     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
726     ok(ret, "DeleteTimerQueueEx\n");
727     ok(n1 == 1, "Timer callback 1\n");
728     ok(n2 < n3, "Timer callback 2 should be much slower than 3\n");
729     ok(n4 == 0, "Timer callback 4\n");
730     ok(n5 == 1, "Timer callback 5\n");
731
732     /* Test synchronous deletion of the timer/queue with event trigger. */
733     e = CreateEvent(NULL, TRUE, FALSE, NULL);
734     et1 = CreateEvent(NULL, TRUE, FALSE, NULL);
735     et2 = CreateEvent(NULL, TRUE, FALSE, NULL);
736     if (!e || !et1 || !et2)
737     {
738         skip("Failed to create timer queue descruction event\n");
739         return;
740     }
741
742     q = pCreateTimerQueue();
743     ok(q != NULL, "CreateTimerQueue\n");
744
745     /* Run once and finish quickly (should be done when we delete it).  */
746     t1 = NULL;
747     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, (PVOID) 0, 0,
748                                  0, 0);
749     ok(ret, "CreateTimerQueueTimer\n");
750     ok(t1 != NULL, "CreateTimerQueueTimer\n");
751
752     /* Run once and finish slowly (shouldn't be done when we delete it).  */
753     t2 = NULL;
754     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
755                                  0, 0);
756     ok(ret, "CreateTimerQueueTimer\n");
757     ok(t2 != NULL, "CreateTimerQueueTimer\n");
758
759     /* Run once and finish quickly (should be done when we delete it).  */
760     t3 = NULL;
761     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, (PVOID) 0, 0,
762                                  0, 0);
763     ok(ret, "CreateTimerQueueTimer\n");
764     ok(t3 != NULL, "CreateTimerQueueTimer\n");
765
766     /* Run once and finish slowly (shouldn't be done when we delete it).  */
767     t4 = NULL;
768     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
769                                  0, 0);
770     ok(ret, "CreateTimerQueueTimer\n");
771     ok(t4 != NULL, "CreateTimerQueueTimer\n");
772
773     /* Give them a chance to start.  */
774     Sleep(400);
775
776     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
777        even if the timer is finished.  */
778     SetLastError(0xdeadbeef);
779     ret = pDeleteTimerQueueTimer(q, t1, NULL);
780     ok(!ret, "DeleteTimerQueueTimer\n");
781     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
782
783     SetLastError(0xdeadbeef);
784     ret = pDeleteTimerQueueTimer(q, t2, NULL);
785     ok(!ret, "DeleteTimerQueueTimer\n");
786     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
787
788     SetLastError(0xdeadbeef);
789     ret = pDeleteTimerQueueTimer(q, t3, et1);
790     ok(ret, "DeleteTimerQueueTimer\n");
791     ok(GetLastError() == 0xdeadbeef, "DeleteTimerQueueTimer\n");
792     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
793        "Timer destruction event not triggered\n");
794
795     SetLastError(0xdeadbeef);
796     ret = pDeleteTimerQueueTimer(q, t4, et2);
797     ok(!ret, "DeleteTimerQueueTimer\n");
798     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
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, "DeleteTimerQueueEx\n");
805     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
806     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
807        "Queue destruction event not triggered\n");
808     CloseHandle(e);
809
810     /* Test deleting/changing a timer in execution.  */
811     q = pCreateTimerQueue();
812     ok(q != NULL, "CreateTimerQueue\n");
813
814     /* Test changing a once-only timer before it fires (this is allowed,
815        whereas after it fires you cannot).  */
816     n1 = 0;
817     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
818                                  0, 0);
819     ok(ret, "CreateTimerQueueTimer\n");
820     ok(t1 != NULL, "CreateTimerQueueTimer\n");
821     ret = pChangeTimerQueueTimer(q, t1, 0, 0);
822     ok(ret, "ChangeTimerQueueTimer\n");
823
824     d2.t = t2 = NULL;
825     d2.num_calls = 0;
826     d2.max_calls = 3;
827     d2.q = q;
828     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
829                                  10, 0);
830     d2.t = t2;
831     ok(ret, "CreateTimerQueueTimer\n");
832     ok(t2 != NULL, "CreateTimerQueueTimer\n");
833
834     d3.t = t3 = NULL;
835     d3.num_calls = 0;
836     d3.max_calls = 4;
837     d3.q = q;
838     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
839                                  10, 0);
840     d3.t = t3;
841     ok(ret, "CreateTimerQueueTimer\n");
842     ok(t3 != NULL, "CreateTimerQueueTimer\n");
843
844     d4.t = t4 = NULL;
845     d4.num_calls = 0;
846     d4.q = q;
847     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
848                                  0, 0);
849     d4.t = t4;
850     ok(ret, "CreateTimerQueueTimer\n");
851     ok(t4 != NULL, "CreateTimerQueueTimer\n");
852
853     Sleep(200);
854
855     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
856     ok(ret, "DeleteTimerQueueEx\n");
857     ok(n1 == 1, "ChangeTimerQueueTimer\n");
858     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
859     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
860     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
861
862     /* Test an obscure bug that was in the original implementation.  */
863     q = pCreateTimerQueue();
864     ok(q != NULL, "CreateTimerQueue\n");
865
866     /* All the work is done in the callback.  */
867     d1.t = t1 = NULL;
868     d1.num_calls = 0;
869     d1.q = q;
870     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
871                                  100, WT_EXECUTELONGFUNCTION);
872     d1.t = t1;
873     ok(ret, "CreateTimerQueueTimer\n");
874     ok(t1 != NULL, "CreateTimerQueueTimer\n");
875
876     Sleep(750);
877
878     SetLastError(0xdeadbeef);
879     ret = pDeleteTimerQueueEx(q, NULL);
880     ok(!ret, "DeleteTimerQueueEx\n");
881     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
882     ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
883
884     /* Test functions on the default timer queue.  */
885     t1 = NULL;
886     n1 = 0;
887     ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
888                                  1000, 0);
889     ok(ret, "CreateTimerQueueTimer, default queue\n");
890     ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
891
892     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
893     ok(ret, "ChangeTimerQueueTimer, default queue\n");
894
895     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
896     ok(ret, "DeleteTimerQueueTimer, default queue\n");
897
898     /* Try mixing default and non-default queues.  Apparently this works.  */
899     q = pCreateTimerQueue();
900     ok(q != NULL, "CreateTimerQueue\n");
901
902     t1 = NULL;
903     n1 = 0;
904     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000,
905                                  1000, 0);
906     ok(ret, "CreateTimerQueueTimer\n");
907     ok(t1 != NULL, "CreateTimerQueueTimer\n");
908
909     t2 = NULL;
910     n2 = 0;
911     ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000,
912                                  1000, 0);
913     ok(ret, "CreateTimerQueueTimer\n");
914     ok(t2 != NULL, "CreateTimerQueueTimer\n");
915
916     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
917     ok(ret, "ChangeTimerQueueTimer\n");
918
919     ret = pChangeTimerQueueTimer(q, t2, 2000, 2000);
920     ok(ret, "ChangeTimerQueueTimer\n");
921
922     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
923     ok(ret, "DeleteTimerQueueTimer\n");
924
925     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
926     ok(ret, "DeleteTimerQueueTimer\n");
927
928     /* Try to delete the default queue?  In any case: not allowed.  */
929     SetLastError(0xdeadbeef);
930     ret = pDeleteTimerQueueEx(NULL, NULL);
931     ok(!ret, "DeleteTimerQueueEx\n");
932     ok(GetLastError() == ERROR_INVALID_HANDLE, "DeleteTimerQueueEx\n");
933
934     SetLastError(0xdeadbeef);
935     ret = pDeleteTimerQueueEx(q, NULL);
936     ok(!ret, "DeleteTimerQueueEx\n");
937     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
938 }
939
940 START_TEST(sync)
941 {
942     HMODULE hdll = GetModuleHandle("kernel32");
943     pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
944     pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
945     pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
946     pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
947     pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
948     pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
949     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
950
951     test_signalandwait();
952     test_mutex();
953     test_slist();
954     test_event();
955     test_semaphore();
956     test_waitable_timer();
957     test_iocp_callback();
958     test_timer_queue();
959 }