kernel32/tests: Do not test GetLastError on success.
[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, t1, t2, t3, t4, t5;
708     int n1, n2, n3, n4, n5;
709     struct timer_queue_data1 d1, d2, d3, d4;
710     HANDLE e, et1, et2;
711     BOOL ret;
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     /* Called once.  */
735     t1 = NULL;
736     n1 = 0;
737     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
738                                  0, 0);
739     ok(ret, "CreateTimerQueueTimer\n");
740     ok(t1 != NULL, "CreateTimerQueueTimer\n");
741
742     /* A slow one.  */
743     t2 = NULL;
744     n2 = 0;
745     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
746                                  100, 0);
747     ok(ret, "CreateTimerQueueTimer\n");
748     ok(t2 != NULL, "CreateTimerQueueTimer\n");
749
750     /* A fast one.  */
751     t3 = NULL;
752     n3 = 0;
753     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
754                                  10, 0);
755     ok(ret, "CreateTimerQueueTimer\n");
756     ok(t3 != NULL, "CreateTimerQueueTimer\n");
757
758     /* Start really late (it won't start).  */
759     t4 = NULL;
760     n4 = 0;
761     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
762                                  10, 0);
763     ok(ret, "CreateTimerQueueTimer\n");
764     ok(t4 != NULL, "CreateTimerQueueTimer\n");
765
766     /* Start soon, but delay so long it won't run again.  */
767     t5 = NULL;
768     n5 = 0;
769     ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
770                                  10000, 0);
771     ok(ret, "CreateTimerQueueTimer\n");
772     ok(t5 != NULL, "CreateTimerQueueTimer\n");
773
774     /* Give them a chance to do some work.  */
775     Sleep(500);
776
777     /* Test deleting a once-only timer.  */
778     ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
779     ok(ret, "DeleteTimerQueueTimer\n");
780
781     /* A periodic timer.  */
782     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
783     ok(ret, "DeleteTimerQueueTimer\n");
784
785     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
786     ok(ret, "DeleteTimerQueueEx\n");
787     ok(n1 == 1, "Timer callback 1\n");
788     ok(n2 < n3, "Timer callback 2 should be much slower than 3\n");
789     ok(n4 == 0, "Timer callback 4\n");
790     ok(n5 == 1, "Timer callback 5\n");
791
792     /* Test synchronous deletion of the timer/queue with event trigger. */
793     e = CreateEvent(NULL, TRUE, FALSE, NULL);
794     et1 = CreateEvent(NULL, TRUE, FALSE, NULL);
795     et2 = CreateEvent(NULL, TRUE, FALSE, NULL);
796     if (!e || !et1 || !et2)
797     {
798         skip("Failed to create timer queue descruction event\n");
799         return;
800     }
801
802     q = pCreateTimerQueue();
803     ok(q != NULL, "CreateTimerQueue\n");
804
805     /* Run once and finish quickly (should be done when we delete it).  */
806     t1 = NULL;
807     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
808     ok(ret, "CreateTimerQueueTimer\n");
809     ok(t1 != NULL, "CreateTimerQueueTimer\n");
810
811     /* Run once and finish slowly (shouldn't be done when we delete it).  */
812     t2 = NULL;
813     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
814                                  0, 0);
815     ok(ret, "CreateTimerQueueTimer\n");
816     ok(t2 != NULL, "CreateTimerQueueTimer\n");
817
818     /* Run once and finish quickly (should be done when we delete it).  */
819     t3 = NULL;
820     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
821     ok(ret, "CreateTimerQueueTimer\n");
822     ok(t3 != NULL, "CreateTimerQueueTimer\n");
823
824     /* Run once and finish slowly (shouldn't be done when we delete it).  */
825     t4 = NULL;
826     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
827                                  0, 0);
828     ok(ret, "CreateTimerQueueTimer\n");
829     ok(t4 != NULL, "CreateTimerQueueTimer\n");
830
831     /* Give them a chance to start.  */
832     Sleep(400);
833
834     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
835        even if the timer is finished.  */
836     SetLastError(0xdeadbeef);
837     ret = pDeleteTimerQueueTimer(q, t1, NULL);
838     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
839        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
840        GetLastError());
841
842     SetLastError(0xdeadbeef);
843     ret = pDeleteTimerQueueTimer(q, t2, NULL);
844     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
845     ok(GetLastError() == ERROR_IO_PENDING,
846        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
847        GetLastError());
848
849     SetLastError(0xdeadbeef);
850     ret = pDeleteTimerQueueTimer(q, t3, et1);
851     ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
852     ok(GetLastError() == 0xdeadbeef,
853        "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
854        GetLastError());
855     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
856        "Timer destruction event not triggered\n");
857
858     SetLastError(0xdeadbeef);
859     ret = pDeleteTimerQueueTimer(q, t4, et2);
860     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
861     ok(GetLastError() == ERROR_IO_PENDING,
862        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
863        GetLastError());
864     ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
865        "Timer destruction event not triggered\n");
866
867     SetLastError(0xdeadbeef);
868     ret = pDeleteTimerQueueEx(q, e);
869     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
870        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
871        GetLastError());
872     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
873        "Queue destruction event not triggered\n");
874     CloseHandle(e);
875
876     /* Test deleting/changing a timer in execution.  */
877     q = pCreateTimerQueue();
878     ok(q != NULL, "CreateTimerQueue\n");
879
880     /* Test changing a once-only timer before it fires (this is allowed,
881        whereas after it fires you cannot).  */
882     n1 = 0;
883     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
884                                  0, 0);
885     ok(ret, "CreateTimerQueueTimer\n");
886     ok(t1 != NULL, "CreateTimerQueueTimer\n");
887     ret = pChangeTimerQueueTimer(q, t1, 0, 0);
888     ok(ret, "ChangeTimerQueueTimer\n");
889
890     d2.t = t2 = NULL;
891     d2.num_calls = 0;
892     d2.max_calls = 3;
893     d2.q = q;
894     ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
895                                  10, 0);
896     d2.t = t2;
897     ok(ret, "CreateTimerQueueTimer\n");
898     ok(t2 != NULL, "CreateTimerQueueTimer\n");
899
900     d3.t = t3 = NULL;
901     d3.num_calls = 0;
902     d3.max_calls = 4;
903     d3.q = q;
904     ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
905                                  10, 0);
906     d3.t = t3;
907     ok(ret, "CreateTimerQueueTimer\n");
908     ok(t3 != NULL, "CreateTimerQueueTimer\n");
909
910     d4.t = t4 = NULL;
911     d4.num_calls = 0;
912     d4.q = q;
913     ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
914                                  0, 0);
915     d4.t = t4;
916     ok(ret, "CreateTimerQueueTimer\n");
917     ok(t4 != NULL, "CreateTimerQueueTimer\n");
918
919     Sleep(500);
920
921     ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
922     ok(ret, "DeleteTimerQueueEx\n");
923     ok(n1 == 1, "ChangeTimerQueueTimer\n");
924     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
925     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
926     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
927
928     /* Test an obscure bug that was in the original implementation.  */
929     q = pCreateTimerQueue();
930     ok(q != NULL, "CreateTimerQueue\n");
931
932     /* All the work is done in the callback.  */
933     d1.t = t1 = NULL;
934     d1.num_calls = 0;
935     d1.q = q;
936     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
937                                  100, WT_EXECUTELONGFUNCTION);
938     d1.t = t1;
939     ok(ret, "CreateTimerQueueTimer\n");
940     ok(t1 != NULL, "CreateTimerQueueTimer\n");
941
942     Sleep(750);
943
944     SetLastError(0xdeadbeef);
945     ret = pDeleteTimerQueueEx(q, NULL);
946     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
947        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
948        GetLastError());
949     ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
950
951     /* Test functions on the default timer queue.  */
952     t1 = NULL;
953     n1 = 0;
954     ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
955                                  1000, 0);
956     ok(ret, "CreateTimerQueueTimer, default queue\n");
957     ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
958
959     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
960     ok(ret, "ChangeTimerQueueTimer, default queue\n");
961
962     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
963     ok(ret, "DeleteTimerQueueTimer, default queue\n");
964
965     /* Try mixing default and non-default queues.  Apparently this works.  */
966     q = pCreateTimerQueue();
967     ok(q != NULL, "CreateTimerQueue\n");
968
969     t1 = NULL;
970     n1 = 0;
971     ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000,
972                                  1000, 0);
973     ok(ret, "CreateTimerQueueTimer\n");
974     ok(t1 != NULL, "CreateTimerQueueTimer\n");
975
976     t2 = NULL;
977     n2 = 0;
978     ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000,
979                                  1000, 0);
980     ok(ret, "CreateTimerQueueTimer\n");
981     ok(t2 != NULL, "CreateTimerQueueTimer\n");
982
983     ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
984     ok(ret, "ChangeTimerQueueTimer\n");
985
986     ret = pChangeTimerQueueTimer(q, t2, 2000, 2000);
987     ok(ret, "ChangeTimerQueueTimer\n");
988
989     ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
990     ok(ret, "DeleteTimerQueueTimer\n");
991
992     ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
993     ok(ret, "DeleteTimerQueueTimer\n");
994
995     /* Try to delete the default queue?  In any case: not allowed.  */
996     SetLastError(0xdeadbeef);
997     ret = pDeleteTimerQueueEx(NULL, NULL);
998     ok(!ret, "DeleteTimerQueueEx call was expected to fail\n");
999     ok(GetLastError() == ERROR_INVALID_HANDLE,
1000        "DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n",
1001        GetLastError());
1002
1003     SetLastError(0xdeadbeef);
1004     ret = pDeleteTimerQueueEx(q, NULL);
1005     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1006        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1007        GetLastError());
1008 }
1009
1010 static HANDLE modify_handle(HANDLE handle, DWORD modify)
1011 {
1012     DWORD tmp = HandleToULong(handle);
1013     tmp |= modify;
1014     return ULongToHandle(tmp);
1015 }
1016
1017 static void test_WaitForSingleObject(void)
1018 {
1019     HANDLE signaled, nonsignaled, invalid;
1020     DWORD ret;
1021
1022     signaled = CreateEventW(NULL, TRUE, TRUE, NULL);
1023     nonsignaled = CreateEventW(NULL, TRUE, FALSE, NULL);
1024     invalid = (HANDLE) 0xdeadbee0;
1025
1026     /* invalid handle with different values for lower 2 bits */
1027     SetLastError(0xdeadbeef);
1028     ret = WaitForSingleObject(invalid, 0);
1029     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1030     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1031
1032     SetLastError(0xdeadbeef);
1033     ret = WaitForSingleObject(modify_handle(invalid, 1), 0);
1034     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1035     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1036
1037     SetLastError(0xdeadbeef);
1038     ret = WaitForSingleObject(modify_handle(invalid, 2), 0);
1039     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1040     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1041
1042     SetLastError(0xdeadbeef);
1043     ret = WaitForSingleObject(modify_handle(invalid, 3), 0);
1044     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1045     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1046
1047     /* valid handle with different values for lower 2 bits */
1048     SetLastError(0xdeadbeef);
1049     ret = WaitForSingleObject(nonsignaled, 0);
1050     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1051     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1052
1053     SetLastError(0xdeadbeef);
1054     ret = WaitForSingleObject(modify_handle(nonsignaled, 1), 0);
1055     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1056     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1057
1058     SetLastError(0xdeadbeef);
1059     ret = WaitForSingleObject(modify_handle(nonsignaled, 2), 0);
1060     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1061     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1062
1063     SetLastError(0xdeadbeef);
1064     ret = WaitForSingleObject(modify_handle(nonsignaled, 3), 0);
1065     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1066     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1067
1068     /* valid handle with different values for lower 2 bits */
1069     SetLastError(0xdeadbeef);
1070     ret = WaitForSingleObject(signaled, 0);
1071     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1072     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1073
1074     SetLastError(0xdeadbeef);
1075     ret = WaitForSingleObject(modify_handle(signaled, 1), 0);
1076     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1077     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1078
1079     SetLastError(0xdeadbeef);
1080     ret = WaitForSingleObject(modify_handle(signaled, 2), 0);
1081     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1082     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1083
1084     SetLastError(0xdeadbeef);
1085     ret = WaitForSingleObject(modify_handle(signaled, 3), 0);
1086     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1087     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1088
1089     CloseHandle(signaled);
1090     CloseHandle(nonsignaled);
1091 }
1092
1093 static void test_WaitForMultipleObjects(void)
1094 {
1095     DWORD r;
1096     int i;
1097     HANDLE maxevents[MAXIMUM_WAIT_OBJECTS];
1098
1099     /* create the maximum number of events and make sure
1100      * we can wait on that many */
1101     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1102     {
1103         maxevents[i] = CreateEvent(NULL, i==0, TRUE, NULL);
1104         ok( maxevents[i] != 0, "should create enough events\n");
1105     }
1106
1107     /* a manual-reset event remains signaled, an auto-reset event is cleared */
1108     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, 0, 0);
1109     ok( r == WAIT_OBJECT_0, "should signal lowest handle first, got %d\n", r);
1110     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, 0, 0);
1111     ok( r == WAIT_OBJECT_0, "should signal handle #0 first, got %d\n", r);
1112     ok(ResetEvent(maxevents[0]), "ResetEvent\n");
1113     for (i=1; i<MAXIMUM_WAIT_OBJECTS; i++)
1114     {
1115         /* the lowest index is checked first and remaining events are untouched */
1116         r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, 0, 0);
1117         ok( r == WAIT_OBJECT_0+i, "should signal handle #%d first, got %d\n", i, r);
1118     }
1119
1120     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1121         if (maxevents[i]) CloseHandle(maxevents[i]);
1122 }
1123
1124 START_TEST(sync)
1125 {
1126     HMODULE hdll = GetModuleHandle("kernel32");
1127     pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
1128     pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
1129     pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
1130     pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
1131     pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
1132     pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
1133     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
1134     pCreateMemoryResourceNotification = (void *)GetProcAddress(hdll, "CreateMemoryResourceNotification");
1135     pQueryMemoryResourceNotification = (void *)GetProcAddress(hdll, "QueryMemoryResourceNotification");
1136
1137     test_signalandwait();
1138     test_mutex();
1139     test_slist();
1140     test_event();
1141     test_semaphore();
1142     test_waitable_timer();
1143     test_iocp_callback();
1144     test_timer_queue();
1145     test_WaitForSingleObject();
1146     test_WaitForMultipleObjects();
1147 }