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     ok(timedOut, "Timer callbacks should always time out\n");
782     ++*pn;
783 }
784 
785 struct timer_queue_data1
786 {
787     int num_calls;
788     int max_calls;
789     HANDLE q, t;
790 };
791 
792 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
793 {
794     struct timer_queue_data1 *d = p;
795     ok(timedOut, "Timer callbacks should always time out\n");
796     if (d->t && ++d->num_calls == d->max_calls)
797     {
798         BOOL ret;
799         SetLastError(0xdeadbeef);
800         /* Note, XP SP2 does *not* do any deadlock checking, so passing
801            INVALID_HANDLE_VALUE here will just hang.  */
802         ret = DeleteTimerQueueTimer(d->q, d->t, NULL);
803         ok(!ret, "DeleteTimerQueueTimer\n");
804         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
805     }
806 }
807 
808 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
809 {
810     struct timer_queue_data1 *d = p;
811     ok(timedOut, "Timer callbacks should always time out\n");
812     if (d->t && ++d->num_calls == d->max_calls)
813     {
814         /* Basically kill the timer since it won't have time to run
815            again.  */
816         BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 10000, 0);
817         ok(ret, "ChangeTimerQueueTimer\n");
818     }
819 }
820 
821 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
822 {
823     struct timer_queue_data1 *d = p;
824     ok(timedOut, "Timer callbacks should always time out\n");
825     if (d->t)
826     {
827         /* This tests whether a timer gets flagged for deletion before
828            or after the callback runs.  If we start this timer with a
829            period of zero (run once), then ChangeTimerQueueTimer will
830            fail if the timer is already flagged.  Hence we really run
831            only once.  Otherwise we will run multiple times.  */
832         BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 50, 50);
833         ok(ret, "ChangeTimerQueueTimer\n");
834         ++d->num_calls;
835     }
836 }
837 
838 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
839 {
840     DWORD_PTR delay = (DWORD_PTR) p;
841     ok(timedOut, "Timer callbacks should always time out\n");
842     if (delay)
843         Sleep(delay);
844 }
845 
846 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
847 {
848     struct timer_queue_data1 *d = p;
849     ok(timedOut, "Timer callbacks should always time out\n");
850     /* This tests an original implementation bug where a deleted timer may get
851        to run, but it is tricky to set up.  */
852     if (d->q && d->num_calls++ == 0)
853     {
854         /* First run: delete ourselves, then insert and remove a timer
855            that goes in front of us in the sorted timeout list.  Once
856            removed, we will still timeout at the faster timer's due time,
857            but this should be a no-op if we are bug-free.  There should
858            not be a second run.  We can test the value of num_calls later.  */
859         BOOL ret;
860         HANDLE t;
861 
862         /* The delete will pend while we are in this callback.  */
863         SetLastError(0xdeadbeef);
864         ret = DeleteTimerQueueTimer(d->q, d->t, NULL);
865         ok(!ret, "DeleteTimerQueueTimer\n");
866         ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
867 
868         ret = CreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
869         ok(ret, "CreateTimerQueueTimer\n");
870         ok(t != NULL, "CreateTimerQueueTimer\n");
871 
872         ret = DeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
873         ok(ret, "DeleteTimerQueueTimer\n");
874 
875         /* Now we stay alive by hanging around in the callback.  */
876         Sleep(500);
877     }
878 }
879 
880 static void test_timer_queue(void)
881 {
882     HANDLE q, t0, t1, t2, t3, t4, t5;
883     int n0, n1, n2, n3, n4, n5;
884     struct timer_queue_data1 d1, d2, d3, d4;
885     HANDLE e, et1, et2;
886     BOOL ret, ret0;
887 
888     /* Test asynchronous deletion of the queue. */
889     q = CreateTimerQueue();
890     ok(q != NULL, "CreateTimerQueue\n");
891 
892     SetLastError(0xdeadbeef);
893     ret = DeleteTimerQueueEx(q, NULL);
894     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
895        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
896        GetLastError());
897 
898     /* Test synchronous deletion of the queue and running timers. */
899     q = CreateTimerQueue();
900     ok(q != NULL, "CreateTimerQueue\n");
901 
902     /* Not called. */
903     t0 = NULL;
904     n0 = 0;
905     ret = CreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0, 300, 0);
906     ok(ret, "CreateTimerQueueTimer\n");
907     ok(t0 != NULL, "CreateTimerQueueTimer\n");
908     ret0 = DeleteTimerQueueTimer(q, t0, NULL);
909     ok((!ret0 && GetLastError() == ERROR_IO_PENDING) ||
910        broken(ret0), /* Win 2000 & XP & 2003 */
911        "DeleteTimerQueueTimer ret=%d le=%u\n", ret0, GetLastError());
912 
913     /* Called once.  */
914     t1 = NULL;
915     n1 = 0;
916     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, 0, 0);
917     ok(ret, "CreateTimerQueueTimer\n");
918     ok(t1 != NULL, "CreateTimerQueueTimer\n");
919 
920     /* A slow one.  */
921     t2 = NULL;
922     n2 = 0;
923     ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, 100, 0);
924     ok(ret, "CreateTimerQueueTimer\n");
925     ok(t2 != NULL, "CreateTimerQueueTimer\n");
926 
927     /* A fast one.  */
928     t3 = NULL;
929     n3 = 0;
930     ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, 10, 0);
931     ok(ret, "CreateTimerQueueTimer\n");
932     ok(t3 != NULL, "CreateTimerQueueTimer\n");
933 
934     /* Start really late (it won't start).  */
935     t4 = NULL;
936     n4 = 0;
937     ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, 10, 0);
938     ok(ret, "CreateTimerQueueTimer\n");
939     ok(t4 != NULL, "CreateTimerQueueTimer\n");
940 
941     /* Start soon, but delay so long it won't run again.  */
942     t5 = NULL;
943     n5 = 0;
944     ret = CreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, 10000, 0);
945     ok(ret, "CreateTimerQueueTimer\n");
946     ok(t5 != NULL, "CreateTimerQueueTimer\n");
947 
948     /* Give them a chance to do some work.  */
949     Sleep(500);
950 
951     /* Test deleting a once-only timer.  */
952     ret = DeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
953     ok(ret, "DeleteTimerQueueTimer\n");
954 
955     /* A periodic timer.  */
956     ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
957     ok(ret, "DeleteTimerQueueTimer\n");
958 
959     ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
960     ok(ret, "DeleteTimerQueueEx\n");
961     todo_wine
962     ok(n0 == 1 || broken(ret0 && n0 == 0), "Timer callback 0 expected 1 got %d\n", n0);
963     ok(n1 == 1, "Timer callback 1 expected 1 got %d\n", n1);
964     ok(n2 < n3, "Timer callback 2 & 3 expected %d < %d\n", n2, n3);
965     ok(n4 == 0, "Timer callback 4 expected 0 got %d\n", n4);
966     ok(n5 == 1, "Timer callback 5 expected 1 got %d\n", n5);
967 
968     /* Test synchronous deletion of the timer/queue with event trigger. */
969     e = CreateEventW(NULL, TRUE, FALSE, NULL);
970     et1 = CreateEventW(NULL, TRUE, FALSE, NULL);
971     et2 = CreateEventW(NULL, TRUE, FALSE, NULL);
972     if (!e || !et1 || !et2)
973     {
974         skip("Failed to create timer queue descruction event\n");
975         return;
976     }
977 
978     q = CreateTimerQueue();
979     ok(q != NULL, "CreateTimerQueue\n");
980 
981     /* Run once and finish quickly (should be done when we delete it).  */
982     t1 = NULL;
983     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
984     ok(ret, "CreateTimerQueueTimer\n");
985     ok(t1 != NULL, "CreateTimerQueueTimer\n");
986 
987     /* Run once and finish slowly (shouldn't be done when we delete it).  */
988     t2 = NULL;
989     ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0);
990     ok(ret, "CreateTimerQueueTimer\n");
991     ok(t2 != NULL, "CreateTimerQueueTimer\n");
992 
993     /* Run once and finish quickly (should be done when we delete it).  */
994     t3 = NULL;
995     ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
996     ok(ret, "CreateTimerQueueTimer\n");
997     ok(t3 != NULL, "CreateTimerQueueTimer\n");
998 
999     /* Run once and finish slowly (shouldn't be done when we delete it).  */
1000     t4 = NULL;
1001     ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0);
1002     ok(ret, "CreateTimerQueueTimer\n");
1003     ok(t4 != NULL, "CreateTimerQueueTimer\n");
1004 
1005     /* Give them a chance to start.  */
1006     Sleep(400);
1007 
1008     /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
1009        even if the timer is finished.  */
1010     SetLastError(0xdeadbeef);
1011     ret = DeleteTimerQueueTimer(q, t1, NULL);
1012     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1013        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1014        GetLastError());
1015 
1016     SetLastError(0xdeadbeef);
1017     ret = DeleteTimerQueueTimer(q, t2, NULL);
1018     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
1019     ok(GetLastError() == ERROR_IO_PENDING,
1020        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1021        GetLastError());
1022 
1023     SetLastError(0xdeadbeef);
1024     ret = DeleteTimerQueueTimer(q, t3, et1);
1025     ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
1026     ok(GetLastError() == 0xdeadbeef,
1027        "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
1028        GetLastError());
1029     ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
1030        "Timer destruction event not triggered\n");
1031 
1032     SetLastError(0xdeadbeef);
1033     ret = DeleteTimerQueueTimer(q, t4, et2);
1034     ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
1035     ok(GetLastError() == ERROR_IO_PENDING,
1036        "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1037        GetLastError());
1038     ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
1039        "Timer destruction event not triggered\n");
1040 
1041     SetLastError(0xdeadbeef);
1042     ret = DeleteTimerQueueEx(q, e);
1043     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1044        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1045        GetLastError());
1046     ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
1047        "Queue destruction event not triggered\n");
1048     CloseHandle(e);
1049 
1050     /* Test deleting/changing a timer in execution.  */
1051     q = CreateTimerQueue();
1052     ok(q != NULL, "CreateTimerQueue\n");
1053 
1054     /* Test changing a once-only timer before it fires (this is allowed,
1055        whereas after it fires you cannot).  */
1056     n1 = 0;
1057     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000, 0, 0);
1058     ok(ret, "CreateTimerQueueTimer\n");
1059     ok(t1 != NULL, "CreateTimerQueueTimer\n");
1060     ret = ChangeTimerQueueTimer(q, t1, 0, 0);
1061     ok(ret, "ChangeTimerQueueTimer\n");
1062 
1063     d2.t = t2 = NULL;
1064     d2.num_calls = 0;
1065     d2.max_calls = 3;
1066     d2.q = q;
1067     ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10, 10, 0);
1068     d2.t = t2;
1069     ok(ret, "CreateTimerQueueTimer\n");
1070     ok(t2 != NULL, "CreateTimerQueueTimer\n");
1071 
1072     d3.t = t3 = NULL;
1073     d3.num_calls = 0;
1074     d3.max_calls = 4;
1075     d3.q = q;
1076     ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10, 10, 0);
1077     d3.t = t3;
1078     ok(ret, "CreateTimerQueueTimer\n");
1079     ok(t3 != NULL, "CreateTimerQueueTimer\n");
1080 
1081     d4.t = t4 = NULL;
1082     d4.num_calls = 0;
1083     d4.q = q;
1084     ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10, 0, 0);
1085     d4.t = t4;
1086     ok(ret, "CreateTimerQueueTimer\n");
1087     ok(t4 != NULL, "CreateTimerQueueTimer\n");
1088 
1089     Sleep(500);
1090 
1091     ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
1092     ok(ret, "DeleteTimerQueueEx\n");
1093     ok(n1 == 1, "ChangeTimerQueueTimer\n");
1094     ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
1095     ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
1096     ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
1097 
1098     /* Test an obscure bug that was in the original implementation.  */
1099     q = CreateTimerQueue();
1100     ok(q != NULL, "CreateTimerQueue\n");
1101 
1102     /* All the work is done in the callback.  */
1103     d1.t = t1 = NULL;
1104     d1.num_calls = 0;
1105     d1.q = q;
1106     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100, 100, WT_EXECUTELONGFUNCTION);
1107     d1.t = t1;
1108     ok(ret, "CreateTimerQueueTimer\n");
1109     ok(t1 != NULL, "CreateTimerQueueTimer\n");
1110 
1111     Sleep(750);
1112 
1113     SetLastError(0xdeadbeef);
1114     ret = DeleteTimerQueueEx(q, NULL);
1115     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1116        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1117        GetLastError());
1118     ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
1119 
1120     /* Test functions on the default timer queue.  */
1121     t1 = NULL;
1122     n1 = 0;
1123     ret = CreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000, 1000, 0);
1124     ok(ret, "CreateTimerQueueTimer, default queue\n");
1125     ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
1126 
1127     ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1128     ok(ret, "ChangeTimerQueueTimer, default queue\n");
1129 
1130     ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1131     ok(ret, "DeleteTimerQueueTimer, default queue\n");
1132 
1133     /* Try mixing default and non-default queues.  Apparently this works.  */
1134     q = CreateTimerQueue();
1135     ok(q != NULL, "CreateTimerQueue\n");
1136 
1137     t1 = NULL;
1138     n1 = 0;
1139     ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000, 1000, 0);
1140     ok(ret, "CreateTimerQueueTimer\n");
1141     ok(t1 != NULL, "CreateTimerQueueTimer\n");
1142 
1143     t2 = NULL;
1144     n2 = 0;
1145     ret = CreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000, 1000, 0);
1146     ok(ret, "CreateTimerQueueTimer\n");
1147     ok(t2 != NULL, "CreateTimerQueueTimer\n");
1148 
1149     ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1150     ok(ret, "ChangeTimerQueueTimer\n");
1151 
1152     ret = ChangeTimerQueueTimer(q, t2, 2000, 2000);
1153     ok(ret, "ChangeTimerQueueTimer\n");
1154 
1155     ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1156     ok(ret, "DeleteTimerQueueTimer\n");
1157 
1158     ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
1159     ok(ret, "DeleteTimerQueueTimer\n");
1160 
1161     /* Try to delete the default queue?  In any case: not allowed.  */
1162     SetLastError(0xdeadbeef);
1163     ret = DeleteTimerQueueEx(NULL, NULL);
1164     ok(!ret, "DeleteTimerQueueEx call was expected to fail\n");
1165     ok(GetLastError() == ERROR_INVALID_HANDLE,
1166        "DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n",
1167        GetLastError());
1168 
1169     SetLastError(0xdeadbeef);
1170     ret = DeleteTimerQueueEx(q, NULL);
1171     ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1172        "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1173        GetLastError());
1174 }
1175 
1176 static HANDLE modify_handle(HANDLE handle, DWORD modify)
1177 {
1178     DWORD tmp = HandleToULong(handle);
1179     tmp |= modify;
1180     return ULongToHandle(tmp);
1181 }
1182 
1183 static void test_WaitForSingleObject(void)
1184 {
1185     HANDLE signaled, nonsignaled, invalid;
1186     LARGE_INTEGER timeout;
1187     NTSTATUS status;
1188     DWORD ret;
1189 
1190     signaled = CreateEventW(NULL, TRUE, TRUE, NULL);
1191     nonsignaled = CreateEventW(NULL, TRUE, FALSE, NULL);
1192     invalid = (HANDLE) 0xdeadbee0;
1193 
1194     /* invalid handle with different values for lower 2 bits */
1195     SetLastError(0xdeadbeef);
1196     ret = WaitForSingleObject(invalid, 0);
1197     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1198     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1199 
1200     SetLastError(0xdeadbeef);
1201     ret = WaitForSingleObject(modify_handle(invalid, 1), 0);
1202     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1203     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1204 
1205     SetLastError(0xdeadbeef);
1206     ret = WaitForSingleObject(modify_handle(invalid, 2), 0);
1207     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1208     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1209 
1210     SetLastError(0xdeadbeef);
1211     ret = WaitForSingleObject(modify_handle(invalid, 3), 0);
1212     ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1213     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1214 
1215     /* valid handle with different values for lower 2 bits */
1216     SetLastError(0xdeadbeef);
1217     ret = WaitForSingleObject(nonsignaled, 0);
1218     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1219     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1220 
1221     SetLastError(0xdeadbeef);
1222     ret = WaitForSingleObject(modify_handle(nonsignaled, 1), 0);
1223     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1224     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1225 
1226     SetLastError(0xdeadbeef);
1227     ret = WaitForSingleObject(modify_handle(nonsignaled, 2), 0);
1228     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1229     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1230 
1231     SetLastError(0xdeadbeef);
1232     ret = WaitForSingleObject(modify_handle(nonsignaled, 3), 0);
1233     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1234     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1235 
1236     /* valid handle with different values for lower 2 bits */
1237     SetLastError(0xdeadbeef);
1238     ret = WaitForSingleObject(signaled, 0);
1239     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1240     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1241 
1242     SetLastError(0xdeadbeef);
1243     ret = WaitForSingleObject(modify_handle(signaled, 1), 0);
1244     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1245     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1246 
1247     SetLastError(0xdeadbeef);
1248     ret = WaitForSingleObject(modify_handle(signaled, 2), 0);
1249     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1250     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1251 
1252     SetLastError(0xdeadbeef);
1253     ret = WaitForSingleObject(modify_handle(signaled, 3), 0);
1254     ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1255     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1256 
1257     /* pseudo handles are allowed in WaitForSingleObject and NtWaitForSingleObject */
1258     ret = WaitForSingleObject(GetCurrentProcess(), 100);
1259     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", ret);
1260 
1261     ret = WaitForSingleObject(GetCurrentThread(), 100);
1262     ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", ret);
1263 
1264     timeout.QuadPart = -1000000;
1265     status = pNtWaitForSingleObject(GetCurrentProcess(), FALSE, &timeout);
1266     ok(status == STATUS_TIMEOUT, "expected STATUS_TIMEOUT, got %08x\n", status);
1267 
1268     timeout.QuadPart = -1000000;
1269     status = pNtWaitForSingleObject(GetCurrentThread(), FALSE, &timeout);
1270     ok(status == STATUS_TIMEOUT, "expected STATUS_TIMEOUT, got %08x\n", status);
1271 
1272     CloseHandle(signaled);
1273     CloseHandle(nonsignaled);
1274 }
1275 
1276 static void test_WaitForMultipleObjects(void)
1277 {
1278     LARGE_INTEGER timeout;
1279     NTSTATUS status;
1280     DWORD r;
1281     int i;
1282     HANDLE maxevents[MAXIMUM_WAIT_OBJECTS];
1283 
1284     /* create the maximum number of events and make sure
1285      * we can wait on that many */
1286     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1287     {
1288         maxevents[i] = CreateEventW(NULL, i==0, TRUE, NULL);
1289         ok( maxevents[i] != 0, "should create enough events\n");
1290     }
1291 
1292     /* a manual-reset event remains signaled, an auto-reset event is cleared */
1293     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1294     ok( r == WAIT_OBJECT_0, "should signal lowest handle first, got %d\n", r);
1295     r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1296     ok( r == WAIT_OBJECT_0, "should signal handle #0 first, got %d\n", r);
1297     ok(ResetEvent(maxevents[0]), "ResetEvent\n");
1298     for (i=1; i<MAXIMUM_WAIT_OBJECTS; i++)
1299     {
1300         /* the lowest index is checked first and remaining events are untouched */
1301         r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1302         ok( r == WAIT_OBJECT_0+i, "should signal handle #%d first, got %d\n", i, r);
1303     }
1304 
1305     /* run same test with Nt* call */
1306     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1307         SetEvent(maxevents[i]);
1308 
1309     /* a manual-reset event remains signaled, an auto-reset event is cleared */
1310     status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1311     ok(status == STATUS_WAIT_0, "should signal lowest handle first, got %08x\n", status);
1312     status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1313     ok(status == STATUS_WAIT_0, "should signal handle #0 first, got %08x\n", status);
1314     ok(ResetEvent(maxevents[0]), "ResetEvent\n");
1315     for (i=1; i<MAXIMUM_WAIT_OBJECTS; i++)
1316     {
1317         /* the lowest index is checked first and remaining events are untouched */
1318         status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1319         ok(status == STATUS_WAIT_0 + i, "should signal handle #%d first, got %08x\n", i, status);
1320     }
1321 
1322     for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1323         if (maxevents[i]) CloseHandle(maxevents[i]);
1324 
1325     /* in contrast to WaitForSingleObject, pseudo handles are not allowed in
1326      * WaitForMultipleObjects and NtWaitForMultipleObjects */
1327     maxevents[0] = GetCurrentProcess();
1328     SetLastError(0xdeadbeef);
1329     r = WaitForMultipleObjects(1, maxevents, FALSE, 100);
1330     todo_wine ok(r == WAIT_FAILED, "expected WAIT_FAILED, got %u\n", r);
1331     todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE,
1332                  "expected ERROR_INVALID_HANDLE, got %u\n", GetLastError());
1333 
1334     maxevents[0] = GetCurrentThread();
1335     SetLastError(0xdeadbeef);
1336     r = WaitForMultipleObjects(1, maxevents, FALSE, 100);
1337     todo_wine ok(r == WAIT_FAILED, "expected WAIT_FAILED, got %u\n", r);
1338     todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE,
1339                  "expected ERROR_INVALID_HANDLE, got %u\n", GetLastError());
1340 
1341     timeout.QuadPart = -1000000;
1342     maxevents[0] = GetCurrentProcess();
1343     status = pNtWaitForMultipleObjects(1, maxevents, TRUE, FALSE, &timeout);
1344     todo_wine ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %08x\n", status);
1345 
1346     timeout.QuadPart = -1000000;
1347     maxevents[0] = GetCurrentThread();
1348     status = pNtWaitForMultipleObjects(1, maxevents, TRUE, FALSE, &timeout);
1349     todo_wine ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %08x\n", status);
1350 }
1351 
1352 static BOOL g_initcallback_ret, g_initcallback_called;
1353 static void *g_initctxt;
1354 
1355 static BOOL CALLBACK initonce_callback(INIT_ONCE *initonce, void *parameter, void **ctxt)
1356 {
1357     g_initcallback_called = TRUE;
1358     /* zero bit set means here that initialization is taking place - initialization locked */
1359     ok(g_initctxt == *ctxt, "got wrong context value %p, expected %p\n", *ctxt, g_initctxt);
1360     ok(initonce->Ptr == (void*)0x1, "got %p\n", initonce->Ptr);
1361     ok(parameter == (void*)0xdeadbeef, "got wrong parameter\n");
1362     return g_initcallback_ret;
1363 }
1364 
1365 static void test_initonce(void)
1366 {
1367     INIT_ONCE initonce;
1368     BOOL ret, pending;
1369 
1370     if (!pInitOnceInitialize || !pInitOnceExecuteOnce)
1371     {
1372         win_skip("one-time initialization API not supported\n");
1373         return;
1374     }
1375 
1376     /* blocking initialization with callback */
1377     initonce.Ptr = (void*)0xdeadbeef;
1378     pInitOnceInitialize(&initonce);
1379     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1380 
1381     /* initialisation completed successfully */
1382     g_initcallback_ret = TRUE;
1383     g_initctxt = NULL;
1384     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1385     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1386     ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
1387     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1388     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1389 
1390     /* so it's been called already so won't be called again */
1391     g_initctxt = NULL;
1392     g_initcallback_called = FALSE;
1393     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1394     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1395     ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
1396     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1397     ok(!g_initcallback_called, "got %d\n", g_initcallback_called);
1398 
1399     pInitOnceInitialize(&initonce);
1400     g_initcallback_called = FALSE;
1401     /* 2 lower order bits should never be used, you'll get a crash in result */
1402     g_initctxt = (void*)0xFFFFFFF0;
1403     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1404     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1405     ok(initonce.Ptr == (void*)0xFFFFFFF2, "got %p\n", initonce.Ptr);
1406     ok(g_initctxt == (void*)0xFFFFFFF0, "got %p\n", g_initctxt);
1407     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1408 
1409     /* callback failed */
1410     g_initcallback_ret = FALSE;
1411     g_initcallback_called = FALSE;
1412     g_initctxt = NULL;
1413     pInitOnceInitialize(&initonce);
1414     SetLastError( 0xdeadbeef );
1415     ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1416     ok(!ret && GetLastError() == 0xdeadbeef, "got wrong ret value %d err %u\n", ret, GetLastError());
1417     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1418     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1419     ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1420 
1421     /* blocking initialization without a callback */
1422     pInitOnceInitialize(&initonce);
1423     g_initctxt = NULL;
1424     pending = FALSE;
1425     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1426     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1427     ok(pending, "got %d\n", pending);
1428     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1429     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1430     /* another attempt to begin initialization with block a single thread */
1431 
1432     g_initctxt = NULL;
1433     pending = 0xf;
1434     SetLastError( 0xdeadbeef );
1435     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1436     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1437     ok(pending == 0xf, "got %d\n", pending);
1438     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1439     ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1440 
1441     g_initctxt = (void*)0xdeadbee0;
1442     SetLastError( 0xdeadbeef );
1443     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, g_initctxt);
1444     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1445     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1446 
1447     /* once failed already */
1448     g_initctxt = (void*)0xdeadbee0;
1449     ret = pInitOnceComplete(&initonce, 0, g_initctxt);
1450     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1451     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1452 
1453     pInitOnceInitialize(&initonce);
1454     SetLastError( 0xdeadbeef );
1455     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1456     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1457     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1458 
1459     SetLastError( 0xdeadbeef );
1460     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1461     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1462     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1463 
1464     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1465     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1466     ok(pending, "got %d\n", pending);
1467     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1468 
1469     SetLastError( 0xdeadbeef );
1470     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1471     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1472 
1473     SetLastError( 0xdeadbeef );
1474     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1475     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1476     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1477 
1478     SetLastError( 0xdeadbeef );
1479     ret = pInitOnceComplete(&initonce, 0, (void *)0xdeadbeef);
1480     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1481     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1482 
1483     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1484     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1485     ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1486 
1487     pInitOnceInitialize(&initonce);
1488     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1489     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1490     ok(pending, "got %d\n", pending);
1491     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1492 
1493     SetLastError( 0xdeadbeef );
1494     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1495     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1496 
1497     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1498     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1499     ok(pending, "got %d\n", pending);
1500     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1501 
1502     SetLastError( 0xdeadbeef );
1503     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1504     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1505     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1506 
1507     SetLastError( 0xdeadbeef );
1508     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1509     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1510     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1511 
1512     SetLastError( 0xdeadbeef );
1513     ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbeef);
1514     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1515     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1516 
1517     ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbee0);
1518     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1519     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1520 
1521     SetLastError( 0xdeadbeef );
1522     ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1523     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1524     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1525 
1526     pInitOnceInitialize(&initonce);
1527     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1528     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1529     ok(pending, "got %d\n", pending);
1530     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1531 
1532     /* test INIT_ONCE_CHECK_ONLY */
1533 
1534     pInitOnceInitialize(&initonce);
1535     SetLastError( 0xdeadbeef );
1536     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1537     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1538     SetLastError( 0xdeadbeef );
1539     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1540     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1541 
1542     ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1543     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1544     ok(pending, "got %d\n", pending);
1545     ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1546 
1547     SetLastError( 0xdeadbeef );
1548     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1549     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1550     SetLastError( 0xdeadbeef );
1551     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1552     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1553 
1554     ret = pInitOnceComplete(&initonce, 0, (void *)0xdeadbee0);
1555     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1556     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1557 
1558     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1559     ok(ret, "got wrong ret value %d err %u\n", ret, GetLastError());
1560     ok(!pending, "got %d\n", pending);
1561     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1562     ok(g_initctxt == (void*)0xdeadbee0, "got %p\n", initonce.Ptr);
1563 
1564     SetLastError( 0xdeadbeef );
1565     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1566     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1567 
1568     pInitOnceInitialize(&initonce);
1569     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1570     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1571     ok(pending, "got %d\n", pending);
1572     ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1573 
1574     SetLastError( 0xdeadbeef );
1575     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1576     ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1577     SetLastError( 0xdeadbeef );
1578     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1579     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1580 
1581     ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbee0);
1582     ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1583     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1584 
1585     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1586     ok(ret, "got wrong ret value %d err %u\n", ret, GetLastError());
1587     ok(!pending, "got %d\n", pending);
1588     ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1589     ok(g_initctxt == (void*)0xdeadbee0, "got %p\n", initonce.Ptr);
1590 
1591     SetLastError( 0xdeadbeef );
1592     ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1593     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1594 }
1595 
1596 static CONDITION_VARIABLE buffernotempty = CONDITION_VARIABLE_INIT;
1597 static CONDITION_VARIABLE buffernotfull = CONDITION_VARIABLE_INIT;
1598 static CRITICAL_SECTION   buffercrit;
1599 static BOOL condvar_stop = FALSE, condvar_sleeperr = FALSE;
1600 static LONG bufferlen,totalproduced,totalconsumed;
1601 static LONG condvar_producer_sleepcnt,condvar_consumer_sleepcnt;
1602 
1603 #define BUFFER_SIZE 5
1604 
1605 static DWORD WINAPI condvar_producer(LPVOID x) {
1606     DWORD sleepinterval = 5;
1607 
1608     while (1) {
1609         Sleep(sleepinterval);
1610         if (sleepinterval > 1)
1611             sleepinterval -= 1;
1612 
1613         EnterCriticalSection(&buffercrit);
1614         while ((bufferlen == BUFFER_SIZE) && !condvar_stop) {
1615             condvar_producer_sleepcnt++;
1616             if (!pSleepConditionVariableCS(&buffernotfull, &buffercrit, sleepinterval)) {
1617                 if (GetLastError() != ERROR_TIMEOUT)
1618                     condvar_sleeperr = TRUE;
1619             }
1620         }
1621         if (condvar_stop) {
1622             LeaveCriticalSection(&buffercrit);
1623             break;
1624         }
1625         bufferlen++;
1626         totalproduced++;
1627         LeaveCriticalSection(&buffercrit);
1628         pWakeConditionVariable(&buffernotempty);
1629     }
1630     return 0;
1631 }
1632 
1633 static DWORD WINAPI condvar_consumer(LPVOID x) {
1634     DWORD *cnt = (DWORD*)x;
1635     DWORD sleepinterval = 1;
1636 
1637     while (1) {
1638         EnterCriticalSection(&buffercrit);
1639         while ((bufferlen == 0) && !condvar_stop) {
1640             condvar_consumer_sleepcnt++;
1641             if (!pSleepConditionVariableCS (&buffernotempty, &buffercrit, sleepinterval)) {
1642                 if (GetLastError() != ERROR_TIMEOUT)
1643                     condvar_sleeperr = TRUE;
1644             }
1645         }
1646         if (condvar_stop && (bufferlen == 0)) {
1647             LeaveCriticalSection(&buffercrit);
1648             break;
1649         }
1650         bufferlen--;
1651         totalconsumed++;
1652         (*cnt)++;
1653         LeaveCriticalSection(&buffercrit);
1654         pWakeConditionVariable(&buffernotfull);
1655         Sleep(sleepinterval);
1656         if (sleepinterval < 5) sleepinterval += 1;
1657     }
1658     return 0;
1659 }
1660 
1661 static void test_condvars_consumer_producer(void)
1662 {
1663     HANDLE hp1,hp2,hp3,hc1,hc2,hc3;
1664     DWORD dummy;
1665     DWORD cnt1,cnt2,cnt3;
1666 
1667     if (!pInitializeConditionVariable) {
1668         /* function is not yet in XP, only in newer Windows */
1669         win_skip("no condition variable support.\n");
1670         return;
1671     }
1672 
1673     /* Implement a producer / consumer scheme with non-full / non-empty triggers */
1674 
1675     /* If we have static initialized condition variables, InitializeConditionVariable
1676      * is not strictly necessary.
1677      * pInitializeConditionVariable(&buffernotfull);
1678      */
1679     pInitializeConditionVariable(&buffernotempty);
1680     InitializeCriticalSection(&buffercrit);
1681 
1682     /* Larger Test: consumer/producer example */
1683 
1684     bufferlen = totalproduced = totalconsumed = cnt1 = cnt2 = cnt3 = 0;
1685 
1686     hp1 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1687     hp2 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1688     hp3 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1689     hc1 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt1, 0, &dummy);
1690     hc2 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt2, 0, &dummy);
1691     hc3 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt3, 0, &dummy);
1692 
1693     /* Limit run to 0.5 seconds. */
1694     Sleep(500);
1695 
1696     /* tear down start */
1697     condvar_stop = TRUE;
1698 
1699     /* final wake up call */
1700     pWakeAllConditionVariable (&buffernotfull);
1701     pWakeAllConditionVariable (&buffernotempty);
1702 
1703     /* (mostly an implementation detail)
1704      * ok(buffernotfull.Ptr == NULL, "buffernotfull.Ptr is %p\n", buffernotfull.Ptr);
1705      */
1706 
1707     WaitForSingleObject(hp1, 1000);
1708     WaitForSingleObject(hp2, 1000);
1709     WaitForSingleObject(hp3, 1000);
1710     WaitForSingleObject(hc1, 1000);
1711     WaitForSingleObject(hc2, 1000);
1712     WaitForSingleObject(hc3, 1000);
1713 
1714     ok(totalconsumed == totalproduced,
1715        "consumed %d != produced %d\n", totalconsumed, totalproduced);
1716     ok (!condvar_sleeperr, "error occurred during SleepConditionVariableCS\n");
1717 
1718     /* Checking cnt1 - cnt2 for non-0 would be not good, the case where
1719      * one consumer does not get anything to do is possible. */
1720     trace("produced %d, c1 %d, c2 %d, c3 %d\n", totalproduced, cnt1, cnt2, cnt3);
1721     /* The sleeps of the producer or consumer should not go above 100* produced count,
1722      * otherwise the implementation does not sleep correctly. But yet again, this is
1723      * not hard defined. */
1724     trace("producer sleep %d, consumer sleep %d\n", condvar_producer_sleepcnt, condvar_consumer_sleepcnt);
1725 }
1726 
1727 /* Sample test for some sequence of events happening, sequenced using "condvar_seq" */
1728 static DWORD condvar_seq = 0;
1729 static CONDITION_VARIABLE condvar_base = CONDITION_VARIABLE_INIT;
1730 static CRITICAL_SECTION condvar_crit;
1731 static SRWLOCK condvar_srwlock;
1732 
1733 /* Sequence of wake/sleep to check boundary conditions:
1734  * 0: init
1735  * 1: producer emits a WakeConditionVariable without consumer waiting.
1736  * 2: consumer sleeps without a wake expecting timeout
1737  * 3: producer emits a WakeAllConditionVariable without consumer waiting.
1738  * 4: consumer sleeps without a wake expecting timeout
1739  * 5: a wake is handed to a SleepConditionVariableCS
1740  * 6: a wakeall is handed to a SleepConditionVariableCS
1741  * 7: sleep after above should timeout
1742  * 8: wake with crit section locked into the sleep timeout
1743  *
1744  * the following tests will only be executed if InitializeSRWLock is available
1745  *
1746  *  9: producer (exclusive) wakes up consumer (exclusive)
1747  * 10: producer (exclusive) wakes up consumer (shared)
1748  * 11: producer (shared) wakes up consumer (exclusive)
1749  * 12: producer (shared) wakes up consumer (shared)
1750  * 13: end
1751  */
1752 static DWORD WINAPI condvar_base_producer(LPVOID x) {
1753     while (condvar_seq < 1) Sleep(1);
1754 
1755     pWakeConditionVariable (&condvar_base);
1756     condvar_seq = 2;
1757 
1758     while (condvar_seq < 3) Sleep(1);
1759     pWakeAllConditionVariable (&condvar_base);
1760     condvar_seq = 4;
1761 
1762     while (condvar_seq < 5) Sleep(1);
1763     EnterCriticalSection (&condvar_crit);
1764     pWakeConditionVariable (&condvar_base);
1765     LeaveCriticalSection (&condvar_crit);
1766     while (condvar_seq < 6) Sleep(1);
1767     EnterCriticalSection (&condvar_crit);
1768     pWakeAllConditionVariable (&condvar_base);
1769     LeaveCriticalSection (&condvar_crit);
1770 
1771     while (condvar_seq < 8) Sleep(1);
1772     EnterCriticalSection (&condvar_crit);
1773     pWakeConditionVariable (&condvar_base);
1774     Sleep(50);
1775     LeaveCriticalSection (&condvar_crit);
1776 
1777     /* skip over remaining tests if InitializeSRWLock is not available */
1778     if (!pInitializeSRWLock)
1779         return 0;
1780 
1781     while (condvar_seq < 9) Sleep(1);
1782     pAcquireSRWLockExclusive(&condvar_srwlock);
1783     pWakeConditionVariable(&condvar_base);
1784     pReleaseSRWLockExclusive(&condvar_srwlock);
1785 
1786     while (condvar_seq < 10) Sleep(1);
1787     pAcquireSRWLockExclusive(&condvar_srwlock);
1788     pWakeConditionVariable(&condvar_base);
1789     pReleaseSRWLockExclusive(&condvar_srwlock);
1790 
1791     while (condvar_seq < 11) Sleep(1);
1792     pAcquireSRWLockShared(&condvar_srwlock);
1793     pWakeConditionVariable(&condvar_base);
1794     pReleaseSRWLockShared(&condvar_srwlock);
1795 
1796     while (condvar_seq < 12) Sleep(1);
1797     Sleep(50); /* ensure that consumer waits for cond variable */
1798     pAcquireSRWLockShared(&condvar_srwlock);
1799     pWakeConditionVariable(&condvar_base);
1800     pReleaseSRWLockShared(&condvar_srwlock);
1801 
1802     return 0;
1803 }
1804 
1805 static DWORD WINAPI condvar_base_consumer(LPVOID x) {
1806     BOOL ret;
1807 
1808     while (condvar_seq < 2) Sleep(1);
1809 
1810     /* wake was emitted, but we were not sleeping */
1811     EnterCriticalSection (&condvar_crit);
1812     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1813     LeaveCriticalSection (&condvar_crit);
1814     ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1815     ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1816 
1817     condvar_seq = 3;
1818     while (condvar_seq < 4) Sleep(1);
1819 
1820     /* wake all was emitted, but we were not sleeping */
1821     EnterCriticalSection (&condvar_crit);
1822     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1823     LeaveCriticalSection (&condvar_crit);
1824     ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1825     ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1826 
1827     EnterCriticalSection (&condvar_crit);
1828     condvar_seq = 5;
1829     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 200);
1830     LeaveCriticalSection (&condvar_crit);
1831     ok (ret, "SleepConditionVariableCS should return TRUE on good wake\n");
1832 
1833     EnterCriticalSection (&condvar_crit);
1834     condvar_seq = 6;
1835     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 200);
1836     LeaveCriticalSection (&condvar_crit);
1837     ok (ret, "SleepConditionVariableCS should return TRUE on good wakeall\n");
1838     condvar_seq = 7;
1839 
1840     EnterCriticalSection (&condvar_crit);
1841     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1842     LeaveCriticalSection (&condvar_crit);
1843     ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1844     ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1845 
1846     EnterCriticalSection (&condvar_crit);
1847     condvar_seq = 8;
1848     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 20);
1849     LeaveCriticalSection (&condvar_crit);
1850     ok (ret, "SleepConditionVariableCS should still return TRUE on crit unlock delay\n");
1851 
1852     /* skip over remaining tests if InitializeSRWLock is not available */
1853     if (!pInitializeSRWLock)
1854     {
1855         win_skip("no srw lock support.\n");
1856         condvar_seq = 13; /* end */
1857         return 0;
1858     }
1859 
1860     pAcquireSRWLockExclusive(&condvar_srwlock);
1861     condvar_seq = 9;
1862     ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0);
1863     pReleaseSRWLockExclusive(&condvar_srwlock);
1864     ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1865 
1866     pAcquireSRWLockShared(&condvar_srwlock);
1867     condvar_seq = 10;
1868     ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED);
1869     pReleaseSRWLockShared(&condvar_srwlock);
1870     ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1871 
1872     pAcquireSRWLockExclusive(&condvar_srwlock);
1873     condvar_seq = 11;
1874     ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0);
1875     pReleaseSRWLockExclusive(&condvar_srwlock);
1876     ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1877 
1878     pAcquireSRWLockShared(&condvar_srwlock);
1879     condvar_seq = 12;
1880     ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED);
1881     pReleaseSRWLockShared(&condvar_srwlock);
1882     ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1883 
1884     condvar_seq = 13;
1885     return 0;
1886 }
1887 
1888 static void test_condvars_base(void) {
1889     HANDLE hp, hc;
1890     DWORD dummy;
1891     BOOL ret;
1892 
1893 
1894     if (!pInitializeConditionVariable) {
1895         /* function is not yet in XP, only in newer Windows */
1896         win_skip("no condition variable support.\n");
1897         return;
1898     }
1899 
1900     InitializeCriticalSection (&condvar_crit);
1901 
1902     if (pInitializeSRWLock)
1903         pInitializeSRWLock(&condvar_srwlock);
1904 
1905     EnterCriticalSection (&condvar_crit);
1906     ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1907     LeaveCriticalSection (&condvar_crit);
1908 
1909     ok (!ret, "SleepConditionVariableCS should return FALSE on untriggered condvar\n");
1910     ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1911 
1912     if (pInitializeSRWLock)
1913     {
1914         pAcquireSRWLockExclusive(&condvar_srwlock);
1915         ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, 0);
1916         pReleaseSRWLockExclusive(&condvar_srwlock);
1917 
1918         ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n");
1919         ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1920 
1921         pAcquireSRWLockShared(&condvar_srwlock);
1922         ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, CONDITION_VARIABLE_LOCKMODE_SHARED);
1923         pReleaseSRWLockShared(&condvar_srwlock);
1924 
1925         ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n");
1926         ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1927     }
1928 
1929 
1930     hp = CreateThread(NULL, 0, condvar_base_producer, NULL, 0, &dummy);
1931     hc = CreateThread(NULL, 0, condvar_base_consumer, NULL, 0, &dummy);
1932 
1933     condvar_seq = 1; /* go */
1934 
1935     while (condvar_seq < 9)
1936         Sleep (5);
1937     WaitForSingleObject(hp, 100);
1938     WaitForSingleObject(hc, 100);
1939 }
1940 
1941 static LONG srwlock_seq = 0;
1942 static SRWLOCK srwlock_base;
1943 static struct
1944 {
1945     LONG wrong_execution_order;
1946     LONG samethread_excl_excl;
1947     LONG samethread_excl_shared;
1948     LONG samethread_shared_excl;
1949     LONG multithread_excl_excl;
1950     LONG excl_not_preferred;
1951     LONG trylock_excl;
1952     LONG trylock_shared;
1953 } srwlock_base_errors;
1954 
1955 /* Sequence of acquire/release to check boundary conditions:
1956  *  0: init
1957  *
1958  *  1: thread2 acquires an exclusive lock and tries to acquire a second exclusive lock
1959  *  2: thread1 expects a deadlock and releases the waiting lock
1960  *     thread2 releases the lock again
1961  *
1962  *  3: thread2 acquires an exclusive lock and tries to acquire a shared lock
1963  *  4: thread1 expects a deadlock and releases the waiting lock
1964  *     thread2 releases the lock again
1965  *
1966  *  5: thread2 acquires a shared lock and tries to acquire an exclusive lock
1967  *  6: thread1 expects a deadlock and releases the waiting lock
1968  *     thread2 releases the lock again
1969  *
1970  *  7: thread2 acquires and releases two nested shared locks
1971  *
1972  *  8: thread1 acquires an exclusive lock
1973  *  9: thread2 tries to acquire the exclusive lock, too
1974  *     thread1 releases the exclusive lock again
1975  * 10: thread2 enters the exclusive lock and leaves it immediately again
1976  *
1977  * 11: thread1 acquires a shared lock
1978  * 12: thread2 acquires and releases a shared lock
1979  *     thread1 releases the lock again
1980  *
1981  * 13: thread1 acquires a shared lock
1982  * 14: thread2 tries to acquire an exclusive lock
1983  * 15: thread3 tries to acquire a shared lock
1984  * 16: thread1 releases the shared lock
1985  * 17: thread2 wakes up and releases the exclusive lock
1986  * 18: thread3 wakes up and releases the shared lock
1987  *
1988  * the following tests will only be executed if TryAcquireSRWLock* is available
1989  *
1990  * 19: thread1 calls TryAcquireSRWLockExclusive which should return TRUE
1991  *     thread1 checks the result of recursive calls to TryAcquireSRWLock*
1992  *     thread1 releases the exclusive lock
1993  *
1994  *     thread1 calls TryAcquireSRWLockShared which should return TRUE
1995  *     thread1 checks the result of recursive calls to TryAcquireSRWLock*
1996  *     thread1 releases the shared lock
1997  *
1998  *     thread1 acquires an exclusive lock
1999  * 20: thread2 calls TryAcquireSRWLockShared which should return FALSE
2000  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2001  * 21: thread1 releases the exclusive lock
2002  *
2003  *     thread1 acquires an shared lock
2004  * 22: thread2 calls TryAcquireSRWLockShared which should return TRUE
2005  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2006  * 23: thread1 releases the shared lock
2007  *
2008  *     thread1 acquires a shared lock and tries to acquire an exclusive lock
2009  * 24: thread2 calls TryAcquireSRWLockShared which should return FALSE
2010  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2011  * 25: thread1 releases the exclusive lock
2012  *
2013  *     thread1 acquires two shared locks
2014  * 26: thread2 calls TryAcquireSRWLockShared which should return TRUE
2015  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2016  * 27: thread1 releases one shared lock
2017  * 28: thread2 calls TryAcquireSRWLockShared which should return TRUE
2018  *     thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2019  * 29: thread1 releases the second shared lock
2020  * 30: thread2 calls TryAcquireSRWLockShared which should return TRUE
2021  *     thread2 calls TryAcquireSRWLockExclusive which should return TRUE
2022  *
2023  * 31: end
2024  */
2025 
2026 static DWORD WINAPI srwlock_base_thread1(LPVOID x)
2027 {
2028     /* seq 2 */
2029     while (srwlock_seq < 2) Sleep(1);
2030     Sleep(100);
2031     if (InterlockedIncrement(&srwlock_seq) != 3)
2032         InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
2033     pReleaseSRWLockExclusive(&srwlock_base);
2034 
2035     /* seq 4 */
2036     while (srwlock_seq < 4) Sleep(1);
2037     Sleep(100);
2038     if (InterlockedIncrement(&srwlock_seq) != 5)
2039         InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
2040     pReleaseSRWLockExclusive(&srwlock_base);
2041 
2042     /* seq 6 */
2043     while (srwlock_seq < 6) Sleep(1);
2044     Sleep(100);
2045     if (InterlockedIncrement(&srwlock_seq) != 7)
2046         InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
2047     pReleaseSRWLockShared(&srwlock_base);
2048 
2049     /* seq 8 */
2050     while (srwlock_seq < 8) Sleep(1);
2051     pAcquireSRWLockExclusive(&srwlock_base);
2052     if (InterlockedIncrement(&srwlock_seq) != 9)
2053         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2054     Sleep(100);
2055     if (InterlockedIncrement(&srwlock_seq) != 10)
2056         InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
2057     pReleaseSRWLockExclusive(&srwlock_base);
2058 
2059     /* seq 11 */
2060     while (srwlock_seq < 11) Sleep(1);
2061     pAcquireSRWLockShared(&srwlock_base);
2062     if (InterlockedIncrement(&srwlock_seq) != 12)
2063         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2064 
2065     /* seq 13 */
2066     while (srwlock_seq < 13) Sleep(1);
2067     pReleaseSRWLockShared(&srwlock_base);
2068     pAcquireSRWLockShared(&srwlock_base);
2069     if (InterlockedIncrement(&srwlock_seq) != 14)
2070         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2071 
2072     /* seq 16 */
2073     while (srwlock_seq < 16) Sleep(1);
2074     Sleep(50); /* ensure that both the exclusive and shared access thread are queued */
2075     if (InterlockedIncrement(&srwlock_seq) != 17)
2076         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2077     pReleaseSRWLockShared(&srwlock_base);
2078 
2079     /* skip over remaining tests if TryAcquireSRWLock* is not available */
2080     if (!pTryAcquireSRWLockExclusive)
2081         return 0;
2082 
2083     /* seq 19 */
2084     while (srwlock_seq < 19) Sleep(1);
2085     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2086     {
2087         if (pTryAcquireSRWLockShared(&srwlock_base))
2088             InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2089         if (pTryAcquireSRWLockExclusive(&srwlock_base))
2090             InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2091         pReleaseSRWLockExclusive(&srwlock_base);
2092     }
2093     else
2094         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2095 
2096     if (pTryAcquireSRWLockShared(&srwlock_base))
2097     {
2098         if (pTryAcquireSRWLockShared(&srwlock_base))
2099             pReleaseSRWLockShared(&srwlock_base);
2100         else
2101             InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2102         if (pTryAcquireSRWLockExclusive(&srwlock_base))
2103             InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2104         pReleaseSRWLockShared(&srwlock_base);
2105     }
2106     else
2107         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2108 
2109     pAcquireSRWLockExclusive(&srwlock_base);
2110     if (InterlockedIncrement(&srwlock_seq) != 20)
2111         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2112 
2113     /* seq 21 */
2114     while (srwlock_seq < 21) Sleep(1);
2115     pReleaseSRWLockExclusive(&srwlock_base);
2116     pAcquireSRWLockShared(&srwlock_base);
2117     if (InterlockedIncrement(&srwlock_seq) != 22)
2118         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2119 
2120     /* seq 23 */
2121     while (srwlock_seq < 23) Sleep(1);
2122     pReleaseSRWLockShared(&srwlock_base);
2123     pAcquireSRWLockShared(&srwlock_base);
2124     if (InterlockedIncrement(&srwlock_seq) != 24)
2125         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2126 
2127     /* seq 25 */
2128     pAcquireSRWLockExclusive(&srwlock_base);
2129     if (srwlock_seq != 25)
2130         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2131     pReleaseSRWLockExclusive(&srwlock_base);
2132 
2133     pAcquireSRWLockShared(&srwlock_base);
2134     pAcquireSRWLockShared(&srwlock_base);
2135     if (InterlockedIncrement(&srwlock_seq) != 26)
2136         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2137 
2138     /* seq 27 */
2139     while (srwlock_seq < 27) Sleep(1);
2140     pReleaseSRWLockShared(&srwlock_base);
2141     if (InterlockedIncrement(&srwlock_seq) != 28)
2142         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2143 
2144     /* seq 29 */
2145     while (srwlock_seq < 29) Sleep(1);
2146     pReleaseSRWLockShared(&srwlock_base);
2147     if (InterlockedIncrement(&srwlock_seq) != 30)
2148         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2149 
2150     return 0;
2151 }
2152 
2153 static DWORD WINAPI srwlock_base_thread2(LPVOID x)
2154 {
2155     /* seq 1 */
2156     while (srwlock_seq < 1) Sleep(1);
2157     pAcquireSRWLockExclusive(&srwlock_base);
2158     if (InterlockedIncrement(&srwlock_seq) != 2)
2159         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2160 
2161     /* seq 3 */
2162     pAcquireSRWLockExclusive(&srwlock_base);
2163     if (srwlock_seq != 3)
2164         InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
2165     pReleaseSRWLockExclusive(&srwlock_base);
2166     pAcquireSRWLockExclusive(&srwlock_base);
2167     if (InterlockedIncrement(&srwlock_seq) != 4)
2168         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2169 
2170     /* seq 5 */
2171     pAcquireSRWLockShared(&srwlock_base);
2172     if (srwlock_seq != 5)
2173         InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
2174     pReleaseSRWLockShared(&srwlock_base);
2175     pAcquireSRWLockShared(&srwlock_base);
2176     if (InterlockedIncrement(&srwlock_seq) != 6)
2177         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2178 
2179     /* seq 7 */
2180     pAcquireSRWLockExclusive(&srwlock_base);
2181     if (srwlock_seq != 7)
2182         InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
2183     pReleaseSRWLockExclusive(&srwlock_base);
2184     pAcquireSRWLockShared(&srwlock_base);
2185     pAcquireSRWLockShared(&srwlock_base);
2186     pReleaseSRWLockShared(&srwlock_base);
2187     pReleaseSRWLockShared(&srwlock_base);
2188     if (InterlockedIncrement(&srwlock_seq) != 8)
2189         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2190 
2191     /* seq 9, 10 */
2192     while (srwlock_seq < 9) Sleep(1);
2193     pAcquireSRWLockExclusive(&srwlock_base);
2194     if (srwlock_seq != 10)
2195         InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
2196     pReleaseSRWLockExclusive(&srwlock_base);
2197     if (InterlockedIncrement(&srwlock_seq) != 11)
2198         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2199 
2200     /* seq 12 */
2201     while (srwlock_seq < 12) Sleep(1);
2202     pAcquireSRWLockShared(&srwlock_base);
2203     pReleaseSRWLockShared(&srwlock_base);
2204     if (InterlockedIncrement(&srwlock_seq) != 13)
2205         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2206 
2207     /* seq 14 */
2208     while (srwlock_seq < 14) Sleep(1);
2209     if (InterlockedIncrement(&srwlock_seq) != 15)
2210         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2211 
2212     /* seq 17 */
2213     pAcquireSRWLockExclusive(&srwlock_base);
2214     if (srwlock_seq != 17)
2215         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2216     if (InterlockedIncrement(&srwlock_seq) != 18)
2217         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2218     pReleaseSRWLockExclusive(&srwlock_base);
2219 
2220     /* skip over remaining tests if TryAcquireSRWLock* is not available */
2221     if (!pTryAcquireSRWLockExclusive)
2222         return 0;
2223 
2224     /* seq 20 */
2225     while (srwlock_seq < 20) Sleep(1);
2226     if (pTryAcquireSRWLockShared(&srwlock_base))
2227         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2228     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2229         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2230     if (InterlockedIncrement(&srwlock_seq) != 21)
2231         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2232 
2233     /* seq 22 */
2234     while (srwlock_seq < 22) Sleep(1);
2235     if (pTryAcquireSRWLockShared(&srwlock_base))
2236         pReleaseSRWLockShared(&srwlock_base);
2237     else
2238         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2239     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2240         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2241     if (InterlockedIncrement(&srwlock_seq) != 23)
2242         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2243 
2244     /* seq 24 */
2245     while (srwlock_seq < 24) Sleep(1);
2246     Sleep(50); /* ensure that exclusive access request is queued */
2247     if (pTryAcquireSRWLockShared(&srwlock_base))
2248     {
2249         pReleaseSRWLockShared(&srwlock_base);
2250         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2251     }
2252     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2253         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2254     if (InterlockedIncrement(&srwlock_seq) != 25)
2255         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2256     pReleaseSRWLockShared(&srwlock_base);
2257 
2258     /* seq 26 */
2259     while (srwlock_seq < 26) Sleep(1);
2260     if (pTryAcquireSRWLockShared(&srwlock_base))
2261         pReleaseSRWLockShared(&srwlock_base);
2262     else
2263         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2264     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2265         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2266     if (InterlockedIncrement(&srwlock_seq) != 27)
2267         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2268 
2269     /* seq 28 */
2270     while (srwlock_seq < 28) Sleep(1);
2271     if (pTryAcquireSRWLockShared(&srwlock_base))
2272         pReleaseSRWLockShared(&srwlock_base);
2273     else
2274         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2275     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2276         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2277     if (InterlockedIncrement(&srwlock_seq) != 29)
2278         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2279 
2280     /* seq 30 */
2281     while (srwlock_seq < 30) Sleep(1);
2282     if (pTryAcquireSRWLockShared(&srwlock_base))
2283         pReleaseSRWLockShared(&srwlock_base);
2284     else
2285         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2286     if (pTryAcquireSRWLockExclusive(&srwlock_base))
2287         pReleaseSRWLockExclusive(&srwlock_base);
2288     else
2289         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2290     if (InterlockedIncrement(&srwlock_seq) != 31)
2291         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2292 
2293     return 0;
2294 }
2295 
2296 static DWORD WINAPI srwlock_base_thread3(LPVOID x)
2297 {
2298     /* seq 15 */
2299     while (srwlock_seq < 15) Sleep(1);
2300     Sleep(50); /* some delay, so that thread2 can try to acquire a second exclusive lock */
2301     if (InterlockedIncrement(&srwlock_seq) != 16)
2302         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2303 
2304     /* seq 18 */
2305     pAcquireSRWLockShared(&srwlock_base);
2306     if (srwlock_seq != 18)
2307         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2308     pReleaseSRWLockShared(&srwlock_base);
2309     if (InterlockedIncrement(&srwlock_seq) != 19)
2310         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2311 
2312     /* skip over remaining tests if TryAcquireSRWLock* is not available */
2313     if (!pTryAcquireSRWLockExclusive)
2314     {
2315         /* function is only in Windows 7 and newer */
2316         win_skip("no srw trylock support.\n");
2317         srwlock_seq = 31; /* end */
2318         return 0;
2319     }
2320 
2321     return 0;
2322 }
2323 
2324 static void test_srwlock_base(void)
2325 {
2326     HANDLE h1, h2, h3;
2327     DWORD dummy;
2328 
2329     if (!pInitializeSRWLock)
2330     {
2331         /* function is not yet in XP, only in newer Windows */
2332         win_skip("no srw lock support.\n");
2333         return;
2334     }
2335 
2336     pInitializeSRWLock(&srwlock_base);
2337     memset(&srwlock_base_errors, 0, sizeof(srwlock_base_errors));
2338 
2339     h1 = CreateThread(NULL, 0, srwlock_base_thread1, NULL, 0, &dummy);
2340     h2 = CreateThread(NULL, 0, srwlock_base_thread2, NULL, 0, &dummy);
2341     h3 = CreateThread(NULL, 0, srwlock_base_thread3, NULL, 0, &dummy);
2342 
2343     srwlock_seq = 1; /* go */
2344     while (srwlock_seq < 31)
2345         Sleep(5);
2346 
2347     WaitForSingleObject(h1, 100);
2348     WaitForSingleObject(h2, 100);
2349     WaitForSingleObject(h3, 100);
2350 
2351     ok(!srwlock_base_errors.wrong_execution_order,
2352             "thread commands were executed in the wrong order (occurred %d times).\n",
2353             srwlock_base_errors.wrong_execution_order);
2354 
2355     ok(!srwlock_base_errors.samethread_excl_excl,
2356             "AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred %d times).\n",
2357             srwlock_base_errors.samethread_excl_excl);
2358 
2359     ok(!srwlock_base_errors.samethread_excl_shared,
2360             "AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred %d times).\n",
2361             srwlock_base_errors.samethread_excl_shared);
2362 
2363     ok(!srwlock_base_errors.samethread_shared_excl,
2364             "AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred %d times).\n",
2365             srwlock_base_errors.samethread_shared_excl);
2366 
2367     ok(!srwlock_base_errors.multithread_excl_excl,
2368             "AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred %d times).\n",
2369             srwlock_base_errors.multithread_excl_excl);
2370 
2371     ok(!srwlock_base_errors.excl_not_preferred,
2372             "thread waiting for exclusive access to the SHMLock was not preferred (occurred %d times).\n",
2373             srwlock_base_errors.excl_not_preferred);
2374 
2375     ok(!srwlock_base_errors.trylock_excl,
2376             "TryAcquireSRWLockExclusive didn't behave as expected (occurred %d times).\n",
2377             srwlock_base_errors.trylock_excl);
2378 
2379     ok(!srwlock_base_errors.trylock_shared,
2380             "TryAcquireSRWLockShared didn't behave as expected (occurred %d times).\n",
2381             srwlock_base_errors.trylock_shared);
2382 
2383 }
2384 
2385 static SRWLOCK srwlock_example;
2386 static LONG srwlock_protected_value = 0;
2387 static LONG srwlock_example_errors = 0, srwlock_inside = 0, srwlock_cnt = 0;
2388 static BOOL srwlock_stop = FALSE;
2389 
2390 static DWORD WINAPI srwlock_example_thread(LPVOID x) {
2391     DWORD *cnt = x;
2392     LONG old;
2393 
2394     while (!srwlock_stop)
2395     {
2396 
2397         /* periodically request exclusive access */
2398         if (InterlockedIncrement(&srwlock_cnt) % 13 == 0)
2399         {
2400             pAcquireSRWLockExclusive(&srwlock_example);
2401             if (InterlockedIncrement(&srwlock_inside) != 1)
2402                 InterlockedIncrement(&srwlock_example_errors);
2403 
2404             InterlockedIncrement(&srwlock_protected_value);
2405             Sleep(1);
2406 
2407             if (InterlockedDecrement(&srwlock_inside) != 0)
2408                 InterlockedIncrement(&srwlock_example_errors);
2409             pReleaseSRWLockExclusive(&srwlock_example);
2410         }
2411 
2412         /* request shared access */
2413         pAcquireSRWLockShared(&srwlock_example);
2414         InterlockedIncrement(&srwlock_inside);
2415         old = srwlock_protected_value;
2416 
2417         (*cnt)++;
2418         Sleep(1);
2419 
2420         if (old != srwlock_protected_value)
2421             InterlockedIncrement(&srwlock_example_errors);
2422         InterlockedDecrement(&srwlock_inside);
2423         pReleaseSRWLockShared(&srwlock_example);
2424     }
2425 
2426     return 0;
2427 }
2428 
2429 static void test_srwlock_example(void)
2430 {
2431     HANDLE h1, h2, h3;
2432     DWORD dummy;
2433     DWORD cnt1, cnt2, cnt3;
2434 
2435     if (!pInitializeSRWLock) {
2436         /* function is not yet in XP, only in newer Windows */
2437         win_skip("no srw lock support.\n");
2438         return;
2439     }
2440 
2441     pInitializeSRWLock(&srwlock_example);
2442 
2443     cnt1 = cnt2 = cnt3 = 0;
2444 
2445     h1 = CreateThread(NULL, 0, srwlock_example_thread, &cnt1, 0, &dummy);
2446     h2 = CreateThread(NULL, 0, srwlock_example_thread, &cnt2, 0, &dummy);
2447     h3 = CreateThread(NULL, 0, srwlock_example_thread, &cnt3, 0, &dummy);
2448 
2449     /* limit run to 1 second. */
2450     Sleep(1000);
2451 
2452     /* tear down start */
2453     srwlock_stop = TRUE;
2454 
2455     WaitForSingleObject(h1, 1000);
2456     WaitForSingleObject(h2, 1000);
2457     WaitForSingleObject(h3, 1000);
2458 
2459     ok(!srwlock_inside, "threads didn't terminate properly, srwlock_inside is %d.\n", srwlock_inside);
2460     ok(!srwlock_example_errors, "errors occurred while running SRWLock example test (number of errors: %d)\n",
2461             srwlock_example_errors);
2462 
2463     trace("number of shared accesses per thread are c1 %d, c2 %d, c3 %d\n", cnt1, cnt2, cnt3);
2464     trace("number of total exclusive accesses is %d\n", srwlock_protected_value);
2465 }
2466 
2467 static DWORD WINAPI alertable_wait_thread(void *param)
2468 {
2469     HANDLE *semaphores = param;
2470     LARGE_INTEGER timeout;
2471     NTSTATUS status;
2472     DWORD result;
2473 
2474     ReleaseSemaphore(semaphores[0], 1, NULL);
2475     result = WaitForMultipleObjectsEx(1, &semaphores[1], TRUE, 1000, TRUE);
2476     ok(result == WAIT_IO_COMPLETION, "expected WAIT_IO_COMPLETION, got %u\n", result);
2477     result = WaitForMultipleObjectsEx(1, &semaphores[1], TRUE, 200, TRUE);
2478     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2479 
2480     ReleaseSemaphore(semaphores[0], 1, NULL);
2481     timeout.QuadPart = -10000000;
2482     status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2483     ok(status == STATUS_USER_APC, "expected STATUS_USER_APC, got %08x\n", status);
2484     timeout.QuadPart = -2000000;
2485     status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2486     ok(status == STATUS_WAIT_0, "expected STATUS_WAIT_0, got %08x\n", status);
2487 
2488     ReleaseSemaphore(semaphores[0], 1, NULL);
2489     timeout.QuadPart = -10000000;
2490     status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2491     ok(status == STATUS_USER_APC, "expected STATUS_USER_APC, got %08x\n", status);
2492     result = WaitForSingleObject(semaphores[0], 0);
2493     ok(result == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", result);
2494 
2495     return 0;
2496 }
2497 
2498 static void CALLBACK alertable_wait_apc(ULONG_PTR userdata)
2499 {
2500     HANDLE *semaphores = (void *)userdata;
2501     ReleaseSemaphore(semaphores[1], 1, NULL);
2502 }
2503 
2504 static void CALLBACK alertable_wait_apc2(ULONG_PTR userdata)
2505 {
2506     HANDLE *semaphores = (void *)userdata;
2507     DWORD result;
2508 
2509     result = WaitForSingleObject(semaphores[0], 1000);
2510     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2511 }
2512 
2513 static void test_alertable_wait(void)
2514 {
2515     HANDLE thread, semaphores[2];
2516     DWORD result;
2517 
2518     semaphores[0] = CreateSemaphoreW(NULL, 0, 2, NULL);
2519     ok(semaphores[0] != NULL, "CreateSemaphore failed with %u\n", GetLastError());
2520     semaphores[1] = CreateSemaphoreW(NULL, 0, 1, NULL);
2521     ok(semaphores[1] != NULL, "CreateSemaphore failed with %u\n", GetLastError());
2522     thread = CreateThread(NULL, 0, alertable_wait_thread, semaphores, 0, NULL);
2523     ok(thread != NULL, "CreateThread failed with %u\n", GetLastError());
2524 
2525     result = WaitForSingleObject(semaphores[0], 1000);
2526     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2527     Sleep(100); /* ensure the thread is blocking in WaitForMultipleObjectsEx */
2528     result = QueueUserAPC(alertable_wait_apc, thread, (ULONG_PTR)semaphores);
2529     ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2530 
2531     result = WaitForSingleObject(semaphores[0], 1000);
2532     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2533     Sleep(100); /* ensure the thread is blocking in NtWaitForMultipleObjects */
2534     result = QueueUserAPC(alertable_wait_apc, thread, (ULONG_PTR)semaphores);
2535     ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2536 
2537     result = WaitForSingleObject(semaphores[0], 1000);
2538     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2539     Sleep(100); /* ensure the thread is blocking in NtWaitForMultipleObjects */
2540     result = QueueUserAPC(alertable_wait_apc2, thread, (ULONG_PTR)semaphores);
2541     ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2542     result = QueueUserAPC(alertable_wait_apc2, thread, (ULONG_PTR)semaphores);
2543     ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2544     ReleaseSemaphore(semaphores[0], 2, NULL);
2545 
2546     result = WaitForSingleObject(thread, 1000);
2547     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2548     CloseHandle(thread);
2549     CloseHandle(semaphores[0]);
2550     CloseHandle(semaphores[1]);
2551 }
2552 
2553 struct apc_deadlock_info
2554 {
2555     PROCESS_INFORMATION *pi;
2556     HANDLE event;
2557     BOOL running;
2558 };
2559 
2560 static DWORD WINAPI apc_deadlock_thread(void *param)
2561 {
2562     struct apc_deadlock_info *info = param;
2563     PROCESS_INFORMATION *pi = info->pi;
2564     NTSTATUS status;
2565     SIZE_T size;
2566     void *base;
2567 
2568     while (info->running)
2569     {
2570         base = NULL;
2571         size = 0x1000;
2572         status = pNtAllocateVirtualMemory(pi->hProcess, &base, 0, &size,
2573                                           MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
2574         ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
2575         ok(base != NULL, "expected base != NULL, got %p\n", base);
2576         SetEvent(info->event);
2577 
2578         size = 0;
2579         status = pNtFreeVirtualMemory(pi->hProcess, &base, &size, MEM_RELEASE);
2580         ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
2581         SetEvent(info->event);
2582     }
2583 
2584     return 0;
2585 }
2586 
2587 static void test_apc_deadlock(void)
2588 {
2589     struct apc_deadlock_info info;
2590     PROCESS_INFORMATION pi;
2591     STARTUPINFOA si = { sizeof(si) };
2592     char cmdline[MAX_PATH];
2593     HANDLE event, thread;
2594     DWORD result;
2595     BOOL success;
2596     char **argv;
2597     int i;
2598 
2599     winetest_get_mainargs(&argv);
2600     sprintf(cmdline, "\"%s\" sync apc_deadlock", argv[0]);
2601     success = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
2602     ok(success, "CreateProcess failed with %u\n", GetLastError());
2603 
2604     event = CreateEventA(NULL, FALSE, FALSE, NULL);
2605     ok(event != NULL, "CreateEvent failed with %u\n", GetLastError());
2606 
2607     info.pi = &pi;
2608     info.event = event;
2609     info.running = TRUE;
2610 
2611     thread = CreateThread(NULL, 0, apc_deadlock_thread, &info, 0, NULL);
2612     ok(thread != NULL, "CreateThread failed with %u\n", GetLastError());
2613     result = WaitForSingleObject(event, 1000);
2614     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2615 
2616     for (i = 0; i < 1000; i++)
2617     {
2618         result = SuspendThread(pi.hThread);
2619         ok(result == 0, "expected 0, got %u\n", result);
2620 
2621         WaitForSingleObject(event, 0); /* reset event */
2622         result = WaitForSingleObject(event, 1000);
2623         ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2624 
2625         result = ResumeThread(pi.hThread);
2626         ok(result == 1, "expected 1, got %u\n", result);
2627         Sleep(1);
2628     }
2629 
2630     info.running = FALSE;
2631     result = WaitForSingleObject(thread, 1000);
2632     ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2633     CloseHandle(thread);
2634     CloseHandle(event);
2635 
2636     TerminateProcess(pi.hProcess, 0);
2637     CloseHandle(pi.hThread);
2638     CloseHandle(pi.hProcess);
2639 }
2640 
2641 START_TEST(sync)
2642 {
2643     char **argv;
2644     int argc;
2645     HMODULE hdll = GetModuleHandleA("kernel32.dll");
2646     HMODULE hntdll = GetModuleHandleA("ntdll.dll");
2647 #ifdef __REACTOS__
2648     HMODULE hdll_vista = GetModuleHandleA("kernel32_vista.dll");
2649 #endif
2650 
2651     pInitOnceInitialize = (void *)GetProcAddress(hdll, "InitOnceInitialize");
2652     pInitOnceExecuteOnce = (void *)GetProcAddress(hdll, "InitOnceExecuteOnce");
2653     pInitOnceBeginInitialize = (void *)GetProcAddress(hdll, "InitOnceBeginInitialize");
2654     pInitOnceComplete = (void *)GetProcAddress(hdll, "InitOnceComplete");
2655     pInitializeConditionVariable = (void *)GetProcAddress(hdll, "InitializeConditionVariable");
2656     pSleepConditionVariableCS = (void *)GetProcAddress(hdll, "SleepConditionVariableCS");
2657     pSleepConditionVariableSRW = (void *)GetProcAddress(hdll, "SleepConditionVariableSRW");
2658     pWakeAllConditionVariable = (void *)GetProcAddress(hdll, "WakeAllConditionVariable");
2659     pWakeConditionVariable = (void *)GetProcAddress(hdll, "WakeConditionVariable");
2660     pInitializeSRWLock = (void *)GetProcAddress(hdll, "InitializeSRWLock");
2661     pAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "AcquireSRWLockExclusive");
2662     pAcquireSRWLockShared = (void *)GetProcAddress(hdll, "AcquireSRWLockShared");
2663     pReleaseSRWLockExclusive = (void *)GetProcAddress(hdll, "ReleaseSRWLockExclusive");
2664     pReleaseSRWLockShared = (void *)GetProcAddress(hdll, "ReleaseSRWLockShared");
2665     pTryAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "TryAcquireSRWLockExclusive");
2666     pTryAcquireSRWLockShared = (void *)GetProcAddress(hdll, "TryAcquireSRWLockShared");
2667     pNtAllocateVirtualMemory = (void *)GetProcAddress(hntdll, "NtAllocateVirtualMemory");
2668     pNtFreeVirtualMemory = (void *)GetProcAddress(hntdll, "NtFreeVirtualMemory");
2669     pNtWaitForSingleObject = (void *)GetProcAddress(hntdll, "NtWaitForSingleObject");
2670     pNtWaitForMultipleObjects = (void *)GetProcAddress(hntdll, "NtWaitForMultipleObjects");
2671     pRtlInterlockedPushListSList = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSList");
2672     pRtlInterlockedPushListSListEx = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSListEx");
2673 
2674 #ifdef __REACTOS__
2675     if (!pInitializeConditionVariable)
2676     {
2677         pInitializeConditionVariable = (void *)GetProcAddress(hdll_vista, "InitializeConditionVariable");
2678         pSleepConditionVariableCS = (void *)GetProcAddress(hdll_vista, "SleepConditionVariableCS");
2679         pSleepConditionVariableSRW = (void *)GetProcAddress(hdll_vista, "SleepConditionVariableSRW");
2680         pWakeAllConditionVariable = (void *)GetProcAddress(hdll_vista, "WakeAllConditionVariable");
2681         pWakeConditionVariable = (void *)GetProcAddress(hdll_vista, "WakeConditionVariable");
2682     }
2683 
2684     if (!pInitializeSRWLock)
2685     {
2686         pInitializeSRWLock = (void *)GetProcAddress(hdll_vista, "InitializeSRWLock");
2687         pAcquireSRWLockExclusive = (void *)GetProcAddress(hdll_vista, "AcquireSRWLockExclusive");
2688         pAcquireSRWLockShared = (void *)GetProcAddress(hdll_vista, "AcquireSRWLockShared");
2689         pReleaseSRWLockExclusive = (void *)GetProcAddress(hdll_vista, "ReleaseSRWLockExclusive");
2690         pReleaseSRWLockShared = (void *)GetProcAddress(hdll_vista, "ReleaseSRWLockShared");
2691         pTryAcquireSRWLockExclusive = (void *)GetProcAddress(hdll_vista, "TryAcquireSRWLockExclusive");
2692         pTryAcquireSRWLockShared = (void *)GetProcAddress(hdll_vista, "TryAcquireSRWLockShared");
2693     }
2694 #endif
2695 
2696     argc = winetest_get_mainargs( &argv );
2697     if (argc >= 3)
2698     {
2699         if (!strcmp(argv[2], "apc_deadlock"))
2700         {
2701             for (;;) SleepEx(INFINITE, TRUE);
2702         }
2703         return;
2704     }
2705 
2706     init_fastcall_thunk();
2707     test_signalandwait();
2708     test_mutex();
2709     test_slist();
2710     test_event();
2711     test_semaphore();
2712     test_waitable_timer();
2713     test_iocp_callback();
2714     test_timer_queue();
2715     test_WaitForSingleObject();
2716     test_WaitForMultipleObjects();
2717     test_initonce();
2718     test_condvars_base();
2719     test_condvars_consumer_producer();
2720     test_srwlock_base();
2721     test_srwlock_example();
2722     test_alertable_wait();
2723     test_apc_deadlock();
2724 }
2725