ReactOS  0.4.14-dev-593-g1793dcc
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 /* INCLUDES *******************************************************************/
11 
12 #include <k32.h>
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 #define SXS_SUPPORT_FIXME
18 
20 
21 /* FUNCTIONS ******************************************************************/
22 
24 WINAPI
27 {
28  BASE_API_MESSAGE ApiMessage;
29  PBASE_CREATE_THREAD CreateThreadRequest = &ApiMessage.Data.CreateThreadRequest;
30 
31  DPRINT("BasepNotifyCsrOfThread: Thread: %p, Handle %p\n",
32  ClientId->UniqueThread, ThreadHandle);
33 
34  /* Fill out the request */
35  CreateThreadRequest->ClientId = *ClientId;
36  CreateThreadRequest->ThreadHandle = ThreadHandle;
37 
38  /* Call CSR */
40  NULL,
42  sizeof(*CreateThreadRequest));
43  if (!NT_SUCCESS(ApiMessage.Status))
44  {
45  DPRINT1("Failed to tell CSRSS about new thread: %lx\n", ApiMessage.Status);
46  return ApiMessage.Status;
47  }
48 
49  /* Return Success */
50  return STATUS_SUCCESS;
51 }
52 
53 __declspec(noreturn)
54 VOID
55 WINAPI
56 BaseThreadStartup(IN LPTHREAD_START_ROUTINE lpStartAddress,
58 {
59  /* Attempt to call the Thread Start Address */
60  _SEH2_TRY
61  {
62  /* Legacy check which is still used today for Win32 threads */
63  if (NtCurrentTeb()->NtTib.Version == (30 << 8)) // OS/2 V3.0 ("Cruiser")
64  {
65  /* This registers the termination port with CSRSS */
67  }
68 
69  /* Get the exit code from the Thread Start */
70  ExitThread((lpStartAddress)((PVOID)lpParameter));
71  }
73  {
74  /* Get the Exit code from the SEH Handler */
76  {
77  /* Kill the whole process, usually */
79  }
80  else
81  {
82  /* If running inside CSRSS, kill just this thread */
84  }
85  }
86  _SEH2_END;
87 }
88 
89 VOID
90 NTAPI
92  IN PVOID Data,
93  IN PACTIVATION_CONTEXT ActivationContext)
94 {
95  RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActivationFrame;
96 
97  /* Setup the activation context */
98  ActivationFrame.Size = sizeof(ActivationFrame);
100 
101  /* Check if caller wanted one */
102  if (ActivationContext == INVALID_ACTIVATION_CONTEXT)
103  {
104  /* Do the APC directly */
106  return;
107  }
108 
109  /* Then activate it */
110  RtlActivateActivationContextUnsafeFast(&ActivationFrame, ActivationContext);
111 
112  /* Call the routine under SEH */
113  _SEH2_TRY
114  {
116  }
118  {
119 
120  }
121  _SEH2_END;
122 
123  /* Now de-activate and release the activation context */
125  RtlReleaseActivationContext(ActivationContext);
126 }
127 
128 /* PUBLIC FUNCTIONS ***********************************************************/
129 
130 /*
131  * @implemented
132  */
133 HANDLE
134 WINAPI
137  IN DWORD dwStackSize,
138  IN LPTHREAD_START_ROUTINE lpStartAddress,
140  IN DWORD dwCreationFlags,
141  OUT LPDWORD lpThreadId)
142 {
143  /* Act as if we're going to create a remote thread in ourselves */
145  lpThreadAttributes,
146  dwStackSize,
147  lpStartAddress,
148  lpParameter,
149  dwCreationFlags,
150  lpThreadId);
151 }
152 
153 /*
154  * @implemented
155  */
156 HANDLE
157 WINAPI
159  IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
160  IN DWORD dwStackSize,
161  IN LPTHREAD_START_ROUTINE lpStartAddress,
163  IN DWORD dwCreationFlags,
164  OUT LPDWORD lpThreadId)
165 {
167  INITIAL_TEB InitialTeb;
170  OBJECT_ATTRIBUTES LocalObjectAttributes;
172  HANDLE hThread;
173  ULONG Dummy;
174  PTEB Teb;
175  THREAD_BASIC_INFORMATION ThreadBasicInfo;
176  PACTIVATION_CONTEXT_STACK ActivationContextStack = NULL;
177  ACTIVATION_CONTEXT_BASIC_INFORMATION ActCtxInfo;
180  SIZE_T ReturnSize;
181 
182  DPRINT("CreateRemoteThread: hProcess: %p dwStackSize: %lu lpStartAddress"
183  ": %p lpParameter: %p, dwCreationFlags: %lx\n", hProcess,
184  dwStackSize, lpStartAddress, lpParameter, dwCreationFlags);
185 
186  /* Clear the Context */
187  RtlZeroMemory(&Context, sizeof(Context));
188 
189  /* Write PID */
191 
192  /* Create the Stack */
194  (dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) ?
195  0 : dwStackSize,
196  (dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) ?
197  dwStackSize : 0,
198  &InitialTeb);
199  if (!NT_SUCCESS(Status))
200  {
202  return NULL;
203  }
204 
205  /* Create the Initial Context */
207  lpParameter,
208  lpStartAddress,
209  InitialTeb.StackBase,
210  1);
211 
212  /* Initialize the attributes for the thread object */
213  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
214  lpThreadAttributes,
215  NULL);
216 
217  /* Create the Kernel Thread Object */
221  hProcess,
222  &ClientId,
223  &Context,
224  &InitialTeb,
225  TRUE);
226  if (!NT_SUCCESS(Status))
227  {
228  /* Fail the kernel create */
229  BaseFreeThreadStack(hProcess, &InitialTeb);
231  return NULL;
232  }
233 
234  /* Are we in the same process? */
235  if (hProcess == NtCurrentProcess())
236  {
237  /* Get the TEB */
240  &ThreadBasicInfo,
241  sizeof(ThreadBasicInfo),
242  &ReturnLength);
243  if (!NT_SUCCESS(Status))
244  {
245  /* Fail */
246  DPRINT1("SXS: %s - Failing thread create because "
247  "NtQueryInformationThread() failed with status %08lx\n",
249  goto Quit;
250  }
251 
252  /* Allocate the Activation Context Stack */
253  Status = RtlAllocateActivationContextStack(&ActivationContextStack);
254  if (!NT_SUCCESS(Status))
255  {
256  /* Fail */
257  DPRINT1("SXS: %s - Failing thread create because "
258  "RtlAllocateActivationContextStack() failed with status %08lx\n",
260  goto Quit;
261  }
262 
263  /* Save it */
264  Teb = ThreadBasicInfo.TebBaseAddress;
265  Teb->ActivationContextStackPointer = ActivationContextStack;
266 
267  /* Query the Context */
269  NULL,
270  0,
271  ActivationContextBasicInformation,
272  &ActCtxInfo,
273  sizeof(ActCtxInfo),
274  &ReturnSize);
275  if (!NT_SUCCESS(Status))
276  {
277  /* Fail */
278  DPRINT1("SXS: %s - Failing thread create because "
279  "RtlQueryInformationActivationContext() failed with status %08lx\n",
281  goto Quit;
282  }
283 
284  /* Does it need to be activated? */
285  if ((ActCtxInfo.hActCtx) && !(ActCtxInfo.dwFlags & 1))
286  {
287  /* Activate it */
289  Teb,
290  ActCtxInfo.hActCtx,
291  &Cookie);
292  if (!NT_SUCCESS(Status))
293  {
294  /* Fail */
295  DPRINT1("SXS: %s - Failing thread create because "
296  "RtlActivateActivationContextEx() failed with status %08lx\n",
298  goto Quit;
299  }
300  }
301 
302  /* Sync the service tag with the parent thread's one */
303  Teb->SubProcessTag = NtCurrentTeb()->SubProcessTag;
304  }
305 
306  /* Notify CSR */
308  {
310  }
311  else
312  {
313  if (hProcess != NtCurrentProcess())
314  {
316 
317  /* Get the direct CSRSRV export */
320  "CsrCreateRemoteThread");
322  {
323  /* Call it instead of going through LPC */
325  }
326  }
327  }
328 
329 Quit:
330  if (!NT_SUCCESS(Status))
331  {
332  /* Failed to create the thread */
333 
334  /* Free the activation context stack */
335  if (ActivationContextStack)
336  RtlFreeActivationContextStack(ActivationContextStack);
337 
339  // FIXME: Wait for the thread to terminate?
340  BaseFreeThreadStack(hProcess, &InitialTeb);
341  NtClose(hThread);
342 
344  return NULL;
345  }
346 
347  /* Success */
348  if (lpThreadId)
349  *lpThreadId = HandleToUlong(ClientId.UniqueThread);
350 
351  /* Resume the thread if asked */
352  if (!(dwCreationFlags & CREATE_SUSPENDED))
353  NtResumeThread(hThread, &Dummy);
354 
355  /* Return handle to thread */
356  return hThread;
357 }
358 
359 /*
360  * @implemented
361  */
362 VOID
363 WINAPI
364 ExitThread(IN DWORD uExitCode)
365 {
368  PRTL_CRITICAL_SECTION LoaderLock;
369 
370  /* Make sure loader lock isn't held */
371  LoaderLock = NtCurrentPeb()->LoaderLock;
372  if (LoaderLock) ASSERT(NtCurrentTeb()->ClientId.UniqueThread != LoaderLock->OwningThread);
373 
374  /*
375  * Terminate process if this is the last thread
376  * of the current process
377  */
380  &LastThread,
381  sizeof(LastThread),
382  NULL);
383  if ((NT_SUCCESS(Status)) && (LastThread)) ExitProcess(uExitCode);
384 
385  /* Notify DLLs and TLS Callbacks of termination */
387 
388  /* Tell the Kernel to free the Stack */
389  NtCurrentTeb()->FreeStackOnTermination = TRUE;
390  NtTerminateThread(NULL, uExitCode);
391 
392  /* We should never reach this place */
393  ERROR_FATAL("It should not happen\n");
394  while (TRUE); /* 'noreturn' function */
395 }
396 
397 /*
398  * @implemented
399  */
400 HANDLE
401 WINAPI
402 OpenThread(IN DWORD dwDesiredAccess,
405 {
407  HANDLE ThreadHandle;
410 
413 
415  NULL,
416  (bInheritHandle ? OBJ_INHERIT : 0),
417  NULL,
418  NULL);
419 
420  Status = NtOpenThread(&ThreadHandle,
421  dwDesiredAccess,
423  &ClientId);
424  if (!NT_SUCCESS(Status))
425  {
427  return NULL;
428  }
429 
430  return ThreadHandle;
431 }
432 
433 /*
434  * @implemented
435  */
436 PTEB
438 {
439  return NtCurrentTeb();
440 }
441 
442 /*
443  * @implemented
444  */
445 BOOL
446 WINAPI
448 {
450 }
451 
452 
453 /*
454  * @implemented
455  */
456 DWORD
457 WINAPI
459 {
461 }
462 
463 /*
464  * @implemented
465  */
466 BOOL
467 NTAPI
469  OUT LPFILETIME lpCreationTime,
470  OUT LPFILETIME lpExitTime,
471  OUT LPFILETIME lpKernelTime,
472  OUT LPFILETIME lpUserTime)
473 {
474  KERNEL_USER_TIMES KernelUserTimes;
476 
478  ThreadTimes,
479  &KernelUserTimes,
480  sizeof(KERNEL_USER_TIMES),
481  NULL);
482  if (!NT_SUCCESS(Status))
483  {
485  return FALSE;
486  }
487 
488  *lpCreationTime = *(LPFILETIME)&KernelUserTimes.CreateTime;
489  *lpExitTime = *(LPFILETIME)&KernelUserTimes.ExitTime;
490  *lpKernelTime = *(LPFILETIME)&KernelUserTimes.KernelTime;
491  *lpUserTime = *(LPFILETIME)&KernelUserTimes.UserTime;
492  return TRUE;
493 }
494 
495 /*
496  * @implemented
497  */
498 BOOL
499 WINAPI
501  OUT LPCONTEXT lpContext)
502 {
504 
505  Status = NtGetContextThread(hThread, lpContext);
506  if (!NT_SUCCESS(Status))
507  {
509  return FALSE;
510  }
511 
512  return TRUE;
513 }
514 
515 /*
516  * @implemented
517  */
518 BOOL
519 WINAPI
521  IN CONST CONTEXT *lpContext)
522 {
524 
525  Status = NtSetContextThread(hThread, (PCONTEXT)lpContext);
526  if (!NT_SUCCESS(Status))
527  {
529  return FALSE;
530  }
531 
532  return TRUE;
533 }
534 
535 /*
536  * @implemented
537  */
538 BOOL
539 WINAPI
541  OUT LPDWORD lpExitCode)
542 {
543  THREAD_BASIC_INFORMATION ThreadBasic;
545 
548  &ThreadBasic,
549  sizeof(THREAD_BASIC_INFORMATION),
550  NULL);
551  if (!NT_SUCCESS(Status))
552  {
554  return FALSE;
555  }
556 
557  *lpExitCode = ThreadBasic.ExitStatus;
558  return TRUE;
559 }
560 
561 /*
562  * @implemented
563  */
564 DWORD
565 WINAPI
567 {
568  ULONG PreviousResumeCount;
570 
571  Status = NtResumeThread(hThread, &PreviousResumeCount);
572  if (!NT_SUCCESS(Status))
573  {
575  return -1;
576  }
577 
578  return PreviousResumeCount;
579 }
580 
581 /*
582  * @implemented
583  */
584 BOOL
585 WINAPI
587  IN DWORD dwExitCode)
588 {
590 #if DBG
591  PRTL_CRITICAL_SECTION LoaderLock;
593 #endif /* DBG */
594 
595  /* Check for invalid thread handle */
596  if (!hThread)
597  {
598  /* Fail if one was passed */
600  return FALSE;
601  }
602 
603 #if DBG
604  /* Get the loader lock */
605  LoaderLock = NtCurrentPeb()->LoaderLock;
606  if (LoaderLock)
607  {
608  /* Get our TID */
611  &ThreadInfo,
612  sizeof(ThreadInfo),
613  NULL);
614  if (NT_SUCCESS(Status))
615  {
616  /* If terminating the current thread, we must not hold the loader lock */
617  if (NtCurrentTeb()->ClientId.UniqueThread == ThreadInfo.ClientId.UniqueThread)
619  }
620  }
621 #endif /* DBG */
622 
623  /* Now terminate the thread */
624  Status = NtTerminateThread(hThread, dwExitCode);
625  if (!NT_SUCCESS(Status))
626  {
627  /* Fail */
629  return FALSE;
630  }
631 
632  /* All done */
633  return TRUE;
634 }
635 
636 /*
637  * @implemented
638  */
639 DWORD
640 WINAPI
642 {
643  ULONG PreviousSuspendCount;
645 
646  Status = NtSuspendThread(hThread, &PreviousSuspendCount);
647  if (!NT_SUCCESS(Status))
648  {
650  return -1;
651  }
652 
653  return PreviousSuspendCount;
654 }
655 
656 /*
657  * @implemented
658  */
659 DWORD_PTR
660 WINAPI
662  IN DWORD_PTR dwThreadAffinityMask)
663 {
664  THREAD_BASIC_INFORMATION ThreadBasic;
665  KAFFINITY AffinityMask;
667 
668  AffinityMask = (KAFFINITY)dwThreadAffinityMask;
669 
672  &ThreadBasic,
673  sizeof(THREAD_BASIC_INFORMATION),
674  NULL);
675  if (!NT_SUCCESS(Status))
676  {
678  return 0;
679  }
680 
683  &AffinityMask,
684  sizeof(KAFFINITY));
685  if (!NT_SUCCESS(Status))
686  {
688  ThreadBasic.AffinityMask = 0;
689  }
690 
691  return ThreadBasic.AffinityMask;
692 }
693 
694 /*
695  * @implemented
696  */
697 BOOL
698 WINAPI
700  IN int nPriority)
701 {
702  LONG Prio = nPriority;
704 
705  /* Check if values forcing saturation should be used */
706  if (Prio == THREAD_PRIORITY_TIME_CRITICAL)
707  {
708  /* This is 16 */
709  Prio = (HIGH_PRIORITY + 1) / 2;
710  }
711  else if (Prio == THREAD_PRIORITY_IDLE)
712  {
713  /* This is -16 */
714  Prio = -((HIGH_PRIORITY + 1) / 2);
715  }
716 
717  /* Set the Base Priority */
720  &Prio,
721  sizeof(LONG));
722  if (!NT_SUCCESS(Status))
723  {
724  /* Failure */
726  return FALSE;
727  }
728 
729  /* Return */
730  return TRUE;
731 }
732 
733 /*
734  * @implemented
735  */
736 int
737 WINAPI
739 {
740  THREAD_BASIC_INFORMATION ThreadBasic;
742 
743  /* Query the Base Priority Increment */
746  &ThreadBasic,
747  sizeof(THREAD_BASIC_INFORMATION),
748  NULL);
749  if (!NT_SUCCESS(Status))
750  {
751  /* Failure */
754  }
755 
756  /* Do some conversions for saturation values */
757  if (ThreadBasic.BasePriority == ((HIGH_PRIORITY + 1) / 2))
758  {
759  /* Win32 calls this "time critical" */
761  }
762  else if (ThreadBasic.BasePriority == -((HIGH_PRIORITY + 1) / 2))
763  {
764  /* Win32 calls this "idle" */
765  ThreadBasic.BasePriority = THREAD_PRIORITY_IDLE;
766  }
767 
768  /* Return the final result */
769  return ThreadBasic.BasePriority;
770 }
771 
772 /*
773  * @implemented
774  */
775 BOOL
776 WINAPI
778  OUT PBOOL pDisablePriorityBoost)
779 {
782 
785  &PriorityBoost,
786  sizeof(ULONG),
787  NULL);
788  if (!NT_SUCCESS(Status))
789  {
791  return FALSE;
792  }
793 
794  *pDisablePriorityBoost = PriorityBoost;
795  return TRUE;
796 }
797 
798 /*
799  * @implemented
800  */
801 BOOL
802 NTAPI
804  IN BOOL bDisablePriorityBoost)
805 {
808 
809  PriorityBoost = bDisablePriorityBoost != FALSE;
810 
813  &PriorityBoost,
814  sizeof(ULONG));
815  if (!NT_SUCCESS(Status))
816  {
818  return FALSE;
819  }
820 
821  return TRUE;
822 }
823 
824 /*
825  * @implemented
826  */
827 BOOL
828 WINAPI
830  IN DWORD dwSelector,
831  OUT LPLDT_ENTRY lpSelectorEntry)
832 {
833 #ifdef _M_IX86
834  DESCRIPTOR_TABLE_ENTRY DescriptionTableEntry;
836 
837  /* Set the selector and do the query */
838  DescriptionTableEntry.Selector = dwSelector;
841  &DescriptionTableEntry,
842  sizeof(DESCRIPTOR_TABLE_ENTRY),
843  NULL);
844  if (!NT_SUCCESS(Status))
845  {
846  /* Fail */
848  return FALSE;
849  }
850 
851  /* Success, return the selector */
852  *lpSelectorEntry = DescriptionTableEntry.Descriptor;
853  return TRUE;
854 #else
855  DPRINT1("Calling GetThreadSelectorEntry!\n");
856  return FALSE;
857 #endif
858 }
859 
860 /*
861  * @implemented
862  */
863 DWORD
864 WINAPI
866  IN DWORD dwIdealProcessor)
867 {
869 
872  &dwIdealProcessor,
873  sizeof(ULONG));
874  if (!NT_SUCCESS(Status))
875  {
877  return -1;
878  }
879 
880  return (DWORD)Status;
881 }
882 
883 /*
884  * @implemented
885  */
886 DWORD
887 WINAPI
889 {
890  THREAD_BASIC_INFORMATION ThreadBasic;
892 
895  &ThreadBasic,
896  sizeof(THREAD_BASIC_INFORMATION),
897  NULL);
898  if (!NT_SUCCESS(Status))
899  {
901  return 0;
902  }
903 
904  return HandleToUlong(ThreadBasic.ClientId.UniqueProcess);
905 }
906 
907 /*
908  * @implemented
909  */
910 DWORD
911 WINAPI
913 {
914  THREAD_BASIC_INFORMATION ThreadBasic;
916 
919  &ThreadBasic,
920  sizeof(THREAD_BASIC_INFORMATION),
921  NULL);
922  if (!NT_SUCCESS(Status))
923  {
925  return 0;
926  }
927 
928  return HandleToUlong(ThreadBasic.ClientId.UniqueThread);
929 }
930 
931 /*
932  * @unimplemented
933  */
934 LANGID
935 WINAPI
937 {
939  return (LANGID)NtCurrentTeb()->CurrentLocale;
940 }
941 
942 /*
943  * @implemented
944  */
945 DWORD
946 WINAPI
948  IN HANDLE hThread,
950 {
952  ACTIVATION_CONTEXT_BASIC_INFORMATION ActCtxInfo;
953 
954  /* Zero the activation context and query information on it */
955  RtlZeroMemory(&ActCtxInfo, sizeof(ActCtxInfo));
957  NULL,
958  0,
959  ActivationContextBasicInformation,
960  &ActCtxInfo,
961  sizeof(ActCtxInfo),
962  NULL);
963  if (!NT_SUCCESS(Status))
964  {
965  /* Fail due to SxS */
966  DbgPrint("SXS: %s failing because RtlQueryInformationActivationContext()"
967  "returned status %08lx\n", __FUNCTION__, Status);
969  return FALSE;
970  }
971 
972  /* Queue the APC */
975  pfnAPC,
976  (PVOID)dwData,
977  (ActCtxInfo.dwFlags & 1) ?
978  INVALID_ACTIVATION_CONTEXT : ActCtxInfo.hActCtx);
979  if (!NT_SUCCESS(Status))
980  {
982  return FALSE;
983  }
984 
985  /* All good */
986  return TRUE;
987 }
988 
989 /*
990  * @unimplemented
991  */
992 BOOL
993 WINAPI
995 {
996  PTEB Teb = NtCurrentTeb();
997  ULONG GuaranteedStackBytes;
999 
1000  if (!StackSizeInBytes)
1001  {
1003  return FALSE;
1004  }
1005 
1006  AllocationSize = *StackSizeInBytes;
1007 
1008  /* Retrieve the current stack size */
1009  GuaranteedStackBytes = Teb->GuaranteedStackBytes;
1010 
1011  /* Return the size of the previous stack */
1012  *StackSizeInBytes = GuaranteedStackBytes;
1013 
1014  /*
1015  * If the new stack size is either zero or is less than the current size,
1016  * the previous stack size is returned and we return success.
1017  */
1018  if ((AllocationSize == 0) || (AllocationSize < GuaranteedStackBytes))
1019  {
1020  return TRUE;
1021  }
1022 
1023  // FIXME: Unimplemented!
1025 
1026  // Temporary HACK for supporting applications!
1027  return TRUE; // FALSE;
1028 }
1029 
1030 /*
1031  * @implemented
1032  */
1033 BOOL
1034 WINAPI
1036  OUT PBOOL lpIOIsPending)
1037 {
1038  ULONG IoPending;
1039  NTSTATUS Status;
1040 
1041  /* Query the flag */
1044  &IoPending,
1045  sizeof(IoPending),
1046  NULL);
1047  if (NT_SUCCESS(Status))
1048  {
1049  /* Return the flag */
1050  *lpIOIsPending = IoPending ? TRUE : FALSE;
1051  return TRUE;
1052  }
1053 
1054  /* Fail */
1056  return FALSE;
1057 }
1058 
1059 /*
1060  * @implemented
1061  */
1062 BOOL
1063 WINAPI
1065  IN PVOID Context,
1066  IN ULONG Flags)
1067 {
1068  NTSTATUS Status;
1069 
1070  /* NOTE: Rtl needs to safely call the function using a trampoline */
1072  if (!NT_SUCCESS(Status))
1073  {
1074  /* Failed */
1076  return FALSE;
1077  }
1078 
1079  /* All good */
1080  return TRUE;
1081 }
1082 
1083 /*
1084  * @implemented
1085  */
1086 DWORD
1087 WINAPI
1089 {
1090  ULONG Index;
1091  PTEB Teb;
1092  PPEB Peb;
1093 
1094  /* Get the PEB and TEB, lock the PEB */
1095  Teb = NtCurrentTeb();
1098 
1099  /* Try to get regular TEB slot */
1101  if (Index != 0xFFFFFFFF)
1102  {
1103  /* Clear the value. */
1104  Teb->TlsSlots[Index] = 0;
1106  return Index;
1107  }
1108 
1109  /* If it fails, try to find expansion TEB slot. */
1111  if (Index != 0xFFFFFFFF)
1112  {
1113  /* Is there no expansion slot yet? */
1114  if (!Teb->TlsExpansionSlots)
1115  {
1116  /* Allocate an array */
1117  Teb->TlsExpansionSlots = RtlAllocateHeap(RtlGetProcessHeap(),
1120  sizeof(PVOID));
1121  }
1122 
1123  /* Did we get an array? */
1124  if (!Teb->TlsExpansionSlots)
1125  {
1126  /* Fail */
1128  Index = 0xFFFFFFFF;
1130  }
1131  else
1132  {
1133  /* Clear the value. */
1134  Teb->TlsExpansionSlots[Index] = 0;
1136  }
1137  }
1138  else
1139  {
1140  /* Fail */
1142  }
1143 
1144  /* Release the lock and return */
1146  return Index;
1147 }
1148 
1149 /*
1150  * @implemented
1151  */
1152 BOOL
1153 WINAPI
1155 {
1156  BOOL BitSet;
1157  PPEB Peb;
1158  ULONG TlsIndex;
1159  PVOID TlsBitmap;
1160  NTSTATUS Status;
1161 
1162  /* Acquire the PEB lock and grab the PEB */
1163  Peb = NtCurrentPeb();
1165 
1166  /* Check if the index is too high */
1168  {
1169  /* Check if it can fit in the expansion slots */
1172  {
1173  /* It's invalid */
1176  return FALSE;
1177  }
1178  else
1179  {
1180  /* Use the expansion bitmap */
1181  TlsBitmap = Peb->TlsExpansionBitmap;
1182  Index = TlsIndex;
1183  }
1184  }
1185  else
1186  {
1187  /* Use the normal bitmap */
1188  TlsBitmap = Peb->TlsBitmap;
1189  }
1190 
1191  /* Check if the index was set */
1192  BitSet = RtlAreBitsSet(TlsBitmap, Index, 1);
1193  if (BitSet)
1194  {
1195  /* Tell the kernel to free the TLS cells */
1198  &Index,
1199  sizeof(DWORD));
1200  if (!NT_SUCCESS(Status))
1201  {
1204  return FALSE;
1205  }
1206 
1207  /* Clear the bit */
1208  RtlClearBits(TlsBitmap, Index, 1);
1209  }
1210  else
1211  {
1212  /* Fail */
1215  return FALSE;
1216  }
1217 
1218  /* Done! */
1220  return TRUE;
1221 }
1222 
1223 /*
1224  * @implemented
1225  */
1226 LPVOID
1227 WINAPI
1229 {
1230  PTEB Teb;
1231 
1232  /* Get the TEB and clear the last error */
1233  Teb = NtCurrentTeb();
1234  Teb->LastErrorValue = 0;
1235 
1236  /* Check for simple TLS index */
1238  {
1239  /* Return it */
1240  return Teb->TlsSlots[Index];
1241  }
1242 
1243  /* Check for valid index */
1245  {
1246  /* Fail */
1248  return NULL;
1249  }
1250 
1251  /* The expansion slots are allocated on demand, so check for it. */
1252  Teb->LastErrorValue = 0;
1253  if (!Teb->TlsExpansionSlots) return NULL;
1254 
1255  /* Return the value from the expansion slots */
1257 }
1258 
1259 /*
1260  * @implemented
1261  */
1262 BOOL
1263 WINAPI
1265  IN LPVOID Value)
1266 {
1267  DWORD TlsIndex;
1268  PTEB Teb = NtCurrentTeb();
1269 
1270  /* Check for simple TLS index */
1272  {
1273  /* Return it */
1274  Teb->TlsSlots[Index] = Value;
1275  return TRUE;
1276  }
1277 
1278  /* Check if this is an expansion slot */
1281  {
1282  /* Fail */
1284  return FALSE;
1285  }
1286 
1287  /* Do we not have expansion slots? */
1288  if (!Teb->TlsExpansionSlots)
1289  {
1290  /* Get the PEB lock to see if we still need them */
1292  if (!Teb->TlsExpansionSlots)
1293  {
1294  /* Allocate them */
1295  Teb->TlsExpansionSlots = RtlAllocateHeap(RtlGetProcessHeap(),
1298  sizeof(PVOID));
1299  if (!Teb->TlsExpansionSlots)
1300  {
1301  /* Fail */
1304  return FALSE;
1305  }
1306  }
1307 
1308  /* Release the lock */
1310  }
1311 
1312  /* Write the value */
1314 
1315  /* Success */
1316  return TRUE;
1317 }
1318 
1319 /* EOF */
PRTL_BITMAP TlsExpansionBitmap
Definition: winternl.h:346
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
LANGID WINAPI SetThreadUILanguage(IN LANGID LangId)
Definition: thread.c:936
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define UNIMPLEMENTED_ONCE
Definition: debug.h:138
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
NTSTATUS WINAPI BaseCreateStack(_In_ HANDLE hProcess, _In_opt_ SIZE_T StackCommit, _In_opt_ SIZE_T StackReserve, _Out_ PINITIAL_TEB InitialTeb)
Definition: utils.c:354
BASE_CREATE_THREAD CreateThreadRequest
Definition: basemsg.h:284
#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:513
BOOL NTAPI GetThreadTimes(IN HANDLE hThread, OUT LPFILETIME lpCreationTime, OUT LPFILETIME lpExitTime, OUT LPFILETIME lpKernelTime, OUT LPFILETIME lpUserTime)
Definition: thread.c:468
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
BOOL WINAPI SwitchToThread(VOID)
Definition: thread.c:447
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:520
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:337
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:586
KAFFINITY AffinityMask
Definition: compat.h:587
#define DbgPrint
Definition: loader.c:25
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
Definition: thread.c:1264
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5272
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
NTSTATUS NTAPI CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength)
Definition: connect.c:365
#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:53
static HANDLE ULONG_PTR dwData
Definition: file.c:35
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
_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:912
struct _ThreadInfo ThreadInfo
WORD LANGID
Definition: typedefs.h:79
BOOL WINAPI GetThreadIOPendingFlag(IN HANDLE hThread, OUT PBOOL lpIOIsPending)
Definition: thread.c:1035
NTSTATUS NTAPI NtSuspendThread(IN HANDLE ThreadHandle, OUT PULONG PreviousSuspendCount OPTIONAL)
Definition: state.c:352
HANDLE UniqueProcess
Definition: compat.h:482
#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:600
KPRIORITY BasePriority
Definition: compat.h:589
_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:540
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:500
_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:947
NTSTATUS Status
Definition: csrmsg.h:112
#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
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
BOOL NTAPI SetThreadPriorityBoost(IN HANDLE hThread, IN BOOL bDisablePriorityBoost)
Definition: thread.c:803
LONG WINAPI UnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: except.c:262
_In_ CCHAR PriorityBoost
Definition: iofuncs.h:763
#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:136
smooth NULL
Definition: ftsmooth.c:416
DWORD_PTR WINAPI SetThreadAffinityMask(IN HANDLE hThread, IN DWORD_PTR dwThreadAffinityMask)
Definition: thread.c:661
PVOID StackBase
Definition: pstypes.h:678
void DPRINT(...)
Definition: polytest.cpp:61
HANDLE ThreadHandle
Definition: basemsg.h:104
BOOL WINAPI GetThreadPriorityBoost(IN HANDLE hThread, OUT PBOOL pDisablePriorityBoost)
Definition: thread.c:777
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:364
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:2014
BOOL * PBOOL
Definition: windef.h:161
#define HIGH_PRIORITY
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:458
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:699
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
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
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
BOOLEAN BaseRunningInServerProcess
Definition: dllmain.c:20
union _BASE_API_MESSAGE::@3411 Data
#define BASESRV_SERVERDLL_INDEX
Definition: basemsg.h:15
BOOL WINAPI TlsFree(IN DWORD Index)
Definition: thread.c:1154
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI BaseDispatchApc(IN PAPCFUNC ApcRoutine, IN PVOID Data, IN PACTIVATION_CONTEXT ActivationContext)
Definition: thread.c:91
NTSTATUS NTAPI NtYieldExecution(VOID)
Definition: thrdschd.c:744
LARGE_INTEGER CreateTime
Definition: winternl.h:1060
CLIENT_ID ClientId
Definition: basemsg.h:105
#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
#define WINAPI
Definition: msvc.h:6
BOOL WINAPI SetThreadStackGuarantee(IN OUT PULONG StackSizeInBytes)
Definition: thread.c:994
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID WINAPI BaseFreeThreadStack(_In_ HANDLE hProcess, _In_ PINITIAL_TEB InitialTeb)
Definition: utils.c:495
_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:5939
#define SetLastError(x)
Definition: compat.h:417
DWORD WINAPI SetThreadIdealProcessor(IN HANDLE hThread, IN DWORD dwIdealProcessor)
Definition: thread.c:865
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2497
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
HANDLE UniqueThread
Definition: compat.h:483
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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
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:641
LPVOID lpParameter
Definition: kernel32.h:241
HANDLE WINAPI OpenThread(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwThreadId)
Definition: thread.c:402
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1088
PTEB GetTeb(VOID)
Definition: thread.c:437
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define TlsIndex
Definition: ws2_32p.h:277
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:436
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:310
ULONG_PTR SIZE_T
Definition: typedefs.h:78
Definition: compat.h:492
NTSTATUS WINAPI BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, IN PCLIENT_ID ClientId)
Definition: thread.c:25
_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:888
#define NtCurrentPeb()
Definition: FLS.c:20
ULONG_PTR KAFFINITY
Definition: compat.h:75
BOOL WINAPI GetThreadSelectorEntry(IN HANDLE hThread, IN DWORD dwSelector, OUT LPLDT_ENTRY lpSelectorEntry)
Definition: thread.c:829
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:5443
#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:19
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1228
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5862
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:5296
#define OUT
Definition: typedefs.h:39
NTSTATUS NTAPI RtlAllocateActivationContextStack(IN PACTIVATION_CONTEXT_STACK *Stack)
Definition: actctx.c:5834
uint32_t * LPDWORD
Definition: typedefs.h:57
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:566
ULONG LastErrorValue
Definition: compat.h:500
struct tagContext Context
Definition: acpixf.h:1030
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:418
PVOID TlsSlots[64]
Definition: compat.h:536
PVOID * TlsExpansionSlots
Definition: compat.h:551
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
PVOID ActivationContextStackPointer
Definition: compat.h:511
#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:1078
return STATUS_SUCCESS
Definition: btrfs.c:2938
PVOID TlsBitmap
Definition: ntddk_ex.h:259
#define __FUNCTION__
Definition: types.h:112
LARGE_INTEGER KernelTime
Definition: winternl.h:1062
int WINAPI GetThreadPriority(IN HANDLE hThread)
Definition: thread.c:738
#define CONST
Definition: pedump.c:81
NTSTATUS NTAPI NtGetContextThread(IN HANDLE ThreadHandle, IN OUT PCONTEXT ThreadContext)
Definition: debug.c:334
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
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
VOID NTAPI RtlFreeActivationContextStack(IN PACTIVATION_CONTEXT_STACK Stack)
Definition: actctx.c:5368