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