kernel32: Move thread functions to kernelbase.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-08-08 14:25:50 +02:00
parent adac42bad6
commit 0116660dd8
6 changed files with 558 additions and 735 deletions

View File

@ -316,8 +316,8 @@
@ stdcall CreateProcessInternalW(long wstr wstr ptr ptr long long ptr wstr ptr ptr ptr) @ stdcall CreateProcessInternalW(long wstr wstr ptr ptr long long ptr wstr ptr ptr ptr)
# @ stub CreateProcessInternalWSecure # @ stub CreateProcessInternalWSecure
@ stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr) @ stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr)
@ stdcall CreateRemoteThread(long ptr long ptr long long ptr) @ stdcall -import CreateRemoteThread(long ptr long ptr long long ptr)
@ stdcall CreateRemoteThreadEx(long ptr long ptr ptr long ptr ptr) @ stdcall -import CreateRemoteThreadEx(long ptr long ptr ptr long ptr ptr)
@ stdcall CreateSemaphoreA(ptr long long str) @ stdcall CreateSemaphoreA(ptr long long str)
@ stdcall CreateSemaphoreExA(ptr long long str long long) @ stdcall CreateSemaphoreExA(ptr long long str long long)
@ stdcall -import CreateSemaphoreExW(ptr long long wstr long long) @ stdcall -import CreateSemaphoreExW(ptr long long wstr long long)
@ -328,7 +328,7 @@
# @ stub CreateSymbolicLinkTransactedW # @ stub CreateSymbolicLinkTransactedW
@ stdcall CreateSymbolicLinkW(wstr wstr long) @ stdcall CreateSymbolicLinkW(wstr wstr long)
@ stdcall CreateTapePartition(long long long long) @ stdcall CreateTapePartition(long long long long)
@ stdcall CreateThread(ptr long ptr long long ptr) @ stdcall -import CreateThread(ptr long ptr long long ptr)
@ stdcall CreateThreadpool(ptr) @ stdcall CreateThreadpool(ptr)
@ stdcall CreateThreadpoolCleanupGroup() @ stdcall CreateThreadpoolCleanupGroup()
@ stdcall CreateThreadpoolIo(ptr ptr ptr ptr) @ stdcall CreateThreadpoolIo(ptr ptr ptr ptr)
@ -437,7 +437,7 @@
@ stdcall EscapeCommFunction(long long) @ stdcall EscapeCommFunction(long long)
@ stdcall -arch=x86_64 ExecuteUmsThread(ptr) @ stdcall -arch=x86_64 ExecuteUmsThread(ptr)
@ stdcall ExitProcess(long) @ stdcall ExitProcess(long)
@ stdcall ExitThread(long) @ stdcall ExitThread(long) ntdll.RtlExitUserThread
@ stub ExitVDM @ stub ExitVDM
@ stdcall ExpandEnvironmentStringsA(str ptr long) @ stdcall ExpandEnvironmentStringsA(str ptr long)
@ stdcall ExpandEnvironmentStringsW(wstr ptr long) @ stdcall ExpandEnvironmentStringsW(wstr ptr long)
@ -635,7 +635,7 @@
@ stdcall GetCurrentProcessorNumberEx(ptr) ntdll.RtlGetCurrentProcessorNumberEx @ stdcall GetCurrentProcessorNumberEx(ptr) ntdll.RtlGetCurrentProcessorNumberEx
@ stdcall -norelay GetCurrentThread() KERNEL32_GetCurrentThread @ stdcall -norelay GetCurrentThread() KERNEL32_GetCurrentThread
@ stdcall -norelay GetCurrentThreadId() KERNEL32_GetCurrentThreadId @ stdcall -norelay GetCurrentThreadId() KERNEL32_GetCurrentThreadId
@ stdcall GetCurrentThreadStackLimits(ptr ptr) @ stdcall -import GetCurrentThreadStackLimits(ptr ptr)
@ stdcall -arch=x86_64 GetCurrentUmsThread() @ stdcall -arch=x86_64 GetCurrentUmsThread()
@ stdcall GetDateFormatA(long long ptr str ptr long) @ stdcall GetDateFormatA(long long ptr str ptr long)
@ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr) @ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr)
@ -666,7 +666,7 @@
# @ stub GetEraNameCountedString # @ stub GetEraNameCountedString
@ stdcall GetErrorMode() @ stdcall GetErrorMode()
@ stdcall GetExitCodeProcess(long ptr) @ stdcall GetExitCodeProcess(long ptr)
@ stdcall GetExitCodeThread(long ptr) @ stdcall -import GetExitCodeThread(long ptr)
@ stdcall GetExpandedNameA(str ptr) @ stdcall GetExpandedNameA(str ptr)
@ stdcall GetExpandedNameW(wstr ptr) @ stdcall GetExpandedNameW(wstr ptr)
@ stdcall GetFileAttributesA(str) @ stdcall GetFileAttributesA(str)
@ -783,7 +783,7 @@
@ stdcall -norelay GetProcessHeap() KERNEL32_GetProcessHeap @ stdcall -norelay GetProcessHeap() KERNEL32_GetProcessHeap
@ stdcall GetProcessHeaps(long ptr) @ stdcall GetProcessHeaps(long ptr)
@ stdcall GetProcessId(long) @ stdcall GetProcessId(long)
@ stdcall GetProcessIdOfThread(long) @ stdcall -import GetProcessIdOfThread(long)
@ stdcall GetProcessIoCounters(long ptr) @ stdcall GetProcessIoCounters(long ptr)
@ stdcall GetProcessMitigationPolicy(long long ptr long) @ stdcall GetProcessMitigationPolicy(long long ptr long)
@ stdcall GetProcessPreferredUILanguages(long ptr ptr ptr) @ stdcall GetProcessPreferredUILanguages(long ptr ptr ptr)
@ -846,18 +846,19 @@
@ stdcall GetTempFileNameW(wstr wstr long ptr) @ stdcall GetTempFileNameW(wstr wstr long ptr)
@ stdcall GetTempPathA(long ptr) @ stdcall GetTempPathA(long ptr)
@ stdcall GetTempPathW(long ptr) @ stdcall GetTempPathW(long ptr)
@ stdcall GetThreadContext(long ptr) @ stdcall -import GetThreadContext(long ptr)
@ stdcall GetThreadErrorMode() @ stdcall -import GetThreadErrorMode()
@ stdcall GetThreadGroupAffinity(long ptr) @ stdcall -import GetThreadGroupAffinity(long ptr)
@ stdcall GetThreadId(ptr) @ stdcall -import GetThreadIOPendingFlag(long ptr)
@ stdcall -import GetThreadId(ptr)
# @ stub GetThreadIdealProcessorEx # @ stub GetThreadIdealProcessorEx
@ stdcall GetThreadIOPendingFlag(long ptr)
@ stdcall GetThreadLocale() @ stdcall GetThreadLocale()
@ stdcall GetThreadPreferredUILanguages(long ptr ptr ptr) @ stdcall GetThreadPreferredUILanguages(long ptr ptr ptr)
@ stdcall GetThreadPriority(long) @ stdcall -import GetThreadPriority(long)
@ stdcall GetThreadPriorityBoost(long ptr) @ stdcall -import GetThreadPriorityBoost(long ptr)
@ stdcall GetThreadSelectorEntry(long long ptr) @ stdcall GetThreadSelectorEntry(long long ptr)
@ stdcall GetThreadTimes(long ptr ptr ptr ptr) @ stdcall -import GetThreadTimes(long ptr ptr ptr ptr)
@ stdcall -import GetThreadUILanguage()
@ stdcall GetTickCount() @ stdcall GetTickCount()
@ stdcall -ret64 GetTickCount64() @ stdcall -ret64 GetTickCount64()
@ stdcall GetTimeFormatA(long long ptr str ptr long) @ stdcall GetTimeFormatA(long long ptr str ptr long)
@ -865,7 +866,6 @@
@ stdcall GetTimeFormatW(long long ptr wstr ptr long) @ stdcall GetTimeFormatW(long long ptr wstr ptr long)
@ stdcall GetTimeZoneInformation(ptr) @ stdcall GetTimeZoneInformation(ptr)
@ stdcall GetTimeZoneInformationForYear(long ptr ptr) @ stdcall GetTimeZoneInformationForYear(long ptr ptr)
@ stdcall GetThreadUILanguage()
# @ stub GetUILanguageInfo # @ stub GetUILanguageInfo
@ stdcall -arch=x86_64 GetUmsCompletionListEvent(ptr ptr) @ stdcall -arch=x86_64 GetUmsCompletionListEvent(ptr ptr)
# @ stub -arch=x86_64 GetUmsSystemThreadInformation # @ stub -arch=x86_64 GetUmsSystemThreadInformation
@ -1129,7 +1129,7 @@
@ stdcall OpenProfileUserMapping() @ stdcall OpenProfileUserMapping()
@ stdcall OpenSemaphoreA(long long str) @ stdcall OpenSemaphoreA(long long str)
@ stdcall -import OpenSemaphoreW(long long wstr) @ stdcall -import OpenSemaphoreW(long long wstr)
@ stdcall OpenThread(long long long) @ stdcall -import OpenThread(long long long)
# @ stub OpenThreadToken # @ stub OpenThreadToken
@ stdcall -i386 OpenVxDHandle(long) @ stdcall -i386 OpenVxDHandle(long)
@ stdcall OpenWaitableTimerA(long long str) @ stdcall OpenWaitableTimerA(long long str)
@ -1179,7 +1179,7 @@
@ stdcall -arch=x86_64 QueryUmsThreadInformation(ptr long ptr long ptr) @ stdcall -arch=x86_64 QueryUmsThreadInformation(ptr long ptr long ptr)
@ stdcall QueryUnbiasedInterruptTime(ptr) @ stdcall QueryUnbiasedInterruptTime(ptr)
@ stub QueryWin31IniFilesMappedToRegistry @ stub QueryWin31IniFilesMappedToRegistry
@ stdcall QueueUserAPC(ptr long long) @ stdcall -import QueueUserAPC(ptr long long)
@ stdcall QueueUserWorkItem(ptr ptr long) @ stdcall QueueUserWorkItem(ptr ptr long)
@ stdcall RaiseException(long long long ptr) @ stdcall RaiseException(long long long ptr)
# @ stub RaiseFailFastException # @ stub RaiseFailFastException
@ -1284,7 +1284,7 @@
@ stdcall ResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long) ntdll.LdrResolveDelayLoadedAPI @ stdcall ResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long) ntdll.LdrResolveDelayLoadedAPI
@ stdcall ResolveLocaleName(wstr ptr long) @ stdcall ResolveLocaleName(wstr ptr long)
@ stdcall RestoreLastError(long) ntdll.RtlRestoreLastWin32Error @ stdcall RestoreLastError(long) ntdll.RtlRestoreLastWin32Error
@ stdcall ResumeThread(long) @ stdcall -import ResumeThread(long)
@ cdecl -arch=arm,arm64,x86_64 RtlAddFunctionTable(ptr long long) ntdll.RtlAddFunctionTable @ cdecl -arch=arm,arm64,x86_64 RtlAddFunctionTable(ptr long long) ntdll.RtlAddFunctionTable
@ stdcall -norelay RtlCaptureContext(ptr) ntdll.RtlCaptureContext @ stdcall -norelay RtlCaptureContext(ptr) ntdll.RtlCaptureContext
@ stdcall RtlCaptureStackBackTrace(long long ptr ptr) ntdll.RtlCaptureStackBackTrace @ stdcall RtlCaptureStackBackTrace(long long ptr ptr) ntdll.RtlCaptureStackBackTrace
@ -1446,17 +1446,17 @@
@ stdcall SetTapePosition(ptr long long long long long) @ stdcall SetTapePosition(ptr long long long long long)
@ stdcall SetTermsrvAppInstallMode(long) @ stdcall SetTermsrvAppInstallMode(long)
@ stdcall SetThreadAffinityMask(long long) @ stdcall SetThreadAffinityMask(long long)
@ stdcall SetThreadContext(long ptr) @ stdcall -import SetThreadContext(long ptr)
@ stdcall SetThreadErrorMode(long ptr) @ stdcall -import SetThreadErrorMode(long ptr)
@ stdcall SetThreadExecutionState(long) @ stdcall SetThreadExecutionState(long)
@ stdcall SetThreadGroupAffinity(long ptr ptr) @ stdcall -import SetThreadGroupAffinity(long ptr ptr)
@ stdcall SetThreadIdealProcessor(long long) @ stdcall -import SetThreadIdealProcessor(long long)
@ stdcall SetThreadIdealProcessorEx(long ptr ptr) @ stdcall -import SetThreadIdealProcessorEx(long ptr ptr)
@ stdcall SetThreadLocale(long) @ stdcall SetThreadLocale(long)
@ stdcall SetThreadPreferredUILanguages(long ptr ptr) @ stdcall SetThreadPreferredUILanguages(long ptr ptr)
@ stdcall SetThreadPriority(long long) @ stdcall -import SetThreadPriority(long long)
@ stdcall SetThreadPriorityBoost(long long) @ stdcall -import SetThreadPriorityBoost(long long)
@ stdcall SetThreadStackGuarantee(ptr) @ stdcall -import SetThreadStackGuarantee(ptr)
# @ stub SetThreadToken # @ stub SetThreadToken
@ stdcall SetThreadUILanguage(long) @ stdcall SetThreadUILanguage(long)
# @ stub SetThreadpoolStackInformation # @ stub SetThreadpoolStackInformation
@ -1489,15 +1489,15 @@
# @ stub SortGetHandle # @ stub SortGetHandle
# @ stub StartThreadpoolIo # @ stub StartThreadpoolIo
@ stdcall SubmitThreadpoolWork(ptr) ntdll.TpPostWork @ stdcall SubmitThreadpoolWork(ptr) ntdll.TpPostWork
@ stdcall SuspendThread(long) @ stdcall -import SuspendThread(long)
@ stdcall SwitchToFiber(ptr) @ stdcall SwitchToFiber(ptr)
@ stdcall SwitchToThread() @ stdcall -import SwitchToThread()
@ stdcall SystemTimeToFileTime(ptr ptr) @ stdcall SystemTimeToFileTime(ptr ptr)
@ stdcall SystemTimeToTzSpecificLocalTime (ptr ptr ptr) @ stdcall SystemTimeToTzSpecificLocalTime (ptr ptr ptr)
# @ stub SystemTimeToTzSpecificLocalTimeEx # @ stub SystemTimeToTzSpecificLocalTimeEx
@ stdcall TerminateJobObject(long long) @ stdcall TerminateJobObject(long long)
@ stdcall TerminateProcess(long long) @ stdcall TerminateProcess(long long)
@ stdcall TerminateThread(long long) @ stdcall -import TerminateThread(long long)
@ stdcall TermsrvAppInstallMode() @ stdcall TermsrvAppInstallMode()
@ stdcall Thread32First(long ptr) @ stdcall Thread32First(long ptr)
@ stdcall Thread32Next(long ptr) @ stdcall Thread32Next(long ptr)

View File

@ -83,15 +83,6 @@ static BOOL get_open_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING
return TRUE; return TRUE;
} }
/***********************************************************************
* SwitchToThread (KERNEL32.@)
*/
BOOL WINAPI SwitchToThread(void)
{
return (NtYieldExecution() != STATUS_NO_YIELD_PERFORMED);
}
static HANDLE normalize_handle_if_console(HANDLE handle) static HANDLE normalize_handle_if_console(HANDLE handle)
{ {
if ((handle == (HANDLE)STD_INPUT_HANDLE) || if ((handle == (HANDLE)STD_INPUT_HANDLE) ||

View File

@ -46,143 +46,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(thread); WINE_DEFAULT_DEBUG_CHANNEL(thread);
/***********************************************************************
* CreateThread (KERNEL32.@)
*/
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread( SECURITY_ATTRIBUTES *sa, SIZE_T stack, LPTHREAD_START_ROUTINE start,
LPVOID param, DWORD flags, LPDWORD id )
{
return CreateRemoteThread( GetCurrentProcess(),
sa, stack, start, param, flags, id );
}
/***************************************************************************
* CreateRemoteThread (KERNEL32.@)
*/
HANDLE WINAPI CreateRemoteThread( HANDLE hProcess, SECURITY_ATTRIBUTES *sa, SIZE_T stack,
LPTHREAD_START_ROUTINE start, LPVOID param,
DWORD flags, DWORD *id )
{
return CreateRemoteThreadEx( hProcess, sa, stack, start, param, flags, NULL, id );
}
/***************************************************************************
* CreateRemoteThreadEx (KERNEL32.@)
*
* Creates a thread that runs in the address space of another process
*
* PARAMS
*
* RETURNS
* Success: Handle to the new thread.
* Failure: NULL. Use GetLastError() to find the error cause.
*
* BUGS
* Improper memory allocation: there's no ability to free new_thread_info
* in other process.
* Bad start address for RtlCreateUserThread because the library
* may be loaded at different address in other process.
*/
HANDLE WINAPI CreateRemoteThreadEx( HANDLE hProcess, SECURITY_ATTRIBUTES *sa, SIZE_T stack,
LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags,
LPPROC_THREAD_ATTRIBUTE_LIST attributes, DWORD *id )
{
HANDLE handle;
CLIENT_ID client_id;
NTSTATUS status;
SIZE_T stack_reserve = 0, stack_commit = 0;
if (attributes)
FIXME("thread attributes ignored\n");
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
else stack_commit = stack;
status = RtlCreateUserThread( hProcess, sa ? sa->lpSecurityDescriptor : NULL, TRUE,
NULL, stack_reserve, stack_commit,
(PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id );
if (status == STATUS_SUCCESS)
{
if (id) *id = HandleToULong(client_id.UniqueThread);
if (sa && (sa->nLength >= sizeof(*sa)) && sa->bInheritHandle)
SetHandleInformation( handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
if (!(flags & CREATE_SUSPENDED))
{
ULONG ret;
if (NtResumeThread( handle, &ret ))
{
NtClose( handle );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
handle = 0;
}
}
}
else
{
SetLastError( RtlNtStatusToDosError(status) );
handle = 0;
}
return handle;
}
/***********************************************************************
* OpenThread [KERNEL32.@] Retrieves a handle to a thread from its thread id
*/
HANDLE WINAPI OpenThread( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId )
{
NTSTATUS status;
HANDLE handle;
OBJECT_ATTRIBUTES attr;
CLIENT_ID cid;
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = bInheritHandle ? OBJ_INHERIT : 0;
attr.ObjectName = NULL;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
cid.UniqueProcess = 0;
cid.UniqueThread = ULongToHandle(dwThreadId);
status = NtOpenThread( &handle, dwDesiredAccess, &attr, &cid );
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
handle = 0;
}
return handle;
}
/***********************************************************************
* ExitThread [KERNEL32.@] Ends a thread
*
* RETURNS
* None
*/
void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
{
RtlExitUserThread( code );
}
/**********************************************************************
* TerminateThread [KERNEL32.@] Terminates a thread
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI TerminateThread( HANDLE handle, /* [in] Handle to thread */
DWORD exit_code) /* [in] Exit code for thread */
{
NTSTATUS status = NtTerminateThread( handle, exit_code );
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/*********************************************************************** /***********************************************************************
* FreeLibraryAndExitThread (KERNEL32.@) * FreeLibraryAndExitThread (KERNEL32.@)
*/ */
@ -193,49 +56,6 @@ void WINAPI FreeLibraryAndExitThread(HINSTANCE hLibModule, DWORD dwExitCode)
} }
/**********************************************************************
* GetExitCodeThread (KERNEL32.@)
*
* Gets termination status of thread.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI GetExitCodeThread(
HANDLE hthread, /* [in] Handle to thread */
LPDWORD exitcode) /* [out] Address to receive termination status */
{
THREAD_BASIC_INFORMATION info;
NTSTATUS status = NtQueryInformationThread( hthread, ThreadBasicInformation,
&info, sizeof(info), NULL );
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
if (exitcode) *exitcode = info.ExitStatus;
return TRUE;
}
/***********************************************************************
* SetThreadContext [KERNEL32.@] Sets context of thread.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread with context */
const CONTEXT *context ) /* [in] Address of context structure */
{
NTSTATUS status = NtSetContextThread( handle, context );
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/*********************************************************************** /***********************************************************************
* Wow64SetThreadContext [KERNEL32.@] * Wow64SetThreadContext [KERNEL32.@]
*/ */
@ -253,22 +73,6 @@ BOOL WINAPI Wow64SetThreadContext( HANDLE handle, const WOW64_CONTEXT *context)
return !status; return !status;
} }
/***********************************************************************
* GetThreadContext [KERNEL32.@] Retrieves context of thread.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with context */
CONTEXT *context ) /* [out] Address of context structure */
{
NTSTATUS status = NtGetContextThread( handle, context );
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/*********************************************************************** /***********************************************************************
* Wow64GetThreadContext [KERNEL32.@] * Wow64GetThreadContext [KERNEL32.@]
*/ */
@ -287,191 +91,6 @@ BOOL WINAPI Wow64GetThreadContext( HANDLE handle, WOW64_CONTEXT *context)
} }
/**********************************************************************
* SuspendThread [KERNEL32.@] Suspends a thread.
*
* RETURNS
* Success: Previous suspend count
* Failure: 0xFFFFFFFF
*/
DWORD WINAPI SuspendThread( HANDLE hthread ) /* [in] Handle to the thread */
{
DWORD ret;
NTSTATUS status = NtSuspendThread( hthread, &ret );
if (status)
{
ret = ~0U;
SetLastError( RtlNtStatusToDosError(status) );
}
return ret;
}
/**********************************************************************
* ResumeThread [KERNEL32.@] Resumes a thread.
*
* Decrements a thread's suspend count. When count is zero, the
* execution of the thread is resumed.
*
* RETURNS
* Success: Previous suspend count
* Failure: 0xFFFFFFFF
* Already running: 0
*/
DWORD WINAPI ResumeThread( HANDLE hthread ) /* [in] Identifies thread to restart */
{
DWORD ret;
NTSTATUS status = NtResumeThread( hthread, &ret );
if (status)
{
ret = ~0U;
SetLastError( RtlNtStatusToDosError(status) );
}
return ret;
}
/**********************************************************************
* GetThreadPriority [KERNEL32.@] Returns priority for thread.
*
* RETURNS
* Success: Thread's priority level.
* Failure: THREAD_PRIORITY_ERROR_RETURN
*/
INT WINAPI GetThreadPriority(
HANDLE hthread) /* [in] Handle to thread */
{
THREAD_BASIC_INFORMATION info;
NTSTATUS status = NtQueryInformationThread( hthread, ThreadBasicInformation,
&info, sizeof(info), NULL );
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return THREAD_PRIORITY_ERROR_RETURN;
}
return info.Priority;
}
/**********************************************************************
* SetThreadPriority [KERNEL32.@] Sets priority for thread.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI SetThreadPriority(
HANDLE hthread, /* [in] Handle to thread */
INT priority) /* [in] Thread priority level */
{
DWORD prio = priority;
NTSTATUS status;
status = NtSetInformationThread(hthread, ThreadBasePriority,
&prio, sizeof(prio));
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/**********************************************************************
* GetThreadPriorityBoost [KERNEL32.@] Returns priority boost for thread.
*
* Always reports that priority boost is disabled.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE
*/
BOOL WINAPI GetThreadPriorityBoost(
HANDLE hthread, /* [in] Handle to thread */
PBOOL pstate) /* [out] pointer to var that receives the boost state */
{
if (pstate) *pstate = FALSE;
return TRUE;
}
/**********************************************************************
* SetThreadPriorityBoost [KERNEL32.@] Sets priority boost for thread.
*
* Priority boost is not implemented, but we return TRUE
* anyway because some games crash otherwise.
*/
BOOL WINAPI SetThreadPriorityBoost(
HANDLE hthread, /* [in] Handle to thread */
BOOL disable) /* [in] TRUE to disable priority boost */
{
return TRUE;
}
/**********************************************************************
* SetThreadStackGuarantee (KERNEL32.@)
*/
BOOL WINAPI SetThreadStackGuarantee(PULONG stacksize)
{
static int once;
if (once++ == 0)
FIXME("(%p): stub\n", stacksize);
return TRUE;
}
/***********************************************************************
* GetThreadGroupAffinity (KERNEL32.@)
*/
BOOL WINAPI GetThreadGroupAffinity( HANDLE thread, GROUP_AFFINITY *affinity )
{
NTSTATUS status;
if (!affinity)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
status = NtQueryInformationThread( thread, ThreadGroupInformation,
affinity, sizeof(*affinity), NULL );
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* SetThreadGroupAffinity (KERNEL32.@)
*/
BOOL WINAPI SetThreadGroupAffinity( HANDLE thread, const GROUP_AFFINITY *affinity_new,
GROUP_AFFINITY *affinity_old )
{
NTSTATUS status;
if (affinity_old && !GetThreadGroupAffinity( thread, affinity_old ))
return FALSE;
status = NtSetInformationThread( thread, ThreadGroupInformation,
affinity_new, sizeof(*affinity_new) );
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/********************************************************************** /**********************************************************************
* SetThreadAffinityMask (KERNEL32.@) * SetThreadAffinityMask (KERNEL32.@)
*/ */
@ -499,36 +118,6 @@ DWORD_PTR WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD_PTR dwThreadAffini
} }
/**********************************************************************
* SetThreadIdealProcessor [KERNEL32.@] Sets preferred processor for thread.
*
* RETURNS
* Success: Value of last call to SetThreadIdealProcessor
* Failure: -1
*/
DWORD WINAPI SetThreadIdealProcessor(
HANDLE hThread, /* [in] Specifies the thread of interest */
DWORD dwIdealProcessor) /* [in] Specifies the new preferred processor */
{
FIXME("(%p): stub\n",hThread);
if (dwIdealProcessor > MAXIMUM_PROCESSORS)
{
SetLastError(ERROR_INVALID_PARAMETER);
return ~0u;
}
return 0;
}
/***********************************************************************
* SetThreadIdealProcessorEx (KERNEL32.@)
*/
BOOL WINAPI SetThreadIdealProcessorEx( HANDLE thread, PROCESSOR_NUMBER *ideal, PROCESSOR_NUMBER *previous )
{
FIXME("(%p %p %p): stub\n", thread, ideal, previous);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*********************************************************************** /***********************************************************************
* GetThreadSelectorEntry (KERNEL32.@) * GetThreadSelectorEntry (KERNEL32.@)
*/ */
@ -549,24 +138,6 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten
} }
/* callback for QueueUserAPC */
static void CALLBACK call_user_apc( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3 )
{
PAPCFUNC func = (PAPCFUNC)arg1;
func( arg2 );
}
/***********************************************************************
* QueueUserAPC (KERNEL32.@)
*/
DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data )
{
NTSTATUS status = NtQueueApcThread( hthread, call_user_apc, (ULONG_PTR)func, data, 0 );
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/*********************************************************************** /***********************************************************************
* QueueUserWorkItem (KERNEL32.@) * QueueUserWorkItem (KERNEL32.@)
*/ */
@ -582,114 +153,6 @@ BOOL WINAPI QueueUserWorkItem( LPTHREAD_START_ROUTINE Function, PVOID Context, U
return !status; return !status;
} }
/**********************************************************************
* GetThreadTimes [KERNEL32.@] Obtains timing information.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI GetThreadTimes(
HANDLE thread, /* [in] Specifies the thread of interest */
LPFILETIME creationtime, /* [out] When the thread was created */
LPFILETIME exittime, /* [out] When the thread was destroyed */
LPFILETIME kerneltime, /* [out] Time thread spent in kernel mode */
LPFILETIME usertime) /* [out] Time thread spent in user mode */
{
KERNEL_USER_TIMES kusrt;
NTSTATUS status;
status = NtQueryInformationThread(thread, ThreadTimes, &kusrt,
sizeof(kusrt), NULL);
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
if (creationtime)
{
creationtime->dwLowDateTime = kusrt.CreateTime.u.LowPart;
creationtime->dwHighDateTime = kusrt.CreateTime.u.HighPart;
}
if (exittime)
{
exittime->dwLowDateTime = kusrt.ExitTime.u.LowPart;
exittime->dwHighDateTime = kusrt.ExitTime.u.HighPart;
}
if (kerneltime)
{
kerneltime->dwLowDateTime = kusrt.KernelTime.u.LowPart;
kerneltime->dwHighDateTime = kusrt.KernelTime.u.HighPart;
}
if (usertime)
{
usertime->dwLowDateTime = kusrt.UserTime.u.LowPart;
usertime->dwHighDateTime = kusrt.UserTime.u.HighPart;
}
return TRUE;
}
/**********************************************************************
* GetThreadId [KERNEL32.@]
*
* Retrieve the identifier of a thread.
*
* PARAMS
* Thread [I] The thread to retrieve the identifier of.
*
* RETURNS
* Success: Identifier of the target thread.
* Failure: 0
*/
DWORD WINAPI GetThreadId(HANDLE Thread)
{
THREAD_BASIC_INFORMATION tbi;
NTSTATUS status;
TRACE("(%p)\n", Thread);
status = NtQueryInformationThread(Thread, ThreadBasicInformation, &tbi,
sizeof(tbi), NULL);
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return 0;
}
return HandleToULong(tbi.ClientId.UniqueThread);
}
/**********************************************************************
* GetProcessIdOfThread [KERNEL32.@]
*
* Retrieve process identifier given thread belongs to.
*
* PARAMS
* Thread [I] The thread identifier.
*
* RETURNS
* Success: Process identifier
* Failure: 0
*/
DWORD WINAPI GetProcessIdOfThread(HANDLE Thread)
{
THREAD_BASIC_INFORMATION tbi;
NTSTATUS status;
TRACE("(%p)\n", Thread);
status = NtQueryInformationThread(Thread, ThreadBasicInformation, &tbi,
sizeof(tbi), NULL);
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return 0;
}
return HandleToULong(tbi.ClientId.UniqueProcess);
}
/*********************************************************************** /***********************************************************************
* GetCurrentThread [KERNEL32.@] Gets pseudohandle for current thread * GetCurrentThread [KERNEL32.@] Gets pseudohandle for current thread
* *
@ -701,15 +164,6 @@ HANDLE WINAPI KERNEL32_GetCurrentThread(void)
return (HANDLE)~(ULONG_PTR)1; return (HANDLE)~(ULONG_PTR)1;
} }
/***********************************************************************
* GetCurrentThreadStackLimits (KERNEL32.@)
*/
void WINAPI GetCurrentThreadStackLimits(ULONG_PTR *low, ULONG_PTR *high)
{
*low = (ULONG_PTR)NtCurrentTeb()->DeallocationStack;
*high = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase;
}
/********************************************************************** /**********************************************************************
* SetLastError (KERNEL32.@) * SetLastError (KERNEL32.@)
* *
@ -770,124 +224,6 @@ HANDLE WINAPI KERNEL32_GetProcessHeap(void)
return NtCurrentTeb()->Peb->ProcessHeap; return NtCurrentTeb()->Peb->ProcessHeap;
} }
/*************************************************************************
* rtlmode_to_win32mode
*/
static DWORD rtlmode_to_win32mode( DWORD rtlmode )
{
DWORD win32mode = 0;
if (rtlmode & 0x10)
win32mode |= SEM_FAILCRITICALERRORS;
if (rtlmode & 0x20)
win32mode |= SEM_NOGPFAULTERRORBOX;
if (rtlmode & 0x40)
win32mode |= SEM_NOOPENFILEERRORBOX;
return win32mode;
}
/***********************************************************************
* SetThreadErrorMode (KERNEL32.@)
*
* Set the thread local error mode.
*
* PARAMS
* mode [I] The new error mode, a bitwise or of SEM_FAILCRITICALERRORS,
* SEM_NOGPFAULTERRORBOX and SEM_NOOPENFILEERRORBOX.
* oldmode [O] Destination of the old error mode (may be NULL)
*
* RETURNS
* Success: TRUE
* Failure: FALSE, check GetLastError
*/
BOOL WINAPI SetThreadErrorMode( DWORD mode, LPDWORD oldmode )
{
NTSTATUS status;
DWORD tmp = 0;
if (mode & ~(SEM_FAILCRITICALERRORS |
SEM_NOGPFAULTERRORBOX |
SEM_NOOPENFILEERRORBOX))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (mode & SEM_FAILCRITICALERRORS)
tmp |= 0x10;
if (mode & SEM_NOGPFAULTERRORBOX)
tmp |= 0x20;
if (mode & SEM_NOOPENFILEERRORBOX)
tmp |= 0x40;
status = RtlSetThreadErrorMode( tmp, oldmode );
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
if (oldmode)
*oldmode = rtlmode_to_win32mode(*oldmode);
return TRUE;
}
/***********************************************************************
* GetThreadErrorMode (KERNEL32.@)
*
* Get the thread local error mode.
*
* PARAMS
* None.
*
* RETURNS
* The current thread local error mode.
*/
DWORD WINAPI GetThreadErrorMode( void )
{
return rtlmode_to_win32mode( RtlGetThreadErrorMode() );
}
/***********************************************************************
* GetThreadUILanguage (KERNEL32.@)
*
* Get the current thread's language identifier.
*
* PARAMS
* None.
*
* RETURNS
* The current thread's language identifier.
*/
LANGID WINAPI GetThreadUILanguage( void )
{
LANGID lang;
NtQueryDefaultUILanguage( &lang );
FIXME(": stub, returning default language.\n");
return lang;
}
/***********************************************************************
* GetThreadIOPendingFlag (KERNEL32.@)
*/
BOOL WINAPI GetThreadIOPendingFlag( HANDLE thread, PBOOL io_pending )
{
NTSTATUS status;
TRACE("%p, %p\n", thread, io_pending);
status = NtQueryInformationThread( thread, ThreadIsIoPending,
io_pending, sizeof(*io_pending), NULL );
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/*********************************************************************** /***********************************************************************
* CallbackMayRunLong (KERNEL32.@) * CallbackMayRunLong (KERNEL32.@)
*/ */

View File

@ -11,4 +11,5 @@ C_SRCS = \
security.c \ security.c \
string.c \ string.c \
sync.c \ sync.c \
thread.c \
version.c version.c

View File

@ -211,8 +211,8 @@
@ stdcall CreateProcessInternalA(long str str ptr ptr long long ptr str ptr ptr ptr) kernel32.CreateProcessInternalA @ stdcall CreateProcessInternalA(long str str ptr ptr long long ptr str ptr ptr ptr) kernel32.CreateProcessInternalA
@ stdcall CreateProcessInternalW(long wstr wstr ptr ptr long long ptr wstr ptr ptr ptr) kernel32.CreateProcessInternalW @ stdcall CreateProcessInternalW(long wstr wstr ptr ptr long long ptr wstr ptr ptr ptr) kernel32.CreateProcessInternalW
@ stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessW @ stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessW
@ stdcall CreateRemoteThread(long ptr long ptr long long ptr) kernel32.CreateRemoteThread @ stdcall CreateRemoteThread(long ptr long ptr long long ptr)
@ stdcall CreateRemoteThreadEx(long ptr long ptr ptr long ptr ptr) kernel32.CreateRemoteThreadEx @ stdcall CreateRemoteThreadEx(long ptr long ptr ptr long ptr ptr)
@ stdcall CreateRestrictedToken(long long long ptr long ptr long ptr ptr) @ stdcall CreateRestrictedToken(long long long ptr long ptr long ptr ptr)
@ stdcall CreateSemaphoreExW(ptr long long wstr long long) @ stdcall CreateSemaphoreExW(ptr long long wstr long long)
@ stdcall CreateSemaphoreW(ptr long long wstr) @ stdcall CreateSemaphoreW(ptr long long wstr)
@ -222,7 +222,7 @@
# @ stub CreateStateLock # @ stub CreateStateLock
# @ stub CreateStateSubcontainer # @ stub CreateStateSubcontainer
@ stdcall CreateSymbolicLinkW(wstr wstr long) kernel32.CreateSymbolicLinkW @ stdcall CreateSymbolicLinkW(wstr wstr long) kernel32.CreateSymbolicLinkW
@ stdcall CreateThread(ptr long ptr long long ptr) kernel32.CreateThread @ stdcall CreateThread(ptr long ptr long long ptr)
@ stdcall CreateThreadpool(ptr) kernel32.CreateThreadpool @ stdcall CreateThreadpool(ptr) kernel32.CreateThreadpool
@ stdcall CreateThreadpoolCleanupGroup() kernel32.CreateThreadpoolCleanupGroup @ stdcall CreateThreadpoolCleanupGroup() kernel32.CreateThreadpoolCleanupGroup
@ stdcall CreateThreadpoolIo(ptr ptr ptr ptr) kernel32.CreateThreadpoolIo @ stdcall CreateThreadpoolIo(ptr ptr ptr ptr) kernel32.CreateThreadpoolIo
@ -395,7 +395,7 @@
# @ stub FreeGPOListInternalA # @ stub FreeGPOListInternalA
# @ stub FreeGPOListInternalW # @ stub FreeGPOListInternalW
@ stdcall FreeLibrary(long) kernel32.FreeLibrary @ stdcall FreeLibrary(long) kernel32.FreeLibrary
@ stdcall FreeLibraryAndExitThread(long long) kernel32.FreeLibraryAndExitThread @ stdcall FreeLibraryAndExitThread(long long)
@ stdcall FreeLibraryWhenCallbackReturns(ptr ptr) ntdll.TpCallbackUnloadDllOnCompletion @ stdcall FreeLibraryWhenCallbackReturns(ptr ptr) ntdll.TpCallbackUnloadDllOnCompletion
@ stdcall FreeResource(long) @ stdcall FreeResource(long)
@ stdcall FreeSid(ptr) @ stdcall FreeSid(ptr)
@ -469,9 +469,9 @@
@ stdcall GetCurrentProcessorNumber() ntdll.NtGetCurrentProcessorNumber @ stdcall GetCurrentProcessorNumber() ntdll.NtGetCurrentProcessorNumber
@ stdcall GetCurrentProcessorNumberEx(ptr) ntdll.RtlGetCurrentProcessorNumberEx @ stdcall GetCurrentProcessorNumberEx(ptr) ntdll.RtlGetCurrentProcessorNumberEx
# @ stub GetCurrentTargetPlatformContext # @ stub GetCurrentTargetPlatformContext
@ stdcall -norelay GetCurrentThread() kernel32.GetCurrentThread @ stdcall -norelay GetCurrentThread() kernelbase_GetCurrentThread
@ stdcall -norelay GetCurrentThreadId() kernel32.GetCurrentThreadId @ stdcall -norelay GetCurrentThreadId() kernelbase_GetCurrentThreadId
@ stdcall GetCurrentThreadStackLimits(ptr ptr) kernel32.GetCurrentThreadStackLimits @ stdcall GetCurrentThreadStackLimits(ptr ptr)
@ stdcall GetDateFormatA(long long ptr str ptr long) kernel32.GetDateFormatA @ stdcall GetDateFormatA(long long ptr str ptr long) kernel32.GetDateFormatA
@ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr) kernel32.GetDateFormatEx @ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr) kernel32.GetDateFormatEx
@ stdcall GetDateFormatW(long long ptr wstr ptr long) kernel32.GetDateFormatW @ stdcall GetDateFormatW(long long ptr wstr ptr long) kernel32.GetDateFormatW
@ -500,7 +500,7 @@
@ stub GetEraNameCountedString @ stub GetEraNameCountedString
@ stdcall GetErrorMode() kernel32.GetErrorMode @ stdcall GetErrorMode() kernel32.GetErrorMode
@ stdcall GetExitCodeProcess(long ptr) kernel32.GetExitCodeProcess @ stdcall GetExitCodeProcess(long ptr) kernel32.GetExitCodeProcess
@ stdcall GetExitCodeThread(long ptr) kernel32.GetExitCodeThread @ stdcall GetExitCodeThread(long ptr)
@ stub GetFallbackDisplayName @ stub GetFallbackDisplayName
@ stdcall GetFileAttributesA(str) kernel32.GetFileAttributesA @ stdcall GetFileAttributesA(str) kernel32.GetFileAttributesA
@ stdcall GetFileAttributesExA(str long ptr) kernel32.GetFileAttributesExA @ stdcall GetFileAttributesExA(str long ptr) kernel32.GetFileAttributesExA
@ -627,7 +627,7 @@
@ stdcall -norelay GetProcessHeap() kernel32.GetProcessHeap @ stdcall -norelay GetProcessHeap() kernel32.GetProcessHeap
@ stdcall GetProcessHeaps(long ptr) kernel32.GetProcessHeaps @ stdcall GetProcessHeaps(long ptr) kernel32.GetProcessHeaps
@ stdcall GetProcessId(long) kernel32.GetProcessId @ stdcall GetProcessId(long) kernel32.GetProcessId
@ stdcall GetProcessIdOfThread(long) kernel32.GetProcessIdOfThread @ stdcall GetProcessIdOfThread(long)
# @ stub GetProcessImageFileNameA # @ stub GetProcessImageFileNameA
# @ stub GetProcessImageFileNameW # @ stub GetProcessImageFileNameW
# @ stub GetProcessInformation # @ stub GetProcessInformation
@ -711,21 +711,21 @@
@ stdcall GetTempFileNameW(wstr wstr long ptr) kernel32.GetTempFileNameW @ stdcall GetTempFileNameW(wstr wstr long ptr) kernel32.GetTempFileNameW
@ stdcall GetTempPathA(long ptr) kernel32.GetTempPathA @ stdcall GetTempPathA(long ptr) kernel32.GetTempPathA
@ stdcall GetTempPathW(long ptr) kernel32.GetTempPathW @ stdcall GetTempPathW(long ptr) kernel32.GetTempPathW
@ stdcall GetThreadContext(long ptr) kernel32.GetThreadContext @ stdcall GetThreadContext(long ptr)
# @ stub GetThreadDescription # @ stub GetThreadDescription
@ stdcall GetThreadErrorMode() kernel32.GetThreadErrorMode @ stdcall GetThreadErrorMode()
@ stdcall GetThreadGroupAffinity(long ptr) kernel32.GetThreadGroupAffinity @ stdcall GetThreadGroupAffinity(long ptr)
@ stdcall GetThreadIOPendingFlag(long ptr) kernel32.GetThreadIOPendingFlag @ stdcall GetThreadIOPendingFlag(long ptr)
@ stdcall GetThreadId(ptr) kernel32.GetThreadId @ stdcall GetThreadId(ptr)
# @ stub GetThreadIdealProcessorEx # @ stub GetThreadIdealProcessorEx
# @ stub GetThreadInformation # @ stub GetThreadInformation
@ stdcall GetThreadLocale() kernel32.GetThreadLocale @ stdcall GetThreadLocale() kernel32.GetThreadLocale
@ stdcall GetThreadPreferredUILanguages(long ptr ptr ptr) kernel32.GetThreadPreferredUILanguages @ stdcall GetThreadPreferredUILanguages(long ptr ptr ptr) kernel32.GetThreadPreferredUILanguages
@ stdcall GetThreadPriority(long) kernel32.GetThreadPriority @ stdcall GetThreadPriority(long)
@ stdcall GetThreadPriorityBoost(long ptr) kernel32.GetThreadPriorityBoost @ stdcall GetThreadPriorityBoost(long ptr)
# @ stub GetThreadSelectedCpuSets # @ stub GetThreadSelectedCpuSets
@ stdcall GetThreadTimes(long ptr ptr ptr ptr) kernel32.GetThreadTimes @ stdcall GetThreadTimes(long ptr ptr ptr ptr)
@ stdcall GetThreadUILanguage() kernel32.GetThreadUILanguage @ stdcall GetThreadUILanguage()
@ stdcall GetTickCount() kernel32.GetTickCount @ stdcall GetTickCount() kernel32.GetTickCount
@ stdcall -ret64 GetTickCount64() kernel32.GetTickCount64 @ stdcall -ret64 GetTickCount64() kernel32.GetTickCount64
@ stdcall GetTimeFormatA(long long ptr str ptr long) kernel32.GetTimeFormatA @ stdcall GetTimeFormatA(long long ptr str ptr long) kernel32.GetTimeFormatA
@ -1000,7 +1000,7 @@
# @ stub OpenStateExplicit # @ stub OpenStateExplicit
# @ stub OpenStateExplicitForUserSid # @ stub OpenStateExplicitForUserSid
# @ stub OpenStateExplicitForUserSidString # @ stub OpenStateExplicitForUserSidString
@ stdcall OpenThread(long long long) kernel32.OpenThread @ stdcall OpenThread(long long long)
@ stdcall OpenThreadToken(long long long ptr) @ stdcall OpenThreadToken(long long long ptr)
@ stdcall OpenWaitableTimerW(long long wstr) @ stdcall OpenWaitableTimerW(long long wstr)
@ stdcall OutputDebugStringA(str) kernel32.OutputDebugStringA @ stdcall OutputDebugStringA(str) kernel32.OutputDebugStringA
@ -1220,7 +1220,7 @@
# @ stub QueryVirtualMemoryInformation # @ stub QueryVirtualMemoryInformation
# @ stub QueryWorkingSet # @ stub QueryWorkingSet
# @ stub QueryWorkingSetEx # @ stub QueryWorkingSetEx
@ stdcall QueueUserAPC(ptr long long) kernel32.QueueUserAPC @ stdcall QueueUserAPC(ptr long long)
@ stdcall QueueUserWorkItem(ptr ptr long) kernel32.QueueUserWorkItem @ stdcall QueueUserWorkItem(ptr ptr long) kernel32.QueueUserWorkItem
# @ stub QuirkGetData # @ stub QuirkGetData
# @ stub QuirkGetData2 # @ stub QuirkGetData2
@ -1348,7 +1348,7 @@
# @ stub ResolveDelayLoadsFromDll # @ stub ResolveDelayLoadsFromDll
@ stdcall ResolveLocaleName(wstr ptr long) kernel32.ResolveLocaleName @ stdcall ResolveLocaleName(wstr ptr long) kernel32.ResolveLocaleName
@ stdcall RestoreLastError(long) ntdll.RtlRestoreLastWin32Error @ stdcall RestoreLastError(long) ntdll.RtlRestoreLastWin32Error
@ stdcall ResumeThread(long) kernel32.ResumeThread @ stdcall ResumeThread(long)
@ stdcall RevertToSelf() @ stdcall RevertToSelf()
# @ stub RsopLoggingEnabledInternal # @ stub RsopLoggingEnabledInternal
# @ stub SHCoCreateInstance # @ stub SHCoCreateInstance
@ -1478,19 +1478,19 @@
@ stdcall SetSystemFileCacheSize(long long long) kernel32.SetSystemFileCacheSize @ stdcall SetSystemFileCacheSize(long long long) kernel32.SetSystemFileCacheSize
@ stdcall SetSystemTime(ptr) kernel32.SetSystemTime @ stdcall SetSystemTime(ptr) kernel32.SetSystemTime
@ stdcall SetSystemTimeAdjustment(long long) kernel32.SetSystemTimeAdjustment @ stdcall SetSystemTimeAdjustment(long long) kernel32.SetSystemTimeAdjustment
@ stdcall SetThreadContext(long ptr) kernel32.SetThreadContext @ stdcall SetThreadContext(long ptr)
# @ stub SetThreadDescription # @ stub SetThreadDescription
@ stdcall SetThreadErrorMode(long ptr) kernel32.SetThreadErrorMode @ stdcall SetThreadErrorMode(long ptr)
@ stdcall SetThreadGroupAffinity(long ptr ptr) kernel32.SetThreadGroupAffinity @ stdcall SetThreadGroupAffinity(long ptr ptr)
@ stdcall SetThreadIdealProcessor(long long) kernel32.SetThreadIdealProcessor @ stdcall SetThreadIdealProcessor(long long)
@ stdcall SetThreadIdealProcessorEx(long ptr ptr) kernel32.SetThreadIdealProcessorEx @ stdcall SetThreadIdealProcessorEx(long ptr ptr)
# @ stub SetThreadInformation # @ stub SetThreadInformation
@ stdcall SetThreadLocale(long) kernel32.SetThreadLocale @ stdcall SetThreadLocale(long) kernel32.SetThreadLocale
@ stdcall SetThreadPreferredUILanguages(long ptr ptr) kernel32.SetThreadPreferredUILanguages @ stdcall SetThreadPreferredUILanguages(long ptr ptr) kernel32.SetThreadPreferredUILanguages
@ stdcall SetThreadPriority(long long) kernel32.SetThreadPriority @ stdcall SetThreadPriority(long long)
@ stdcall SetThreadPriorityBoost(long long) kernel32.SetThreadPriorityBoost @ stdcall SetThreadPriorityBoost(long long)
# @ stub SetThreadSelectedCpuSets # @ stub SetThreadSelectedCpuSets
@ stdcall SetThreadStackGuarantee(ptr) kernel32.SetThreadStackGuarantee @ stdcall SetThreadStackGuarantee(ptr)
@ stdcall SetThreadToken(ptr ptr) @ stdcall SetThreadToken(ptr ptr)
@ stdcall SetThreadUILanguage(long) kernel32.SetThreadUILanguage @ stdcall SetThreadUILanguage(long) kernel32.SetThreadUILanguage
@ stub SetThreadpoolStackInformation @ stub SetThreadpoolStackInformation
@ -1588,15 +1588,15 @@
@ stdcall SubmitThreadpoolWork(ptr) ntdll.TpPostWork @ stdcall SubmitThreadpoolWork(ptr) ntdll.TpPostWork
# @ stub SubscribeEdpEnabledStateChange # @ stub SubscribeEdpEnabledStateChange
# @ stub SubscribeStateChangeNotification # @ stub SubscribeStateChangeNotification
@ stdcall SuspendThread(long) kernel32.SuspendThread @ stdcall SuspendThread(long)
@ stdcall SwitchToFiber(ptr) kernel32.SwitchToFiber @ stdcall SwitchToFiber(ptr) kernel32.SwitchToFiber
@ stdcall SwitchToThread() kernel32.SwitchToThread @ stdcall SwitchToThread()
@ stdcall SystemTimeToFileTime(ptr ptr) kernel32.SystemTimeToFileTime @ stdcall SystemTimeToFileTime(ptr ptr) kernel32.SystemTimeToFileTime
@ stdcall SystemTimeToTzSpecificLocalTime(ptr ptr ptr) kernel32.SystemTimeToTzSpecificLocalTime @ stdcall SystemTimeToTzSpecificLocalTime(ptr ptr ptr) kernel32.SystemTimeToTzSpecificLocalTime
@ stub SystemTimeToTzSpecificLocalTimeEx @ stub SystemTimeToTzSpecificLocalTimeEx
@ stdcall TerminateProcess(long long) kernel32.TerminateProcess @ stdcall TerminateProcess(long long) kernel32.TerminateProcess
# @ stub TerminateProcessOnMemoryExhaustion # @ stub TerminateProcessOnMemoryExhaustion
@ stdcall TerminateThread(long long) kernel32.TerminateThread @ stdcall TerminateThread(long long)
@ stdcall TlsAlloc() kernel32.TlsAlloc @ stdcall TlsAlloc() kernel32.TlsAlloc
@ stdcall TlsFree(long) kernel32.TlsFree @ stdcall TlsFree(long) kernel32.TlsFree
@ stdcall TlsGetValue(long) kernel32.TlsGetValue @ stdcall TlsGetValue(long) kernel32.TlsGetValue

495
dlls/kernelbase/thread.c Normal file
View File

@ -0,0 +1,495 @@
/*
* Win32 threads
*
* Copyright 1996 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "kernelbase.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(thread);
/***********************************************************************
* Threads
***********************************************************************/
static DWORD rtlmode_to_win32mode( DWORD rtlmode )
{
DWORD win32mode = 0;
if (rtlmode & 0x10) win32mode |= SEM_FAILCRITICALERRORS;
if (rtlmode & 0x20) win32mode |= SEM_NOGPFAULTERRORBOX;
if (rtlmode & 0x40) win32mode |= SEM_NOOPENFILEERRORBOX;
return win32mode;
}
/***************************************************************************
* CreateRemoteThread (kernelbase.@)
*/
HANDLE WINAPI DECLSPEC_HOTPATCH CreateRemoteThread( HANDLE process, SECURITY_ATTRIBUTES *sa, SIZE_T stack,
LPTHREAD_START_ROUTINE start, LPVOID param,
DWORD flags, DWORD *id )
{
return CreateRemoteThreadEx( process, sa, stack, start, param, flags, NULL, id );
}
/***************************************************************************
* CreateRemoteThreadEx (kernelbase.@)
*/
HANDLE WINAPI DECLSPEC_HOTPATCH CreateRemoteThreadEx( HANDLE process, SECURITY_ATTRIBUTES *sa,
SIZE_T stack, LPTHREAD_START_ROUTINE start,
LPVOID param, DWORD flags,
LPPROC_THREAD_ATTRIBUTE_LIST attributes, DWORD *id )
{
HANDLE handle;
CLIENT_ID client_id;
NTSTATUS status;
SIZE_T stack_reserve = 0, stack_commit = 0;
if (attributes) FIXME("thread attributes ignored\n");
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
else stack_commit = stack;
status = RtlCreateUserThread( process, sa ? sa->lpSecurityDescriptor : NULL, TRUE,
NULL, stack_reserve, stack_commit,
(PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id );
if (status == STATUS_SUCCESS)
{
if (id) *id = HandleToULong( client_id.UniqueThread );
if (sa && sa->nLength >= sizeof(*sa) && sa->bInheritHandle)
SetHandleInformation( handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
if (!(flags & CREATE_SUSPENDED))
{
ULONG ret;
if (NtResumeThread( handle, &ret ))
{
NtClose( handle );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
handle = 0;
}
}
}
else
{
SetLastError( RtlNtStatusToDosError(status) );
handle = 0;
}
return handle;
}
/***********************************************************************
* CreateThread (kernelbase.@)
*/
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread( SECURITY_ATTRIBUTES *sa, SIZE_T stack,
LPTHREAD_START_ROUTINE start, LPVOID param,
DWORD flags, LPDWORD id )
{
return CreateRemoteThread( GetCurrentProcess(), sa, stack, start, param, flags, id );
}
/***********************************************************************
* FreeLibraryAndExitThread (kernelbase.@)
*/
void WINAPI DECLSPEC_HOTPATCH FreeLibraryAndExitThread( HINSTANCE module, DWORD exit_code )
{
FreeLibrary( module );
RtlExitUserThread( exit_code );
}
/***********************************************************************
* GetCurrentThreadStackLimits (kernelbase.@)
*/
void WINAPI DECLSPEC_HOTPATCH GetCurrentThreadStackLimits( ULONG_PTR *low, ULONG_PTR *high )
{
*low = (ULONG_PTR)NtCurrentTeb()->DeallocationStack;
*high = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase;
}
/***********************************************************************
* GetCurrentThread (kernelbase.@)
*/
HANDLE WINAPI kernelbase_GetCurrentThread(void)
{
return (HANDLE)~(ULONG_PTR)1;
}
/***********************************************************************
* GetCurrentThreadId (kernelbase.@)
*/
DWORD WINAPI kernelbase_GetCurrentThreadId(void)
{
return HandleToULong( NtCurrentTeb()->ClientId.UniqueThread );
}
/**********************************************************************
* GetExitCodeThread (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetExitCodeThread( HANDLE thread, LPDWORD exit_code )
{
THREAD_BASIC_INFORMATION info;
NTSTATUS status = NtQueryInformationThread( thread, ThreadBasicInformation,
&info, sizeof(info), NULL );
if (!status && exit_code) *exit_code = info.ExitStatus;
return set_ntstatus( status );
}
/**********************************************************************
* GetProcessIdOfThread (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetProcessIdOfThread( HANDLE thread )
{
THREAD_BASIC_INFORMATION tbi;
if (!set_ntstatus( NtQueryInformationThread( thread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL)))
return 0;
return HandleToULong( tbi.ClientId.UniqueProcess );
}
/***********************************************************************
* GetThreadContext (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetThreadContext( HANDLE thread, CONTEXT *context )
{
return set_ntstatus( NtGetContextThread( thread, context ));
}
/***********************************************************************
* GetThreadErrorMode (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetThreadErrorMode(void)
{
return rtlmode_to_win32mode( RtlGetThreadErrorMode() );
}
/***********************************************************************
* GetThreadGroupAffinity (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetThreadGroupAffinity( HANDLE thread, GROUP_AFFINITY *affinity )
{
if (!affinity)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
return set_ntstatus( NtQueryInformationThread( thread, ThreadGroupInformation,
affinity, sizeof(*affinity), NULL ));
}
/***********************************************************************
* GetThreadIOPendingFlag (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetThreadIOPendingFlag( HANDLE thread, PBOOL pending )
{
return set_ntstatus( NtQueryInformationThread( thread, ThreadIsIoPending,
pending, sizeof(*pending), NULL ));
}
/**********************************************************************
* GetThreadId (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetThreadId( HANDLE thread )
{
THREAD_BASIC_INFORMATION tbi;
if (!set_ntstatus( NtQueryInformationThread( thread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL)))
return 0;
return HandleToULong( tbi.ClientId.UniqueThread );
}
/**********************************************************************
* GetThreadPriority (kernelbase.@)
*/
INT WINAPI DECLSPEC_HOTPATCH GetThreadPriority( HANDLE thread )
{
THREAD_BASIC_INFORMATION info;
if (!set_ntstatus( NtQueryInformationThread( thread, ThreadBasicInformation,
&info, sizeof(info), NULL )))
return THREAD_PRIORITY_ERROR_RETURN;
return info.Priority;
}
/**********************************************************************
* GetThreadPriorityBoost (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetThreadPriorityBoost( HANDLE thread, BOOL *state )
{
if (state) *state = FALSE;
return TRUE;
}
/**********************************************************************
* GetThreadTimes (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetThreadTimes( HANDLE thread, LPFILETIME creationtime, LPFILETIME exittime,
LPFILETIME kerneltime, LPFILETIME usertime )
{
KERNEL_USER_TIMES times;
NTSTATUS status = NtQueryInformationThread( thread, ThreadTimes, &times, sizeof(times), NULL);
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
if (creationtime)
{
creationtime->dwLowDateTime = times.CreateTime.u.LowPart;
creationtime->dwHighDateTime = times.CreateTime.u.HighPart;
}
if (exittime)
{
exittime->dwLowDateTime = times.ExitTime.u.LowPart;
exittime->dwHighDateTime = times.ExitTime.u.HighPart;
}
if (kerneltime)
{
kerneltime->dwLowDateTime = times.KernelTime.u.LowPart;
kerneltime->dwHighDateTime = times.KernelTime.u.HighPart;
}
if (usertime)
{
usertime->dwLowDateTime = times.UserTime.u.LowPart;
usertime->dwHighDateTime = times.UserTime.u.HighPart;
}
return TRUE;
}
/***********************************************************************
* GetThreadUILanguage (kernelbase.@)
*/
LANGID WINAPI DECLSPEC_HOTPATCH GetThreadUILanguage(void)
{
LANGID lang;
FIXME(": stub, returning default language.\n");
NtQueryDefaultUILanguage( &lang );
return lang;
}
/***********************************************************************
* OpenThread (kernelbase.@)
*/
HANDLE WINAPI DECLSPEC_HOTPATCH OpenThread( DWORD access, BOOL inherit, DWORD id )
{
HANDLE handle;
OBJECT_ATTRIBUTES attr;
CLIENT_ID cid;
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = inherit ? OBJ_INHERIT : 0;
attr.ObjectName = NULL;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
cid.UniqueProcess = 0;
cid.UniqueThread = ULongToHandle( id );
if (!set_ntstatus( NtOpenThread( &handle, access, &attr, &cid ))) handle = 0;
return handle;
}
/* callback for QueueUserAPC */
static void CALLBACK call_user_apc( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3 )
{
PAPCFUNC func = (PAPCFUNC)arg1;
func( arg2 );
}
/***********************************************************************
* QueueUserAPC (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH QueueUserAPC( PAPCFUNC func, HANDLE thread, ULONG_PTR data )
{
return set_ntstatus( NtQueueApcThread( thread, call_user_apc, (ULONG_PTR)func, data, 0 ));
}
/**********************************************************************
* ResumeThread (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH ResumeThread( HANDLE thread )
{
DWORD ret;
if (!set_ntstatus( NtResumeThread( thread, &ret ))) ret = ~0U;
return ret;
}
/***********************************************************************
* SetThreadContext (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetThreadContext( HANDLE thread, const CONTEXT *context )
{
return set_ntstatus( NtSetContextThread( thread, context ));
}
/***********************************************************************
* SetThreadErrorMode (kernelbase.@)
*/
BOOL WINAPI SetThreadErrorMode( DWORD mode, DWORD *old )
{
NTSTATUS status;
DWORD new = 0;
if (mode & ~(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (mode & SEM_FAILCRITICALERRORS) new |= 0x10;
if (mode & SEM_NOGPFAULTERRORBOX) new |= 0x20;
if (mode & SEM_NOOPENFILEERRORBOX) new |= 0x40;
status = RtlSetThreadErrorMode( new, old );
if (!status && old) *old = rtlmode_to_win32mode( *old );
return set_ntstatus( status );
}
/***********************************************************************
* SetThreadGroupAffinity (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetThreadGroupAffinity( HANDLE thread, const GROUP_AFFINITY *new,
GROUP_AFFINITY *old )
{
if (old && !GetThreadGroupAffinity( thread, old )) return FALSE;
return set_ntstatus( NtSetInformationThread( thread, ThreadGroupInformation, new, sizeof(*new) ));
}
/**********************************************************************
* SetThreadIdealProcessor (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH SetThreadIdealProcessor( HANDLE thread, DWORD proc )
{
FIXME( "(%p %u): stub\n", thread, proc );
if (proc > MAXIMUM_PROCESSORS)
{
SetLastError( ERROR_INVALID_PARAMETER );
return ~0u;
}
return 0;
}
/***********************************************************************
* SetThreadIdealProcessorEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetThreadIdealProcessorEx( HANDLE thread, PROCESSOR_NUMBER *ideal,
PROCESSOR_NUMBER *previous )
{
FIXME( "(%p %p %p): stub\n", thread, ideal, previous );
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
}
/**********************************************************************
* SetThreadPriority (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetThreadPriority( HANDLE thread, INT priority )
{
DWORD prio = priority;
return set_ntstatus( NtSetInformationThread( thread, ThreadBasePriority, &prio, sizeof(prio) ));
}
/**********************************************************************
* SetThreadPriorityBoost (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetThreadPriorityBoost( HANDLE thread, BOOL disable )
{
return TRUE;
}
/**********************************************************************
* SetThreadStackGuarantee (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetThreadStackGuarantee( ULONG *size )
{
static int once;
if (once++ == 0) FIXME("(%p): stub\n", size);
return TRUE;
}
/**********************************************************************
* SuspendThread (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH SuspendThread( HANDLE thread )
{
DWORD ret;
if (!set_ntstatus( NtSuspendThread( thread, &ret ))) ret = ~0U;
return ret;
}
/***********************************************************************
* SwitchToThread (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SwitchToThread(void)
{
return (NtYieldExecution() != STATUS_NO_YIELD_PERFORMED);
}
/**********************************************************************
* TerminateThread (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH TerminateThread( HANDLE handle, DWORD exit_code )
{
return set_ntstatus( NtTerminateThread( handle, exit_code ));
}