Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / dll / win32 / kernel32 / client / thread.c
diff --git a/reactos/dll/win32/kernel32/client/thread.c b/reactos/dll/win32/kernel32/client/thread.c
deleted file mode 100644 (file)
index a7963e2..0000000
+++ /dev/null
@@ -1,1276 +0,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * FILE:            dll/win32/kernel32/client/thread.c
- * PURPOSE:         Thread functions
- * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
- *                  Ariadne (ariadne@xs4all.nl)
- *
- */
-
-/* INCLUDES *******************************************************************/
-
-#include <k32.h>
-
-#define NDEBUG
-#include <debug.h>
-
-#define SXS_SUPPORT_FIXME
-
-typedef NTSTATUS (NTAPI *PCSR_CREATE_REMOTE_THREAD)(IN HANDLE ThreadHandle, IN PCLIENT_ID ClientId);
-
-NTSTATUS
-WINAPI
-BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
-                       IN PCLIENT_ID ClientId);
-
-/* FUNCTIONS ******************************************************************/
-
-static
-LONG BaseThreadExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo)
-{
-    LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
-    LPTOP_LEVEL_EXCEPTION_FILTER RealFilter;
-
-    RealFilter = RtlDecodePointer(GlobalTopLevelExceptionFilter);
-    if (RealFilter != NULL)
-    {
-        _SEH2_TRY
-        {
-            ExceptionDisposition = RealFilter(ExceptionInfo);
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo);
-        }
-        _SEH2_END;
-    }
-
-    return ExceptionDisposition;
-}
-
-__declspec(noreturn)
-VOID
-WINAPI
-BaseThreadStartup(IN LPTHREAD_START_ROUTINE lpStartAddress,
-                  IN LPVOID lpParameter)
-{
-    /* Attempt to call the Thread Start Address */
-    _SEH2_TRY
-    {
-        /* Legacy check which is still used today for Win32 threads */
-        if (NtCurrentTeb()->NtTib.Version == (30 << 8)) // OS/2 V3.0 ("Cruiser")
-        {
-            /* This registers the termination port with CSRSS */
-            if (!BaseRunningInServerProcess) CsrNewThread();
-        }
-
-        /* Get the exit code from the Thread Start */
-        ExitThread((lpStartAddress)((PVOID)lpParameter));
-    }
-    _SEH2_EXCEPT(BaseThreadExceptionFilter(_SEH2_GetExceptionInformation()))
-    {
-        /* Get the Exit code from the SEH Handler */
-        if (!BaseRunningInServerProcess)
-        {
-            /* Kill the whole process, usually */
-            ExitProcess(_SEH2_GetExceptionCode());
-        }
-        else
-        {
-            /* If running inside CSRSS, kill just this thread */
-            ExitThread(_SEH2_GetExceptionCode());
-        }
-    }
-    _SEH2_END;
-}
-
-VOID
-NTAPI
-BaseDispatchApc(IN PAPCFUNC ApcRoutine,
-                IN PVOID Data,
-                IN PACTIVATION_CONTEXT ActivationContext)
-{
-    RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActivationFrame;
-
-    /* Setup the activation context */
-    ActivationFrame.Size = sizeof(ActivationFrame);
-    ActivationFrame.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER;
-
-    /* Check if caller wanted one */
-    if (ActivationContext == INVALID_ACTIVATION_CONTEXT)
-    {
-        /* Do the APC directly */
-        ApcRoutine((ULONG_PTR)Data);
-        return;
-    }
-
-    /* Then activate it */
-    RtlActivateActivationContextUnsafeFast(&ActivationFrame, ActivationContext);
-
-    /* Call the routine under SEH */
-    _SEH2_TRY
-    {
-        ApcRoutine((ULONG_PTR)Data);
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-
-    }
-    _SEH2_END;
-
-    /* Now de-activate and release the activation context */
-    RtlDeactivateActivationContextUnsafeFast(&ActivationFrame);
-    RtlReleaseActivationContext(ActivationContext);
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-/*
- * @implemented
- */
-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)
-{
-    /* Act as if we're going to create a remote thread in ourselves */
-    return CreateRemoteThread(NtCurrentProcess(),
-                              lpThreadAttributes,
-                              dwStackSize,
-                              lpStartAddress,
-                              lpParameter,
-                              dwCreationFlags,
-                              lpThreadId);
-}
-
-/*
- * @implemented
- */
-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)
-{
-    NTSTATUS Status;
-    INITIAL_TEB InitialTeb;
-    CONTEXT Context;
-    CLIENT_ID ClientId;
-    OBJECT_ATTRIBUTES LocalObjectAttributes;
-    POBJECT_ATTRIBUTES ObjectAttributes;
-    HANDLE hThread;
-    ULONG Dummy;
-    PTEB Teb;
-    THREAD_BASIC_INFORMATION ThreadBasicInfo;
-    PACTIVATION_CONTEXT_STACK ActivationContextStack = NULL;
-    ACTIVATION_CONTEXT_BASIC_INFORMATION ActCtxInfo;
-    ULONG_PTR Cookie;
-    ULONG ReturnLength;
-    DPRINT("CreateRemoteThread: hProcess: %p dwStackSize: %lu lpStartAddress"
-            ": %p lpParameter: %p, dwCreationFlags: %lx\n", hProcess,
-            dwStackSize, lpStartAddress, lpParameter, dwCreationFlags);
-
-    /* Clear the Context */
-    RtlZeroMemory(&Context, sizeof(CONTEXT));
-
-    /* Write PID */
-    ClientId.UniqueProcess = hProcess;
-
-    /* Create the Stack */
-    Status = BaseCreateStack(hProcess,
-                             dwStackSize,
-                             dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION ?
-                             dwStackSize : 0,
-                             &InitialTeb);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return NULL;
-    }
-
-    /* Create Initial Context */
-    BaseInitializeContext(&Context,
-                          lpParameter,
-                          lpStartAddress,
-                          InitialTeb.StackBase,
-                          1);
-
-    /* initialize the attributes for the thread object */
-    ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
-                                                  lpThreadAttributes,
-                                                  NULL);
-
-    /* Create the Kernel Thread Object */
-    Status = NtCreateThread(&hThread,
-                            THREAD_ALL_ACCESS,
-                            ObjectAttributes,
-                            hProcess,
-                            &ClientId,
-                            &Context,
-                            &InitialTeb,
-                            TRUE);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Fail the kernel create */
-        BaseFreeThreadStack(hProcess, &InitialTeb);
-        BaseSetLastNTError(Status);
-        return NULL;
-    }
-
-    /* Are we in the same process? */
-    if (hProcess == NtCurrentProcess())
-    {
-        /* Get the TEB */
-        Status = NtQueryInformationThread(hThread,
-                                          ThreadBasicInformation,
-                                          &ThreadBasicInfo,
-                                          sizeof(ThreadBasicInfo),
-                                          &ReturnLength);
-        if (!NT_SUCCESS(Status))
-        {
-            /* Fail */
-            ERROR_DBGBREAK("SXS: %s - Failing thread create because "
-                           "NtQueryInformationThread() failed with status %08lx\n",
-                           __FUNCTION__, Status);
-            return NULL;
-        }
-
-        /* Allocate the Activation Context Stack */
-        Status = RtlAllocateActivationContextStack(&ActivationContextStack);
-        if (!NT_SUCCESS(Status))
-        {
-            /* Fail */
-            ERROR_DBGBREAK("SXS: %s - Failing thread create because "
-                           "RtlAllocateActivationContextStack() failed with status %08lx\n",
-                           __FUNCTION__, Status);
-            return NULL;
-        }
-
-        /* Save it */
-        Teb = ThreadBasicInfo.TebBaseAddress;
-        Teb->ActivationContextStackPointer = ActivationContextStack;
-
-        /* Query the Context */
-        Status = RtlQueryInformationActivationContext(RTL_QUERY_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT,
-                                                      NULL,
-                                                      0,
-                                                      ActivationContextBasicInformation,
-                                                      &ActCtxInfo,
-                                                      sizeof(ActCtxInfo),
-                                                      &ReturnLength);
-        if (!NT_SUCCESS(Status))
-        {
-            /* Fail */
-            ERROR_DBGBREAK("SXS: %s - Failing thread create because "
-                           "RtlQueryInformationActivationContext() failed with status %08lx\n",
-                           __FUNCTION__, Status);
-
-            /* Free the activation context stack */
-            // RtlFreeThreadActivationContextStack();
-            RtlFreeActivationContextStack(Teb->ActivationContextStackPointer);
-
-            return NULL;
-        }
-
-        /* Does it need to be activated? */
-        if ((ActCtxInfo.hActCtx) && !(ActCtxInfo.dwFlags & 1))
-        {
-            /* Activate it */
-            Status = RtlActivateActivationContextEx(RTL_ACTIVATE_ACTIVATION_CONTEXT_EX_FLAG_RELEASE_ON_STACK_DEALLOCATION,
-                                                    Teb,
-                                                    ActCtxInfo.hActCtx,
-                                                    &Cookie);
-            if (!NT_SUCCESS(Status))
-            {
-                /* Fail */
-                ERROR_DBGBREAK("SXS: %s - Failing thread create because "
-                               "RtlActivateActivationContextEx() failed with status %08lx\n",
-                               __FUNCTION__, Status);
-
-                /* Free the activation context stack */
-                // RtlFreeThreadActivationContextStack();
-                RtlFreeActivationContextStack(Teb->ActivationContextStackPointer);
-
-                return NULL;
-            }
-        }
-    }
-
-    /* Notify CSR */
-    if (!BaseRunningInServerProcess)
-    {
-        Status = BasepNotifyCsrOfThread(hThread, &ClientId);
-        ASSERT(NT_SUCCESS(Status));
-    }
-    else
-    {
-        if (hProcess != NtCurrentProcess())
-        {
-            PCSR_CREATE_REMOTE_THREAD CsrCreateRemoteThread;
-
-            /* Get the direct CSRSRV export */
-            CsrCreateRemoteThread = (PCSR_CREATE_REMOTE_THREAD)
-                                    GetProcAddress(GetModuleHandleA("csrsrv"),
-                                                   "CsrCreateRemoteThread");
-            if (CsrCreateRemoteThread)
-            {
-                /* Call it instead of going through LPC */
-                Status = CsrCreateRemoteThread(hThread, &ClientId);
-                ASSERT(NT_SUCCESS(Status));
-            }
-        }
-    }
-
-    /* Success */
-    if (lpThreadId) *lpThreadId = HandleToUlong(ClientId.UniqueThread);
-
-    /* Resume it if asked */
-    if (!(dwCreationFlags & CREATE_SUSPENDED)) NtResumeThread(hThread, &Dummy);
-
-    /* Return handle to thread */
-    return hThread;
-}
-
-/*
- * @implemented
- */
-VOID
-WINAPI
-ExitThread(IN DWORD uExitCode)
-{
-    NTSTATUS Status;
-    ULONG LastThread;
-    PRTL_CRITICAL_SECTION LoaderLock;
-
-    /* Make sure loader lock isn't held */
-    LoaderLock = NtCurrentPeb()->LoaderLock;
-    if (LoaderLock) ASSERT(NtCurrentTeb()->ClientId.UniqueThread != LoaderLock->OwningThread);
-
-    /*
-     * Terminate process if this is the last thread
-     * of the current process
-     */
-    Status = NtQueryInformationThread(NtCurrentThread(),
-                                      ThreadAmILastThread,
-                                      &LastThread,
-                                      sizeof(LastThread),
-                                      NULL);
-    if ((NT_SUCCESS(Status)) && (LastThread)) ExitProcess(uExitCode);
-
-    /* Notify DLLs and TLS Callbacks of termination */
-    LdrShutdownThread();
-
-    /* Tell the Kernel to free the Stack */
-    NtCurrentTeb()->FreeStackOnTermination = TRUE;
-    NtTerminateThread(NULL, uExitCode);
-
-    /* We should never reach this place */
-    ERROR_FATAL("It should not happen\n");
-    while (TRUE); /* 'noreturn' function */
-}
-
-/*
- * @implemented
- */
-HANDLE
-WINAPI
-OpenThread(IN DWORD dwDesiredAccess,
-           IN BOOL bInheritHandle,
-           IN DWORD dwThreadId)
-{
-    NTSTATUS Status;
-    HANDLE ThreadHandle;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    CLIENT_ID ClientId;
-
-    ClientId.UniqueProcess = 0;
-    ClientId.UniqueThread = ULongToHandle(dwThreadId);
-
-    InitializeObjectAttributes(&ObjectAttributes,
-                               NULL,
-                               (bInheritHandle ? OBJ_INHERIT : 0),
-                               NULL,
-                               NULL);
-
-    Status = NtOpenThread(&ThreadHandle,
-                          dwDesiredAccess,
-                          &ObjectAttributes,
-                          &ClientId);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return NULL;
-    }
-
-    return ThreadHandle;
-}
-
-/*
- * @implemented
- */
-PTEB
-GetTeb(VOID)
-{
-    return NtCurrentTeb();
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-SwitchToThread(VOID)
-{
-    return NtYieldExecution() != STATUS_NO_YIELD_PERFORMED;
-}
-
-
-/*
- * @implemented
- */
-DWORD
-WINAPI
-GetCurrentThreadId(VOID)
-{
-    return HandleToUlong(NtCurrentTeb()->ClientId.UniqueThread);
-}
-
-/*
- * @implemented
- */
-BOOL
-NTAPI
-GetThreadTimes(IN HANDLE hThread,
-               OUT LPFILETIME lpCreationTime,
-               OUT LPFILETIME lpExitTime,
-               OUT LPFILETIME lpKernelTime,
-               OUT LPFILETIME lpUserTime)
-{
-    KERNEL_USER_TIMES KernelUserTimes;
-    NTSTATUS Status;
-
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadTimes,
-                                      &KernelUserTimes,
-                                      sizeof(KERNEL_USER_TIMES),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    *lpCreationTime = *(LPFILETIME)&KernelUserTimes.CreateTime;
-    *lpExitTime = *(LPFILETIME)&KernelUserTimes.ExitTime;
-    *lpKernelTime = *(LPFILETIME)&KernelUserTimes.KernelTime;
-    *lpUserTime = *(LPFILETIME)&KernelUserTimes.UserTime;
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-GetThreadContext(IN HANDLE hThread,
-                 OUT LPCONTEXT lpContext)
-{
-    NTSTATUS Status;
-
-    Status = NtGetContextThread(hThread, lpContext);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-SetThreadContext(IN HANDLE hThread,
-                 IN CONST CONTEXT *lpContext)
-{
-    NTSTATUS Status;
-
-    Status = NtSetContextThread(hThread, (PCONTEXT)lpContext);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-GetExitCodeThread(IN HANDLE hThread,
-                  OUT LPDWORD lpExitCode)
-{
-    THREAD_BASIC_INFORMATION ThreadBasic;
-    NTSTATUS Status;
-
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadBasicInformation,
-                                      &ThreadBasic,
-                                      sizeof(THREAD_BASIC_INFORMATION),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    *lpExitCode = ThreadBasic.ExitStatus;
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-DWORD
-WINAPI
-ResumeThread(IN HANDLE hThread)
-{
-    ULONG PreviousResumeCount;
-    NTSTATUS Status;
-
-    Status = NtResumeThread(hThread, &PreviousResumeCount);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return -1;
-    }
-
-    return PreviousResumeCount;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-TerminateThread(IN HANDLE hThread,
-                IN DWORD dwExitCode)
-{
-    NTSTATUS Status;
-#if DBG
-    PRTL_CRITICAL_SECTION LoaderLock;
-    THREAD_BASIC_INFORMATION ThreadInfo;
-#endif /* DBG */
-
-    /* Check for invalid thread handle */
-    if (!hThread)
-    {
-        /* Fail if one was passed */
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-#if DBG
-    /* Get the loader lock */
-    LoaderLock = NtCurrentPeb()->LoaderLock;
-    if (LoaderLock)
-    {
-        /* Get our TID */
-        Status = NtQueryInformationThread(hThread,
-                                          ThreadBasicInformation,
-                                          &ThreadInfo,
-                                          sizeof(ThreadInfo),
-                                          NULL);
-        if (NT_SUCCESS(Status))
-        {
-            /* If terminating the current thread, we must not hold the loader lock */
-            if (NtCurrentTeb()->ClientId.UniqueThread == ThreadInfo.ClientId.UniqueThread)
-                ASSERT(NtCurrentTeb()->ClientId.UniqueThread != LoaderLock->OwningThread);
-        }
-    }
-#endif /* DBG */
-
-    /* Now terminate the thread */
-    Status = NtTerminateThread(hThread, dwExitCode);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Fail */
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    /* All done */
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-DWORD
-WINAPI
-SuspendThread(IN HANDLE hThread)
-{
-    ULONG PreviousSuspendCount;
-    NTSTATUS Status;
-
-    Status = NtSuspendThread(hThread, &PreviousSuspendCount);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return -1;
-    }
-
-    return PreviousSuspendCount;
-}
-
-/*
- * @implemented
- */
-DWORD_PTR
-WINAPI
-SetThreadAffinityMask(IN HANDLE hThread,
-                      IN DWORD_PTR dwThreadAffinityMask)
-{
-    THREAD_BASIC_INFORMATION ThreadBasic;
-    KAFFINITY AffinityMask;
-    NTSTATUS Status;
-
-    AffinityMask = (KAFFINITY)dwThreadAffinityMask;
-
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadBasicInformation,
-                                      &ThreadBasic,
-                                      sizeof(THREAD_BASIC_INFORMATION),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return 0;
-    }
-
-    Status = NtSetInformationThread(hThread,
-                                    ThreadAffinityMask,
-                                    &AffinityMask,
-                                    sizeof(KAFFINITY));
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        ThreadBasic.AffinityMask = 0;
-    }
-
-    return ThreadBasic.AffinityMask;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-SetThreadPriority(IN HANDLE hThread,
-                  IN int nPriority)
-{
-    LONG Prio = nPriority;
-    NTSTATUS Status;
-
-    /* Check if values forcing saturation should be used */
-    if (Prio == THREAD_PRIORITY_TIME_CRITICAL)
-    {
-        /* This is 16 */
-        Prio = (HIGH_PRIORITY + 1) / 2;
-    }
-    else if (Prio == THREAD_PRIORITY_IDLE)
-    {
-        /* This is -16 */
-        Prio = -((HIGH_PRIORITY + 1) / 2);
-    }
-
-    /* Set the Base Priority */
-    Status = NtSetInformationThread(hThread,
-                                    ThreadBasePriority,
-                                    &Prio,
-                                    sizeof(LONG));
-    if (!NT_SUCCESS(Status))
-    {
-        /* Failure */
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    /* Return */
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-int
-WINAPI
-GetThreadPriority(IN HANDLE hThread)
-{
-    THREAD_BASIC_INFORMATION ThreadBasic;
-    NTSTATUS Status;
-
-    /* Query the Base Priority Increment */
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadBasicInformation,
-                                      &ThreadBasic,
-                                      sizeof(THREAD_BASIC_INFORMATION),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Failure */
-        BaseSetLastNTError(Status);
-        return THREAD_PRIORITY_ERROR_RETURN;
-    }
-
-    /* Do some conversions for saturation values */
-    if (ThreadBasic.BasePriority == ((HIGH_PRIORITY + 1) / 2))
-    {
-        /* Win32 calls this "time critical" */
-        ThreadBasic.BasePriority = THREAD_PRIORITY_TIME_CRITICAL;
-    }
-    else if (ThreadBasic.BasePriority == -((HIGH_PRIORITY + 1) / 2))
-    {
-        /* Win32 calls this "idle" */
-        ThreadBasic.BasePriority = THREAD_PRIORITY_IDLE;
-    }
-
-    /* Return the final result */
-    return ThreadBasic.BasePriority;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-GetThreadPriorityBoost(IN HANDLE hThread,
-                       OUT PBOOL pDisablePriorityBoost)
-{
-    ULONG PriorityBoost;
-    NTSTATUS Status;
-
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadPriorityBoost,
-                                      &PriorityBoost,
-                                      sizeof(ULONG),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    *pDisablePriorityBoost = PriorityBoost;
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-NTAPI
-SetThreadPriorityBoost(IN HANDLE hThread,
-                       IN BOOL bDisablePriorityBoost)
-{
-    ULONG PriorityBoost;
-    NTSTATUS Status;
-
-    PriorityBoost = bDisablePriorityBoost != FALSE;
-
-    Status = NtSetInformationThread(hThread,
-                                    ThreadPriorityBoost,
-                                    &PriorityBoost,
-                                    sizeof(ULONG));
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-GetThreadSelectorEntry(IN HANDLE hThread,
-                       IN DWORD dwSelector,
-                       OUT LPLDT_ENTRY lpSelectorEntry)
-{
-#ifdef _M_IX86
-    DESCRIPTOR_TABLE_ENTRY DescriptionTableEntry;
-    NTSTATUS Status;
-
-    /* Set the selector and do the query */
-    DescriptionTableEntry.Selector = dwSelector;
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadDescriptorTableEntry,
-                                      &DescriptionTableEntry,
-                                      sizeof(DESCRIPTOR_TABLE_ENTRY),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Fail */
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    /* Success, return the selector */
-    *lpSelectorEntry = DescriptionTableEntry.Descriptor;
-    return TRUE;
-#else
-    DPRINT1("Calling GetThreadSelectorEntry!\n");
-    return FALSE;
-#endif
-}
-
-/*
- * @implemented
- */
-DWORD
-WINAPI
-SetThreadIdealProcessor(IN HANDLE hThread,
-                        IN DWORD dwIdealProcessor)
-{
-    NTSTATUS Status;
-
-    Status = NtSetInformationThread(hThread,
-                                    ThreadIdealProcessor,
-                                    &dwIdealProcessor,
-                                    sizeof(ULONG));
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return -1;
-    }
-
-    return (DWORD)Status;
-}
-
-/*
- * @implemented
- */
-DWORD
-WINAPI
-GetProcessIdOfThread(IN HANDLE Thread)
-{
-    THREAD_BASIC_INFORMATION ThreadBasic;
-    NTSTATUS Status;
-
-    Status = NtQueryInformationThread(Thread,
-                                      ThreadBasicInformation,
-                                      &ThreadBasic,
-                                      sizeof(THREAD_BASIC_INFORMATION),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return 0;
-    }
-
-    return HandleToUlong(ThreadBasic.ClientId.UniqueProcess);
-}
-
-/*
- * @implemented
- */
-DWORD
-WINAPI
-GetThreadId(IN HANDLE Thread)
-{
-    THREAD_BASIC_INFORMATION ThreadBasic;
-    NTSTATUS Status;
-
-    Status = NtQueryInformationThread(Thread,
-                                      ThreadBasicInformation,
-                                      &ThreadBasic,
-                                      sizeof(THREAD_BASIC_INFORMATION),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return 0;
-    }
-
-    return HandleToUlong(ThreadBasic.ClientId.UniqueThread);
-}
-
-/*
- * @unimplemented
- */
-LANGID
-WINAPI
-SetThreadUILanguage(IN LANGID LangId)
-{
-    UNIMPLEMENTED;
-    return (LANGID)NtCurrentTeb()->CurrentLocale;
-}
-
-/*
- * @implemented
- */
-DWORD
-WINAPI
-QueueUserAPC(IN PAPCFUNC pfnAPC,
-             IN HANDLE hThread,
-             IN ULONG_PTR dwData)
-{
-    NTSTATUS Status;
-    ACTIVATION_CONTEXT_BASIC_INFORMATION ActCtxInfo;
-
-    /* Zero the activation context and query information on it */
-    RtlZeroMemory(&ActCtxInfo, sizeof(ActCtxInfo));
-    Status = RtlQueryInformationActivationContext(RTL_QUERY_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT,
-                                                  NULL,
-                                                  0,
-                                                  ActivationContextBasicInformation,
-                                                  &ActCtxInfo,
-                                                  sizeof(ActCtxInfo),
-                                                  NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Fail due to SxS */
-        DbgPrint("SXS: %s failing because RtlQueryInformationActivationContext()"
-                 "returned status %08lx\n", __FUNCTION__, Status);
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    /* Queue the APC */
-    Status = NtQueueApcThread(hThread,
-                              (PKNORMAL_ROUTINE)BaseDispatchApc,
-                              pfnAPC,
-                              (PVOID)dwData,
-                              (ActCtxInfo.dwFlags & 1) ?
-                              INVALID_ACTIVATION_CONTEXT : ActCtxInfo.hActCtx);
-    if (!NT_SUCCESS(Status))
-    {
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    /* All good */
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-SetThreadStackGuarantee(IN OUT PULONG StackSizeInBytes)
-{
-    static int once;
-    if (once++ == 0)
-         DPRINT1("SetThreadStackGuarantee(%p): stub\n", StackSizeInBytes);
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-GetThreadIOPendingFlag(IN HANDLE hThread,
-                       OUT PBOOL lpIOIsPending)
-{
-    ULONG IoPending;
-    NTSTATUS Status;
-
-    /* Query the flag */
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadIsIoPending,
-                                      &IoPending,
-                                      sizeof(IoPending),
-                                      NULL);
-    if (NT_SUCCESS(Status))
-    {
-        /* Return the flag */
-        *lpIOIsPending = IoPending ? TRUE : FALSE;
-        return TRUE;
-    }
-
-    /* Fail */
-    BaseSetLastNTError(Status);
-    return FALSE;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-QueueUserWorkItem(IN LPTHREAD_START_ROUTINE Function,
-                  IN PVOID Context,
-                  IN ULONG Flags)
-{
-    NTSTATUS Status;
-
-    /* NOTE: Rtl needs to safely call the function using a trampoline */
-    Status = RtlQueueWorkItem((WORKERCALLBACKFUNC)Function, Context, Flags);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Failed */
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
-
-    /* All good */
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-DWORD
-WINAPI
-TlsAlloc(VOID)
-{
-    ULONG Index;
-    PTEB Teb;
-    PPEB Peb;
-
-    /* Get the PEB and TEB, lock the PEB */
-    Teb = NtCurrentTeb();
-    Peb = Teb->ProcessEnvironmentBlock;
-    RtlAcquirePebLock();
-
-    /* Try to get regular TEB slot */
-    Index = RtlFindClearBitsAndSet(Peb->TlsBitmap, 1, 0);
-    if (Index != 0xFFFFFFFF)
-    {
-        /* Clear the value. */
-        Teb->TlsSlots[Index] = 0;
-        RtlReleasePebLock();
-        return Index;
-    }
-
-    /* If it fails, try to find expansion TEB slot. */
-    Index = RtlFindClearBitsAndSet(Peb->TlsExpansionBitmap, 1, 0);
-    if (Index != 0xFFFFFFFF)
-    {
-        /* Is there no expansion slot yet? */
-        if (!Teb->TlsExpansionSlots)
-        {
-            /* Allocate an array */
-            Teb->TlsExpansionSlots = RtlAllocateHeap(RtlGetProcessHeap(),
-                                                     HEAP_ZERO_MEMORY,
-                                                     TLS_EXPANSION_SLOTS *
-                                                     sizeof(PVOID));
-        }
-
-        /* Did we get an array? */
-        if (!Teb->TlsExpansionSlots)
-        {
-            /* Fail */
-            RtlClearBits(Peb->TlsExpansionBitmap, Index, 1);
-            Index = 0xFFFFFFFF;
-            BaseSetLastNTError(STATUS_NO_MEMORY);
-        }
-        else
-        {
-            /* Clear the value. */
-            Teb->TlsExpansionSlots[Index] = 0;
-            Index += TLS_MINIMUM_AVAILABLE;
-        }
-    }
-    else
-    {
-        /* Fail */
-        BaseSetLastNTError(STATUS_NO_MEMORY);
-    }
-
-    /* Release the lock and return */
-    RtlReleasePebLock();
-    return Index;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-TlsFree(IN DWORD Index)
-{
-    BOOL BitSet;
-    PPEB Peb;
-    ULONG TlsIndex;
-    PVOID TlsBitmap;
-    NTSTATUS Status;
-
-    /* Acquire the PEB lock and grab the PEB */
-    Peb = NtCurrentPeb();
-    RtlAcquirePebLock();
-
-    /* Check if the index is too high */
-    if (Index >= TLS_MINIMUM_AVAILABLE)
-    {
-        /* Check if it can fit in the expansion slots */
-        TlsIndex = Index - TLS_MINIMUM_AVAILABLE;
-        if (TlsIndex >= TLS_EXPANSION_SLOTS)
-        {
-            /* It's invalid */
-            BaseSetLastNTError(STATUS_INVALID_PARAMETER);
-            RtlReleasePebLock();
-            return FALSE;
-        }
-        else
-        {
-            /* Use the expansion bitmap */
-            TlsBitmap = Peb->TlsExpansionBitmap;
-            Index = TlsIndex;
-        }
-    }
-    else
-    {
-        /* Use the normal bitmap */
-        TlsBitmap = Peb->TlsBitmap;
-    }
-
-    /* Check if the index was set */
-    BitSet = RtlAreBitsSet(TlsBitmap, Index, 1);
-    if (BitSet)
-    {
-        /* Tell the kernel to free the TLS cells */
-        Status = NtSetInformationThread(NtCurrentThread(),
-                                        ThreadZeroTlsCell,
-                                        &Index,
-                                        sizeof(DWORD));
-        if (!NT_SUCCESS(Status))
-        {
-            BaseSetLastNTError(STATUS_INVALID_PARAMETER);
-            RtlReleasePebLock();
-            return FALSE;
-        }
-
-        /* Clear the bit */
-        RtlClearBits(TlsBitmap, Index, 1);
-    }
-    else
-    {
-        /* Fail */
-        BaseSetLastNTError(STATUS_INVALID_PARAMETER);
-        RtlReleasePebLock();
-        return FALSE;
-    }
-
-    /* Done! */
-    RtlReleasePebLock();
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-LPVOID
-WINAPI
-TlsGetValue(IN DWORD Index)
-{
-    PTEB Teb;
-
-    /* Get the TEB and clear the last error */
-    Teb = NtCurrentTeb();
-    Teb->LastErrorValue = 0;
-
-    /* Check for simple TLS index */
-    if (Index < TLS_MINIMUM_AVAILABLE)
-    {
-        /* Return it */
-        return Teb->TlsSlots[Index];
-    }
-
-    /* Check for valid index */
-    if (Index >= TLS_EXPANSION_SLOTS + TLS_MINIMUM_AVAILABLE)
-    {
-        /* Fail */
-        BaseSetLastNTError(STATUS_INVALID_PARAMETER);
-        return NULL;
-    }
-
-    /* The expansion slots are allocated on demand, so check for it. */
-    Teb->LastErrorValue = 0;
-    if (!Teb->TlsExpansionSlots) return NULL;
-
-    /* Return the value from the expansion slots */
-    return Teb->TlsExpansionSlots[Index - TLS_MINIMUM_AVAILABLE];
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-TlsSetValue(IN DWORD Index,
-            IN LPVOID Value)
-{
-    DWORD TlsIndex;
-    PTEB Teb = NtCurrentTeb();
-
-    /* Check for simple TLS index */
-    if (Index < TLS_MINIMUM_AVAILABLE)
-    {
-        /* Return it */
-        Teb->TlsSlots[Index] = Value;
-        return TRUE;
-    }
-
-    /* Check if this is an expansion slot */
-    TlsIndex = Index - TLS_MINIMUM_AVAILABLE;
-    if (TlsIndex >= TLS_EXPANSION_SLOTS)
-    {
-        /* Fail */
-        BaseSetLastNTError(STATUS_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    /* Do we not have expansion slots? */
-    if (!Teb->TlsExpansionSlots)
-    {
-        /* Get the PEB lock to see if we still need them */
-        RtlAcquirePebLock();
-        if (!Teb->TlsExpansionSlots)
-        {
-            /* Allocate them */
-            Teb->TlsExpansionSlots = RtlAllocateHeap(RtlGetProcessHeap(),
-                                                     HEAP_ZERO_MEMORY,
-                                                     TLS_EXPANSION_SLOTS *
-                                                     sizeof(PVOID));
-            if (!Teb->TlsExpansionSlots)
-            {
-                /* Fail */
-                RtlReleasePebLock();
-                BaseSetLastNTError(STATUS_NO_MEMORY);
-                return FALSE;
-            }
-        }
-
-        /* Release the lock */
-        RtlReleasePebLock();
-    }
-
-    /* Write the value */
-    Teb->TlsExpansionSlots[TlsIndex] = Value;
-
-    /* Success */
-    return TRUE;
-}
-
-/* EOF */