/* INCLUDES ******************************************************************/
-#include <windows.h>
-#include <kernel32/thread.h>
-#include <ntdll/ldr.h>
-#include <string.h>
-#include <napi/i386/segment.h>
+#include <k32.h>
#define NDEBUG
#include <kernel32/kernel32.h>
-#include <kernel32/error.h>
-
-static VOID ThreadAttachDlls (VOID);
+//static VOID ThreadAttachDlls (VOID);
/* FUNCTIONS *****************************************************************/
-static\r
-EXCEPTION_DISPOSITION\r
-__cdecl\r
-_except_handler(\r
- struct _EXCEPTION_RECORD *ExceptionRecord,\r
- void * EstablisherFrame,\r
- struct _CONTEXT *ContextRecord,\r
- void * DispatcherContext )\r
-{\r
- ExitThread(0);
-
- /* We should not get to here */
- return ExceptionContinueSearch;
-}\r
+/* FIXME: please put this in some header */
+static EXCEPTION_DISPOSITION __cdecl
+_except_handler(EXCEPTION_RECORD *ExceptionRecord,
+ void * EstablisherFrame,
+ CONTEXT *ContextRecord,
+ void * DispatcherContext)
+{
+ ExitThread(0);
+
+ /* We should not get to here */
+ return(ExceptionContinueSearch);
+}
+
static VOID STDCALL
-ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress,
- LPVOID lpParameter)
+ThreadStartup(LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter)
{
- UINT uExitCode;
+ UINT uExitCode;
+
+ __try1(_except_handler)
+ {
+ /* FIXME: notify csrss of thread creation ?? */
+ uExitCode = (lpStartAddress)(lpParameter);
+ }
+ __except1
+ {
+ }
+
+ ExitThread(uExitCode);
+}
- __try1(_except_handler)
- {
- /* FIXME: notify csrss of thread creation ?? */
- uExitCode = (lpStartAddress)(lpParameter);
- } __except1
- {
- }
- ExitThread(uExitCode);
+HANDLE STDCALL CreateThread
+(
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ DWORD dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter,
+ DWORD dwCreationFlags,
+ LPDWORD lpThreadId
+)
+{
+ return CreateRemoteThread
+ (
+ NtCurrentProcess(),
+ lpThreadAttributes,
+ dwStackSize,
+ lpStartAddress,
+ lpParameter,
+ dwCreationFlags,
+ lpThreadId
+ );
}
-HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
- DWORD dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress,
- LPVOID lpParameter,
- DWORD dwCreationFlags,
- LPDWORD lpThreadId)
+
+HANDLE STDCALL CreateRemoteThread
+(
+ HANDLE hProcess,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ DWORD dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter,
+ DWORD dwCreationFlags,
+ LPDWORD lpThreadId
+)
{
- return(CreateRemoteThread(NtCurrentProcess(),
- lpThreadAttributes,
- dwStackSize,
- lpStartAddress,
- lpParameter,
- dwCreationFlags,
- lpThreadId));
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ HANDLE hThread;
+ CLIENT_ID cidClientId;
+ NTSTATUS nErrCode;
+ ULONG_PTR nStackReserve;
+ ULONG_PTR nStackCommit;
+ OBJECT_ATTRIBUTES oaThreadAttribs;
+ PIMAGE_NT_HEADERS pinhHeader =
+ RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
+
+ DPRINT
+ (
+ "hProcess %08X\n"
+ "lpThreadAttributes %08X\n"
+ "dwStackSize %08X\n"
+ "lpStartAddress %08X\n"
+ "lpParameter %08X\n"
+ "dwCreationFlags %08X\n"
+ "lpThreadId %08X\n",
+ hProcess,
+ lpThreadAttributes,
+ dwStackSize,
+ lpStartAddress,
+ lpParameter,
+ dwCreationFlags,
+ lpThreadId
+ );
+
+ /* FIXME: do more checks - e.g. the image may not have an optional header */
+ if(pinhHeader == NULL)
+ {
+ nStackReserve = 0x100000;
+ nStackCommit = PAGE_SIZE;
+ }
+ else
+ {
+ nStackReserve = pinhHeader->OptionalHeader.SizeOfStackReserve;
+ nStackCommit = pinhHeader->OptionalHeader.SizeOfStackCommit;
+ }
+
+ /* FIXME: this should be defined in winbase.h */
+#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
+#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
+#endif
+
+ /* use defaults */
+ if(dwStackSize == 0);
+ /* dwStackSize specifies the size to reserve */
+ else if(dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION)
+ nStackReserve = dwStackSize;
+ /* dwStackSize specifies the size to commit */
+ else
+ nStackCommit = dwStackSize;
+
+ /* fix the stack reserve size */
+ if(nStackCommit > nStackReserve)
+ nStackReserve = ROUNDUP(nStackCommit, 0x100000);
+
+ /* initialize the attributes for the thread object */
+ InitializeObjectAttributes
+ (
+ &oaThreadAttribs,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ );
+
+ if(lpThreadAttributes)
+ {
+ /* make the handle inheritable */
+ if(lpThreadAttributes->bInheritHandle)
+ oaThreadAttribs.Attributes |= OBJ_INHERIT;
+
+ /* user-defined security descriptor */
+ oaThreadAttribs.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
+ }
+
+ DPRINT
+ (
+ "RtlRosCreateUserThreadVa\n"
+ "(\n"
+ " ProcessHandle %p,\n"
+ " ObjectAttributes %p,\n"
+ " CreateSuspended %d,\n"
+ " StackZeroBits %d,\n"
+ " StackReserve %lu,\n"
+ " StackCommit %lu,\n"
+ " StartAddress %p,\n"
+ " ThreadHandle %p,\n"
+ " ClientId %p,\n"
+ " ParameterCount %u,\n"
+ " Parameters[0] %p,\n"
+ " Parameters[1] %p\n"
+ ")\n",
+ hProcess,
+ &oaThreadAttribs,
+ dwCreationFlags & CREATE_SUSPENDED,
+ 0,
+ nStackReserve,
+ nStackCommit,
+ ThreadStartup,
+ &hThread,
+ &cidClientId,
+ 2,
+ lpStartAddress,
+ lpParameter
+ );
+
+ /* create the thread */
+ nErrCode = RtlRosCreateUserThreadVa
+ (
+ hProcess,
+ &oaThreadAttribs,
+ dwCreationFlags & CREATE_SUSPENDED,
+ 0,
+ &nStackReserve,
+ &nStackCommit,
+ (PTHREAD_START_ROUTINE)ThreadStartup,
+ &hThread,
+ &cidClientId,
+ 2,
+ lpStartAddress,
+ lpParameter
+ );
+
+ /* failure */
+ if(!NT_SUCCESS(nErrCode))
+ {
+ SetLastErrorByStatus(nErrCode);
+ return NULL;
+ }
+
+ DPRINT
+ (
+ "StackReserve %p\n"
+ "StackCommit %p\n"
+ "ThreadHandle %p\n"
+ "ClientId.UniqueThread %p\n",
+ nStackReserve,
+ nStackCommit,
+ hThread,
+ cidClientId.UniqueThread
+ );
+
+ /* success */
+ if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;
+ return hThread;
}
-HANDLE STDCALL CreateRemoteThread(HANDLE hProcess,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- DWORD dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress,
- LPVOID lpParameter,
- DWORD dwCreationFlags,
- LPDWORD lpThreadId)
+PTEB
+GetTeb(VOID)
{
- HANDLE ThreadHandle;
- OBJECT_ATTRIBUTES ObjectAttributes;
- CLIENT_ID ClientId;
- CONTEXT ThreadContext;
- INITIAL_TEB InitialTeb;
- BOOLEAN CreateSuspended = FALSE;
- PVOID BaseAddress;
- ULONG OldPageProtection;
- NTSTATUS Status;
-
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = NULL;
- ObjectAttributes.Attributes = 0;
- if (lpThreadAttributes != NULL)
- {
- if (lpThreadAttributes->bInheritHandle)
- ObjectAttributes.Attributes = OBJ_INHERIT;
- ObjectAttributes.SecurityDescriptor =
- lpThreadAttributes->lpSecurityDescriptor;
- }
- ObjectAttributes.SecurityQualityOfService = NULL;
-
- if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED)
- CreateSuspended = TRUE;
- else
- CreateSuspended = FALSE;
-
- InitialTeb.StackReserve = 0x100000; /* 1MByte */
- /* FIXME: use correct commit size */
-#if 0
- InitialTeb.StackCommit = (dwStackSize == 0) ? PAGE_SIZE : dwStackSize;
-#endif
- InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE;
-
- /* size of guard page */
- InitialTeb.StackCommit += PAGE_SIZE;
-
- /* Reserve stack */
- InitialTeb.StackAllocate = NULL;
- Status = NtAllocateVirtualMemory(hProcess,
- &InitialTeb.StackAllocate,
- 0,
- &InitialTeb.StackReserve,
- MEM_RESERVE,
- PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
+ return(NtCurrentTeb());
+}
+
+
+WINBOOL STDCALL
+SwitchToThread(VOID)
+{
+ NTSTATUS errCode;
+ errCode = NtYieldExecution();
+ return TRUE;
+}
+
+
+DWORD STDCALL
+GetCurrentThreadId(VOID)
+{
+ return((DWORD)(NtCurrentTeb()->Cid).UniqueThread);
+}
+
+
+VOID STDCALL
+ExitThread(DWORD uExitCode)
+{
+ BOOLEAN LastThread;
+ NTSTATUS Status;
+
+ /*
+ * Terminate process if this is the last thread
+ * of the current process
+ */
+ Status = NtQueryInformationThread(NtCurrentThread(),
+ ThreadAmILastThread,
+ &LastThread,
+ sizeof(BOOLEAN),
+ NULL);
+ if (NT_SUCCESS(Status) && LastThread == TRUE)
{
- DPRINT("Error reserving stack space!\n");
- SetLastErrorByStatus(Status);
- return(NULL);
+ ExitProcess(uExitCode);
}
- DPRINT("StackDeallocation: %p ReserveSize: 0x%lX\n",
- InitialTeb.StackDeallocation, InitialTeb.StackReserve);
+ /* FIXME: notify csrss of thread termination */
- InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve);
- InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit);
+ LdrShutdownThread();
- DPRINT("StackBase: %p\nStackCommit: 0x%lX\n",
- InitialTeb.StackBase,
- InitialTeb.StackCommit);
-
- /* Commit stack pages */
- Status = NtAllocateVirtualMemory(hProcess,
- &InitialTeb.StackLimit,
- 0,
- &InitialTeb.StackCommit,
- MEM_COMMIT,
- PAGE_READWRITE);
+ Status = NtTerminateThread(NtCurrentThread(),
+ uExitCode);
if (!NT_SUCCESS(Status))
{
- /* release the stack space */
- NtFreeVirtualMemory(hProcess,
- InitialTeb.StackAllocate,
- &InitialTeb.StackReserve,
- MEM_RELEASE);
-
- DPRINT("Error comitting stack page(s)!\n");
SetLastErrorByStatus(Status);
- return(NULL);
}
+}
- DPRINT("StackLimit: %p\n",
- InitialTeb.StackLimit);
- /* Protect guard page */
- Status = NtProtectVirtualMemory(hProcess,
- InitialTeb.StackLimit,
- PAGE_SIZE,
- PAGE_GUARD | PAGE_READWRITE,
- &OldPageProtection);
+WINBOOL STDCALL
+GetThreadTimes(HANDLE hThread,
+ LPFILETIME lpCreationTime,
+ LPFILETIME lpExitTime,
+ LPFILETIME lpKernelTime,
+ LPFILETIME lpUserTime)
+{
+ KERNEL_USER_TIMES KernelUserTimes;
+ ULONG ReturnLength;
+ NTSTATUS Status;
+
+ Status = NtQueryInformationThread(hThread,
+ ThreadTimes,
+ &KernelUserTimes,
+ sizeof(KERNEL_USER_TIMES),
+ &ReturnLength);
if (!NT_SUCCESS(Status))
{
- /* release the stack space */
- NtFreeVirtualMemory(hProcess,
- InitialTeb.StackAllocate,
- &InitialTeb.StackReserve,
- MEM_RELEASE);
-
- DPRINT("Error comitting guard page!\n");
SetLastErrorByStatus(Status);
- return(NULL);
+ return(FALSE);
}
- memset(&ThreadContext,0,sizeof(CONTEXT));
- ThreadContext.Eip = (LONG)ThreadStartup;
- ThreadContext.SegGs = USER_DS;
- ThreadContext.SegFs = TEB_SELECTOR;
- ThreadContext.SegEs = USER_DS;
- ThreadContext.SegDs = USER_DS;
- ThreadContext.SegCs = USER_CS;
- ThreadContext.SegSs = USER_DS;
- ThreadContext.Esp = (ULONG)InitialTeb.StackBase - 12;
- ThreadContext.EFlags = (1<<1) + (1<<9);
-
- /* initialize call stack */
- *((PULONG)((ULONG)InitialTeb.StackBase - 4)) = (ULONG)lpParameter;
- *((PULONG)((ULONG)InitialTeb.StackBase - 8)) = (ULONG)lpStartAddress;
- *((PULONG)((ULONG)InitialTeb.StackBase - 12)) = 0xdeadbeef;
-
- DPRINT("Esp: %p\n", ThreadContext.Esp);
- DPRINT("Eip: %p\n", ThreadContext.Eip);
-
- Status = NtCreateThread(&ThreadHandle,
- THREAD_ALL_ACCESS,
- &ObjectAttributes,
- hProcess,
- &ClientId,
- &ThreadContext,
- &InitialTeb,
- CreateSuspended);
+ memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));
+ memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));
+ memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));
+ memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));
+
+ return(TRUE);
+}
+
+
+WINBOOL STDCALL
+GetThreadContext(HANDLE hThread,
+ LPCONTEXT lpContext)
+{
+ NTSTATUS Status;
+
+ Status = NtGetContextThread(hThread,
+ lpContext);
if (!NT_SUCCESS(Status))
{
- NtFreeVirtualMemory(hProcess,
- InitialTeb.StackAllocate,
- &InitialTeb.StackReserve,
- MEM_RELEASE);
-
- DPRINT("NtCreateThread() failed!\n");
SetLastErrorByStatus(Status);
- return(NULL);
+ return(FALSE);
}
- if (lpThreadId != NULL)
- memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
-
- return(ThreadHandle);
+ return(TRUE);
}
-PTEB
-GetTeb(VOID)
+
+WINBOOL STDCALL
+SetThreadContext(HANDLE hThread,
+ CONST CONTEXT *lpContext)
{
- return(NtCurrentTeb());
+ NTSTATUS Status;
+
+ Status = NtSetContextThread(hThread,
+ (void *)lpContext);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+
+ return(TRUE);
}
+
WINBOOL STDCALL
-SwitchToThread(VOID)
+GetExitCodeThread(HANDLE hThread,
+ LPDWORD lpExitCode)
{
- NTSTATUS errCode;
- errCode = NtYieldExecution();
- return TRUE;
+ THREAD_BASIC_INFORMATION ThreadBasic;
+ ULONG DataWritten;
+ NTSTATUS Status;
+
+ Status = NtQueryInformationThread(hThread,
+ ThreadBasicInformation,
+ &ThreadBasic,
+ sizeof(THREAD_BASIC_INFORMATION),
+ &DataWritten);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+
+ memcpy(lpExitCode, &ThreadBasic.ExitStatus, sizeof(DWORD));
+
+ return(TRUE);
}
+
DWORD STDCALL
-GetCurrentThreadId()
+ResumeThread(HANDLE hThread)
{
- return((DWORD)(NtCurrentTeb()->Cid).UniqueThread);
-}
+ ULONG PreviousResumeCount;
+ NTSTATUS Status;
-VOID STDCALL
-ExitThread(DWORD uExitCode)
-{
- NTSTATUS errCode;
- BOOLEAN LastThread;
- NTSTATUS Status;
-
- /*
- * Terminate process if this is the last thread
- * of the current process
- */
- Status = NtQueryInformationThread(NtCurrentThread(),
- ThreadAmILastThread,
- &LastThread,
- sizeof(BOOLEAN),
- NULL);
- if (NT_SUCCESS(Status) && LastThread == TRUE)
- {
- ExitProcess (uExitCode);
- }
-
- /* FIXME: notify csrss of thread termination */
-
- LdrShutdownThread();
-
- errCode = NtTerminateThread(NtCurrentThread(),
- uExitCode);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- }
-}
+ Status = NtResumeThread(hThread,
+ &PreviousResumeCount);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(-1);
+ }
-WINBOOL STDCALL GetThreadTimes(HANDLE hThread,
- LPFILETIME lpCreationTime,
- LPFILETIME lpExitTime,
- LPFILETIME lpKernelTime,
- LPFILETIME lpUserTime)
-{
- NTSTATUS errCode;
- KERNEL_USER_TIMES KernelUserTimes;
- ULONG ReturnLength;
-
- errCode = NtQueryInformationThread(hThread,
- ThreadTimes,
- &KernelUserTimes,
- sizeof(KERNEL_USER_TIMES),
- &ReturnLength);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return FALSE;
- }
- memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));
- memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));
- memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));
- memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));
- return TRUE;
+ return(PreviousResumeCount);
}
-WINBOOL STDCALL GetThreadContext(HANDLE hThread,
- LPCONTEXT lpContext)
+WINBOOL STDCALL
+TerminateThread(HANDLE hThread,
+ DWORD dwExitCode)
{
- NTSTATUS errCode;
-
- errCode = NtGetContextThread(hThread,
- lpContext);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return FALSE;
- }
- return TRUE;
-}
+ NTSTATUS Status;
-WINBOOL STDCALL SetThreadContext(HANDLE hThread,
- CONST CONTEXT *lpContext)
-{
- NTSTATUS errCode;
-
- errCode = NtSetContextThread(hThread,
- (void *)lpContext);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return FALSE;
- }
- return TRUE;
+ if (0 == hThread)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ Status = NtTerminateThread(hThread,
+ dwExitCode);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+
+ return(TRUE);
}
-WINBOOL STDCALL GetExitCodeThread(HANDLE hThread,
- LPDWORD lpExitCode)
+
+DWORD STDCALL
+SuspendThread(HANDLE hThread)
{
- NTSTATUS errCode;
- THREAD_BASIC_INFORMATION ThreadBasic;
- ULONG DataWritten;
-
- errCode = NtQueryInformationThread(hThread,
- ThreadBasicInformation,
- &ThreadBasic,
- sizeof(THREAD_BASIC_INFORMATION),
- &DataWritten);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return FALSE;
- }
- memcpy(lpExitCode, &ThreadBasic.ExitStatus, sizeof(DWORD));
- return TRUE;
+ ULONG PreviousSuspendCount;
+ NTSTATUS Status;
+
+ Status = NtSuspendThread(hThread,
+ &PreviousSuspendCount);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(-1);
+ }
+
+ return(PreviousSuspendCount);
}
-DWORD STDCALL ResumeThread(HANDLE hThread)
+
+DWORD STDCALL
+SetThreadAffinityMask(HANDLE hThread,
+ DWORD dwThreadAffinityMask)
{
- NTSTATUS errCode;
- ULONG PreviousResumeCount;
-
- errCode = NtResumeThread(hThread,
- &PreviousResumeCount);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return -1;
- }
- return PreviousResumeCount;
+ THREAD_BASIC_INFORMATION ThreadBasic;
+ KAFFINITY AffinityMask;
+ ULONG DataWritten;
+ NTSTATUS Status;
+
+ AffinityMask = (KAFFINITY)dwThreadAffinityMask;
+
+ Status = NtQueryInformationThread(hThread,
+ ThreadBasicInformation,
+ &ThreadBasic,
+ sizeof(THREAD_BASIC_INFORMATION),
+ &DataWritten);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(0);
+ }
+
+ Status = NtSetInformationThread(hThread,
+ ThreadAffinityMask,
+ &AffinityMask,
+ sizeof(KAFFINITY));
+ if (!NT_SUCCESS(Status))
+ SetLastErrorByStatus(Status);
+
+ return(ThreadBasic.AffinityMask);
}
WINBOOL STDCALL
-TerminateThread (HANDLE hThread,
- DWORD dwExitCode)
+SetThreadPriority(HANDLE hThread,
+ int nPriority)
{
- if (0 == hThread)
+ ULONG Prio = nPriority;
+ NTSTATUS Status;
+
+ Status = NtSetInformationThread(hThread,
+ ThreadBasePriority,
+ &Prio,
+ sizeof(ULONG));
+
+ if (!NT_SUCCESS(Status))
{
- SetLastError (ERROR_INVALID_HANDLE);
+ SetLastErrorByStatus(Status);
+ return(FALSE);
}
- else
+
+ return(TRUE);
+}
+
+
+int STDCALL
+GetThreadPriority(HANDLE hThread)
+{
+ THREAD_BASIC_INFORMATION ThreadBasic;
+ ULONG DataWritten;
+ NTSTATUS Status;
+
+ Status = NtQueryInformationThread(hThread,
+ ThreadBasicInformation,
+ &ThreadBasic,
+ sizeof(THREAD_BASIC_INFORMATION),
+ &DataWritten);
+ if (!NT_SUCCESS(Status))
{
- NTSTATUS Status = NtTerminateThread (hThread, dwExitCode);
-
- if (NT_SUCCESS(Status))
- {
- return TRUE;
- }
- SetLastErrorByStatus (Status);
+ SetLastErrorByStatus(Status);
+ return(THREAD_PRIORITY_ERROR_RETURN);
}
- return FALSE;
+
+ return(ThreadBasic.BasePriority);
}
-DWORD STDCALL SuspendThread(HANDLE hThread)
+WINBOOL STDCALL
+GetThreadPriorityBoost(IN HANDLE hThread,
+ OUT PBOOL pDisablePriorityBoost)
{
- NTSTATUS errCode;
- ULONG PreviousSuspendCount;
-
- errCode = NtSuspendThread(hThread,
- &PreviousSuspendCount);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return -1;
- }
- return PreviousSuspendCount;
+ ULONG PriorityBoost;
+ ULONG DataWritten;
+ NTSTATUS Status;
+
+ Status = NtQueryInformationThread(hThread,
+ ThreadPriorityBoost,
+ &PriorityBoost,
+ sizeof(ULONG),
+ &DataWritten);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+
+ *pDisablePriorityBoost = !((WINBOOL)PriorityBoost);
+
+ return(TRUE);
}
-DWORD STDCALL SetThreadAffinityMask(HANDLE hThread,
- DWORD dwThreadAffinityMask)
+
+WINBOOL STDCALL
+SetThreadPriorityBoost(IN HANDLE hThread,
+ IN WINBOOL bDisablePriorityBoost)
{
- return 0;
+ ULONG PriorityBoost;
+ NTSTATUS Status;
+
+ PriorityBoost = (ULONG)!bDisablePriorityBoost;
+
+ Status = NtSetInformationThread(hThread,
+ ThreadPriorityBoost,
+ &PriorityBoost,
+ sizeof(ULONG));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+
+ return(TRUE);
}
-WINBOOL STDCALL SetThreadPriority(HANDLE hThread,
- int nPriority)
+
+WINBOOL STDCALL
+GetThreadSelectorEntry(IN HANDLE hThread,
+ IN DWORD dwSelector,
+ OUT LPLDT_ENTRY lpSelectorEntry)
{
- NTSTATUS errCode;
- THREAD_BASIC_INFORMATION ThreadBasic;
- ULONG DataWritten;
-
- errCode = NtQueryInformationThread(hThread,
- ThreadBasicInformation,
- &ThreadBasic,
- sizeof(THREAD_BASIC_INFORMATION),
- &DataWritten);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return FALSE;
- }
- ThreadBasic.BasePriority = nPriority;
- errCode = NtSetInformationThread(hThread,
- ThreadBasicInformation,
- &ThreadBasic,
- sizeof(THREAD_BASIC_INFORMATION));
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return FALSE;
- }
- return TRUE;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return(FALSE);
}
-int STDCALL GetThreadPriority(HANDLE hThread)
+
+WINBOOL STDCALL
+SetThreadIdealProcessor(HANDLE hThread,
+ DWORD dwIdealProcessor)
{
- NTSTATUS errCode;
- THREAD_BASIC_INFORMATION ThreadBasic;
- ULONG DataWritten;
-
- errCode = NtQueryInformationThread(hThread,
- ThreadBasicInformation,
- &ThreadBasic,
- sizeof(THREAD_BASIC_INFORMATION),
- &DataWritten);
- if (!NT_SUCCESS(errCode))
- {
- SetLastErrorByStatus(errCode);
- return THREAD_PRIORITY_ERROR_RETURN;
- }
- return ThreadBasic.BasePriority;
+ ULONG IdealProcessor;
+ NTSTATUS Status;
+
+ IdealProcessor = (ULONG)dwIdealProcessor;
+
+ Status = NtSetInformationThread(hThread,
+ ThreadIdealProcessor,
+ &IdealProcessor,
+ sizeof(ULONG));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+
+ return(TRUE);
}
/* EOF */