mshtml: Add tests for get_scrollLeft.
[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     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
516                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
517     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
518     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
519     ok(retb == TRUE, "BindIoCompletionCallback failed with a NULL callback(first time set)\n");
520     ret = CloseHandle(hFile);
521     ok( ret, "CloseHandle: error %d\n", GetLastError());
522     ret = DeleteFileA(filename);
523     ok( ret, "DeleteFileA: error %d\n", GetLastError());
524
525     /* win2k3 requires the Flags parameter to be zero */
526     SetLastError(0xdeadbeef);
527     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
528                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
529     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
530     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
531     if (!retb)
532         ok(GetLastError() == ERROR_INVALID_PARAMETER,
533            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
534     else
535         ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
536     ret = CloseHandle(hFile);
537     ok( ret, "CloseHandle: error %d\n", GetLastError());
538     ret = DeleteFileA(filename);
539     ok( ret, "DeleteFileA: error %d\n", GetLastError());
540
541     retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
542     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
543     ok(GetLastError() == ERROR_INVALID_HANDLE, "Last error is %d\n", GetLastError());
544 }
545
546 static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut)
547 {
548     int *pn = (int *) p;
549     ok(timedOut, "Timer callbacks should always time out\n");
550     ++*pn;
551 }
552
553 struct timer_queue_data1
554 {
555     int num_calls;
556     int max_calls;
557     HANDLE q, t;
558 };
559
560 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
561 {
562     struct timer_queue_data1 *d = p;
563     ok(timedOut, "Timer callbacks should always time out\n");
564     if (d->t && ++d->num_calls == d->max_calls)
565     {
566         BOOL ret;
567         SetLastError(0xdeadbeef);
568         /* Note, XP SP2 does *not* do any deadlock checking, so passing
569            INVALID_HANDLE_VALUE here will just hang.  */
570         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
571         ok(!ret, "DeleteTimerQueueTimer\n");
572         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
573     }
574 }
575
576 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
577 {
578     struct timer_queue_data1 *d = p;
579     ok(timedOut, "Timer callbacks should always time out\n");
580     if (d->t && ++d->num_calls == d->max_calls)
581     {
582         /* Basically kill the timer since it won't have time to run
583            again.  */
584         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0);
585         ok(ret, "ChangeTimerQueueTimer\n");
586     }
587 }
588
589 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
590 {
591     struct timer_queue_data1 *d = p;
592     ok(timedOut, "Timer callbacks should always time out\n");
593     if (d->t)
594     {
595         /* This tests whether a timer gets flagged for deletion before
596            or after the callback runs.  If we start this timer with a
597            period of zero (run once), then ChangeTimerQueueTimer will
598            fail if the timer is already flagged.  Hence we really run
599            only once.  Otherwise we will run multiple times.  */
600         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50);
601         ok(ret, "ChangeTimerQueueTimer\n");
602         ++d->num_calls;
603     }
604 }
605
606 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
607 {
608     DWORD delay = (DWORD) p;
609     ok(timedOut, "Timer callbacks should always time out\n");
610     if (delay)
611         Sleep(delay);
612 }
613
614 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
615 {
616     struct timer_queue_data1 *d = p;
617     ok(timedOut, "Timer callbacks should always time out\n");
618     /* This tests an original implementation bug where a deleted timer may get
619        to run, but it is tricky to set up.  */
620     if (d->q && d->num_calls++ == 0)
621     {
622         /* First run: delete ourselves, then insert and remove a timer
623            that goes in front of us in the sorted timeout list.  Once
624            removed, we will still timeout at the faster timer's due time,
625            but this should be a no-op if we are bug-free.  There should
626            not be a second run.  We can test the value of num_calls later.  */
627         BOOL ret;
628         HANDLE t;
629
630         /* The delete will pend while we are in this callback.  */
631         SetLastError(0xdeadbeef);
632         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
633         ok(!ret, "DeleteTimerQueueTimer\n");
634         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
635
636         ret = pCreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
637         ok(ret, "CreateTimerQueueTimer\n");
638         ok(t != NULL, "CreateTimerQueueTimer\n");
639
640         ret = pDeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
641         ok(ret, "DeleteTimerQueueTimer\n");
642
643         /* Now we stay alive by hanging around in the callback.  */
644         Sleep(500);
645     }
646 }
647
648 static void test_timer_queue(void)
649 {
650     HANDLE q, t1, t2, t3, t4, t5;
651     int n1, n2, n3, n4, n5;
652     struct timer_queue_data1 d1, d2, d3, d4;
653     HANDLE e, et1, et2;
654     BOOL ret;
655
656     if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer
657         || !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer)
658     {
659         skip("TimerQueue API not present\n");
660         return;
661     }
662
663     /* Test asynchronous deletion of the queue. */
664     q = pCreateTimerQueue();
665     ok(q != NULL, "CreateTimerQueue\n");
666
667     SetLastError(0xdeadbeef);
668     ret = pDeleteTimerQueueEx(q, NULL);
669     ok(!ret, "DeleteTimerQueueEx\n");
670     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
671
672     /* Test synchronous deletion of the queue and running timers. */
673     q = pCreateTimerQueue();
674     ok(q != NULL, "CreateTimerQueue\n");
675
676     /* Called once.  */
677     t1 = NULL;
678     n1 = 0;
679     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
680                                  0, 0);
681     ok(ret, "CreateTimerQueueTimer\n");
682     ok(t1 != NULL, "CreateTimerQueueTimer\n");
683
684     /* A slow one.  */
685     t2 = NULL;
686     n2 = 0;
687     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
688                                  100, 0);
689     ok(ret, "CreateTimerQueueTimer\n");
690     ok(t2 != NULL, "CreateTimerQueueTimer\n");
691
692     /* A fast one.  */
693     t3 = NULL;
694     n3 = 0;
695     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
696                                  10, 0);
697     ok(ret, "CreateTimerQueueTimer\n");
698     ok(t3 != NULL, "CreateTimerQueueTimer\n");
699
700     /* Start really late (it won't start).  */
701     t4 = NULL;
702     n4 = 0;
703     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
704                                  10, 0);
705     ok(ret, "CreateTimerQueueTimer\n");
706     ok(t4 != NULL, "CreateTimerQueueTimer\n");
707
708     /* Start soon, but delay so long it won't run again.  */
709     t5 = NULL;
710     n5 = 0;
711     ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
712                                  10000, 0);
713     ok(ret, "CreateTimerQueueTimer\n");
714     ok(t5 != NULL, "CreateTimerQueueTimer\n");
715
716     /* Give them a chance to do some work.  */
717     Sleep(500);
718
719     /* Test deleting a once-only timer.  */
720     ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
721     ok(ret, "DeleteTimerQueueTimer\n");
722
723     /* A periodic timer.  */
724     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
725     ok(ret, "DeleteTimerQueueTimer\n");
726
727     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
728     ok(ret, "DeleteTimerQueueEx\n");
729     ok(n1 == 1, "Timer callback 1\n");
730     ok(n2 < n3, "Timer callback 2 should be much slower than 3\n");
731     ok(n4 == 0, "Timer callback 4\n");
732     ok(n5 == 1, "Timer callback 5\n");
733
734     /* Test synchronous deletion of the timer/queue with event trigger. */
735     e = CreateEvent(NULL, TRUE, FALSE, NULL);
736     et1 = CreateEvent(NULL, TRUE, FALSE, NULL);
737     et2 = CreateEvent(NULL, TRUE, FALSE, NULL);
738     if (!e || !et1 || !et2)
739     {
740         skip("Failed to create timer queue descruction event\n");
741         return;
742     }
743
744     q = pCreateTimerQueue();
745     ok(q != NULL, "CreateTimerQueue\n");
746
747     /* Run once and finish quickly (should be done when we delete it).  */
748     t1 = NULL;
749     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, (PVOID) 0, 0,
750                                  0, 0);
751     ok(ret, "CreateTimerQueueTimer\n");
752     ok(t1 != NULL, "CreateTimerQueueTimer\n");
753
754     /* Run once and finish slowly (shouldn't be done when we delete it).  */
755     t2 = NULL;
756     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
757                                  0, 0);
758     ok(ret, "CreateTimerQueueTimer\n");
759     ok(t2 != NULL, "CreateTimerQueueTimer\n");
760
761     /* Run once and finish quickly (should be done when we delete it).  */
762     t3 = NULL;
763     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, (PVOID) 0, 0,
764                                  0, 0);
765     ok(ret, "CreateTimerQueueTimer\n");
766     ok(t3 != NULL, "CreateTimerQueueTimer\n");
767
768     /* Run once and finish slowly (shouldn't be done when we delete it).  */
769     t4 = NULL;
770     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
771                                  0, 0);
772     ok(ret, "CreateTimerQueueTimer\n");
773     ok(t4 != NULL, "CreateTimerQueueTimer\n");
774
775     /* Give them a chance to start.  */
776     Sleep(400);
777
778     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
779        even if the timer is finished.  */
780     SetLastError(0xdeadbeef);
781     ret = pDeleteTimerQueueTimer(q, t1, NULL);
782     ok(!ret, "DeleteTimerQueueTimer\n");
783     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
784
785     SetLastError(0xdeadbeef);
786     ret = pDeleteTimerQueueTimer(q, t2, NULL);
787     ok(!ret, "DeleteTimerQueueTimer\n");
788     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
789
790     SetLastError(0xdeadbeef);
791     ret = pDeleteTimerQueueTimer(q, t3, et1);
792     ok(ret, "DeleteTimerQueueTimer\n");
793     ok(GetLastError() == 0xdeadbeef, "DeleteTimerQueueTimer\n");
794     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
795        "Timer destruction event not triggered\n");
796
797     SetLastError(0xdeadbeef);
798     ret = pDeleteTimerQueueTimer(q, t4, et2);
799     ok(!ret, "DeleteTimerQueueTimer\n");
800     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
801     ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
802        "Timer destruction event not triggered\n");
803
804     SetLastError(0xdeadbeef);
805     ret = pDeleteTimerQueueEx(q, e);
806     ok(!ret, "DeleteTimerQueueEx\n");
807     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
808     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
809        "Queue destruction event not triggered\n");
810     CloseHandle(e);
811
812     /* Test deleting/changing a timer in execution.  */
813     q = pCreateTimerQueue();
814     ok(q != NULL, "CreateTimerQueue\n");
815
816     /* Test changing a once-only timer before it fires (this is allowed,
817        whereas after it fires you cannot).  */
818     n1 = 0;
819     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
820                                  0, 0);
821     ok(ret, "CreateTimerQueueTimer\n");
822     ok(t1 != NULL, "CreateTimerQueueTimer\n");
823     ret = pChangeTimerQueueTimer(q, t1, 0, 0);
824     ok(ret, "ChangeTimerQueueTimer\n");
825
826     d2.t = t2 = NULL;
827     d2.num_calls = 0;
828     d2.max_calls = 3;
829     d2.q = q;
830     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
831                                  10, 0);
832     d2.t = t2;
833     ok(ret, "CreateTimerQueueTimer\n");
834     ok(t2 != NULL, "CreateTimerQueueTimer\n");
835
836     d3.t = t3 = NULL;
837     d3.num_calls = 0;
838     d3.max_calls = 4;
839     d3.q = q;
840     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
841                                  10, 0);
842     d3.t = t3;
843     ok(ret, "CreateTimerQueueTimer\n");
844     ok(t3 != NULL, "CreateTimerQueueTimer\n");
845
846     d4.t = t4 = NULL;
847     d4.num_calls = 0;
848     d4.q = q;
849     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
850                                  0, 0);
851     d4.t = t4;
852     ok(ret, "CreateTimerQueueTimer\n");
853     ok(t4 != NULL, "CreateTimerQueueTimer\n");
854
855     Sleep(200);
856
857     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
858     ok(ret, "DeleteTimerQueueEx\n");
859     ok(n1 == 1, "ChangeTimerQueueTimer\n");
860     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
861     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
862     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
863
864     /* Test an obscure bug that was in the original implementation.  */
865     q = pCreateTimerQueue();
866     ok(q != NULL, "CreateTimerQueue\n");
867
868     /* All the work is done in the callback.  */
869     d1.t = t1 = NULL;
870     d1.num_calls = 0;
871     d1.q = q;
872     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
873                                  100, WT_EXECUTELONGFUNCTION);
874     d1.t = t1;
875     ok(ret, "CreateTimerQueueTimer\n");
876     ok(t1 != NULL, "CreateTimerQueueTimer\n");
877
878     Sleep(750);
879
880     SetLastError(0xdeadbeef);
881     ret = pDeleteTimerQueueEx(q, NULL);
882     ok(!ret, "DeleteTimerQueueEx\n");
883     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
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\n");
934     ok(GetLastError() == ERROR_INVALID_HANDLE, "DeleteTimerQueueEx\n");
935
936     SetLastError(0xdeadbeef);
937     ret = pDeleteTimerQueueEx(q, NULL);
938     ok(!ret, "DeleteTimerQueueEx\n");
939     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
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 }