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