100 lines
3.0 KiB
C++
100 lines
3.0 KiB
C++
#pragma once
|
|
|
|
namespace Ooganizer
|
|
{
|
|
// Generic Thread Class!
|
|
class Thread
|
|
{
|
|
public:
|
|
|
|
// Starts the thread
|
|
// This function starts the thread pointed by m_pThreadFunc with default attributes
|
|
DWORD Start( void* arg = NULL )
|
|
{
|
|
m_ThreadCtx.m_pUserData = arg;
|
|
m_ThreadCtx.m_hThread = CreateThread(NULL, 0, m_pThreadFunc, this, 0, &m_ThreadCtx.m_dwTID);
|
|
m_ThreadCtx.m_dwExitCode = (DWORD)-1;
|
|
return GetLastError();
|
|
}
|
|
|
|
// Stops the thread.
|
|
// This function stops the current thread
|
|
DWORD Stop ( bool bForceKill = false )
|
|
{
|
|
log(LOGGING_HIGH, L"Hidden Wnd Thread Stopped()");
|
|
if ( m_ThreadCtx.m_hThread )
|
|
{
|
|
GetExitCodeThread(m_ThreadCtx.m_hThread, &m_ThreadCtx.m_dwExitCode);
|
|
|
|
if ( m_ThreadCtx.m_dwExitCode == STILL_ACTIVE && bForceKill )
|
|
TerminateThread(m_ThreadCtx.m_hThread, DWORD(-1));
|
|
|
|
m_ThreadCtx.m_hThread = NULL;
|
|
}
|
|
return m_ThreadCtx.m_dwExitCode;
|
|
}
|
|
|
|
// Returns Thread Exit Code
|
|
DWORD GetExitCode() const
|
|
{
|
|
if ( m_ThreadCtx.m_hThread )
|
|
GetExitCodeThread(m_ThreadCtx.m_hThread, (LPDWORD)&m_ThreadCtx.m_dwExitCode);
|
|
return m_ThreadCtx.m_dwExitCode;
|
|
}
|
|
|
|
// Attaches a Thread Function
|
|
// Used primarily for porting but can serve in developing generic thread objects
|
|
void Attach( LPTHREAD_START_ROUTINE lpThreadFunc ){
|
|
m_pThreadFunc = lpThreadFunc;
|
|
}
|
|
|
|
// Detaches the Attached Thread Function
|
|
// Detaches the Attached Thread Function, If any.
|
|
void Detach( void ){
|
|
m_pThreadFunc = Thread::EntryPoint;
|
|
}
|
|
|
|
Thread(){ m_pThreadFunc = Thread::EntryPoint; /*Can call Detach Also*/ }
|
|
//plug-in constructor
|
|
Thread(PTHREAD_START_ROUTINE lpExternalRoutine){Attach(lpExternalRoutine);}
|
|
~Thread(){ if(m_ThreadCtx.m_hThread) Stop(true);}
|
|
|
|
protected:
|
|
|
|
// Std Template: Override if you are sure of what you are doing
|
|
static DWORD WINAPI EntryPoint( LPVOID pArg)
|
|
{
|
|
Thread *pParent = reinterpret_cast<Thread*>(pArg);
|
|
pParent->ThreadCtor();
|
|
pParent->Run( pParent->m_ThreadCtx.m_pUserData );
|
|
pParent->ThreadDtor();
|
|
return STILL_ACTIVE;
|
|
}
|
|
|
|
// Override this method with the body/code of your thread
|
|
virtual DWORD Run( LPVOID /*arg */){return m_ThreadCtx.m_dwExitCode;}
|
|
// override this function to provide your extra initialization
|
|
virtual void ThreadCtor(){}
|
|
// Override this function to provide your extra destruction
|
|
virtual void ThreadDtor(){}
|
|
|
|
////
|
|
// Thread Context Inner Class (UserData Pointer, Handle, Thread ID)
|
|
////
|
|
class CThreadContext
|
|
{
|
|
public:
|
|
CThreadContext(){memset(this, 0, sizeof(this));}
|
|
|
|
// Attributes
|
|
public:
|
|
HANDLE m_hThread; // The Thread Handle
|
|
DWORD m_dwTID; // The Thread ID
|
|
LPVOID m_pUserData; // The user data pointer
|
|
LPVOID m_pParent; // The this pointer of the parent CThread object
|
|
DWORD m_dwExitCode; // The Exit Code of the thread
|
|
|
|
} m_ThreadCtx; // The Thread Context Member
|
|
LPTHREAD_START_ROUTINE m_pThreadFunc; // The Worker Thread Function Pointer
|
|
};
|
|
} |