mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Implemented SetThreadAffinityMask().
Fixed some *nix line breaks. svn path=/trunk/; revision=3817
This commit is contained in:
parent
a378416e55
commit
c00bebf1f2
1 changed files with 276 additions and 216 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: thread.c,v 1.31 2002/10/25 22:59:55 chorns Exp $
|
/* $Id: thread.c,v 1.32 2002/12/02 21:28:40 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -27,44 +27,45 @@ static VOID ThreadAttachDlls (VOID);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
static
|
static EXCEPTION_DISPOSITION __cdecl
|
||||||
EXCEPTION_DISPOSITION
|
_except_handler(struct _EXCEPTION_RECORD *ExceptionRecord,
|
||||||
__cdecl
|
void * EstablisherFrame,
|
||||||
_except_handler(
|
struct _CONTEXT *ContextRecord,
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
void * DispatcherContext)
|
||||||
void * EstablisherFrame,
|
|
||||||
struct _CONTEXT *ContextRecord,
|
|
||||||
void * DispatcherContext )
|
|
||||||
{
|
|
||||||
ExitThread(0);
|
|
||||||
|
|
||||||
/* We should not get to here */
|
|
||||||
return ExceptionContinueSearch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID STDCALL
|
|
||||||
ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress,
|
|
||||||
LPVOID lpParameter)
|
|
||||||
{
|
{
|
||||||
UINT uExitCode;
|
ExitThread(0);
|
||||||
|
|
||||||
__try1(_except_handler)
|
/* We should not get to here */
|
||||||
{
|
return(ExceptionContinueSearch);
|
||||||
/* FIXME: notify csrss of thread creation ?? */
|
|
||||||
uExitCode = (lpStartAddress)(lpParameter);
|
|
||||||
} __except1
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ExitThread(uExitCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
||||||
DWORD dwStackSize,
|
static VOID STDCALL
|
||||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
ThreadStartup(LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
LPVOID lpParameter,
|
LPVOID lpParameter)
|
||||||
DWORD dwCreationFlags,
|
{
|
||||||
LPDWORD lpThreadId)
|
UINT 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(),
|
return(CreateRemoteThread(NtCurrentProcess(),
|
||||||
lpThreadAttributes,
|
lpThreadAttributes,
|
||||||
|
@ -75,41 +76,43 @@ HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
lpThreadId));
|
lpThreadId));
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE STDCALL CreateRemoteThread(HANDLE hProcess,
|
|
||||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
HANDLE STDCALL
|
||||||
DWORD dwStackSize,
|
CreateRemoteThread(HANDLE hProcess,
|
||||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
LPVOID lpParameter,
|
DWORD dwStackSize,
|
||||||
DWORD dwCreationFlags,
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
LPDWORD lpThreadId)
|
LPVOID lpParameter,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPDWORD lpThreadId)
|
||||||
{
|
{
|
||||||
HANDLE ThreadHandle;
|
HANDLE ThreadHandle;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
CLIENT_ID ClientId;
|
CLIENT_ID ClientId;
|
||||||
CONTEXT ThreadContext;
|
CONTEXT ThreadContext;
|
||||||
INITIAL_TEB InitialTeb;
|
INITIAL_TEB InitialTeb;
|
||||||
BOOLEAN CreateSuspended = FALSE;
|
BOOLEAN CreateSuspended = FALSE;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
ULONG OldPageProtection;
|
ULONG OldPageProtection;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||||
ObjectAttributes.RootDirectory = NULL;
|
ObjectAttributes.RootDirectory = NULL;
|
||||||
ObjectAttributes.ObjectName = NULL;
|
ObjectAttributes.ObjectName = NULL;
|
||||||
ObjectAttributes.Attributes = 0;
|
ObjectAttributes.Attributes = 0;
|
||||||
if (lpThreadAttributes != NULL)
|
if (lpThreadAttributes != NULL)
|
||||||
{
|
{
|
||||||
if (lpThreadAttributes->bInheritHandle)
|
if (lpThreadAttributes->bInheritHandle)
|
||||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||||
ObjectAttributes.SecurityDescriptor =
|
ObjectAttributes.SecurityDescriptor =
|
||||||
lpThreadAttributes->lpSecurityDescriptor;
|
lpThreadAttributes->lpSecurityDescriptor;
|
||||||
}
|
}
|
||||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED)
|
if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED)
|
||||||
CreateSuspended = TRUE;
|
CreateSuspended = TRUE;
|
||||||
else
|
else
|
||||||
CreateSuspended = FALSE;
|
CreateSuspended = FALSE;
|
||||||
|
|
||||||
InitialTeb.StackReserve = 0x100000; /* 1MByte */
|
InitialTeb.StackReserve = 0x100000; /* 1MByte */
|
||||||
/* FIXME: use correct commit size */
|
/* FIXME: use correct commit size */
|
||||||
|
@ -233,26 +236,30 @@ HANDLE STDCALL CreateRemoteThread(HANDLE hProcess,
|
||||||
return(ThreadHandle);
|
return(ThreadHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PTEB
|
PTEB
|
||||||
GetTeb(VOID)
|
GetTeb(VOID)
|
||||||
{
|
{
|
||||||
return(NtCurrentTeb());
|
return(NtCurrentTeb());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WINBOOL STDCALL
|
WINBOOL STDCALL
|
||||||
SwitchToThread(VOID)
|
SwitchToThread(VOID)
|
||||||
{
|
{
|
||||||
NTSTATUS errCode;
|
NTSTATUS errCode;
|
||||||
errCode = NtYieldExecution();
|
errCode = NtYieldExecution();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DWORD STDCALL
|
DWORD STDCALL
|
||||||
GetCurrentThreadId()
|
GetCurrentThreadId(VOID)
|
||||||
{
|
{
|
||||||
return((DWORD)(NtCurrentTeb()->Cid).UniqueThread);
|
return((DWORD)(NtCurrentTeb()->Cid).UniqueThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
ExitThread(DWORD uExitCode)
|
ExitThread(DWORD uExitCode)
|
||||||
{
|
{
|
||||||
|
@ -286,11 +293,13 @@ ExitThread(DWORD uExitCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WINBOOL STDCALL GetThreadTimes(HANDLE hThread,
|
|
||||||
LPFILETIME lpCreationTime,
|
WINBOOL STDCALL
|
||||||
LPFILETIME lpExitTime,
|
GetThreadTimes(HANDLE hThread,
|
||||||
LPFILETIME lpKernelTime,
|
LPFILETIME lpCreationTime,
|
||||||
LPFILETIME lpUserTime)
|
LPFILETIME lpExitTime,
|
||||||
|
LPFILETIME lpKernelTime,
|
||||||
|
LPFILETIME lpUserTime)
|
||||||
{
|
{
|
||||||
NTSTATUS errCode;
|
NTSTATUS errCode;
|
||||||
KERNEL_USER_TIMES KernelUserTimes;
|
KERNEL_USER_TIMES KernelUserTimes;
|
||||||
|
@ -314,163 +323,214 @@ WINBOOL STDCALL GetThreadTimes(HANDLE hThread,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WINBOOL STDCALL GetThreadContext(HANDLE hThread,
|
WINBOOL STDCALL
|
||||||
LPCONTEXT lpContext)
|
GetThreadContext(HANDLE hThread,
|
||||||
|
LPCONTEXT lpContext)
|
||||||
{
|
{
|
||||||
NTSTATUS errCode;
|
NTSTATUS Status;
|
||||||
|
|
||||||
errCode = NtGetContextThread(hThread,
|
|
||||||
lpContext);
|
|
||||||
if (!NT_SUCCESS(errCode))
|
|
||||||
{
|
|
||||||
SetLastErrorByStatus(errCode);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
WINBOOL STDCALL SetThreadContext(HANDLE hThread,
|
Status = NtGetContextThread(hThread,
|
||||||
CONST CONTEXT *lpContext)
|
lpContext);
|
||||||
{
|
if (!NT_SUCCESS(Status))
|
||||||
NTSTATUS errCode;
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
errCode = NtSetContextThread(hThread,
|
return(FALSE);
|
||||||
(void *)lpContext);
|
}
|
||||||
if (!NT_SUCCESS(errCode))
|
|
||||||
{
|
|
||||||
SetLastErrorByStatus(errCode);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
WINBOOL STDCALL GetExitCodeThread(HANDLE hThread,
|
return(TRUE);
|
||||||
LPDWORD lpExitCode)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD STDCALL ResumeThread(HANDLE hThread)
|
|
||||||
{
|
|
||||||
NTSTATUS errCode;
|
|
||||||
ULONG PreviousResumeCount;
|
|
||||||
|
|
||||||
errCode = NtResumeThread(hThread,
|
|
||||||
&PreviousResumeCount);
|
|
||||||
if (!NT_SUCCESS(errCode))
|
|
||||||
{
|
|
||||||
SetLastErrorByStatus(errCode);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return PreviousResumeCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WINBOOL STDCALL
|
WINBOOL STDCALL
|
||||||
TerminateThread (HANDLE hThread,
|
SetThreadContext(HANDLE hThread,
|
||||||
DWORD dwExitCode)
|
CONST CONTEXT *lpContext)
|
||||||
{
|
{
|
||||||
if (0 == hThread)
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = NtSetContextThread(hThread,
|
||||||
|
(void *)lpContext);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
SetLastError (ERROR_INVALID_HANDLE);
|
SetLastErrorByStatus(Status);
|
||||||
|
return(FALSE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return(TRUE);
|
||||||
NTSTATUS Status = NtTerminateThread (hThread, dwExitCode);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
SetLastErrorByStatus (Status);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DWORD STDCALL SuspendThread(HANDLE hThread)
|
WINBOOL STDCALL
|
||||||
|
GetExitCodeThread(HANDLE hThread,
|
||||||
|
LPDWORD lpExitCode)
|
||||||
{
|
{
|
||||||
NTSTATUS errCode;
|
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||||
ULONG PreviousSuspendCount;
|
ULONG DataWritten;
|
||||||
|
NTSTATUS Status;
|
||||||
errCode = NtSuspendThread(hThread,
|
|
||||||
&PreviousSuspendCount);
|
|
||||||
if (!NT_SUCCESS(errCode))
|
|
||||||
{
|
|
||||||
SetLastErrorByStatus(errCode);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return PreviousSuspendCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD STDCALL SetThreadAffinityMask(HANDLE hThread,
|
Status = NtQueryInformationThread(hThread,
|
||||||
DWORD dwThreadAffinityMask)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
WINBOOL STDCALL SetThreadPriority(HANDLE hThread,
|
|
||||||
int nPriority)
|
|
||||||
{
|
|
||||||
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,
|
ThreadBasicInformation,
|
||||||
&ThreadBasic,
|
&ThreadBasic,
|
||||||
sizeof(THREAD_BASIC_INFORMATION));
|
sizeof(THREAD_BASIC_INFORMATION),
|
||||||
if (!NT_SUCCESS(errCode))
|
&DataWritten);
|
||||||
{
|
if (!NT_SUCCESS(Status))
|
||||||
SetLastErrorByStatus(errCode);
|
{
|
||||||
return FALSE;
|
SetLastErrorByStatus(Status);
|
||||||
}
|
return(FALSE);
|
||||||
return TRUE;
|
}
|
||||||
|
|
||||||
|
memcpy(lpExitCode, &ThreadBasic.ExitStatus, sizeof(DWORD));
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int STDCALL GetThreadPriority(HANDLE hThread)
|
|
||||||
|
DWORD STDCALL
|
||||||
|
ResumeThread(HANDLE hThread)
|
||||||
{
|
{
|
||||||
NTSTATUS errCode;
|
ULONG PreviousResumeCount;
|
||||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
NTSTATUS Status;
|
||||||
ULONG DataWritten;
|
|
||||||
|
Status = NtResumeThread(hThread,
|
||||||
errCode = NtQueryInformationThread(hThread,
|
&PreviousResumeCount);
|
||||||
ThreadBasicInformation,
|
if (!NT_SUCCESS(Status))
|
||||||
&ThreadBasic,
|
{
|
||||||
sizeof(THREAD_BASIC_INFORMATION),
|
SetLastErrorByStatus(Status);
|
||||||
&DataWritten);
|
return(-1);
|
||||||
if (!NT_SUCCESS(errCode))
|
}
|
||||||
{
|
|
||||||
SetLastErrorByStatus(errCode);
|
return(PreviousResumeCount);
|
||||||
return THREAD_PRIORITY_ERROR_RETURN;
|
}
|
||||||
}
|
|
||||||
return ThreadBasic.BasePriority;
|
|
||||||
|
WINBOOL STDCALL
|
||||||
|
TerminateThread(HANDLE hThread,
|
||||||
|
DWORD dwExitCode)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (0 == hThread)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = NtTerminateThread(hThread,
|
||||||
|
dwExitCode);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD STDCALL
|
||||||
|
SuspendThread(HANDLE hThread)
|
||||||
|
{
|
||||||
|
ULONG PreviousSuspendCount;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = NtSuspendThread(hThread,
|
||||||
|
&PreviousSuspendCount);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(PreviousSuspendCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD STDCALL
|
||||||
|
SetThreadAffinityMask(HANDLE hThread,
|
||||||
|
DWORD dwThreadAffinityMask)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
SetThreadPriority(HANDLE hThread,
|
||||||
|
int nPriority)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBasic.BasePriority = nPriority;
|
||||||
|
|
||||||
|
Status = NtSetInformationThread(hThread,
|
||||||
|
ThreadBasicInformation,
|
||||||
|
&ThreadBasic,
|
||||||
|
sizeof(THREAD_BASIC_INFORMATION));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return(THREAD_PRIORITY_ERROR_RETURN);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ThreadBasic.BasePriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue