Back

// 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(EX_NOACCESS);

   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(EX_INVALIDPARAMETER);
   }

   HANDLE hThread = ::OpenThread(THREAD_SET_INFORMATION, FALSE, m_ThreadID);
   if(hThread)
   {
      ::SetThreadPriority(hThread, iPriority);
      ::CloseHandle(hThread);
   }
   else
      if(::GetLastError() == ERROR_ACCESS_DENIED)
         SetException(EX_NOACCESS);

   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(EX_INVALIDPARAMETER);

   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(EX_INVALIDPARAMETER);
   LPARAM L = CPSLUtilities::GetVariantBig(&lParam, &bError);
   if(bError)
      return MakeException(EX_INVALIDPARAMETER);
   *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(EX_NOACCESS);
   }

   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(EX_NOACCESS);
   }


   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(EX_NOACCESS);
   }

   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(EX_NOACCESS);
   }

   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(EX_NOACCESS);
   }

   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(EX_NOACCESS);
   }

   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(EX_NOACCESS);
   }

   PSL_END
}

Top