server: Debugging our own process is disallowed.
[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,~0UL);
818    ok(broken(retMask==0) || retMask==processMask,
819       "SetThreadAffinityMask(thread,-1) failed to request all processors.\n");
820 /* NOTE: This only works on WinNT/2000/XP) */
821    if (pSetThreadIdealProcessor) {
822      SetLastError(0xdeadbeef);
823      error=pSetThreadIdealProcessor(curthread,0);
824      if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
825      {
826        win_skip("SetThreadIdealProcessor is not implemented\n");
827        return;
828      }
829      ok(error!=-1, "SetThreadIdealProcessor failed\n");
830
831      if (is_wow64)
832      {
833          SetLastError(0xdeadbeef);
834          error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
835          todo_wine
836          ok(error!=-1, "SetThreadIdealProcessor failed for %u on Wow64\n", MAXIMUM_PROCESSORS+1);
837
838          SetLastError(0xdeadbeef);
839          error=pSetThreadIdealProcessor(curthread,65);
840          ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
841          ok(GetLastError()==ERROR_INVALID_PARAMETER,
842             "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
843      }
844      else
845      {
846          SetLastError(0xdeadbeef);
847          error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
848          ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
849          ok(GetLastError()==ERROR_INVALID_PARAMETER,
850             "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
851      }
852
853      error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
854      ok(error==0, "SetThreadIdealProcessor returned an incorrect value\n");
855    }
856 }
857
858 static VOID test_GetThreadExitCode(void)
859 {
860     DWORD exitCode, threadid;
861     DWORD GLE, ret;
862     HANDLE thread;
863
864     ret = GetExitCodeThread((HANDLE)0x2bad2bad,&exitCode);
865     ok(ret==0, "GetExitCodeThread returned non zero value: %d\n", ret);
866     GLE = GetLastError();
867     ok(GLE==ERROR_INVALID_HANDLE, "GetLastError returned %d (expected 6)\n", GLE);
868
869     thread = CreateThread(NULL,0,threadFunc2,NULL,0,&threadid);
870     ret = WaitForSingleObject(thread,100);
871     ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
872     ret = GetExitCodeThread(thread,&exitCode);
873     ok(ret==exitCode || ret==1, 
874        "GetExitCodeThread returned %d (expected 1 or %d)\n", ret, exitCode);
875     ok(exitCode==99, "threadFunc2 exited with code %d (expected 99)\n", exitCode);
876     ok(CloseHandle(thread)!=0,"Error closing thread handle\n");
877 }
878
879 #ifdef __i386__
880
881 static int test_value = 0;
882 static HANDLE event;
883
884 static void WINAPI set_test_val( int val )
885 {
886     test_value += val;
887 }
888
889 static DWORD WINAPI threadFunc6(LPVOID p)
890 {
891     SetEvent( event );
892     Sleep( 1000 );
893     test_value *= (int)p;
894     return 0;
895 }
896
897 static void test_SetThreadContext(void)
898 {
899     CONTEXT ctx;
900     int *stack;
901     HANDLE thread;
902     DWORD threadid;
903     DWORD prevcount;
904     BOOL ret;
905
906     SetLastError(0xdeadbeef);
907     event = CreateEvent( NULL, TRUE, FALSE, NULL );
908     thread = CreateThread( NULL, 0, threadFunc6, (void *)2, 0, &threadid );
909     ok( thread != NULL, "CreateThread failed : (%d)\n", GetLastError() );
910     if (!thread)
911     {
912         trace("Thread creation failed, skipping rest of test\n");
913         return;
914     }
915     WaitForSingleObject( event, INFINITE );
916     SuspendThread( thread );
917     CloseHandle( event );
918
919     ctx.ContextFlags = CONTEXT_FULL;
920     SetLastError(0xdeadbeef);
921     ret = GetThreadContext( thread, &ctx );
922     ok( ret, "GetThreadContext failed : (%u)\n", GetLastError() );
923
924     if (ret)
925     {
926         /* simulate a call to set_test_val(10) */
927         stack = (int *)ctx.Esp;
928         stack[-1] = 10;
929         stack[-2] = ctx.Eip;
930         ctx.Esp -= 2 * sizeof(int *);
931         ctx.Eip = (DWORD)set_test_val;
932         SetLastError(0xdeadbeef);
933         ok( SetThreadContext( thread, &ctx ), "SetThreadContext failed : (%d)\n", GetLastError() );
934     }
935
936     SetLastError(0xdeadbeef);
937     prevcount = ResumeThread( thread );
938     ok ( prevcount == 1, "Previous suspend count (%d) instead of 1, last error : (%d)\n",
939                          prevcount, GetLastError() );
940
941     WaitForSingleObject( thread, INFINITE );
942     ok( test_value == 20, "test_value %d instead of 20\n", test_value );
943 }
944
945 #endif  /* __i386__ */
946
947 static HANDLE finish_event;
948 static LONG times_executed;
949
950 static DWORD CALLBACK work_function(void *p)
951 {
952     LONG executed = InterlockedIncrement(&times_executed);
953
954     if (executed == 100)
955         SetEvent(finish_event);
956     return 0;
957 }
958
959 static void test_QueueUserWorkItem(void)
960 {
961     INT_PTR i;
962     DWORD wait_result;
963     DWORD before, after;
964
965     /* QueueUserWorkItem not present on win9x */
966     if (!pQueueUserWorkItem) return;
967
968     finish_event = CreateEvent(NULL, TRUE, FALSE, NULL);
969
970     before = GetTickCount();
971
972     for (i = 0; i < 100; i++)
973     {
974         BOOL ret = pQueueUserWorkItem(work_function, (void *)i, WT_EXECUTEDEFAULT);
975         ok(ret, "QueueUserWorkItem failed with error %d\n", GetLastError());
976     }
977
978     wait_result = WaitForSingleObject(finish_event, 10000);
979
980     after = GetTickCount();
981     trace("100 QueueUserWorkItem calls took %dms\n", after - before);
982     ok(wait_result == WAIT_OBJECT_0, "wait failed with error 0x%x\n", wait_result);
983
984     ok(times_executed == 100, "didn't execute all of the work items\n");
985 }
986
987 static void CALLBACK signaled_function(PVOID p, BOOLEAN TimerOrWaitFired)
988 {
989     HANDLE event = p;
990     SetEvent(event);
991     ok(!TimerOrWaitFired, "wait shouldn't have timed out\n");
992 }
993
994 static void CALLBACK timeout_function(PVOID p, BOOLEAN TimerOrWaitFired)
995 {
996     HANDLE event = p;
997     SetEvent(event);
998     ok(TimerOrWaitFired, "wait should have timed out\n");
999 }
1000
1001 static void test_RegisterWaitForSingleObject(void)
1002 {
1003     BOOL ret;
1004     HANDLE wait_handle;
1005     HANDLE handle;
1006     HANDLE complete_event;
1007
1008     if (!pRegisterWaitForSingleObject || !pUnregisterWait)
1009     {
1010         win_skip("RegisterWaitForSingleObject or UnregisterWait not implemented\n");
1011         return;
1012     }
1013
1014     /* test signaled case */
1015
1016     handle = CreateEvent(NULL, TRUE, TRUE, NULL);
1017     complete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
1018
1019     ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1020     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1021
1022     WaitForSingleObject(complete_event, INFINITE);
1023     /* give worker thread chance to complete */
1024     Sleep(100);
1025
1026     ret = pUnregisterWait(wait_handle);
1027     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1028
1029     /* test cancel case */
1030
1031     ResetEvent(handle);
1032
1033     ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1034     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1035
1036     ret = pUnregisterWait(wait_handle);
1037     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1038
1039     /* test timeout case */
1040
1041     ret = pRegisterWaitForSingleObject(&wait_handle, handle, timeout_function, complete_event, 0, WT_EXECUTEONLYONCE);
1042     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1043
1044     WaitForSingleObject(complete_event, INFINITE);
1045     /* give worker thread chance to complete */
1046     Sleep(100);
1047
1048     ret = pUnregisterWait(wait_handle);
1049     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1050 }
1051
1052 static DWORD TLS_main;
1053 static DWORD TLS_index0, TLS_index1;
1054
1055 static DWORD WINAPI TLS_InheritanceProc(LPVOID p)
1056 {
1057   /* We should NOT inherit the TLS values from our parent or from the
1058      main thread.  */
1059   LPVOID val;
1060
1061   val = TlsGetValue(TLS_main);
1062   ok(val == NULL, "TLS inheritance failed\n");
1063
1064   val = TlsGetValue(TLS_index0);
1065   ok(val == NULL, "TLS inheritance failed\n");
1066
1067   val = TlsGetValue(TLS_index1);
1068   ok(val == NULL, "TLS inheritance failed\n");
1069
1070   return 0;
1071 }
1072
1073 /* Basic TLS usage test.  Make sure we can create slots and the values we
1074    store in them are separate among threads.  Also test TLS value
1075    inheritance with TLS_InheritanceProc.  */
1076 static DWORD WINAPI TLS_ThreadProc(LPVOID p)
1077 {
1078   LONG_PTR id = (LONG_PTR) p;
1079   LPVOID val;
1080   BOOL ret;
1081
1082   if (sync_threads_and_run_one(0, id))
1083   {
1084     TLS_index0 = TlsAlloc();
1085     ok(TLS_index0 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1086   }
1087   resync_after_run();
1088
1089   if (sync_threads_and_run_one(1, id))
1090   {
1091     TLS_index1 = TlsAlloc();
1092     ok(TLS_index1 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1093
1094     /* Slot indices should be different even if created in different
1095        threads.  */
1096     ok(TLS_index0 != TLS_index1, "TlsAlloc failed\n");
1097
1098     /* Both slots should be initialized to NULL */
1099     val = TlsGetValue(TLS_index0);
1100     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1101     ok(val == NULL, "TLS slot not initialized correctly\n");
1102
1103     val = TlsGetValue(TLS_index1);
1104     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1105     ok(val == NULL, "TLS slot not initialized correctly\n");
1106   }
1107   resync_after_run();
1108
1109   if (sync_threads_and_run_one(0, id))
1110   {
1111     val = TlsGetValue(TLS_index0);
1112     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1113     ok(val == NULL, "TLS slot not initialized correctly\n");
1114
1115     val = TlsGetValue(TLS_index1);
1116     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1117     ok(val == NULL, "TLS slot not initialized correctly\n");
1118
1119     ret = TlsSetValue(TLS_index0, (LPVOID) 1);
1120     ok(ret, "TlsSetValue failed\n");
1121
1122     ret = TlsSetValue(TLS_index1, (LPVOID) 2);
1123     ok(ret, "TlsSetValue failed\n");
1124
1125     val = TlsGetValue(TLS_index0);
1126     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1127     ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
1128
1129     val = TlsGetValue(TLS_index1);
1130     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1131     ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
1132   }
1133   resync_after_run();
1134
1135   if (sync_threads_and_run_one(1, id))
1136   {
1137     val = TlsGetValue(TLS_index0);
1138     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1139     ok(val == NULL, "TLS slot not initialized correctly\n");
1140
1141     val = TlsGetValue(TLS_index1);
1142     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1143     ok(val == NULL, "TLS slot not initialized correctly\n");
1144
1145     ret = TlsSetValue(TLS_index0, (LPVOID) 3);
1146     ok(ret, "TlsSetValue failed\n");
1147
1148     ret = TlsSetValue(TLS_index1, (LPVOID) 4);
1149     ok(ret, "TlsSetValue failed\n");
1150
1151     val = TlsGetValue(TLS_index0);
1152     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1153     ok(val == (LPVOID) 3, "TLS slot not initialized correctly\n");
1154
1155     val = TlsGetValue(TLS_index1);
1156     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1157     ok(val == (LPVOID) 4, "TLS slot not initialized correctly\n");
1158   }
1159   resync_after_run();
1160
1161   if (sync_threads_and_run_one(0, id))
1162   {
1163     HANDLE thread;
1164     DWORD waitret, tid;
1165
1166     val = TlsGetValue(TLS_index0);
1167     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1168     ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
1169
1170     val = TlsGetValue(TLS_index1);
1171     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1172     ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
1173
1174     thread = CreateThread(NULL, 0, TLS_InheritanceProc, 0, 0, &tid);
1175     ok(thread != NULL, "CreateThread failed\n");
1176     waitret = WaitForSingleObject(thread, 60000);
1177     ok(waitret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1178     CloseHandle(thread);
1179
1180     ret = TlsFree(TLS_index0);
1181     ok(ret, "TlsFree failed\n");
1182   }
1183   resync_after_run();
1184
1185   if (sync_threads_and_run_one(1, id))
1186   {
1187     ret = TlsFree(TLS_index1);
1188     ok(ret, "TlsFree failed\n");
1189   }
1190   resync_after_run();
1191
1192   return 0;
1193 }
1194
1195 static void test_TLS(void)
1196 {
1197   HANDLE threads[2];
1198   LONG_PTR i;
1199   DWORD ret;
1200   BOOL suc;
1201
1202   init_thread_sync_helpers();
1203
1204   /* Allocate a TLS slot in the main thread to test for inheritance.  */
1205   TLS_main = TlsAlloc();
1206   ok(TLS_main != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1207   suc = TlsSetValue(TLS_main, (LPVOID) 4114);
1208   ok(suc, "TlsSetValue failed\n");
1209
1210   for (i = 0; i < 2; ++i)
1211   {
1212     DWORD tid;
1213
1214     threads[i] = CreateThread(NULL, 0, TLS_ThreadProc, (LPVOID) i, 0, &tid);
1215     ok(threads[i] != NULL, "CreateThread failed\n");
1216   }
1217
1218   ret = WaitForMultipleObjects(2, threads, TRUE, 60000);
1219   ok(ret == WAIT_OBJECT_0 || ret == WAIT_OBJECT_0+1 /* nt4 */, "WaitForMultipleObjects failed %u\n",ret);
1220
1221   for (i = 0; i < 2; ++i)
1222     CloseHandle(threads[i]);
1223
1224   suc = TlsFree(TLS_main);
1225   ok(suc, "TlsFree failed\n");
1226   cleanup_thread_sync_helpers();
1227 }
1228
1229 static void test_ThreadErrorMode(void)
1230 {
1231     DWORD oldmode;
1232     DWORD mode;
1233     DWORD rtlmode;
1234     BOOL ret;
1235
1236     if (!pSetThreadErrorMode || !pGetThreadErrorMode)
1237     {
1238         win_skip("SetThreadErrorMode and/or GetThreadErrorMode unavailable (added in Windows 7)\n");
1239         return;
1240     }
1241
1242     if (!pRtlGetThreadErrorMode) {
1243         win_skip("RtlGetThreadErrorMode not available\n");
1244         return;
1245     }
1246
1247     oldmode = pGetThreadErrorMode();
1248
1249     ret = pSetThreadErrorMode(0, &mode);
1250     ok(ret, "SetThreadErrorMode failed\n");
1251     ok(mode == oldmode,
1252        "SetThreadErrorMode returned old mode 0x%x, expected 0x%x\n",
1253        mode, oldmode);
1254     mode = pGetThreadErrorMode();
1255     ok(mode == 0, "GetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1256     rtlmode = pRtlGetThreadErrorMode();
1257     ok(rtlmode == 0,
1258        "RtlGetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1259
1260     ret = pSetThreadErrorMode(SEM_FAILCRITICALERRORS, &mode);
1261     ok(ret, "SetThreadErrorMode failed\n");
1262     ok(mode == 0,
1263        "SetThreadErrorMode returned old mode 0x%x, expected 0\n", mode);
1264     mode = pGetThreadErrorMode();
1265     ok(mode == SEM_FAILCRITICALERRORS,
1266        "GetThreadErrorMode returned mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1267        mode);
1268     rtlmode = pRtlGetThreadErrorMode();
1269     ok(rtlmode == 0x10,
1270        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x10\n", mode);
1271
1272     ret = pSetThreadErrorMode(SEM_NOGPFAULTERRORBOX, &mode);
1273     ok(ret, "SetThreadErrorMode failed\n");
1274     ok(mode == SEM_FAILCRITICALERRORS,
1275        "SetThreadErrorMode returned old mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1276        mode);
1277     mode = pGetThreadErrorMode();
1278     ok(mode == SEM_NOGPFAULTERRORBOX,
1279        "GetThreadErrorMode returned mode 0x%x, expected SEM_NOGPFAULTERRORBOX\n",
1280        mode);
1281     rtlmode = pRtlGetThreadErrorMode();
1282     ok(rtlmode == 0x20,
1283        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x20\n", mode);
1284
1285     ret = pSetThreadErrorMode(SEM_NOOPENFILEERRORBOX, NULL);
1286     ok(ret, "SetThreadErrorMode failed\n");
1287     mode = pGetThreadErrorMode();
1288     ok(mode == SEM_NOOPENFILEERRORBOX,
1289        "GetThreadErrorMode returned mode 0x%x, expected SEM_NOOPENFILEERRORBOX\n",
1290        mode);
1291     rtlmode = pRtlGetThreadErrorMode();
1292     ok(rtlmode == 0x40,
1293        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x40\n", rtlmode);
1294
1295     for (mode = 1; mode; mode <<= 1)
1296     {
1297         ret = pSetThreadErrorMode(mode, NULL);
1298         if (mode & (SEM_FAILCRITICALERRORS |
1299                     SEM_NOGPFAULTERRORBOX |
1300                     SEM_NOOPENFILEERRORBOX))
1301         {
1302             ok(ret,
1303                "SetThreadErrorMode(0x%x,NULL) failed with error %d\n",
1304                mode, GetLastError());
1305         }
1306         else
1307         {
1308             DWORD GLE = GetLastError();
1309             ok(!ret,
1310                "SetThreadErrorMode(0x%x,NULL) succeeded, expected failure\n",
1311                mode);
1312             ok(GLE == ERROR_INVALID_PARAMETER,
1313                "SetThreadErrorMode(0x%x,NULL) failed with %d, "
1314                "expected ERROR_INVALID_PARAMETER\n",
1315                mode, GLE);
1316         }
1317     }
1318
1319     pSetThreadErrorMode(oldmode, NULL);
1320 }
1321
1322 START_TEST(thread)
1323 {
1324    HINSTANCE lib;
1325    HINSTANCE ntdll;
1326    int argc;
1327    char **argv;
1328    argc = winetest_get_mainargs( &argv );
1329 /* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
1330    so that the compile passes
1331 */
1332    lib=GetModuleHandleA("kernel32.dll");
1333    ok(lib!=NULL,"Couldn't get a handle for kernel32.dll\n");
1334    pGetThreadPriorityBoost=(void *)GetProcAddress(lib,"GetThreadPriorityBoost");
1335    pOpenThread=(void *)GetProcAddress(lib,"OpenThread");
1336    pQueueUserWorkItem=(void *)GetProcAddress(lib,"QueueUserWorkItem");
1337    pSetThreadIdealProcessor=(void *)GetProcAddress(lib,"SetThreadIdealProcessor");
1338    pSetThreadPriorityBoost=(void *)GetProcAddress(lib,"SetThreadPriorityBoost");
1339    pRegisterWaitForSingleObject=(void *)GetProcAddress(lib,"RegisterWaitForSingleObject");
1340    pUnregisterWait=(void *)GetProcAddress(lib,"UnregisterWait");
1341    pIsWow64Process=(void *)GetProcAddress(lib,"IsWow64Process");
1342    pSetThreadErrorMode=(void *)GetProcAddress(lib,"SetThreadErrorMode");
1343    pGetThreadErrorMode=(void *)GetProcAddress(lib,"GetThreadErrorMode");
1344
1345    ntdll=GetModuleHandleA("ntdll.dll");
1346    if (ntdll)
1347    {
1348        pRtlGetThreadErrorMode=(void *)GetProcAddress(ntdll,"RtlGetThreadErrorMode");
1349    }
1350
1351    if (argc >= 3)
1352    {
1353        if (!strcmp(argv[2], "sleep"))
1354        {
1355            HANDLE hAddrEvents[2];
1356            create_function_addr_events(hAddrEvents);
1357            SetEvent(hAddrEvents[0]);
1358            SetEvent(hAddrEvents[1]);
1359            Sleep(5000); /* spawned process runs for at most 5 seconds */
1360            return;
1361        }
1362        while (1)
1363        {
1364            HANDLE hThread;
1365            DWORD tid;
1366            hThread = CreateThread(NULL, 0, threadFunc2, NULL, 0, &tid);
1367            ok(hThread != NULL, "CreateThread failed, error %u\n",
1368               GetLastError());
1369            ok(WaitForSingleObject(hThread, 200) == WAIT_OBJECT_0,
1370               "Thread did not exit in time\n");
1371            if (hThread == NULL) break;
1372            CloseHandle(hThread);
1373        }
1374        return;
1375    }
1376
1377    test_CreateRemoteThread();
1378    test_CreateThread_basic();
1379    test_CreateThread_suspended();
1380    test_SuspendThread();
1381    test_TerminateThread();
1382    test_CreateThread_stack();
1383    test_thread_priority();
1384    test_GetThreadTimes();
1385    test_thread_processor();
1386    test_GetThreadExitCode();
1387 #ifdef __i386__
1388    test_SetThreadContext();
1389 #endif
1390    test_QueueUserWorkItem();
1391    test_RegisterWaitForSingleObject();
1392    test_TLS();
1393    test_ThreadErrorMode();
1394 }