wintrust: Use helper function for setting confidence in SoftpubCheckCert.
[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\n");
662     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
663
664     /* Test synchronous deletion of the queue and running timers. */
665     q = pCreateTimerQueue();
666     ok(q != NULL, "CreateTimerQueue\n");
667
668     /* Called once.  */
669     t1 = NULL;
670     n1 = 0;
671     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
672                                  0, 0);
673     ok(ret, "CreateTimerQueueTimer\n");
674     ok(t1 != NULL, "CreateTimerQueueTimer\n");
675
676     /* A slow one.  */
677     t2 = NULL;
678     n2 = 0;
679     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
680                                  100, 0);
681     ok(ret, "CreateTimerQueueTimer\n");
682     ok(t2 != NULL, "CreateTimerQueueTimer\n");
683
684     /* A fast one.  */
685     t3 = NULL;
686     n3 = 0;
687     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
688                                  10, 0);
689     ok(ret, "CreateTimerQueueTimer\n");
690     ok(t3 != NULL, "CreateTimerQueueTimer\n");
691
692     /* Start really late (it won't start).  */
693     t4 = NULL;
694     n4 = 0;
695     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
696                                  10, 0);
697     ok(ret, "CreateTimerQueueTimer\n");
698     ok(t4 != NULL, "CreateTimerQueueTimer\n");
699
700     /* Start soon, but delay so long it won't run again.  */
701     t5 = NULL;
702     n5 = 0;
703     ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
704                                  10000, 0);
705     ok(ret, "CreateTimerQueueTimer\n");
706     ok(t5 != NULL, "CreateTimerQueueTimer\n");
707
708     /* Give them a chance to do some work.  */
709     Sleep(500);
710
711     /* Test deleting a once-only timer.  */
712     ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
713     ok(ret, "DeleteTimerQueueTimer\n");
714
715     /* A periodic timer.  */
716     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
717     ok(ret, "DeleteTimerQueueTimer\n");
718
719     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
720     ok(ret, "DeleteTimerQueueEx\n");
721     ok(n1 == 1, "Timer callback 1\n");
722     ok(n2 < n3, "Timer callback 2 should be much slower than 3\n");
723     ok(n4 == 0, "Timer callback 4\n");
724     ok(n5 == 1, "Timer callback 5\n");
725
726     /* Test synchronous deletion of the timer/queue with event trigger. */
727     e = CreateEvent(NULL, TRUE, FALSE, NULL);
728     et1 = CreateEvent(NULL, TRUE, FALSE, NULL);
729     et2 = CreateEvent(NULL, TRUE, FALSE, NULL);
730     if (!e || !et1 || !et2)
731     {
732         skip("Failed to create timer queue descruction event\n");
733         return;
734     }
735
736     q = pCreateTimerQueue();
737     ok(q != NULL, "CreateTimerQueue\n");
738
739     /* Run once and finish quickly (should be done when we delete it).  */
740     t1 = NULL;
741     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, (PVOID) 0, 0,
742                                  0, 0);
743     ok(ret, "CreateTimerQueueTimer\n");
744     ok(t1 != NULL, "CreateTimerQueueTimer\n");
745
746     /* Run once and finish slowly (shouldn't be done when we delete it).  */
747     t2 = NULL;
748     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
749                                  0, 0);
750     ok(ret, "CreateTimerQueueTimer\n");
751     ok(t2 != NULL, "CreateTimerQueueTimer\n");
752
753     /* Run once and finish quickly (should be done when we delete it).  */
754     t3 = NULL;
755     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, (PVOID) 0, 0,
756                                  0, 0);
757     ok(ret, "CreateTimerQueueTimer\n");
758     ok(t3 != NULL, "CreateTimerQueueTimer\n");
759
760     /* Run once and finish slowly (shouldn't be done when we delete it).  */
761     t4 = NULL;
762     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
763                                  0, 0);
764     ok(ret, "CreateTimerQueueTimer\n");
765     ok(t4 != NULL, "CreateTimerQueueTimer\n");
766
767     /* Give them a chance to start.  */
768     Sleep(400);
769
770     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
771        even if the timer is finished.  */
772     SetLastError(0xdeadbeef);
773     ret = pDeleteTimerQueueTimer(q, t1, NULL);
774     ok(!ret, "DeleteTimerQueueTimer\n");
775     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
776
777     SetLastError(0xdeadbeef);
778     ret = pDeleteTimerQueueTimer(q, t2, NULL);
779     ok(!ret, "DeleteTimerQueueTimer\n");
780     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
781
782     SetLastError(0xdeadbeef);
783     ret = pDeleteTimerQueueTimer(q, t3, et1);
784     ok(ret, "DeleteTimerQueueTimer\n");
785     ok(GetLastError() == 0xdeadbeef, "DeleteTimerQueueTimer\n");
786     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
787        "Timer destruction event not triggered\n");
788
789     SetLastError(0xdeadbeef);
790     ret = pDeleteTimerQueueTimer(q, t4, et2);
791     ok(!ret, "DeleteTimerQueueTimer\n");
792     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
793     ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
794        "Timer destruction event not triggered\n");
795
796     SetLastError(0xdeadbeef);
797     ret = pDeleteTimerQueueEx(q, e);
798     ok(!ret, "DeleteTimerQueueEx\n");
799     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
800     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
801        "Queue destruction event not triggered\n");
802     CloseHandle(e);
803
804     /* Test deleting/changing a timer in execution.  */
805     q = pCreateTimerQueue();
806     ok(q != NULL, "CreateTimerQueue\n");
807
808     /* Test changing a once-only timer before it fires (this is allowed,
809        whereas after it fires you cannot).  */
810     n1 = 0;
811     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
812                                  0, 0);
813     ok(ret, "CreateTimerQueueTimer\n");
814     ok(t1 != NULL, "CreateTimerQueueTimer\n");
815     ret = pChangeTimerQueueTimer(q, t1, 0, 0);
816     ok(ret, "ChangeTimerQueueTimer\n");
817
818     d2.t = t2 = NULL;
819     d2.num_calls = 0;
820     d2.max_calls = 3;
821     d2.q = q;
822     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
823                                  10, 0);
824     d2.t = t2;
825     ok(ret, "CreateTimerQueueTimer\n");
826     ok(t2 != NULL, "CreateTimerQueueTimer\n");
827
828     d3.t = t3 = NULL;
829     d3.num_calls = 0;
830     d3.max_calls = 4;
831     d3.q = q;
832     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
833                                  10, 0);
834     d3.t = t3;
835     ok(ret, "CreateTimerQueueTimer\n");
836     ok(t3 != NULL, "CreateTimerQueueTimer\n");
837
838     d4.t = t4 = NULL;
839     d4.num_calls = 0;
840     d4.q = q;
841     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
842                                  0, 0);
843     d4.t = t4;
844     ok(ret, "CreateTimerQueueTimer\n");
845     ok(t4 != NULL, "CreateTimerQueueTimer\n");
846
847     Sleep(200);
848
849     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
850     ok(ret, "DeleteTimerQueueEx\n");
851     ok(n1 == 1, "ChangeTimerQueueTimer\n");
852     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
853     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
854     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
855
856     /* Test an obscure bug that was in the original implementation.  */
857     q = pCreateTimerQueue();
858     ok(q != NULL, "CreateTimerQueue\n");
859
860     /* All the work is done in the callback.  */
861     d1.t = t1 = NULL;
862     d1.num_calls = 0;
863     d1.q = q;
864     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
865                                  100, WT_EXECUTELONGFUNCTION);
866     d1.t = t1;
867     ok(ret, "CreateTimerQueueTimer\n");
868     ok(t1 != NULL, "CreateTimerQueueTimer\n");
869
870     Sleep(750);
871
872     SetLastError(0xdeadbeef);
873     ret = pDeleteTimerQueueEx(q, NULL);
874     ok(!ret, "DeleteTimerQueueEx\n");
875     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
876     ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
877
878     /* Test functions on the default timer queue.  */
879     t1 = NULL;
880     n1 = 0;
881     ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
882                                  1000, 0);
883     ok(ret, "CreateTimerQueueTimer, default queue\n");
884     ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
885
886     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
887     ok(ret, "ChangeTimerQueueTimer, default queue\n");
888
889     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
890     ok(ret, "DeleteTimerQueueTimer, default queue\n");
891
892     /* Try mixing default and non-default queues.  Apparently this works.  */
893     q = pCreateTimerQueue();
894     ok(q != NULL, "CreateTimerQueue\n");
895
896     t1 = NULL;
897     n1 = 0;
898     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000,
899                                  1000, 0);
900     ok(ret, "CreateTimerQueueTimer\n");
901     ok(t1 != NULL, "CreateTimerQueueTimer\n");
902
903     t2 = NULL;
904     n2 = 0;
905     ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000,
906                                  1000, 0);
907     ok(ret, "CreateTimerQueueTimer\n");
908     ok(t2 != NULL, "CreateTimerQueueTimer\n");
909
910     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
911     ok(ret, "ChangeTimerQueueTimer\n");
912
913     ret = pChangeTimerQueueTimer(q, t2, 2000, 2000);
914     ok(ret, "ChangeTimerQueueTimer\n");
915
916     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
917     ok(ret, "DeleteTimerQueueTimer\n");
918
919     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
920     ok(ret, "DeleteTimerQueueTimer\n");
921
922     /* Try to delete the default queue?  In any case: not allowed.  */
923     SetLastError(0xdeadbeef);
924     ret = pDeleteTimerQueueEx(NULL, NULL);
925     ok(!ret, "DeleteTimerQueueEx\n");
926     ok(GetLastError() == ERROR_INVALID_HANDLE, "DeleteTimerQueueEx\n");
927
928     SetLastError(0xdeadbeef);
929     ret = pDeleteTimerQueueEx(q, NULL);
930     ok(!ret, "DeleteTimerQueueEx\n");
931     ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
932 }
933
934 START_TEST(sync)
935 {
936     HMODULE hdll = GetModuleHandle("kernel32");
937     pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
938     pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
939     pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
940     pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
941     pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
942     pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
943     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
944
945     test_signalandwait();
946     test_mutex();
947     test_slist();
948     test_event();
949     test_semaphore();
950     test_waitable_timer();
951     test_iocp_callback();
952     test_timer_queue();
953 }