ReactOS  0.4.15-dev-4872-g8a3db97
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 
54 VOID
55 WINAPI
57  _In_ LPTHREAD_START_ROUTINE lpStartAddress,
58  _In_ LPVOID lpParameter)
59 {
60  /* Attempt to call the Thread Start Address */
61  _SEH2_TRY
62  {
63  /* Legacy check which is still used today for Win32 threads */
64  if (NtCurrentTeb()->NtTib.Version == (30 << 8)) // OS/2 V3.0 ("Cruiser")
65  {
66  /* This registers the termination port with CSRSS */
68  }
69 
70  /* Get the exit code from the Thread Start */
71  ExitThread(lpStartAddress(lpParameter));
72  }
74  {
75  /* Get the Exit code from the SEH Handler */
77  {
78  /* Kill the whole process, usually */
80  }
81  else
82  {
83  /* If running inside CSRSS, kill just this thread */
85  }
86  }
87  _SEH2_END;
88 }
89 
90 VOID
91 NTAPI
93  IN PVOID Data,
94  IN PACTIVATION_CONTEXT ActivationContext)
95 {
96  RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActivationFrame;
97 
98  /* Setup the activation context */
99  ActivationFrame.Size = sizeof(ActivationFrame);
101 
102  /* Check if caller wanted one */
103  if (ActivationContext == INVALID_ACTIVATION_CONTEXT)
104  {
105  /* Do the APC directly */
107  return;
108  }
109 
110  /* Then activate it */
111  RtlActivateActivationContextUnsafeFast(&ActivationFrame, ActivationContext);
112 
113  /* Call the routine under SEH */
114  _SEH2_TRY
115  {
117  }
119  {
120 
121  }
122  _SEH2_END;
123 
124  /* Now de-activate and release the activation context */
126  RtlReleaseActivationContext(ActivationContext);
127 }
128 
129 /* PUBLIC FUNCTIONS ***********************************************************/
130 
131 /*
132  * @implemented
133  */
134 HANDLE
135 WINAPI
138  IN DWORD dwStackSize,
139  IN LPTHREAD_START_ROUTINE lpStartAddress,
140  IN LPVOID lpParameter,
141  IN DWORD dwCreationFlags,
142  OUT LPDWORD lpThreadId)
143 {
144  /* Act as if we're going to create a remote thread in ourselves */
146  lpThreadAttributes,
147  dwStackSize,
148  lpStartAddress,
149  lpParameter,
150  dwCreationFlags,
151  lpThreadId);
152 }
153 
154 /*
155  * @implemented
156  */
157 HANDLE
158 WINAPI
160  IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
161  IN DWORD dwStackSize,
162  IN LPTHREAD_START_ROUTINE lpStartAddress,
163  IN LPVOID lpParameter,
164  IN DWORD dwCreationFlags,
165  OUT LPDWORD lpThreadId)
166 {
168  INITIAL_TEB InitialTeb;
171  OBJECT_ATTRIBUTES LocalObjectAttributes;
173  HANDLE hThread;
174  ULONG Dummy;
175  PTEB Teb;
176  THREAD_BASIC_INFORMATION ThreadBasicInfo;
177  PACTIVATION_CONTEXT_STACK ActivationContextStack = NULL;
178  ACTIVATION_CONTEXT_BASIC_INFORMATION ActCtxInfo;
181  SIZE_T ReturnSize;
182 
183  DPRINT("CreateRemoteThread: hProcess: %p dwStackSize: %lu lpStartAddress"
184  ": %p lpParameter: %p, dwCreationFlags: %lx\n", hProcess,
185  dwStackSize, lpStartAddress, lpParameter, dwCreationFlags);
186 
187  /* Clear the Context */
188  RtlZeroMemory(&Context, sizeof(Context));
189 
190  /* Write PID */
192 
193  /* Create the Stack */
195  (dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) ?
196  0 : dwStackSize,
197  (dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) ?
198  dwStackSize : 0,
199  &InitialTeb);
200  if (!NT_SUCCESS(Status))
201  {
203  return NULL;
204  }
205 
206  /* Create the Initial Context */
208  lpParameter,
209  lpStartAddress,
210  InitialTeb.StackBase,
211  1);
212 
213  /* Initialize the attributes for the thread object */
214  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
215  lpThreadAttributes,
216  NULL);
217 
218  /* Create the Kernel Thread Object */
222  hProcess,
223  &ClientId,
224  &Context,
225  &InitialTeb,
226  TRUE);
227  if (!NT_SUCCESS(Status))
228  {
229  /* Fail the kernel create */
230  BaseFreeThreadStack(hProcess, &InitialTeb);
232  return NULL;
233  }
234 
235  /* Are we in the same process? */
236  if (hProcess == NtCurrentProcess())
237  {
238  /* Get the TEB */
241  &ThreadBasicInfo,
242  sizeof(ThreadBasicInfo),
243  &ReturnLength);
244  if (!NT_SUCCESS(Status))
245  {
246  /* Fail */
247  DPRINT1("SXS: %s - Failing thread create because "
248  "NtQueryInformationThread() failed with status %08lx\n",
250  goto Quit;
251  }
252 
253  /* Allocate the Activation Context Stack */
254  Status = RtlAllocateActivationContextStack(&ActivationContextStack);
255  if (!NT_SUCCESS(Status))
256  {
257  /* Fail */
258  DPRINT1("SXS: %s - Failing thread create because "
259  "RtlAllocateActivationContextStack() failed with status %08lx\n",
261  goto Quit;
262  }
263 
264  /* Save it */
265  Teb = ThreadBasicInfo.TebBaseAddress;
266  Teb->ActivationContextStackPointer = ActivationContextStack;
267 
268  /* Query the Context */
270  NULL,
271  0,
272  ActivationContextBasicInformation,
273  &ActCtxInfo,
274  sizeof(ActCtxInfo),
275  &ReturnSize);
276  if (!NT_SUCCESS(Status))
277  {
278  /* Fail */
279  DPRINT1("SXS: %s - Failing thread create because "
280  "RtlQueryInformationActivationContext() failed with status %08lx\n",
282  goto Quit;
283  }
284 
285  /* Does it need to be activated? */
286  if ((ActCtxInfo.hActCtx) && !(ActCtxInfo.dwFlags & 1))
287  {
288  /* Activate it */
290  Teb,
291  ActCtxInfo.hActCtx,
292  &Cookie);
293  if (!NT_SUCCESS(Status))
294  {
295  /* Fail */
296  DPRINT1("SXS: %s - Failing thread create because "
297  "RtlActivateActivationContextEx() failed with status %08lx\n",
299  goto Quit;
300  }
301  }
302 
303  /* Sync the service tag with the parent thread's one */
304  Teb->SubProcessTag = NtCurrentTeb()->SubProcessTag;
305  }
306 
307  /* Notify CSR */
309  {
311  }
312  else
313  {
314  if (hProcess != NtCurrentProcess())
315  {
317 
318  /* Get the direct CSRSRV export */
321  "CsrCreateRemoteThread");
323  {
324  /* Call it instead of going through LPC */
326  }
327  }
328  }
329 
330 Quit:
331  if (!NT_SUCCESS(Status))
332  {
333  /* Failed to create the thread */
334 
335  /* Free the activation context stack */
336  if (ActivationContextStack)
337  RtlFreeActivationContextStack(ActivationContextStack);
338 
340  // FIXME: Wait for the thread to terminate?
341  BaseFreeThreadStack(hProcess, &InitialTeb);
342  NtClose(hThread);
343 
345  return NULL;
346  }
347 
348  /* Success */
349  if (lpThreadId)
350  *lpThreadId = HandleToUlong(ClientId.UniqueThread);
351 
352  /* Resume the thread if asked */
353  if (!(dwCreationFlags & CREATE_SUSPENDED))
354  NtResumeThread(hThread, &Dummy);
355 
356  /* Return handle to thread */
357  return hThread;
358 }
359 
360 /*
361  * @implemented
362  */
363 VOID
364 WINAPI
365 ExitThread(IN DWORD uExitCode)
366 {
369  PRTL_CRITICAL_SECTION LoaderLock;
370 
371  /* Make sure loader lock isn't held */
372  LoaderLock = NtCurrentPeb()->LoaderLock;
373  if (LoaderLock) ASSERT(NtCurrentTeb()->ClientId.UniqueThread != LoaderLock->OwningThread);
374 
375  /*
376  * Terminate process if this is the last thread
377  * of the current process
378  */
381  &LastThread,
382  sizeof(LastThread),
383  NULL);
384  if ((NT_SUCCESS(Status)) && (LastThread)) ExitProcess(uExitCode);
385 
386  /* Notify DLLs and TLS Callbacks of termination */
388 
389  /* Tell the Kernel to free the Stack */
390  NtCurrentTeb()->FreeStackOnTermination = TRUE;
391  NtTerminateThread(NULL, uExitCode);
392 
393  /* We should never reach this place */
394  ERROR_FATAL("It should not happen\n");
395  while (TRUE); /* 'noreturn' function */
396 }
397 
398 /*
399  * @implemented
400  */
401 HANDLE
402 WINAPI
403 OpenThread(IN DWORD dwDesiredAccess,
406 {
408  HANDLE ThreadHandle;
411 
414 
416  NULL,
417  (bInheritHandle ? OBJ_INHERIT : 0),
418  NULL,
419  NULL);
420 
421  Status = NtOpenThread(&ThreadHandle,
422  dwDesiredAccess,
424  &ClientId);
425  if (!NT_SUCCESS(Status))
426  {
428  return NULL;
429  }
430 
431  return ThreadHandle;
432 }
433 
434 /*
435  * @implemented
436  */
437 PTEB
439 {
440  return NtCurrentTeb();
441 }
442 
443 /*
444  * @implemented
445  */
446 BOOL
447 WINAPI
449 {
451 }
452 
453 
454 /*
455  * @implemented
456  */
457 DWORD
458 WINAPI
460 {
462 }
463 
464 /*
465  * @implemented
466  */
467 BOOL
468 NTAPI
470  OUT LPFILETIME lpCreationTime,
471  OUT LPFILETIME lpExitTime,
472  OUT LPFILETIME lpKernelTime,
473  OUT LPFILETIME lpUserTime)
474 {
475  KERNEL_USER_TIMES KernelUserTimes;
477 
479  ThreadTimes,
480  &KernelUserTimes,
481  sizeof(KERNEL_USER_TIMES),
482  NULL);
483  if (!NT_SUCCESS(Status))
484  {
486  return FALSE;
487  }
488 
489  *lpCreationTime = *(LPFILETIME)&KernelUserTimes.CreateTime;
490  *lpExitTime = *(LPFILETIME)&KernelUserTimes.ExitTime;
491  *lpKernelTime = *(LPFILETIME)&KernelUserTimes.KernelTime;
492  *lpUserTime = *(LPFILETIME)&KernelUserTimes.UserTime;
493  return TRUE;
494 }
495 
496 /*
497  * @implemented
498  */
499 BOOL
500 WINAPI
502  OUT LPCONTEXT lpContext)
503 {
505 
506  Status = NtGetContextThread(hThread, lpContext);
507  if (!NT_SUCCESS(Status))
508  {
510  return FALSE;
511  }
512 
513  return TRUE;
514 }
515 
516 /*
517  * @implemented
518  */
519 BOOL
520 WINAPI
522  IN CONST CONTEXT *lpContext)
523 {
525 
526  Status = NtSetContextThread(hThread, (PCONTEXT)lpContext);
527  if (!NT_SUCCESS(Status))
528  {
530  return FALSE;
531  }
532 
533  return TRUE;
534 }
535 
536 /*
537  * @implemented
538  */
539 BOOL
540 WINAPI
542  OUT LPDWORD lpExitCode)
543 {
544  THREAD_BASIC_INFORMATION ThreadBasic;
546 
549  &ThreadBasic,
550  sizeof(THREAD_BASIC_INFORMATION),
551  NULL);
552  if (!NT_SUCCESS(Status))
553  {
555  return FALSE;
556  }
557 
558  *lpExitCode = ThreadBasic.ExitStatus;
559  return TRUE;
560 }
561 
562 /*
563  * @implemented
564  */
565 DWORD
566 WINAPI
568 {
569  ULONG PreviousResumeCount;
571 
572  Status = NtResumeThread(hThread, &PreviousResumeCount);
573  if (!NT_SUCCESS(Status))
574  {
576  return -1;
577  }
578 
579  return PreviousResumeCount;
580 }
581 
582 /*
583  * @implemented
584  */
585 BOOL
586 WINAPI
588  IN DWORD dwExitCode)
589 {
591 #if DBG
592  PRTL_CRITICAL_SECTION LoaderLock;
594 #endif /* DBG */
595 
596  /* Check for invalid thread handle */
597  if (!hThread)
598  {
599  /* Fail if one was passed */
601  return FALSE;
602  }
603 
604 #if DBG
605  /* Get the loader lock */
606  LoaderLock = NtCurrentPeb()->LoaderLock;
607  if (LoaderLock)
608  {
609  /* Get our TID */
612  &ThreadInfo,
613  sizeof(ThreadInfo),
614  NULL);
615  if (NT_SUCCESS(Status))
616  {
617  /* If terminating the current thread, we must not hold the loader lock */
618  if (NtCurrentTeb()->ClientId.UniqueThread == ThreadInfo.ClientId.UniqueThread)
620  }
621  }
622 #endif /* DBG */
623 
624  /* Now terminate the thread */
625  Status = NtTerminateThread(hThread, dwExitCode);
626  if (!NT_SUCCESS(Status))
627  {
628  /* Fail */
630  return FALSE;
631  }
632 
633  /* All done */
634  return TRUE;
635 }
636 
637 /*
638  * @implemented
639  */
640 DWORD
641 WINAPI
643 {
644  ULONG PreviousSuspendCount;
646 
647  Status = NtSuspendThread(hThread, &PreviousSuspendCount);
648  if (!NT_SUCCESS(Status))
649  {
651  return -1;
652  }
653 
654  return PreviousSuspendCount;
655 }
656 
657 /*
658  * @implemented
659  */
660 DWORD_PTR
661 WINAPI
663  IN DWORD_PTR dwThreadAffinityMask)
664 {
665  THREAD_BASIC_INFORMATION ThreadBasic;
666  KAFFINITY AffinityMask;
668 
669  AffinityMask = (KAFFINITY)dwThreadAffinityMask;
670 
673  &ThreadBasic,
674  sizeof(THREAD_BASIC_INFORMATION),
675  NULL);
676  if (!NT_SUCCESS(Status))
677  {
679  return 0;
680  }
681 
684  &AffinityMask,
685  sizeof(KAFFINITY));
686  if (!NT_SUCCESS(Status))
687  {
689  ThreadBasic.AffinityMask = 0;
690  }
691 
692  return ThreadBasic.AffinityMask;
693 }
694 
695 /*
696  * @implemented
697  */
698 BOOL
699 WINAPI
701  IN int nPriority)
702 {
703  LONG Prio = nPriority;
705 
706  /* Check if values forcing saturation should be used */
707  if (Prio == THREAD_PRIORITY_TIME_CRITICAL)
708  {
709  /* This is 16 */
710  Prio = (HIGH_PRIORITY + 1) / 2;
711  }
712  else if (Prio == THREAD_PRIORITY_IDLE)
713  {
714  /* This is -16 */
715  Prio = -((HIGH_PRIORITY + 1) / 2);
716  }
717 
718  /* Set the Base Priority */
721  &Prio,
722  sizeof(LONG));
723  if (!NT_SUCCESS(Status))
724  {
725  /* Failure */
727  return FALSE;
728  }
729 
730  /* Return */
731  return TRUE;
732 }
733 
734 /*
735  * @implemented
736  */
737 int
738 WINAPI
740 {
741  THREAD_BASIC_INFORMATION ThreadBasic;
743 
744  /* Query the Base Priority Increment */
747  &ThreadBasic,
748  sizeof(THREAD_BASIC_INFORMATION),
749  NULL);
750  if (!NT_SUCCESS(Status))
751  {
752  /* Failure */
755  }
756 
757  /* Do some conversions for saturation values */
758  if (ThreadBasic.BasePriority == ((HIGH_PRIORITY + 1) / 2))
759  {
760  /* Win32 calls this "time critical" */
762  }
763  else if (ThreadBasic.BasePriority == -((HIGH_PRIORITY + 1) / 2))
764  {
765  /* Win32 calls this "idle" */
766  ThreadBasic.BasePriority = THREAD_PRIORITY_IDLE;
767  }
768 
769  /* Return the final result */
770  return ThreadBasic.BasePriority;
771 }
772 
773 /*
774  * @implemented
775  */
776 BOOL
777 WINAPI
779  OUT PBOOL pDisablePriorityBoost)
780 {
783 
786  &PriorityBoost,
787  sizeof(ULONG),
788  NULL);
789  if (!NT_SUCCESS(Status))
790  {
792  return FALSE;
793  }
794 
795  *pDisablePriorityBoost = PriorityBoost;
796  return TRUE;
797 }
798 
799 /*
800  * @implemented
801  */
802 BOOL
803 NTAPI
805  IN BOOL bDisablePriorityBoost)
806 {
809 
810  PriorityBoost = bDisablePriorityBoost != FALSE;
811 
814  &PriorityBoost,
815  sizeof(ULONG));
816  if (!NT_SUCCESS(Status))
817  {
819  return FALSE;
820  }
821 
822  return TRUE;
823 }
824 
825 /*
826  * @implemented
827  */
828 BOOL
829 WINAPI
831  IN DWORD dwSelector,
832  OUT LPLDT_ENTRY lpSelectorEntry)
833 {
834 #ifdef _M_IX86
835  DESCRIPTOR_TABLE_ENTRY DescriptionTableEntry;
837 
838  /* Set the selector and do the query */
839  DescriptionTableEntry.Selector = dwSelector;
842  &DescriptionTableEntry,
843  sizeof(DESCRIPTOR_TABLE_ENTRY),
844  NULL);
845  if (!NT_SUCCESS(Status))
846  {
847  /* Fail */
849  return FALSE;
850  }
851 
852  /* Success, return the selector */
853  *lpSelectorEntry = DescriptionTableEntry.Descriptor;
854  return TRUE;
855 #else
856  DPRINT1("Calling GetThreadSelectorEntry!\n");
857  return FALSE;
858 #endif
859 }
860 
861 /*
862  * @implemented
863  */
864 DWORD
865 WINAPI
867  IN DWORD dwIdealProcessor)
868 {
870 
873  &dwIdealProcessor,
874  sizeof(ULONG));
875  if (!NT_SUCCESS(Status))
876  {
878  return -1;
879  }
880 
881  return (DWORD)Status;
882 }
883 
884 /*
885  * @implemented
886  */
887 DWORD
888 WINAPI
890 {
891  THREAD_BASIC_INFORMATION ThreadBasic;
893 
896  &ThreadBasic,
897  sizeof(THREAD_BASIC_INFORMATION),
898  NULL);
899  if (!NT_SUCCESS(Status))
900  {
902  return 0;
903  }
904 
905  return HandleToUlong(ThreadBasic.ClientId.UniqueProcess);
906 }
907 
908 /*
909  * @implemented
910  */
911 DWORD
912 WINAPI
914 {
915  THREAD_BASIC_INFORMATION ThreadBasic;
917 
920  &ThreadBasic,
921  sizeof(THREAD_BASIC_INFORMATION),
922  NULL);
923  if (!NT_SUCCESS(Status))
924  {
926  return 0;
927  }
928 
929  return HandleToUlong(ThreadBasic.ClientId.UniqueThread);
930 }
931 
932 /*
933  * @unimplemented
934  */
935 LANGID
936 WINAPI
938 {
939 #if (NTDDI_VERSION < NTDDI_LONGHORN)
940  /* We only support LangId == 0, for selecting a language
941  * identifier that best supports the NT Console. */
942  if (LangId != 0)
943  {
945  return 0;
946  }
947 #endif
948 
950 
951  return LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale);
952 }
953 
954 /*
955  * @implemented
956  */
957 DWORD
958 WINAPI
960  IN HANDLE hThread,
962 {
964  ACTIVATION_CONTEXT_BASIC_INFORMATION ActCtxInfo;
965 
966  /* Zero the activation context and query information on it */
967  RtlZeroMemory(&ActCtxInfo, sizeof(ActCtxInfo));
969  NULL,
970  0,
971  ActivationContextBasicInformation,
972  &ActCtxInfo,
973  sizeof(ActCtxInfo),
974  NULL);
975  if (!NT_SUCCESS(Status))
976  {
977  /* Fail due to SxS */
978  DbgPrint("SXS: %s failing because RtlQueryInformationActivationContext()"
979  "returned status %08lx\n", __FUNCTION__, Status);
981  return FALSE;
982  }
983 
984  /* Queue the APC */
987  pfnAPC,
988  (PVOID)dwData,
989  (ActCtxInfo.dwFlags & 1) ?
990  INVALID_ACTIVATION_CONTEXT : ActCtxInfo.hActCtx);
991  if (!NT_SUCCESS(Status))
992  {
994  return FALSE;
995  }
996 
997  /* All good */
998  return TRUE;
999 }
1000 
1001 /*
1002  * @unimplemented
1003  */
1004 BOOL
1005 WINAPI
1007 {
1008  PTEB Teb = NtCurrentTeb();
1009  ULONG GuaranteedStackBytes;
1011 
1012  if (!StackSizeInBytes)
1013  {
1015  return FALSE;
1016  }
1017 
1018  AllocationSize = *StackSizeInBytes;
1019 
1020  /* Retrieve the current stack size */
1021  GuaranteedStackBytes = Teb->GuaranteedStackBytes;
1022 
1023  /* Return the size of the previous stack */
1024  *StackSizeInBytes = GuaranteedStackBytes;
1025 
1026  /*
1027  * If the new stack size is either zero or is less than the current size,
1028  * the previous stack size is returned and we return success.
1029  */
1030  if ((AllocationSize == 0) || (AllocationSize < GuaranteedStackBytes))
1031  {
1032  return TRUE;
1033  }
1034 
1035  // FIXME: Unimplemented!
1037 
1038  // Temporary HACK for supporting applications!
1039  return TRUE; // FALSE;
1040 }
1041 
1042 /*
1043  * @implemented
1044  */
1045 BOOL
1046 WINAPI
1048  OUT PBOOL lpIOIsPending)
1049 {
1050  ULONG IoPending;
1051  NTSTATUS Status;
1052 
1053  /* Query the flag */
1056  &IoPending,
1057  sizeof(IoPending),
1058  NULL);
1059  if (NT_SUCCESS(Status))
1060  {
1061  /* Return the flag */
1062  *lpIOIsPending = IoPending ? TRUE : FALSE;
1063  return TRUE;
1064  }
1065 
1066  /* Fail */
1068  return FALSE;
1069 }
1070 
1071 /*
1072  * @implemented
1073  */
1074 BOOL
1075 WINAPI
1077  IN PVOID Context,
1078  IN ULONG Flags)
1079 {
1080  NTSTATUS Status;
1081 
1082  /* NOTE: Rtl needs to safely call the function using a trampoline */
1084  if (!NT_SUCCESS(Status))
1085  {
1086  /* Failed */
1088  return FALSE;
1089  }
1090 
1091  /* All good */
1092  return TRUE;
1093 }
1094 
1095 /*
1096  * @implemented
1097  */
1098 DWORD
1099 WINAPI
1101 {
1102  ULONG Index;
1103  PTEB Teb;
1104  PPEB Peb;
1105 
1106  /* Get the PEB and TEB, lock the PEB */
1107  Teb = NtCurrentTeb();
1110 
1111  /* Try to get regular TEB slot */
1113  if (Index != 0xFFFFFFFF)
1114  {
1115  /* Clear the value. */
1116  Teb->TlsSlots[Index] = 0;
1118  return Index;
1119  }
1120 
1121  /* If it fails, try to find expansion TEB slot. */
1123  if (Index != 0xFFFFFFFF)
1124  {
1125  /* Is there no expansion slot yet? */
1126  if (!Teb->TlsExpansionSlots)
1127  {
1128  /* Allocate an array */
1129  Teb->TlsExpansionSlots = RtlAllocateHeap(RtlGetProcessHeap(),
1132  sizeof(PVOID));
1133  }
1134 
1135  /* Did we get an array? */
1136  if (!Teb->TlsExpansionSlots)
1137  {
1138  /* Fail */
1140  Index = 0xFFFFFFFF;
1142  }
1143  else
1144  {
1145  /* Clear the value. */
1146  Teb->TlsExpansionSlots[Index] = 0;
1148  }
1149  }
1150  else
1151  {
1152  /* Fail */
1154  }
1155 
1156  /* Release the lock and return */
1158  return Index;
1159 }
1160 
1161 /*
1162  * @implemented
1163  */
1164 BOOL
1165 WINAPI
1167 {
1168  BOOL BitSet;
1169  PPEB Peb;
1170  ULONG TlsIndex;
1171  PVOID TlsBitmap;
1172  NTSTATUS Status;
1173 
1174  /* Acquire the PEB lock and grab the PEB */
1175  Peb = NtCurrentPeb();
1177 
1178  /* Check if the index is too high */
1180  {
1181  /* Check if it can fit in the expansion slots */
1184  {
1185  /* It's invalid */
1188  return FALSE;
1189  }
1190  else
1191  {
1192  /* Use the expansion bitmap */
1193  TlsBitmap = Peb->TlsExpansionBitmap;
1194  Index = TlsIndex;
1195  }
1196  }
1197  else
1198  {
1199  /* Use the normal bitmap */
1200  TlsBitmap = Peb->TlsBitmap;
1201  }
1202 
1203  /* Check if the index was set */
1204  BitSet = RtlAreBitsSet(TlsBitmap, Index, 1);
1205  if (BitSet)
1206  {
1207  /* Tell the kernel to free the TLS cells */
1210  &Index,
1211  sizeof(DWORD));
1212  if (!NT_SUCCESS(Status))
1213  {
1216  return FALSE;
1217  }
1218 
1219  /* Clear the bit */
1220  RtlClearBits(TlsBitmap, Index, 1);
1221  }
1222  else
1223  {
1224  /* Fail */
1227  return FALSE;
1228  }
1229 
1230  /* Done! */
1232  return TRUE;
1233 }
1234 
1235 /*
1236  * @implemented
1237  */
1238 LPVOID
1239 WINAPI
1241 {
1242  PTEB Teb;
1243 
1244  /* Get the TEB and clear the last error */
1245  Teb = NtCurrentTeb();
1246  Teb->LastErrorValue = 0;
1247 
1248  /* Check for simple TLS index */
1250  {
1251  /* Return it */
1252  return Teb->TlsSlots[Index];
1253  }
1254 
1255  /* Check for valid index */
1257  {
1258  /* Fail */
1260  return NULL;
1261  }
1262 
1263  /* The expansion slots are allocated on demand, so check for it. */
1264  Teb->LastErrorValue = 0;
1265  if (!Teb->TlsExpansionSlots) return NULL;
1266 
1267  /* Return the value from the expansion slots */
1269 }
1270 
1271 /*
1272  * @implemented
1273  */
1274 BOOL
1275 WINAPI
1277  IN LPVOID Value)
1278 {
1279  DWORD TlsIndex;
1280  PTEB Teb = NtCurrentTeb();
1281 
1282  /* Check for simple TLS index */
1284  {
1285  /* Return it */
1286  Teb->TlsSlots[Index] = Value;
1287  return TRUE;
1288  }
1289 
1290  /* Check if this is an expansion slot */
1293  {
1294  /* Fail */
1296  return FALSE;
1297  }
1298 
1299  /* Do we not have expansion slots? */
1300  if (!Teb->TlsExpansionSlots)
1301  {
1302  /* Get the PEB lock to see if we still need them */
1304  if (!Teb->TlsExpansionSlots)
1305  {
1306  /* Allocate them */
1307  Teb->TlsExpansionSlots = RtlAllocateHeap(RtlGetProcessHeap(),
1310  sizeof(PVOID));
1311  if (!Teb->TlsExpansionSlots)
1312  {
1313  /* Fail */
1316  return FALSE;
1317  }
1318  }
1319 
1320  /* Release the lock */
1322  }
1323 
1324  /* Write the value */
1326 
1327  /* Success */
1328  return TRUE;
1329 }
1330 
1331 /* EOF */
PRTL_BITMAP TlsExpansionBitmap
Definition: winternl.h:346
LANGID WINAPI SetThreadUILanguage(IN LANGID LangId)
Definition: thread.c:937
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
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:39
return STATUS_NOT_SUPPORTED
#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:469
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
BOOL WINAPI SwitchToThread(VOID)
Definition: thread.c:448
DWORD(WINAPI * LPTHREAD_START_ROUTINE)(LPVOID)
Definition: winbase.h:726
BOOL WINAPI SetThreadContext(IN HANDLE hThread, IN CONST CONTEXT *lpContext)
Definition: thread.c:521
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
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:587
KAFFINITY AffinityMask
Definition: compat.h:789
#define DbgPrint
Definition: hal.h:12
union _BASE_API_MESSAGE::@3485 Data
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
Definition: thread.c:1276
struct _FILETIME * LPFILETIME
Definition: time.c:29
#define TRUE
Definition: types.h:120
#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:310
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:98
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)
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:913
struct _ThreadInfo ThreadInfo
WORD LANGID
Definition: typedefs.h:81
BOOL WINAPI GetThreadIOPendingFlag(IN HANDLE hThread, OUT PBOOL lpIOIsPending)
Definition: thread.c:1047
NTSTATUS NTAPI NtSuspendThread(IN HANDLE ThreadHandle, OUT PULONG PreviousSuspendCount OPTIONAL)
Definition: state.c:352
HANDLE UniqueProcess
Definition: compat.h:684
#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
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5515
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
KPRIORITY BasePriority
Definition: compat.h:791
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
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:541
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:501
DWORD WINAPI QueueUserAPC(IN PAPCFUNC pfnAPC, IN HANDLE hThread, IN ULONG_PTR dwData)
Definition: thread.c:959
NTSTATUS Status
Definition: csrmsg.h:110
#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
#define FALSE
Definition: types.h:117
_In_ WDFREQUEST _In_ NTSTATUS _In_ CCHAR PriorityBoost
Definition: wdfrequest.h:1011
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:804
LONG WINAPI UnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: except.c:269
DECLSPEC_NORETURN VOID WINAPI BaseThreadStartup(_In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_ LPVOID lpParameter)
Definition: thread.c:56
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
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:137
DWORD_PTR WINAPI SetThreadAffinityMask(IN HANDLE hThread, IN DWORD_PTR dwThreadAffinityMask)
Definition: thread.c:662
#define _In_
Definition: ms_sal.h:308
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
PVOID StackBase
Definition: pstypes.h:694
HANDLE ThreadHandle
Definition: basemsg.h:104
BOOL WINAPI GetThreadPriorityBoost(IN HANDLE hThread, OUT PBOOL pDisablePriorityBoost)
Definition: thread.c:778
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
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:2018
BOOL * PBOOL
Definition: windef.h:161
#define HIGH_PRIORITY
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:459
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
#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
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:243
Status
Definition: gdiplustypes.h:24
ULONG GuaranteedStackBytes
Definition: winternl.h:279
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1282
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1165
BOOLEAN BaseRunningInServerProcess
Definition: dllmain.c:20
#define ASSERT(a)
Definition: mode.c:44
#define BASESRV_SERVERDLL_INDEX
Definition: basemsg.h:15
BOOL WINAPI TlsFree(IN DWORD Index)
Definition: thread.c:1166
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI BaseDispatchApc(IN PAPCFUNC ApcRoutine, IN PVOID Data, IN PACTIVATION_CONTEXT ActivationContext)
Definition: thread.c:92
#define OBJ_INHERIT
Definition: winternl.h:225
NTSTATUS NTAPI NtYieldExecution(VOID)
Definition: thrdschd.c:744
_In_ WDFCOLLECTION _In_ ULONG Index
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
LARGE_INTEGER CreateTime
Definition: winternl.h:1060
CLIENT_ID ClientId
Definition: basemsg.h:105
#define STACK_SIZE_PARAM_IS_A_RESERVATION
Definition: winbase.h:574
_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:1006
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:2652
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:6011
#define SetLastError(x)
Definition: compat.h:611
DWORD WINAPI SetThreadIdealProcessor(IN HANDLE hThread, IN DWORD dwIdealProcessor)
Definition: thread.c:866
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2624
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
HANDLE UniqueThread
Definition: compat.h:685
BOOL WINAPI QueueUserWorkItem(IN LPTHREAD_START_ROUTINE Function, IN PVOID Context, IN ULONG Flags)
Definition: thread.c:1076
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:278
NTSTATUS NTAPI CsrCreateRemoteThread(IN HANDLE hThread, IN PCLIENT_ID ClientId)
Definition: thredsup.c:569
DWORD dwThreadId
Definition: fdebug.c:31
#define THREAD_PRIORITY_IDLE
Definition: winbase.h:275
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:642
PVOID TlsBitmap
Definition: ntddk_ex.h:259
HANDLE WINAPI OpenThread(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwThreadId)
Definition: thread.c:403
#define LANGIDFROMLCID(l)
Definition: nls.h:18
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1100
PTEB GetTeb(VOID)
Definition: thread.c:438
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5344
uint32_t DWORD_PTR
Definition: typedefs.h:65
#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
NTSTATUS NTAPI CsrNewThread(VOID)
Definition: api.c:27
PETHREAD LastThread
Definition: pinsup.c:109
Definition: compat.h:636
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:319
ULONG_PTR SIZE_T
Definition: typedefs.h:80
Definition: compat.h:694
NTSTATUS WINAPI BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, IN PCLIENT_ID ClientId)
Definition: thread.c:25
_SEH2_END
Definition: create.c:4400
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
DWORD WINAPI GetProcessIdOfThread(IN HANDLE Thread)
Definition: thread.c:889
#define NtCurrentPeb()
Definition: FLS.c:22
ULONG_PTR KAFFINITY
Definition: compat.h:85
BOOL WINAPI GetThreadSelectorEntry(IN HANDLE hThread, IN DWORD dwSelector, OUT LPLDT_ENTRY lpSelectorEntry)
Definition: thread.c:830
NTSTATUS NTAPI NtSetContextThread(IN HANDLE ThreadHandle, IN PCONTEXT ThreadContext)
Definition: debug.c:387
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
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
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
HANDLE hThread
Definition: wizard.c:28
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:1240
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5934
VOID(NTAPI * WORKERCALLBACKFUNC)(_In_ PVOID Context)
Definition: rtltypes.h:513
NTSTATUS NTAPI RtlActivateActivationContextEx(ULONG flags, PTEB tebAddress, HANDLE handle, PULONG_PTR cookie)
Definition: actctx.c:5368
struct tagContext Context
Definition: acpixf.h:1034
#define OUT
Definition: typedefs.h:40
NTSTATUS NTAPI RtlAllocateActivationContextStack(IN PACTIVATION_CONTEXT_STACK *Stack)
Definition: actctx.c:5906
uint32_t * LPDWORD
Definition: typedefs.h:59
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
ULONG LastErrorValue
Definition: compat.h:702
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define GetProcAddress(x, y)
Definition: compat.h:612
PVOID TlsSlots[64]
Definition: compat.h:738
PVOID * TlsExpansionSlots
Definition: compat.h:753
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
PVOID ActivationContextStackPointer
Definition: compat.h:713
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:684
#define DPRINT
Definition: sndvol32.h:71
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
NTSTATUS NTAPI LdrShutdownThread(VOID)
Definition: ldrinit.c:1078
#define __FUNCTION__
Definition: types.h:112
LARGE_INTEGER KernelTime
Definition: winternl.h:1062
int WINAPI GetThreadPriority(IN HANDLE hThread)
Definition: thread.c:739
#define CONST
Definition: pedump.c:81
NTSTATUS NTAPI NtGetContextThread(IN HANDLE ThreadHandle, IN OUT PCONTEXT ThreadContext)
Definition: debug.c:350
#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:159
NTSYSAPI BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP, ULONG, ULONG)
VOID NTAPI RtlFreeActivationContextStack(IN PACTIVATION_CONTEXT_STACK Stack)
Definition: actctx.c:5440