kernel32/tests: Add tests for buffer allocation in FormatMessage.
[wine] / dlls / kernel32 / tests / thread.c
1 /*
2  * Unit test suite for thread functions.
3  *
4  * Copyright 2002 Geoffrey Hausheer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* Define _WIN32_WINNT to get SetThreadIdealProcessor on Windows */
22 #define _WIN32_WINNT 0x0500
23
24 #include <assert.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27
28 #include "wine/test.h"
29 #include <windef.h>
30 #include <winbase.h>
31 #include <winnt.h>
32 #include <winerror.h>
33
34 /* Specify the number of simultaneous threads to test */
35 #define NUM_THREADS 4
36 /* Specify whether to test the extended priorities for Win2k/XP */
37 #define USE_EXTENDED_PRIORITIES 0
38 /* Specify whether to test the stack allocation in CreateThread */
39 #define CHECK_STACK 0
40
41 /* Set CHECK_STACK to 1 if you want to try to test the stack-limit from
42    CreateThread.  So far I have been unable to make this work, and
43    I am in doubt as to how portable it is.  Also, according to MSDN,
44    you shouldn't mix C-run-time-libraries (i.e. alloca) with CreateThread.
45    Anyhow, the check is currently commented out
46 */
47 #if CHECK_STACK
48 # ifdef __try
49 #  define __TRY __try
50 #  define __EXCEPT __except
51 #  define __ENDTRY
52 # else
53 #  include "wine/exception.h"
54 # endif
55 #endif
56
57 static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE,PBOOL);
58 static HANDLE (WINAPI *pOpenThread)(DWORD,BOOL,DWORD);
59 static BOOL (WINAPI *pQueueUserWorkItem)(LPTHREAD_START_ROUTINE,PVOID,ULONG);
60 static DWORD (WINAPI *pSetThreadIdealProcessor)(HANDLE,DWORD);
61 static BOOL (WINAPI *pSetThreadPriorityBoost)(HANDLE,BOOL);
62 static BOOL (WINAPI *pRegisterWaitForSingleObject)(PHANDLE,HANDLE,WAITORTIMERCALLBACK,PVOID,ULONG,ULONG);
63 static BOOL (WINAPI *pUnregisterWait)(HANDLE);
64 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
65 static BOOL (WINAPI *pSetThreadErrorMode)(DWORD,PDWORD);
66 static DWORD (WINAPI *pGetThreadErrorMode)(void);
67 static DWORD (WINAPI *pRtlGetThreadErrorMode)(void);
68
69 static HANDLE create_target_process(const char *arg)
70 {
71     char **argv;
72     char cmdline[MAX_PATH];
73     PROCESS_INFORMATION pi;
74     STARTUPINFO si = { 0 };
75     si.cb = sizeof(si);
76
77     winetest_get_mainargs( &argv );
78     sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
79     ok(CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
80                      &si, &pi) != 0, "error: %u\n", GetLastError());
81     ok(CloseHandle(pi.hThread) != 0, "error %u\n", GetLastError());
82     return pi.hProcess;
83 }
84
85 /* Functions not tested yet:
86   AttachThreadInput
87   SetThreadContext
88   SwitchToThread
89
90 In addition there are no checks that the inheritance works properly in
91 CreateThread
92 */
93
94 /* Functions to ensure that from a group of threads, only one executes
95    certain chunks of code at a time, and we know which one is executing
96    it.  It basically makes multithreaded execution linear, which defeats
97    the purpose of multiple threads, but makes testing easy.  */
98 static HANDLE start_event, stop_event;
99 static LONG num_synced;
100
101 static void init_thread_sync_helpers(void)
102 {
103   start_event = CreateEvent(NULL, TRUE, FALSE, NULL);
104   ok(start_event != NULL, "CreateEvent failed\n");
105   stop_event = CreateEvent(NULL, TRUE, FALSE, NULL);
106   ok(stop_event != NULL, "CreateEvent failed\n");
107   num_synced = -1;
108 }
109
110 static BOOL sync_threads_and_run_one(DWORD sync_id, DWORD my_id)
111 {
112   LONG num = InterlockedIncrement(&num_synced);
113   assert(-1 <= num && num <= 1);
114   if (num == 1)
115   {
116       ResetEvent( stop_event );
117       SetEvent( start_event );
118   }
119   else
120   {
121     DWORD ret = WaitForSingleObject(start_event, 10000);
122     ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed %x\n",ret);
123   }
124   return sync_id == my_id;
125 }
126
127 static void resync_after_run(void)
128 {
129   LONG num = InterlockedDecrement(&num_synced);
130   assert(-1 <= num && num <= 1);
131   if (num == -1)
132   {
133       ResetEvent( start_event );
134       SetEvent( stop_event );
135   }
136   else
137   {
138     DWORD ret = WaitForSingleObject(stop_event, 10000);
139     ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
140   }
141 }
142
143 static void cleanup_thread_sync_helpers(void)
144 {
145   CloseHandle(start_event);
146   CloseHandle(stop_event);
147 }
148
149 DWORD tlsIndex;
150
151 typedef struct {
152   int threadnum;
153   HANDLE *event;
154   DWORD *threadmem;
155 } t1Struct;
156
157 /* WinME supports OpenThread but doesn't know about access restrictions so
158    we require them to be either completely ignored or always obeyed.
159 */
160 INT obeying_ars = 0; /* -1 == no, 0 == dunno yet, 1 == yes */
161 #define obey_ar(x) \
162   (obeying_ars == 0 \
163     ? ((x) \
164       ? (obeying_ars = +1) \
165       : ((obeying_ars = -1), \
166          trace("not restricted, assuming consistent behaviour\n"))) \
167     : (obeying_ars < 0) \
168       ? ok(!(x), "access restrictions obeyed\n") \
169       : ok( (x), "access restrictions not obeyed\n"))
170
171 /* Basic test that simultaneous threads can access shared memory,
172    that the thread local storage routines work correctly, and that
173    threads actually run concurrently
174 */
175 static DWORD WINAPI threadFunc1(LPVOID p)
176 {
177    t1Struct *tstruct = p;
178    int i;
179 /* write our thread # into shared memory */
180    tstruct->threadmem[tstruct->threadnum]=GetCurrentThreadId();
181    ok(TlsSetValue(tlsIndex,(LPVOID)(INT_PTR)(tstruct->threadnum+1))!=0,
182       "TlsSetValue failed\n");
183 /* The threads synchronize before terminating.  This is done by
184    Signaling an event, and waiting for all events to occur
185 */
186    SetEvent(tstruct->event[tstruct->threadnum]);
187    WaitForMultipleObjects(NUM_THREADS,tstruct->event,TRUE,INFINITE);
188 /* Double check that all threads really did run by validating that
189    they have all written to the shared memory. There should be no race
190    here, since all threads were synchronized after the write.*/
191    for(i=0;i<NUM_THREADS;i++) {
192      while(tstruct->threadmem[i]==0) ;
193    }
194
195    /* lstrlenA contains an exception handler so this makes sure exceptions work in threads */
196    ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
197
198 /* Check that no one changed our tls memory */
199    ok((INT_PTR)TlsGetValue(tlsIndex)-1==tstruct->threadnum,
200       "TlsGetValue failed\n");
201    return NUM_THREADS+tstruct->threadnum;
202 }
203
204 static DWORD WINAPI threadFunc2(LPVOID p)
205 {
206    return 99;
207 }
208
209 static DWORD WINAPI threadFunc3(LPVOID p)
210 {
211    HANDLE thread;
212    thread=GetCurrentThread();
213    SuspendThread(thread);
214    return 99;
215 }
216
217 static DWORD WINAPI threadFunc4(LPVOID p)
218 {
219    HANDLE event = p;
220    if(event != NULL) {
221      SetEvent(event);
222    }
223    Sleep(99000);
224    return 0;
225 }
226
227 #if CHECK_STACK
228 static DWORD WINAPI threadFunc5(LPVOID p)
229 {
230   DWORD *exitCode = p;
231   SYSTEM_INFO sysInfo;
232   sysInfo.dwPageSize=0;
233   GetSystemInfo(&sysInfo);
234   *exitCode=0;
235    __TRY
236    {
237      alloca(2*sysInfo.dwPageSize);
238    }
239     __EXCEPT(1) {
240      *exitCode=1;
241    }
242    __ENDTRY
243    return 0;
244 }
245 #endif
246
247 static DWORD WINAPI threadFunc_SetEvent(LPVOID p)
248 {
249     SetEvent(p);
250     return 0;
251 }
252
253 static DWORD WINAPI threadFunc_CloseHandle(LPVOID p)
254 {
255     CloseHandle(p);
256     return 0;
257 }
258
259 static void create_function_addr_events(HANDLE events[2])
260 {
261     char buffer[256];
262
263     sprintf(buffer, "threadFunc_SetEvent %p", threadFunc_SetEvent);
264     events[0] = CreateEvent(NULL, FALSE, FALSE, buffer);
265
266     sprintf(buffer, "threadFunc_CloseHandle %p", threadFunc_CloseHandle);
267     events[1] = CreateEvent(NULL, FALSE, FALSE, buffer);
268 }
269
270 /* check CreateRemoteThread */
271 static VOID test_CreateRemoteThread(void)
272 {
273     HANDLE hProcess, hThread, hEvent, hRemoteEvent;
274     DWORD tid, ret, exitcode;
275     HANDLE hAddrEvents[2];
276
277     hProcess = create_target_process("sleep");
278     ok(hProcess != NULL, "Can't start process\n");
279
280     /* ensure threadFunc_SetEvent & threadFunc_CloseHandle are the same
281      * address as in the child process */
282     create_function_addr_events(hAddrEvents);
283     ret = WaitForMultipleObjects(2, hAddrEvents, TRUE, 5000);
284     if (ret == WAIT_TIMEOUT)
285     {
286         skip("child process wasn't mapped at same address, so can't do CreateRemoteThread tests.\n");
287         return;
288     }
289
290     hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
291     ok(hEvent != NULL, "Can't create event, err=%u\n", GetLastError());
292     ret = DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hRemoteEvent,
293                           0, FALSE, DUPLICATE_SAME_ACCESS);
294     ok(ret != 0, "DuplicateHandle failed, err=%u\n", GetLastError());
295
296     /* create suspended remote thread with entry point SetEvent() */
297     SetLastError(0xdeadbeef);
298     hThread = CreateRemoteThread(hProcess, NULL, 0, threadFunc_SetEvent,
299                                  hRemoteEvent, CREATE_SUSPENDED, &tid);
300     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
301     {
302         win_skip("CreateRemoteThread is not implemented\n");
303         goto cleanup;
304     }
305     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
306     ok(tid != 0, "null tid\n");
307     ret = SuspendThread(hThread);
308     ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
309     ret = ResumeThread(hThread);
310     ok(ret == 2, "ret=%u, err=%u\n", ret, GetLastError());
311
312     /* thread still suspended, so wait times out */
313     ret = WaitForSingleObject(hEvent, 100);
314     ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
315
316     ret = ResumeThread(hThread);
317     ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
318
319     /* wait that doesn't time out */
320     ret = WaitForSingleObject(hEvent, 100);
321     ok(ret == WAIT_OBJECT_0, "object not signaled, ret=%u\n", ret);
322
323     /* wait for thread end */
324     ret = WaitForSingleObject(hThread, 100);
325     ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
326     CloseHandle(hThread);
327
328     /* create and wait for remote thread with entry point CloseHandle() */
329     hThread = CreateRemoteThread(hProcess, NULL, 0,
330                                  threadFunc_CloseHandle,
331                                  hRemoteEvent, 0, &tid);
332     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
333     ret = WaitForSingleObject(hThread, 100);
334     ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
335     CloseHandle(hThread);
336
337     /* create remote thread with entry point SetEvent() */
338     hThread = CreateRemoteThread(hProcess, NULL, 0,
339                                  threadFunc_SetEvent,
340                                  hRemoteEvent, 0, &tid);
341     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
342
343     /* closed handle, so wait times out */
344     ret = WaitForSingleObject(hEvent, 100);
345     ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
346
347     /* check that remote SetEvent() failed */
348     ret = GetExitCodeThread(hThread, &exitcode);
349     ok(ret != 0, "GetExitCodeThread failed, err=%u\n", GetLastError());
350     if (ret) ok(exitcode == 0, "SetEvent succeeded, expected to fail\n");
351     CloseHandle(hThread);
352
353 cleanup:
354     TerminateProcess(hProcess, 0);
355     CloseHandle(hEvent);
356     CloseHandle(hProcess);
357 }
358
359 /* Check basic functionality of CreateThread and Tls* functions */
360 static VOID test_CreateThread_basic(void)
361 {
362    HANDLE thread[NUM_THREADS],event[NUM_THREADS];
363    DWORD threadid[NUM_THREADS],curthreadId;
364    DWORD threadmem[NUM_THREADS];
365    DWORD exitCode;
366    t1Struct tstruct[NUM_THREADS];
367    int error;
368    DWORD i,j;
369    DWORD GLE, ret;
370    DWORD tid;
371
372    /* lstrlenA contains an exception handler so this makes sure exceptions work in the main thread */
373    ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
374
375 /* Retrieve current Thread ID for later comparisons */
376   curthreadId=GetCurrentThreadId();
377 /* Allocate some local storage */
378   ok((tlsIndex=TlsAlloc())!=TLS_OUT_OF_INDEXES,"TlsAlloc failed\n");
379 /* Create events for thread synchronization */
380   for(i=0;i<NUM_THREADS;i++) {
381     threadmem[i]=0;
382 /* Note that it doesn't matter what type of event we choose here.  This
383    test isn't trying to thoroughly test events
384 */
385     event[i]=CreateEventA(NULL,TRUE,FALSE,NULL);
386     tstruct[i].threadnum=i;
387     tstruct[i].threadmem=threadmem;
388     tstruct[i].event=event;
389   }
390
391 /* Test that passing arguments to threads works okay */
392   for(i=0;i<NUM_THREADS;i++) {
393     thread[i] = CreateThread(NULL,0,threadFunc1,
394                              &tstruct[i],0,&threadid[i]);
395     ok(thread[i]!=NULL,"Create Thread failed\n");
396   }
397 /* Test that the threads actually complete */
398   for(i=0;i<NUM_THREADS;i++) {
399     error=WaitForSingleObject(thread[i],5000);
400     ok(error==WAIT_OBJECT_0, "Thread did not complete within timelimit\n");
401     if(error!=WAIT_OBJECT_0) {
402       TerminateThread(thread[i],i+NUM_THREADS);
403     }
404     ok(GetExitCodeThread(thread[i],&exitCode),"Could not retrieve ext code\n");
405     ok(exitCode==i+NUM_THREADS,"Thread returned an incorrect exit code\n");
406   }
407 /* Test that each thread executed in its parent's address space
408    (it was able to change threadmem and pass that change back to its parent)
409    and that each thread id was independent).  Note that we prove that the
410    threads actually execute concurrently by having them block on each other
411    in threadFunc1
412 */
413   for(i=0;i<NUM_THREADS;i++) {
414     error=0;
415     for(j=i+1;j<NUM_THREADS;j++) {
416       if (threadmem[i]==threadmem[j]) {
417         error=1;
418       }
419     }
420     ok(!error && threadmem[i]==threadid[i] && threadmem[i]!=curthreadId,
421          "Thread did not execute successfully\n");
422     ok(CloseHandle(thread[i])!=0,"CloseHandle failed\n");
423   }
424
425   SetLastError(0xCAFEF00D);
426   ok(TlsFree(tlsIndex)!=0,"TlsFree failed: %08x\n", GetLastError());
427   ok(GetLastError()==0xCAFEF00D,
428      "GetLastError: expected 0xCAFEF00D, got %08x\n", GetLastError());
429
430   /* Test freeing an already freed TLS index */
431   SetLastError(0xCAFEF00D);
432   ok(TlsFree(tlsIndex)==0,"TlsFree succeeded\n");
433   ok(GetLastError()==ERROR_INVALID_PARAMETER,
434      "GetLastError: expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
435
436   /* Test how passing NULL as a pointer to threadid works */
437   SetLastError(0xFACEaBAD);
438   thread[0] = CreateThread(NULL,0,threadFunc2,NULL,0,&tid);
439   GLE = GetLastError();
440   if (thread[0]) { /* NT */
441     ok(GLE==0xFACEaBAD, "CreateThread set last error to %d, expected 4207848365\n", GLE);
442     ret = WaitForSingleObject(thread[0],100);
443     ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
444     ret = GetExitCodeThread(thread[0],&exitCode);
445     ok(ret!=0, "GetExitCodeThread returned %d (expected nonzero)\n", ret);
446     ok(exitCode==99, "threadFunc2 exited with code: %d (expected 99)\n", exitCode);
447     ok(CloseHandle(thread[0])!=0,"Error closing thread handle\n");
448   }
449   else { /* 9x */
450     ok(GLE==ERROR_INVALID_PARAMETER, "CreateThread set last error to %d, expected 87\n", GLE);
451   }
452 }
453
454 /* Check that using the CREATE_SUSPENDED flag works */
455 static VOID test_CreateThread_suspended(void)
456 {
457   HANDLE thread;
458   DWORD threadId;
459   DWORD suspend_count;
460   int error;
461
462   thread = CreateThread(NULL,0,threadFunc2,NULL,
463                         CREATE_SUSPENDED,&threadId);
464   ok(thread!=NULL,"Create Thread failed\n");
465 /* Check that the thread is suspended */
466   ok(SuspendThread(thread)==1,"Thread did not start suspended\n");
467   ok(ResumeThread(thread)==2,"Resume thread returned an invalid value\n");
468 /* Check that resume thread didn't actually start the thread.  I can't think
469    of a better way of checking this than just waiting.  I am not sure if this
470    will work on slow computers.
471 */
472   ok(WaitForSingleObject(thread,1000)==WAIT_TIMEOUT,
473      "ResumeThread should not have actually started the thread\n");
474 /* Now actually resume the thread and make sure that it actually completes*/
475   ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
476   ok((error=WaitForSingleObject(thread,1000))==WAIT_OBJECT_0,
477      "Thread did not resume\n");
478   if(error!=WAIT_OBJECT_0) {
479     TerminateThread(thread,1);
480   }
481
482   suspend_count = SuspendThread(thread);
483   ok(suspend_count == -1, "SuspendThread returned %d, expected -1\n", suspend_count);
484
485   suspend_count = ResumeThread(thread);
486   ok(suspend_count == 0 ||
487      broken(suspend_count == -1), /* win9x */
488      "ResumeThread returned %d, expected 0\n", suspend_count);
489
490   ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
491 }
492
493 /* Check that SuspendThread and ResumeThread work */
494 static VOID test_SuspendThread(void)
495 {
496   HANDLE thread,access_thread;
497   DWORD threadId,exitCode,error;
498   int i;
499
500   thread = CreateThread(NULL,0,threadFunc3,NULL,
501                         0,&threadId);
502   ok(thread!=NULL,"Create Thread failed\n");
503 /* Check that the thread is suspended */
504 /* Note that this is a polling method, and there is a race between
505    SuspendThread being called (in the child, and the loop below timing out,
506    so the test could fail on a heavily loaded or slow computer.
507 */
508   error=0;
509   for(i=0;error==0 && i<100;i++) {
510     error=SuspendThread(thread);
511     ResumeThread(thread);
512     if(error==0) {
513       Sleep(50);
514       i++;
515     }
516   }
517   ok(error==1,"SuspendThread did not work\n");
518 /* check that access restrictions are obeyed */
519   if (pOpenThread) {
520     access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_SUSPEND_RESUME),
521                            0,threadId);
522     ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
523     if (access_thread!=NULL) {
524       obey_ar(SuspendThread(access_thread)==~0U);
525       obey_ar(ResumeThread(access_thread)==~0U);
526       ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
527     }
528   }
529 /* Double check that the thread really is suspended */
530   ok((error=GetExitCodeThread(thread,&exitCode))!=0 && exitCode==STILL_ACTIVE,
531      "Thread did not really suspend\n");
532 /* Resume the thread, and make sure it actually completes */
533   ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
534   ok((error=WaitForSingleObject(thread,1000))==WAIT_OBJECT_0,
535      "Thread did not resume\n");
536   if(error!=WAIT_OBJECT_0) {
537     TerminateThread(thread,1);
538   }
539   /* Trying to suspend a terminated thread should fail */
540   error=SuspendThread(thread);
541   ok(error==~0U, "wrong return code: %d\n", error);
542   ok(GetLastError()==ERROR_ACCESS_DENIED || GetLastError()==ERROR_NO_MORE_ITEMS, "unexpected error code: %d\n", GetLastError());
543
544   ok(CloseHandle(thread)!=0,"CloseHandle Failed\n");
545 }
546
547 /* Check that TerminateThread works properly
548 */
549 static VOID test_TerminateThread(void)
550 {
551   HANDLE thread,access_thread,event;
552   DWORD threadId,exitCode;
553   event=CreateEventA(NULL,TRUE,FALSE,NULL);
554   thread = CreateThread(NULL,0,threadFunc4,event,0,&threadId);
555   ok(thread!=NULL,"Create Thread failed\n");
556 /* TerminateThread has a race condition in Wine.  If the thread is terminated
557    before it starts, it leaves a process behind.  Therefore, we wait for the
558    thread to signal that it has started.  There is no easy way to force the
559    race to occur, so we don't try to find it.
560 */
561   ok(WaitForSingleObject(event,5000)==WAIT_OBJECT_0,
562      "TerminateThread didn't work\n");
563 /* check that access restrictions are obeyed */
564   if (pOpenThread) {
565     access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_TERMINATE),
566                              0,threadId);
567     ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
568     if (access_thread!=NULL) {
569       obey_ar(TerminateThread(access_thread,99)==0);
570       ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
571     }
572   }
573 /* terminate a job and make sure it terminates */
574   ok(TerminateThread(thread,99)!=0,"TerminateThread failed\n");
575   ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
576      "TerminateThread didn't work\n");
577   ok(GetExitCodeThread(thread,&exitCode)!=STILL_ACTIVE,
578      "TerminateThread should not leave the thread 'STILL_ACTIVE'\n");
579   ok(exitCode==99, "TerminateThread returned invalid exit code\n");
580   ok(CloseHandle(thread)!=0,"Error Closing thread handle\n");
581 }
582
583 /* Check if CreateThread obeys the specified stack size.  This code does
584    not work properly, and is currently disabled
585 */
586 static VOID test_CreateThread_stack(void)
587 {
588 #if CHECK_STACK
589 /* The only way I know of to test the stack size is to use alloca
590    and __try/__except.  However, this is probably not portable,
591    and I couldn't get it to work under Wine anyhow.  However, here
592    is the code which should allow for testing that CreateThread
593    respects the stack-size limit
594 */
595      HANDLE thread;
596      DWORD threadId,exitCode;
597
598      SYSTEM_INFO sysInfo;
599      sysInfo.dwPageSize=0;
600      GetSystemInfo(&sysInfo);
601      ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
602      thread = CreateThread(NULL,sysInfo.dwPageSize,
603                            threadFunc5,&exitCode,
604                            0,&threadId);
605      ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
606         "TerminateThread didn't work\n");
607      ok(exitCode==1,"CreateThread did not obey stack-size-limit\n");
608      ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
609 #endif
610 }
611
612 /* Check whether setting/retrieving thread priorities works */
613 static VOID test_thread_priority(void)
614 {
615    HANDLE curthread,access_thread;
616    DWORD curthreadId,exitCode;
617    int min_priority=-2,max_priority=2;
618    BOOL disabled,rc;
619    int i;
620
621    curthread=GetCurrentThread();
622    curthreadId=GetCurrentThreadId();
623 /* Check thread priority */
624 /* NOTE: on Win2k/XP priority can be from -7 to 6.  All other platforms it
625          is -2 to 2.  However, even on a real Win2k system, using thread
626          priorities beyond the -2 to 2 range does not work.  If you want to try
627          anyway, enable USE_EXTENDED_PRIORITIES
628 */
629    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_NORMAL,
630       "GetThreadPriority Failed\n");
631
632    if (pOpenThread) {
633 /* check that access control is obeyed */
634      access_thread=pOpenThread(THREAD_ALL_ACCESS &
635                        (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION),
636                        0,curthreadId);
637      ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
638      if (access_thread!=NULL) {
639        obey_ar(SetThreadPriority(access_thread,1)==0);
640        obey_ar(GetThreadPriority(access_thread)==THREAD_PRIORITY_ERROR_RETURN);
641        obey_ar(GetExitCodeThread(access_thread,&exitCode)==0);
642        ok(CloseHandle(access_thread),"Error Closing thread handle\n");
643      }
644    }
645 #if USE_EXTENDED_PRIORITIES
646    min_priority=-7; max_priority=6;
647 #endif
648    for(i=min_priority;i<=max_priority;i++) {
649      ok(SetThreadPriority(curthread,i)!=0,
650         "SetThreadPriority Failed for priority: %d\n",i);
651      ok(GetThreadPriority(curthread)==i,
652         "GetThreadPriority Failed for priority: %d\n",i);
653    }
654    ok(SetThreadPriority(curthread,THREAD_PRIORITY_TIME_CRITICAL)!=0,
655       "SetThreadPriority Failed\n");
656    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_TIME_CRITICAL,
657       "GetThreadPriority Failed\n");
658    ok(SetThreadPriority(curthread,THREAD_PRIORITY_IDLE)!=0,
659        "SetThreadPriority Failed\n");
660    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_IDLE,
661        "GetThreadPriority Failed\n");
662    ok(SetThreadPriority(curthread,0)!=0,"SetThreadPriority Failed\n");
663
664 /* Check that the thread priority is not changed if SetThreadPriority
665    is called with a value outside of the max/min range */
666    SetThreadPriority(curthread,min_priority);
667    SetLastError(0xdeadbeef);
668    rc = SetThreadPriority(curthread,min_priority-1);
669
670    ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
671    ok(GetLastError() == ERROR_INVALID_PARAMETER ||
672       GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
673       "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
674       GetLastError());
675    ok(GetThreadPriority(curthread)==min_priority,
676       "GetThreadPriority didn't return min_priority\n");
677
678    SetThreadPriority(curthread,max_priority);
679    SetLastError(0xdeadbeef);
680    rc = SetThreadPriority(curthread,max_priority+1);
681
682    ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
683    ok(GetLastError() == ERROR_INVALID_PARAMETER ||
684       GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
685       "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
686       GetLastError());
687    ok(GetThreadPriority(curthread)==max_priority,
688       "GetThreadPriority didn't return max_priority\n");
689
690 /* Check thread priority boost */
691    if (!pGetThreadPriorityBoost || !pSetThreadPriorityBoost) 
692      return; /* Win9x */
693
694    SetLastError(0xdeadbeef);
695    rc=pGetThreadPriorityBoost(curthread,&disabled);
696    if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
697    {
698       win_skip("GetThreadPriorityBoost is not implemented on WinME\n");
699       return;
700    }
701
702    ok(rc!=0,"error=%d\n",GetLastError());
703
704    if (pOpenThread) {
705 /* check that access control is obeyed */
706      access_thread=pOpenThread(THREAD_ALL_ACCESS &
707                        (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION),
708                        0,curthreadId);
709      ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
710      if (access_thread!=NULL) {
711        obey_ar(pSetThreadPriorityBoost(access_thread,1)==0);
712        todo_wine obey_ar(pGetThreadPriorityBoost(access_thread,&disabled)==0);
713        ok(CloseHandle(access_thread),"Error Closing thread handle\n");
714      }
715    }
716
717    todo_wine {
718      rc = pSetThreadPriorityBoost(curthread,1);
719      ok( rc != 0, "error=%d\n",GetLastError());
720      rc=pGetThreadPriorityBoost(curthread,&disabled);
721      ok(rc!=0 && disabled==1,
722         "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
723
724      rc = pSetThreadPriorityBoost(curthread,0);
725      ok( rc != 0, "error=%d\n",GetLastError());
726    }
727    rc=pGetThreadPriorityBoost(curthread,&disabled);
728    ok(rc!=0 && disabled==0,
729       "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
730 }
731
732 /* check the GetThreadTimes function */
733 static VOID test_GetThreadTimes(void)
734 {
735      HANDLE thread,access_thread=NULL;
736      FILETIME creationTime,exitTime,kernelTime,userTime;
737      DWORD threadId;
738      int error;
739
740      thread = CreateThread(NULL,0,threadFunc2,NULL,
741                            CREATE_SUSPENDED,&threadId);
742
743      ok(thread!=NULL,"Create Thread failed\n");
744 /* check that access control is obeyed */
745      if (pOpenThread) {
746        access_thread=pOpenThread(THREAD_ALL_ACCESS &
747                                    (~THREAD_QUERY_INFORMATION), 0,threadId);
748        ok(access_thread!=NULL,
749           "OpenThread returned an invalid handle\n");
750      }
751      ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
752      ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
753         "ResumeThread didn't work\n");
754      creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99;
755      exitTime.dwLowDateTime=99;     exitTime.dwHighDateTime=99;
756      kernelTime.dwLowDateTime=99;   kernelTime.dwHighDateTime=99;
757      userTime.dwLowDateTime=99;     userTime.dwHighDateTime=99;
758 /* GetThreadTimes should set all of the parameters passed to it */
759      error=GetThreadTimes(thread,&creationTime,&exitTime,
760                           &kernelTime,&userTime);
761
762      if (error == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
763        win_skip("GetThreadTimes is not implemented\n");
764      else {
765        ok(error!=0,"GetThreadTimes failed\n");
766        ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
767           "creationTime was invalid\n");
768        ok(exitTime.dwLowDateTime!=99 || exitTime.dwHighDateTime!=99,
769           "exitTime was invalid\n");
770        ok(kernelTime.dwLowDateTime!=99 || kernelTime.dwHighDateTime!=99,
771           "kernelTimewas invalid\n");
772        ok(userTime.dwLowDateTime!=99 || userTime.dwHighDateTime!=99,
773           "userTime was invalid\n");
774        ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
775        if(access_thread!=NULL)
776        {
777          error=GetThreadTimes(access_thread,&creationTime,&exitTime,
778                               &kernelTime,&userTime);
779          obey_ar(error==0);
780        }
781      }
782      if(access_thread!=NULL) {
783        ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
784      }
785 }
786
787 /* Check the processor affinity functions */
788 /* NOTE: These functions should also be checked that they obey access control
789 */
790 static VOID test_thread_processor(void)
791 {
792    HANDLE curthread,curproc;
793    DWORD_PTR processMask,systemMask,retMask;
794    SYSTEM_INFO sysInfo;
795    int error=0;
796    BOOL is_wow64;
797
798    if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
799
800    sysInfo.dwNumberOfProcessors=0;
801    GetSystemInfo(&sysInfo);
802    ok(sysInfo.dwNumberOfProcessors>0,
803       "GetSystemInfo failed to return a valid # of processors\n");
804 /* Use the current Thread/process for all tests */
805    curthread=GetCurrentThread();
806    ok(curthread!=NULL,"GetCurrentThread failed\n");
807    curproc=GetCurrentProcess();
808    ok(curproc!=NULL,"GetCurrentProcess failed\n");
809 /* Check the Affinity Mask functions */
810    ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0,
811       "GetProcessAffinityMask failed\n");
812    ok(SetThreadAffinityMask(curthread,processMask)==processMask,
813       "SetThreadAffinityMask failed\n");
814    ok(SetThreadAffinityMask(curthread,processMask+1)==0,
815       "SetThreadAffinityMask passed for an illegal processor\n");
816 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
817    retMask = SetThreadAffinityMask(curthread,~0);
818    ok(broken(retMask==0) || retMask==processMask,
819       "SetThreadAffinityMask(thread,-1) failed to request all processors.\n");
820    if (retMask == processMask && sizeof(ULONG_PTR) > sizeof(ULONG))
821    {
822        /* only the low 32-bits matter */
823        retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0);
824        ok(retMask == processMask, "SetThreadAffinityMask failed\n");
825        retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0 >> 3);
826        ok(retMask == processMask, "SetThreadAffinityMask failed\n");
827        retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)1);
828        ok(retMask == 0, "SetThreadAffinityMask succeeded\n");
829    }
830 /* NOTE: This only works on WinNT/2000/XP) */
831    if (pSetThreadIdealProcessor) {
832      SetLastError(0xdeadbeef);
833      error=pSetThreadIdealProcessor(curthread,0);
834      if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
835      {
836        win_skip("SetThreadIdealProcessor is not implemented\n");
837        return;
838      }
839      ok(error!=-1, "SetThreadIdealProcessor failed\n");
840
841      if (is_wow64)
842      {
843          SetLastError(0xdeadbeef);
844          error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
845          todo_wine
846          ok(error!=-1, "SetThreadIdealProcessor failed for %u on Wow64\n", MAXIMUM_PROCESSORS+1);
847
848          SetLastError(0xdeadbeef);
849          error=pSetThreadIdealProcessor(curthread,65);
850          ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
851          ok(GetLastError()==ERROR_INVALID_PARAMETER,
852             "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
853      }
854      else
855      {
856          SetLastError(0xdeadbeef);
857          error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
858          ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
859          ok(GetLastError()==ERROR_INVALID_PARAMETER,
860             "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
861      }
862
863      error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
864      ok(error==0, "SetThreadIdealProcessor returned an incorrect value\n");
865    }
866 }
867
868 static VOID test_GetThreadExitCode(void)
869 {
870     DWORD exitCode, threadid;
871     DWORD GLE, ret;
872     HANDLE thread;
873
874     ret = GetExitCodeThread((HANDLE)0x2bad2bad,&exitCode);
875     ok(ret==0, "GetExitCodeThread returned non zero value: %d\n", ret);
876     GLE = GetLastError();
877     ok(GLE==ERROR_INVALID_HANDLE, "GetLastError returned %d (expected 6)\n", GLE);
878
879     thread = CreateThread(NULL,0,threadFunc2,NULL,0,&threadid);
880     ret = WaitForSingleObject(thread,100);
881     ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
882     ret = GetExitCodeThread(thread,&exitCode);
883     ok(ret==exitCode || ret==1, 
884        "GetExitCodeThread returned %d (expected 1 or %d)\n", ret, exitCode);
885     ok(exitCode==99, "threadFunc2 exited with code %d (expected 99)\n", exitCode);
886     ok(CloseHandle(thread)!=0,"Error closing thread handle\n");
887 }
888
889 #ifdef __i386__
890
891 static int test_value = 0;
892 static HANDLE event;
893
894 static void WINAPI set_test_val( int val )
895 {
896     test_value += val;
897 }
898
899 static DWORD WINAPI threadFunc6(LPVOID p)
900 {
901     SetEvent( event );
902     Sleep( 1000 );
903     test_value *= (int)p;
904     return 0;
905 }
906
907 static void test_SetThreadContext(void)
908 {
909     CONTEXT ctx;
910     int *stack;
911     HANDLE thread;
912     DWORD threadid;
913     DWORD prevcount;
914     BOOL ret;
915
916     SetLastError(0xdeadbeef);
917     event = CreateEvent( NULL, TRUE, FALSE, NULL );
918     thread = CreateThread( NULL, 0, threadFunc6, (void *)2, 0, &threadid );
919     ok( thread != NULL, "CreateThread failed : (%d)\n", GetLastError() );
920     if (!thread)
921     {
922         trace("Thread creation failed, skipping rest of test\n");
923         return;
924     }
925     WaitForSingleObject( event, INFINITE );
926     SuspendThread( thread );
927     CloseHandle( event );
928
929     ctx.ContextFlags = CONTEXT_FULL;
930     SetLastError(0xdeadbeef);
931     ret = GetThreadContext( thread, &ctx );
932     ok( ret, "GetThreadContext failed : (%u)\n", GetLastError() );
933
934     if (ret)
935     {
936         /* simulate a call to set_test_val(10) */
937         stack = (int *)ctx.Esp;
938         stack[-1] = 10;
939         stack[-2] = ctx.Eip;
940         ctx.Esp -= 2 * sizeof(int *);
941         ctx.Eip = (DWORD)set_test_val;
942         SetLastError(0xdeadbeef);
943         ok( SetThreadContext( thread, &ctx ), "SetThreadContext failed : (%d)\n", GetLastError() );
944     }
945
946     SetLastError(0xdeadbeef);
947     prevcount = ResumeThread( thread );
948     ok ( prevcount == 1, "Previous suspend count (%d) instead of 1, last error : (%d)\n",
949                          prevcount, GetLastError() );
950
951     WaitForSingleObject( thread, INFINITE );
952     ok( test_value == 20, "test_value %d instead of 20\n", test_value );
953 }
954
955 #endif  /* __i386__ */
956
957 static HANDLE finish_event;
958 static LONG times_executed;
959
960 static DWORD CALLBACK work_function(void *p)
961 {
962     LONG executed = InterlockedIncrement(&times_executed);
963
964     if (executed == 100)
965         SetEvent(finish_event);
966     return 0;
967 }
968
969 static void test_QueueUserWorkItem(void)
970 {
971     INT_PTR i;
972     DWORD wait_result;
973     DWORD before, after;
974
975     /* QueueUserWorkItem not present on win9x */
976     if (!pQueueUserWorkItem) return;
977
978     finish_event = CreateEvent(NULL, TRUE, FALSE, NULL);
979
980     before = GetTickCount();
981
982     for (i = 0; i < 100; i++)
983     {
984         BOOL ret = pQueueUserWorkItem(work_function, (void *)i, WT_EXECUTEDEFAULT);
985         ok(ret, "QueueUserWorkItem failed with error %d\n", GetLastError());
986     }
987
988     wait_result = WaitForSingleObject(finish_event, 10000);
989
990     after = GetTickCount();
991     trace("100 QueueUserWorkItem calls took %dms\n", after - before);
992     ok(wait_result == WAIT_OBJECT_0, "wait failed with error 0x%x\n", wait_result);
993
994     ok(times_executed == 100, "didn't execute all of the work items\n");
995 }
996
997 static void CALLBACK signaled_function(PVOID p, BOOLEAN TimerOrWaitFired)
998 {
999     HANDLE event = p;
1000     SetEvent(event);
1001     ok(!TimerOrWaitFired, "wait shouldn't have timed out\n");
1002 }
1003
1004 static void CALLBACK timeout_function(PVOID p, BOOLEAN TimerOrWaitFired)
1005 {
1006     HANDLE event = p;
1007     SetEvent(event);
1008     ok(TimerOrWaitFired, "wait should have timed out\n");
1009 }
1010
1011 static void test_RegisterWaitForSingleObject(void)
1012 {
1013     BOOL ret;
1014     HANDLE wait_handle;
1015     HANDLE handle;
1016     HANDLE complete_event;
1017
1018     if (!pRegisterWaitForSingleObject || !pUnregisterWait)
1019     {
1020         win_skip("RegisterWaitForSingleObject or UnregisterWait not implemented\n");
1021         return;
1022     }
1023
1024     /* test signaled case */
1025
1026     handle = CreateEvent(NULL, TRUE, TRUE, NULL);
1027     complete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
1028
1029     ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1030     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1031
1032     WaitForSingleObject(complete_event, INFINITE);
1033     /* give worker thread chance to complete */
1034     Sleep(100);
1035
1036     ret = pUnregisterWait(wait_handle);
1037     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1038
1039     /* test cancel case */
1040
1041     ResetEvent(handle);
1042
1043     ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1044     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1045
1046     ret = pUnregisterWait(wait_handle);
1047     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1048
1049     /* test timeout case */
1050
1051     ret = pRegisterWaitForSingleObject(&wait_handle, handle, timeout_function, complete_event, 0, WT_EXECUTEONLYONCE);
1052     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1053
1054     WaitForSingleObject(complete_event, INFINITE);
1055     /* give worker thread chance to complete */
1056     Sleep(100);
1057
1058     ret = pUnregisterWait(wait_handle);
1059     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1060 }
1061
1062 static DWORD TLS_main;
1063 static DWORD TLS_index0, TLS_index1;
1064
1065 static DWORD WINAPI TLS_InheritanceProc(LPVOID p)
1066 {
1067   /* We should NOT inherit the TLS values from our parent or from the
1068      main thread.  */
1069   LPVOID val;
1070
1071   val = TlsGetValue(TLS_main);
1072   ok(val == NULL, "TLS inheritance failed\n");
1073
1074   val = TlsGetValue(TLS_index0);
1075   ok(val == NULL, "TLS inheritance failed\n");
1076
1077   val = TlsGetValue(TLS_index1);
1078   ok(val == NULL, "TLS inheritance failed\n");
1079
1080   return 0;
1081 }
1082
1083 /* Basic TLS usage test.  Make sure we can create slots and the values we
1084    store in them are separate among threads.  Also test TLS value
1085    inheritance with TLS_InheritanceProc.  */
1086 static DWORD WINAPI TLS_ThreadProc(LPVOID p)
1087 {
1088   LONG_PTR id = (LONG_PTR) p;
1089   LPVOID val;
1090   BOOL ret;
1091
1092   if (sync_threads_and_run_one(0, id))
1093   {
1094     TLS_index0 = TlsAlloc();
1095     ok(TLS_index0 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1096   }
1097   resync_after_run();
1098
1099   if (sync_threads_and_run_one(1, id))
1100   {
1101     TLS_index1 = TlsAlloc();
1102     ok(TLS_index1 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1103
1104     /* Slot indices should be different even if created in different
1105        threads.  */
1106     ok(TLS_index0 != TLS_index1, "TlsAlloc failed\n");
1107
1108     /* Both slots should be initialized to NULL */
1109     val = TlsGetValue(TLS_index0);
1110     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1111     ok(val == NULL, "TLS slot not initialized correctly\n");
1112
1113     val = TlsGetValue(TLS_index1);
1114     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1115     ok(val == NULL, "TLS slot not initialized correctly\n");
1116   }
1117   resync_after_run();
1118
1119   if (sync_threads_and_run_one(0, id))
1120   {
1121     val = TlsGetValue(TLS_index0);
1122     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1123     ok(val == NULL, "TLS slot not initialized correctly\n");
1124
1125     val = TlsGetValue(TLS_index1);
1126     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1127     ok(val == NULL, "TLS slot not initialized correctly\n");
1128
1129     ret = TlsSetValue(TLS_index0, (LPVOID) 1);
1130     ok(ret, "TlsSetValue failed\n");
1131
1132     ret = TlsSetValue(TLS_index1, (LPVOID) 2);
1133     ok(ret, "TlsSetValue failed\n");
1134
1135     val = TlsGetValue(TLS_index0);
1136     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1137     ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
1138
1139     val = TlsGetValue(TLS_index1);
1140     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1141     ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
1142   }
1143   resync_after_run();
1144
1145   if (sync_threads_and_run_one(1, id))
1146   {
1147     val = TlsGetValue(TLS_index0);
1148     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1149     ok(val == NULL, "TLS slot not initialized correctly\n");
1150
1151     val = TlsGetValue(TLS_index1);
1152     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1153     ok(val == NULL, "TLS slot not initialized correctly\n");
1154
1155     ret = TlsSetValue(TLS_index0, (LPVOID) 3);
1156     ok(ret, "TlsSetValue failed\n");
1157
1158     ret = TlsSetValue(TLS_index1, (LPVOID) 4);
1159     ok(ret, "TlsSetValue failed\n");
1160
1161     val = TlsGetValue(TLS_index0);
1162     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1163     ok(val == (LPVOID) 3, "TLS slot not initialized correctly\n");
1164
1165     val = TlsGetValue(TLS_index1);
1166     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1167     ok(val == (LPVOID) 4, "TLS slot not initialized correctly\n");
1168   }
1169   resync_after_run();
1170
1171   if (sync_threads_and_run_one(0, id))
1172   {
1173     HANDLE thread;
1174     DWORD waitret, tid;
1175
1176     val = TlsGetValue(TLS_index0);
1177     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1178     ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
1179
1180     val = TlsGetValue(TLS_index1);
1181     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1182     ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
1183
1184     thread = CreateThread(NULL, 0, TLS_InheritanceProc, 0, 0, &tid);
1185     ok(thread != NULL, "CreateThread failed\n");
1186     waitret = WaitForSingleObject(thread, 60000);
1187     ok(waitret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1188     CloseHandle(thread);
1189
1190     ret = TlsFree(TLS_index0);
1191     ok(ret, "TlsFree failed\n");
1192   }
1193   resync_after_run();
1194
1195   if (sync_threads_and_run_one(1, id))
1196   {
1197     ret = TlsFree(TLS_index1);
1198     ok(ret, "TlsFree failed\n");
1199   }
1200   resync_after_run();
1201
1202   return 0;
1203 }
1204
1205 static void test_TLS(void)
1206 {
1207   HANDLE threads[2];
1208   LONG_PTR i;
1209   DWORD ret;
1210   BOOL suc;
1211
1212   init_thread_sync_helpers();
1213
1214   /* Allocate a TLS slot in the main thread to test for inheritance.  */
1215   TLS_main = TlsAlloc();
1216   ok(TLS_main != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1217   suc = TlsSetValue(TLS_main, (LPVOID) 4114);
1218   ok(suc, "TlsSetValue failed\n");
1219
1220   for (i = 0; i < 2; ++i)
1221   {
1222     DWORD tid;
1223
1224     threads[i] = CreateThread(NULL, 0, TLS_ThreadProc, (LPVOID) i, 0, &tid);
1225     ok(threads[i] != NULL, "CreateThread failed\n");
1226   }
1227
1228   ret = WaitForMultipleObjects(2, threads, TRUE, 60000);
1229   ok(ret == WAIT_OBJECT_0 || ret == WAIT_OBJECT_0+1 /* nt4 */, "WaitForMultipleObjects failed %u\n",ret);
1230
1231   for (i = 0; i < 2; ++i)
1232     CloseHandle(threads[i]);
1233
1234   suc = TlsFree(TLS_main);
1235   ok(suc, "TlsFree failed\n");
1236   cleanup_thread_sync_helpers();
1237 }
1238
1239 static void test_ThreadErrorMode(void)
1240 {
1241     DWORD oldmode;
1242     DWORD mode;
1243     DWORD rtlmode;
1244     BOOL ret;
1245
1246     if (!pSetThreadErrorMode || !pGetThreadErrorMode)
1247     {
1248         win_skip("SetThreadErrorMode and/or GetThreadErrorMode unavailable (added in Windows 7)\n");
1249         return;
1250     }
1251
1252     if (!pRtlGetThreadErrorMode) {
1253         win_skip("RtlGetThreadErrorMode not available\n");
1254         return;
1255     }
1256
1257     oldmode = pGetThreadErrorMode();
1258
1259     ret = pSetThreadErrorMode(0, &mode);
1260     ok(ret, "SetThreadErrorMode failed\n");
1261     ok(mode == oldmode,
1262        "SetThreadErrorMode returned old mode 0x%x, expected 0x%x\n",
1263        mode, oldmode);
1264     mode = pGetThreadErrorMode();
1265     ok(mode == 0, "GetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1266     rtlmode = pRtlGetThreadErrorMode();
1267     ok(rtlmode == 0,
1268        "RtlGetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1269
1270     ret = pSetThreadErrorMode(SEM_FAILCRITICALERRORS, &mode);
1271     ok(ret, "SetThreadErrorMode failed\n");
1272     ok(mode == 0,
1273        "SetThreadErrorMode returned old mode 0x%x, expected 0\n", mode);
1274     mode = pGetThreadErrorMode();
1275     ok(mode == SEM_FAILCRITICALERRORS,
1276        "GetThreadErrorMode returned mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1277        mode);
1278     rtlmode = pRtlGetThreadErrorMode();
1279     ok(rtlmode == 0x10,
1280        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x10\n", mode);
1281
1282     ret = pSetThreadErrorMode(SEM_NOGPFAULTERRORBOX, &mode);
1283     ok(ret, "SetThreadErrorMode failed\n");
1284     ok(mode == SEM_FAILCRITICALERRORS,
1285        "SetThreadErrorMode returned old mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1286        mode);
1287     mode = pGetThreadErrorMode();
1288     ok(mode == SEM_NOGPFAULTERRORBOX,
1289        "GetThreadErrorMode returned mode 0x%x, expected SEM_NOGPFAULTERRORBOX\n",
1290        mode);
1291     rtlmode = pRtlGetThreadErrorMode();
1292     ok(rtlmode == 0x20,
1293        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x20\n", mode);
1294
1295     ret = pSetThreadErrorMode(SEM_NOOPENFILEERRORBOX, NULL);
1296     ok(ret, "SetThreadErrorMode failed\n");
1297     mode = pGetThreadErrorMode();
1298     ok(mode == SEM_NOOPENFILEERRORBOX,
1299        "GetThreadErrorMode returned mode 0x%x, expected SEM_NOOPENFILEERRORBOX\n",
1300        mode);
1301     rtlmode = pRtlGetThreadErrorMode();
1302     ok(rtlmode == 0x40,
1303        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x40\n", rtlmode);
1304
1305     for (mode = 1; mode; mode <<= 1)
1306     {
1307         ret = pSetThreadErrorMode(mode, NULL);
1308         if (mode & (SEM_FAILCRITICALERRORS |
1309                     SEM_NOGPFAULTERRORBOX |
1310                     SEM_NOOPENFILEERRORBOX))
1311         {
1312             ok(ret,
1313                "SetThreadErrorMode(0x%x,NULL) failed with error %d\n",
1314                mode, GetLastError());
1315         }
1316         else
1317         {
1318             DWORD GLE = GetLastError();
1319             ok(!ret,
1320                "SetThreadErrorMode(0x%x,NULL) succeeded, expected failure\n",
1321                mode);
1322             ok(GLE == ERROR_INVALID_PARAMETER,
1323                "SetThreadErrorMode(0x%x,NULL) failed with %d, "
1324                "expected ERROR_INVALID_PARAMETER\n",
1325                mode, GLE);
1326         }
1327     }
1328
1329     pSetThreadErrorMode(oldmode, NULL);
1330 }
1331
1332 START_TEST(thread)
1333 {
1334    HINSTANCE lib;
1335    HINSTANCE ntdll;
1336    int argc;
1337    char **argv;
1338    argc = winetest_get_mainargs( &argv );
1339 /* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
1340    so that the compile passes
1341 */
1342    lib=GetModuleHandleA("kernel32.dll");
1343    ok(lib!=NULL,"Couldn't get a handle for kernel32.dll\n");
1344    pGetThreadPriorityBoost=(void *)GetProcAddress(lib,"GetThreadPriorityBoost");
1345    pOpenThread=(void *)GetProcAddress(lib,"OpenThread");
1346    pQueueUserWorkItem=(void *)GetProcAddress(lib,"QueueUserWorkItem");
1347    pSetThreadIdealProcessor=(void *)GetProcAddress(lib,"SetThreadIdealProcessor");
1348    pSetThreadPriorityBoost=(void *)GetProcAddress(lib,"SetThreadPriorityBoost");
1349    pRegisterWaitForSingleObject=(void *)GetProcAddress(lib,"RegisterWaitForSingleObject");
1350    pUnregisterWait=(void *)GetProcAddress(lib,"UnregisterWait");
1351    pIsWow64Process=(void *)GetProcAddress(lib,"IsWow64Process");
1352    pSetThreadErrorMode=(void *)GetProcAddress(lib,"SetThreadErrorMode");
1353    pGetThreadErrorMode=(void *)GetProcAddress(lib,"GetThreadErrorMode");
1354
1355    ntdll=GetModuleHandleA("ntdll.dll");
1356    if (ntdll)
1357    {
1358        pRtlGetThreadErrorMode=(void *)GetProcAddress(ntdll,"RtlGetThreadErrorMode");
1359    }
1360
1361    if (argc >= 3)
1362    {
1363        if (!strcmp(argv[2], "sleep"))
1364        {
1365            HANDLE hAddrEvents[2];
1366            create_function_addr_events(hAddrEvents);
1367            SetEvent(hAddrEvents[0]);
1368            SetEvent(hAddrEvents[1]);
1369            Sleep(5000); /* spawned process runs for at most 5 seconds */
1370            return;
1371        }
1372        while (1)
1373        {
1374            HANDLE hThread;
1375            DWORD tid;
1376            hThread = CreateThread(NULL, 0, threadFunc2, NULL, 0, &tid);
1377            ok(hThread != NULL, "CreateThread failed, error %u\n",
1378               GetLastError());
1379            ok(WaitForSingleObject(hThread, 200) == WAIT_OBJECT_0,
1380               "Thread did not exit in time\n");
1381            if (hThread == NULL) break;
1382            CloseHandle(hThread);
1383        }
1384        return;
1385    }
1386
1387    test_CreateRemoteThread();
1388    test_CreateThread_basic();
1389    test_CreateThread_suspended();
1390    test_SuspendThread();
1391    test_TerminateThread();
1392    test_CreateThread_stack();
1393    test_thread_priority();
1394    test_GetThreadTimes();
1395    test_thread_processor();
1396    test_GetThreadExitCode();
1397 #ifdef __i386__
1398    test_SetThreadContext();
1399 #endif
1400    test_QueueUserWorkItem();
1401    test_RegisterWaitForSingleObject();
1402    test_TLS();
1403    test_ThreadErrorMode();
1404 }