// PSLThread.cpp : Implementation of CPSLThread
#include "stdafx.h"
#include "PSLThread.h"
#include "ProSysModule.h"
#include <ATLComTime.h>
CPSLThread::CPSLThread()
{
m_ThreadID = 0;
}
HRESULT CPSLThread::FinalConstruct()
{
return S_OK;
}
void CPSLThread::FinalRelease()
{
}
void CPSLThread::Initialize(THREADENTRY32 * pInfo)
{
m_ThreadID = pInfo->th32ThreadID;
m_Created = NULL;
HANDLE hThread = ::OpenThread(THREAD_QUERY_INFORMATION, FALSE, m_ThreadID);
if(hThread)
{
FILETIME tCreate, tExit, tKernel, tUser;
if(::GetThreadTimes(hThread, &tCreate, &tExit, &tKernel, &tUser))
m_Created = COleDateTime(tCreate);
::CloseHandle(hThread);
}
}
////////////////////////////////////////////////////////////////////////
// Interface Implementation;
////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPSLThread::get_ThreadID(long * pValue)
{
PSL_BEGIN
*pValue = m_ThreadID;
PSL_END
}
STDMETHODIMP CPSLThread::get_IsCurrent(VARIANT_BOOL * pValue)
{
PSL_BEGIN
if(::GetCurrentThreadId() == m_ThreadID)
*pValue = VARIANT_TRUE;
else
*pValue = VARIANT_FALSE;
PSL_END
}
STDMETHODIMP CPSLThread::get_Created(DATE * pValue)
{
PSL_BEGIN
*pValue = m_Created;
PSL_END
}
STDMETHODIMP CPSLThread::get_Priority(PSLThreadPriority * pValue)
{
PSL_BEGIN
*pValue = tpUnknown;
HANDLE hThread = ::OpenThread(THREAD_QUERY_INFORMATION, FALSE, m_ThreadID);
if(hThread)
{
int iPriority = ::GetThreadPriority(hThread);
::CloseHandle(hThread);
switch(iPriority)
{
case THREAD_PRIORITY_ABOVE_NORMAL:
{
*pValue = tpAboveNormal;
break;
}
case THREAD_PRIORITY_BELOW_NORMAL:
{
*pValue = tpBelowNormal;
break;
}
case THREAD_PRIORITY_HIGHEST:
{
*pValue = tpHighest;
break;
}
case THREAD_PRIORITY_IDLE:
{
*pValue = tpIdle;
break;
}
case THREAD_PRIORITY_LOWEST:
{
*pValue = tpLowest;
break;
}
case THREAD_PRIORITY_NORMAL:
{
*pValue = tpNormal;
break;
}
case THREAD_PRIORITY_TIME_CRITICAL:
{
*pValue = tpTimeCritical;
break;
}
default:
break;
}
}
else
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
PSL_END
}
STDMETHODIMP CPSLThread::put_Priority(PSLThreadPriority newValue)
{
PSL_BEGIN
int iPriority = 0;
switch(newValue)
{
case tpAboveNormal:
{
iPriority = THREAD_PRIORITY_ABOVE_NORMAL;
break;
}
case tpBelowNormal:
{
iPriority = THREAD_PRIORITY_BELOW_NORMAL;
break;
}
case tpHighest:
{
iPriority = THREAD_PRIORITY_HIGHEST;
break;
}
case THREAD_PRIORITY_IDLE:
{
iPriority = tpIdle;
break;
}
case tpLowest:
{
iPriority = THREAD_PRIORITY_LOWEST;
break;
}
case tpNormal:
{
iPriority = THREAD_PRIORITY_NORMAL;
break;
}
case tpTimeCritical:
{
iPriority = THREAD_PRIORITY_TIME_CRITICAL;
break;
}
default:
return MakeException(exInvalidParameter);
}
HANDLE hThread = ::OpenThread(THREAD_SET_INFORMATION, FALSE, m_ThreadID);
if(hThread)
{
::SetThreadPriority(hThread, iPriority);
::CloseHandle(hThread);
}
else
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
PSL_END
}
STDMETHODIMP CPSLThread::get_AffinityMask(VARIANT * pValue)
{
PSL_BEGIN
CPSLUtilities::SetVariantBig(pValue, 0);
DWORD_PTR ProcessAffinityMask = 0;
DWORD_PTR SystemAffinityMask = 0;
if(::GetProcessAffinityMask(::GetCurrentProcess(), &ProcessAffinityMask, &SystemAffinityMask))
{
DWORD_PTR ThreadAffinityMask = ProcessAffinityMask;
DWORD_PTR AffinityMask = ::SetThreadAffinityMask(::GetCurrentThread(), ThreadAffinityMask);
if(AffinityMask)
{
CPSLUtilities::SetVariantBig(pValue, AffinityMask);
if(AffinityMask != ProcessAffinityMask)
::SetThreadAffinityMask(::GetCurrentThread(), AffinityMask);
}
}
PSL_END
}
STDMETHODIMP CPSLThread::put_AffinityMask(VARIANT newValue)
{
PSL_BEGIN
ABIG Mask = CPSLUtilities::GetVariantBig(&newValue);
if(Mask)
{
DWORD_PTR ThreadAffinityMask = Mask;
::SetThreadAffinityMask(::GetCurrentThread(), ThreadAffinityMask);
}
else
SetException(exInvalidParameter);
PSL_END
}
STDMETHODIMP CPSLThread::PostMsg(long Msg, VARIANT wParam, VARIANT lParam, VARIANT_BOOL * pValue)
{
PSL_BEGIN
*pValue = VARIANT_FALSE;
bool bError = false;
WPARAM W = CPSLUtilities::GetVariantBig(&wParam, &bError);
if(bError)
return MakeException(exInvalidParameter);
LPARAM L = CPSLUtilities::GetVariantBig(&lParam, &bError);
if(bError)
return MakeException(exInvalidParameter);
*pValue = ::PostThreadMessage(m_ThreadID, Msg, W, L);
PSL_END
}
STDMETHODIMP CPSLThread::Wait(long TimeOut, VARIANT_BOOL * pValue)
{
PSL_BEGIN
*pValue = VARIANT_FALSE;
HANDLE hThread = ::OpenThread(SYNCHRONIZE, FALSE, m_ThreadID);
if(hThread)
{
DWORD dwResult = ::WaitForSingleObject(hThread, TimeOut);
::CloseHandle(hThread);
if(dwResult == WAIT_OBJECT_0)
*pValue = VARIANT_TRUE;
}
else
{
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
}
PSL_END
}
STDMETHODIMP CPSLThread::Terminate(long ExitCode, VARIANT_BOOL * pValue)
{
PSL_BEGIN
*pValue = VARIANT_FALSE;
HANDLE hThread = ::OpenThread(THREAD_TERMINATE, FALSE, m_ThreadID);
if(hThread)
{
*pValue = ::TerminateThread(hThread, ExitCode)?VARIANT_TRUE:VARIANT_FALSE;
::CloseHandle(hThread);
}
else
{
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
}
PSL_END
}
STDMETHODIMP CPSLThread::Suspend(long * pValue)
{
PSL_BEGIN
*pValue = -1;
HANDLE hThread = ::OpenThread(THREAD_SUSPEND_RESUME, FALSE, m_ThreadID);
if(hThread)
{
*pValue = ::SuspendThread(hThread);
::CloseHandle(hThread);
}
else
{
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
}
PSL_END
}
STDMETHODIMP CPSLThread::Resume(long * pValue)
{
PSL_BEGIN
*pValue = -1;
HANDLE hThread = ::OpenThread(THREAD_SUSPEND_RESUME, FALSE, m_ThreadID);
if(hThread)
{
*pValue = ::ResumeThread(hThread);
::CloseHandle(hThread);
}
else
{
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
}
PSL_END
}
STDMETHODIMP CPSLThread::get_PriorityBoost(VARIANT_BOOL * pValue)
{
PSL_BEGIN
*pValue = VARIANT_FALSE;
HANDLE hThread = ::OpenThread(THREAD_QUERY_INFORMATION, FALSE, m_ThreadID);
if(hThread)
{
BOOL bBoost = FALSE;
if(::GetThreadPriorityBoost(hThread, &bBoost))
*pValue = bBoost?VARIANT_TRUE:VARIANT_FALSE;
::CloseHandle(hThread);
}
else
{
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
}
PSL_END
}
STDMETHODIMP CPSLThread::put_PriorityBoost(VARIANT_BOOL newValue)
{
PSL_BEGIN
HANDLE hThread = ::OpenThread(THREAD_SET_INFORMATION, FALSE, m_ThreadID);
if(hThread)
{
::SetThreadPriorityBoost(hThread, newValue?TRUE:FALSE);
::CloseHandle(hThread);
}
else
{
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
}
PSL_END
}
STDMETHODIMP CPSLThread::get_IsAlive(VARIANT_BOOL * pValue)
{
PSL_BEGIN
*pValue = VARIANT_FALSE;
HANDLE hThread = ::OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, m_ThreadID);
if(hThread)
{
::CloseHandle(hThread);
*pValue = VARIANT_TRUE;
}
else
{
if(::GetLastError() == ERROR_ACCESS_DENIED)
SetException(exAccessDenied);
}
PSL_END
}