ReactOS  0.4.15-dev-1397-g19779b3
thread.c
Go to the documentation of this file.
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 #include <assert.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 
25 /* the tests intentionally pass invalid pointers and need an exception handler */
26 #define WINE_NO_INLINE_STRING
27 
28 #include <ntstatus.h>
29 #define WIN32_NO_STATUS
30 #include <windef.h>
31 #include <winbase.h>
32 #include <winnt.h>
33 #include <winerror.h>
34 #include <winnls.h>
35 #include <winternl.h>
36 #include "wine/test.h"
37 
38 /* THREAD_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
39 #define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
40 
41 /* Specify the number of simultaneous threads to test */
42 #define NUM_THREADS 4
43 /* Specify whether to test the extended priorities for Win2k/XP */
44 #define USE_EXTENDED_PRIORITIES 0
45 /* Specify whether to test the stack allocation in CreateThread */
46 #define CHECK_STACK 0
47 
48 /* Set CHECK_STACK to 1 if you want to try to test the stack-limit from
49  CreateThread. So far I have been unable to make this work, and
50  I am in doubt as to how portable it is. Also, according to MSDN,
51  you shouldn't mix C-run-time-libraries (i.e. alloca) with CreateThread.
52  Anyhow, the check is currently commented out
53 */
54 #if CHECK_STACK
55 # ifdef __try
56 # define __TRY __try
57 # define __EXCEPT __except
58 # define __ENDTRY
59 # else
60 # include "wine/exception.h"
61 # endif
62 #endif
63 
64 #ifdef __i386__
65 #define ARCH "x86"
66 #elif defined __x86_64__
67 #define ARCH "amd64"
68 #elif defined __arm__
69 #define ARCH "arm"
70 #elif defined __aarch64__
71 #define ARCH "arm64"
72 #else
73 #define ARCH "none"
74 #endif
75 
76 static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE,PBOOL);
77 static HANDLE (WINAPI *pOpenThread)(DWORD,BOOL,DWORD);
78 static BOOL (WINAPI *pQueueUserWorkItem)(LPTHREAD_START_ROUTINE,PVOID,ULONG);
79 static DWORD (WINAPI *pSetThreadIdealProcessor)(HANDLE,DWORD);
80 static BOOL (WINAPI *pSetThreadPriorityBoost)(HANDLE,BOOL);
81 static BOOL (WINAPI *pRegisterWaitForSingleObject)(PHANDLE,HANDLE,WAITORTIMERCALLBACK,PVOID,ULONG,ULONG);
82 static BOOL (WINAPI *pUnregisterWait)(HANDLE);
83 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
84 static BOOL (WINAPI *pSetThreadErrorMode)(DWORD,PDWORD);
85 static DWORD (WINAPI *pGetThreadErrorMode)(void);
86 static DWORD (WINAPI *pRtlGetThreadErrorMode)(void);
87 static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
88 static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
89 static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
90 static BOOL (WINAPI *pGetCurrentActCtx)(HANDLE *);
91 static void (WINAPI *pReleaseActCtx)(HANDLE);
92 static PTP_POOL (WINAPI *pCreateThreadpool)(PVOID);
93 static void (WINAPI *pCloseThreadpool)(PTP_POOL);
94 static PTP_WORK (WINAPI *pCreateThreadpoolWork)(PTP_WORK_CALLBACK,PVOID,PTP_CALLBACK_ENVIRON);
95 static void (WINAPI *pSubmitThreadpoolWork)(PTP_WORK);
96 static void (WINAPI *pWaitForThreadpoolWorkCallbacks)(PTP_WORK,BOOL);
97 static void (WINAPI *pCloseThreadpoolWork)(PTP_WORK);
98 static NTSTATUS (WINAPI *pNtQueryInformationThread)(HANDLE,THREADINFOCLASS,PVOID,ULONG,PULONG);
99 static BOOL (WINAPI *pGetThreadGroupAffinity)(HANDLE,GROUP_AFFINITY*);
100 static BOOL (WINAPI *pSetThreadGroupAffinity)(HANDLE,const GROUP_AFFINITY*,GROUP_AFFINITY*);
101 static NTSTATUS (WINAPI *pNtSetInformationThread)(HANDLE,THREADINFOCLASS,LPCVOID,ULONG);
102 static NTSTATUS (WINAPI *pNtSetLdtEntries)(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
103 
104 static HANDLE create_target_process(const char *arg)
105 {
106  char **argv;
107  char cmdline[MAX_PATH];
109  BOOL ret;
110  STARTUPINFOA si = { 0 };
111  si.cb = sizeof(si);
112 
114  sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
115  ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
116  ok(ret, "error: %u\n", GetLastError());
117  ret = CloseHandle(pi.hThread);
118  ok(ret, "error %u\n", GetLastError());
119  return pi.hProcess;
120 }
121 
122 /* Functions not tested yet:
123  AttachThreadInput
124  SetThreadContext
125  SwitchToThread
126 
127 In addition there are no checks that the inheritance works properly in
128 CreateThread
129 */
130 
131 /* Functions to ensure that from a group of threads, only one executes
132  certain chunks of code at a time, and we know which one is executing
133  it. It basically makes multithreaded execution linear, which defeats
134  the purpose of multiple threads, but makes testing easy. */
137 
138 static void init_thread_sync_helpers(void)
139 {
141  ok(start_event != NULL, "CreateEvent failed\n");
143  ok(stop_event != NULL, "CreateEvent failed\n");
144  num_synced = -1;
145 }
146 
147 static BOOL sync_threads_and_run_one(DWORD sync_id, DWORD my_id)
148 {
150  assert(-1 <= num && num <= 1);
151  if (num == 1)
152  {
155  }
156  else
157  {
159  ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed %x\n",ret);
160  }
161  return sync_id == my_id;
162 }
163 
164 static void resync_after_run(void)
165 {
167  assert(-1 <= num && num <= 1);
168  if (num == -1)
169  {
171  SetEvent( stop_event );
172  }
173  else
174  {
176  ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
177  }
178 }
179 
181 {
184 }
185 
187 
188 typedef struct {
192 } t1Struct;
193 
194 /* WinME supports OpenThread but doesn't know about access restrictions so
195  we require them to be either completely ignored or always obeyed.
196 */
197 static INT obeying_ars = 0; /* -1 == no, 0 == dunno yet, 1 == yes */
198 #define obey_ar(x) \
199  (obeying_ars == 0 \
200  ? ((x) \
201  ? (obeying_ars = +1) \
202  : ((obeying_ars = -1), \
203  trace("not restricted, assuming consistent behaviour\n"))) \
204  : (obeying_ars < 0) \
205  ? ok(!(x), "access restrictions obeyed\n") \
206  : ok( (x), "access restrictions not obeyed\n"))
207 
208 /* Basic test that simultaneous threads can access shared memory,
209  that the thread local storage routines work correctly, and that
210  threads actually run concurrently
211 */
213 {
214  t1Struct *tstruct = p;
215  int i;
216 /* write our thread # into shared memory */
217  tstruct->threadmem[tstruct->threadnum]=GetCurrentThreadId();
218  ok(TlsSetValue(tlsIndex,(LPVOID)(INT_PTR)(tstruct->threadnum+1))!=0,
219  "TlsSetValue failed\n");
220 /* The threads synchronize before terminating. This is done by
221  Signaling an event, and waiting for all events to occur
222 */
223  SetEvent(tstruct->event[tstruct->threadnum]);
225 /* Double check that all threads really did run by validating that
226  they have all written to the shared memory. There should be no race
227  here, since all threads were synchronized after the write.*/
228  for (i = 0; i < NUM_THREADS; i++)
229  ok(tstruct->threadmem[i] != 0, "expected threadmem[%d] != 0\n", i);
230 
231  /* lstrlenA contains an exception handler so this makes sure exceptions work in threads */
232  ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
233 
234 /* Check that no one changed our tls memory */
235  ok((INT_PTR)TlsGetValue(tlsIndex)-1==tstruct->threadnum,
236  "TlsGetValue failed\n");
237  return NUM_THREADS+tstruct->threadnum;
238 }
239 
241 {
242  return 99;
243 }
244 
246 {
247  HANDLE thread;
250  return 99;
251 }
252 
254 {
255  HANDLE event = p;
256  if(event != NULL) {
257  SetEvent(event);
258  }
259  Sleep(99000);
260  return 0;
261 }
262 
263 #if CHECK_STACK
264 static DWORD WINAPI threadFunc5(LPVOID p)
265 {
266  DWORD *exitCode = p;
267  SYSTEM_INFO sysInfo;
268  sysInfo.dwPageSize=0;
269  GetSystemInfo(&sysInfo);
270  *exitCode=0;
271  __TRY
272  {
273  alloca(2*sysInfo.dwPageSize);
274  }
275  __EXCEPT(1) {
276  *exitCode=1;
277  }
278  __ENDTRY
279  return 0;
280 }
281 #endif
282 
284 {
285  SetEvent(p);
286  return 0;
287 }
288 
290 {
291  CloseHandle(p);
292  return 0;
293 }
294 
296 {
299 };
300 
302 {
303  struct thread_actctx_param *param = (struct thread_actctx_param*)p;
304  HANDLE cur;
305  BOOL ret;
306 
307  cur = (void*)0xdeadbeef;
308  ret = pGetCurrentActCtx(&cur);
309  ok(ret, "thread GetCurrentActCtx failed, %u\n", GetLastError());
310  ok(cur == param->handle, "got %p, expected %p\n", cur, param->handle);
311  param->thread_context = cur;
312 
313  return 0;
314 }
315 
317 {
318  char buffer[256];
319 
320  sprintf(buffer, "threadFunc_SetEvent %p", threadFunc_SetEvent);
322 
323  sprintf(buffer, "threadFunc_CloseHandle %p", threadFunc_CloseHandle);
325 }
326 
327 /* check CreateRemoteThread */
329 {
330  HANDLE hProcess, hThread, hEvent, hRemoteEvent;
331  DWORD tid, ret, exitcode;
332  HANDLE hAddrEvents[2];
333 
334  hProcess = create_target_process("sleep");
335  ok(hProcess != NULL, "Can't start process\n");
336 
337  /* ensure threadFunc_SetEvent & threadFunc_CloseHandle are the same
338  * address as in the child process */
339  create_function_addr_events(hAddrEvents);
340  ret = WaitForMultipleObjects(2, hAddrEvents, TRUE, 5000);
341  if (ret == WAIT_TIMEOUT)
342  {
343  skip("child process wasn't mapped at same address, so can't do CreateRemoteThread tests.\n");
344  return;
345  }
346  ok(ret == WAIT_OBJECT_0 || broken(ret == WAIT_OBJECT_0+1 /* nt4,w2k */), "WaitForAllObjects 2 events %d\n", ret);
347 
349  ok(hEvent != NULL, "Can't create event, err=%u\n", GetLastError());
350  ret = DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hRemoteEvent,
352  ok(ret != 0, "DuplicateHandle failed, err=%u\n", GetLastError());
353 
354  /* create suspended remote thread with entry point SetEvent() */
355  SetLastError(0xdeadbeef);
357  hRemoteEvent, CREATE_SUSPENDED, &tid);
359  {
360  win_skip("CreateRemoteThread is not implemented\n");
361  goto cleanup;
362  }
363  ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
364  ok(tid != 0, "null tid\n");
366  ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
368  ok(ret == 2, "ret=%u, err=%u\n", ret, GetLastError());
369 
370  /* thread still suspended, so wait times out */
371  ret = WaitForSingleObject(hEvent, 1000);
372  ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
373 
375  ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
376 
377  /* wait that doesn't time out */
378  ret = WaitForSingleObject(hEvent, 1000);
379  ok(ret == WAIT_OBJECT_0, "object not signaled, ret=%u\n", ret);
380 
381  /* wait for thread end */
383  ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
385 
386  /* create and wait for remote thread with entry point CloseHandle() */
389  hRemoteEvent, 0, &tid);
390  ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
392  ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
394 
395  /* create remote thread with entry point SetEvent() */
398  hRemoteEvent, 0, &tid);
399  ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
400 
401  /* closed handle, so wait times out */
402  ret = WaitForSingleObject(hEvent, 1000);
403  ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
404 
405  /* check that remote SetEvent() failed */
406  ret = GetExitCodeThread(hThread, &exitcode);
407  ok(ret != 0, "GetExitCodeThread failed, err=%u\n", GetLastError());
408  if (ret) ok(exitcode == 0, "SetEvent succeeded, expected to fail\n");
410 
411 cleanup:
415 }
416 
417 /* Check basic functionality of CreateThread and Tls* functions */
419 {
421  DWORD threadid[NUM_THREADS],curthreadId;
422  DWORD threadmem[NUM_THREADS];
423  DWORD exitCode;
424  t1Struct tstruct[NUM_THREADS];
425  int error;
426  DWORD i,j;
427  DWORD GLE, ret;
428  DWORD tid;
429  BOOL bRet;
430 
431  /* lstrlenA contains an exception handler so this makes sure exceptions work in the main thread */
432  ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
433 
434 /* Retrieve current Thread ID for later comparisons */
435  curthreadId=GetCurrentThreadId();
436 /* Allocate some local storage */
437  ok((tlsIndex=TlsAlloc())!=TLS_OUT_OF_INDEXES,"TlsAlloc failed\n");
438 /* Create events for thread synchronization */
439  for(i=0;i<NUM_THREADS;i++) {
440  threadmem[i]=0;
441 /* Note that it doesn't matter what type of event we choose here. This
442  test isn't trying to thoroughly test events
443 */
444  event[i]=CreateEventA(NULL,TRUE,FALSE,NULL);
445  tstruct[i].threadnum=i;
446  tstruct[i].threadmem=threadmem;
447  tstruct[i].event=event;
448  }
449 
450 /* Test that passing arguments to threads works okay */
451  for(i=0;i<NUM_THREADS;i++) {
453  &tstruct[i],0,&threadid[i]);
454  ok(thread[i]!=NULL,"Create Thread failed\n");
455  }
456 /* Test that the threads actually complete */
457  for(i=0;i<NUM_THREADS;i++) {
459  ok(error==WAIT_OBJECT_0, "Thread did not complete within timelimit\n");
460  if(error!=WAIT_OBJECT_0) {
462  }
463  ok(GetExitCodeThread(thread[i],&exitCode),"Could not retrieve ext code\n");
464  ok(exitCode==i+NUM_THREADS,"Thread returned an incorrect exit code\n");
465  }
466 /* Test that each thread executed in its parent's address space
467  (it was able to change threadmem and pass that change back to its parent)
468  and that each thread id was independent). Note that we prove that the
469  threads actually execute concurrently by having them block on each other
470  in threadFunc1
471 */
472  for(i=0;i<NUM_THREADS;i++) {
473  error=0;
474  for(j=i+1;j<NUM_THREADS;j++) {
475  if (threadmem[i]==threadmem[j]) {
476  error=1;
477  }
478  }
479  ok(!error && threadmem[i]==threadid[i] && threadmem[i]!=curthreadId,
480  "Thread did not execute successfully\n");
481  ok(CloseHandle(thread[i])!=0,"CloseHandle failed\n");
482  }
483 
484  SetLastError(0xCAFEF00D);
485  bRet = TlsFree(tlsIndex);
486  ok(bRet, "TlsFree failed: %08x\n", GetLastError());
487  ok(GetLastError()==0xCAFEF00D,
488  "GetLastError: expected 0xCAFEF00D, got %08x\n", GetLastError());
489 
490  /* Test freeing an already freed TLS index */
491  SetLastError(0xCAFEF00D);
492  ok(TlsFree(tlsIndex)==0,"TlsFree succeeded\n");
494  "GetLastError: expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
495 
496  /* Test how passing NULL as a pointer to threadid works */
497  SetLastError(0xFACEaBAD);
499  GLE = GetLastError();
500  if (thread[0]) { /* NT */
501  ok(GLE==0xFACEaBAD, "CreateThread set last error to %d, expected 4207848365\n", GLE);
502  ret = WaitForSingleObject(thread[0],100);
503  ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
504  ret = GetExitCodeThread(thread[0],&exitCode);
505  ok(ret!=0, "GetExitCodeThread returned %d (expected nonzero)\n", ret);
506  ok(exitCode==99, "threadFunc2 exited with code: %d (expected 99)\n", exitCode);
507  ok(CloseHandle(thread[0])!=0,"Error closing thread handle\n");
508  }
509  else { /* 9x */
510  ok(GLE==ERROR_INVALID_PARAMETER, "CreateThread set last error to %d, expected 87\n", GLE);
511  }
512 }
513 
514 /* Check that using the CREATE_SUSPENDED flag works */
516 {
517  HANDLE thread;
518  DWORD threadId;
519  DWORD suspend_count;
520  int error;
521 
523  CREATE_SUSPENDED,&threadId);
524  ok(thread!=NULL,"Create Thread failed\n");
525 /* Check that the thread is suspended */
526  ok(SuspendThread(thread)==1,"Thread did not start suspended\n");
527  ok(ResumeThread(thread)==2,"Resume thread returned an invalid value\n");
528 /* Check that resume thread didn't actually start the thread. I can't think
529  of a better way of checking this than just waiting. I am not sure if this
530  will work on slow computers.
531 */
533  "ResumeThread should not have actually started the thread\n");
534 /* Now actually resume the thread and make sure that it actually completes*/
535  ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
537  "Thread did not resume\n");
538  if(error!=WAIT_OBJECT_0) {
540  }
541 
542  suspend_count = SuspendThread(thread);
543  ok(suspend_count == -1, "SuspendThread returned %d, expected -1\n", suspend_count);
544 
545  suspend_count = ResumeThread(thread);
546  ok(suspend_count == 0 ||
547  broken(suspend_count == -1), /* win9x */
548  "ResumeThread returned %d, expected 0\n", suspend_count);
549 
550  ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
551 }
552 
553 /* Check that SuspendThread and ResumeThread work */
555 {
556  HANDLE thread,access_thread;
557  DWORD threadId,exitCode,error;
558  int i;
559 
561  0,&threadId);
562  ok(thread!=NULL,"Create Thread failed\n");
563 /* Check that the thread is suspended */
564 /* Note that this is a polling method, and there is a race between
565  SuspendThread being called (in the child, and the loop below timing out,
566  so the test could fail on a heavily loaded or slow computer.
567 */
568  error=0;
569  for(i=0;error==0 && i<100;i++) {
572  if(error==0) {
573  Sleep(50);
574  i++;
575  }
576  }
577  ok(error==1,"SuspendThread did not work\n");
578 /* check that access restrictions are obeyed */
579  if (pOpenThread) {
580  access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_SUSPEND_RESUME),
581  0,threadId);
582  ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
583  if (access_thread!=NULL) {
584  obey_ar(SuspendThread(access_thread)==~0U);
585  obey_ar(ResumeThread(access_thread)==~0U);
586  ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
587  }
588  }
589 /* Double check that the thread really is suspended */
590  ok((error=GetExitCodeThread(thread,&exitCode))!=0 && exitCode==STILL_ACTIVE,
591  "Thread did not really suspend\n");
592 /* Resume the thread, and make sure it actually completes */
593  ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
595  "Thread did not resume\n");
596  if(error!=WAIT_OBJECT_0) {
598  }
599  /* Trying to suspend a terminated thread should fail */
601  ok(error==~0U, "wrong return code: %d\n", error);
602  ok(GetLastError()==ERROR_ACCESS_DENIED || GetLastError()==ERROR_NO_MORE_ITEMS, "unexpected error code: %d\n", GetLastError());
603 
604  ok(CloseHandle(thread)!=0,"CloseHandle Failed\n");
605 }
606 
607 /* Check that TerminateThread works properly
608 */
610 {
611  HANDLE thread,access_thread,event;
612  DWORD threadId,exitCode;
614  thread = CreateThread(NULL,0,threadFunc4,event,0,&threadId);
615  ok(thread!=NULL,"Create Thread failed\n");
616 /* TerminateThread has a race condition in Wine. If the thread is terminated
617  before it starts, it leaves a process behind. Therefore, we wait for the
618  thread to signal that it has started. There is no easy way to force the
619  race to occur, so we don't try to find it.
620 */
622  "TerminateThread didn't work\n");
623 /* check that access restrictions are obeyed */
624  if (pOpenThread) {
625  access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_TERMINATE),
626  0,threadId);
627  ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
628  if (access_thread!=NULL) {
629  obey_ar(TerminateThread(access_thread,99)==0);
630  ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
631  }
632  }
633 /* terminate a job and make sure it terminates */
634  ok(TerminateThread(thread,99)!=0,"TerminateThread failed\n");
636  "TerminateThread didn't work\n");
638  "TerminateThread should not leave the thread 'STILL_ACTIVE'\n");
639  ok(exitCode==99, "TerminateThread returned invalid exit code\n");
640  ok(CloseHandle(thread)!=0,"Error Closing thread handle\n");
641 }
642 
643 /* Check if CreateThread obeys the specified stack size. This code does
644  not work properly, and is currently disabled
645 */
647 {
648 #if CHECK_STACK
649 /* The only way I know of to test the stack size is to use alloca
650  and __try/__except. However, this is probably not portable,
651  and I couldn't get it to work under Wine anyhow. However, here
652  is the code which should allow for testing that CreateThread
653  respects the stack-size limit
654 */
655  HANDLE thread;
656  DWORD threadId,exitCode;
657 
658  SYSTEM_INFO sysInfo;
659  sysInfo.dwPageSize=0;
660  GetSystemInfo(&sysInfo);
661  ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
663  threadFunc5,&exitCode,
664  0,&threadId);
666  "TerminateThread didn't work\n");
667  ok(exitCode==1,"CreateThread did not obey stack-size-limit\n");
668  ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
669 #endif
670 }
671 
672 /* Check whether setting/retrieving thread priorities works */
674 {
675  HANDLE curthread,access_thread;
676  DWORD curthreadId,exitCode;
677  int min_priority=-2,max_priority=2;
678  BOOL disabled,rc;
679  int i;
680 
681  curthread=GetCurrentThread();
682  curthreadId=GetCurrentThreadId();
683 /* Check thread priority */
684 /* NOTE: on Win2k/XP priority can be from -7 to 6. All other platforms it
685  is -2 to 2. However, even on a real Win2k system, using thread
686  priorities beyond the -2 to 2 range does not work. If you want to try
687  anyway, enable USE_EXTENDED_PRIORITIES
688 */
690  "GetThreadPriority Failed\n");
691 
692  if (pOpenThread) {
693 /* check that access control is obeyed */
694  access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 &
696  0,curthreadId);
697  ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
698  if (access_thread!=NULL) {
699  obey_ar(SetThreadPriority(access_thread,1)==0);
701  obey_ar(GetExitCodeThread(access_thread,&exitCode)==0);
702  ok(CloseHandle(access_thread),"Error Closing thread handle\n");
703  }
704  }
705 #if USE_EXTENDED_PRIORITIES
706  min_priority=-7; max_priority=6;
707 #endif
708  for(i=min_priority;i<=max_priority;i++) {
709  ok(SetThreadPriority(curthread,i)!=0,
710  "SetThreadPriority Failed for priority: %d\n",i);
711  ok(GetThreadPriority(curthread)==i,
712  "GetThreadPriority Failed for priority: %d\n",i);
713  }
715  "SetThreadPriority Failed\n");
717  "GetThreadPriority Failed\n");
719  "SetThreadPriority Failed\n");
721  "GetThreadPriority Failed\n");
722  ok(SetThreadPriority(curthread,0)!=0,"SetThreadPriority Failed\n");
723 
724 /* Check that the thread priority is not changed if SetThreadPriority
725  is called with a value outside of the max/min range */
726  SetThreadPriority(curthread,min_priority);
727  SetLastError(0xdeadbeef);
728  rc = SetThreadPriority(curthread,min_priority-1);
729 
730  ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
732  GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
733  "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
734  GetLastError());
735  ok(GetThreadPriority(curthread)==min_priority,
736  "GetThreadPriority didn't return min_priority\n");
737 
738  SetThreadPriority(curthread,max_priority);
739  SetLastError(0xdeadbeef);
740  rc = SetThreadPriority(curthread,max_priority+1);
741 
742  ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
744  GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
745  "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
746  GetLastError());
747  ok(GetThreadPriority(curthread)==max_priority,
748  "GetThreadPriority didn't return max_priority\n");
749 
750 /* Check thread priority boost */
751  if (!pGetThreadPriorityBoost || !pSetThreadPriorityBoost)
752  return; /* Win9x */
753 
754  SetLastError(0xdeadbeef);
755  rc=pGetThreadPriorityBoost(curthread,&disabled);
757  {
758  win_skip("GetThreadPriorityBoost is not implemented on WinME\n");
759  return;
760  }
761 
762  ok(rc!=0,"error=%d\n",GetLastError());
763 
764  if (pOpenThread) {
765 /* check that access control is obeyed */
766  access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 &
768  0,curthreadId);
769  ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
770  if (access_thread!=NULL) {
771  todo_wine obey_ar(pSetThreadPriorityBoost(access_thread,1)==0);
772  todo_wine obey_ar(pGetThreadPriorityBoost(access_thread,&disabled)==0);
773  ok(CloseHandle(access_thread),"Error Closing thread handle\n");
774  }
775  }
776 
777  rc = pSetThreadPriorityBoost(curthread,1);
778  ok( rc != 0, "error=%d\n",GetLastError());
779  todo_wine {
780  rc=pGetThreadPriorityBoost(curthread,&disabled);
781  ok(rc!=0 && disabled==1,
782  "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
783  }
784 
785  rc = pSetThreadPriorityBoost(curthread,0);
786  ok( rc != 0, "error=%d\n",GetLastError());
787  rc=pGetThreadPriorityBoost(curthread,&disabled);
788  ok(rc!=0 && disabled==0,
789  "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
790 }
791 
792 /* check the GetThreadTimes function */
794 {
795  HANDLE thread,access_thread=NULL;
796  FILETIME creationTime,exitTime,kernelTime,userTime;
797  DWORD threadId;
798  int error;
799 
801  CREATE_SUSPENDED,&threadId);
802 
803  ok(thread!=NULL,"Create Thread failed\n");
804 /* check that access control is obeyed */
805  if (pOpenThread) {
806  access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 &
807  (~THREAD_QUERY_INFORMATION), 0,threadId);
808  ok(access_thread!=NULL,
809  "OpenThread returned an invalid handle\n");
810  }
811  ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
813  "ResumeThread didn't work\n");
814  creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99;
815  exitTime.dwLowDateTime=99; exitTime.dwHighDateTime=99;
816  kernelTime.dwLowDateTime=99; kernelTime.dwHighDateTime=99;
817  userTime.dwLowDateTime=99; userTime.dwHighDateTime=99;
818 /* GetThreadTimes should set all of the parameters passed to it */
819  error=GetThreadTimes(thread,&creationTime,&exitTime,
820  &kernelTime,&userTime);
821 
823  win_skip("GetThreadTimes is not implemented\n");
824  else {
825  ok(error!=0,"GetThreadTimes failed\n");
826  ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
827  "creationTime was invalid\n");
828  ok(exitTime.dwLowDateTime!=99 || exitTime.dwHighDateTime!=99,
829  "exitTime was invalid\n");
830  ok(kernelTime.dwLowDateTime!=99 || kernelTime.dwHighDateTime!=99,
831  "kernelTimewas invalid\n");
832  ok(userTime.dwLowDateTime!=99 || userTime.dwHighDateTime!=99,
833  "userTime was invalid\n");
834  ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
835  if(access_thread!=NULL)
836  {
837  error=GetThreadTimes(access_thread,&creationTime,&exitTime,
838  &kernelTime,&userTime);
839  obey_ar(error==0);
840  }
841  }
842  if(access_thread!=NULL) {
843  ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
844  }
845 }
846 
847 /* Check the processor affinity functions */
848 /* NOTE: These functions should also be checked that they obey access control
849 */
851 {
852  HANDLE curthread,curproc;
853  DWORD_PTR processMask,systemMask,retMask;
854  SYSTEM_INFO sysInfo;
855  int error=0;
856  BOOL is_wow64;
857 
858  if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
859 
860  sysInfo.dwNumberOfProcessors=0;
861  GetSystemInfo(&sysInfo);
862  ok(sysInfo.dwNumberOfProcessors>0,
863  "GetSystemInfo failed to return a valid # of processors\n");
864 /* Use the current Thread/process for all tests */
865  curthread=GetCurrentThread();
866  ok(curthread!=NULL,"GetCurrentThread failed\n");
867  curproc=GetCurrentProcess();
868  ok(curproc!=NULL,"GetCurrentProcess failed\n");
869 /* Check the Affinity Mask functions */
870  ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0,
871  "GetProcessAffinityMask failed\n");
872  ok(SetThreadAffinityMask(curthread,processMask)==processMask,
873  "SetThreadAffinityMask failed\n");
874  ok(SetThreadAffinityMask(curthread,processMask+1)==0,
875  "SetThreadAffinityMask passed for an illegal processor\n");
876 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
877  retMask = SetThreadAffinityMask(curthread,~0);
878  ok(broken(retMask==0) || retMask==processMask,
879  "SetThreadAffinityMask(thread,-1) failed to request all processors.\n");
880 
881  if (retMask == processMask)
882  {
883  /* Show that the "all processors" flag is handled in ntdll */
884  DWORD_PTR mask = ~0u;
885  NTSTATUS status = pNtSetInformationThread(curthread, ThreadAffinityMask, &mask, sizeof(mask));
886  ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS in NtSetInformationThread, got %x\n", status);
887  }
888 
889  if (retMask == processMask && sizeof(ULONG_PTR) > sizeof(ULONG))
890  {
891  /* only the low 32-bits matter */
892  retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0);
893  ok(retMask == processMask, "SetThreadAffinityMask failed\n");
894  retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0 >> 3);
895  ok(retMask == processMask, "SetThreadAffinityMask failed\n");
896  }
897 /* NOTE: This only works on WinNT/2000/XP) */
898  if (pSetThreadIdealProcessor)
899  {
900  SetLastError(0xdeadbeef);
901  error=pSetThreadIdealProcessor(curthread,0);
903  {
904  ok(error!=-1, "SetThreadIdealProcessor failed\n");
905 
906  if (is_wow64)
907  {
908  SetLastError(0xdeadbeef);
909  error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
910  todo_wine
911  ok(error!=-1, "SetThreadIdealProcessor failed for %u on Wow64\n", MAXIMUM_PROCESSORS+1);
912 
913  SetLastError(0xdeadbeef);
914  error=pSetThreadIdealProcessor(curthread,65);
915  ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
917  "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
918  }
919  else
920  {
921  SetLastError(0xdeadbeef);
922  error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
923  ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
925  "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
926  }
927 
928  error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
929  ok(error!=-1, "SetThreadIdealProcessor failed\n");
930  }
931  else
932  win_skip("SetThreadIdealProcessor is not implemented\n");
933  }
934 
935  if (pGetThreadGroupAffinity && pSetThreadGroupAffinity)
936  {
937  GROUP_AFFINITY affinity, affinity_new;
939 
940  memset(&affinity, 0, sizeof(affinity));
941  ok(pGetThreadGroupAffinity(curthread, &affinity), "GetThreadGroupAffinity failed\n");
942 
943  SetLastError(0xdeadbeef);
944  ok(!pGetThreadGroupAffinity(curthread, NULL), "GetThreadGroupAffinity succeeded\n");
946  "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
947  ok(affinity.Group == 0, "Expected group 0 got %u\n", affinity.Group);
948 
949  memset(&affinity_new, 0, sizeof(affinity_new));
950  affinity_new.Group = 0;
951  affinity_new.Mask = affinity.Mask;
952  ok(pSetThreadGroupAffinity(curthread, &affinity_new, &affinity), "SetThreadGroupAffinity failed\n");
953  ok(affinity_new.Mask == affinity.Mask, "Expected old affinity mask %lx, got %lx\n",
954  affinity_new.Mask, affinity.Mask);
955 
956  /* show that the "all processors" flag is not supported for SetThreadGroupAffinity */
957  affinity_new.Group = 0;
958  affinity_new.Mask = ~0u;
959  SetLastError(0xdeadbeef);
960  ok(!pSetThreadGroupAffinity(curthread, &affinity_new, NULL), "SetThreadGroupAffinity succeeded\n");
962  "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
963 
964  affinity_new.Group = 1; /* assumes that you have less than 64 logical processors */
965  affinity_new.Mask = 0x1;
966  SetLastError(0xdeadbeef);
967  ok(!pSetThreadGroupAffinity(curthread, &affinity_new, NULL), "SetThreadGroupAffinity succeeded\n");
969  "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
970 
971  SetLastError(0xdeadbeef);
972  ok(!pSetThreadGroupAffinity(curthread, NULL, NULL), "SetThreadGroupAffinity succeeded\n");
974  "Expected ERROR_NOACCESS, got %d\n", GetLastError());
975 
976  /* show that the access violation was detected in ntdll */
977  status = pNtSetInformationThread(curthread, ThreadGroupInformation, NULL, sizeof(affinity_new));
979  "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
980 
981  /* restore original mask */
982  affinity_new.Group = 0;
983  affinity_new.Mask = affinity.Mask;
984  SetLastError(0xdeadbeef);
985  ok(pSetThreadGroupAffinity(curthread, &affinity_new, &affinity), "SetThreadGroupAffinity failed\n");
986  ok(affinity_new.Mask == affinity.Mask, "Expected old affinity mask %lx, got %lx\n",
987  affinity_new.Mask, affinity.Mask);
988  }
989  else
990  win_skip("Get/SetThreadGroupAffinity not available\n");
991 }
992 
994 {
995  DWORD exitCode, threadid;
996  DWORD GLE, ret;
997  HANDLE thread;
998 
999  ret = GetExitCodeThread((HANDLE)0x2bad2bad,&exitCode);
1000  ok(ret==0, "GetExitCodeThread returned non zero value: %d\n", ret);
1001  GLE = GetLastError();
1002  ok(GLE==ERROR_INVALID_HANDLE, "GetLastError returned %d (expected 6)\n", GLE);
1003 
1004  thread = CreateThread(NULL,0,threadFunc2,NULL,0,&threadid);
1006  ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
1007  ret = GetExitCodeThread(thread,&exitCode);
1008  ok(ret==exitCode || ret==1,
1009  "GetExitCodeThread returned %d (expected 1 or %d)\n", ret, exitCode);
1010  ok(exitCode==99, "threadFunc2 exited with code %d (expected 99)\n", exitCode);
1011  ok(CloseHandle(thread)!=0,"Error closing thread handle\n");
1012 }
1013 
1014 #ifdef __i386__
1015 
1016 static int test_value = 0;
1017 static HANDLE event;
1018 
1019 static void WINAPI set_test_val( int val )
1020 {
1021  test_value += val;
1022  ExitThread(0);
1023 }
1024 
1025 static DWORD WINAPI threadFunc6(LPVOID p)
1026 {
1027  SetEvent( event );
1028  Sleep( 1000 );
1029  test_value *= (int)p;
1030  return 0;
1031 }
1032 
1033 static void test_SetThreadContext(void)
1034 {
1035  CONTEXT ctx;
1036  int *stack;
1037  HANDLE thread;
1038  DWORD threadid;
1039  DWORD prevcount;
1040  BOOL ret;
1041 
1042  SetLastError(0xdeadbeef);
1043  event = CreateEventW( NULL, TRUE, FALSE, NULL );
1044  thread = CreateThread( NULL, 0, threadFunc6, (void *)2, 0, &threadid );
1045  ok( thread != NULL, "CreateThread failed : (%d)\n", GetLastError() );
1046  if (!thread)
1047  {
1048  trace("Thread creation failed, skipping rest of test\n");
1049  return;
1050  }
1052  SuspendThread( thread );
1053  CloseHandle( event );
1054 
1055  ctx.ContextFlags = CONTEXT_FULL;
1056  SetLastError(0xdeadbeef);
1057  ret = GetThreadContext( thread, &ctx );
1058  ok( ret, "GetThreadContext failed : (%u)\n", GetLastError() );
1059 
1060  if (ret)
1061  {
1062  /* simulate a call to set_test_val(10) */
1063  stack = (int *)ctx.Esp;
1064  stack[-1] = 10;
1065  stack[-2] = ctx.Eip;
1066  ctx.Esp -= 2 * sizeof(int *);
1067  ctx.Eip = (DWORD)set_test_val;
1068  SetLastError(0xdeadbeef);
1069  ret = SetThreadContext( thread, &ctx );
1070  ok( ret, "SetThreadContext failed : (%d)\n", GetLastError() );
1071  }
1072 
1073  SetLastError(0xdeadbeef);
1074  prevcount = ResumeThread( thread );
1075  ok ( prevcount == 1, "Previous suspend count (%d) instead of 1, last error : (%d)\n",
1076  prevcount, GetLastError() );
1077 
1079  ok( test_value == 10, "test_value %d\n", test_value );
1080 
1081  ctx.ContextFlags = CONTEXT_FULL;
1082  SetLastError(0xdeadbeef);
1083  ret = GetThreadContext( thread, &ctx );
1085  (!ret && broken(GetLastError() == ERROR_INVALID_HANDLE)) || /* win2k */
1086  broken(ret), /* 32bit application on NT 5.x 64bit */
1087  "got %d with %u (expected FALSE with ERROR_GEN_FAILURE or ERROR_ACCESS_DENIED)\n",
1088  ret, GetLastError() );
1089 
1090  SetLastError(0xdeadbeef);
1091  ret = SetThreadContext( thread, &ctx );
1093  (!ret && broken(GetLastError() == ERROR_INVALID_HANDLE)) || /* win2k */
1094  broken(ret), /* 32bit application on NT 5.x 64bit */
1095  "got %d with %u (expected FALSE with ERROR_GEN_FAILURE or ERROR_ACCESS_DENIED)\n",
1096  ret, GetLastError() );
1097 
1098  CloseHandle( thread );
1099 }
1100 
1101 static void test_GetThreadSelectorEntry(void)
1102 {
1103  LDT_ENTRY entry;
1104  CONTEXT ctx;
1105  DWORD limit;
1106  void *base;
1107  BOOL ret;
1108 
1109  memset(&ctx, 0x11, sizeof(ctx));
1110  ctx.ContextFlags = CONTEXT_SEGMENTS | CONTEXT_CONTROL;
1112  ok(ret, "GetThreadContext error %u\n", GetLastError());
1113  ok(!HIWORD(ctx.SegCs), "expected HIWORD(SegCs) == 0, got %u\n", ctx.SegCs);
1114  ok(!HIWORD(ctx.SegDs), "expected HIWORD(SegDs) == 0, got %u\n", ctx.SegDs);
1115  ok(!HIWORD(ctx.SegFs), "expected HIWORD(SegFs) == 0, got %u\n", ctx.SegFs);
1116 
1118  ok(ret, "GetThreadSelectorEntry(SegCs) error %u\n", GetLastError());
1120  ok(ret, "GetThreadSelectorEntry(SegDs) error %u\n", GetLastError());
1121 
1122  memset(&entry, 0x11, sizeof(entry));
1124  ok(ret, "GetThreadSelectorEntry(SegFs) error %u\n", GetLastError());
1125  entry.HighWord.Bits.Type &= ~1; /* ignore accessed bit */
1126 
1127  base = (void *)((entry.HighWord.Bits.BaseHi << 24) | (entry.HighWord.Bits.BaseMid << 16) | entry.BaseLow);
1128  limit = (entry.HighWord.Bits.LimitHi << 16) | entry.LimitLow;
1129 
1130  ok(base == NtCurrentTeb(), "expected %p, got %p\n", NtCurrentTeb(), base);
1131  ok(limit == 0x0fff || limit == 0x4000, "expected 0x0fff or 0x4000, got %#x\n", limit);
1132  ok(entry.HighWord.Bits.Type == 0x12, "expected 0x12, got %#x\n", entry.HighWord.Bits.Type);
1133  ok(entry.HighWord.Bits.Dpl == 3, "expected 3, got %u\n", entry.HighWord.Bits.Dpl);
1134  ok(entry.HighWord.Bits.Pres == 1, "expected 1, got %u\n", entry.HighWord.Bits.Pres);
1135  ok(entry.HighWord.Bits.Sys == 0, "expected 0, got %u\n", entry.HighWord.Bits.Sys);
1136  ok(entry.HighWord.Bits.Reserved_0 == 0, "expected 0, got %u\n", entry.HighWord.Bits.Reserved_0);
1137  ok(entry.HighWord.Bits.Default_Big == 1, "expected 1, got %u\n", entry.HighWord.Bits.Default_Big);
1138  ok(entry.HighWord.Bits.Granularity == 0, "expected 0, got %u\n", entry.HighWord.Bits.Granularity);
1139 }
1140 
1141 static void test_NtSetLdtEntries(void)
1142 {
1144  LDT_ENTRY ds_entry;
1145  CONTEXT ctx;
1146  DWORD ret;
1147  union
1148  {
1149  LDT_ENTRY entry;
1150  DWORD dw[2];
1151  } sel;
1152 
1153  if (!pNtSetLdtEntries)
1154  {
1155  win_skip("NtSetLdtEntries is not available on this platform\n");
1156  return;
1157  }
1158 
1159  if (pNtSetLdtEntries(0, 0, 0, 0, 0, 0) == STATUS_NOT_IMPLEMENTED) /* WoW64 */
1160  {
1161  win_skip("NtSetLdtEntries is not implemented on this platform\n");
1162  return;
1163  }
1164 
1165  ret = pNtSetLdtEntries(0, 0, 0, 0, 0, 0);
1166  ok(!ret, "NtSetLdtEntries failed: %08x\n", ret);
1167 
1168  ctx.ContextFlags = CONTEXT_SEGMENTS;
1170  ok(ret, "GetThreadContext failed\n");
1171 
1172  tdi.Selector = ctx.SegDs;
1173  ret = pNtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret);
1174  ok(!ret, "NtQueryInformationThread failed: %08x\n", ret);
1175  ds_entry = tdi.Entry;
1176 
1177  tdi.Selector = 0x000f;
1178  ret = pNtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret);
1179  ok(ret == STATUS_ACCESS_VIOLATION, "got %08x\n", ret);
1180 
1181  tdi.Selector = 0x001f;
1182  ret = pNtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret);
1183  ok(ret == STATUS_ACCESS_VIOLATION, "NtQueryInformationThread returned %08x\n", ret);
1184 
1185  ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry);
1186  ok(!ret, "GetThreadSelectorEntry should fail\n");
1187 
1188  ret = GetThreadSelectorEntry(GetCurrentThread(), 0x001f, &sel.entry);
1189  ok(!ret, "GetThreadSelectorEntry should fail\n");
1190 
1191  memset(&sel.entry, 0x9a, sizeof(sel.entry));
1192  ret = GetThreadSelectorEntry(GetCurrentThread(), ctx.SegDs, &sel.entry);
1193  ok(ret, "GetThreadSelectorEntry failed\n");
1194  ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
1195 
1196  ret = pNtSetLdtEntries(0x000f, sel.dw[0], sel.dw[1], 0x001f, sel.dw[0], sel.dw[1]);
1197  ok(!ret || broken(ret == STATUS_INVALID_LDT_DESCRIPTOR) /*XP*/, "NtSetLdtEntries failed: %08x\n", ret);
1198 
1199  if (!ret)
1200  {
1201  memset(&sel.entry, 0x9a, sizeof(sel.entry));
1202  ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry);
1203  ok(ret, "GetThreadSelectorEntry failed\n");
1204  ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
1205 
1206  memset(&sel.entry, 0x9a, sizeof(sel.entry));
1207  ret = GetThreadSelectorEntry(GetCurrentThread(), 0x001f, &sel.entry);
1208  ok(ret, "GetThreadSelectorEntry failed\n");
1209  ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
1210  }
1211 }
1212 
1213 #endif /* __i386__ */
1214 
1217 
1219 {
1221 
1222  if (executed == 100)
1224  return 0;
1225 }
1226 
1227 static void test_QueueUserWorkItem(void)
1228 {
1229  INT_PTR i;
1230  DWORD wait_result;
1231  DWORD before, after;
1232 
1233  /* QueueUserWorkItem not present on win9x */
1234  if (!pQueueUserWorkItem) return;
1235 
1237 
1238  before = GetTickCount();
1239 
1240  for (i = 0; i < 100; i++)
1241  {
1242  BOOL ret = pQueueUserWorkItem(work_function, (void *)i, WT_EXECUTEDEFAULT);
1243  ok(ret, "QueueUserWorkItem failed with error %d\n", GetLastError());
1244  }
1245 
1246  wait_result = WaitForSingleObject(finish_event, 10000);
1247 
1248  after = GetTickCount();
1249  trace("100 QueueUserWorkItem calls took %dms\n", after - before);
1250  ok(wait_result == WAIT_OBJECT_0, "wait failed with error 0x%x\n", wait_result);
1251 
1252  ok(times_executed == 100, "didn't execute all of the work items\n");
1253 }
1254 
1255 static void CALLBACK signaled_function(PVOID p, BOOLEAN TimerOrWaitFired)
1256 {
1257  HANDLE event = p;
1258  SetEvent(event);
1259  ok(!TimerOrWaitFired, "wait shouldn't have timed out\n");
1260 }
1261 
1262 static void CALLBACK timeout_function(PVOID p, BOOLEAN TimerOrWaitFired)
1263 {
1264  HANDLE event = p;
1265  SetEvent(event);
1266  ok(TimerOrWaitFired, "wait should have timed out\n");
1267 }
1268 
1270 {
1271  BOOL ret;
1272  HANDLE wait_handle;
1273  HANDLE handle;
1275 
1276  if (!pRegisterWaitForSingleObject || !pUnregisterWait)
1277  {
1278  win_skip("RegisterWaitForSingleObject or UnregisterWait not implemented\n");
1279  return;
1280  }
1281 
1282  /* test signaled case */
1283 
1286 
1287  ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1288  ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1289 
1291  /* give worker thread chance to complete */
1292  Sleep(100);
1293 
1294  ret = pUnregisterWait(wait_handle);
1295  ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1296 
1297  /* test cancel case */
1298 
1299  ResetEvent(handle);
1300 
1301  ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1302  ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1303 
1304  ret = pUnregisterWait(wait_handle);
1305  ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1306 
1307  /* test timeout case */
1308 
1309  ret = pRegisterWaitForSingleObject(&wait_handle, handle, timeout_function, complete_event, 0, WT_EXECUTEONLYONCE);
1310  ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1311 
1313  /* give worker thread chance to complete */
1314  Sleep(100);
1315 
1316  ret = pUnregisterWait(wait_handle);
1317  ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1318 
1319  SetLastError(0xdeadbeef);
1320  ret = pUnregisterWait(NULL);
1321  ok(!ret, "Expected UnregisterWait to fail\n");
1323  "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1324 }
1325 
1329 
1330 /* Function pointers to the FLS/TLS functions to test in LS_ThreadProc() */
1331 static DWORD (WINAPI *LS_AllocFunc)(void);
1332 static PVOID (WINAPI *LS_GetValueFunc)(DWORD);
1333 static BOOL (WINAPI *LS_SetValueFunc)(DWORD, PVOID);
1334 static BOOL (WINAPI *LS_FreeFunc)(DWORD);
1335 
1336 /* Names of the functions tested in LS_ThreadProc(), for error messages */
1337 static const char* LS_AllocFuncName = "";
1338 static const char* LS_GetValueFuncName = "";
1339 static const char* LS_SetValueFuncName = "";
1340 static const char* LS_FreeFuncName = "";
1341 
1342 /* FLS entry points, dynamically loaded in platforms that support them */
1343 static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
1344 static BOOL (WINAPI *pFlsFree)(DWORD);
1345 static PVOID (WINAPI *pFlsGetValue)(DWORD);
1346 static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID);
1347 
1348 /* A thunk function to make FlsAlloc compatible with the signature of TlsAlloc */
1350 {
1351  return pFlsAlloc(NULL);
1352 }
1353 
1355 {
1356  /* We should NOT inherit the FLS/TLS values from our parent or from the
1357  main thread. */
1358  LPVOID val;
1359 
1360  val = LS_GetValueFunc(LS_main);
1361  ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1362 
1363  val = LS_GetValueFunc(LS_index0);
1364  ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1365 
1366  val = LS_GetValueFunc(LS_index1);
1367  ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1368 
1369  return 0;
1370 }
1371 
1372 /* Basic FLS/TLS usage test. Make sure we can create slots and the values we
1373  store in them are separate among threads. Also test FLS/TLS value
1374  inheritance with LS_InheritanceProc. */
1376 {
1377  LONG_PTR id = (LONG_PTR) p;
1378  LPVOID val;
1379  BOOL ret;
1380 
1381  if (sync_threads_and_run_one(0, id))
1382  {
1383  LS_index0 = LS_AllocFunc();
1384  ok(LS_index0 != LS_OutOfIndexesValue, "%s failed\n", LS_AllocFuncName);
1385  }
1386  resync_after_run();
1387 
1388  if (sync_threads_and_run_one(1, id))
1389  {
1390  LS_index1 = LS_AllocFunc();
1391  ok(LS_index1 != LS_OutOfIndexesValue, "%s failed\n", LS_AllocFuncName);
1392 
1393  /* Slot indices should be different even if created in different
1394  threads. */
1395  ok(LS_index0 != LS_index1, "%s failed\n", LS_AllocFuncName);
1396 
1397  /* Both slots should be initialized to NULL */
1398  SetLastError(0xdeadbeef);
1399  val = LS_GetValueFunc(LS_index0);
1400  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1401  ok(val == NULL, "Slot not initialized correctly\n");
1402 
1403  SetLastError(0xdeadbeef);
1404  val = LS_GetValueFunc(LS_index1);
1405  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1406  ok(val == NULL, "Slot not initialized correctly\n");
1407  }
1408  resync_after_run();
1409 
1410  if (sync_threads_and_run_one(0, id))
1411  {
1412  SetLastError(0xdeadbeef);
1413  val = LS_GetValueFunc(LS_index0);
1414  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1415  ok(val == NULL, "Slot not initialized correctly\n");
1416 
1417  SetLastError(0xdeadbeef);
1418  val = LS_GetValueFunc(LS_index1);
1419  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1420  ok(val == NULL, "Slot not initialized correctly\n");
1421 
1422  ret = LS_SetValueFunc(LS_index0, (LPVOID) 1);
1423  ok(ret, "%s failed\n", LS_SetValueFuncName);
1424 
1425  ret = LS_SetValueFunc(LS_index1, (LPVOID) 2);
1426  ok(ret, "%s failed\n", LS_SetValueFuncName);
1427 
1428  SetLastError(0xdeadbeef);
1429  val = LS_GetValueFunc(LS_index0);
1430  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1431  ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
1432 
1433  SetLastError(0xdeadbeef);
1434  val = LS_GetValueFunc(LS_index1);
1435  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1436  ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
1437  }
1438  resync_after_run();
1439 
1440  if (sync_threads_and_run_one(1, id))
1441  {
1442  val = LS_GetValueFunc(LS_index0);
1443  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1444  ok(val == NULL, "Slot not initialized correctly\n");
1445 
1446  val = LS_GetValueFunc(LS_index1);
1447  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1448  ok(val == NULL, "Slot not initialized correctly\n");
1449 
1450  ret = LS_SetValueFunc(LS_index0, (LPVOID) 3);
1451  ok(ret, "%s failed\n", LS_SetValueFuncName);
1452 
1453  ret = LS_SetValueFunc(LS_index1, (LPVOID) 4);
1454  ok(ret, "%s failed\n", LS_SetValueFuncName);
1455 
1456  val = LS_GetValueFunc(LS_index0);
1457  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1458  ok(val == (LPVOID) 3, "Slot not initialized correctly\n");
1459 
1460  val = LS_GetValueFunc(LS_index1);
1461  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1462  ok(val == (LPVOID) 4, "Slot not initialized correctly\n");
1463  }
1464  resync_after_run();
1465 
1466  if (sync_threads_and_run_one(0, id))
1467  {
1468  HANDLE thread;
1469  DWORD waitret, tid;
1470 
1471  val = LS_GetValueFunc(LS_index0);
1472  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1473  ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
1474 
1475  val = LS_GetValueFunc(LS_index1);
1476  ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1477  ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
1478 
1480  ok(thread != NULL, "CreateThread failed\n");
1481  waitret = WaitForSingleObject(thread, 60000);
1482  ok(waitret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1484 
1485  ret = LS_FreeFunc(LS_index0);
1486  ok(ret, "%s failed\n", LS_FreeFuncName);
1487  }
1488  resync_after_run();
1489 
1490  if (sync_threads_and_run_one(1, id))
1491  {
1492  ret = LS_FreeFunc(LS_index1);
1493  ok(ret, "%s failed\n", LS_FreeFuncName);
1494  }
1495  resync_after_run();
1496 
1497  return 0;
1498 }
1499 
1500 static void run_LS_tests(void)
1501 {
1502  HANDLE threads[2];
1503  LONG_PTR i;
1504  DWORD ret;
1505  BOOL suc;
1506 
1508 
1509  /* Allocate a slot in the main thread to test for inheritance. */
1510  LS_main = LS_AllocFunc();
1511  ok(LS_main != LS_OutOfIndexesValue, "%s failed\n", LS_AllocFuncName);
1512  suc = LS_SetValueFunc(LS_main, (LPVOID) 4114);
1513  ok(suc, "%s failed\n", LS_SetValueFuncName);
1514 
1515  for (i = 0; i < 2; ++i)
1516  {
1517  DWORD tid;
1518 
1519  threads[i] = CreateThread(NULL, 0, LS_ThreadProc, (LPVOID) i, 0, &tid);
1520  ok(threads[i] != NULL, "CreateThread failed\n");
1521  }
1522 
1523  ret = WaitForMultipleObjects(2, threads, TRUE, 60000);
1524  ok(ret == WAIT_OBJECT_0 || broken(ret == WAIT_OBJECT_0+1 /* nt4,w2k */), "WaitForAllObjects 2 threads %d\n",ret);
1525 
1526  for (i = 0; i < 2; ++i)
1527  CloseHandle(threads[i]);
1528 
1529  suc = LS_FreeFunc(LS_main);
1530  ok(suc, "%s failed\n", LS_FreeFuncName);
1532 }
1533 
1534 static void test_TLS(void)
1535 {
1537 
1538  LS_AllocFunc = &TlsAlloc;
1539  LS_GetValueFunc = &TlsGetValue;
1540  LS_SetValueFunc = &TlsSetValue;
1541  LS_FreeFunc = &TlsFree;
1542 
1543  LS_AllocFuncName = "TlsAlloc";
1544  LS_GetValueFuncName = "TlsGetValue";
1545  LS_SetValueFuncName = "TlsSetValue";
1546  LS_FreeFuncName = "TlsFree";
1547 
1548  run_LS_tests();
1549 }
1550 
1551 static void test_FLS(void)
1552 {
1553  if (!pFlsAlloc || !pFlsFree || !pFlsGetValue || !pFlsSetValue)
1554  {
1555  win_skip("Fiber Local Storage not supported\n");
1556  return;
1557  }
1558 
1560 
1561  LS_AllocFunc = &FLS_AllocFuncThunk;
1562  LS_GetValueFunc = pFlsGetValue;
1563  LS_SetValueFunc = pFlsSetValue;
1564  LS_FreeFunc = pFlsFree;
1565 
1566  LS_AllocFuncName = "FlsAlloc";
1567  LS_GetValueFuncName = "FlsGetValue";
1568  LS_SetValueFuncName = "FlsSetValue";
1569  LS_FreeFuncName = "FlsFree";
1570 
1571  run_LS_tests();
1572 }
1573 
1574 static void test_ThreadErrorMode(void)
1575 {
1576  DWORD oldmode;
1577  DWORD mode;
1578  DWORD rtlmode;
1579  BOOL ret;
1580 
1581  if (!pSetThreadErrorMode || !pGetThreadErrorMode)
1582  {
1583  win_skip("SetThreadErrorMode and/or GetThreadErrorMode unavailable (added in Windows 7)\n");
1584  return;
1585  }
1586 
1587  if (!pRtlGetThreadErrorMode) {
1588  win_skip("RtlGetThreadErrorMode not available\n");
1589  return;
1590  }
1591 
1592  oldmode = pGetThreadErrorMode();
1593 
1594  ret = pSetThreadErrorMode(0, &mode);
1595  ok(ret, "SetThreadErrorMode failed\n");
1596  ok(mode == oldmode,
1597  "SetThreadErrorMode returned old mode 0x%x, expected 0x%x\n",
1598  mode, oldmode);
1599  mode = pGetThreadErrorMode();
1600  ok(mode == 0, "GetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1601  rtlmode = pRtlGetThreadErrorMode();
1602  ok(rtlmode == 0,
1603  "RtlGetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1604 
1605  ret = pSetThreadErrorMode(SEM_FAILCRITICALERRORS, &mode);
1606  ok(ret, "SetThreadErrorMode failed\n");
1607  ok(mode == 0,
1608  "SetThreadErrorMode returned old mode 0x%x, expected 0\n", mode);
1609  mode = pGetThreadErrorMode();
1611  "GetThreadErrorMode returned mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1612  mode);
1613  rtlmode = pRtlGetThreadErrorMode();
1614  ok(rtlmode == 0x10,
1615  "RtlGetThreadErrorMode returned mode 0x%x, expected 0x10\n", mode);
1616 
1617  ret = pSetThreadErrorMode(SEM_NOGPFAULTERRORBOX, &mode);
1618  ok(ret, "SetThreadErrorMode failed\n");
1620  "SetThreadErrorMode returned old mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1621  mode);
1622  mode = pGetThreadErrorMode();
1624  "GetThreadErrorMode returned mode 0x%x, expected SEM_NOGPFAULTERRORBOX\n",
1625  mode);
1626  rtlmode = pRtlGetThreadErrorMode();
1627  ok(rtlmode == 0x20,
1628  "RtlGetThreadErrorMode returned mode 0x%x, expected 0x20\n", mode);
1629 
1630  ret = pSetThreadErrorMode(SEM_NOOPENFILEERRORBOX, NULL);
1631  ok(ret, "SetThreadErrorMode failed\n");
1632  mode = pGetThreadErrorMode();
1634  "GetThreadErrorMode returned mode 0x%x, expected SEM_NOOPENFILEERRORBOX\n",
1635  mode);
1636  rtlmode = pRtlGetThreadErrorMode();
1637  ok(rtlmode == 0x40,
1638  "RtlGetThreadErrorMode returned mode 0x%x, expected 0x40\n", rtlmode);
1639 
1640  for (mode = 1; mode; mode <<= 1)
1641  {
1642  ret = pSetThreadErrorMode(mode, NULL);
1643  if (mode & (SEM_FAILCRITICALERRORS |
1646  {
1647  ok(ret,
1648  "SetThreadErrorMode(0x%x,NULL) failed with error %d\n",
1649  mode, GetLastError());
1650  }
1651  else
1652  {
1653  DWORD GLE = GetLastError();
1654  ok(!ret,
1655  "SetThreadErrorMode(0x%x,NULL) succeeded, expected failure\n",
1656  mode);
1658  "SetThreadErrorMode(0x%x,NULL) failed with %d, "
1659  "expected ERROR_INVALID_PARAMETER\n",
1660  mode, GLE);
1661  }
1662  }
1663 
1664  pSetThreadErrorMode(oldmode, NULL);
1665 }
1666 
1667 #if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) || (defined(_MSC_VER) && defined(__i386__))
1668 static inline void set_fpu_cw(WORD cw)
1669 {
1670 #ifdef _MSC_VER
1671  __asm { fnclex }
1672  __asm { fldcw [cw] }
1673 #else
1674  __asm__ volatile ("fnclex; fldcw %0" : : "m" (cw));
1675 #endif
1676 }
1677 
1678 static inline WORD get_fpu_cw(void)
1679 {
1680  WORD cw = 0;
1681 #ifdef _MSC_VER
1682  __asm { fnstcw [cw] }
1683 #else
1684  __asm__ volatile ("fnstcw %0" : "=m" (cw));
1685 #endif
1686  return cw;
1687 }
1688 
1689 struct fpu_thread_ctx
1690 {
1691  WORD cw;
1692  HANDLE finished;
1693 };
1694 
1695 static DWORD WINAPI fpu_thread(void *param)
1696 {
1697  struct fpu_thread_ctx *ctx = param;
1698  BOOL ret;
1699 
1700  ctx->cw = get_fpu_cw();
1701 
1702  ret = SetEvent(ctx->finished);
1703  ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
1704 
1705  return 0;
1706 }
1707 
1708 static WORD get_thread_fpu_cw(void)
1709 {
1710  struct fpu_thread_ctx ctx;
1711  DWORD tid, res;
1712  HANDLE thread;
1713 
1714  ctx.finished = CreateEventW(NULL, FALSE, FALSE, NULL);
1715  ok(!!ctx.finished, "Failed to create event, last error %#x.\n", GetLastError());
1716 
1717  thread = CreateThread(NULL, 0, fpu_thread, &ctx, 0, &tid);
1718  ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
1719 
1720  res = WaitForSingleObject(ctx.finished, INFINITE);
1721  ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
1722 
1723  res = CloseHandle(ctx.finished);
1724  ok(!!res, "Failed to close event handle, last error %#x.\n", GetLastError());
1725 
1727  return ctx.cw;
1728 }
1729 
1730 static void test_thread_fpu_cw(void)
1731 {
1732  WORD initial_cw, cw;
1733 
1734  initial_cw = get_fpu_cw();
1735  ok(initial_cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", initial_cw);
1736 
1737  cw = get_thread_fpu_cw();
1738  ok(cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", cw);
1739 
1740  set_fpu_cw(0xf60);
1741  cw = get_fpu_cw();
1742  ok(cw == 0xf60, "Expected FPU control word 0xf60, got %#x.\n", cw);
1743 
1744  cw = get_thread_fpu_cw();
1745  ok(cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", cw);
1746 
1747  cw = get_fpu_cw();
1748  ok(cw == 0xf60, "Expected FPU control word 0xf60, got %#x.\n", cw);
1749 
1750  set_fpu_cw(initial_cw);
1751  cw = get_fpu_cw();
1752  ok(cw == initial_cw, "Expected FPU control word %#x, got %#x.\n", initial_cw, cw);
1753 }
1754 #endif
1755 
1756 static const char manifest_dep[] =
1757 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1758 "<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
1759 " <file name=\"testdep.dll\" />"
1760 "</assembly>";
1761 
1762 static const char manifest_main[] =
1763 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1764 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
1765 "<dependency>"
1766 " <dependentAssembly>"
1767 " <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
1768 " </dependentAssembly>"
1769 "</dependency>"
1770 "</assembly>";
1771 
1772 static void create_manifest_file(const char *filename, const char *manifest)
1773 {
1774  WCHAR path[MAX_PATH];
1775  HANDLE file;
1776  DWORD size;
1777 
1780  ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
1782  CloseHandle(file);
1783 }
1784 
1785 static HANDLE test_create(const char *file)
1786 {
1787  WCHAR path[MAX_PATH];
1788  ACTCTXW actctx;
1789  HANDLE handle;
1790 
1792  memset(&actctx, 0, sizeof(ACTCTXW));
1793  actctx.cbSize = sizeof(ACTCTXW);
1794  actctx.lpSource = path;
1795 
1796  handle = pCreateActCtxW(&actctx);
1797  ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
1798 
1799  ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
1800  ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
1801  ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource);
1802  ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
1803  ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
1804  ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
1805  ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
1806  ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
1807  ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
1808 
1809  return handle;
1810 }
1811 
1812 static void test_thread_actctx(void)
1813 {
1814  struct thread_actctx_param param;
1816  ULONG_PTR cookie;
1817  DWORD tid, ret;
1818  BOOL b;
1819 
1820  if (!pActivateActCtx)
1821  {
1822  win_skip("skipping activation context tests\n");
1823  return;
1824  }
1825 
1826  create_manifest_file("testdep1.manifest", manifest_dep);
1827  create_manifest_file("main.manifest", manifest_main);
1828 
1829  context = test_create("main.manifest");
1830  DeleteFileA("testdep1.manifest");
1831  DeleteFileA("main.manifest");
1832 
1833  handle = (void*)0xdeadbeef;
1834  b = pGetCurrentActCtx(&handle);
1835  ok(b, "GetCurrentActCtx failed: %u\n", GetLastError());
1836  ok(handle == 0, "active context %p\n", handle);
1837 
1838  /* without active context */
1839  param.thread_context = (void*)0xdeadbeef;
1840  param.handle = NULL;
1842  ok(thread != NULL, "failed, got %u\n", GetLastError());
1843 
1844  ret = WaitForSingleObject(thread, 1000);
1845  ok(ret == WAIT_OBJECT_0, "wait timeout\n");
1846  ok(param.thread_context == NULL, "got wrong thread context %p\n", param.thread_context);
1848 
1849  b = pActivateActCtx(context, &cookie);
1850  ok(b, "activation failed: %u\n", GetLastError());
1851 
1852  handle = 0;
1853  b = pGetCurrentActCtx(&handle);
1854  ok(b, "GetCurrentActCtx failed: %u\n", GetLastError());
1855  ok(handle != 0, "no active context\n");
1856  pReleaseActCtx(handle);
1857 
1858  param.handle = NULL;
1859  b = pGetCurrentActCtx(&param.handle);
1860  ok(b && param.handle != NULL, "failed to get context, %u\n", GetLastError());
1861 
1862  param.thread_context = (void*)0xdeadbeef;
1864  ok(thread != NULL, "failed, got %u\n", GetLastError());
1865 
1866  ret = WaitForSingleObject(thread, 1000);
1867  ok(ret == WAIT_OBJECT_0, "wait timeout\n");
1868  ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context);
1869  pReleaseActCtx(param.thread_context);
1871 
1872  /* similar test for CreateRemoteThread() */
1873  param.thread_context = (void*)0xdeadbeef;
1875  ok(thread != NULL, "failed, got %u\n", GetLastError());
1876 
1877  ret = WaitForSingleObject(thread, 1000);
1878  ok(ret == WAIT_OBJECT_0, "wait timeout\n");
1879  ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context);
1880  pReleaseActCtx(param.thread_context);
1882 
1883  pReleaseActCtx(param.handle);
1884 
1885  b = pDeactivateActCtx(0, cookie);
1886  ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
1887  pReleaseActCtx(context);
1888 }
1889 
1890 
1892  int *foo = (int*)context;
1893 
1894  (*foo)++;
1895 }
1896 
1897 
1898 static void test_threadpool(void)
1899 {
1900  PTP_POOL pool;
1901  PTP_WORK work;
1902  int workcalled = 0;
1903 
1904  if (!pCreateThreadpool) {
1905  win_skip("thread pool apis not supported.\n");
1906  return;
1907  }
1908 
1909  work = pCreateThreadpoolWork(threadpool_workcallback, &workcalled, NULL);
1910  ok (work != NULL, "Error %d in CreateThreadpoolWork\n", GetLastError());
1911  pSubmitThreadpoolWork(work);
1912  pWaitForThreadpoolWorkCallbacks(work, FALSE);
1913  pCloseThreadpoolWork(work);
1914 
1915  ok (workcalled == 1, "expected work to be called once, got %d\n", workcalled);
1916 
1917  pool = pCreateThreadpool(NULL);
1918  ok (pool != NULL, "CreateThreadpool failed\n");
1919  pCloseThreadpool(pool);
1920 }
1921 
1922 static void test_reserved_tls(void)
1923 {
1924  void *val;
1925  DWORD tls;
1926  BOOL ret;
1927 
1928  /* This seems to be a WinXP SP2+ feature. */
1929  if(!pIsWow64Process) {
1930  win_skip("Skipping reserved TLS slot on too old Windows.\n");
1931  return;
1932  }
1933 
1934  val = TlsGetValue(0);
1935  ok(!val, "TlsGetValue(0) = %p\n", val);
1936 
1937  /* Also make sure that there is a TLS allocated. */
1938  tls = TlsAlloc();
1939  ok(tls && tls != TLS_OUT_OF_INDEXES, "tls = %x\n", tls);
1940  TlsSetValue(tls, (void*)1);
1941 
1942  val = TlsGetValue(0);
1943  ok(!val, "TlsGetValue(0) = %p\n", val);
1944 
1945  TlsFree(tls);
1946 
1947  /* The following is too ugly to be run by default */
1948  if(0) {
1949  /* Set TLS index 0 value and see that this works and doesn't cause problems
1950  * for remaining tests. */
1951  ret = TlsSetValue(0, (void*)1);
1952  ok(ret, "TlsSetValue(0, 1) failed: %u\n", GetLastError());
1953 
1954  val = TlsGetValue(0);
1955  ok(val == (void*)1, "TlsGetValue(0) = %p\n", val);
1956  }
1957 }
1958 
1959 static void test_thread_info(void)
1960 {
1961  char buf[4096];
1962  static const ULONG info_size[] =
1963  {
1964  sizeof(THREAD_BASIC_INFORMATION), /* ThreadBasicInformation */
1965  sizeof(KERNEL_USER_TIMES), /* ThreadTimes */
1966  sizeof(ULONG), /* ThreadPriority */
1967  sizeof(ULONG), /* ThreadBasePriority */
1968  sizeof(ULONG_PTR), /* ThreadAffinityMask */
1969  sizeof(HANDLE), /* ThreadImpersonationToken */
1970  sizeof(THREAD_DESCRIPTOR_INFORMATION), /* ThreadDescriptorTableEntry */
1971  sizeof(BOOLEAN), /* ThreadEnableAlignmentFaultFixup */
1972  0, /* ThreadEventPair_Reusable */
1973  sizeof(ULONG_PTR), /* ThreadQuerySetWin32StartAddress */
1974  sizeof(ULONG), /* ThreadZeroTlsCell */
1975  sizeof(LARGE_INTEGER), /* ThreadPerformanceCount */
1976  sizeof(ULONG), /* ThreadAmILastThread */
1977  sizeof(ULONG), /* ThreadIdealProcessor */
1978  sizeof(ULONG), /* ThreadPriorityBoost */
1979  sizeof(ULONG_PTR), /* ThreadSetTlsArrayAddress */
1980  sizeof(ULONG), /* ThreadIsIoPending */
1981  sizeof(BOOLEAN), /* ThreadHideFromDebugger */
1982  /* FIXME: Add remaining classes */
1983  };
1984  HANDLE thread;
1985  ULONG i, status, ret_len;
1986 
1987  if (!pOpenThread)
1988  {
1989  win_skip("OpenThread is not available on this platform\n");
1990  return;
1991  }
1992 
1993  if (!pNtQueryInformationThread)
1994  {
1995  win_skip("NtQueryInformationThread is not available on this platform\n");
1996  return;
1997  }
1998 
2000  if (!thread)
2001  {
2002  win_skip("THREAD_QUERY_LIMITED_INFORMATION is not supported on this platform\n");
2003  return;
2004  }
2005 
2006  for (i = 0; i < sizeof(info_size)/sizeof(info_size[0]); i++)
2007  {
2008  memset(buf, 0, sizeof(buf));
2009 
2010 #ifdef __i386__
2012  {
2013  CONTEXT ctx;
2014  THREAD_DESCRIPTOR_INFORMATION *tdi = (void *)buf;
2015 
2016  ctx.ContextFlags = CONTEXT_SEGMENTS;
2018  tdi->Selector = ctx.SegDs;
2019  }
2020 #endif
2021  ret_len = 0;
2022  status = pNtQueryInformationThread(thread, i, buf, info_size[i], &ret_len);
2023  if (status == STATUS_NOT_IMPLEMENTED) continue;
2024  if (status == STATUS_INVALID_INFO_CLASS) continue;
2025  if (status == STATUS_UNSUCCESSFUL) continue;
2026 
2027  switch (i)
2028  {
2030  case ThreadAmILastThread:
2031  case ThreadPriorityBoost:
2032  ok(status == STATUS_SUCCESS, "for info %u expected STATUS_SUCCESS, got %08x (ret_len %u)\n", i, status, ret_len);
2033  break;
2034 
2035 #ifdef __i386__
2037  ok(status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED) /* testbot VM is broken */,
2038  "for info %u expected STATUS_SUCCESS, got %08x (ret_len %u)\n", i, status, ret_len);
2039  break;
2040 #endif
2041 
2042  case ThreadTimes:
2043 todo_wine
2044  ok(status == STATUS_SUCCESS, "for info %u expected STATUS_SUCCESS, got %08x (ret_len %u)\n", i, status, ret_len);
2045  break;
2046 
2047  case ThreadAffinityMask:
2049  case ThreadIsIoPending:
2050 todo_wine
2051  ok(status == STATUS_ACCESS_DENIED, "for info %u expected STATUS_ACCESS_DENIED, got %08x (ret_len %u)\n", i, status, ret_len);
2052  break;
2053 
2054  default:
2055  ok(status == STATUS_ACCESS_DENIED, "for info %u expected STATUS_ACCESS_DENIED, got %08x (ret_len %u)\n", i, status, ret_len);
2056  break;
2057  }
2058  }
2059 
2061 }
2062 
2063 static void init_funcs(void)
2064 {
2065  HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
2066  HMODULE ntdll = GetModuleHandleA("ntdll.dll");
2067 
2068 /* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
2069  so that the compile passes */
2070 
2071 #define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
2073  X(OpenThread);
2078  X(UnregisterWait);
2079  X(IsWow64Process);
2080  X(SetThreadErrorMode);
2081  X(GetThreadErrorMode);
2082  X(ActivateActCtx);
2083  X(CreateActCtxW);
2086  X(ReleaseActCtx);
2087 
2088  X(CreateThreadpool);
2089  X(CloseThreadpool);
2090  X(CreateThreadpoolWork);
2091  X(SubmitThreadpoolWork);
2092  X(WaitForThreadpoolWorkCallbacks);
2093  X(CloseThreadpoolWork);
2094 
2095  X(GetThreadGroupAffinity);
2096  X(SetThreadGroupAffinity);
2097 
2098  X(FlsAlloc);
2099  X(FlsFree);
2100  X(FlsSetValue);
2101  X(FlsGetValue);
2102 #undef X
2103 
2104 #define X(f) p##f = (void*)GetProcAddress(ntdll, #f)
2105  if (ntdll)
2106  {
2110  X(NtSetLdtEntries);
2111  }
2112 #undef X
2113 }
2114 
2116 {
2117  int argc;
2118  char **argv;
2120 
2121  init_funcs();
2122 
2123  if (argc >= 3)
2124  {
2125  if (!strcmp(argv[2], "sleep"))
2126  {
2127  HANDLE hAddrEvents[2];
2128  create_function_addr_events(hAddrEvents);
2129  SetEvent(hAddrEvents[0]);
2130  SetEvent(hAddrEvents[1]);
2131  Sleep(5000); /* spawned process runs for at most 5 seconds */
2132  return;
2133  }
2134  while (1)
2135  {
2136  HANDLE hThread;
2137  DWORD tid;
2139  ok(hThread != NULL, "CreateThread failed, error %u\n",
2140  GetLastError());
2142  "Thread did not exit in time\n");
2143  if (hThread == NULL) break;
2145  }
2146  return;
2147  }
2148 
2149  test_thread_info();
2161 #ifdef __i386__
2162  test_SetThreadContext();
2163  test_GetThreadSelectorEntry();
2164  test_NtSetLdtEntries();
2165 #endif
2168  test_TLS();
2169  test_FLS();
2171 #if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) || (defined(_MSC_VER) && defined(__i386__))
2172  test_thread_fpu_cw();
2173 #endif
2175 
2176  test_threadpool();
2177 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
#define __EXCEPT(func)
Definition: exception.h:60
static PTP_CALLBACK_ENVIRON
Definition: thread.c:94
struct _THREAD_BASIC_INFORMATION THREAD_BASIC_INFORMATION
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static HANDLE stop_event
Definition: thread.c:135
static VOID test_TerminateThread(void)
Definition: thread.c:609
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static int test_value
Definition: signal.c:25
static int argc
Definition: ServiceArgs.c:12
static ULONG
Definition: thread.c:78
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
KAFFINITY affinity
Definition: wave.h:2
#define LONG_PTR
Definition: treelist.c:79
static void test_TLS(void)
Definition: thread.c:1534
BOOL NTAPI GetThreadTimes(IN HANDLE hThread, OUT LPFILETIME lpCreationTime, OUT LPFILETIME lpExitTime, OUT LPFILETIME lpKernelTime, OUT LPFILETIME lpUserTime)
Definition: thread.c:468
static HANDLE
Definition: thread.c:81
DWORD(WINAPI * LPTHREAD_START_ROUTINE)(LPVOID)
Definition: winbase.h:707
static DWORD WINAPI LS_ThreadProc(LPVOID p)
Definition: thread.c:1375
static void cleanup_thread_sync_helpers(void)
Definition: thread.c:180
#define CloseHandle
Definition: compat.h:598
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
static void test_threadpool(void)
Definition: thread.c:1898
BOOL WINAPI SetThreadContext(IN HANDLE hThread, IN CONST CONTEXT *lpContext)
Definition: thread.c:520
static const char * LS_GetValueFuncName
Definition: thread.c:1338
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static void run_LS_tests(void)
Definition: thread.c:1500
static HANDLE test_create(const char *file)
Definition: thread.c:1785
static VOID test_CreateRemoteThread(void)
Definition: thread.c:328
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:557
static DWORD WINAPI FLS_AllocFuncThunk(void)
Definition: thread.c:1349
#define ERROR_SUCCESS
Definition: deptool.c:10
static const char * LS_AllocFuncName
Definition: thread.c:1337
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:586
static INT obeying_ars
Definition: thread.c:197
#define error(str)
Definition: mkdosfs.c:1605
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define THREAD_PRIORITY_NORMAL
Definition: winbase.h:277
HANDLE thread_context
Definition: thread.c:297
static DWORD WINAPI threadFunc3(LPVOID p)
Definition: thread.c:245
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define ERROR_INVALID_PRIORITY
Definition: winerror.h:1107
static HANDLE complete_event
Definition: url.c:179
Definition: http.c:7094
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
Definition: thread.c:1264
#define TRUE
Definition: types.h:120
GLsizei const GLchar ** path
Definition: glext.h:7234
VOID(WINAPI * PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winbase.h:1410
static VOID test_CreateThread_stack(void)
Definition: thread.c:646
static void(WINAPI *pReleaseActCtx)(HANDLE)
#define CP_ACP
Definition: compat.h:109
static BOOL sync_threads_and_run_one(DWORD sync_id, DWORD my_id)
Definition: thread.c:147
#define THREAD_PRIORITY_ERROR_RETURN
Definition: winbase.h:279
#define U(x)
Definition: wordpad.c:45
static void resync_after_run(void)
Definition: thread.c:164
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define THREAD_SET_INFORMATION
Definition: nt_native.h:1337
LONG NTSTATUS
Definition: precomp.h:26
static VOID test_thread_processor(void)
Definition: thread.c:850
#define CALLBACK
Definition: compat.h:35
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
Definition: fiber.c:481
BOOL WINAPI GetCurrentActCtx(OUT PHANDLE phActCtx)
Definition: actctx.c:298
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define assert(x)
Definition: debug.h:53
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
GLuint buffer
Definition: glext.h:5915
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2414
static stack_node_t * stack
Definition: rpn_ieee.c:37
static const char * LS_FreeFuncName
Definition: thread.c:1340
TCHAR * cmdline
Definition: stretchblt.cpp:32
static void test_FLS(void)
Definition: thread.c:1551
static PVOID
Definition: thread.c:78
int32_t INT_PTR
Definition: typedefs.h:64
#define argv
Definition: mplay32.c:18
const char * filename
Definition: ioapi.h:135
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
int32_t INT
Definition: typedefs.h:58
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
int threadnum
Definition: thread.c:189
static BOOL
Definition: thread.c:77
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
#define alloca
Definition: malloc.h:361
static HANDLE hEvent
Definition: comm.c:54
GLint limit
Definition: glext.h:10326
#define obey_ar(x)
Definition: thread.c:198
uint32_t ULONG_PTR
Definition: typedefs.h:65
static PBOOL
Definition: thread.c:76
HANDLE * event
Definition: thread.c:190
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
Definition: fiber.c:341
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define NUM_THREADS
Definition: thread.c:42
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:500
BOOL WINAPI UnregisterWait(IN HANDLE WaitHandle)
Definition: synch.c:934
DWORD dwHighDateTime
Definition: mapidefs.h:66
return STATUS_NOT_IMPLEMENTED
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
#define ERROR_NOACCESS
Definition: winerror.h:578
#define CREATE_SUSPENDED
Definition: winbase.h:178
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
GLenum GLint GLuint mask
Definition: glext.h:6028
#define DUPLICATE_SAME_ACCESS
#define FALSE
Definition: types.h:117
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1148
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
static DWORD WINAPI threadFunc_SetEvent(LPVOID p)
Definition: thread.c:283
static DWORD LS_OutOfIndexesValue
Definition: thread.c:1328
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint base
Definition: 3dtext.c:35
long LONG
Definition: pedump.c:60
static GROUP_AFFINITY *static const GROUP_AFFINITY GROUP_AFFINITY *static LPCVOID
Definition: thread.c:101
__asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" "stwu 0,-16(1)\n\t" "mfmsr 5\n\t" "andi. 6,5,0xffef\n\t" "mtmsr 6\n\t" "isync\n\t" "sync\n\t" "lwz 3,0(3)\n\t" "mtmsr 5\n\t" "isync\n\t" "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" "blr")
BOOL NTAPI SetThreadPriorityBoost(IN HANDLE hThread, IN BOOL bDisablePriorityBoost)
Definition: thread.c:803
static void CALLBACK signaled_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1255
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSTATUS NTAPI NtSetLdtEntries(ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2)
Definition: stubs.c:418
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
static DWORD tlsIndex
Definition: thread.c:186
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex)
Definition: fiber.c:460
unsigned char BOOLEAN
static VOID test_CreateThread_suspended(void)
Definition: thread.c:515
static PTP_POOL(WINAPI *pCreateThreadpool)(PVOID)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
static ULONG_PTR
Definition: thread.c:89
DWORD_PTR WINAPI SetThreadAffinityMask(IN HANDLE hThread, IN DWORD_PTR dwThreadAffinityMask)
Definition: thread.c:661
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
#define ARCH
Definition: thread.c:73
#define actctx
Definition: kernel32.h:8
BOOL WINAPI GetThreadPriorityBoost(IN HANDLE hThread, OUT PBOOL pDisablePriorityBoost)
Definition: thread.c:777
static LONG times_executed
Definition: thread.c:1216
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
static void test_ThreadErrorMode(void)
Definition: thread.c:1574
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:364
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2018
static const char * LS_SetValueFuncName
Definition: thread.c:1339
#define __TRY
Definition: compat.h:80
struct _TP_CALLBACK_INSTANCE * PTP_CALLBACK_INSTANCE
Definition: winnt_old.h:4303
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:458
#define b
Definition: ke_i.h:79
static THREADINFOCLASS
Definition: thread.c:98
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:699
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static DWORD
Definition: thread.c:77
Definition: _stack.h:47
BOOL WINAPI IsWow64Process(IN HANDLE hProcess, OUT PBOOL Wow64Process)
Definition: proc.c:1976
static DWORD WINAPI threadFunc1(LPVOID p)
Definition: thread.c:212
#define THREAD_QUERY_LIMITED_INFORMATION
Definition: security.c:62
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define CONTEXT_FULL
Definition: nt_native.h:1375
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
DWORD cb
Definition: winbase.h:809
#define trace
Definition: atltest.h:70
static HANDLE create_target_process(const char *arg)
Definition: thread.c:104
BOOL WINAPI TlsFree(IN DWORD Index)
Definition: thread.c:1154
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define STILL_ACTIVE
Definition: winbase.h:230
static refpint_t pi[]
Definition: server.c:96
static LONG num_synced
Definition: thread.c:136
#define WT_EXECUTEONLYONCE
Definition: winnt_old.h:1075
static void test_thread_actctx(void)
Definition: thread.c:1812
KAFFINITY Mask
Definition: ntbasedef.h:661
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
static BOOL is_wow64
Definition: loader.c:55
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4744
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
unsigned short WORD
Definition: ntddk_ex.h:93
static void test_thread_info(void)
Definition: thread.c:1959
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
static DWORD LS_main
Definition: thread.c:1326
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define SetLastError(x)
Definition: compat.h:611
DWORD WINAPI SetThreadIdealProcessor(IN HANDLE hThread, IN DWORD dwIdealProcessor)
Definition: thread.c:865
static HANDLE finish_event
Definition: thread.c:1215
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2501
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:79
int winetest_get_mainargs(char ***pargv)
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static HANDLE thread
Definition: service.c:33
BOOL WINAPI QueueUserWorkItem(IN LPTHREAD_START_ROUTINE Function, IN PVOID Context, IN ULONG Flags)
Definition: thread.c:1064
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:278
#define __ENDTRY
Definition: compat.h:82
int ret
union _LARGE_INTEGER LARGE_INTEGER
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
static DWORD WINAPI threadFunc2(LPVOID p)
Definition: thread.c:240
#define THREAD_PRIORITY_IDLE
Definition: winbase.h:275
static void test_QueueUserWorkItem(void)
Definition: thread.c:1227
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:641
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define todo_wine
Definition: test.h:162
#define InterlockedDecrement
Definition: armddk.h:52
static PDWORD
Definition: thread.c:84
static void CALLBACK timeout_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1262
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
HANDLE WINAPI OpenThread(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwThreadId)
Definition: thread.c:402
static HANDLE ULONG_PTR DWORD threads
Definition: process.c:81
static void test_RegisterWaitForSingleObject(void)
Definition: thread.c:1269
uint32_t entry
Definition: isohybrid.c:63
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
static void test_reserved_tls(void)
Definition: thread.c:1922
#define GetCurrentProcess()
Definition: compat.h:618
#define THREAD_ALL_ACCESS_NT4
Definition: thread.c:39
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1088
#define TLS_OUT_OF_INDEXES
Definition: winbase.h:530
__inline int after(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2419
struct _cl_event * event
Definition: glext.h:7739
#define SEM_NOGPFAULTERRORBOX
Definition: rtltypes.h:70
uint32_t DWORD_PTR
Definition: typedefs.h:65
GLenum mode
Definition: glext.h:6217
#define broken(x)
Definition: _sntprintf.h:21
START_TEST(thread)
Definition: thread.c:2115
static NTSTATUS(WINAPI *pNtQueryInformationThread)(HANDLE
FxCollectionEntry * cur
static VOID test_GetThreadTimes(void)
Definition: thread.c:793
static PULONG
Definition: thread.c:98
Definition: compat.h:636
static const char manifest_dep[]
Definition: thread.c:1756
#define THREAD_SUSPEND_RESUME
#define CREATE_ALWAYS
Definition: disk.h:72
DWORD dwPageSize
Definition: winbase.h:1139
struct _TP_WORK * PTP_WORK
Definition: winnt_old.h:4302
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define InterlockedIncrement
Definition: armddk.h:53
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
static WAITORTIMERCALLBACK
Definition: thread.c:81
static void create_manifest_file(const char *filename, const char *manifest)
Definition: thread.c:1772
BOOL WINAPI GetThreadSelectorEntry(IN HANDLE hThread, IN DWORD dwSelector, OUT LPLDT_ENTRY lpSelectorEntry)
Definition: thread.c:829
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
#define ok(value,...)
Definition: atltest.h:57
static HINSTANCE instance
Definition: main.c:40
BOOL WINAPI RegisterWaitForSingleObject(OUT PHANDLE phNewWaitObject, IN HANDLE hObject, IN WAITORTIMERCALLBACK Callback, IN PVOID Context, IN ULONG dwMilliseconds, IN ULONG dwFlags)
Definition: synch.c:850
Definition: cookie.c:33
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:142
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static DWORD LS_index0
Definition: thread.c:1327
#define NULL
Definition: types.h:112
static DWORD CALLBACK work_function(void *p)
Definition: thread.c:1218
#define STATUS_INVALID_LDT_DESCRIPTOR
Definition: ntstatus.h:518
#define SEM_NOOPENFILEERRORBOX
Definition: rtltypes.h:72
HANDLE hThread
Definition: wizard.c:27
struct _THREAD_DESCRIPTOR_INFORMATION THREAD_DESCRIPTOR_INFORMATION
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
BOOL WINAPI GetProcessAffinityMask(IN HANDLE hProcess, OUT PDWORD_PTR lpProcessAffinityMask, OUT PDWORD_PTR lpSystemAffinityMask)
Definition: proc.c:863
#define MultiByteToWideChar
Definition: compat.h:110
#define CreateFileW
Definition: compat.h:600
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1228
#define THREAD_TERMINATE
Definition: nt_native.h:1336
#define skip(...)
Definition: atltest.h:64
HANDLE events[2]
Definition: event.c:4
DWORD * threadmem
Definition: thread.c:191
static VOID test_GetThreadExitCode(void)
Definition: thread.c:993
#define BOOLEAN
Definition: pedump.c:73
DWORD dwNumberOfProcessors
Definition: winbase.h:1143
GLuint res
Definition: glext.h:9613
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:566
#define THREAD_QUERY_INFORMATION
Definition: pstypes.h:141
#define X(f)
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
Definition: actctx.c:104
static VOID test_thread_priority(void)
Definition: thread.c:673
#define HIWORD(l)
Definition: typedefs.h:247
unsigned int ULONG
Definition: retypes.h:1
static void init_thread_sync_helpers(void)
Definition: thread.c:138
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
char * cleanup(char *str)
Definition: wpickclick.c:99
static VOID test_CreateThread_basic(void)
Definition: thread.c:418
static void create_function_addr_events(HANDLE events[2])
Definition: thread.c:316
static DWORD WINAPI threadFunc_CloseHandle(LPVOID p)
Definition: thread.c:289
NTSYSAPI DWORD WINAPI RtlGetThreadErrorMode(void)
Definition: error.c:217
static const CHAR manifest[]
Definition: v6util.h:39
struct _TP_POOL * PTP_POOL
Definition: winnt_old.h:4301
static DWORD tls
Definition: sock.c:230
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOL WINAPI FlsFree(DWORD dwFlsIndex)
Definition: fiber.c:400
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
$USHORT Group
Definition: ntbasedef.h:662
GLfloat GLfloat p
Definition: glext.h:8902
static DWORD WINAPI thread_actctx_func(void *p)
Definition: thread.c:301
#define INFINITE
Definition: serial.h:102
static PTP_WORK(WINAPI *pCreateThreadpoolWork)(PTP_WORK_CALLBACK
VOID(NTAPI * PTP_WORK_CALLBACK)(_Inout_ PTP_CALLBACK_INSTANCE Instance, _Inout_opt_ PVOID Context, _Inout_ PTP_WORK Work)
Definition: winnt_old.h:4316
static const char manifest_main[]
Definition: thread.c:1762
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
static void WINAPI threadpool_workcallback(PTP_CALLBACK_INSTANCE instance, void *context, PTP_WORK work)
Definition: thread.c:1891
static VOID test_SuspendThread(void)
Definition: thread.c:554
#define win_skip
Definition: test.h:149
static TfClientId tid
static DWORD LS_index1
Definition: thread.c:1327
int WINAPI GetThreadPriority(IN HANDLE hThread)
Definition: thread.c:738
static DWORD WINAPI LS_InheritanceProc(LPVOID p)
Definition: thread.c:1354
static DWORD WINAPI threadFunc4(LPVOID p)
Definition: thread.c:253
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
DWORD dwLowDateTime
Definition: mapidefs.h:65
#define WT_EXECUTEDEFAULT
Definition: winnt_old.h:1071
static HANDLE start_event
Definition: thread.c:135
static void init_funcs(void)
Definition: thread.c:2063
HANDLE WINAPI CreateRemoteThread(IN HANDLE hProcess, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:158
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
static DWORD GLE
Definition: registry.c:38
Definition: fci.c:126
Definition: ps.c:97