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