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