2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/thread/thread.c
5 * PURPOSE: Thread functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 Tls functions are modified from WINE
13 #include <kernel32/thread.h>
14 #include <ddk/ntddk.h>
21 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
23 LPTHREAD_START_ROUTINE lpStartAddress
,
25 DWORD dwCreationFlags
,
29 return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes
,dwStackSize
,
30 lpStartAddress
,lpParameter
,dwCreationFlags
,lpThreadId
);
40 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
42 LPTHREAD_START_ROUTINE lpStartAddress
,
44 DWORD dwCreationFlags
,
50 OBJECT_ATTRIBUTES ObjectAttributes
;
52 CONTEXT ThreadContext
;
53 INITIAL_TEB InitialTeb
;
54 BOOLEAN CreateSuspended
= FALSE
;
56 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
57 ObjectAttributes
.RootDirectory
= NULL
;
58 ObjectAttributes
.ObjectName
= NULL
;
59 ObjectAttributes
.Attributes
= 0;
60 if ( lpThreadAttributes
!= NULL
) {
61 if ( lpThreadAttributes
->bInheritHandle
)
62 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
63 ObjectAttributes
.SecurityDescriptor
= lpThreadAttributes
->lpSecurityDescriptor
;
65 ObjectAttributes
.SecurityQualityOfService
= NULL
;
67 if ( ( dwCreationFlags
& CREATE_SUSPENDED
) == CREATE_SUSPENDED
)
68 CreateSuspended
= TRUE
;
70 CreateSuspended
= FALSE
;
72 GetThreadContext(NtCurrentThread(),&ThreadContext
);
73 // fix teb [ stack context ] --> check the image file
75 errCode
= NtCreateThread(
85 if ( lpThreadId
!= NULL
)
86 memcpy(lpThreadId
, &ClientId
.UniqueThread
,sizeof(ULONG
));
100 errCode
= NtYieldExecution();
109 return (DWORD
)(GetTeb()->Cid
).UniqueThread
;
120 errCode
= NtTerminateThread(
124 if ( !NT_SUCCESS(errCode
) ) {
125 SetLastError(RtlNtStatusToDosError(errCode
));
134 LPFILETIME lpCreationTime
,
135 LPFILETIME lpExitTime
,
136 LPFILETIME lpKernelTime
,
137 LPFILETIME lpUserTime
141 KERNEL_USER_TIMES KernelUserTimes
;
143 errCode
= NtQueryInformationThread(hThread
,ThreadTimes
,&KernelUserTimes
,sizeof(KERNEL_USER_TIMES
),&ReturnLength
);
144 if ( !NT_SUCCESS(errCode
) ) {
145 SetLastError(RtlNtStatusToDosError(errCode
));
148 memcpy(lpCreationTime
, &KernelUserTimes
.CreateTime
, sizeof(FILETIME
));
149 memcpy(lpExitTime
, &KernelUserTimes
.ExitTime
, sizeof(FILETIME
));
150 memcpy(lpKernelTime
, &KernelUserTimes
.KernelTime
, sizeof(FILETIME
));
151 memcpy(lpUserTime
, &KernelUserTimes
.UserTime
, sizeof(FILETIME
));
158 STDCALL
GetThreadContext(
164 errCode
= NtGetContextThread(hThread
,lpContext
);
165 if ( !NT_SUCCESS(errCode
) ) {
166 SetLastError(RtlNtStatusToDosError(errCode
));
176 CONST CONTEXT
*lpContext
181 errCode
= NtSetContextThread(hThread
,(void *)lpContext
);
182 if (!NT_SUCCESS(errCode
) ) {
183 SetLastError(RtlNtStatusToDosError(errCode
));
199 THREAD_BASIC_INFORMATION ThreadBasic
;
201 errCode
= NtQueryInformationThread(hThread
,ThreadBasicInformation
,&ThreadBasic
,sizeof(THREAD_BASIC_INFORMATION
),&DataWritten
);
202 if ( !NT_SUCCESS(errCode
) ) {
203 SetLastError(RtlNtStatusToDosError(errCode
));
206 memcpy( lpExitCode
,&ThreadBasic
.ExitStatus
,sizeof(DWORD
));
219 ULONG PreviousResumeCount
;
221 errCode
= NtResumeThread(hThread
,&PreviousResumeCount
);
222 if ( !NT_SUCCESS(errCode
) ) {
223 SetLastError(RtlNtStatusToDosError(errCode
));
226 return PreviousResumeCount
;
236 ULONG PreviousSuspendCount
;
238 errCode
= NtSuspendThread(hThread
,&PreviousSuspendCount
);
239 if ( !NT_SUCCESS(errCode
) ) {
240 SetLastError(RtlNtStatusToDosError(errCode
));
243 return PreviousSuspendCount
;
249 SetThreadAffinityMask(
251 DWORD dwThreadAffinityMask
266 THREAD_BASIC_INFORMATION ThreadBasic
;
268 errCode
= NtQueryInformationThread(hThread
,ThreadBasicInformation
,&ThreadBasic
,sizeof(THREAD_BASIC_INFORMATION
),&DataWritten
);
269 if ( !NT_SUCCESS(errCode
) ) {
270 SetLastError(RtlNtStatusToDosError(errCode
));
273 ThreadBasic
.BasePriority
= nPriority
;
274 errCode
= NtSetInformationThread(hThread
,ThreadBasicInformation
,&ThreadBasic
,sizeof(THREAD_BASIC_INFORMATION
));
275 if ( !NT_SUCCESS(errCode
) ) {
276 SetLastError(RtlNtStatusToDosError(errCode
));
290 THREAD_BASIC_INFORMATION ThreadBasic
;
292 errCode
= NtQueryInformationThread(hThread
,ThreadBasicInformation
,&ThreadBasic
,sizeof(THREAD_BASIC_INFORMATION
),&DataWritten
);
293 if ( !NT_SUCCESS(errCode
) ) {
294 SetLastError(RtlNtStatusToDosError(errCode
));
295 return THREAD_PRIORITY_ERROR_RETURN
;
297 return ThreadBasic
.BasePriority
;
301 /* (WIN32) Thread Local Storage ******************************************** */
306 DWORD dwTlsIndex
= GetTeb()->dwTlsIndex
;
309 void **TlsData
= GetTeb()->TlsData
;
312 if (dwTlsIndex
< sizeof(TlsData
) / sizeof(TlsData
[0]))
314 TlsData
[dwTlsIndex
] = NULL
;
315 return (dwTlsIndex
++);
317 return (0xFFFFFFFFUL
);
321 TlsFree(DWORD dwTlsIndex
)
328 TlsGetValue(DWORD dwTlsIndex
)
332 void **TlsData
= GetTeb()->TlsData
;
335 if (dwTlsIndex
< sizeof(TlsData
) / sizeof(TlsData
[0]))
338 SetLastError(NO_ERROR
);
339 return (TlsData
[dwTlsIndex
]);
346 TlsSetValue(DWORD dwTlsIndex
, LPVOID lpTlsValue
)
350 void **TlsData
= GetTeb()->TlsData
;
353 if (dwTlsIndex
< sizeof(TlsData
) / sizeof(TlsData
[0]))
356 TlsData
[dwTlsIndex
] = lpTlsValue
;
362 /*************************************************************/