include: Assorted spelling fixes.
[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 #define _WIN32_WINNT 0x500
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <windef.h>
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 static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFICATION_TYPE);
39 static BOOL   (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL);
40 static VOID   (WINAPI *pInitOnceInitialize)(PINIT_ONCE);
41 static BOOL   (WINAPI *pInitOnceExecuteOnce)(PINIT_ONCE,PINIT_ONCE_FN,PVOID,LPVOID*);
42 static BOOL   (WINAPI *pInitOnceBeginInitialize)(PINIT_ONCE,DWORD,BOOL*,LPVOID*);
43 static BOOL   (WINAPI *pInitOnceComplete)(PINIT_ONCE,DWORD,LPVOID);
44
45 static VOID   (WINAPI *pInitializeConditionVariable)(PCONDITION_VARIABLE);
46 static BOOL   (WINAPI *pSleepConditionVariableCS)(PCONDITION_VARIABLE,PCRITICAL_SECTION,DWORD);
47 static VOID   (WINAPI *pWakeAllConditionVariable)(PCONDITION_VARIABLE);
48 static VOID   (WINAPI *pWakeConditionVariable)(PCONDITION_VARIABLE);
49
50 static void test_signalandwait(void)
51 {
52     DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL);
53     HMODULE kernel32;
54     DWORD r;
55     HANDLE event[2], semaphore[2], file;
56
57     kernel32 = GetModuleHandle("kernel32");
58     pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait");
59
60     if (!pSignalObjectAndWait)
61         return;
62
63     /* invalid parameters */
64     r = pSignalObjectAndWait(NULL, NULL, 0, 0);
65     if (r == ERROR_INVALID_FUNCTION)
66     {
67         win_skip("SignalObjectAndWait is not implemented\n");
68         return; /* Win98/ME */
69     }
70     ok( r == WAIT_FAILED, "should fail\n");
71
72     event[0] = CreateEvent(NULL, 0, 0, NULL);
73     event[1] = CreateEvent(NULL, 1, 1, NULL);
74
75     ok( event[0] && event[1], "failed to create event flags\n");
76
77     r = pSignalObjectAndWait(event[0], NULL, 0, FALSE);
78     ok( r == WAIT_FAILED, "should fail\n");
79
80     r = pSignalObjectAndWait(NULL, event[0], 0, FALSE);
81     ok( r == WAIT_FAILED, "should fail\n");
82
83
84     /* valid parameters */
85     r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
86     ok( r == WAIT_OBJECT_0, "should succeed\n");
87
88     /* event[0] is now signalled */
89     r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
90     ok( r == WAIT_OBJECT_0, "should succeed\n");
91
92     /* event[0] is not signalled */
93     r = WaitForSingleObject(event[0], 0);
94     ok( r == WAIT_TIMEOUT, "event was signalled\n");
95
96     r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
97     ok( r == WAIT_OBJECT_0, "should succeed\n");
98
99     /* clear event[1] and check for a timeout */
100     ok(ResetEvent(event[1]), "failed to clear event[1]\n");
101     r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
102     ok( r == WAIT_TIMEOUT, "should timeout\n");
103
104     CloseHandle(event[0]);
105     CloseHandle(event[1]);
106
107     /* semaphores */
108     semaphore[0] = CreateSemaphore( NULL, 0, 1, NULL );
109     semaphore[1] = CreateSemaphore( NULL, 1, 1, NULL );
110     ok( semaphore[0] && semaphore[1], "failed to create semaphore\n");
111
112     r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
113     ok( r == WAIT_OBJECT_0, "should succeed\n");
114
115     r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
116     ok( r == WAIT_FAILED, "should fail\n");
117
118     r = ReleaseSemaphore(semaphore[0],1,NULL);
119     ok( r == FALSE, "should fail\n");
120
121     r = ReleaseSemaphore(semaphore[1],1,NULL);
122     ok( r == TRUE, "should succeed\n");
123
124     CloseHandle(semaphore[0]);
125     CloseHandle(semaphore[1]);
126
127     /* try a registry key */
128     file = CreateFile("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 
129         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
130     r = pSignalObjectAndWait(file, file, 0, FALSE);
131     ok( r == WAIT_FAILED, "should fail\n");
132     ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n");
133     CloseHandle(file);
134 }
135
136 static void test_mutex(void)
137 {
138     DWORD wait_ret;
139     BOOL ret;
140     HANDLE hCreated;
141     HANDLE hOpened;
142     int i;
143     DWORD failed = 0;
144
145     SetLastError(0xdeadbeef);
146     hOpened = OpenMutex(0, FALSE, "WineTestMutex");
147     ok(hOpened == NULL, "OpenMutex succeeded\n");
148     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
149
150     SetLastError(0xdeadbeef);
151     hCreated = CreateMutex(NULL, FALSE, "WineTestMutex");
152     ok(hCreated != NULL, "CreateMutex failed with error %d\n", GetLastError());
153
154     SetLastError(0xdeadbeef);
155     hOpened = OpenMutex(0, FALSE, "WineTestMutex");
156 todo_wine
157     ok(hOpened == NULL, "OpenMutex succeeded\n");
158 todo_wine
159     ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError());
160
161     SetLastError(0xdeadbeef);
162     hOpened = OpenMutex(GENERIC_EXECUTE, FALSE, "WineTestMutex");
163     ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
164     wait_ret = WaitForSingleObject(hOpened, INFINITE);
165     ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error %d\n", GetLastError());
166     CloseHandle(hOpened);
167
168     for(i=0; i < 31; i++)
169     {
170         wait_ret = WaitForSingleObject(hCreated, INFINITE);
171         ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error 0x%08x\n", wait_ret);
172     }
173
174     SetLastError(0xdeadbeef);
175     hOpened = OpenMutex(GENERIC_READ | GENERIC_WRITE, FALSE, "WineTestMutex");
176     ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
177     wait_ret = WaitForSingleObject(hOpened, INFINITE);
178     ok(wait_ret == WAIT_FAILED, "WaitForSingleObject succeeded\n");
179     CloseHandle(hOpened);
180
181     for (i = 0; i < 32; i++)
182     {
183         SetLastError(0xdeadbeef);
184         hOpened = OpenMutex(0x1 << i, FALSE, "WineTestMutex");
185         if(hOpened != NULL)
186         {
187             SetLastError(0xdeadbeef);
188             ret = ReleaseMutex(hOpened);
189             ok(ret, "ReleaseMutex failed with error %d, access %x\n", GetLastError(), 1 << i);
190             CloseHandle(hOpened);
191         }
192         else
193         {
194             if ((1 << i) == ACCESS_SYSTEM_SECURITY)
195                 todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "wrong error %u, access %x\n", GetLastError(), 1 << i);
196             else
197                 todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u, , access %x\n", GetLastError(), 1 << i);
198             ReleaseMutex(hCreated);
199             failed |=0x1 << i;
200         }
201     }
202
203 todo_wine
204     ok( failed == 0x0de0fffe, "open succeeded when it shouldn't: %x\n", failed);
205
206     SetLastError(0xdeadbeef);
207     ret = ReleaseMutex(hCreated);
208     ok(!ret && (GetLastError() == ERROR_NOT_OWNER),
209         "ReleaseMutex should have failed with ERROR_NOT_OWNER instead of %d\n", GetLastError());
210
211     /* test case sensitivity */
212
213     SetLastError(0xdeadbeef);
214     hOpened = OpenMutex(READ_CONTROL, FALSE, "WINETESTMUTEX");
215     ok(!hOpened, "OpenMutex succeeded\n");
216     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
217
218     SetLastError(0xdeadbeef);
219     hOpened = OpenMutex(READ_CONTROL, FALSE, "winetestmutex");
220     ok(!hOpened, "OpenMutex succeeded\n");
221     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
222
223     SetLastError(0xdeadbeef);
224     hOpened = CreateMutex(NULL, FALSE, "WineTestMutex");
225     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
226     ok(GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
227     CloseHandle(hOpened);
228
229     SetLastError(0xdeadbeef);
230     hOpened = CreateMutex(NULL, FALSE, "WINETESTMUTEX");
231     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
232     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
233     CloseHandle(hOpened);
234
235     CloseHandle(hCreated);
236 }
237
238 static void test_slist(void)
239 {
240     struct item
241     {
242         SLIST_ENTRY entry;
243         int value;
244     } item1, item2, item3, *pitem;
245
246     SLIST_HEADER slist_header;
247     PSLIST_ENTRY entry;
248     USHORT size;
249
250     VOID (WINAPI *pInitializeSListHead)(PSLIST_HEADER);
251     USHORT (WINAPI *pQueryDepthSList)(PSLIST_HEADER);
252     PSLIST_ENTRY (WINAPI *pInterlockedFlushSList)(PSLIST_HEADER);
253     PSLIST_ENTRY (WINAPI *pInterlockedPopEntrySList)(PSLIST_HEADER);
254     PSLIST_ENTRY (WINAPI *pInterlockedPushEntrySList)(PSLIST_HEADER,PSLIST_ENTRY);
255     HMODULE kernel32;
256
257     kernel32 = GetModuleHandle("KERNEL32.DLL");
258     pInitializeSListHead = (void*) GetProcAddress(kernel32, "InitializeSListHead");
259     pQueryDepthSList = (void*) GetProcAddress(kernel32, "QueryDepthSList");
260     pInterlockedFlushSList = (void*) GetProcAddress(kernel32, "InterlockedFlushSList");
261     pInterlockedPopEntrySList = (void*) GetProcAddress(kernel32, "InterlockedPopEntrySList");
262     pInterlockedPushEntrySList = (void*) GetProcAddress(kernel32, "InterlockedPushEntrySList");
263     if (pInitializeSListHead == NULL ||
264         pQueryDepthSList == NULL ||
265         pInterlockedFlushSList == NULL ||
266         pInterlockedPopEntrySList == NULL ||
267         pInterlockedPushEntrySList == NULL)
268     {
269         win_skip("some required slist entrypoints were not found, skipping tests\n");
270         return;
271     }
272
273     memset(&slist_header, 0xFF, sizeof(slist_header));
274     pInitializeSListHead(&slist_header);
275     size = pQueryDepthSList(&slist_header);
276     ok(size == 0, "initially created slist has size %d, expected 0\n", size);
277
278     item1.value = 1;
279     ok(pInterlockedPushEntrySList(&slist_header, &item1.entry) == NULL,
280         "previous entry in empty slist wasn't NULL\n");
281     size = pQueryDepthSList(&slist_header);
282     ok(size == 1, "slist with 1 item has size %d\n", size);
283
284     item2.value = 2;
285     entry = pInterlockedPushEntrySList(&slist_header, &item2.entry);
286     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
287     if (entry != NULL)
288     {
289         pitem = (struct item*) entry;
290         ok(pitem->value == 1, "previous entry in slist wasn't the one added\n");
291     }
292     size = pQueryDepthSList(&slist_header);
293     ok(size == 2, "slist with 2 items has size %d\n", size);
294
295     item3.value = 3;
296     entry = pInterlockedPushEntrySList(&slist_header, &item3.entry);
297     ok(entry != NULL, "previous entry in non-empty slist was NULL\n");
298     if (entry != NULL)
299     {
300         pitem = (struct item*) entry;
301         ok(pitem->value == 2, "previous entry in slist wasn't the one added\n");
302     }
303     size = pQueryDepthSList(&slist_header);
304     ok(size == 3, "slist with 3 items has size %d\n", size);
305
306     entry = pInterlockedPopEntrySList(&slist_header);
307     ok(entry != NULL, "entry shouldn't be NULL\n");
308     if (entry != NULL)
309     {
310         pitem = (struct item*) entry;
311         ok(pitem->value == 3, "unexpected entry removed\n");
312     }
313     size = pQueryDepthSList(&slist_header);
314     ok(size == 2, "slist with 2 items has size %d\n", size);
315
316     entry = pInterlockedFlushSList(&slist_header);
317     size = pQueryDepthSList(&slist_header);
318     ok(size == 0, "flushed slist should be empty, size is %d\n", size);
319     if (size == 0)
320     {
321         ok(pInterlockedPopEntrySList(&slist_header) == NULL,
322             "popping empty slist didn't return NULL\n");
323     }
324     ok(((struct item*)entry)->value == 2, "item 2 not in front of list\n");
325     ok(((struct item*)entry->Next)->value == 1, "item 1 not at the back of list\n");
326 }
327
328 static void test_event(void)
329 {
330     HANDLE handle, handle2;
331     SECURITY_ATTRIBUTES sa;
332     SECURITY_DESCRIPTOR sd;
333     ACL acl;
334     DWORD ret;
335     BOOL val;
336
337     /* no sd */
338     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
339     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
340     CloseHandle(handle);
341
342     sa.nLength = sizeof(sa);
343     sa.lpSecurityDescriptor = &sd;
344     sa.bInheritHandle = FALSE;
345
346     InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
347
348     /* blank sd */
349     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
350     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
351     CloseHandle(handle);
352
353     /* sd with NULL dacl */
354     SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
355     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
356     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
357     CloseHandle(handle);
358
359     /* sd with empty dacl */
360     InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
361     SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
362     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
363     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
364     CloseHandle(handle);
365
366     /* test case sensitivity */
367
368     SetLastError(0xdeadbeef);
369     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
370     ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
371     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
372
373     SetLastError(0xdeadbeef);
374     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
375     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
376     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
377     CloseHandle( handle2 );
378
379     SetLastError(0xdeadbeef);
380     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
381     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
382     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
383     CloseHandle( handle2 );
384
385     SetLastError(0xdeadbeef);
386     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
387     ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
388     CloseHandle( handle2 );
389
390     SetLastError(0xdeadbeef);
391     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
392     ok( !handle2, "OpenEvent succeeded\n");
393     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
394
395     CloseHandle( handle );
396
397     /* resource notifications are events too */
398
399     if (!pCreateMemoryResourceNotification || !pQueryMemoryResourceNotification)
400     {
401         trace( "memory resource notifications not supported\n" );
402         return;
403     }
404     handle = pCreateMemoryResourceNotification( HighMemoryResourceNotification + 1 );
405     ok( !handle, "CreateMemoryResourceNotification succeeded\n" );
406     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
407     ret = pQueryMemoryResourceNotification( handle, &val );
408     ok( !ret, "QueryMemoryResourceNotification succeeded\n" );
409     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
410
411     handle = pCreateMemoryResourceNotification( LowMemoryResourceNotification );
412     ok( handle != 0, "CreateMemoryResourceNotification failed err %u\n", GetLastError() );
413     ret = WaitForSingleObject( handle, 10 );
414     ok( ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT, "WaitForSingleObject wrong ret %u\n", ret );
415
416     val = ~0;
417     ret = pQueryMemoryResourceNotification( handle, &val );
418     ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
419     ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
420     ret = CloseHandle( handle );
421     ok( ret, "CloseHandle failed err %u\n", GetLastError() );
422
423     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
424     val = ~0;
425     ret = pQueryMemoryResourceNotification( handle, &val );
426     ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
427     ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
428     CloseHandle( handle );
429 }
430
431 static void test_semaphore(void)
432 {
433     HANDLE handle, handle2;
434
435     /* test case sensitivity */
436
437     SetLastError(0xdeadbeef);
438     handle = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
439     ok(handle != NULL, "CreateSemaphore failed with error %u\n", GetLastError());
440     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
441
442     SetLastError(0xdeadbeef);
443     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
444     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
445     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
446     CloseHandle( handle2 );
447
448     SetLastError(0xdeadbeef);
449     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": TEST SEMAPHORE");
450     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
451     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
452     CloseHandle( handle2 );
453
454     SetLastError(0xdeadbeef);
455     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": Test Semaphore");
456     ok( handle2 != NULL, "OpenSemaphore failed with error %d\n", GetLastError());
457     CloseHandle( handle2 );
458
459     SetLastError(0xdeadbeef);
460     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": TEST SEMAPHORE");
461     ok( !handle2, "OpenSemaphore succeeded\n");
462     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
463
464     CloseHandle( handle );
465 }
466
467 static void test_waitable_timer(void)
468 {
469     HANDLE handle, handle2;
470
471     if (!pCreateWaitableTimerA || !pOpenWaitableTimerA)
472     {
473         win_skip("{Create,Open}WaitableTimerA() is not available\n");
474         return;
475     }
476
477     /* test case sensitivity */
478
479     SetLastError(0xdeadbeef);
480     handle = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
481     ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
482     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
483
484     SetLastError(0xdeadbeef);
485     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
486     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
487     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
488     CloseHandle( handle2 );
489
490     SetLastError(0xdeadbeef);
491     handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
492     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
493     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
494     CloseHandle( handle2 );
495
496     SetLastError(0xdeadbeef);
497     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
498     ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
499     CloseHandle( handle2 );
500
501     SetLastError(0xdeadbeef);
502     handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
503     ok( !handle2, "OpenWaitableTimer succeeded\n");
504     ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
505         GetLastError() == ERROR_INVALID_NAME, /* win98 */
506         "wrong error %u\n", GetLastError());
507
508     CloseHandle( handle );
509 }
510
511 static HANDLE sem = 0;
512
513 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
514 {
515     ReleaseSemaphore(sem, 1, NULL);
516 }
517
518 static BOOL (WINAPI *p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
519
520 static void test_iocp_callback(void)
521 {
522     char temp_path[MAX_PATH];
523     char filename[MAX_PATH];
524     DWORD ret;
525     BOOL retb;
526     static const char prefix[] = "pfx";
527     HANDLE hFile;
528     HMODULE hmod = GetModuleHandleA("kernel32.dll");
529     DWORD bytesWritten;
530     const char *buffer = "12345678123456781234567812345678";
531     OVERLAPPED overlapped;
532
533     p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
534     if(!p_BindIoCompletionCallback) {
535         win_skip("BindIoCompletionCallback not found in this DLL\n");
536         return;
537     }
538
539     sem = CreateSemaphore(NULL, 0, 1, NULL);
540     ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
541
542     ret = GetTempPathA(MAX_PATH, temp_path);
543     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
544     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
545
546     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
547     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
548
549     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
550                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
551     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
552
553     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
554     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
555     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
556
557     ret = CloseHandle(hFile);
558     ok( ret, "CloseHandle: error %d\n", GetLastError());
559     ret = DeleteFileA(filename);
560     ok( ret, "DeleteFileA: error %d\n", GetLastError());
561
562     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
563                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
564     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
565
566     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
567     ok(retb == TRUE, "BindIoCompletionCallback failed\n");
568
569     memset(&overlapped, 0, sizeof(overlapped));
570     retb = WriteFile(hFile, buffer, 4, &bytesWritten, &overlapped);
571     ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
572
573     ret = WaitForSingleObject(sem, 5000);
574     ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
575     CloseHandle(sem);
576
577     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
578     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
579     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
580     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
581     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
582     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
583
584     ret = CloseHandle(hFile);
585     ok( ret, "CloseHandle: error %d\n", GetLastError());
586     ret = DeleteFileA(filename);
587     ok( ret, "DeleteFileA: error %d\n", GetLastError());
588
589     /* win2k3 requires the Flags parameter to be zero */
590     SetLastError(0xdeadbeef);
591     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
592                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
593     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
594     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
595     if (!retb)
596         ok(GetLastError() == ERROR_INVALID_PARAMETER,
597            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
598     else
599         ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
600     ret = CloseHandle(hFile);
601     ok( ret, "CloseHandle: error %d\n", GetLastError());
602     ret = DeleteFileA(filename);
603     ok( ret, "DeleteFileA: error %d\n", GetLastError());
604
605     retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
606     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
607     ok(GetLastError() == ERROR_INVALID_HANDLE ||
608        GetLastError() == ERROR_INVALID_PARAMETER, /* vista */
609        "Last error is %d\n", GetLastError());
610 }
611
612 static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut)
613 {
614     int *pn = p;
615     ok(timedOut, "Timer callbacks should always time out\n");
616     ++*pn;
617 }
618
619 struct timer_queue_data1
620 {
621     int num_calls;
622     int max_calls;
623     HANDLE q, t;
624 };
625
626 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
627 {
628     struct timer_queue_data1 *d = p;
629     ok(timedOut, "Timer callbacks should always time out\n");
630     if (d->t && ++d->num_calls == d->max_calls)
631     {
632         BOOL ret;
633         SetLastError(0xdeadbeef);
634         /* Note, XP SP2 does *not* do any deadlock checking, so passing
635            INVALID_HANDLE_VALUE here will just hang.  */
636         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
637         ok(!ret, "DeleteTimerQueueTimer\n");
638         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
639     }
640 }
641
642 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
643 {
644     struct timer_queue_data1 *d = p;
645     ok(timedOut, "Timer callbacks should always time out\n");
646     if (d->t && ++d->num_calls == d->max_calls)
647     {
648         /* Basically kill the timer since it won't have time to run
649            again.  */
650         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0);
651         ok(ret, "ChangeTimerQueueTimer\n");
652     }
653 }
654
655 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
656 {
657     struct timer_queue_data1 *d = p;
658     ok(timedOut, "Timer callbacks should always time out\n");
659     if (d->t)
660     {
661         /* This tests whether a timer gets flagged for deletion before
662            or after the callback runs.  If we start this timer with a
663            period of zero (run once), then ChangeTimerQueueTimer will
664            fail if the timer is already flagged.  Hence we really run
665            only once.  Otherwise we will run multiple times.  */
666         BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50);
667         ok(ret, "ChangeTimerQueueTimer\n");
668         ++d->num_calls;
669     }
670 }
671
672 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
673 {
674     DWORD_PTR delay = (DWORD_PTR) p;
675     ok(timedOut, "Timer callbacks should always time out\n");
676     if (delay)
677         Sleep(delay);
678 }
679
680 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
681 {
682     struct timer_queue_data1 *d = p;
683     ok(timedOut, "Timer callbacks should always time out\n");
684     /* This tests an original implementation bug where a deleted timer may get
685        to run, but it is tricky to set up.  */
686     if (d->q && d->num_calls++ == 0)
687     {
688         /* First run: delete ourselves, then insert and remove a timer
689            that goes in front of us in the sorted timeout list.  Once
690            removed, we will still timeout at the faster timer's due time,
691            but this should be a no-op if we are bug-free.  There should
692            not be a second run.  We can test the value of num_calls later.  */
693         BOOL ret;
694         HANDLE t;
695
696         /* The delete will pend while we are in this callback.  */
697         SetLastError(0xdeadbeef);
698         ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
699         ok(!ret, "DeleteTimerQueueTimer\n");
700         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
701
702         ret = pCreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
703         ok(ret, "CreateTimerQueueTimer\n");
704         ok(t != NULL, "CreateTimerQueueTimer\n");
705
706         ret = pDeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
707         ok(ret, "DeleteTimerQueueTimer\n");
708
709         /* Now we stay alive by hanging around in the callback.  */
710         Sleep(500);
711     }
712 }
713
714 static void test_timer_queue(void)
715 {
716     HANDLE q, t0, t1, t2, t3, t4, t5;
717     int n0, n1, n2, n3, n4, n5;
718     struct timer_queue_data1 d1, d2, d3, d4;
719     HANDLE e, et1, et2;
720     BOOL ret, ret0;
721
722     if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer
723         || !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer)
724     {
725         win_skip("TimerQueue API not present\n");
726         return;
727     }
728
729     /* Test asynchronous deletion of the queue. */
730     q = pCreateTimerQueue();
731     ok(q != NULL, "CreateTimerQueue\n");
732
733     SetLastError(0xdeadbeef);
734     ret = pDeleteTimerQueueEx(q, NULL);
735     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
736        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
737        GetLastError());
738
739     /* Test synchronous deletion of the queue and running timers. */
740     q = pCreateTimerQueue();
741     ok(q != NULL, "CreateTimerQueue\n");
742
743     /* Not called. */
744     t0 = NULL;
745     n0 = 0;
746     ret = pCreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0,
747                                  300, 0);
748     ok(ret, "CreateTimerQueueTimer\n");
749     ok(t0 != NULL, "CreateTimerQueueTimer\n");
750     ret0 = pDeleteTimerQueueTimer(q, t0, NULL);
751     ok((!ret0 && GetLastError() == ERROR_IO_PENDING) ||
752        broken(ret0), /* Win 2000 & XP & 2003 */
753        "DeleteTimerQueueTimer ret=%d le=%u\n", ret0, GetLastError());
754
755     /* Called once.  */
756     t1 = NULL;
757     n1 = 0;
758     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
759                                  0, 0);
760     ok(ret, "CreateTimerQueueTimer\n");
761     ok(t1 != NULL, "CreateTimerQueueTimer\n");
762
763     /* A slow one.  */
764     t2 = NULL;
765     n2 = 0;
766     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
767                                  100, 0);
768     ok(ret, "CreateTimerQueueTimer\n");
769     ok(t2 != NULL, "CreateTimerQueueTimer\n");
770
771     /* A fast one.  */
772     t3 = NULL;
773     n3 = 0;
774     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
775                                  10, 0);
776     ok(ret, "CreateTimerQueueTimer\n");
777     ok(t3 != NULL, "CreateTimerQueueTimer\n");
778
779     /* Start really late (it won't start).  */
780     t4 = NULL;
781     n4 = 0;
782     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
783                                  10, 0);
784     ok(ret, "CreateTimerQueueTimer\n");
785     ok(t4 != NULL, "CreateTimerQueueTimer\n");
786
787     /* Start soon, but delay so long it won't run again.  */
788     t5 = NULL;
789     n5 = 0;
790     ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
791                                  10000, 0);
792     ok(ret, "CreateTimerQueueTimer\n");
793     ok(t5 != NULL, "CreateTimerQueueTimer\n");
794
795     /* Give them a chance to do some work.  */
796     Sleep(500);
797
798     /* Test deleting a once-only timer.  */
799     ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
800     ok(ret, "DeleteTimerQueueTimer\n");
801
802     /* A periodic timer.  */
803     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
804     ok(ret, "DeleteTimerQueueTimer\n");
805
806     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
807     ok(ret, "DeleteTimerQueueEx\n");
808     todo_wine
809     ok(n0 == 1 || broken(ret0 && n0 == 0), "Timer callback 0 expected 1 got %d\n", n0);
810     ok(n1 == 1, "Timer callback 1 expected 1 got %d\n", n1);
811     ok(n2 < n3, "Timer callback 2 & 3 expected %d < %d\n", n2, n3);
812     ok(n4 == 0, "Timer callback 4 expected 0 got %d\n", n4);
813     ok(n5 == 1, "Timer callback 5 expected 1 got %d\n", n5);
814
815     /* Test synchronous deletion of the timer/queue with event trigger. */
816     e = CreateEvent(NULL, TRUE, FALSE, NULL);
817     et1 = CreateEvent(NULL, TRUE, FALSE, NULL);
818     et2 = CreateEvent(NULL, TRUE, FALSE, NULL);
819     if (!e || !et1 || !et2)
820     {
821         skip("Failed to create timer queue descruction event\n");
822         return;
823     }
824
825     q = pCreateTimerQueue();
826     ok(q != NULL, "CreateTimerQueue\n");
827
828     /* Run once and finish quickly (should be done when we delete it).  */
829     t1 = NULL;
830     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
831     ok(ret, "CreateTimerQueueTimer\n");
832     ok(t1 != NULL, "CreateTimerQueueTimer\n");
833
834     /* Run once and finish slowly (shouldn't be done when we delete it).  */
835     t2 = NULL;
836     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
837                                  0, 0);
838     ok(ret, "CreateTimerQueueTimer\n");
839     ok(t2 != NULL, "CreateTimerQueueTimer\n");
840
841     /* Run once and finish quickly (should be done when we delete it).  */
842     t3 = NULL;
843     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
844     ok(ret, "CreateTimerQueueTimer\n");
845     ok(t3 != NULL, "CreateTimerQueueTimer\n");
846
847     /* Run once and finish slowly (shouldn't be done when we delete it).  */
848     t4 = NULL;
849     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
850                                  0, 0);
851     ok(ret, "CreateTimerQueueTimer\n");
852     ok(t4 != NULL, "CreateTimerQueueTimer\n");
853
854     /* Give them a chance to start.  */
855     Sleep(400);
856
857     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
858        even if the timer is finished.  */
859     SetLastError(0xdeadbeef);
860     ret = pDeleteTimerQueueTimer(q, t1, NULL);
861     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
862        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
863        GetLastError());
864
865     SetLastError(0xdeadbeef);
866     ret = pDeleteTimerQueueTimer(q, t2, NULL);
867     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
868     ok(GetLastError() == ERROR_IO_PENDING,
869        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
870        GetLastError());
871
872     SetLastError(0xdeadbeef);
873     ret = pDeleteTimerQueueTimer(q, t3, et1);
874     ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
875     ok(GetLastError() == 0xdeadbeef,
876        "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
877        GetLastError());
878     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
879        "Timer destruction event not triggered\n");
880
881     SetLastError(0xdeadbeef);
882     ret = pDeleteTimerQueueTimer(q, t4, et2);
883     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
884     ok(GetLastError() == ERROR_IO_PENDING,
885        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
886        GetLastError());
887     ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
888        "Timer destruction event not triggered\n");
889
890     SetLastError(0xdeadbeef);
891     ret = pDeleteTimerQueueEx(q, e);
892     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
893        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
894        GetLastError());
895     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
896        "Queue destruction event not triggered\n");
897     CloseHandle(e);
898
899     /* Test deleting/changing a timer in execution.  */
900     q = pCreateTimerQueue();
901     ok(q != NULL, "CreateTimerQueue\n");
902
903     /* Test changing a once-only timer before it fires (this is allowed,
904        whereas after it fires you cannot).  */
905     n1 = 0;
906     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
907                                  0, 0);
908     ok(ret, "CreateTimerQueueTimer\n");
909     ok(t1 != NULL, "CreateTimerQueueTimer\n");
910     ret = pChangeTimerQueueTimer(q, t1, 0, 0);
911     ok(ret, "ChangeTimerQueueTimer\n");
912
913     d2.t = t2 = NULL;
914     d2.num_calls = 0;
915     d2.max_calls = 3;
916     d2.q = q;
917     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
918                                  10, 0);
919     d2.t = t2;
920     ok(ret, "CreateTimerQueueTimer\n");
921     ok(t2 != NULL, "CreateTimerQueueTimer\n");
922
923     d3.t = t3 = NULL;
924     d3.num_calls = 0;
925     d3.max_calls = 4;
926     d3.q = q;
927     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
928                                  10, 0);
929     d3.t = t3;
930     ok(ret, "CreateTimerQueueTimer\n");
931     ok(t3 != NULL, "CreateTimerQueueTimer\n");
932
933     d4.t = t4 = NULL;
934     d4.num_calls = 0;
935     d4.q = q;
936     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
937                                  0, 0);
938     d4.t = t4;
939     ok(ret, "CreateTimerQueueTimer\n");
940     ok(t4 != NULL, "CreateTimerQueueTimer\n");
941
942     Sleep(500);
943
944     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
945     ok(ret, "DeleteTimerQueueEx\n");
946     ok(n1 == 1, "ChangeTimerQueueTimer\n");
947     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
948     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
949     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
950
951     /* Test an obscure bug that was in the original implementation.  */
952     q = pCreateTimerQueue();
953     ok(q != NULL, "CreateTimerQueue\n");
954
955     /* All the work is done in the callback.  */
956     d1.t = t1 = NULL;
957     d1.num_calls = 0;
958     d1.q = q;
959     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
960                                  100, WT_EXECUTELONGFUNCTION);
961     d1.t = t1;
962     ok(ret, "CreateTimerQueueTimer\n");
963     ok(t1 != NULL, "CreateTimerQueueTimer\n");
964
965     Sleep(750);
966
967     SetLastError(0xdeadbeef);
968     ret = pDeleteTimerQueueEx(q, NULL);
969     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
970        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
971        GetLastError());
972     ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
973
974     /* Test functions on the default timer queue.  */
975     t1 = NULL;
976     n1 = 0;
977     ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
978                                  1000, 0);
979     ok(ret, "CreateTimerQueueTimer, default queue\n");
980     ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
981
982     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
983     ok(ret, "ChangeTimerQueueTimer, default queue\n");
984
985     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
986     ok(ret, "DeleteTimerQueueTimer, default queue\n");
987
988     /* Try mixing default and non-default queues.  Apparently this works.  */
989     q = pCreateTimerQueue();
990     ok(q != NULL, "CreateTimerQueue\n");
991
992     t1 = NULL;
993     n1 = 0;
994     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000,
995                                  1000, 0);
996     ok(ret, "CreateTimerQueueTimer\n");
997     ok(t1 != NULL, "CreateTimerQueueTimer\n");
998
999     t2 = NULL;
1000     n2 = 0;
1001     ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000,
1002                                  1000, 0);
1003     ok(ret, "CreateTimerQueueTimer\n");
1004     ok(t2 != NULL, "CreateTimerQueueTimer\n");
1005
1006     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1007     ok(ret, "ChangeTimerQueueTimer\n");
1008
1009     ret = pChangeTimerQueueTimer(q, t2, 2000, 2000);
1010     ok(ret, "ChangeTimerQueueTimer\n");
1011
1012     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1013     ok(ret, "DeleteTimerQueueTimer\n");
1014
1015     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
1016     ok(ret, "DeleteTimerQueueTimer\n");
1017
1018     /* Try to delete the default queue?  In any case: not allowed.  */
1019     SetLastError(0xdeadbeef);
1020     ret = pDeleteTimerQueueEx(NULL, NULL);
1021     ok(!ret, "DeleteTimerQueueEx call was expected to fail\n");
1022     ok(GetLastError() == ERROR_INVALID_HANDLE,
1023        "DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n",
1024        GetLastError());
1025
1026     SetLastError(0xdeadbeef);
1027     ret = pDeleteTimerQueueEx(q, NULL);
1028     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1029        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1030        GetLastError());
1031 }
1032
1033 static HANDLE modify_handle(HANDLE handle, DWORD modify)
1034 {
1035     DWORD tmp = HandleToULong(handle);
1036     tmp |= modify;
1037     return ULongToHandle(tmp);
1038 }
1039
1040 static void test_WaitForSingleObject(void)
1041 {
1042     HANDLE signaled, nonsignaled, invalid;
1043     DWORD ret;
1044
1045     signaled = CreateEventW(NULL, TRUE, TRUE, NULL);
1046     nonsignaled = CreateEventW(NULL, TRUE, FALSE, NULL);
1047     invalid = (HANDLE) 0xdeadbee0;
1048
1049     /* invalid handle with different values for lower 2 bits */
1050     SetLastError(0xdeadbeef);
1051     ret = WaitForSingleObject(invalid, 0);
1052     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1053     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1054
1055     SetLastError(0xdeadbeef);
1056     ret = WaitForSingleObject(modify_handle(invalid, 1), 0);
1057     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1058     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1059
1060     SetLastError(0xdeadbeef);
1061     ret = WaitForSingleObject(modify_handle(invalid, 2), 0);
1062     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1063     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1064
1065     SetLastError(0xdeadbeef);
1066     ret = WaitForSingleObject(modify_handle(invalid, 3), 0);
1067     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1068     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1069
1070     /* valid handle with different values for lower 2 bits */
1071     SetLastError(0xdeadbeef);
1072     ret = WaitForSingleObject(nonsignaled, 0);
1073     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1074     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1075
1076     SetLastError(0xdeadbeef);
1077     ret = WaitForSingleObject(modify_handle(nonsignaled, 1), 0);
1078     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1079     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1080
1081     SetLastError(0xdeadbeef);
1082     ret = WaitForSingleObject(modify_handle(nonsignaled, 2), 0);
1083     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1084     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1085
1086     SetLastError(0xdeadbeef);
1087     ret = WaitForSingleObject(modify_handle(nonsignaled, 3), 0);
1088     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1089     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1090
1091     /* valid handle with different values for lower 2 bits */
1092     SetLastError(0xdeadbeef);
1093     ret = WaitForSingleObject(signaled, 0);
1094     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1095     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1096
1097     SetLastError(0xdeadbeef);
1098     ret = WaitForSingleObject(modify_handle(signaled, 1), 0);
1099     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1100     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1101
1102     SetLastError(0xdeadbeef);
1103     ret = WaitForSingleObject(modify_handle(signaled, 2), 0);
1104     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1105     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1106
1107     SetLastError(0xdeadbeef);
1108     ret = WaitForSingleObject(modify_handle(signaled, 3), 0);
1109     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1110     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1111
1112     CloseHandle(signaled);
1113     CloseHandle(nonsignaled);
1114 }
1115
1116 static void test_WaitForMultipleObjects(void)
1117 {
1118     DWORD r;
1119     int i;
1120     HANDLE maxevents[MAXIMUM_WAIT_OBJECTS];
1121
1122     /* create the maximum number of events and make sure
1123      * we can wait on that many */
1124     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1125     {
1126         maxevents[i] = CreateEvent(NULL, i==0, TRUE, NULL);
1127         ok( maxevents[i] != 0, "should create enough events\n");
1128     }
1129
1130     /* a manual-reset event remains signaled, an auto-reset event is cleared */
1131     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, 0, 0);
1132     ok( r == WAIT_OBJECT_0, "should signal lowest handle first, got %d\n", r);
1133     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, 0, 0);
1134     ok( r == WAIT_OBJECT_0, "should signal handle #0 first, got %d\n", r);
1135     ok(ResetEvent(maxevents[0]), "ResetEvent\n");
1136     for (i=1; i<MAXIMUM_WAIT_OBJECTS; i++)
1137     {
1138         /* the lowest index is checked first and remaining events are untouched */
1139         r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, 0, 0);
1140         ok( r == WAIT_OBJECT_0+i, "should signal handle #%d first, got %d\n", i, r);
1141     }
1142
1143     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1144         if (maxevents[i]) CloseHandle(maxevents[i]);
1145 }
1146
1147 static BOOL g_initcallback_ret, g_initcallback_called;
1148 static void *g_initctxt;
1149
1150 static BOOL CALLBACK initonce_callback(INIT_ONCE *initonce, void *parameter, void **ctxt)
1151 {
1152     g_initcallback_called = TRUE;
1153     /* zero bit set means here that initialization is taking place - initialization locked */
1154     ok(g_initctxt == *ctxt, "got wrong context value %p, expected %p\n", *ctxt, g_initctxt);
1155     ok(initonce->Ptr == (void*)0x1, "got %p\n", initonce->Ptr);
1156     ok(parameter == (void*)0xdeadbeef, "got wrong parameter\n");
1157     return g_initcallback_ret;
1158 }
1159
1160 static void test_initonce(void)
1161 {
1162     INIT_ONCE initonce;
1163     BOOL ret, pending;
1164
1165     if (!pInitOnceInitialize || !pInitOnceExecuteOnce)
1166     {
1167         skip("one-time initialization API not supported\n");
1168         return;
1169     }
1170
1171     /* blocking initialization with callback */
1172     initonce.Ptr = (void*)0xdeadbeef;
1173     pInitOnceInitialize(&initonce);
1174     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1175
1176     /* initialisation completed successfully */
1177     g_initcallback_ret = TRUE;
1178     g_initctxt = NULL;
1179     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1180     ok(ret, "got wrong ret value %d\n", ret);
1181     ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
1182     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1183     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1184
1185     /* so it's been called already so won't be called again */
1186     g_initctxt = NULL;
1187     g_initcallback_called = FALSE;
1188     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1189     ok(ret, "got wrong ret value %d\n", ret);
1190     ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
1191     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1192     ok(!g_initcallback_called, "got %d\n", g_initcallback_called);
1193
1194     pInitOnceInitialize(&initonce);
1195     g_initcallback_called = FALSE;
1196     /* 2 lower order bits should never be used, you'll get a crash in result */
1197     g_initctxt = (void*)0xFFFFFFF0;
1198     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1199     ok(ret, "got wrong ret value %d\n", ret);
1200     ok(initonce.Ptr == (void*)0xFFFFFFF2, "got %p\n", initonce.Ptr);
1201     ok(g_initctxt == (void*)0xFFFFFFF0, "got %p\n", g_initctxt);
1202     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1203
1204     /* callback failed */
1205     g_initcallback_ret = FALSE;
1206     g_initcallback_called = FALSE;
1207     g_initctxt = NULL;
1208     pInitOnceInitialize(&initonce);
1209     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1210     ok(!ret, "got wrong ret value %d\n", ret);
1211     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1212     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1213     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1214
1215     /* blocking initialzation without a callback */
1216     pInitOnceInitialize(&initonce);
1217     g_initctxt = NULL;
1218     pending = FALSE;
1219     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1220     ok(ret, "got wrong ret value %d\n", ret);
1221     ok(pending, "got %d\n", pending);
1222     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1223     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1224     /* another attempt to begin initialization with block a single thread */
1225
1226     g_initctxt = NULL;
1227     pending = 0xf;
1228     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1229     ok(!ret, "got wrong ret value %d\n", ret);
1230     ok(pending == 0xf, "got %d\n", pending);
1231     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1232     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1233
1234     g_initctxt = (void*)0xdeadbee0;
1235     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, g_initctxt);
1236     ok(!ret, "got wrong ret value %d\n", ret);
1237     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1238
1239     /* once failed already */
1240     g_initctxt = (void*)0xdeadbee0;
1241     ret = pInitOnceComplete(&initonce, 0, g_initctxt);
1242     ok(ret, "got wrong ret value %d\n", ret);
1243     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1244 }
1245
1246 static CONDITION_VARIABLE buffernotempty,buffernotfull;
1247 static CRITICAL_SECTION   buffercrit;
1248 static BOOL condvar_stop = FALSE, condvar_sleeperr = FALSE;
1249 static LONG bufferlen,totalproduced,totalconsumed;
1250 static LONG condvar_producer_sleepcnt,condvar_consumer_sleepcnt;
1251
1252 #define BUFFER_SIZE 10
1253
1254 static DWORD WINAPI condvar_producer(LPVOID x) {
1255     while (1) {
1256         Sleep(rand() % 10);
1257
1258         EnterCriticalSection(&buffercrit);
1259         while ((bufferlen == BUFFER_SIZE) && !condvar_stop) {
1260             condvar_producer_sleepcnt++;
1261             if (!pSleepConditionVariableCS(&buffernotfull, &buffercrit, 2000))
1262                 condvar_sleeperr = TRUE;
1263         }
1264         if (condvar_stop) {
1265             LeaveCriticalSection(&buffercrit);
1266             break;
1267         }
1268         bufferlen++;
1269         totalproduced++;
1270         LeaveCriticalSection(&buffercrit);
1271         pWakeConditionVariable(&buffernotempty);
1272     }
1273     return 0;
1274 }
1275
1276 static DWORD WINAPI condvar_consumer(LPVOID x) {
1277     DWORD *cnt = (DWORD*)x;
1278
1279     while (1) {
1280         EnterCriticalSection(&buffercrit);
1281         while ((bufferlen == 0) && !condvar_stop) {
1282             condvar_consumer_sleepcnt++;
1283             if (!pSleepConditionVariableCS (&buffernotempty, &buffercrit, 2000))
1284                 condvar_sleeperr = TRUE;
1285         }
1286         if (condvar_stop && (bufferlen == 0)) {
1287             LeaveCriticalSection(&buffercrit);
1288             break;
1289         }
1290         bufferlen--;
1291         totalconsumed++;
1292         (*cnt)++;
1293         LeaveCriticalSection(&buffercrit);
1294         pWakeConditionVariable(&buffernotfull);
1295         Sleep(rand() % 10);
1296     }
1297     return 0;
1298 }
1299
1300 static void test_condvars(void)
1301 {
1302     HANDLE hp1,hp2,hc1,hc2;
1303     DWORD dummy;
1304     DWORD cnt1,cnt2;
1305
1306     if (!pInitializeConditionVariable) {
1307         /* function is not yet in XP, only in newer Windows */
1308         /* and not yet implemented in Wine for some days/weeks */
1309         todo_wine win_skip("no condition variable support.\n");
1310         return;
1311     }
1312
1313     /* Implement a producer / consumer scheme with non-full / non-empty triggers */
1314     pInitializeConditionVariable(&buffernotfull);
1315     pInitializeConditionVariable(&buffernotempty);
1316     InitializeCriticalSection(&buffercrit);
1317     bufferlen = totalproduced = totalconsumed = cnt1 = cnt2 = 0;
1318
1319     hp1 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1320     hp2 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1321     hc1 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt1, 0, &dummy);
1322     hc2 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt2, 0, &dummy);
1323
1324     /* Limit run to 0.5 seconds. */
1325     Sleep(500);
1326
1327     /* tear down start */
1328     condvar_stop = TRUE;
1329
1330     /* final wake up call */
1331     pWakeAllConditionVariable (&buffernotfull);
1332     pWakeAllConditionVariable (&buffernotempty);
1333
1334     WaitForSingleObject(hp1, 1000);
1335     WaitForSingleObject(hp2, 1000);
1336     WaitForSingleObject(hc1, 1000);
1337     WaitForSingleObject(hc2, 1000);
1338
1339     ok(totalconsumed == totalproduced,
1340        "consumed %d != produced %d\n", totalconsumed, totalproduced);
1341     ok (!condvar_sleeperr, "error occurred during SleepConditionVariableCS\n");
1342
1343     /* Checking cnt1 - cnt2 for non-0 would be not good, the case where
1344      * one consumer does not get anything to do is possible. */
1345     trace("produced %d, c1 %d, c2 %d\n", totalproduced, cnt1, cnt2);
1346     /* The sleeps of the producer or consumer should not go above 100* produced count,
1347      * otherwise the implementation does not sleep correctly. But yet again, this is
1348      * not hard defined. */
1349     trace("producer sleep %d, consumer sleep %d\n", condvar_producer_sleepcnt, condvar_consumer_sleepcnt);
1350 }
1351
1352 START_TEST(sync)
1353 {
1354     HMODULE hdll = GetModuleHandle("kernel32");
1355     pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
1356     pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
1357     pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
1358     pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
1359     pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
1360     pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
1361     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
1362     pCreateMemoryResourceNotification = (void *)GetProcAddress(hdll, "CreateMemoryResourceNotification");
1363     pQueryMemoryResourceNotification = (void *)GetProcAddress(hdll, "QueryMemoryResourceNotification");
1364     pInitOnceInitialize = (void *)GetProcAddress(hdll, "InitOnceInitialize");
1365     pInitOnceExecuteOnce = (void *)GetProcAddress(hdll, "InitOnceExecuteOnce");
1366     pInitOnceBeginInitialize = (void *)GetProcAddress(hdll, "InitOnceBeginInitialize");
1367     pInitOnceComplete = (void *)GetProcAddress(hdll, "InitOnceComplete");
1368     pInitializeConditionVariable = (void *)GetProcAddress(hdll, "InitializeConditionVariable");
1369     pSleepConditionVariableCS = (void *)GetProcAddress(hdll, "SleepConditionVariableCS");
1370     pWakeAllConditionVariable = (void *)GetProcAddress(hdll, "WakeAllConditionVariable");
1371     pWakeConditionVariable = (void *)GetProcAddress(hdll, "WakeConditionVariable");
1372
1373     test_signalandwait();
1374     test_mutex();
1375     test_slist();
1376     test_event();
1377     test_semaphore();
1378     test_waitable_timer();
1379     test_iocp_callback();
1380     test_timer_queue();
1381     test_WaitForSingleObject();
1382     test_WaitForMultipleObjects();
1383     test_initonce();
1384     test_condvars();
1385 }