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 #ifndef __REACTOS__
22 #define _WIN32_WINNT 0x500
23 #endif
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <windef.h>
28 #include <winbase.h>
29 #include <winternl.h>
30 
31 #include "wine/test.h"
32 
33 #ifdef __REACTOS__
34 #define QueryDepthSList(x) RtlQueryDepthSList(x)
35 #define InterlockedPushEntrySList(x,y) RtlInterlockedPushEntrySList(x,y)
36 #define InterlockedPopEntrySList(x) RtlInterlockedPopEntrySList(x)
37 #define InterlockedFlushSList(x) RtlInterlockedFlushSList(x)
38 #endif
39 
40 #undef __fastcall
41 #define __fastcall __stdcall
42 
43 static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFICATION_TYPE);
44 static BOOL   (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL);
45 static VOID   (WINAPI *pInitOnceInitialize)(PINIT_ONCE);
46 static BOOL   (WINAPI *pInitOnceExecuteOnce)(PINIT_ONCE,PINIT_ONCE_FN,PVOID,LPVOID*);
47 static BOOL   (WINAPI *pInitOnceBeginInitialize)(PINIT_ONCE,DWORD,BOOL*,LPVOID*);
48 static BOOL   (WINAPI *pInitOnceComplete)(PINIT_ONCE,DWORD,LPVOID);
49 
50 static VOID   (WINAPI *pInitializeConditionVariable)(PCONDITION_VARIABLE);
51 static BOOL   (WINAPI *pSleepConditionVariableCS)(PCONDITION_VARIABLE,PCRITICAL_SECTION,DWORD);
52 static BOOL   (WINAPI *pSleepConditionVariableSRW)(PCONDITION_VARIABLE,PSRWLOCK,DWORD,ULONG);
53 static VOID   (WINAPI *pWakeAllConditionVariable)(PCONDITION_VARIABLE);
54 static VOID   (WINAPI *pWakeConditionVariable)(PCONDITION_VARIABLE);
55 
56 static VOID   (WINAPI *pInitializeSRWLock)(PSRWLOCK);
57 static VOID   (WINAPI *pAcquireSRWLockExclusive)(PSRWLOCK);
58 static VOID   (WINAPI *pAcquireSRWLockShared)(PSRWLOCK);
59 static VOID   (WINAPI *pReleaseSRWLockExclusive)(PSRWLOCK);
60 static VOID   (WINAPI *pReleaseSRWLockShared)(PSRWLOCK);
61 static BOOLEAN (WINAPI *pTryAcquireSRWLockExclusive)(PSRWLOCK);
62 static BOOLEAN (WINAPI *pTryAcquireSRWLockShared)(PSRWLOCK);
63 
64 static NTSTATUS (WINAPI *pNtAllocateVirtualMemory)(HANDLE, PVOID *, ULONG, SIZE_T *, ULONG, ULONG);
65 static NTSTATUS (WINAPI *pNtFreeVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG);
66 static NTSTATUS (WINAPI *pNtWaitForSingleObject)(HANDLE, BOOLEAN, const LARGE_INTEGER *);
67 static NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*);
68 static PSLIST_ENTRY (__fastcall *pRtlInterlockedPushListSList)(PSLIST_HEADER list, PSLIST_ENTRY first,
69                                                                PSLIST_ENTRY last, ULONG count);
70 static PSLIST_ENTRY (WINAPI *pRtlInterlockedPushListSListEx)(PSLIST_HEADER list, PSLIST_ENTRY first,
71                                                              PSLIST_ENTRY last, ULONG count);
72 
73 #ifdef __i386__
74 
75 #include "pshpack1.h"
76 struct fastcall_thunk
77 {
78     BYTE pop_edx;   /* popl %edx            (ret addr) */
79     BYTE pop_eax;   /* popl %eax            (func) */
80     BYTE pop_ecx;   /* popl %ecx            (param 1) */
81     BYTE xchg[3];   /* xchgl (%esp),%edx    (param 2) */
82     WORD jmp_eax;   /* jmp  *%eax */
83 };
84 #include "poppack.h"
85 
86 static void * (WINAPI *call_fastcall_func4)(void *func, const void *a, const void *b, const void *c, const void *d);
87 
88 static void init_fastcall_thunk(void)
89 {
90     struct fastcall_thunk *thunk = VirtualAlloc(NULL, sizeof(*thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
91     thunk->pop_edx = 0x5a;      /* popl  %edx */
92     thunk->pop_eax = 0x58;      /* popl  %eax */
93     thunk->pop_ecx = 0x59;      /* popl  %ecx */
94     thunk->xchg[0] = 0x87;      /* xchgl (%esp),%edx */
95     thunk->xchg[1] = 0x14;
96     thunk->xchg[2] = 0x24;
97     thunk->jmp_eax = 0xe0ff;    /* jmp *%eax */
98     call_fastcall_func4 = (void *)thunk;
99 }
100 
101 #define call_func4(func, a, b, c, d) call_fastcall_func4(func, (const void *)(a), \
102         (const void *)(b), (const void *)(c), (const void *)(d))
103 
104 #else  /* __i386__ */
105 
106 #define init_fastcall_thunk() do { } while(0)
107 #define call_func4(func, a, b, c, d) func(a, b, c, d)
108 
109 #endif /* __i386__ */
110 
111 static void test_signalandwait(void)
112 {
113     DWORD r;
114     HANDLE event[2], semaphore[2], file;
115     int i;
116 
117     /* invalid parameters */
118     r = SignalObjectAndWait(NULL, NULL, 0, 0);
119     ok( r == WAIT_FAILED, "should fail\n");
120 
121     event[0] = CreateEventW(NULL, 0, 0, NULL);
122     event[1] = CreateEventW(NULL, 1, 1, NULL);
123 
124     ok( event[0] && event[1], "failed to create event flags\n");
125 
126     r = SignalObjectAndWait(event[0], NULL, 0, FALSE);
127     ok( r == WAIT_FAILED, "should fail\n");
128 
129     r = SignalObjectAndWait(NULL, event[0], 0, FALSE);
130     ok( r == WAIT_FAILED, "should fail\n");
131 
132 
133     /* valid parameters */
134     r = SignalObjectAndWait(event[0], event[1], 0, FALSE);
135     ok( r == WAIT_OBJECT_0, "should succeed\n");
136 
137     /* event[0] is now signalled - we repeat this test multiple times
138      * to ensure that the wineserver handles this situation properly. */
139     for (i = 0; i < 10000; i++)
140     {
141         r = SignalObjectAndWait(event[0], event[0], 0, FALSE);
142         ok(r == WAIT_OBJECT_0, "should succeed\n");
143     }
144 
145     /* event[0] is not signalled */
146     r = WaitForSingleObject(event[0], 0);
147     ok( r == WAIT_TIMEOUT, "event was signalled\n");
148 
149     r = SignalObjectAndWait(event[0], event[0], 0, FALSE);
150     ok( r == WAIT_OBJECT_0, "should succeed\n");
151 
152     /* clear event[1] and check for a timeout */
153     ok(ResetEvent(event[1]), "failed to clear event[1]\n");
154     r = SignalObjectAndWait(event[0], event[1], 0, FALSE);
155     ok( r == WAIT_TIMEOUT, "should timeout\n");
156 
157     CloseHandle(event[0]);
158     CloseHandle(event[1]);
159 
160     /* semaphores */
161     semaphore[0] = CreateSemaphoreW( NULL, 0, 1, NULL );
162     semaphore[1] = CreateSemaphoreW( NULL, 1, 1, NULL );
163     ok( semaphore[0] && semaphore[1], "failed to create semaphore\n");
164 
165     r = SignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
166     ok( r == WAIT_OBJECT_0, "should succeed\n");
167 
168     r = SignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
169     ok( r == WAIT_FAILED, "should fail\n");
170 
171     r = ReleaseSemaphore(semaphore[0],1,NULL);
172     ok( r == FALSE, "should fail\n");
173 
174     r = ReleaseSemaphore(semaphore[1],1,NULL);
175     ok( r == TRUE, "should succeed\n");
176 
177     CloseHandle(semaphore[0]);
178     CloseHandle(semaphore[1]);
179 
180     /* try a registry key */
181     file = CreateFileA("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
182         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
183     r = SignalObjectAndWait(file, file, 0, FALSE);
184     ok( r == WAIT_FAILED, "should fail\n");
185     ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n");
186     CloseHandle(file);
187 }
188 
189 static void test_mutex(void)
190 {
191     DWORD wait_ret;
192     BOOL ret;
193     HANDLE hCreated;
194     HANDLE hOpened;
195     int i;
196     DWORD failed = 0;
197 
198     SetLastError(0xdeadbeef);
199     hOpened = OpenMutexA(0, FALSE, "WineTestMutex");
200     ok(hOpened == NULL, "OpenMutex succeeded\n");
201     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
202 
203     SetLastError(0xdeadbeef);
204     hCreated = CreateMutexA(NULL, FALSE, "WineTestMutex");
205     ok(hCreated != NULL, "CreateMutex failed with error %d\n", GetLastError());
206 
207     SetLastError(0xdeadbeef);
208     hOpened = OpenMutexA(0, FALSE, "WineTestMutex");
209 todo_wine
210     ok(hOpened == NULL, "OpenMutex succeeded\n");
211 todo_wine
212     ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError());
213 
214     SetLastError(0xdeadbeef);
215     hOpened = OpenMutexA(GENERIC_EXECUTE, FALSE, "WineTestMutex");
216     ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
217     wait_ret = WaitForSingleObject(hOpened, INFINITE);
218     ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error %d\n", GetLastError());
219     CloseHandle(hOpened);
220 
221     for(i=0; i < 31; i++)
222     {
223         wait_ret = WaitForSingleObject(hCreated, INFINITE);
224         ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error 0x%08x\n", wait_ret);
225     }
226 
227     SetLastError(0xdeadbeef);
228     hOpened = OpenMutexA(GENERIC_READ | GENERIC_WRITE, FALSE, "WineTestMutex");
229     ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
230     wait_ret = WaitForSingleObject(hOpened, INFINITE);
231     ok(wait_ret == WAIT_FAILED, "WaitForSingleObject succeeded\n");
232     CloseHandle(hOpened);
233 
234     for (i = 0; i < 32; i++)
235     {
236         SetLastError(0xdeadbeef);
237         hOpened = OpenMutexA(0x1 << i, FALSE, "WineTestMutex");
238         if(hOpened != NULL)
239         {
240             SetLastError(0xdeadbeef);
241             ret = ReleaseMutex(hOpened);
242             ok(ret, "ReleaseMutex failed with error %d, access %x\n", GetLastError(), 1 << i);
243             CloseHandle(hOpened);
244         }
245         else
246         {
247             if ((1 << i) == ACCESS_SYSTEM_SECURITY)
248                 todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "wrong error %u, access %x\n", GetLastError(), 1 << i);
249             else
250                 todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u, , access %x\n", GetLastError(), 1 << i);
251             ReleaseMutex(hCreated);
252             failed |=0x1 << i;
253         }
254     }
255 
256 todo_wine
257     ok( failed == 0x0de0fffe, "open succeeded when it shouldn't: %x\n", failed);
258 
259     SetLastError(0xdeadbeef);
260     ret = ReleaseMutex(hCreated);
261     ok(!ret && (GetLastError() == ERROR_NOT_OWNER),
262         "ReleaseMutex should have failed with ERROR_NOT_OWNER instead of %d\n", GetLastError());
263 
264     /* test case sensitivity */
265 
266     SetLastError(0xdeadbeef);
267     hOpened = OpenMutexA(READ_CONTROL, FALSE, "WINETESTMUTEX");
268     ok(!hOpened, "OpenMutex succeeded\n");
269     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
270 
271     SetLastError(0xdeadbeef);
272     hOpened = OpenMutexA(READ_CONTROL, FALSE, "winetestmutex");
273     ok(!hOpened, "OpenMutex succeeded\n");
274     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
275 
276     SetLastError(0xdeadbeef);
277     hOpened = OpenMutexA(READ_CONTROL, FALSE, NULL);
278     ok(!hOpened, "OpenMutex succeeded\n");
279     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
280 
281     SetLastError(0xdeadbeef);
282     hOpened = OpenMutexW(READ_CONTROL, FALSE, NULL);
283     ok(!hOpened, "OpenMutex succeeded\n");
284     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
285 
286     SetLastError(0xdeadbeef);
287     hOpened = CreateMutexA(NULL, FALSE, "WineTestMutex");
288     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
289     ok(GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
290     CloseHandle(hOpened);
291 
292     SetLastError(0xdeadbeef);
293     hOpened = CreateMutexA(NULL, FALSE, "WINETESTMUTEX");
294     ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
295     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
296     CloseHandle(hOpened);
297 
298     CloseHandle(hCreated);
299 }
300 
301 static void test_slist(void)
302 {
303     struct item
304     {
305         SLIST_ENTRY entry;
306         int value;
307     } item1, item2, item3, *item;
308     SLIST_HEADER slist_header;
309     SLIST_ENTRY *entry;
310     USHORT size;
311     int i;
312 
313     item1.value = 1;
314     item2.value = 2;
315     item3.value = 3;
316 
317     memset(&slist_header, 0xff, sizeof(slist_header));
318     InitializeSListHead(&slist_header);
319     size = QueryDepthSList(&slist_header);
320     ok(size == 0, "Expected size == 0, got %u\n", size);
321 
322     /* test PushEntry, PopEntry and Flush */
323     entry = InterlockedPushEntrySList(&slist_header, &item1.entry);
324     ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
325     size = QueryDepthSList(&slist_header);
326     ok(size == 1, "Expected size == 1, got %u\n", size);
327 
328     entry = InterlockedPushEntrySList(&slist_header, &item2.entry);
329     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
330     item = CONTAINING_RECORD(entry, struct item, entry);
331     ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
332     size = QueryDepthSList(&slist_header);
333     ok(size == 2, "Expected size == 2, got %u\n", size);
334 
335     entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
336     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
337     item = CONTAINING_RECORD(entry, struct item, entry);
338     ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
339     size = QueryDepthSList(&slist_header);
340     ok(size == 3, "Expected size == 3, got %u\n", size);
341 
342     entry = InterlockedPopEntrySList(&slist_header);
343     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
344     item = CONTAINING_RECORD(entry, struct item, entry);
345     ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
346     size = QueryDepthSList(&slist_header);
347     ok(size == 2, "Expected size == 2, got %u\n", size);
348 
349     entry = InterlockedFlushSList(&slist_header);
350     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
351     item = CONTAINING_RECORD(entry, struct item, entry);
352     ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
353     item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
354     ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
355     size = QueryDepthSList(&slist_header);
356     ok(size == 0, "Expected size == 0, got %u\n", size);
357     entry = InterlockedPopEntrySList(&slist_header);
358     ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
359 
360     /* test RtlInterlockedPushListSList */
361     entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
362     ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
363     entry = call_func4(pRtlInterlockedPushListSList, &slist_header, &item2.entry, &item1.entry, 42);
364     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
365     item = CONTAINING_RECORD(entry, struct item, entry);
366     ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
367     size = QueryDepthSList(&slist_header);
368     ok(size == 43, "Expected size == 43, got %u\n", size);
369 
370     entry = InterlockedPopEntrySList(&slist_header);
371     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
372     item = CONTAINING_RECORD(entry, struct item, entry);
373     ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
374     size = QueryDepthSList(&slist_header);
375     ok(size == 42, "Expected size == 42, got %u\n", size);
376 
377     entry = InterlockedPopEntrySList(&slist_header);
378     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
379     item = CONTAINING_RECORD(entry, struct item, entry);
380     ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
381     size = QueryDepthSList(&slist_header);
382     ok(size == 41, "Expected size == 41, got %u\n", size);
383 
384     entry = InterlockedPopEntrySList(&slist_header);
385     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
386     item = CONTAINING_RECORD(entry, struct item, entry);
387     ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
388     size = QueryDepthSList(&slist_header);
389     ok(size == 40, "Expected size == 40, got %u\n", size);
390 
391     entry = InterlockedPopEntrySList(&slist_header);
392     ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
393     size = QueryDepthSList(&slist_header);
394     ok(size == 40, "Expected size == 40, got %u\n", size);
395 
396     entry = InterlockedFlushSList(&slist_header);
397     ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
398     size = QueryDepthSList(&slist_header);
399     ok(size == 40 || broken(size == 0) /* >= Win 8 */, "Expected size == 40, got %u\n", size);
400 
401     entry = InterlockedPushEntrySList(&slist_header, &item1.entry);
402     ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
403     entry = InterlockedFlushSList(&slist_header);
404     ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
405     item = CONTAINING_RECORD(entry, struct item, entry);
406     ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
407     size = QueryDepthSList(&slist_header);
408     ok(size == 0, "Expected size == 0, got %u\n", size);
409 
410     /* test RtlInterlockedPushListSListEx */
411     if (pRtlInterlockedPushListSListEx)
412     {
413         entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
414         ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
415         entry = pRtlInterlockedPushListSListEx(&slist_header, &item2.entry, &item1.entry, 42);
416         ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
417         item = CONTAINING_RECORD(entry, struct item, entry);
418         ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
419         size = QueryDepthSList(&slist_header);
420         ok(size == 43, "Expected size == 43, got %u\n", size);
421 
422         entry = InterlockedFlushSList(&slist_header);
423         ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
424         item = CONTAINING_RECORD(entry, struct item, entry);
425         ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
426         item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
427         ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
428         item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
429         ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
430         size = QueryDepthSList(&slist_header);
431         ok(size == 0, "Expected size == 0, got %u\n", size);
432     }
433     else
434         win_skip("RtlInterlockedPushListSListEx not available, skipping tests\n");
435 
436     /* test with a lot of items */
437     for (i = 0; i < 65536; i++)
438     {
439         item = HeapAlloc(GetProcessHeap(), 0, sizeof(*item));
440         item->value = i + 1;
441         entry = InterlockedPushEntrySList(&slist_header, &item->entry);
442         if (i)
443         {
444             ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
445             item = CONTAINING_RECORD(entry, struct item, entry);
446             ok(item->value == i, "Expected item->value == %u, got %u\n", i, item->value);
447         }
448         else
449         {
450             ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
451         }
452         size = QueryDepthSList(&slist_header);
453         ok(size == ((i + 1) & 0xffff), "Expected size == %u, got %u\n", (i + 1) & 0xffff, size);
454     }
455 
456     entry = InterlockedFlushSList(&slist_header);
457     for (i = 65536; i > 0; i--)
458     {
459         ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
460         item = CONTAINING_RECORD(entry, struct item, entry);
461         ok(item->value == i, "Expected item->value == %u, got %u\n", i, item->value);
462         entry = item->entry.Next;
463         HeapFree(GetProcessHeap(), 0, item);
464     }
465     ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
466     size = QueryDepthSList(&slist_header);
467     ok(size == 0, "Expected size == 0, got %u\n", size);
468     entry = InterlockedPopEntrySList(&slist_header);
469     ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
470 }
471 
472 static void test_event(void)
473 {
474     HANDLE handle, handle2;
475     SECURITY_ATTRIBUTES sa;
476     SECURITY_DESCRIPTOR sd;
477     ACL acl;
478     DWORD ret;
479     BOOL val;
480 
481     /* no sd */
482     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
483     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
484     CloseHandle(handle);
485 
486     sa.nLength = sizeof(sa);
487     sa.lpSecurityDescriptor = &sd;
488     sa.bInheritHandle = FALSE;
489 
490     InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
491 
492     /* blank sd */
493     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
494     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
495     CloseHandle(handle);
496 
497     /* sd with NULL dacl */
498     SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
499     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
500     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
501     CloseHandle(handle);
502 
503     /* sd with empty dacl */
504     InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
505     SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
506     handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
507     ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
508     CloseHandle(handle);
509 
510     /* test case sensitivity */
511 
512     SetLastError(0xdeadbeef);
513     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
514     ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
515     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
516 
517     SetLastError(0xdeadbeef);
518     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
519     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
520     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
521     CloseHandle( handle2 );
522 
523     SetLastError(0xdeadbeef);
524     handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
525     ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
526     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
527     CloseHandle( handle2 );
528 
529     SetLastError(0xdeadbeef);
530     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
531     ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
532     CloseHandle( handle2 );
533 
534     SetLastError(0xdeadbeef);
535     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
536     ok( !handle2, "OpenEvent succeeded\n");
537     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
538 
539     SetLastError(0xdeadbeef);
540     handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, NULL );
541     ok( !handle2, "OpenEvent succeeded\n");
542     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
543 
544     SetLastError(0xdeadbeef);
545     handle2 = OpenEventW( EVENT_ALL_ACCESS, FALSE, NULL );
546     ok( !handle2, "OpenEvent succeeded\n");
547     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
548 
549     CloseHandle( handle );
550 
551     /* resource notifications are events too */
552 
553     if (!pCreateMemoryResourceNotification || !pQueryMemoryResourceNotification)
554     {
555         trace( "memory resource notifications not supported\n" );
556         return;
557     }
558     handle = pCreateMemoryResourceNotification( HighMemoryResourceNotification + 1 );
559     ok( !handle, "CreateMemoryResourceNotification succeeded\n" );
560     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
561     ret = pQueryMemoryResourceNotification( handle, &val );
562     ok( !ret, "QueryMemoryResourceNotification succeeded\n" );
563     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
564 
565     handle = pCreateMemoryResourceNotification( LowMemoryResourceNotification );
566     ok( handle != 0, "CreateMemoryResourceNotification failed err %u\n", GetLastError() );
567     ret = WaitForSingleObject( handle, 10 );
568     ok( ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT, "WaitForSingleObject wrong ret %u\n", ret );
569 
570     val = ~0;
571     ret = pQueryMemoryResourceNotification( handle, &val );
572     ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
573     ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
574     ret = CloseHandle( handle );
575     ok( ret, "CloseHandle failed err %u\n", GetLastError() );
576 
577     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
578     val = ~0;
579     ret = pQueryMemoryResourceNotification( handle, &val );
580     ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
581     ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
582     CloseHandle( handle );
583 }
584 
585 static void test_semaphore(void)
586 {
587     HANDLE handle, handle2;
588 
589     /* test case sensitivity */
590 
591     SetLastError(0xdeadbeef);
592     handle = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
593     ok(handle != NULL, "CreateSemaphore failed with error %u\n", GetLastError());
594     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
595 
596     SetLastError(0xdeadbeef);
597     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
598     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
599     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
600     CloseHandle( handle2 );
601 
602     SetLastError(0xdeadbeef);
603     handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": TEST SEMAPHORE");
604     ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
605     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
606     CloseHandle( handle2 );
607 
608     SetLastError(0xdeadbeef);
609     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": Test Semaphore");
610     ok( handle2 != NULL, "OpenSemaphore failed with error %d\n", GetLastError());
611     CloseHandle( handle2 );
612 
613     SetLastError(0xdeadbeef);
614     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": TEST SEMAPHORE");
615     ok( !handle2, "OpenSemaphore succeeded\n");
616     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
617 
618     SetLastError(0xdeadbeef);
619     handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, NULL );
620     ok( !handle2, "OpenSemaphore succeeded\n");
621     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
622 
623     SetLastError(0xdeadbeef);
624     handle2 = OpenSemaphoreW( SEMAPHORE_ALL_ACCESS, FALSE, NULL );
625     ok( !handle2, "OpenSemaphore succeeded\n");
626     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
627 
628     CloseHandle( handle );
629 }
630 
631 static void test_waitable_timer(void)
632 {
633     HANDLE handle, handle2;
634 
635     /* test case sensitivity */
636 
637     SetLastError(0xdeadbeef);
638     handle = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
639     ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
640     ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
641 
642     SetLastError(0xdeadbeef);
643     handle2 = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
644     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
645     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
646     CloseHandle( handle2 );
647 
648     SetLastError(0xdeadbeef);
649     handle2 = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
650     ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
651     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
652     CloseHandle( handle2 );
653 
654     SetLastError(0xdeadbeef);
655     handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
656     ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
657     CloseHandle( handle2 );
658 
659     SetLastError(0xdeadbeef);
660     handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
661     ok( !handle2, "OpenWaitableTimer succeeded\n");
662     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
663 
664     SetLastError(0xdeadbeef);
665     handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, NULL );
666     ok( !handle2, "OpenWaitableTimer failed with error %d\n", GetLastError());
667     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
668 
669     SetLastError(0xdeadbeef);
670     handle2 = OpenWaitableTimerW( TIMER_ALL_ACCESS, FALSE, NULL );
671     ok( !handle2, "OpenWaitableTimer failed with error %d\n", GetLastError());
672     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
673 
674     CloseHandle( handle );
675 }
676 
677 static HANDLE sem = 0;
678 
679 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
680 {
681     ReleaseSemaphore(sem, 1, NULL);
682 }
683 
684 static BOOL (WINAPI *p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
685 
686 static void test_iocp_callback(void)
687 {
688     char temp_path[MAX_PATH];
689     char filename[MAX_PATH];
690     DWORD ret;
691     BOOL retb;
692     static const char prefix[] = "pfx";
693     HANDLE hFile;
694     HMODULE hmod = GetModuleHandleA("kernel32.dll");
695     DWORD bytesWritten;
696     const char *buffer = "12345678123456781234567812345678";
697     OVERLAPPED overlapped;
698 
699     p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
700     if(!p_BindIoCompletionCallback) {
701         win_skip("BindIoCompletionCallback not found in this DLL\n");
702         return;
703     }
704 
705     sem = CreateSemaphoreW(NULL, 0, 1, NULL);
706     ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
707 
708     ret = GetTempPathA(MAX_PATH, temp_path);
709     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
710     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
711 
712     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
713     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
714 
715     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
716                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
717     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
718 
719     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
720     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
721     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
722 
723     ret = CloseHandle(hFile);
724     ok( ret, "CloseHandle: error %d\n", GetLastError());
725     ret = DeleteFileA(filename);
726     ok( ret, "DeleteFileA: error %d\n", GetLastError());
727 
728     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
729                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
730     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
731 
732     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
733     ok(retb == TRUE, "BindIoCompletionCallback failed\n");
734 
735     memset(&overlapped, 0, sizeof(overlapped));
736     retb = WriteFile(hFile, buffer, 4, &bytesWritten, &overlapped);
737     ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
738 
739     ret = WaitForSingleObject(sem, 5000);
740     ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
741     CloseHandle(sem);
742 
743     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
744     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
745     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
746     retb = p_BindIoCompletionCallback(hFile, NULL, 0);
747     ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
748     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
749 
750     ret = CloseHandle(hFile);
751     ok( ret, "CloseHandle: error %d\n", GetLastError());
752     ret = DeleteFileA(filename);
753     ok( ret, "DeleteFileA: error %d\n", GetLastError());
754 
755     /* win2k3 requires the Flags parameter to be zero */
756     SetLastError(0xdeadbeef);
757     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
758                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
759     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
760     retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
761     if (!retb)
762         ok(GetLastError() == ERROR_INVALID_PARAMETER,
763            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
764     else
765         ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
766     ret = CloseHandle(hFile);
767     ok( ret, "CloseHandle: error %d\n", GetLastError());
768     ret = DeleteFileA(filename);
769     ok( ret, "DeleteFileA: error %d\n", GetLastError());
770 
771     retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
772     ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
773     ok(GetLastError() == ERROR_INVALID_HANDLE ||
774        GetLastError() == ERROR_INVALID_PARAMETER, /* vista */
775        "Last error is %d\n", GetLastError());
776 }
777 
778 static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut)
779 {
780     int *pn = p;
781     disable_success_count
782     ok(timedOut, "Timer callbacks should always time out\n");
783     ++*pn;
784 }
785 
786 struct timer_queue_data1
787 {
788     int num_calls;
789     int max_calls;
790     HANDLE q, t;
791 };
792 
793 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
794 {
795     struct timer_queue_data1 *d = p;
796     ok(timedOut, "Timer callbacks should always time out\n");
797     if (d->t && ++d->num_calls == d->max_calls)
798     {
799         BOOL ret;
800         SetLastError(0xdeadbeef);
801         /* Note, XP SP2 does *not* do any deadlock checking, so passing
802            INVALID_HANDLE_VALUE here will just hang.  */
803         ret = DeleteTimerQueueTimer(d->q, d->t, NULL);
804         ok(!ret, "DeleteTimerQueueTimer\n");
805         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
806     }
807 }
808 
809 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
810 {
811     struct timer_queue_data1 *d = p;
812     ok(timedOut, "Timer callbacks should always time out\n");
813     if (d->t && ++d->num_calls == d->max_calls)
814     {
815         /* Basically kill the timer since it won't have time to run
816            again.  */
817         BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 10000, 0);
818         ok(ret, "ChangeTimerQueueTimer\n");
819     }
820 }
821 
822 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
823 {
824     struct timer_queue_data1 *d = p;
825     ok(timedOut, "Timer callbacks should always time out\n");
826     if (d->t)
827     {
828         /* This tests whether a timer gets flagged for deletion before
829            or after the callback runs.  If we start this timer with a
830            period of zero (run once), then ChangeTimerQueueTimer will
831            fail if the timer is already flagged.  Hence we really run
832            only once.  Otherwise we will run multiple times.  */
833         BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 50, 50);
834         ok(ret, "ChangeTimerQueueTimer\n");
835         ++d->num_calls;
836     }
837 }
838 
839 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
840 {
841     DWORD_PTR delay = (DWORD_PTR) p;
842     ok(timedOut, "Timer callbacks should always time out\n");
843     if (delay)
844         Sleep(delay);
845 }
846 
847 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
848 {
849     struct timer_queue_data1 *d = p;
850     ok(timedOut, "Timer callbacks should always time out\n");
851     /* This tests an original implementation bug where a deleted timer may get
852        to run, but it is tricky to set up.  */
853     if (d->q && d->num_calls++ == 0)
854     {
855         /* First run: delete ourselves, then insert and remove a timer
856            that goes in front of us in the sorted timeout list.  Once
857            removed, we will still timeout at the faster timer's due time,
858            but this should be a no-op if we are bug-free.  There should
859            not be a second run.  We can test the value of num_calls later.  */
860         BOOL ret;
861         HANDLE t;
862 
863         /* The delete will pend while we are in this callback.  */
864         SetLastError(0xdeadbeef);
865         ret = DeleteTimerQueueTimer(d->q, d->t, NULL);
866         ok(!ret, "DeleteTimerQueueTimer\n");
867         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
868 
869         ret = CreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
870         ok(ret, "CreateTimerQueueTimer\n");
871         ok(t != NULL, "CreateTimerQueueTimer\n");
872 
873         ret = DeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
874         ok(ret, "DeleteTimerQueueTimer\n");
875 
876         /* Now we stay alive by hanging around in the callback.  */
877         Sleep(500);
878     }
879 }
880 
881 static void test_timer_queue(void)
882 {
883     HANDLE q, t0, t1, t2, t3, t4, t5;
884     int n0, n1, n2, n3, n4, n5;
885     struct timer_queue_data1 d1, d2, d3, d4;
886     HANDLE e, et1, et2;
887     BOOL ret, ret0;
888 
889     /* Test asynchronous deletion of the queue. */
890     q = CreateTimerQueue();
891     ok(q != NULL, "CreateTimerQueue\n");
892 
893     SetLastError(0xdeadbeef);
894     ret = DeleteTimerQueueEx(q, NULL);
895     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
896        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
897        GetLastError());
898 
899     /* Test synchronous deletion of the queue and running timers. */
900     q = CreateTimerQueue();
901     ok(q != NULL, "CreateTimerQueue\n");
902 
903     /* Not called. */
904     t0 = NULL;
905     n0 = 0;
906     ret = CreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0, 300, 0);
907     ok(ret, "CreateTimerQueueTimer\n");
908     ok(t0 != NULL, "CreateTimerQueueTimer\n");
909     ret0 = DeleteTimerQueueTimer(q, t0, NULL);
910     ok((!ret0 && GetLastError() == ERROR_IO_PENDING) ||
911        broken(ret0), /* Win 2000 & XP & 2003 */
912        "DeleteTimerQueueTimer ret=%d le=%u\n", ret0, GetLastError());
913 
914     /* Called once.  */
915     t1 = NULL;
916     n1 = 0;
917     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, 0, 0);
918     ok(ret, "CreateTimerQueueTimer\n");
919     ok(t1 != NULL, "CreateTimerQueueTimer\n");
920 
921     /* A slow one.  */
922     t2 = NULL;
923     n2 = 0;
924     ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, 100, 0);
925     ok(ret, "CreateTimerQueueTimer\n");
926     ok(t2 != NULL, "CreateTimerQueueTimer\n");
927 
928     /* A fast one.  */
929     t3 = NULL;
930     n3 = 0;
931     ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, 10, 0);
932     ok(ret, "CreateTimerQueueTimer\n");
933     ok(t3 != NULL, "CreateTimerQueueTimer\n");
934 
935     /* Start really late (it won't start).  */
936     t4 = NULL;
937     n4 = 0;
938     ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, 10, 0);
939     ok(ret, "CreateTimerQueueTimer\n");
940     ok(t4 != NULL, "CreateTimerQueueTimer\n");
941 
942     /* Start soon, but delay so long it won't run again.  */
943     t5 = NULL;
944     n5 = 0;
945     ret = CreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, 10000, 0);
946     ok(ret, "CreateTimerQueueTimer\n");
947     ok(t5 != NULL, "CreateTimerQueueTimer\n");
948 
949     /* Give them a chance to do some work.  */
950     Sleep(500);
951 
952     /* Test deleting a once-only timer.  */
953     ret = DeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
954     ok(ret, "DeleteTimerQueueTimer\n");
955 
956     /* A periodic timer.  */
957     ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
958     ok(ret, "DeleteTimerQueueTimer\n");
959 
960     ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
961     ok(ret, "DeleteTimerQueueEx\n");
962     todo_wine
963     ok(n0 == 1 || broken(ret0 && n0 == 0), "Timer callback 0 expected 1 got %d\n", n0);
964     ok(n1 == 1, "Timer callback 1 expected 1 got %d\n", n1);
965     ok(n2 < n3, "Timer callback 2 & 3 expected %d < %d\n", n2, n3);
966     ok(n4 == 0, "Timer callback 4 expected 0 got %d\n", n4);
967     ok(n5 == 1, "Timer callback 5 expected 1 got %d\n", n5);
968 
969     /* Test synchronous deletion of the timer/queue with event trigger. */
970     e = CreateEventW(NULL, TRUE, FALSE, NULL);
971     et1 = CreateEventW(NULL, TRUE, FALSE, NULL);
972     et2 = CreateEventW(NULL, TRUE, FALSE, NULL);
973     if (!e || !et1 || !et2)
974     {
975         skip("Failed to create timer queue descruction event\n");
976         return;
977     }
978 
979     q = CreateTimerQueue();
980     ok(q != NULL, "CreateTimerQueue\n");
981 
982     /* Run once and finish quickly (should be done when we delete it).  */
983     t1 = NULL;
984     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
985     ok(ret, "CreateTimerQueueTimer\n");
986     ok(t1 != NULL, "CreateTimerQueueTimer\n");
987 
988     /* Run once and finish slowly (shouldn't be done when we delete it).  */
989     t2 = NULL;
990     ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0);
991     ok(ret, "CreateTimerQueueTimer\n");
992     ok(t2 != NULL, "CreateTimerQueueTimer\n");
993 
994     /* Run once and finish quickly (should be done when we delete it).  */
995     t3 = NULL;
996     ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
997     ok(ret, "CreateTimerQueueTimer\n");
998     ok(t3 != NULL, "CreateTimerQueueTimer\n");
999 
1000     /* Run once and finish slowly (shouldn't be done when we delete it).  */
1001     t4 = NULL;
1002     ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0);
1003     ok(ret, "CreateTimerQueueTimer\n");
1004     ok(t4 != NULL, "CreateTimerQueueTimer\n");
1005 
1006     /* Give them a chance to start.  */
1007     Sleep(400);
1008 
1009     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
1010        even if the timer is finished.  */
1011     SetLastError(0xdeadbeef);
1012     ret = DeleteTimerQueueTimer(q, t1, NULL);
1013     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1014        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1015        GetLastError());
1016 
1017     SetLastError(0xdeadbeef);
1018     ret = DeleteTimerQueueTimer(q, t2, NULL);
1019     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
1020     ok(GetLastError() == ERROR_IO_PENDING,
1021        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1022        GetLastError());
1023 
1024     SetLastError(0xdeadbeef);
1025     ret = DeleteTimerQueueTimer(q, t3, et1);
1026     ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
1027     ok(GetLastError() == 0xdeadbeef,
1028        "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
1029        GetLastError());
1030     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
1031        "Timer destruction event not triggered\n");
1032 
1033     SetLastError(0xdeadbeef);
1034     ret = DeleteTimerQueueTimer(q, t4, et2);
1035     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
1036     ok(GetLastError() == ERROR_IO_PENDING,
1037        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1038        GetLastError());
1039     ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
1040        "Timer destruction event not triggered\n");
1041 
1042     SetLastError(0xdeadbeef);
1043     ret = DeleteTimerQueueEx(q, e);
1044     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1045        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1046        GetLastError());
1047     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
1048        "Queue destruction event not triggered\n");
1049     CloseHandle(e);
1050 
1051     /* Test deleting/changing a timer in execution.  */
1052     q = CreateTimerQueue();
1053     ok(q != NULL, "CreateTimerQueue\n");
1054 
1055     /* Test changing a once-only timer before it fires (this is allowed,
1056        whereas after it fires you cannot).  */
1057     n1 = 0;
1058     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000, 0, 0);
1059     ok(ret, "CreateTimerQueueTimer\n");
1060     ok(t1 != NULL, "CreateTimerQueueTimer\n");
1061     ret = ChangeTimerQueueTimer(q, t1, 0, 0);
1062     ok(ret, "ChangeTimerQueueTimer\n");
1063 
1064     d2.t = t2 = NULL;
1065     d2.num_calls = 0;
1066     d2.max_calls = 3;
1067     d2.q = q;
1068     ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10, 10, 0);
1069     d2.t = t2;
1070     ok(ret, "CreateTimerQueueTimer\n");
1071     ok(t2 != NULL, "CreateTimerQueueTimer\n");
1072 
1073     d3.t = t3 = NULL;
1074     d3.num_calls = 0;
1075     d3.max_calls = 4;
1076     d3.q = q;
1077     ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10, 10, 0);
1078     d3.t = t3;
1079     ok(ret, "CreateTimerQueueTimer\n");
1080     ok(t3 != NULL, "CreateTimerQueueTimer\n");
1081 
1082     d4.t = t4 = NULL;
1083     d4.num_calls = 0;
1084     d4.q = q;
1085     ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10, 0, 0);
1086     d4.t = t4;
1087     ok(ret, "CreateTimerQueueTimer\n");
1088     ok(t4 != NULL, "CreateTimerQueueTimer\n");
1089 
1090     Sleep(500);
1091 
1092     ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
1093     ok(ret, "DeleteTimerQueueEx\n");
1094     ok(n1 == 1, "ChangeTimerQueueTimer\n");
1095     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
1096     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
1097     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
1098 
1099     /* Test an obscure bug that was in the original implementation.  */
1100     q = CreateTimerQueue();
1101     ok(q != NULL, "CreateTimerQueue\n");
1102 
1103     /* All the work is done in the callback.  */
1104     d1.t = t1 = NULL;
1105     d1.num_calls = 0;
1106     d1.q = q;
1107     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100, 100, WT_EXECUTELONGFUNCTION);
1108     d1.t = t1;
1109     ok(ret, "CreateTimerQueueTimer\n");
1110     ok(t1 != NULL, "CreateTimerQueueTimer\n");
1111 
1112     Sleep(750);
1113 
1114     SetLastError(0xdeadbeef);
1115     ret = DeleteTimerQueueEx(q, NULL);
1116     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1117        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1118        GetLastError());
1119     ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
1120 
1121     /* Test functions on the default timer queue.  */
1122     t1 = NULL;
1123     n1 = 0;
1124     ret = CreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000, 1000, 0);
1125     ok(ret, "CreateTimerQueueTimer, default queue\n");
1126     ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
1127 
1128     ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1129     ok(ret, "ChangeTimerQueueTimer, default queue\n");
1130 
1131     ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1132     ok(ret, "DeleteTimerQueueTimer, default queue\n");
1133 
1134     /* Try mixing default and non-default queues.  Apparently this works.  */
1135     q = CreateTimerQueue();
1136     ok(q != NULL, "CreateTimerQueue\n");
1137 
1138     t1 = NULL;
1139     n1 = 0;
1140     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000, 1000, 0);
1141     ok(ret, "CreateTimerQueueTimer\n");
1142     ok(t1 != NULL, "CreateTimerQueueTimer\n");
1143 
1144     t2 = NULL;
1145     n2 = 0;
1146     ret = CreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000, 1000, 0);
1147     ok(ret, "CreateTimerQueueTimer\n");
1148     ok(t2 != NULL, "CreateTimerQueueTimer\n");
1149 
1150     ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1151     ok(ret, "ChangeTimerQueueTimer\n");
1152 
1153     ret = ChangeTimerQueueTimer(q, t2, 2000, 2000);
1154     ok(ret, "ChangeTimerQueueTimer\n");
1155 
1156     ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1157     ok(ret, "DeleteTimerQueueTimer\n");
1158 
1159     ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
1160     ok(ret, "DeleteTimerQueueTimer\n");
1161 
1162     /* Try to delete the default queue?  In any case: not allowed.  */
1163     SetLastError(0xdeadbeef);
1164     ret = DeleteTimerQueueEx(NULL, NULL);
1165     ok(!ret, "DeleteTimerQueueEx call was expected to fail\n");
1166     ok(GetLastError() == ERROR_INVALID_HANDLE,
1167        "DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n",
1168        GetLastError());
1169 
1170     SetLastError(0xdeadbeef);
1171     ret = DeleteTimerQueueEx(q, NULL);
1172     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1173        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1174        GetLastError());
1175 }
1176 
1177 static HANDLE modify_handle(HANDLE handle, DWORD modify)
1178 {
1179     DWORD tmp = HandleToULong(handle);
1180     tmp |= modify;
1181     return ULongToHandle(tmp);
1182 }
1183 
1184 static void test_WaitForSingleObject(void)
1185 {
1186     HANDLE signaled, nonsignaled, invalid;
1187     LARGE_INTEGER timeout;
1188     NTSTATUS status;
1189     DWORD ret;
1190 
1191     signaled = CreateEventW(NULL, TRUE, TRUE, NULL);
1192     nonsignaled = CreateEventW(NULL, TRUE, FALSE, NULL);
1193     invalid = (HANDLE) 0xdeadbee0;
1194 
1195     /* invalid handle with different values for lower 2 bits */
1196     SetLastError(0xdeadbeef);
1197     ret = WaitForSingleObject(invalid, 0);
1198     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1199     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1200 
1201     SetLastError(0xdeadbeef);
1202     ret = WaitForSingleObject(modify_handle(invalid, 1), 0);
1203     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1204     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1205 
1206     SetLastError(0xdeadbeef);
1207     ret = WaitForSingleObject(modify_handle(invalid, 2), 0);
1208     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1209     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1210 
1211     SetLastError(0xdeadbeef);
1212     ret = WaitForSingleObject(modify_handle(invalid, 3), 0);
1213     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1214     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1215 
1216     /* valid handle with different values for lower 2 bits */
1217     SetLastError(0xdeadbeef);
1218     ret = WaitForSingleObject(nonsignaled, 0);
1219     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1220     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1221 
1222     SetLastError(0xdeadbeef);
1223     ret = WaitForSingleObject(modify_handle(nonsignaled, 1), 0);
1224     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1225     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1226 
1227     SetLastError(0xdeadbeef);
1228     ret = WaitForSingleObject(modify_handle(nonsignaled, 2), 0);
1229     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1230     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1231 
1232     SetLastError(0xdeadbeef);
1233     ret = WaitForSingleObject(modify_handle(nonsignaled, 3), 0);
1234     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1235     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1236 
1237     /* valid handle with different values for lower 2 bits */
1238     SetLastError(0xdeadbeef);
1239     ret = WaitForSingleObject(signaled, 0);
1240     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1241     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1242 
1243     SetLastError(0xdeadbeef);
1244     ret = WaitForSingleObject(modify_handle(signaled, 1), 0);
1245     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1246     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1247 
1248     SetLastError(0xdeadbeef);
1249     ret = WaitForSingleObject(modify_handle(signaled, 2), 0);
1250     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1251     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1252 
1253     SetLastError(0xdeadbeef);
1254     ret = WaitForSingleObject(modify_handle(signaled, 3), 0);
1255     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1256     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1257 
1258     /* pseudo handles are allowed in WaitForSingleObject and NtWaitForSingleObject */
1259     ret = WaitForSingleObject(GetCurrentProcess(), 100);
1260     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", ret);
1261 
1262     ret = WaitForSingleObject(GetCurrentThread(), 100);
1263     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", ret);
1264 
1265     timeout.QuadPart = -1000000;
1266     status = pNtWaitForSingleObject(GetCurrentProcess(), FALSE, &timeout);
1267     ok(status == STATUS_TIMEOUT, "expected STATUS_TIMEOUT, got %08x\n", status);
1268 
1269     timeout.QuadPart = -1000000;
1270     status = pNtWaitForSingleObject(GetCurrentThread(), FALSE, &timeout);
1271     ok(status == STATUS_TIMEOUT, "expected STATUS_TIMEOUT, got %08x\n", status);
1272 
1273     CloseHandle(signaled);
1274     CloseHandle(nonsignaled);
1275 }
1276 
1277 static void test_WaitForMultipleObjects(void)
1278 {
1279     LARGE_INTEGER timeout;
1280     NTSTATUS status;
1281     DWORD r;
1282     int i;
1283     HANDLE maxevents[MAXIMUM_WAIT_OBJECTS];
1284 
1285     /* create the maximum number of events and make sure
1286      * we can wait on that many */
1287     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1288     {
1289         maxevents[i] = CreateEventW(NULL, i==0, TRUE, NULL);
1290         ok( maxevents[i] != 0, "should create enough events\n");
1291     }
1292 
1293     /* a manual-reset event remains signaled, an auto-reset event is cleared */
1294     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1295     ok( r == WAIT_OBJECT_0, "should signal lowest handle first, got %d\n", r);
1296     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1297     ok( r == WAIT_OBJECT_0, "should signal handle #0 first, got %d\n", r);
1298     ok(ResetEvent(maxevents[0]), "ResetEvent\n");
1299     for (i=1; i<MAXIMUM_WAIT_OBJECTS; i++)
1300     {
1301         /* the lowest index is checked first and remaining events are untouched */
1302         r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1303         ok( r == WAIT_OBJECT_0+i, "should signal handle #%d first, got %d\n", i, r);
1304     }
1305 
1306     /* run same test with Nt* call */
1307     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1308         SetEvent(maxevents[i]);
1309 
1310     /* a manual-reset event remains signaled, an auto-reset event is cleared */
1311     status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1312     ok(status == STATUS_WAIT_0, "should signal lowest handle first, got %08x\n", status);
1313     status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1314     ok(status == STATUS_WAIT_0, "should signal handle #0 first, got %08x\n", status);
1315     ok(ResetEvent(maxevents[0]), "ResetEvent\n");
1316     for (i=1; i<MAXIMUM_WAIT_OBJECTS; i++)
1317     {
1318         /* the lowest index is checked first and remaining events are untouched */
1319         status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1320         ok(status == STATUS_WAIT_0 + i, "should signal handle #%d first, got %08x\n", i, status);
1321     }
1322 
1323     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1324         if (maxevents[i]) CloseHandle(maxevents[i]);
1325 
1326     /* in contrast to WaitForSingleObject, pseudo handles are not allowed in
1327      * WaitForMultipleObjects and NtWaitForMultipleObjects */
1328     maxevents[0] = GetCurrentProcess();
1329     SetLastError(0xdeadbeef);
1330     r = WaitForMultipleObjects(1, maxevents, FALSE, 100);
1331     todo_wine ok(r == WAIT_FAILED, "expected WAIT_FAILED, got %u\n", r);
1332     todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE,
1333                  "expected ERROR_INVALID_HANDLE, got %u\n", GetLastError());
1334 
1335     maxevents[0] = GetCurrentThread();
1336     SetLastError(0xdeadbeef);
1337     r = WaitForMultipleObjects(1, maxevents, FALSE, 100);
1338     todo_wine ok(r == WAIT_FAILED, "expected WAIT_FAILED, got %u\n", r);
1339     todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE,
1340                  "expected ERROR_INVALID_HANDLE, got %u\n", GetLastError());
1341 
1342     timeout.QuadPart = -1000000;
1343     maxevents[0] = GetCurrentProcess();
1344     status = pNtWaitForMultipleObjects(1, maxevents, TRUE, FALSE, &timeout);
1345     todo_wine ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %08x\n", status);
1346 
1347     timeout.QuadPart = -1000000;
1348     maxevents[0] = GetCurrentThread();
1349     status = pNtWaitForMultipleObjects(1, maxevents, TRUE, FALSE, &timeout);
1350     todo_wine ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %08x\n", status);
1351 }
1352 
1353 static BOOL g_initcallback_ret, g_initcallback_called;
1354 static void *g_initctxt;
1355 
1356 static BOOL CALLBACK initonce_callback(INIT_ONCE *initonce, void *parameter, void **ctxt)
1357 {
1358     g_initcallback_called = TRUE;
1359     /* zero bit set means here that initialization is taking place - initialization locked */
1360     ok(g_initctxt == *ctxt, "got wrong context value %p, expected %p\n", *ctxt, g_initctxt);
1361     ok(initonce->Ptr == (void*)0x1, "got %p\n", initonce->Ptr);
1362     ok(parameter == (void*)0xdeadbeef, "got wrong parameter\n");
1363     return g_initcallback_ret;
1364 }
1365 
1366 static void test_initonce(void)
1367 {
1368     INIT_ONCE initonce;
1369     BOOL ret, pending;
1370 
1371     if (!pInitOnceInitialize || !pInitOnceExecuteOnce)
1372     {
1373         win_skip("one-time initialization API not supported\n");
1374         return;
1375     }
1376 
1377     /* blocking initialization with callback */
1378     initonce.Ptr = (void*)0xdeadbeef;
1379     pInitOnceInitialize(&initonce);
1380     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1381 
1382     /* initialisation completed successfully */
1383     g_initcallback_ret = TRUE;
1384     g_initctxt = NULL;
1385     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1386     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1387     ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
1388     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1389     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1390 
1391     /* so it's been called already so won't be called again */
1392     g_initctxt = NULL;
1393     g_initcallback_called = FALSE;
1394     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1395     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1396     ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
1397     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1398     ok(!g_initcallback_called, "got %d\n", g_initcallback_called);
1399 
1400     pInitOnceInitialize(&initonce);
1401     g_initcallback_called = FALSE;
1402     /* 2 lower order bits should never be used, you'll get a crash in result */
1403     g_initctxt = (void*)0xFFFFFFF0;
1404     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1405     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1406     ok(initonce.Ptr == (void*)0xFFFFFFF2, "got %p\n", initonce.Ptr);
1407     ok(g_initctxt == (void*)0xFFFFFFF0, "got %p\n", g_initctxt);
1408     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1409 
1410     /* callback failed */
1411     g_initcallback_ret = FALSE;
1412     g_initcallback_called = FALSE;
1413     g_initctxt = NULL;
1414     pInitOnceInitialize(&initonce);
1415     SetLastError( 0xdeadbeef );
1416     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1417     ok(!ret && GetLastError() == 0xdeadbeef, "got wrong ret value %d err %u\n", ret, GetLastError());
1418     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1419     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1420     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1421 
1422     /* blocking initialization without a callback */
1423     pInitOnceInitialize(&initonce);
1424     g_initctxt = NULL;
1425     pending = FALSE;
1426     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1427     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1428     ok(pending, "got %d\n", pending);
1429     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1430     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1431     /* another attempt to begin initialization with block a single thread */
1432 
1433     g_initctxt = NULL;
1434     pending = 0xf;
1435     SetLastError( 0xdeadbeef );
1436     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1437     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1438     ok(pending == 0xf, "got %d\n", pending);
1439     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1440     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1441 
1442     g_initctxt = (void*)0xdeadbee0;
1443     SetLastError( 0xdeadbeef );
1444     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, g_initctxt);
1445     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1446     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1447 
1448     /* once failed already */
1449     g_initctxt = (void*)0xdeadbee0;
1450     ret = pInitOnceComplete(&initonce, 0, g_initctxt);
1451     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1452     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1453 
1454     pInitOnceInitialize(&initonce);
1455     SetLastError( 0xdeadbeef );
1456     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1457     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1458     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1459 
1460     SetLastError( 0xdeadbeef );
1461     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1462     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1463     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1464 
1465     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1466     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1467     ok(pending, "got %d\n", pending);
1468     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1469 
1470     SetLastError( 0xdeadbeef );
1471     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1472     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1473 
1474     SetLastError( 0xdeadbeef );
1475     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1476     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1477     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1478 
1479     SetLastError( 0xdeadbeef );
1480     ret = pInitOnceComplete(&initonce, 0, (void *)0xdeadbeef);
1481     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1482     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1483 
1484     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1485     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1486     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1487 
1488     pInitOnceInitialize(&initonce);
1489     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1490     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1491     ok(pending, "got %d\n", pending);
1492     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1493 
1494     SetLastError( 0xdeadbeef );
1495     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1496     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1497 
1498     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1499     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1500     ok(pending, "got %d\n", pending);
1501     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1502 
1503     SetLastError( 0xdeadbeef );
1504     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1505     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1506     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1507 
1508     SetLastError( 0xdeadbeef );
1509     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1510     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1511     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1512 
1513     SetLastError( 0xdeadbeef );
1514     ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbeef);
1515     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1516     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1517 
1518     ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbee0);
1519     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1520     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1521 
1522     SetLastError( 0xdeadbeef );
1523     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1524     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1525     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1526 
1527     pInitOnceInitialize(&initonce);
1528     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1529     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1530     ok(pending, "got %d\n", pending);
1531     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1532 
1533     /* test INIT_ONCE_CHECK_ONLY */
1534 
1535     pInitOnceInitialize(&initonce);
1536     SetLastError( 0xdeadbeef );
1537     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1538     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1539     SetLastError( 0xdeadbeef );
1540     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1541     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1542 
1543     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1544     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1545     ok(pending, "got %d\n", pending);
1546     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1547 
1548     SetLastError( 0xdeadbeef );
1549     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1550     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1551     SetLastError( 0xdeadbeef );
1552     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1553     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1554 
1555     ret = pInitOnceComplete(&initonce, 0, (void *)0xdeadbee0);
1556     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1557     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1558 
1559     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1560     ok(ret, "got wrong ret value %d err %u\n", ret, GetLastError());
1561     ok(!pending, "got %d\n", pending);
1562     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1563     ok(g_initctxt == (void*)0xdeadbee0, "got %p\n", initonce.Ptr);
1564 
1565     SetLastError( 0xdeadbeef );
1566     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1567     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1568 
1569     pInitOnceInitialize(&initonce);
1570     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1571     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1572     ok(pending, "got %d\n", pending);
1573     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1574 
1575     SetLastError( 0xdeadbeef );
1576     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1577     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1578     SetLastError( 0xdeadbeef );
1579     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1580     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1581 
1582     ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbee0);
1583     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1584     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1585 
1586     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1587     ok(ret, "got wrong ret value %d err %u\n", ret, GetLastError());
1588     ok(!pending, "got %d\n", pending);
1589     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1590     ok(g_initctxt == (void*)0xdeadbee0, "got %p\n", initonce.Ptr);
1591 
1592     SetLastError( 0xdeadbeef );
1593     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1594     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1595 }
1596 
1597 static CONDITION_VARIABLE buffernotempty = CONDITION_VARIABLE_INIT;
1598 static CONDITION_VARIABLE buffernotfull = CONDITION_VARIABLE_INIT;
1599 static CRITICAL_SECTION   buffercrit;
1600 static BOOL condvar_stop = FALSE, condvar_sleeperr = FALSE;
1601 static LONG bufferlen,totalproduced,totalconsumed;
1602 static LONG condvar_producer_sleepcnt,condvar_consumer_sleepcnt;
1603 
1604 #define BUFFER_SIZE 5
1605 
1606 static DWORD WINAPI condvar_producer(LPVOID x) {
1607     DWORD sleepinterval = 5;
1608 
1609     while (1) {
1610         Sleep(sleepinterval);
1611         if (sleepinterval > 1)
1612             sleepinterval -= 1;
1613 
1614         EnterCriticalSection(&buffercrit);
1615         while ((bufferlen == BUFFER_SIZE) && !condvar_stop) {
1616             condvar_producer_sleepcnt++;
1617             if (!pSleepConditionVariableCS(&buffernotfull, &buffercrit, sleepinterval)) {
1618                 if (GetLastError() != ERROR_TIMEOUT)
1619                     condvar_sleeperr = TRUE;
1620             }
1621         }
1622         if (condvar_stop) {
1623             LeaveCriticalSection(&buffercrit);
1624             break;
1625         }
1626         bufferlen++;
1627         totalproduced++;
1628         LeaveCriticalSection(&buffercrit);
1629         pWakeConditionVariable(&buffernotempty);
1630     }
1631     return 0;
1632 }
1633 
1634 static DWORD WINAPI condvar_consumer(LPVOID x) {
1635     DWORD *cnt = (DWORD*)x;
1636     DWORD sleepinterval = 1;
1637 
1638     while (1) {
1639         EnterCriticalSection(&buffercrit);
1640         while ((bufferlen == 0) && !condvar_stop) {
1641             condvar_consumer_sleepcnt++;
1642             if (!pSleepConditionVariableCS (&buffernotempty, &buffercrit, sleepinterval)) {
1643                 if (GetLastError() != ERROR_TIMEOUT)
1644                     condvar_sleeperr = TRUE;
1645             }
1646         }
1647         if (condvar_stop && (bufferlen == 0)) {
1648             LeaveCriticalSection(&buffercrit);
1649             break;
1650         }
1651         bufferlen--;
1652         totalconsumed++;
1653         (*cnt)++;
1654         LeaveCriticalSection(&buffercrit);
1655         pWakeConditionVariable(&buffernotfull);
1656         Sleep(sleepinterval);
1657         if (sleepinterval < 5) sleepinterval += 1;
1658     }
1659     return 0;
1660 }
1661 
1662 static void test_condvars_consumer_producer(void)
1663 {
1664     HANDLE hp1,hp2,hp3,hc1,hc2,hc3;
1665     DWORD dummy;
1666     DWORD cnt1,cnt2,cnt3;
1667 
1668     if (!pInitializeConditionVariable) {
1669         /* function is not yet in XP, only in newer Windows */
1670         win_skip("no condition variable support.\n");
1671         return;
1672     }
1673 
1674     /* Implement a producer / consumer scheme with non-full / non-empty triggers */
1675 
1676     /* If we have static initialized condition variables, InitializeConditionVariable
1677      * is not strictly necessary.
1678      * pInitializeConditionVariable(&buffernotfull);
1679      */
1680     pInitializeConditionVariable(&buffernotempty);
1681     InitializeCriticalSection(&buffercrit);
1682 
1683     /* Larger Test: consumer/producer example */
1684 
1685     bufferlen = totalproduced = totalconsumed = cnt1 = cnt2 = cnt3 = 0;
1686 
1687     hp1 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1688     hp2 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1689     hp3 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1690     hc1 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt1, 0, &dummy);
1691     hc2 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt2, 0, &dummy);
1692     hc3 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt3, 0, &dummy);
1693 
1694     /* Limit run to 0.5 seconds. */
1695     Sleep(500);
1696 
1697     /* tear down start */
1698     condvar_stop = TRUE;
1699 
1700     /* final wake up call */
1701     pWakeAllConditionVariable (&buffernotfull);
1702     pWakeAllConditionVariable (&buffernotempty);
1703 
1704     /* (mostly an implementation detail)
1705      * ok(buffernotfull.Ptr == NULL, "buffernotfull.Ptr is %p\n", buffernotfull.Ptr);
1706      */
1707 
1708     WaitForSingleObject(hp1, 1000);
1709     WaitForSingleObject(hp2, 1000);
1710     WaitForSingleObject(hp3, 1000);
1711     WaitForSingleObject(hc1, 1000);
1712     WaitForSingleObject(hc2, 1000);
1713     WaitForSingleObject(hc3, 1000);
1714 
1715     ok(totalconsumed == totalproduced,
1716        "consumed %d != produced %d\n", totalconsumed, totalproduced);
1717     ok (!condvar_sleeperr, "error occurred during SleepConditionVariableCS\n");
1718 
1719     /* Checking cnt1 - cnt2 for non-0 would be not good, the case where
1720      * one consumer does not get anything to do is possible. */
1721     trace("produced %d, c1 %d, c2 %d, c3 %d\n", totalproduced, cnt1, cnt2, cnt3);
1722     /* The sleeps of the producer or consumer should not go above 100* produced count,
1723      * otherwise the implementation does not sleep correctly. But yet again, this is
1724      * not hard defined. */
1725     trace("producer sleep %d, consumer sleep %d\n", condvar_producer_sleepcnt, condvar_consumer_sleepcnt);
1726 }
1727 
1728 /* Sample test for some sequence of events happening, sequenced using "condvar_seq" */
1729 static DWORD condvar_seq = 0;
1730 static CONDITION_VARIABLE condvar_base = CONDITION_VARIABLE_INIT;
1731 static CRITICAL_SECTION condvar_crit;
1732 static SRWLOCK condvar_srwlock;
1733 
1734 /* Sequence of wake/sleep to check boundary conditions:
1735  * 0: init
1736  * 1: producer emits a WakeConditionVariable without consumer waiting.
1737  * 2: consumer sleeps without a wake expecting timeout
1738  * 3: producer emits a WakeAllConditionVariable without consumer waiting.
1739  * 4: consumer sleeps without a wake expecting timeout
1740  * 5: a wake is handed to a SleepConditionVariableCS
1741  * 6: a wakeall is handed to a SleepConditionVariableCS
1742  * 7: sleep after above should timeout
1743  * 8: wake with crit section locked into the sleep timeout
1744  *
1745  * the following tests will only be executed if InitializeSRWLock is available
1746  *
1747  *  9: producer (exclusive) wakes up consumer (exclusive)
1748  * 10: producer (exclusive) wakes up consumer (shared)
1749  * 11: producer (shared) wakes up consumer (exclusive)
1750  * 12: producer (shared) wakes up consumer (shared)
1751  * 13: end
1752  */
1753 static DWORD WINAPI condvar_base_producer(LPVOID x) {
1754     while (condvar_seq < 1) Sleep(1);
1755 
1756     pWakeConditionVariable (&condvar_base);
1757     condvar_seq = 2;
1758 
1759     while (condvar_seq < 3) Sleep(1);
1760     pWakeAllConditionVariable (&condvar_base);
1761     condvar_seq = 4;
1762 
1763     while (condvar_seq < 5) Sleep(1);
1764     EnterCriticalSection (&condvar_crit);
1765     pWakeConditionVariable (&condvar_base);
1766     LeaveCriticalSection (&condvar_crit);
1767     while (condvar_seq < 6) Sleep(1);
1768     EnterCriticalSection (&condvar_crit);
1769     pWakeAllConditionVariable (&condvar_base);
1770     LeaveCriticalSection (&condvar_crit);
1771 
1772     while (condvar_seq < 8) Sleep(1);
1773     EnterCriticalSection (&condvar_crit);
1774     pWakeConditionVariable (&condvar_base);
1775     Sleep(50);
1776     LeaveCriticalSection (&condvar_crit);
1777 
1778     /* skip over remaining tests if InitializeSRWLock is not available */
1779     if (!pInitializeSRWLock)
1780         return 0;
1781 
1782     while (condvar_seq < 9) Sleep(1);
1783     pAcquireSRWLockExclusive(&condvar_srwlock);
1784     pWakeConditionVariable(&condvar_base);
1785     pReleaseSRWLockExclusive(&condvar_srwlock);
1786 
1787     while (condvar_seq < 10) Sleep(1);
1788     pAcquireSRWLockExclusive(&condvar_srwlock);
1789     pWakeConditionVariable(&condvar_base);
1790     pReleaseSRWLockExclusive(&condvar_srwlock);
1791 
1792     while (condvar_seq < 11) Sleep(1);
1793     pAcquireSRWLockShared(&condvar_srwlock);
1794     pWakeConditionVariable(&condvar_base);
1795     pReleaseSRWLockShared(&condvar_srwlock);
1796 
1797     while (condvar_seq < 12) Sleep(1);
1798     Sleep(50); /* ensure that consumer waits for cond variable */
1799     pAcquireSRWLockShared(&condvar_srwlock);
1800     pWakeConditionVariable(&condvar_base);
1801     pReleaseSRWLockShared(&condvar_srwlock);
1802 
1803     return 0;
1804 }
1805 
1806 static DWORD WINAPI condvar_base_consumer(LPVOID x) {
1807     BOOL ret;
1808 
1809     while (condvar_seq < 2) Sleep(1);
1810 
1811     /* wake was emitted, but we were not sleeping */
1812     EnterCriticalSection (&condvar_crit);
1813     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1814     LeaveCriticalSection (&condvar_crit);
1815     ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1816     ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1817 
1818     condvar_seq = 3;
1819     while (condvar_seq < 4) Sleep(1);
1820 
1821     /* wake all was emitted, but we were not sleeping */
1822     EnterCriticalSection (&condvar_crit);
1823     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1824     LeaveCriticalSection (&condvar_crit);
1825     ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1826     ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1827 
1828     EnterCriticalSection (&condvar_crit);
1829     condvar_seq = 5;
1830     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 200);
1831     LeaveCriticalSection (&condvar_crit);
1832     ok (ret, "SleepConditionVariableCS should return TRUE on good wake\n");
1833 
1834     EnterCriticalSection (&condvar_crit);
1835     condvar_seq = 6;
1836     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 200);
1837     LeaveCriticalSection (&condvar_crit);
1838     ok (ret, "SleepConditionVariableCS should return TRUE on good wakeall\n");
1839     condvar_seq = 7;
1840 
1841     EnterCriticalSection (&condvar_crit);
1842     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1843     LeaveCriticalSection (&condvar_crit);
1844     ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1845     ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1846 
1847     EnterCriticalSection (&condvar_crit);
1848     condvar_seq = 8;
1849     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 20);
1850     LeaveCriticalSection (&condvar_crit);
1851     ok (ret, "SleepConditionVariableCS should still return TRUE on crit unlock delay\n");
1852 
1853     /* skip over remaining tests if InitializeSRWLock is not available */
1854     if (!pInitializeSRWLock)
1855     {
1856         win_skip("no srw lock support.\n");
1857         condvar_seq = 13; /* end */
1858         return 0;
1859     }
1860 
1861     pAcquireSRWLockExclusive(&condvar_srwlock);
1862     condvar_seq = 9;
1863     ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0);
1864     pReleaseSRWLockExclusive(&condvar_srwlock);
1865     ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1866 
1867     pAcquireSRWLockShared(&condvar_srwlock);
1868     condvar_seq = 10;
1869     ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED);
1870     pReleaseSRWLockShared(&condvar_srwlock);
1871     ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1872 
1873     pAcquireSRWLockExclusive(&condvar_srwlock);
1874     condvar_seq = 11;
1875     ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0);
1876     pReleaseSRWLockExclusive(&condvar_srwlock);
1877     ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1878 
1879     pAcquireSRWLockShared(&condvar_srwlock);
1880     condvar_seq = 12;
1881     ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED);
1882     pReleaseSRWLockShared(&condvar_srwlock);
1883     ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1884 
1885     condvar_seq = 13;
1886     return 0;
1887 }
1888 
1889 static void test_condvars_base(void) {
1890     HANDLE hp, hc;
1891     DWORD dummy;
1892     BOOL ret;
1893 
1894 
1895     if (!pInitializeConditionVariable) {
1896         /* function is not yet in XP, only in newer Windows */
1897         win_skip("no condition variable support.\n");
1898         return;
1899     }
1900 
1901     InitializeCriticalSection (&condvar_crit);
1902 
1903     if (pInitializeSRWLock)
1904         pInitializeSRWLock(&condvar_srwlock);
1905 
1906     EnterCriticalSection (&condvar_crit);
1907     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1908     LeaveCriticalSection (&condvar_crit);
1909 
1910     ok (!ret, "SleepConditionVariableCS should return FALSE on untriggered condvar\n");
1911     ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1912 
1913     if (pInitializeSRWLock)
1914     {
1915         pAcquireSRWLockExclusive(&condvar_srwlock);
1916         ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, 0);
1917         pReleaseSRWLockExclusive(&condvar_srwlock);
1918 
1919         ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n");
1920         ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1921 
1922         pAcquireSRWLockShared(&condvar_srwlock);
1923         ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, CONDITION_VARIABLE_LOCKMODE_SHARED);
1924         pReleaseSRWLockShared(&condvar_srwlock);
1925 
1926         ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n");
1927         ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1928     }
1929 
1930 
1931     hp = CreateThread(NULL, 0, condvar_base_producer, NULL, 0, &dummy);
1932     hc = CreateThread(NULL, 0, condvar_base_consumer, NULL, 0, &dummy);
1933 
1934     condvar_seq = 1; /* go */
1935 
1936     while (condvar_seq < 9)
1937         Sleep (5);
1938     WaitForSingleObject(hp, 100);
1939     WaitForSingleObject(hc, 100);
1940 }
1941 
1942 static LONG srwlock_seq = 0;
1943 static SRWLOCK srwlock_base;
1944 static struct
1945 {
1946     LONG wrong_execution_order;
1947     LONG samethread_excl_excl;
1948     LONG samethread_excl_shared;
1949     LONG samethread_shared_excl;
1950     LONG multithread_excl_excl;
1951     LONG excl_not_preferred;
1952     LONG trylock_excl;
1953     LONG trylock_shared;
1954 } srwlock_base_errors;
1955 
1956 /* Sequence of acquire/release to check boundary conditions:
1957  *  0: init
1958  *
1959  *  1: thread2 acquires an exclusive lock and tries to acquire a second exclusive lock
1960  *  2: thread1 expects a deadlock and releases the waiting lock
1961  *     thread2 releases the lock again
1962  *
1963  *  3: thread2 acquires an exclusive lock and tries to acquire a shared lock
1964  *  4: thread1 expects a deadlock and releases the waiting lock
1965  *     thread2 releases the lock again
1966  *
1967  *  5: thread2 acquires a shared lock and tries to acquire an exclusive lock
1968  *  6: thread1 expects a deadlock and releases the waiting lock
1969  *     thread2 releases the lock again
1970  *
1971  *  7: thread2 acquires and releases two nested shared locks
1972  *
1973  *  8: thread1 acquires an exclusive lock
1974  *  9: thread2 tries to acquire the exclusive lock, too
1975  *     thread1 releases the exclusive lock again
1976  * 10: thread2 enters the exclusive lock and leaves it immediately again
1977  *
1978  * 11: thread1 acquires a shared lock
1979  * 12: thread2 acquires and releases a shared lock
1980  *     thread1 releases the lock again
1981  *
1982  * 13: thread1 acquires a shared lock
1983  * 14: thread2 tries to acquire an exclusive lock
1984  * 15: thread3 tries to acquire a shared lock
1985  * 16: thread1 releases the shared lock
1986  * 17: thread2 wakes up and releases the exclusive lock
1987  * 18: thread3 wakes up and releases the shared lock
1988  *
1989  * the following tests will only be executed if TryAcquireSRWLock* is available
1990  *
1991  * 19: thread1 calls TryAcquireSRWLockExclusive which should return TRUE
1992  *     thread1 checks the result of recursive calls to TryAcquireSRWLock*
1993  *     thread1 releases the exclusive lock
1994  *
1995  *     thread1 calls TryAcquireSRWLockShared which should return TRUE
1996  *     thread1 checks the result of recursive calls to TryAcquireSRWLock*
1997  *     thread1 releases the shared lock
1998  *
1999  *     thread1 acquires an exclusive lock
2000  * 20: thread2 calls TryAcquireSRWLockShared which should return FALSE
2001  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2002  * 21: thread1 releases the exclusive lock
2003  *
2004  *     thread1 acquires an shared lock
2005  * 22: thread2 calls TryAcquireSRWLockShared which should return TRUE
2006  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2007  * 23: thread1 releases the shared lock
2008  *
2009  *     thread1 acquires a shared lock and tries to acquire an exclusive lock
2010  * 24: thread2 calls TryAcquireSRWLockShared which should return FALSE
2011  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2012  * 25: thread1 releases the exclusive lock
2013  *
2014  *     thread1 acquires two shared locks
2015  * 26: thread2 calls TryAcquireSRWLockShared which should return TRUE
2016  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2017  * 27: thread1 releases one shared lock
2018  * 28: thread2 calls TryAcquireSRWLockShared which should return TRUE
2019  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2020  * 29: thread1 releases the second shared lock
2021  * 30: thread2 calls TryAcquireSRWLockShared which should return TRUE
2022  *     thread2 calls TryAcquireSRWLockExclusive which should return TRUE
2023  *
2024  * 31: end
2025  */
2026 
2027 static DWORD WINAPI srwlock_base_thread1(LPVOID x)
2028 {
2029     /* seq 2 */
2030     while (srwlock_seq < 2) Sleep(1);
2031     Sleep(100);
2032     if (InterlockedIncrement(&srwlock_seq) != 3)
2033         InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
2034     pReleaseSRWLockExclusive(&srwlock_base);
2035 
2036     /* seq 4 */
2037     while (srwlock_seq < 4) Sleep(1);
2038     Sleep(100);
2039     if (InterlockedIncrement(&srwlock_seq) != 5)
2040         InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
2041     pReleaseSRWLockExclusive(&srwlock_base);
2042 
2043     /* seq 6 */
2044     while (srwlock_seq < 6) Sleep(1);
2045     Sleep(100);
2046     if (InterlockedIncrement(&srwlock_seq) != 7)
2047         InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
2048     pReleaseSRWLockShared(&srwlock_base);
2049 
2050     /* seq 8 */
2051     while (srwlock_seq < 8) Sleep(1);
2052     pAcquireSRWLockExclusive(&srwlock_base);
2053     if (InterlockedIncrement(&srwlock_seq) != 9)
2054         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2055     Sleep(100);
2056     if (InterlockedIncrement(&srwlock_seq) != 10)
2057         InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
2058     pReleaseSRWLockExclusive(&srwlock_base);
2059 
2060     /* seq 11 */
2061     while (srwlock_seq < 11) Sleep(1);
2062     pAcquireSRWLockShared(&srwlock_base);
2063     if (InterlockedIncrement(&srwlock_seq) != 12)
2064         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2065 
2066     /* seq 13 */
2067     while (srwlock_seq < 13) Sleep(1);
2068     pReleaseSRWLockShared(&srwlock_base);
2069     pAcquireSRWLockShared(&srwlock_base);
2070     if (InterlockedIncrement(&srwlock_seq) != 14)
2071         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2072 
2073     /* seq 16 */
2074     while (srwlock_seq < 16) Sleep(1);
2075     Sleep(50); /* ensure that both the exclusive and shared access thread are queued */
2076     if (InterlockedIncrement(&srwlock_seq) != 17)
2077         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2078     pReleaseSRWLockShared(&srwlock_base);
2079 
2080     /* skip over remaining tests if TryAcquireSRWLock* is not available */
2081     if (!pTryAcquireSRWLockExclusive)
2082         return 0;
2083 
2084     /* seq 19 */
2085     while (srwlock_seq < 19) Sleep(1);
2086     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2087     {
2088         if (pTryAcquireSRWLockShared(&srwlock_base))
2089             InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2090         if (pTryAcquireSRWLockExclusive(&srwlock_base))
2091             InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2092         pReleaseSRWLockExclusive(&srwlock_base);
2093     }
2094     else
2095         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2096 
2097     if (pTryAcquireSRWLockShared(&srwlock_base))
2098     {
2099         if (pTryAcquireSRWLockShared(&srwlock_base))
2100             pReleaseSRWLockShared(&srwlock_base);
2101         else
2102             InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2103         if (pTryAcquireSRWLockExclusive(&srwlock_base))
2104             InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2105         pReleaseSRWLockShared(&srwlock_base);
2106     }
2107     else
2108         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2109 
2110     pAcquireSRWLockExclusive(&srwlock_base);
2111     if (InterlockedIncrement(&srwlock_seq) != 20)
2112         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2113 
2114     /* seq 21 */
2115     while (srwlock_seq < 21) Sleep(1);
2116     pReleaseSRWLockExclusive(&srwlock_base);
2117     pAcquireSRWLockShared(&srwlock_base);
2118     if (InterlockedIncrement(&srwlock_seq) != 22)
2119         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2120 
2121     /* seq 23 */
2122     while (srwlock_seq < 23) Sleep(1);
2123     pReleaseSRWLockShared(&srwlock_base);
2124     pAcquireSRWLockShared(&srwlock_base);
2125     if (InterlockedIncrement(&srwlock_seq) != 24)
2126         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2127 
2128     /* seq 25 */
2129     pAcquireSRWLockExclusive(&srwlock_base);
2130     if (srwlock_seq != 25)
2131         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2132     pReleaseSRWLockExclusive(&srwlock_base);
2133 
2134     pAcquireSRWLockShared(&srwlock_base);
2135     pAcquireSRWLockShared(&srwlock_base);
2136     if (InterlockedIncrement(&srwlock_seq) != 26)
2137         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2138 
2139     /* seq 27 */
2140     while (srwlock_seq < 27) Sleep(1);
2141     pReleaseSRWLockShared(&srwlock_base);
2142     if (InterlockedIncrement(&srwlock_seq) != 28)
2143         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2144 
2145     /* seq 29 */
2146     while (srwlock_seq < 29) Sleep(1);
2147     pReleaseSRWLockShared(&srwlock_base);
2148     if (InterlockedIncrement(&srwlock_seq) != 30)
2149         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2150 
2151     return 0;
2152 }
2153 
2154 static DWORD WINAPI srwlock_base_thread2(LPVOID x)
2155 {
2156     /* seq 1 */
2157     while (srwlock_seq < 1) Sleep(1);
2158     pAcquireSRWLockExclusive(&srwlock_base);
2159     if (InterlockedIncrement(&srwlock_seq) != 2)
2160         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2161 
2162     /* seq 3 */
2163     pAcquireSRWLockExclusive(&srwlock_base);
2164     if (srwlock_seq != 3)
2165         InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
2166     pReleaseSRWLockExclusive(&srwlock_base);
2167     pAcquireSRWLockExclusive(&srwlock_base);
2168     if (InterlockedIncrement(&srwlock_seq) != 4)
2169         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2170 
2171     /* seq 5 */
2172     pAcquireSRWLockShared(&srwlock_base);
2173     if (srwlock_seq != 5)
2174         InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
2175     pReleaseSRWLockShared(&srwlock_base);
2176     pAcquireSRWLockShared(&srwlock_base);
2177     if (InterlockedIncrement(&srwlock_seq) != 6)
2178         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2179 
2180     /* seq 7 */
2181     pAcquireSRWLockExclusive(&srwlock_base);
2182     if (srwlock_seq != 7)
2183         InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
2184     pReleaseSRWLockExclusive(&srwlock_base);
2185     pAcquireSRWLockShared(&srwlock_base);
2186     pAcquireSRWLockShared(&srwlock_base);
2187     pReleaseSRWLockShared(&srwlock_base);
2188     pReleaseSRWLockShared(&srwlock_base);
2189     if (InterlockedIncrement(&srwlock_seq) != 8)
2190         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2191 
2192     /* seq 9, 10 */
2193     while (srwlock_seq < 9) Sleep(1);
2194     pAcquireSRWLockExclusive(&srwlock_base);
2195     if (srwlock_seq != 10)
2196         InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
2197     pReleaseSRWLockExclusive(&srwlock_base);
2198     if (InterlockedIncrement(&srwlock_seq) != 11)
2199         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2200 
2201     /* seq 12 */
2202     while (srwlock_seq < 12) Sleep(1);
2203     pAcquireSRWLockShared(&srwlock_base);
2204     pReleaseSRWLockShared(&srwlock_base);
2205     if (InterlockedIncrement(&srwlock_seq) != 13)
2206         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2207 
2208     /* seq 14 */
2209     while (srwlock_seq < 14) Sleep(1);
2210     if (InterlockedIncrement(&srwlock_seq) != 15)
2211         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2212 
2213     /* seq 17 */
2214     pAcquireSRWLockExclusive(&srwlock_base);
2215     if (srwlock_seq != 17)
2216         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2217     if (InterlockedIncrement(&srwlock_seq) != 18)
2218         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2219     pReleaseSRWLockExclusive(&srwlock_base);
2220 
2221     /* skip over remaining tests if TryAcquireSRWLock* is not available */
2222     if (!pTryAcquireSRWLockExclusive)
2223         return 0;
2224 
2225     /* seq 20 */
2226     while (srwlock_seq < 20) Sleep(1);
2227     if (pTryAcquireSRWLockShared(&srwlock_base))
2228         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2229     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2230         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2231     if (InterlockedIncrement(&srwlock_seq) != 21)
2232         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2233 
2234     /* seq 22 */
2235     while (srwlock_seq < 22) Sleep(1);
2236     if (pTryAcquireSRWLockShared(&srwlock_base))
2237         pReleaseSRWLockShared(&srwlock_base);
2238     else
2239         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2240     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2241         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2242     if (InterlockedIncrement(&srwlock_seq) != 23)
2243         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2244 
2245     /* seq 24 */
2246     while (srwlock_seq < 24) Sleep(1);
2247     Sleep(50); /* ensure that exclusive access request is queued */
2248     if (pTryAcquireSRWLockShared(&srwlock_base))
2249     {
2250         pReleaseSRWLockShared(&srwlock_base);
2251         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2252     }
2253     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2254         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2255     if (InterlockedIncrement(&srwlock_seq) != 25)
2256         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2257     pReleaseSRWLockShared(&srwlock_base);
2258 
2259     /* seq 26 */
2260     while (srwlock_seq < 26) Sleep(1);
2261     if (pTryAcquireSRWLockShared(&srwlock_base))
2262         pReleaseSRWLockShared(&srwlock_base);
2263     else
2264         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2265     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2266         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2267     if (InterlockedIncrement(&srwlock_seq) != 27)
2268         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2269 
2270     /* seq 28 */
2271     while (srwlock_seq < 28) Sleep(1);
2272     if (pTryAcquireSRWLockShared(&srwlock_base))
2273         pReleaseSRWLockShared(&srwlock_base);
2274     else
2275         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2276     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2277         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2278     if (InterlockedIncrement(&srwlock_seq) != 29)
2279         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2280 
2281     /* seq 30 */
2282     while (srwlock_seq < 30) Sleep(1);
2283     if (pTryAcquireSRWLockShared(&srwlock_base))
2284         pReleaseSRWLockShared(&srwlock_base);
2285     else
2286         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2287     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2288         pReleaseSRWLockExclusive(&srwlock_base);
2289     else
2290         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2291     if (InterlockedIncrement(&srwlock_seq) != 31)
2292         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2293 
2294     return 0;
2295 }
2296 
2297 static DWORD WINAPI srwlock_base_thread3(LPVOID x)
2298 {
2299     /* seq 15 */
2300     while (srwlock_seq < 15) Sleep(1);
2301     Sleep(50); /* some delay, so that thread2 can try to acquire a second exclusive lock */
2302     if (InterlockedIncrement(&srwlock_seq) != 16)
2303         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2304 
2305     /* seq 18 */
2306     pAcquireSRWLockShared(&srwlock_base);
2307     if (srwlock_seq != 18)
2308         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2309     pReleaseSRWLockShared(&srwlock_base);
2310     if (InterlockedIncrement(&srwlock_seq) != 19)
2311         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2312 
2313     /* skip over remaining tests if TryAcquireSRWLock* is not available */
2314     if (!pTryAcquireSRWLockExclusive)
2315     {
2316         /* function is only in Windows 7 and newer */
2317         win_skip("no srw trylock support.\n");
2318         srwlock_seq = 31; /* end */
2319         return 0;
2320     }
2321 
2322     return 0;
2323 }
2324 
2325 static void test_srwlock_base(void)
2326 {
2327     HANDLE h1, h2, h3;
2328     DWORD dummy;
2329 
2330     if (!pInitializeSRWLock)
2331     {
2332         /* function is not yet in XP, only in newer Windows */
2333         win_skip("no srw lock support.\n");
2334         return;
2335     }
2336 
2337     pInitializeSRWLock(&srwlock_base);
2338     memset(&srwlock_base_errors, 0, sizeof(srwlock_base_errors));
2339 
2340     h1 = CreateThread(NULL, 0, srwlock_base_thread1, NULL, 0, &dummy);
2341     h2 = CreateThread(NULL, 0, srwlock_base_thread2, NULL, 0, &dummy);
2342     h3 = CreateThread(NULL, 0, srwlock_base_thread3, NULL, 0, &dummy);
2343 
2344     srwlock_seq = 1; /* go */
2345     while (srwlock_seq < 31)
2346         Sleep(5);
2347 
2348     WaitForSingleObject(h1, 100);
2349     WaitForSingleObject(h2, 100);
2350     WaitForSingleObject(h3, 100);
2351 
2352     ok(!srwlock_base_errors.wrong_execution_order,
2353             "thread commands were executed in the wrong order (occurred %d times).\n",
2354             srwlock_base_errors.wrong_execution_order);
2355 
2356     ok(!srwlock_base_errors.samethread_excl_excl,
2357             "AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred %d times).\n",
2358             srwlock_base_errors.samethread_excl_excl);
2359 
2360     ok(!srwlock_base_errors.samethread_excl_shared,
2361             "AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred %d times).\n",
2362             srwlock_base_errors.samethread_excl_shared);
2363 
2364     ok(!srwlock_base_errors.samethread_shared_excl,
2365             "AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred %d times).\n",
2366             srwlock_base_errors.samethread_shared_excl);
2367 
2368     ok(!srwlock_base_errors.multithread_excl_excl,
2369             "AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred %d times).\n",
2370             srwlock_base_errors.multithread_excl_excl);
2371 
2372     ok(!srwlock_base_errors.excl_not_preferred,
2373             "thread waiting for exclusive access to the SHMLock was not preferred (occurred %d times).\n",
2374             srwlock_base_errors.excl_not_preferred);
2375 
2376     ok(!srwlock_base_errors.trylock_excl,
2377             "TryAcquireSRWLockExclusive didn't behave as expected (occurred %d times).\n",
2378             srwlock_base_errors.trylock_excl);
2379 
2380     ok(!srwlock_base_errors.trylock_shared,
2381             "TryAcquireSRWLockShared didn't behave as expected (occurred %d times).\n",
2382             srwlock_base_errors.trylock_shared);
2383 
2384 }
2385 
2386 static SRWLOCK srwlock_example;
2387 static LONG srwlock_protected_value = 0;
2388 static LONG srwlock_example_errors = 0, srwlock_inside = 0, srwlock_cnt = 0;
2389 static BOOL srwlock_stop = FALSE;
2390 
2391 static DWORD WINAPI srwlock_example_thread(LPVOID x) {
2392     DWORD *cnt = x;
2393     LONG old;
2394 
2395     while (!srwlock_stop)
2396     {
2397 
2398         /* periodically request exclusive access */
2399         if (InterlockedIncrement(&srwlock_cnt) % 13 == 0)
2400         {
2401             pAcquireSRWLockExclusive(&srwlock_example);
2402             if (InterlockedIncrement(&srwlock_inside) != 1)
2403                 InterlockedIncrement(&srwlock_example_errors);
2404 
2405             InterlockedIncrement(&srwlock_protected_value);
2406             Sleep(1);
2407 
2408             if (InterlockedDecrement(&srwlock_inside) != 0)
2409                 InterlockedIncrement(&srwlock_example_errors);
2410             pReleaseSRWLockExclusive(&srwlock_example);
2411         }
2412 
2413         /* request shared access */
2414         pAcquireSRWLockShared(&srwlock_example);
2415         InterlockedIncrement(&srwlock_inside);
2416         old = srwlock_protected_value;
2417 
2418         (*cnt)++;
2419         Sleep(1);
2420 
2421         if (old != srwlock_protected_value)
2422             InterlockedIncrement(&srwlock_example_errors);
2423         InterlockedDecrement(&srwlock_inside);
2424         pReleaseSRWLockShared(&srwlock_example);
2425     }
2426 
2427     return 0;
2428 }
2429 
2430 static void test_srwlock_example(void)
2431 {
2432     HANDLE h1, h2, h3;
2433     DWORD dummy;
2434     DWORD cnt1, cnt2, cnt3;
2435 
2436     if (!pInitializeSRWLock) {
2437         /* function is not yet in XP, only in newer Windows */
2438         win_skip("no srw lock support.\n");
2439         return;
2440     }
2441 
2442     pInitializeSRWLock(&srwlock_example);
2443 
2444     cnt1 = cnt2 = cnt3 = 0;
2445 
2446     h1 = CreateThread(NULL, 0, srwlock_example_thread, &cnt1, 0, &dummy);
2447     h2 = CreateThread(NULL, 0, srwlock_example_thread, &cnt2, 0, &dummy);
2448     h3 = CreateThread(NULL, 0, srwlock_example_thread, &cnt3, 0, &dummy);
2449 
2450     /* limit run to 1 second. */
2451     Sleep(1000);
2452 
2453     /* tear down start */
2454     srwlock_stop = TRUE;
2455 
2456     WaitForSingleObject(h1, 1000);
2457     WaitForSingleObject(h2, 1000);
2458     WaitForSingleObject(h3, 1000);
2459 
2460     ok(!srwlock_inside, "threads didn't terminate properly, srwlock_inside is %d.\n", srwlock_inside);
2461     ok(!srwlock_example_errors, "errors occurred while running SRWLock example test (number of errors: %d)\n",
2462             srwlock_example_errors);
2463 
2464     trace("number of shared accesses per thread are c1 %d, c2 %d, c3 %d\n", cnt1, cnt2, cnt3);
2465     trace("number of total exclusive accesses is %d\n", srwlock_protected_value);
2466 }
2467 
2468 static DWORD WINAPI alertable_wait_thread(void *param)
2469 {
2470     HANDLE *semaphores = param;
2471     LARGE_INTEGER timeout;
2472     NTSTATUS status;
2473     DWORD result;
2474 
2475     ReleaseSemaphore(semaphores[0], 1, NULL);
2476     result = WaitForMultipleObjectsEx(1, &semaphores[1], TRUE, 1000, TRUE);
2477     ok(result == WAIT_IO_COMPLETION, "expected WAIT_IO_COMPLETION, got %u\n", result);
2478     result = WaitForMultipleObjectsEx(1, &semaphores[1], TRUE, 200, TRUE);
2479     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2480 
2481     ReleaseSemaphore(semaphores[0], 1, NULL);
2482     timeout.QuadPart = -10000000;
2483     status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2484     ok(status == STATUS_USER_APC, "expected STATUS_USER_APC, got %08x\n", status);
2485     timeout.QuadPart = -2000000;
2486     status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2487     ok(status == STATUS_WAIT_0, "expected STATUS_WAIT_0, got %08x\n", status);
2488 
2489     ReleaseSemaphore(semaphores[0], 1, NULL);
2490     timeout.QuadPart = -10000000;
2491     status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2492     ok(status == STATUS_USER_APC, "expected STATUS_USER_APC, got %08x\n", status);
2493     result = WaitForSingleObject(semaphores[0], 0);
2494     ok(result == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", result);
2495 
2496     return 0;
2497 }
2498 
2499 static void CALLBACK alertable_wait_apc(ULONG_PTR userdata)
2500 {
2501     HANDLE *semaphores = (void *)userdata;
2502     ReleaseSemaphore(semaphores[1], 1, NULL);
2503 }
2504 
2505 static void CALLBACK alertable_wait_apc2(ULONG_PTR userdata)
2506 {
2507     HANDLE *semaphores = (void *)userdata;
2508     DWORD result;
2509 
2510     result = WaitForSingleObject(semaphores[0], 1000);
2511     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2512 }
2513 
2514 static void test_alertable_wait(void)
2515 {
2516     HANDLE thread, semaphores[2];
2517     DWORD result;
2518 
2519     semaphores[0] = CreateSemaphoreW(NULL, 0, 2, NULL);
2520     ok(semaphores[0] != NULL, "CreateSemaphore failed with %u\n", GetLastError());
2521     semaphores[1] = CreateSemaphoreW(NULL, 0, 1, NULL);
2522     ok(semaphores[1] != NULL, "CreateSemaphore failed with %u\n", GetLastError());
2523     thread = CreateThread(NULL, 0, alertable_wait_thread, semaphores, 0, NULL);
2524     ok(thread != NULL, "CreateThread failed with %u\n", GetLastError());
2525 
2526     result = WaitForSingleObject(semaphores[0], 1000);
2527     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2528     Sleep(100); /* ensure the thread is blocking in WaitForMultipleObjectsEx */
2529     result = QueueUserAPC(alertable_wait_apc, thread, (ULONG_PTR)semaphores);
2530     ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2531 
2532     result = WaitForSingleObject(semaphores[0], 1000);
2533     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2534     Sleep(100); /* ensure the thread is blocking in NtWaitForMultipleObjects */
2535     result = QueueUserAPC(alertable_wait_apc, thread, (ULONG_PTR)semaphores);
2536     ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2537 
2538     result = WaitForSingleObject(semaphores[0], 1000);
2539     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2540     Sleep(100); /* ensure the thread is blocking in NtWaitForMultipleObjects */
2541     result = QueueUserAPC(alertable_wait_apc2, thread, (ULONG_PTR)semaphores);
2542     ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2543     result = QueueUserAPC(alertable_wait_apc2, thread, (ULONG_PTR)semaphores);
2544     ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2545     ReleaseSemaphore(semaphores[0], 2, NULL);
2546 
2547     result = WaitForSingleObject(thread, 1000);
2548     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2549     CloseHandle(thread);
2550     CloseHandle(semaphores[0]);
2551     CloseHandle(semaphores[1]);
2552 }
2553 
2554 struct apc_deadlock_info
2555 {
2556     PROCESS_INFORMATION *pi;
2557     HANDLE event;
2558     BOOL running;
2559 };
2560 
2561 static DWORD WINAPI apc_deadlock_thread(void *param)
2562 {
2563     struct apc_deadlock_info *info = param;
2564     PROCESS_INFORMATION *pi = info->pi;
2565     NTSTATUS status;
2566     SIZE_T size;
2567     void *base;
2568 
2569     while (info->running)
2570     {
2571         base = NULL;
2572         size = 0x1000;
2573         status = pNtAllocateVirtualMemory(pi->hProcess, &base, 0, &size,
2574                                           MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
2575         disable_success_count
2576         ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
2577         ok(base != NULL, "expected base != NULL, got %p\n", base);
2578         SetEvent(info->event);
2579 
2580         size = 0;
2581         status = pNtFreeVirtualMemory(pi->hProcess, &base, &size, MEM_RELEASE);
2582         disable_success_count
2583         ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
2584         SetEvent(info->event);
2585     }
2586 
2587     return 0;
2588 }
2589 
2590 static void test_apc_deadlock(void)
2591 {
2592     struct apc_deadlock_info info;
2593     PROCESS_INFORMATION pi;
2594     STARTUPINFOA si = { sizeof(si) };
2595     char cmdline[MAX_PATH];
2596     HANDLE event, thread;
2597     DWORD result;
2598     BOOL success;
2599     char **argv;
2600     int i;
2601 
2602     winetest_get_mainargs(&argv);
2603     sprintf(cmdline, "\"%s\" sync apc_deadlock", argv[0]);
2604     success = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
2605     ok(success, "CreateProcess failed with %u\n", GetLastError());
2606 
2607     event = CreateEventA(NULL, FALSE, FALSE, NULL);
2608     ok(event != NULL, "CreateEvent failed with %u\n", GetLastError());
2609 
2610     info.pi = &pi;
2611     info.event = event;
2612     info.running = TRUE;
2613 
2614     thread = CreateThread(NULL, 0, apc_deadlock_thread, &info, 0, NULL);
2615     ok(thread != NULL, "CreateThread failed with %u\n", GetLastError());
2616     result = WaitForSingleObject(event, 1000);
2617     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2618 
2619     disable_success_count
2620     for (i = 0; i < 1000; i++)
2621     {
2622         result = SuspendThread(pi.hThread);
2623         ok(result == 0, "expected 0, got %u\n", result);
2624 
2625         WaitForSingleObject(event, 0); /* reset event */
2626         result = WaitForSingleObject(event, 1000);
2627         ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2628 
2629         result = ResumeThread(pi.hThread);
2630         ok(result == 1, "expected 1, got %u\n", result);
2631         Sleep(1);
2632     }
2633 
2634     info.running = FALSE;
2635     result = WaitForSingleObject(thread, 1000);
2636     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2637     CloseHandle(thread);
2638     CloseHandle(event);
2639 
2640     TerminateProcess(pi.hProcess, 0);
2641     CloseHandle(pi.hThread);
2642     CloseHandle(pi.hProcess);
2643 }
2644 
2645 START_TEST(sync)
2646 {
2647     char **argv;
2648     int argc;
2649     HMODULE hdll = GetModuleHandleA("kernel32.dll");
2650     HMODULE hntdll = GetModuleHandleA("ntdll.dll");
2651 #ifdef __REACTOS__
2652     HMODULE hdll_vista = GetModuleHandleA("kernel32_vista.dll");
2653 #endif
2654 
2655     pInitOnceInitialize = (void *)GetProcAddress(hdll, "InitOnceInitialize");
2656     pInitOnceExecuteOnce = (void *)GetProcAddress(hdll, "InitOnceExecuteOnce");
2657     pInitOnceBeginInitialize = (void *)GetProcAddress(hdll, "InitOnceBeginInitialize");
2658     pInitOnceComplete = (void *)GetProcAddress(hdll, "InitOnceComplete");
2659     pInitializeConditionVariable = (void *)GetProcAddress(hdll, "InitializeConditionVariable");
2660     pSleepConditionVariableCS = (void *)GetProcAddress(hdll, "SleepConditionVariableCS");
2661     pSleepConditionVariableSRW = (void *)GetProcAddress(hdll, "SleepConditionVariableSRW");
2662     pWakeAllConditionVariable = (void *)GetProcAddress(hdll, "WakeAllConditionVariable");
2663     pWakeConditionVariable = (void *)GetProcAddress(hdll, "WakeConditionVariable");
2664     pInitializeSRWLock = (void *)GetProcAddress(hdll, "InitializeSRWLock");
2665     pAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "AcquireSRWLockExclusive");
2666     pAcquireSRWLockShared = (void *)GetProcAddress(hdll, "AcquireSRWLockShared");
2667     pReleaseSRWLockExclusive = (void *)GetProcAddress(hdll, "ReleaseSRWLockExclusive");
2668     pReleaseSRWLockShared = (void *)GetProcAddress(hdll, "ReleaseSRWLockShared");
2669     pTryAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "TryAcquireSRWLockExclusive");
2670     pTryAcquireSRWLockShared = (void *)GetProcAddress(hdll, "TryAcquireSRWLockShared");
2671     pNtAllocateVirtualMemory = (void *)GetProcAddress(hntdll, "NtAllocateVirtualMemory");
2672     pNtFreeVirtualMemory = (void *)GetProcAddress(hntdll, "NtFreeVirtualMemory");
2673     pNtWaitForSingleObject = (void *)GetProcAddress(hntdll, "NtWaitForSingleObject");
2674     pNtWaitForMultipleObjects = (void *)GetProcAddress(hntdll, "NtWaitForMultipleObjects");
2675     pRtlInterlockedPushListSList = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSList");
2676     pRtlInterlockedPushListSListEx = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSListEx");
2677 
2678 #ifdef __REACTOS__
2679     if (!pInitializeConditionVariable)
2680     {
2681         pInitializeConditionVariable = (void *)GetProcAddress(hdll_vista, "InitializeConditionVariable");
2682         pSleepConditionVariableCS = (void *)GetProcAddress(hdll_vista, "SleepConditionVariableCS");
2683         pSleepConditionVariableSRW = (void *)GetProcAddress(hdll_vista, "SleepConditionVariableSRW");
2684         pWakeAllConditionVariable = (void *)GetProcAddress(hdll_vista, "WakeAllConditionVariable");
2685         pWakeConditionVariable = (void *)GetProcAddress(hdll_vista, "WakeConditionVariable");
2686     }
2687 
2688     if (!pInitializeSRWLock)
2689     {
2690         pInitializeSRWLock = (void *)GetProcAddress(hdll_vista, "InitializeSRWLock");
2691         pAcquireSRWLockExclusive = (void *)GetProcAddress(hdll_vista, "AcquireSRWLockExclusive");
2692         pAcquireSRWLockShared = (void *)GetProcAddress(hdll_vista, "AcquireSRWLockShared");
2693         pReleaseSRWLockExclusive = (void *)GetProcAddress(hdll_vista, "ReleaseSRWLockExclusive");
2694         pReleaseSRWLockShared = (void *)GetProcAddress(hdll_vista, "ReleaseSRWLockShared");
2695         pTryAcquireSRWLockExclusive = (void *)GetProcAddress(hdll_vista, "TryAcquireSRWLockExclusive");
2696         pTryAcquireSRWLockShared = (void *)GetProcAddress(hdll_vista, "TryAcquireSRWLockShared");
2697     }
2698 #endif
2699 
2700     argc = winetest_get_mainargs( &argv );
2701     if (argc >= 3)
2702     {
2703         if (!strcmp(argv[2], "apc_deadlock"))
2704         {
2705             for (;;) SleepEx(INFINITE, TRUE);
2706         }
2707         return;
2708     }
2709 
2710     init_fastcall_thunk();
2711     test_signalandwait();
2712     test_mutex();
2713     test_slist();
2714     test_event();
2715     test_semaphore();
2716     test_waitable_timer();
2717     test_iocp_callback();
2718     test_timer_queue();
2719     test_WaitForSingleObject();
2720     test_WaitForMultipleObjects();
2721     test_initonce();
2722     test_condvars_base();
2723     test_condvars_consumer_producer();
2724     test_srwlock_base();
2725     test_srwlock_example();
2726     test_alertable_wait();
2727     test_apc_deadlock();
2728 }
2729