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