kernel32: Fix a few test failures in win9x.
[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 ||
160        GetLastError() == ERROR_INVALID_NAME, /* win9x */
161        "wrong error %u\n", GetLastError());
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 = CreateMutex(NULL, FALSE, "WineTestMutex");
172     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
173     ok(GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
174     CloseHandle(hOpened);
175
176     SetLastError(0xdeadbeef);
177     hOpened = CreateMutex(NULL, FALSE, "WINETESTMUTEX");
178     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
179     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
180     CloseHandle(hOpened);
181
182     CloseHandle(hCreated);
183 }
184
185 static void test_slist(void)
186 {
187     struct item
188     {
189         SLIST_ENTRY entry;
190         int value;
191     } item1, item2, item3, *pitem;
192
193     SLIST_HEADER slist_header, test_header;
194     PSLIST_ENTRY entry;
195     USHORT size;
196
197     VOID (WINAPI *pInitializeSListHead)(PSLIST_HEADER);
198     USHORT (WINAPI *pQueryDepthSList)(PSLIST_HEADER);
199     PSLIST_ENTRY (WINAPI *pInterlockedFlushSList)(PSLIST_HEADER);
200     PSLIST_ENTRY (WINAPI *pInterlockedPopEntrySList)(PSLIST_HEADER);
201     PSLIST_ENTRY (WINAPI *pInterlockedPushEntrySList)(PSLIST_HEADER,PSLIST_ENTRY);
202     HMODULE kernel32;
203
204     kernel32 = GetModuleHandle("KERNEL32.DLL");
205     pInitializeSListHead = (void*) GetProcAddress(kernel32, "InitializeSListHead");
206     pQueryDepthSList = (void*) GetProcAddress(kernel32, "QueryDepthSList");
207     pInterlockedFlushSList = (void*) GetProcAddress(kernel32, "InterlockedFlushSList");
208     pInterlockedPopEntrySList = (void*) GetProcAddress(kernel32, "InterlockedPopEntrySList");
209     pInterlockedPushEntrySList = (void*) GetProcAddress(kernel32, "InterlockedPushEntrySList");
210     if (pInitializeSListHead == NULL ||
211         pQueryDepthSList == NULL ||
212         pInterlockedFlushSList == NULL ||
213         pInterlockedPopEntrySList == NULL ||
214         pInterlockedPushEntrySList == NULL)
215     {
216         skip("some required slist entrypoints were not found, skipping tests\n");
217         return;
218     }
219
220     memset(&test_header, 0, sizeof(test_header));
221     memset(&slist_header, 0xFF, sizeof(slist_header));
222     pInitializeSListHead(&slist_header);
223     ok(memcmp(&test_header, &slist_header, sizeof(SLIST_HEADER)) == 0,
224         "InitializeSListHead didn't zero-fill list header\n");
225     size = pQueryDepthSList(&slist_header);
226     ok(size == 0, "initially created slist has size %d, expected 0\n", size);
227
228     item1.value = 1;
229     ok(pInterlockedPushEntrySList(&slist_header, &item1.entry) == NULL,
230         "previous entry in empty slist wasn't NULL\n");
231     size = pQueryDepthSList(&slist_header);
232     ok(size == 1, "slist with 1 item has size %d\n", size);
233
234     item2.value = 2;
235     entry = pInterlockedPushEntrySList(&slist_header, &item2.entry);
236     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
237     if (entry != NULL)
238     {
239         pitem = (struct item*) entry;
240         ok(pitem->value == 1, "previous entry in slist wasn't the one added\n");
241     }
242     size = pQueryDepthSList(&slist_header);
243     ok(size == 2, "slist with 2 items has size %d\n", size);
244
245     item3.value = 3;
246     entry = pInterlockedPushEntrySList(&slist_header, &item3.entry);
247     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
248     if (entry != NULL)
249     {
250         pitem = (struct item*) entry;
251         ok(pitem->value == 2, "previous entry in slist wasn't the one added\n");
252     }
253     size = pQueryDepthSList(&slist_header);
254     ok(size == 3, "slist with 3 items has size %d\n", size);
255
256     entry = pInterlockedPopEntrySList(&slist_header);
257     ok(entry != NULL, "entry shouldn't be NULL\n");
258     if (entry != NULL)
259     {
260         pitem = (struct item*) entry;
261         ok(pitem->value == 3, "unexpected entry removed\n");
262     }
263     size = pQueryDepthSList(&slist_header);
264     ok(size == 2, "slist with 2 items has size %d\n", size);
265
266     entry = pInterlockedFlushSList(&slist_header);
267     size = pQueryDepthSList(&slist_header);
268     ok(size == 0, "flushed slist should be empty, size is %d\n", size);
269     if (size == 0)
270     {
271         ok(pInterlockedPopEntrySList(&slist_header) == NULL,
272             "popping empty slist didn't return NULL\n");
273     }
274     ok(((struct item*)entry)->value == 2, "item 2 not in front of list\n");
275     ok(((struct item*)entry->Next)->value == 1, "item 1 not at the back of list\n");
276 }
277
278 static void test_event(void)
279 {
280     HANDLE handle, handle2;
281     SECURITY_ATTRIBUTES sa;
282     SECURITY_DESCRIPTOR sd;
283     ACL acl;
284
285     /* no sd */
286     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
287     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
288     CloseHandle(handle);
289
290     sa.nLength = sizeof(sa);
291     sa.lpSecurityDescriptor = &sd;
292     sa.bInheritHandle = FALSE;
293
294     InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
295
296     /* blank sd */
297     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
298     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
299     CloseHandle(handle);
300
301     /* sd with NULL dacl */
302     SetSecurityDescriptorDacl(&sd, TRUE, NULL, 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     /* sd with empty dacl */
308     InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
309     SetSecurityDescriptorDacl(&sd, TRUE, &acl, 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     /* test case sensitivity */
315
316     SetLastError(0xdeadbeef);
317     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
318     ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
319     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
320
321     SetLastError(0xdeadbeef);
322     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
323     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
324     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
325     CloseHandle( handle2 );
326
327     SetLastError(0xdeadbeef);
328     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
329     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
330     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
331     CloseHandle( handle2 );
332
333     SetLastError(0xdeadbeef);
334     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
335     ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
336     CloseHandle( handle2 );
337
338     SetLastError(0xdeadbeef);
339     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
340     ok( !handle2, "OpenEvent succeeded\n");
341     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
342         GetLastError() == ERROR_INVALID_NAME, /* win9x */
343         "wrong error %u\n", GetLastError());
344
345     CloseHandle( handle );
346 }
347
348 static void test_semaphore(void)
349 {
350     HANDLE handle, handle2;
351
352     /* test case sensitivity */
353
354     SetLastError(0xdeadbeef);
355     handle = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
356     ok(handle != NULL, "CreateSemaphore failed with error %u\n", GetLastError());
357     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
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() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
363     CloseHandle( handle2 );
364
365     SetLastError(0xdeadbeef);
366     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": TEST SEMAPHORE");
367     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
368     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
369     CloseHandle( handle2 );
370
371     SetLastError(0xdeadbeef);
372     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": Test Semaphore");
373     ok( handle2 != NULL, "OpenSemaphore failed with error %d\n", GetLastError());
374     CloseHandle( handle2 );
375
376     SetLastError(0xdeadbeef);
377     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": TEST SEMAPHORE");
378     ok( !handle2, "OpenSemaphore succeeded\n");
379     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
380         GetLastError() == ERROR_INVALID_NAME, /* win9x */
381         "wrong error %u\n", GetLastError());
382
383     CloseHandle( handle );
384 }
385
386 static void test_waitable_timer(void)
387 {
388     HANDLE handle, handle2;
389
390     if (!pCreateWaitableTimerA || !pOpenWaitableTimerA)
391     {
392         skip("{Create,Open}WaitableTimerA() is not available\n");
393         return;
394     }
395
396     /* test case sensitivity */
397
398     SetLastError(0xdeadbeef);
399     handle = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
400     ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
401     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
402
403     SetLastError(0xdeadbeef);
404     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
405     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
406     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
407     CloseHandle( handle2 );
408
409     SetLastError(0xdeadbeef);
410     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
411     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
412     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
413     CloseHandle( handle2 );
414
415     SetLastError(0xdeadbeef);
416     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
417     ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
418     CloseHandle( handle2 );
419
420     SetLastError(0xdeadbeef);
421     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
422     ok( !handle2, "OpenWaitableTimer succeeded\n");
423     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
424
425     CloseHandle( handle );
426 }
427
428 static HANDLE sem = 0;
429
430 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
431 {
432     ReleaseSemaphore(sem, 1, NULL);
433 }
434
435 static BOOL WINAPI (*p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
436
437 static void test_iocp_callback(void)
438 {
439     char temp_path[MAX_PATH];
440     char filename[MAX_PATH];
441     DWORD ret;
442     BOOL retb;
443     static const char prefix[] = "pfx";
444     HANDLE hFile;
445     HMODULE hmod = GetModuleHandleA("kernel32.dll");
446     DWORD bytesWritten;
447     const char *buffer = "12345678123456781234567812345678";
448     OVERLAPPED overlapped;
449
450     p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
451     if(!p_BindIoCompletionCallback) {
452         skip("BindIoCompletionCallback not found in this DLL\n");
453         return;
454     }
455
456     sem = CreateSemaphore(NULL, 0, 1, NULL);
457     ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
458
459     ret = GetTempPathA(MAX_PATH, temp_path);
460     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
461     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
462
463     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
464     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
465
466     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
467                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
468     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
469
470     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
471     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
472     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
473
474     ret = CloseHandle(hFile);
475     ok( ret, "CloseHandle: error %d\n", GetLastError());
476     ret = DeleteFileA(filename);
477     ok( ret, "DeleteFileA: error %d\n", GetLastError());
478
479     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
480                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
481     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
482
483     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
484     ok(retb == TRUE, "BindIoCompletionCallback failed\n");
485
486     memset(&overlapped, 0, sizeof(overlapped));
487     retb = WriteFile(hFile, (const void *) buffer, 4, &bytesWritten, &overlapped);
488     ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
489
490     ret = WaitForSingleObject(sem, 5000);
491     ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
492     CloseHandle(sem);
493
494     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
495     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
496     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
497     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
498     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
499     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
500
501     ret = CloseHandle(hFile);
502     ok( ret, "CloseHandle: error %d\n", GetLastError());
503     ret = DeleteFileA(filename);
504     ok( ret, "DeleteFileA: error %d\n", GetLastError());
505
506     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
507                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
508     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
509     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
510     ok(retb == TRUE, "BindIoCompletionCallback failed with a NULL callback(first time set)\n");
511     ret = CloseHandle(hFile);
512     ok( ret, "CloseHandle: error %d\n", GetLastError());
513     ret = DeleteFileA(filename);
514     ok( ret, "DeleteFileA: error %d\n", GetLastError());
515
516     /* win2k3 requires the Flags parameter to be zero */
517     SetLastError(0xdeadbeef);
518     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
519                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
520     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
521     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
522     if (!retb)
523         ok(GetLastError() == ERROR_INVALID_PARAMETER,
524            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
525     else
526         ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
527     ret = CloseHandle(hFile);
528     ok( ret, "CloseHandle: error %d\n", GetLastError());
529     ret = DeleteFileA(filename);
530     ok( ret, "DeleteFileA: error %d\n", GetLastError());
531
532     retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
533     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
534     ok(GetLastError() == ERROR_INVALID_HANDLE, "Last error is %d\n", GetLastError());
535 }
536
537 START_TEST(sync)
538 {
539     HMODULE hdll = GetModuleHandle("kernel32");
540     pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
541     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
542
543     test_signalandwait();
544     test_mutex();
545     test_slist();
546     test_event();
547     test_semaphore();
548     test_waitable_timer();
549     test_iocp_callback();
550 }