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