ReactOS  0.4.12-dev-36-g472787f
thread.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: dll/win32/kernel32/client/thread.c
5  * PURPOSE: Thread functions
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Ariadne (ariadne@xs4all.nl)
8  *
9  */
10 
11 /* INCLUDES *******************************************************************/
12 
13 #include <k32.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 #define SXS_SUPPORT_FIXME
19 
21 
23 WINAPI
24 BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
26 
27 /* FUNCTIONS ******************************************************************/
28 
29 __declspec(noreturn)
30 VOID
31 WINAPI
32 BaseThreadStartup(IN LPTHREAD_START_ROUTINE lpStartAddress,
34 {
35  /* Attempt to call the Thread Start Address */
36  _SEH2_TRY
37  {
38  /* Legacy check which is still used today for Win32 threads */
39  if (NtCurrentTeb()->NtTib.Version == (30 << 8)) // OS/2 V3.0 ("Cruiser")
40  {
41  /* This registers the termination port with CSRSS */
43  }
44 
45  /* Get the exit code from the Thread Start */
46  ExitThread((lpStartAddress)((PVOID)lpParameter));
47  }
49  {
50  /* Get the Exit code from the SEH Handler */
52  {
53  /* Kill the whole process, usually */
55  }
56  else
57  {
58  /* If running inside CSRSS, kill just this thread */
60  }
61  }
62  _SEH2_END;
63 }
64 
65 VOID
66 NTAPI
68  IN PVOID Data,
69  IN PACTIVATION_CONTEXT ActivationContext)
70 {
71  RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActivationFrame;
72 
73  /* Setup the activation context */
74  ActivationFrame.Size = sizeof(ActivationFrame);
76 
77  /* Check if caller wanted one */
78  if (ActivationContext == INVALID_ACTIVATION_CONTEXT)
79  {
80  /* Do the APC directly */
81  ApcRoutine((ULONG_PTR)Data);
82  return;
83  }
84 
85  /* Then activate it */
86  RtlActivateActivationContextUnsafeFast(&ActivationFrame, ActivationContext);
87 
88  /* Call the routine under SEH */
89  _SEH2_TRY
90  {
91  ApcRoutine((ULONG_PTR)Data);
92  }
94  {
95 
96  }
97  _SEH2_END;
98 
99  /* Now de-activate and release the activation context */
101  RtlReleaseActivationContext(ActivationContext);
102 }
103 
104 /* PUBLIC FUNCTIONS ***********************************************************/
105 
106 /*
107  * @implemented
108  */
109 HANDLE
110 WINAPI
113  IN DWORD dwStackSize,
114  IN LPTHREAD_START_ROUTINE lpStartAddress,
116  IN DWORD dwCreationFlags,
117  OUT LPDWORD lpThreadId)
118 {
119  /* Act as if we're going to create a remote thread in ourselves */
121  lpThreadAttributes,
122  dwStackSize,
123  lpStartAddress,
124  lpParameter,
125  dwCreationFlags,
126  lpThreadId);
127 }
128 
129 /*
130  * @implemented
131  */
132 HANDLE
133 WINAPI
135  IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
136  IN DWORD dwStackSize,
137  IN LPTHREAD_START_ROUTINE lpStartAddress,
139  IN DWORD dwCreationFlags,
140  OUT LPDWORD lpThreadId)
141 {
143  INITIAL_TEB InitialTeb;
146  OBJECT_ATTRIBUTES LocalObjectAttributes;
148  HANDLE hThread;
149  ULONG Dummy;
150  PTEB Teb;
151  THREAD_BASIC_INFORMATION ThreadBasicInfo;
152  PACTIVATION_CONTEXT_STACK ActivationContextStack = NULL;
153  ACTIVATION_CONTEXT_BASIC_INFORMATION ActCtxInfo;
156  SIZE_T ReturnSize;
157  DPRINT("CreateRemoteThread: hProcess: %p dwStackSize: %lu lpStartAddress"
158  ": %p lpParameter: %p, dwCreationFlags: %lx\n", hProcess,
159  dwStackSize, lpStartAddress, lpParameter, dwCreationFlags);
160 
161  /* Clear the Context */
162  RtlZeroMemory(&Context, sizeof(CONTEXT));
163 
164  /* Write PID */
165  ClientId.UniqueProcess = hProcess;
166 
167  /* Create the Stack */
168  Status = BaseCreateStack(hProcess,
169  dwStackSize,
170  dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION ?
171  dwStackSize : 0,
172  &InitialTeb);
173  if (!NT_SUCCESS(Status))
174  {
175  BaseSetLastNTError(Status);
176  return NULL;
177  }
178 
179  /* Create Initial Context */
180  BaseInitializeContext(&Context,
181  lpParameter,
182  lpStartAddress,
183  InitialTeb.StackBase,
184  1);
185 
186  /* initialize the attributes for the thread object */
187  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
188  lpThreadAttributes,
189  NULL);
190 
191  /* Create the Kernel Thread Object */
192  Status = NtCreateThread(&hThread,
194  ObjectAttributes,
195  hProcess,
196  &ClientId,
197  &Context,
198  &InitialTeb,
199  TRUE);
200  if (!NT_SUCCESS(Status))
201  {
202  /* Fail the kernel create */
203  BaseFreeThreadStack(hProcess, &InitialTeb);
204  BaseSetLastNTError(Status);
205  return NULL;
206  }
207 
208  /* Are we in the same process? */
209  if (hProcess == NtCurrentProcess())
210  {
211  /* Get the TEB */
212  Status = NtQueryInformationThread(hThread,
214  &ThreadBasicInfo,
215  sizeof(ThreadBasicInfo),
216  &ReturnLength);
217  if (!NT_SUCCESS(Status))
218  {
219  /* Fail */
220  ERROR_DBGBREAK("SXS: %s - Failing thread create because "
221  "NtQueryInformationThread() failed with status %08lx\n",
222  __FUNCTION__, Status);
223  return NULL;
224  }
225 
226  /* Allocate the Activation Context Stack */
227  Status = RtlAllocateActivationContextStack(&ActivationContextStack);
228  if (!NT_SUCCESS(Status))
229  {
230  /* Fail */
231  ERROR_DBGBREAK("SXS: %s - Failing thread create because "
232  "RtlAllocateActivationContextStack() failed with status %08lx\n",
233  __FUNCTION__, Status);
234  return NULL;
235  }
236 
237  /* Save it */
238  Teb = ThreadBasicInfo.TebBaseAddress;
239  Teb->ActivationContextStackPointer = ActivationContextStack;
240 
241  /* Query the Context */
243  NULL,
244  0,
245  ActivationContextBasicInformation,
246  &ActCtxInfo,
247  sizeof(ActCtxInfo),
248  &ReturnSize);
249  if (!NT_SUCCESS(Status))
250  {
251  /* Fail */
252  ERROR_DBGBREAK("SXS: %s - Failing thread create because "
253  "RtlQueryInformationActivationContext() failed with status %08lx\n",
254  __FUNCTION__, Status);
255 
256  /* Free the activation context stack */
257  // RtlFreeThreadActivationContextStack();
259 
260  return NULL;
261  }
262 
263  /* Does it need to be activated? */
264  if ((ActCtxInfo.hActCtx) && !(ActCtxInfo.dwFlags & 1))
265  {
266  /* Activate it */
268  Teb,
269  ActCtxInfo.hActCtx,
270  &Cookie);
271  if (!NT_SUCCESS(Status))
272  {
273  /* Fail */
274  ERROR_DBGBREAK("SXS: %s - Failing thread create because "
275  "RtlActivateActivationContextEx() failed with status %08lx\n",
276  __FUNCTION__, Status);
277 
278  /* Free the activation context stack */
279  // RtlFreeThreadActivationContextStack();
281 
282  return NULL;
283  }
284  }
285  }
286 
287  /* Notify CSR */
289  {
290  Status = BasepNotifyCsrOfThread(hThread, &ClientId);
291  ASSERT(NT_SUCCESS(Status));
292  }
293  else
294  {
295  if (hProcess != NtCurrentProcess())
296  {
298 
299  /* Get the direct CSRSRV export */
300  CsrCreateRemoteThread = (PCSR_CREATE_REMOTE_THREAD)
302  "CsrCreateRemoteThread");
303  if (CsrCreateRemoteThread)
304  {
305  /* Call it instead of going through LPC */
306  Status = CsrCreateRemoteThread(hThread, &ClientId);
307  ASSERT(NT_SUCCESS(Status));
308  }
309  }
310  }
311 
312  /* Success */
313  if (lpThreadId) *lpThreadId = HandleToUlong(ClientId.UniqueThread);
314 
315  /* Resume it if asked */
316  if (!(dwCreationFlags & CREATE_SUSPENDED)) NtResumeThread(hThread, &Dummy);
317 
318  /* Return handle to thread */
319  return hThread;
320 }
321 
322 /*
323  * @implemented
324  */
325 VOID
326 WINAPI
327 ExitThread(IN DWORD uExitCode)
328 {
331  PRTL_CRITICAL_SECTION LoaderLock;
332 
333  /* Make sure loader lock isn't held */
334  LoaderLock = NtCurrentPeb()->LoaderLock;
335  if (LoaderLock) ASSERT(NtCurrentTeb()->ClientId.UniqueThread != LoaderLock->OwningThread);
336 
337  /*
338  * Terminate process if this is the last thread
339  * of the current process
340  */
343  &LastThread,
344  sizeof(LastThread),
345  NULL);
346  if ((NT_SUCCESS(Status)) && (LastThread)) ExitProcess(uExitCode);
347 
348  /* Notify DLLs and TLS Callbacks of termination */
350 
351  /* Tell the Kernel to free the Stack */
352  NtCurrentTeb()->FreeStackOnTermination = TRUE;
353  NtTerminateThread(NULL, uExitCode);
354 
355  /* We should never reach this place */
356  ERROR_FATAL("It should not happen\n");
357  while (TRUE); /* 'noreturn' function */
358 }
359 
360 /*
361  * @implemented
362  */
363 HANDLE
364 WINAPI
365 OpenThread(IN DWORD dwDesiredAccess,
368 {
370  HANDLE ThreadHandle;
373 
374  ClientId.UniqueProcess = 0;
375  ClientId.UniqueThread = ULongToHandle(dwThreadId);
376 
377  InitializeObjectAttributes(&ObjectAttributes,
378  NULL,
379  (bInheritHandle ? OBJ_INHERIT : 0),
380  NULL,
381  NULL);
382 
383  Status = NtOpenThread(&ThreadHandle,
384  dwDesiredAccess,
385  &ObjectAttributes,
386  &ClientId);
387  if (!NT_SUCCESS(Status))
388  {
389  BaseSetLastNTError(Status);
390  return NULL;
391  }
392 
393  return ThreadHandle;
394 }
395 
396 /*
397  * @implemented
398  */
399 PTEB
401 {
402  return NtCurrentTeb();
403 }
404 
405 /*
406  * @implemented
407  */
408 BOOL
409 WINAPI
411 {
413 }
414 
415 
416 /*
417  * @implemented
418  */
419 DWORD
420 WINAPI
422 {
424 }
425 
426 /*
427  * @implemented
428  */
429 BOOL
430 NTAPI
432  OUT LPFILETIME lpCreationTime,
433  OUT LPFILETIME lpExitTime,
434  OUT LPFILETIME lpKernelTime,
435  OUT LPFILETIME lpUserTime)
436 {
437  KERNEL_USER_TIMES KernelUserTimes;
439 
440  Status = NtQueryInformationThread(hThread,
441  ThreadTimes,
442  &KernelUserTimes,
443  sizeof(KERNEL_USER_TIMES),
444  NULL);
445  if (!NT_SUCCESS(Status))
446  {
447  BaseSetLastNTError(Status);
448  return FALSE;
449  }
450 
451  *lpCreationTime = *(LPFILETIME)&KernelUserTimes.CreateTime;
452  *lpExitTime = *(LPFILETIME)&KernelUserTimes.ExitTime;
453  *lpKernelTime = *(LPFILETIME)&KernelUserTimes.KernelTime;
454  *lpUserTime = *(LPFILETIME)&KernelUserTimes.UserTime;
455  return TRUE;
456 }
457 
458 /*
459  * @implemented
460  */
461 BOOL
462 WINAPI
464  OUT LPCONTEXT lpContext)
465 {
467 
468  Status = NtGetContextThread(hThread, lpContext);
469  if (!NT_SUCCESS(Status))
470  {
471  BaseSetLastNTError(Status);
472  return FALSE;
473  }
474 
475  return TRUE;
476 }
477 
478 /*
479  * @implemented
480  */
481 BOOL
482 WINAPI
484  IN CONST CONTEXT *lpContext)
485 {
487 
488  Status = NtSetContextThread(hThread, (PCONTEXT)lpContext);
489  if (!NT_SUCCESS(Status))
490  {
491  BaseSetLastNTError(Status);
492  return FALSE;
493  }
494 
495  return TRUE;
496 }
497 
498 /*
499  * @implemented
500  */
501 BOOL
502 WINAPI
504  OUT LPDWORD lpExitCode)
505 {
506  THREAD_BASIC_INFORMATION ThreadBasic;
508 
509  Status = NtQueryInformationThread(hThread,
511  &ThreadBasic,
512  sizeof(THREAD_BASIC_INFORMATION),
513  NULL);
514  if (!NT_SUCCESS(Status))
515  {
516  BaseSetLastNTError(Status);
517  return FALSE;
518  }
519 
520  *lpExitCode = ThreadBasic.ExitStatus;
521  return TRUE;
522 }
523 
524 /*
525  * @implemented
526  */
527 DWORD
528 WINAPI
530 {
531  ULONG PreviousResumeCount;
533 
534  Status = NtResumeThread(hThread, &PreviousResumeCount);
535  if (!NT_SUCCESS(Status))
536  {
537  BaseSetLastNTError(Status);
538  return -1;
539  }
540 
541  return PreviousResumeCount;
542 }
543 
544 /*
545  * @implemented
546  */
547 BOOL
548 WINAPI
550  IN DWORD dwExitCode)
551 {
553 #if DBG
554  PRTL_CRITICAL_SECTION LoaderLock;
556 #endif /* DBG */
557 
558  /* Check for invalid thread handle */
559  if (!hThread)
560  {
561  /* Fail if one was passed */
563  return FALSE;
564  }
565 
566 #if DBG
567  /* Get the loader lock */
568  LoaderLock = NtCurrentPeb()->LoaderLock;
569  if (LoaderLock)
570  {
571  /* Get our TID */
572  Status = NtQueryInformationThread(hThread,
574  &ThreadInfo,
575  sizeof(ThreadInfo),
576  NULL);
577  if (NT_SUCCESS(Status))
578  {
579  /* If terminating the current thread, we must not hold the loader lock */
582  }
583  }
584 #endif /* DBG */
585 
586  /* Now terminate the thread */
587  Status = NtTerminateThread(hThread, dwExitCode);
588  if (!NT_SUCCESS(Status))
589  {
590  /* Fail */
591  BaseSetLastNTError(Status);
592  return FALSE;
593  }
594 
595  /* All done */
596  return TRUE;
597 }
598 
599 /*
600  * @implemented
601  */
602 DWORD
603 WINAPI
605 {
606  ULONG PreviousSuspendCount;
608 
609  Status = NtSuspendThread(hThread, &PreviousSuspendCount);
610  if (!NT_SUCCESS(Status))
611  {
612  BaseSetLastNTError(Status);
613  return -1;
614  }
615 
616  return PreviousSuspendCount;
617 }
618 
619 /*
620  * @implemented
621  */
622 DWORD_PTR
623 WINAPI
625  IN DWORD_PTR dwThreadAffinityMask)
626 {
627  THREAD_BASIC_INFORMATION ThreadBasic;
628  KAFFINITY AffinityMask;
630 
631  AffinityMask = (KAFFINITY)dwThreadAffinityMask;
632 
633  Status = NtQueryInformationThread(hThread,
635  &ThreadBasic,
636  sizeof(THREAD_BASIC_INFORMATION),
637  NULL);
638  if (!NT_SUCCESS(Status))
639  {
640  BaseSetLastNTError(Status);
641  return 0;
642  }
643 
644  Status = NtSetInformationThread(hThread,
646  &AffinityMask,
647  sizeof(KAFFINITY));
648  if (!NT_SUCCESS(Status))
649  {
650  BaseSetLastNTError(Status);
651  ThreadBasic.AffinityMask = 0;
652  }
653 
654  return ThreadBasic.AffinityMask;
655 }
656 
657 /*
658  * @implemented
659  */
660 BOOL
661 WINAPI
663  IN int nPriority)
664 {
665  LONG Prio = nPriority;
667 
668  /* Check if values forcing saturation should be used */
669  if (Prio == THREAD_PRIORITY_TIME_CRITICAL)
670  {
671  /* This is 16 */
672  Prio = (HIGH_PRIORITY + 1) / 2;
673  }
674  else if (Prio == THREAD_PRIORITY_IDLE)
675  {
676  /* This is -16 */
677  Prio = -((HIGH_PRIORITY + 1) / 2);
678  }
679 
680  /* Set the Base Priority */
681  Status = NtSetInformationThread(hThread,
683  &Prio,
684  sizeof(LONG));
685  if (!NT_SUCCESS(Status))
686  {
687  /* Failure */
688  BaseSetLastNTError(Status);
689  return FALSE;
690  }
691 
692  /* Return */
693  return TRUE;
694 }
695 
696 /*
697  * @implemented
698  */
699 int
700 WINAPI
702 {
703  THREAD_BASIC_INFORMATION ThreadBasic;
705 
706  /* Query the Base Priority Increment */
707  Status = NtQueryInformationThread(hThread,
709  &ThreadBasic,
710  sizeof(THREAD_BASIC_INFORMATION),
711  NULL);
712  if (!NT_SUCCESS(Status))
713  {
714  /* Failure */
715  BaseSetLastNTError(Status);
717  }
718 
719  /* Do some conversions for saturation values */
720  if (ThreadBasic.BasePriority == ((HIGH_PRIORITY + 1) / 2))
721  {
722  /* Win32 calls this "time critical" */
724  }
725  else if (ThreadBasic.BasePriority == -((HIGH_PRIORITY + 1) / 2))
726  {
727  /* Win32 calls this "idle" */
728  ThreadBasic.BasePriority = THREAD_PRIORITY_IDLE;
729  }
730 
731  /* Return the final result */
732  return ThreadBasic.BasePriority;
733 }
734 
735 /*
736  * @implemented
737  */
738 BOOL
739 WINAPI
741  OUT PBOOL pDisablePriorityBoost)
742 {
745 
746  Status = NtQueryInformationThread(hThread,
748  &PriorityBoost,
749  sizeof(ULONG),
750  NULL);
751  if (!NT_SUCCESS(Status))
752  {
753  BaseSetLastNTError(Status);
754  return FALSE;
755  }
756 
757  *pDisablePriorityBoost = PriorityBoost;
758  return TRUE;
759 }
760 
761 /*
762  * @implemented
763  */
764 BOOL
765 NTAPI
767  IN BOOL bDisablePriorityBoost)
768 {
771 
772  PriorityBoost = bDisablePriorityBoost != FALSE;
773 
774  Status = NtSetInformationThread(hThread,
776  &PriorityBoost,
777  sizeof(ULONG));
778  if (!NT_SUCCESS(Status))
779  {
780  BaseSetLastNTError(Status);
781  return FALSE;
782  }
783 
784  return TRUE;
785 }
786 
787 /*
788  * @implemented
789  */
790 BOOL
791 WINAPI
793  IN DWORD dwSelector,
794  OUT LPLDT_ENTRY lpSelectorEntry)
795 {
796 #ifdef _M_IX86
797  DESCRIPTOR_TABLE_ENTRY DescriptionTableEntry;
799 
800  /* Set the selector and do the query */
801  DescriptionTableEntry.Selector = dwSelector;
802  Status = NtQueryInformationThread(hThread,
804  &DescriptionTableEntry,
805  sizeof(DESCRIPTOR_TABLE_ENTRY),
806  NULL);
807  if (!NT_SUCCESS(Status))
808  {
809  /* Fail */
810  BaseSetLastNTError(Status);
811  return FALSE;
812  }
813 
814  /* Success, return the selector */
815  *lpSelectorEntry = DescriptionTableEntry.Descriptor;
816  return TRUE;
817 #else
818  DPRINT1("Calling GetThreadSelectorEntry!\n");
819  return FALSE;
820 #endif
821 }
822 
823 /*
824  * @implemented
825  */
826 DWORD
827 WINAPI
829  IN DWORD dwIdealProcessor)
830 {
832 
833  Status = NtSetInformationThread(hThread,
835  &dwIdealProcessor,
836  sizeof(ULONG));
837  if (!NT_SUCCESS(Status))
838  {
839  BaseSetLastNTError(Status);
840  return -1;
841  }
842 
843  return (DWORD)Status;
844 }
845 
846 /*
847  * @implemented
848  */
849 DWORD
850 WINAPI
852 {
853  THREAD_BASIC_INFORMATION ThreadBasic;
855 
856  Status = NtQueryInformationThread(Thread,
858  &ThreadBasic,
859  sizeof(THREAD_BASIC_INFORMATION),
860  NULL);
861  if (!NT_SUCCESS(Status))
862  {
863  BaseSetLastNTError(Status);
864  return 0;
865  }
866 
867  return HandleToUlong(ThreadBasic.ClientId.UniqueProcess);
868 }
869 
870 /*
871  * @implemented
872  */
873 DWORD
874 WINAPI
876 {
877  THREAD_BASIC_INFORMATION ThreadBasic;
879 
880  Status = NtQueryInformationThread(Thread,
882  &ThreadBasic,
883  sizeof(THREAD_BASIC_INFORMATION),
884  NULL);
885  if (!NT_SUCCESS(Status))
886  {
887  BaseSetLastNTError(Status);
888  return 0;
889  }
890 
891  return HandleToUlong(ThreadBasic.ClientId.UniqueThread);
892 }
893 
894 /*
895  * @unimplemented
896  */
897 LANGID
898 WINAPI
900 {
902  return (LANGID)NtCurrentTeb()->CurrentLocale;
903 }
904 
905 /*
906  * @implemented
907  */
908 DWORD
909 WINAPI
911  IN HANDLE hThread,
913 {
915  ACTIVATION_CONTEXT_BASIC_INFORMATION ActCtxInfo;
916 
917  /* Zero the activation context and query information on it */
918  RtlZeroMemory(&ActCtxInfo, sizeof(ActCtxInfo));
920  NULL,
921  0,
922  ActivationContextBasicInformation,
923  &ActCtxInfo,
924  sizeof(ActCtxInfo),
925  NULL);
926  if (!NT_SUCCESS(Status))
927  {
928  /* Fail due to SxS */
929  DbgPrint("SXS: %s failing because RtlQueryInformationActivationContext()"
930  "returned status %08lx\n", __FUNCTION__, Status);
931  BaseSetLastNTError(Status);
932  return FALSE;
933  }
934 
935  /* Queue the APC */
936  Status = NtQueueApcThread(hThread,
938  pfnAPC,
939  (PVOID)dwData,
940  (ActCtxInfo.dwFlags & 1) ?
941  INVALID_ACTIVATION_CONTEXT : ActCtxInfo.hActCtx);
942  if (!NT_SUCCESS(Status))
943  {
944  BaseSetLastNTError(Status);
945  return FALSE;
946  }
947 
948  /* All good */
949  return TRUE;
950 }
951 
952 /*
953  * @implemented
954  */
955 BOOL
956 WINAPI
958 {
959  static int once;
960  if (once++ == 0)
961  DPRINT1("SetThreadStackGuarantee(%p): stub\n", StackSizeInBytes);
962  return TRUE;
963 }
964 
965 /*
966  * @implemented
967  */
968 BOOL
969 WINAPI
971  OUT PBOOL lpIOIsPending)
972 {
973  ULONG IoPending;
975 
976  /* Query the flag */
977  Status = NtQueryInformationThread(hThread,
979  &IoPending,
980  sizeof(IoPending),
981  NULL);
982  if (NT_SUCCESS(Status))
983  {
984  /* Return the flag */
985  *lpIOIsPending = IoPending ? TRUE : FALSE;
986  return TRUE;
987  }
988 
989  /* Fail */
990  BaseSetLastNTError(Status);
991  return FALSE;
992 }
993 
994 /*
995  * @implemented
996  */
997 BOOL
998 WINAPI
1000  IN PVOID Context,
1001  IN ULONG Flags)
1002 {
1003  NTSTATUS Status;
1004 
1005  /* NOTE: Rtl needs to safely call the function using a trampoline */
1006  Status = RtlQueueWorkItem((WORKERCALLBACKFUNC)Function, Context, Flags);
1007  if (!NT_SUCCESS(Status))
1008  {
1009  /* Failed */
1010  BaseSetLastNTError(Status);
1011  return FALSE;
1012  }
1013 
1014  /* All good */
1015  return TRUE;
1016 }
1017 
1018 /*
1019  * @implemented
1020  */
1021 DWORD
1022 WINAPI
1024 {
1025  ULONG Index;
1026  PTEB Teb;
1027  PPEB Peb;
1028 
1029  /* Get the PEB and TEB, lock the PEB */
1030  Teb = NtCurrentTeb();
1031  Peb = Teb->ProcessEnvironmentBlock;
1033 
1034  /* Try to get regular TEB slot */
1035  Index = RtlFindClearBitsAndSet(Peb->TlsBitmap, 1, 0);
1036  if (Index != 0xFFFFFFFF)
1037  {
1038  /* Clear the value. */
1039  Teb->TlsSlots[Index] = 0;
1041  return Index;
1042  }
1043 
1044  /* If it fails, try to find expansion TEB slot. */
1045  Index = RtlFindClearBitsAndSet(Peb->TlsExpansionBitmap, 1, 0);
1046  if (Index != 0xFFFFFFFF)
1047  {
1048  /* Is there no expansion slot yet? */
1049  if (!Teb->TlsExpansionSlots)
1050  {
1051  /* Allocate an array */
1052  Teb->TlsExpansionSlots = RtlAllocateHeap(RtlGetProcessHeap(),
1055  sizeof(PVOID));
1056  }
1057 
1058  /* Did we get an array? */
1059  if (!Teb->TlsExpansionSlots)
1060  {
1061  /* Fail */
1062  RtlClearBits(Peb->TlsExpansionBitmap, Index, 1);
1063  Index = 0xFFFFFFFF;
1065  }
1066  else
1067  {
1068  /* Clear the value. */
1069  Teb->TlsExpansionSlots[Index] = 0;
1070  Index += TLS_MINIMUM_AVAILABLE;
1071  }
1072  }
1073  else
1074  {
1075  /* Fail */
1077  }
1078 
1079  /* Release the lock and return */
1081  return Index;
1082 }
1083 
1084 /*
1085  * @implemented
1086  */
1087 BOOL
1088 WINAPI
1090 {
1091  BOOL BitSet;
1092  PPEB Peb;
1093  ULONG TlsIndex;
1094  PVOID TlsBitmap;
1095  NTSTATUS Status;
1096 
1097  /* Acquire the PEB lock and grab the PEB */
1098  Peb = NtCurrentPeb();
1100 
1101  /* Check if the index is too high */
1102  if (Index >= TLS_MINIMUM_AVAILABLE)
1103  {
1104  /* Check if it can fit in the expansion slots */
1105  TlsIndex = Index - TLS_MINIMUM_AVAILABLE;
1106  if (TlsIndex >= TLS_EXPANSION_SLOTS)
1107  {
1108  /* It's invalid */
1111  return FALSE;
1112  }
1113  else
1114  {
1115  /* Use the expansion bitmap */
1116  TlsBitmap = Peb->TlsExpansionBitmap;
1117  Index = TlsIndex;
1118  }
1119  }
1120  else
1121  {
1122  /* Use the normal bitmap */
1123  TlsBitmap = Peb->TlsBitmap;
1124  }
1125 
1126  /* Check if the index was set */
1127  BitSet = RtlAreBitsSet(TlsBitmap, Index, 1);
1128  if (BitSet)
1129  {
1130  /* Tell the kernel to free the TLS cells */
1133  &Index,
1134  sizeof(DWORD));
1135  if (!NT_SUCCESS(Status))
1136  {
1139  return FALSE;
1140  }
1141 
1142  /* Clear the bit */
1143  RtlClearBits(TlsBitmap, Index, 1);
1144  }
1145  else
1146  {
1147  /* Fail */
1150  return FALSE;
1151  }
1152 
1153  /* Done! */
1155  return TRUE;
1156 }
1157 
1158 /*
1159  * @implemented
1160  */
1161 LPVOID
1162 WINAPI
1164 {
1165  PTEB Teb;
1166 
1167  /* Get the TEB and clear the last error */
1168  Teb = NtCurrentTeb();
1169  Teb->LastErrorValue = 0;
1170 
1171  /* Check for simple TLS index */
1172  if (Index < TLS_MINIMUM_AVAILABLE)
1173  {
1174  /* Return it */
1175  return Teb->TlsSlots[Index];
1176  }
1177 
1178  /* Check for valid index */
1180  {
1181  /* Fail */
1183  return NULL;
1184  }
1185 
1186  /* The expansion slots are allocated on demand, so check for it. */
1187  Teb->LastErrorValue = 0;
1188  if (!Teb->TlsExpansionSlots) return NULL;
1189 
1190  /* Return the value from the expansion slots */
1191  return Teb->TlsExpansionSlots[Index - TLS_MINIMUM_AVAILABLE];
1192 }
1193 
1194 /*
1195  * @implemented
1196  */
1197 BOOL
1198 WINAPI
1200  IN LPVOID Value)
1201 {
1202  DWORD TlsIndex;
1203  PTEB Teb = NtCurrentTeb();
1204 
1205  /* Check for simple TLS index */
1206  if (Index < TLS_MINIMUM_AVAILABLE)
1207  {
1208  /* Return it */
1209  Teb->TlsSlots[Index] = Value;
1210  return TRUE;
1211  }
1212 
1213  /* Check if this is an expansion slot */
1214  TlsIndex = Index - TLS_MINIMUM_AVAILABLE;
1215  if (TlsIndex >= TLS_EXPANSION_SLOTS)
1216  {
1217  /* Fail */
1219  return FALSE;
1220  }
1221 
1222  /* Do we not have expansion slots? */
1223  if (!Teb->TlsExpansionSlots)
1224  {
1225  /* Get the PEB lock to see if we still need them */
1227  if (!Teb->TlsExpansionSlots)
1228  {
1229  /* Allocate them */
1230  Teb->TlsExpansionSlots = RtlAllocateHeap(RtlGetProcessHeap(),
1233  sizeof(PVOID));
1234  if (!Teb->TlsExpansionSlots)
1235  {
1236  /* Fail */
1239  return FALSE;
1240  }
1241  }
1242 
1243  /* Release the lock */
1245  }
1246 
1247  /* Write the value */
1249 
1250  /* Success */
1251  return TRUE;
1252 }
1253 
1254 /* EOF */
PRTL_BITMAP TlsExpansionBitmap
Definition: winternl.h:346
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
LANGID WINAPI SetThreadUILanguage(IN LANGID LangId)
Definition: thread.c:899
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define IN
Definition: typedefs.h:38
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define ULongToHandle(h)
Definition: basetsd.h:81
VOID WINAPI BaseInitializeContext(IN PCONTEXT Context, IN PVOID Parameter, IN PVOID StartAddress, IN PVOID StackAddress, IN ULONG ContextType)
Definition: utils.c:503
BOOL NTAPI GetThreadTimes(IN HANDLE hThread, OUT LPFILETIME lpCreationTime, OUT LPFILETIME lpExitTime, OUT LPFILETIME lpKernelTime, OUT LPFILETIME lpUserTime)
Definition: thread.c:431
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
BOOL WINAPI SwitchToThread(VOID)
Definition: thread.c:410
DWORD(WINAPI * LPTHREAD_START_ROUTINE)(LPVOID)
Definition: winbase.h:707
#define TRUE
Definition: types.h:120
BOOL WINAPI SetThreadContext(IN HANDLE hThread, IN CONST CONTEXT *lpContext)
Definition: thread.c:483
NTSTATUS NTAPI NtOpenThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL)
Definition: thread.c:1013
PPEB Peb
Definition: dllmain.c:27
PPEB ProcessEnvironmentBlock
Definition: ntddk_ex.h:341
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:549
KAFFINITY AffinityMask
Definition: compat.h:579
#define DbgPrint
Definition: loader.c:25
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
Definition: thread.c:1199
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5267
struct _FILETIME * LPFILETIME
Definition: time.c:29
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_YIELD_PERFORMED
Definition: ntstatus.h:150
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:294
#define THREAD_PRIORITY_ERROR_RETURN
Definition: winbase.h:279
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
LONG NTSTATUS
Definition: precomp.h:26
LARGE_INTEGER UserTime
Definition: winternl.h:1063
#define HandleToUlong(h)
Definition: basetsd.h:79
#define NtCurrentThread()
NTSYSAPI NTSTATUS NTAPI RtlQueueWorkItem(_In_ WORKERCALLBACKFUNC Function, _In_opt_ PVOID Context, _In_ ULONG Flags)
__declspec(noreturn)
Definition: thread.c:29
static HANDLE ULONG_PTR dwData
Definition: file.c:35
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
VOID NTAPI RtlReleasePebLock(VOID)
Definition: libsupp.c:82
DWORD WINAPI GetThreadId(IN HANDLE Thread)
Definition: thread.c:875
struct _ThreadInfo ThreadInfo
WORD LANGID
Definition: typedefs.h:79
BOOL WINAPI GetThreadIOPendingFlag(IN HANDLE hThread, OUT PBOOL lpIOIsPending)
Definition: thread.c:970
NTSTATUS NTAPI NtSuspendThread(IN HANDLE ThreadHandle, OUT PULONG PreviousSuspendCount OPTIONAL)
Definition: state.c:352
HANDLE UniqueProcess
Definition: compat.h:474
#define RTL_ACTIVATE_ACTIVATION_CONTEXT_EX_FLAG_RELEASE_ON_STACK_DEALLOCATION
Definition: rtltypes.h:106
NTSTATUS NTAPI NtQueueApcThread(IN HANDLE ThreadHandle, IN PKNORMAL_ROUTINE ApcRoutine, IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: state.c:500
KPRIORITY BasePriority
Definition: compat.h:581
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
LARGE_INTEGER ExitTime
Definition: winternl.h:1061
#define ERROR_FATAL(...)
Definition: debug.h:238
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:503
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:463
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
DWORD WINAPI QueueUserAPC(IN PAPCFUNC pfnAPC, IN HANDLE hThread, IN ULONG_PTR dwData)
Definition: thread.c:910
#define CREATE_SUSPENDED
Definition: winbase.h:178
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
static BOOL bInheritHandle
Definition: pipe.c:82
long LONG
Definition: pedump.c:60
BOOL NTAPI SetThreadPriorityBoost(IN HANDLE hThread, IN BOOL bDisablePriorityBoost)
Definition: thread.c:766
LONG WINAPI UnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: except.c:262
_In_ CCHAR PriorityBoost
Definition: iofuncs.h:763
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
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:112
smooth NULL
Definition: ftsmooth.c:416
DWORD_PTR WINAPI SetThreadAffinityMask(IN HANDLE hThread, IN DWORD_PTR dwThreadAffinityMask)
Definition: thread.c:624
PVOID StackBase
Definition: pstypes.h:678
void DPRINT(...)
Definition: polytest.cpp:61
BOOL WINAPI GetThreadPriorityBoost(IN HANDLE hThread, OUT PBOOL pDisablePriorityBoost)
Definition: thread.c:740
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:327
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:1967
BOOL * PBOOL
Definition: windef.h:161
#define HIGH_PRIORITY
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:421
#define CONST
Definition: compiler.h:170
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:662
#define NtCurrentProcess()
Definition: nt_native.h:1657
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:224
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
unsigned int BOOL
Definition: ntddk_ex.h:94
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
BOOLEAN BaseRunningInServerProcess
Definition: dllmain.c:20
BOOL WINAPI TlsFree(IN DWORD Index)
Definition: thread.c:1089
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
VOID NTAPI BaseDispatchApc(IN PAPCFUNC ApcRoutine, IN PVOID Data, IN PACTIVATION_CONTEXT ActivationContext)
Definition: thread.c:67
NTSTATUS NTAPI NtYieldExecution(VOID)
Definition: thrdschd.c:744
LARGE_INTEGER CreateTime
Definition: winternl.h:1060
#define OBJ_INHERIT
Definition: winternl.h:225
#define STACK_SIZE_PARAM_IS_A_RESERVATION
Definition: winbase.h:558
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
BOOL WINAPI SetThreadStackGuarantee(IN OUT PULONG StackSizeInBytes)
Definition: thread.c:957
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:5934
#define SetLastError(x)
Definition: compat.h:409
DWORD WINAPI SetThreadIdealProcessor(IN HANDLE hThread, IN DWORD dwIdealProcessor)
Definition: thread.c:828
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2450
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
HANDLE UniqueThread
Definition: compat.h:475
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOL WINAPI QueueUserWorkItem(IN LPTHREAD_START_ROUTINE Function, IN PVOID Context, IN ULONG Flags)
Definition: thread.c:999
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:278
NTSTATUS NTAPI CsrCreateRemoteThread(IN HANDLE hThread, IN PCLIENT_ID ClientId)
Definition: thredsup.c:568
DWORD dwThreadId
Definition: fdebug.c:31
#define THREAD_PRIORITY_IDLE
Definition: winbase.h:275
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:604
NTSTATUS WINAPI BaseCreateStack(HANDLE hProcess, SIZE_T StackCommit, SIZE_T StackReserve, PINITIAL_TEB InitialTeb)
Definition: utils.c:353
LPVOID lpParameter
Definition: kernel32.h:232
HANDLE WINAPI OpenThread(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwThreadId)
Definition: thread.c:365
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1023
PTEB GetTeb(VOID)
Definition: thread.c:400
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define TlsIndex
Definition: ws2_32p.h:267
#define WINAPI
Definition: msvc.h:20
POBJECT_ATTRIBUTES WINAPI BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes, IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL, IN PUNICODE_STRING ObjectName)
Definition: utils.c:304
static NTSTATUS(WINAPI *pNtQueryInformationThread)(HANDLE
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI CsrNewThread(VOID)
Definition: api.c:27
PETHREAD LastThread
Definition: pinsup.c:109
Definition: compat.h:428
ULONG_PTR SIZE_T
Definition: typedefs.h:78
Definition: compat.h:484
NTSTATUS WINAPI BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, IN PCLIENT_ID ClientId)
Definition: proc.c:484
_SEH2_END
Definition: create.c:4424
NTSYSAPI BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP, ULONG, ULONG)
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
DWORD WINAPI GetProcessIdOfThread(IN HANDLE Thread)
Definition: thread.c:851
#define NtCurrentPeb()
Definition: FLS.c:19
ULONG_PTR KAFFINITY
Definition: compat.h:75
BOOL WINAPI GetThreadSelectorEntry(IN HANDLE hThread, IN DWORD dwSelector, OUT LPLDT_ENTRY lpSelectorEntry)
Definition: thread.c:792
NTSTATUS NTAPI NtSetContextThread(IN HANDLE ThreadHandle, IN PCONTEXT ThreadContext)
Definition: debug.c:371
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI NtCreateThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, OUT PCLIENT_ID ClientId, IN PCONTEXT ThreadContext, IN PINITIAL_TEB InitialTeb, IN BOOLEAN CreateSuspended)
Definition: thread.c:941
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5438
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
HANDLE hThread
Definition: wizard.c:27
VOID NTAPI RtlAcquirePebLock(VOID)
Definition: libsupp.c:72
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT
Definition: rtltypes.h:116
#define DPRINT1
Definition: precomp.h:8
NTSTATUS(NTAPI * PCSR_CREATE_REMOTE_THREAD)(IN HANDLE ThreadHandle, IN PCLIENT_ID ClientId)
Definition: thread.c:20
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1163
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5857
VOID(NTAPI * WORKERCALLBACKFUNC)(_In_ PVOID Context)
Definition: rtltypes.h:509
NTSTATUS NTAPI RtlActivateActivationContextEx(ULONG flags, PTEB tebAddress, HANDLE handle, PULONG_PTR cookie)
Definition: actctx.c:5291
#define OUT
Definition: typedefs.h:39
NTSTATUS NTAPI RtlAllocateActivationContextStack(IN PACTIVATION_CONTEXT_STACK *Stack)
Definition: actctx.c:5829
uint32_t * LPDWORD
Definition: typedefs.h:57
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:529
ULONG LastErrorValue
Definition: compat.h:492
struct tagContext Context
Definition: acpixf.h:1027
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define GetProcAddress(x, y)
Definition: compat.h:410
PVOID TlsSlots[64]
Definition: compat.h:528
PVOID * TlsExpansionSlots
Definition: compat.h:543
#define __FUNCTION__
Definition: compiler.h:205
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
PVOID ActivationContextStackPointer
Definition: compat.h:503
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:632
NTSTATUS NTAPI LdrShutdownThread(VOID)
Definition: ldrinit.c:1076
PVOID TlsBitmap
Definition: ntddk_ex.h:263
LARGE_INTEGER KernelTime
Definition: winternl.h:1062
int WINAPI GetThreadPriority(IN HANDLE hThread)
Definition: thread.c:701
NTSTATUS NTAPI NtGetContextThread(IN HANDLE ThreadHandle, IN OUT PCONTEXT ThreadContext)
Definition: debug.c:334
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:240
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:134
VOID WINAPI BaseFreeThreadStack(IN HANDLE hProcess, IN PINITIAL_TEB InitialTeb)
Definition: utils.c:486
VOID NTAPI RtlFreeActivationContextStack(IN PACTIVATION_CONTEXT_STACK Stack)
Definition: actctx.c:5363