ole32: Include ole2.h in ole32_main.c to type-check the function signature of OleMeta...
[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 #include <winbase.h>
26
27 #include "wine/test.h"
28
29 static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*,BOOL,LPCSTR);
30 static HANDLE (WINAPI *pOpenWaitableTimerA)(DWORD,BOOL,LPCSTR);
31
32 static void test_signalandwait(void)
33 {
34     DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL);
35     HMODULE kernel32;
36     DWORD r;
37     int i;
38     HANDLE event[2], maxevents[MAXIMUM_WAIT_OBJECTS], semaphore[2], file;
39
40     kernel32 = GetModuleHandle("kernel32");
41     pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait");
42
43     if (!pSignalObjectAndWait)
44         return;
45
46     /* invalid parameters */
47     r = pSignalObjectAndWait(NULL, NULL, 0, 0);
48     if (r == ERROR_INVALID_FUNCTION)
49     {
50         trace("SignalObjectAndWait not implemented, skipping tests\n");
51         return; /* Win98/ME */
52     }
53     ok( r == WAIT_FAILED, "should fail\n");
54
55     event[0] = CreateEvent(NULL, 0, 0, NULL);
56     event[1] = CreateEvent(NULL, 1, 1, NULL);
57
58     ok( event[0] && event[1], "failed to create event flags\n");
59
60     r = pSignalObjectAndWait(event[0], NULL, 0, FALSE);
61     ok( r == WAIT_FAILED, "should fail\n");
62
63     r = pSignalObjectAndWait(NULL, event[0], 0, FALSE);
64     ok( r == WAIT_FAILED, "should fail\n");
65
66
67     /* valid parameters */
68     r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
69     ok( r == WAIT_OBJECT_0, "should succeed\n");
70
71     /* event[0] is now signalled */
72     r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
73     ok( r == WAIT_OBJECT_0, "should succeed\n");
74
75     /* event[0] is not signalled */
76     r = WaitForSingleObject(event[0], 0);
77     ok( r == WAIT_TIMEOUT, "event was signalled\n");
78
79     r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
80     ok( r == WAIT_OBJECT_0, "should succeed\n");
81
82     /* clear event[1] and check for a timeout */
83     ok(ResetEvent(event[1]), "failed to clear event[1]\n");
84     r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
85     ok( r == WAIT_TIMEOUT, "should timeout\n");
86
87     CloseHandle(event[0]);
88     CloseHandle(event[1]);
89
90     /* create the maximum number of events and make sure 
91      * we can wait on that many */
92     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
93     {
94         maxevents[i] = CreateEvent(NULL, 1, 1, NULL);
95         ok( maxevents[i] != 0, "should create enough events\n");
96     }
97     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, 0, 0);
98     ok( r != WAIT_FAILED && r != WAIT_TIMEOUT, "should succeed\n");
99
100     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
101         if (maxevents[i]) CloseHandle(maxevents[i]);
102
103     /* semaphores */
104     semaphore[0] = CreateSemaphore( NULL, 0, 1, NULL );
105     semaphore[1] = CreateSemaphore( NULL, 1, 1, NULL );
106     ok( semaphore[0] && semaphore[1], "failed to create semaphore\n");
107
108     r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
109     ok( r == WAIT_OBJECT_0, "should succeed\n");
110
111     r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
112     ok( r == WAIT_FAILED, "should fail\n");
113
114     r = ReleaseSemaphore(semaphore[0],1,NULL);
115     ok( r == FALSE, "should fail\n");
116
117     r = ReleaseSemaphore(semaphore[1],1,NULL);
118     ok( r == TRUE, "should succeed\n");
119
120     CloseHandle(semaphore[0]);
121     CloseHandle(semaphore[1]);
122
123     /* try a registry key */
124     file = CreateFile("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 
125         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
126     r = pSignalObjectAndWait(file, file, 0, FALSE);
127     ok( r == WAIT_FAILED, "should fail\n");
128     ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n");
129     CloseHandle(file);
130 }
131
132 static void test_mutex(void)
133 {
134     DWORD wait_ret;
135     BOOL ret;
136     HANDLE hCreated;
137     HANDLE hOpened;
138
139     hCreated = CreateMutex(NULL, FALSE, "WineTestMutex");
140     ok(hCreated != NULL, "CreateMutex failed with error %d\n", GetLastError());
141     wait_ret = WaitForSingleObject(hCreated, INFINITE);
142     ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error 0x%08x\n", wait_ret);
143
144     /* yes, opening with just READ_CONTROL access allows us to successfully
145      * call ReleaseMutex */
146     hOpened = OpenMutex(READ_CONTROL, FALSE, "WineTestMutex");
147     ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
148     ret = ReleaseMutex(hOpened);
149     todo_wine ok(ret, "ReleaseMutex failed with error %d\n", GetLastError());
150     ret = ReleaseMutex(hCreated);
151     todo_wine ok(!ret && (GetLastError() == ERROR_NOT_OWNER),
152         "ReleaseMutex should have failed with ERROR_NOT_OWNER instead of %d\n", GetLastError());
153
154     /* test case sensitivity */
155
156     SetLastError(0xdeadbeef);
157     hOpened = OpenMutex(READ_CONTROL, FALSE, "WINETESTMUTEX");
158     ok(!hOpened, "OpenMutex succeeded\n");
159     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
160
161     SetLastError(0xdeadbeef);
162     hOpened = OpenMutex(READ_CONTROL, FALSE, "winetestmutex");
163     ok(!hOpened, "OpenMutex succeeded\n");
164     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
165
166     SetLastError(0xdeadbeef);
167     hOpened = CreateMutex(NULL, FALSE, "WineTestMutex");
168     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
169     ok(GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
170     CloseHandle(hOpened);
171
172     SetLastError(0xdeadbeef);
173     hOpened = CreateMutex(NULL, FALSE, "WINETESTMUTEX");
174     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
175     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
176     CloseHandle(hOpened);
177
178     CloseHandle(hCreated);
179 }
180
181 static void test_slist(void)
182 {
183     struct item
184     {
185         SLIST_ENTRY entry;
186         int value;
187     } item1, item2, item3, *pitem;
188
189     SLIST_HEADER slist_header, test_header;
190     PSLIST_ENTRY entry;
191     USHORT size;
192
193     VOID (WINAPI *pInitializeSListHead)(PSLIST_HEADER);
194     USHORT (WINAPI *pQueryDepthSList)(PSLIST_HEADER);
195     PSLIST_ENTRY (WINAPI *pInterlockedFlushSList)(PSLIST_HEADER);
196     PSLIST_ENTRY (WINAPI *pInterlockedPopEntrySList)(PSLIST_HEADER);
197     PSLIST_ENTRY (WINAPI *pInterlockedPushEntrySList)(PSLIST_HEADER,PSLIST_ENTRY);
198     HMODULE kernel32;
199
200     kernel32 = GetModuleHandle("KERNEL32.DLL");
201     pInitializeSListHead = (void*) GetProcAddress(kernel32, "InitializeSListHead");
202     pQueryDepthSList = (void*) GetProcAddress(kernel32, "QueryDepthSList");
203     pInterlockedFlushSList = (void*) GetProcAddress(kernel32, "InterlockedFlushSList");
204     pInterlockedPopEntrySList = (void*) GetProcAddress(kernel32, "InterlockedPopEntrySList");
205     pInterlockedPushEntrySList = (void*) GetProcAddress(kernel32, "InterlockedPushEntrySList");
206     if (pInitializeSListHead == NULL ||
207         pQueryDepthSList == NULL ||
208         pInterlockedFlushSList == NULL ||
209         pInterlockedPopEntrySList == NULL ||
210         pInterlockedPushEntrySList == NULL)
211     {
212         skip("some required slist entrypoints were not found, skipping tests\n");
213         return;
214     }
215
216     memset(&test_header, 0, sizeof(test_header));
217     memset(&slist_header, 0xFF, sizeof(slist_header));
218     pInitializeSListHead(&slist_header);
219     ok(memcmp(&test_header, &slist_header, sizeof(SLIST_HEADER)) == 0,
220         "InitializeSListHead didn't zero-fill list header\n");
221     size = pQueryDepthSList(&slist_header);
222     ok(size == 0, "initially created slist has size %d, expected 0\n", size);
223
224     item1.value = 1;
225     ok(pInterlockedPushEntrySList(&slist_header, &item1.entry) == NULL,
226         "previous entry in empty slist wasn't NULL\n");
227     size = pQueryDepthSList(&slist_header);
228     ok(size == 1, "slist with 1 item has size %d\n", size);
229
230     item2.value = 2;
231     entry = pInterlockedPushEntrySList(&slist_header, &item2.entry);
232     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
233     if (entry != NULL)
234     {
235         pitem = (struct item*) entry;
236         ok(pitem->value == 1, "previous entry in slist wasn't the one added\n");
237     }
238     size = pQueryDepthSList(&slist_header);
239     ok(size == 2, "slist with 2 items has size %d\n", size);
240
241     item3.value = 3;
242     entry = pInterlockedPushEntrySList(&slist_header, &item3.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 == 2, "previous entry in slist wasn't the one added\n");
248     }
249     size = pQueryDepthSList(&slist_header);
250     ok(size == 3, "slist with 3 items has size %d\n", size);
251
252     entry = pInterlockedPopEntrySList(&slist_header);
253     ok(entry != NULL, "entry shouldn't be NULL\n");
254     if (entry != NULL)
255     {
256         pitem = (struct item*) entry;
257         ok(pitem->value == 3, "unexpected entry removed\n");
258     }
259     size = pQueryDepthSList(&slist_header);
260     ok(size == 2, "slist with 2 items has size %d\n", size);
261
262     entry = pInterlockedFlushSList(&slist_header);
263     size = pQueryDepthSList(&slist_header);
264     ok(size == 0, "flushed slist should be empty, size is %d\n", size);
265     if (size == 0)
266     {
267         ok(pInterlockedPopEntrySList(&slist_header) == NULL,
268             "popping empty slist didn't return NULL\n");
269     }
270     ok(((struct item*)entry)->value == 2, "item 2 not in front of list\n");
271     ok(((struct item*)entry->Next)->value == 1, "item 1 not at the back of list\n");
272 }
273
274 static void test_event(void)
275 {
276     HANDLE handle, handle2;
277     SECURITY_ATTRIBUTES sa;
278     SECURITY_DESCRIPTOR sd;
279     ACL acl;
280
281     /* no sd */
282     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
283     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
284     CloseHandle(handle);
285
286     sa.nLength = sizeof(sa);
287     sa.lpSecurityDescriptor = &sd;
288     sa.bInheritHandle = FALSE;
289
290     InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
291
292     /* blank sd */
293     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
294     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
295     CloseHandle(handle);
296
297     /* sd with NULL dacl */
298     SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
299     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
300     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
301     CloseHandle(handle);
302
303     /* sd with empty dacl */
304     InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
305     SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
306     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
307     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
308     CloseHandle(handle);
309
310     /* test case sensitivity */
311
312     SetLastError(0xdeadbeef);
313     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
314     ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
315     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
316
317     SetLastError(0xdeadbeef);
318     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
319     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
320     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
321     CloseHandle( handle2 );
322
323     SetLastError(0xdeadbeef);
324     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
325     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
326     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
327     CloseHandle( handle2 );
328
329     SetLastError(0xdeadbeef);
330     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
331     ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
332     CloseHandle( handle2 );
333
334     SetLastError(0xdeadbeef);
335     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
336     ok( !handle2, "OpenEvent succeeded\n");
337     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
338
339     CloseHandle( handle );
340 }
341
342 static void test_semaphore(void)
343 {
344     HANDLE handle, handle2;
345
346     /* test case sensitivity */
347
348     SetLastError(0xdeadbeef);
349     handle = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
350     ok(handle != NULL, "CreateSemaphore failed with error %u\n", GetLastError());
351     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
352
353     SetLastError(0xdeadbeef);
354     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
355     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
356     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
357     CloseHandle( handle2 );
358
359     SetLastError(0xdeadbeef);
360     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": TEST SEMAPHORE");
361     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
362     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
363     CloseHandle( handle2 );
364
365     SetLastError(0xdeadbeef);
366     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": Test Semaphore");
367     ok( handle2 != NULL, "OpenSemaphore failed with error %d\n", GetLastError());
368     CloseHandle( handle2 );
369
370     SetLastError(0xdeadbeef);
371     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": TEST SEMAPHORE");
372     ok( !handle2, "OpenSemaphore succeeded\n");
373     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
374
375     CloseHandle( handle );
376 }
377
378 static void test_waitable_timer(void)
379 {
380     HANDLE handle, handle2;
381
382     if (!pCreateWaitableTimerA || !pOpenWaitableTimerA)
383     {
384         skip("{Create,Open}WaitableTimerA() is not available\n");
385         return;
386     }
387
388     /* test case sensitivity */
389
390     SetLastError(0xdeadbeef);
391     handle = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
392     ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
393     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
394
395     SetLastError(0xdeadbeef);
396     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
397     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
398     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
399     CloseHandle( handle2 );
400
401     SetLastError(0xdeadbeef);
402     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
403     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
404     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
405     CloseHandle( handle2 );
406
407     SetLastError(0xdeadbeef);
408     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
409     ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
410     CloseHandle( handle2 );
411
412     SetLastError(0xdeadbeef);
413     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
414     ok( !handle2, "OpenWaitableTimer succeeded\n");
415     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
416
417     CloseHandle( handle );
418 }
419
420 static HANDLE sem = 0;
421
422 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
423 {
424     ReleaseSemaphore(sem, 1, NULL);
425 }
426
427 static BOOL WINAPI (*p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
428
429 static void test_iocp_callback(void)
430 {
431     char temp_path[MAX_PATH];
432     char filename[MAX_PATH];
433     DWORD ret;
434     BOOL retb;
435     static const char prefix[] = "pfx";
436     HANDLE hFile;
437     HMODULE hmod = GetModuleHandleA("kernel32.dll");
438     DWORD bytesWritten;
439     const char *buffer = "12345678123456781234567812345678";
440     OVERLAPPED overlapped;
441
442     p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
443     if(!p_BindIoCompletionCallback) {
444         skip("BindIoCompletionCallback not found in this DLL\n");
445         return;
446     }
447
448     sem = CreateSemaphore(NULL, 0, 1, NULL);
449     ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
450
451     ret = GetTempPathA(MAX_PATH, temp_path);
452     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
453     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
454
455     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
456     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
457
458     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
459                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
460     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
461
462     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
463     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
464     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
465
466     ret = CloseHandle(hFile);
467     ok( ret, "CloseHandle: error %d\n", GetLastError());
468     ret = DeleteFileA(filename);
469     ok( ret, "DeleteFileA: error %d\n", GetLastError());
470
471     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
472                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
473     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
474
475     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
476     ok(retb == TRUE, "BindIoCompletionCallback failed\n");
477
478     memset(&overlapped, 0, sizeof(overlapped));
479     retb = WriteFile(hFile, (const void *) buffer, 4, &bytesWritten, &overlapped);
480     ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
481
482     ret = WaitForSingleObject(sem, 5000);
483     ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
484     CloseHandle(sem);
485
486     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
487     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
488     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
489     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
490     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
491     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
492
493     ret = CloseHandle(hFile);
494     ok( ret, "CloseHandle: error %d\n", GetLastError());
495     ret = DeleteFileA(filename);
496     ok( ret, "DeleteFileA: error %d\n", GetLastError());
497
498     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
499                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
500     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
501     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
502     ok(retb == TRUE, "BindIoCompletionCallback failed with a NULL callback(first time set)\n");
503     ret = CloseHandle(hFile);
504     ok( ret, "CloseHandle: error %d\n", GetLastError());
505     ret = DeleteFileA(filename);
506     ok( ret, "DeleteFileA: error %d\n", GetLastError());
507
508     /* win2k3 requires the Flags parameter to be zero */
509     SetLastError(0xdeadbeef);
510     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
511                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
512     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
513     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
514     if (!retb)
515         ok(GetLastError() == ERROR_INVALID_PARAMETER,
516            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
517     else
518         ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
519     ret = CloseHandle(hFile);
520     ok( ret, "CloseHandle: error %d\n", GetLastError());
521     ret = DeleteFileA(filename);
522     ok( ret, "DeleteFileA: error %d\n", GetLastError());
523
524     retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
525     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
526     ok(GetLastError() == ERROR_INVALID_HANDLE, "Last error is %d\n", GetLastError());
527 }
528
529 START_TEST(sync)
530 {
531     HMODULE hdll = GetModuleHandle("kernel32");
532     pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
533     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
534
535     test_signalandwait();
536     test_mutex();
537     test_slist();
538     test_event();
539     test_semaphore();
540     test_waitable_timer();
541     test_iocp_callback();
542 }