/** * WinPR: Windows Portable Runtime * Process Thread Functions * * Copyright 2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include /** * api-ms-win-core-processthreads-l1-1-1.dll * * CreateRemoteThread * CreateRemoteThreadEx * CreateThread * DeleteProcThreadAttributeList * ExitThread * FlushInstructionCache * FlushProcessWriteBuffers * GetCurrentThread * GetCurrentThreadId * GetCurrentThreadStackLimits * GetExitCodeThread * GetPriorityClass * GetStartupInfoW * GetThreadContext * GetThreadId * GetThreadIdealProcessorEx * GetThreadPriority * GetThreadPriorityBoost * GetThreadTimes * InitializeProcThreadAttributeList * OpenThread * OpenThreadToken * QueryProcessAffinityUpdateMode * QueueUserAPC * ResumeThread * SetPriorityClass * SetThreadContext * SetThreadPriority * SetThreadPriorityBoost * SetThreadStackGuarantee * SetThreadToken * SuspendThread * SwitchToThread * TerminateThread * UpdateProcThreadAttribute */ #ifndef _WIN32 #include #include /** * TODO: implement thread suspend/resume using pthreads * http://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition */ typedef void *(*pthread_start_routine)(void*); struct winpr_thread { BOOL started; pthread_t thread; SIZE_T dwStackSize; LPVOID lpParameter; pthread_mutex_t mutex; LPTHREAD_START_ROUTINE lpStartAddress; LPSECURITY_ATTRIBUTES lpThreadAttributes; }; typedef struct winpr_thread WINPR_THREAD; void winpr_StartThread(WINPR_THREAD* thread) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (thread->dwStackSize > 0) pthread_attr_setstacksize(&attr, (size_t) thread->dwStackSize); thread->started = TRUE; pthread_create(&thread->thread, &attr, (pthread_start_routine) thread->lpStartAddress, thread->lpParameter); pthread_attr_destroy(&attr); } HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) { HANDLE handle; WINPR_THREAD* thread; thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD)); ZeroMemory(thread, sizeof(WINPR_THREAD)); thread->started = FALSE; thread->dwStackSize = dwStackSize; thread->lpParameter = lpParameter; thread->lpStartAddress = lpStartAddress; thread->lpThreadAttributes = lpThreadAttributes; pthread_mutex_init(&thread->mutex, 0); handle = winpr_Handle_Insert(HANDLE_TYPE_THREAD, (void*) thread); if (!(dwCreationFlags & CREATE_SUSPENDED)) winpr_StartThread(thread); return handle; } HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) { return NULL; } VOID ExitThread(DWORD dwExitCode) { pthread_exit((void*) dwExitCode); } HANDLE GetCurrentThread(VOID) { return NULL; } DWORD GetCurrentThreadId(VOID) { return 0; } DWORD ResumeThread(HANDLE hThread) { ULONG Type; PVOID Object; WINPR_THREAD* thread; if (!winpr_Handle_GetInfo(hThread, &Type, &Object)) return 0; thread = (WINPR_THREAD*) Object; pthread_mutex_lock(&thread->mutex); if (!thread->started) winpr_StartThread(thread); pthread_mutex_unlock(&thread->mutex); return 0; } DWORD SuspendThread(HANDLE hThread) { return 0; } BOOL SwitchToThread(VOID) { return TRUE; } BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode) { ULONG Type; PVOID Object; WINPR_THREAD* thread; if (!winpr_Handle_GetInfo(hThread, &Type, &Object)) return 0; thread = (WINPR_THREAD*) Object; pthread_mutex_lock(&thread->mutex); pthread_cancel(thread->thread); pthread_mutex_unlock(&thread->mutex); return TRUE; } #endif