This commit is contained in:
2024-08-07 09:16:27 -04:00
parent fdfadd5c7e
commit 5f971cf684
5200 changed files with 731717 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
#include <watchdog/CBThunkCtrlHandler.hpp>
CBThunkCtrlHandler::~CBThunkCtrlHandler()
{
}
void CBThunkCtrlHandler::entryProc(DWORD control)
{
controlHandler(control);
}
// *** virtuals
void CBThunkCtrlHandler::controlHandler(DWORD control)
{
::OutputDebugString("[CBThunkCtrlHandler::controlHandler]\n");
return;
}

View File

@@ -0,0 +1,45 @@
#ifndef _WATCHDOG_CBTHUNKCTRLHANDLER_HPP_
#define _HOOKPROC_CBTHUNKCTRLHANDLER_HPP_
#ifndef _HOOKPROC_APIENTRY_HPP_
#include <hookproc/apientry.hpp>
#endif
#ifndef _HOOKPROC_PROCADDRESS_HPP_
#include <hookproc/procaddr.hpp>
#endif
class CBThunkCtrlHandler;
typedef ProcAddress<CBThunkCtrlHandler> CBThunkCtrlHandlerProc;
class CBThunkCtrlHandler : protected APIEntry, private CBThunkCtrlHandlerProc
{
public:
typedef void (WINAPI *LPFNCONTROLHANDLER)(DWORD control);
CBThunkCtrlHandler(void);
virtual ~CBThunkCtrlHandler();
DWORD getAddress(void);
protected:
virtual void controlHandler(DWORD control);
private:
enum {ParamLength=4};
CBThunkCtrlHandler &operator=(const CBThunkCtrlHandler &cbThunkSvcMain);
void entryProc(DWORD control);
};
inline
CBThunkCtrlHandler::CBThunkCtrlHandler(void)
: APIEntry(ParamLength,(DWORD)this,getProcAddress((ProcAddress<CBThunkCtrlHandler>::LPFNMETHODVOID)&CBThunkCtrlHandler::entryProc))
{
}
inline
CBThunkCtrlHandler &CBThunkCtrlHandler::operator=(const CBThunkCtrlHandler &CBThunkCtrlHandler)
{ // no implementation
return *this;
}
inline
DWORD CBThunkCtrlHandler::getAddress(void)
{
return codeBase();
}
#endif

View File

@@ -0,0 +1,19 @@
#include <watchdog/CBThunkSvcMain.hpp>
#include <common/string.hpp>
CBThunkSvcMain::~CBThunkSvcMain()
{
}
void CBThunkSvcMain::entryProc(DWORD dwArgs,LPTSTR *lpszArgs)
{
serviceMain(dwArgs,lpszArgs);
}
// *** virtuals
void CBThunkSvcMain::serviceMain(DWORD dwArgs,LPTSTR *lpszArgs)
{
::OutputDebugString("[CBThunkSvcMain::serviceMain]\n");
return;
}

View File

@@ -0,0 +1,45 @@
#ifndef _WATCHDOG_CBTHUNKSVCMAIN_HPP_
#define _HOOKPROC_CBTHUNKSVCMAIN_HPP_
#ifndef _HOOKPROC_APIENTRY_HPP_
#include <hookproc/apientry.hpp>
#endif
#ifndef _HOOKPROC_PROCADDRESS_HPP_
#include <hookproc/procaddr.hpp>
#endif
class CBThunkSvcMain;
typedef ProcAddress<CBThunkSvcMain> CBThunkSvcMainProc;
class CBThunkSvcMain : protected APIEntry, private CBThunkSvcMainProc
{
public:
typedef void (WINAPI *LPFNSERVICEMAIN)(DWORD dwArg,LPTSTR *pszArg);
CBThunkSvcMain(void);
virtual ~CBThunkSvcMain();
DWORD getAddress(void);
protected:
virtual void serviceMain(DWORD dwArg,LPTSTR *pszArg);
private:
enum {ParamLength=8};
CBThunkSvcMain &operator=(const CBThunkSvcMain &cbThunkSvcMain);
void entryProc(DWORD dwArg,LPTSTR *pszArg);
};
inline
CBThunkSvcMain::CBThunkSvcMain(void)
: APIEntry(ParamLength,(DWORD)this,getProcAddress((ProcAddress<CBThunkSvcMain>::LPFNMETHODVOID)&CBThunkSvcMain::entryProc))
{
}
inline
CBThunkSvcMain &CBThunkSvcMain::operator=(const CBThunkSvcMain &cbThunkSvcMain)
{ // no implementation
return *this;
}
inline
DWORD CBThunkSvcMain::getAddress(void)
{
return codeBase();
}
#endif

View File

@@ -0,0 +1,30 @@
#include <watchdog/CreateServiceParams.hpp>
bool CreateServiceParams::getNullSeparatedDependencies(Array<char> &dependencies)
{
String strDepCopy;
char *pString=0;
char *pDest=0;
if(mDependencies.isNull())return false;
dependencies.size(1024);
::memset(&dependencies[0],0,dependencies.size());
strDepCopy=mDependencies;
pString=strDepCopy;
pDest=&dependencies[0];
pString=::strtok(pString,";,\0");
if(0==pString)return false;
::strcpy(pDest,pString);
pDest+=::strlen(pString);
while(true)
{
pString=::strtok(0,";,\0");
if(0==pString)break;
*(pDest++)='\0';
::strcpy(pDest,pString);
pDest+=::strlen(pString);
}
*(pDest++)=0;
*(pDest++)=0;
return true;
}

View File

@@ -0,0 +1,215 @@
#ifndef _WATCHDOG_CREATESERVICEPARAMS_HPP_
#define _WATCHDOG_CREATESERVICEPARAMS_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_ARRAY_HPP_
#include <common/array.hpp>
#endif
#ifndef _COMMON_WINSVC_HPP_
#include <common/winsvc.hpp>
#endif
class CreateServiceParams
{
public:
CreateServiceParams();
virtual ~CreateServiceParams();
const String &getServiceName(void)const;
void setServiceName(const String &serviceName);
const String &getDisplayName(void)const;
void setDisplayName(const String &displayName);
DWORD getDesiredAccess(void)const;
void setDesiredAccess(DWORD desiredAccess);
DWORD getServiceType(void)const;
void setServiceType(DWORD serviceType);
DWORD getStartType(void)const;
void setStartType(DWORD startType);
DWORD getErrorControl(void)const;
void setErrorControl(DWORD errorControl);
const String &getBinaryPathName(void)const;
void setBinaryPathName(const String &binaryPathName);
const String &getLoadOrderGroup(void)const;
void setLoadOrderGroup(const String &loadOrderGroup);
DWORD getTagID(void)const;
void setTagID(DWORD tagID);
const String &getDependencies(void)const;
void setDependencies(const String &dependencies);
bool getNullSeparatedDependencies(Array<char> &dependencies);
const String &getServiceStartName(void)const;
void setServiceStartName(const String &serviceStartName);
const String &getPassword(void)const;
void setPassword(const String &password);
private:
String mServiceName;
String mDisplayName;
DWORD mDesiredAccess;
DWORD mServiceType;
DWORD mStartType;
DWORD mErrorControl;
String mBinaryPathName;
String mLoadOrderGroup;
DWORD mTagID;
String mDependencies;
String mServiceStartName;
String mPassword;
};
inline
CreateServiceParams::CreateServiceParams()
: mDesiredAccess(0), mServiceType(0), mStartType(0), mErrorControl(0), mTagID(0)
{
}
inline
CreateServiceParams::~CreateServiceParams()
{
}
inline
const String &CreateServiceParams::getServiceName(void)const
{
return mServiceName;
}
inline
void CreateServiceParams::setServiceName(const String &serviceName)
{
mServiceName=serviceName;
}
inline
const String &CreateServiceParams::getDisplayName(void)const
{
return mDisplayName;
}
inline
void CreateServiceParams::setDisplayName(const String &displayName)
{
mDisplayName=displayName;
}
inline
DWORD CreateServiceParams::getDesiredAccess(void)const
{
return mDesiredAccess;
}
inline
void CreateServiceParams::setDesiredAccess(DWORD desiredAccess)
{
mDesiredAccess=desiredAccess;
}
inline
DWORD CreateServiceParams::getServiceType(void)const
{
return mServiceType;
}
inline
void CreateServiceParams::setServiceType(DWORD serviceType)
{
mServiceType=serviceType;
}
inline
DWORD CreateServiceParams::getStartType(void)const
{
return mStartType;
}
inline
void CreateServiceParams::setStartType(DWORD startType)
{
mStartType=startType;
}
inline
DWORD CreateServiceParams::getErrorControl(void)const
{
return mErrorControl;
}
inline
void CreateServiceParams::setErrorControl(DWORD errorControl)
{
mErrorControl=errorControl;
}
inline
const String &CreateServiceParams::getBinaryPathName(void)const
{
return mBinaryPathName;
}
inline
void CreateServiceParams::setBinaryPathName(const String &binaryPathName)
{
mBinaryPathName=binaryPathName;
}
inline
const String &CreateServiceParams::getLoadOrderGroup(void)const
{
return mLoadOrderGroup;
}
inline
void CreateServiceParams::setLoadOrderGroup(const String &loadOrderGroup)
{
mLoadOrderGroup=loadOrderGroup;
}
inline
DWORD CreateServiceParams::getTagID(void)const
{
return mTagID;
}
inline
void CreateServiceParams::setTagID(DWORD tagID)
{
mTagID=tagID;
}
inline
const String &CreateServiceParams::getDependencies(void)const
{
return mDependencies;
}
inline
void CreateServiceParams::setDependencies(const String &dependencies)
{
mDependencies=dependencies;
}
inline
const String &CreateServiceParams::getServiceStartName(void)const
{
return mServiceStartName;
}
inline
void CreateServiceParams::setServiceStartName(const String &serviceStartName)
{
mServiceStartName=serviceStartName;
}
inline
const String &CreateServiceParams::getPassword(void)const
{
return mPassword;
}
inline
void CreateServiceParams::setPassword(const String &password)
{
mPassword=password;
}
#endif

BIN
watchdog/Debug/vc60.idb Normal file

Binary file not shown.

BIN
watchdog/Debug/watchdog.exe Normal file

Binary file not shown.

114
watchdog/Evaluator.cpp Normal file
View File

@@ -0,0 +1,114 @@
#include <WatchDog/Evaluator.hpp>
void Evaluator::evaluate(void)
{
Block<String> appKeys;
Block<String> notifyKeys;
if(!getAppKeys(appKeys))return;
evaluateAppKeys(appKeys);
if(!getNotifyKeys(notifyKeys))return;
evaluateNotifyKeys(notifyKeys);
}
bool Evaluator::getAppKeys(Block<String> &keys)
{
RegKey regKey(RegKey::LocalMachine);
DWORD index=0;
String key;
String value;
keys.remove();
if(!regKey.openKey("Software\\Diversified\\WatchDog\\Apps"))return false;
while(true)
{
if(!regKey.enumKey(index++,key))break;
keys.insert(&key);
}
return keys.size()?true:false;
}
bool Evaluator::getNotifyKeys(Block<String> &keys)
{
RegKey regKey(RegKey::LocalMachine);
DWORD index=0;
String key;
String value;
keys.remove();
if(!regKey.openKey("Software\\Diversified\\WatchDog\\Notify"))return false;
while(true)
{
if(!regKey.enumKey(index++,key))break;
keys.insert(&key);
}
return keys.size()?true:false;
}
void Evaluator::evaluateAppKeys(Block<String> &keys)
{
String strAppPath;
String strRun;
String strStartIn;
String strArgs;
String strPause;
for(int index=0;index<keys.size();index++)
{
RegKey regKey(RegKey::LocalMachine);
if(!regKey.openKey("Software\\Diversified\\WatchDog\\Apps\\"+keys[index]))continue;
regKey.queryValue("Run",strRun);
if(!(strRun=="true"))continue;
regKey.queryValue("AppPath",strAppPath);
regKey.queryValue("StartIn",strStartIn);
regKey.queryValue("Args",strArgs);
regKey.queryValue("Pause",strPause);
Process process;
process.createProcess(strAppPath,false,strStartIn,strArgs);
if(!strPause.isNull())::Sleep(strPause.toInt());
}
}
void Evaluator::evaluateNotifyKeys(Block<String> &keys)
{
String strEmail;
String strHost;
String strDomainSender;
String strSender;
Block<String> mailData;
RegKey regKey(RegKey::LocalMachine);
if(!regKey.openKey("Software\\Diversified\\WatchDog\\Notify"))return;
if(!regKey.queryValue("Host",strHost))return;
if(!regKey.queryValue("Sender",strSender))return;
if(!regKey.queryValue("DomainSender",strDomainSender))return;
for(int index=0;index<keys.size();index++)
{
RegKey regKey(RegKey::LocalMachine);
if(!regKey.openKey("Software\\Diversified\\WatchDog\\Notify\\"+keys[index]))continue;
regKey.queryValue("EMAIL",strEmail);
SMTPClient smtp;
if(!smtp.open(strHost))continue;
if(!smtp.helo(strDomainSender))
{
smtp.quit();
continue;
}
if(!smtp.mail(strSender))
{
smtp.quit();
continue;
}
smtp.rcpt(strEmail);
mailData.insert(&String(String("To: ")+strEmail));
mailData.insert(&String(String("Reply-To: ")+strSender));
mailData.insert(&String(String("From: ")+strSender));
mailData.insert(&String(String("Subject: WatchDog")));
mailData.insert(&String("\n"));
mailData.insert(&String("\n"));
mailData.insert(&String("WatchDog startup process"));
smtp.data(mailData);
smtp.quit();
smtp.close();
}
}

25
watchdog/Evaluator.hpp Normal file
View File

@@ -0,0 +1,25 @@
#ifndef _WATCHDOG_EVALUATOR_HPP_
#define _WATCHDOG_EVALUATOR_HPP_
#ifndef _COMMON_REGKEY_HPP_
#include <common/regkey.hpp>
#endif
#ifndef _COMMON_PROCESS_HPP_
#include <common/process.hpp>
#endif
#ifndef _SMTP_SMTPCLIENT_HPP_
#include <smtp/smtp.hpp>
#endif
class Evaluator
{
public:
static void evaluate(void);
private:
static bool getAppKeys(Block<String> &keys);
static bool getNotifyKeys(Block<String> &keys);
static void evaluateAppKeys(Block<String> &keys);
static void evaluateNotifyKeys(Block<String> &keys);
Evaluator();
virtual ~Evaluator();
};
#endif

BIN
watchdog/MC.EXE Normal file

Binary file not shown.

BIN
watchdog/MSG00001.bin Normal file

Binary file not shown.

View File

@@ -0,0 +1,106 @@
#include <watchdog/ServiceControlManager.hpp>
bool ServiceControlManager::startService(const String &serviceName,Block<String> &serviceArgs)
{
char **pArgs=(char**)0;
DWORD access=0;
bool retCode=false;
if(!isOkay())return false;
ServiceHandle serviceHandle;
serviceHandle.setHandle(::OpenService(mServiceHandle.getHandle(),serviceName,
SERVICE_PAUSE_CONTINUE|SERVICE_START|SERVICE_STOP),ServiceHandle::Delete);
if(!serviceHandle.isOkay())
{
mLastError=::GetLastError();
return retCode;
}
pArgs=new (char*[serviceArgs.size()]);
for(int index=0;index<serviceArgs.size();index++)
{
pArgs[index]=serviceArgs[index].str();
}
retCode=::StartService(serviceHandle.getHandle(),serviceArgs.size(),(const char**)pArgs);
if(!retCode)mLastError=::GetLastError();
return retCode;
}
bool ServiceControlManager::createService(CreateServiceParams &csp,ServiceHandle &serviceHandle)
{
Array<char> dependencies;
if(!isOkay())return false;
csp.getNullSeparatedDependencies(dependencies);
serviceHandle.setHandle(::CreateService(mServiceHandle.getHandle(),csp.getServiceName().str(),
csp.getDisplayName().str(),csp.getDesiredAccess(),csp.getServiceType(),
csp.getStartType(),csp.getErrorControl(),csp.getBinaryPathName().str(),
csp.getLoadOrderGroup().isNull()?(char*)0:csp.getLoadOrderGroup().str(),
0,dependencies.size()?&dependencies[0]:0,
csp.getServiceStartName().isNull()?(char*)0:csp.getServiceStartName().str(),
csp.getPassword().isNull()?(char*)0:csp.getPassword().str()),ServiceHandle::Delete);
if(!serviceHandle.isOkay())mLastError=::GetLastError();
return serviceHandle.isOkay();
}
bool ServiceControlManager::deleteService(const String &serviceName)
{
bool retCode=false;
if(!isOkay())return retCode;
ServiceHandle serviceHandle;
serviceHandle.setHandle(::OpenService(mServiceHandle.getHandle(),serviceName,DELETE),ServiceHandle::Delete);
if(!serviceHandle.isOkay())
{
mLastError=::GetLastError();
return retCode;
}
retCode=::DeleteService(serviceHandle.getHandle())?true:false;
if(!retCode)mLastError=::GetLastError();
return retCode;
}
String ServiceControlManager::getLastErrorCode(void)const
{
switch(mLastError)
{
case ERROR_ACCESS_DENIED :
return "ERROR_ACCESS_DENIED";
case ERROR_CIRCULAR_DEPENDENCY :
return "ERROR_CIRCULAR_DEPENDENCY";
case ERROR_DUP_NAME :
return "ERROR_DUP_NAME";
case ERROR_INVALID_HANDLE :
return "ERROR_INVALID_HANDLE";
case ERROR_INVALID_NAME :
return "ERROR_INVALID_NAME";
case ERROR_INVALID_PARAMETER :
return "ERROR_INVALID_PARAMETER";
case ERROR_INVALID_SERVICE_ACCOUNT :
return "ERROR_INVALID_SERVICE_ACCOUNT";
case ERROR_SERVICE_EXISTS :
return "ERROR_SERVICE_EXISTS";
case ERROR_PATH_NOT_FOUND :
return "ERROR_PATH_NOT_FOUND";
case ERROR_SERVICE_ALREADY_RUNNING :
return "ERROR_SERVICE_ALREADY_RUNNING";
case ERROR_SERVICE_DATABASE_LOCKED :
return "ERROR_SERVICE_DATABASE_LOCKED";
case ERROR_SERVICE_DEPENDENCY_DELETED :
return "ERROR_SERVICE_DEPENDENCY_DELETED";
case ERROR_SERVICE_DEPENDENCY_FAIL :
return "ERROR_SERVICE_DEPENDENCY_FAIL";
case ERROR_SERVICE_DISABLED :
return "ERROR_SERVICE_DISABLED";
case ERROR_SERVICE_LOGON_FAILED :
return "ERROR_SERVICE_LOGON_FAILED";
case ERROR_SERVICE_MARKED_FOR_DELETE :
return "ERROR_SERVICE_MARKED_FOR_DELETE";
case ERROR_SERVICE_NO_THREAD :
return "ERROR_SERVICE_NO_THREAD";
case ERROR_SERVICE_REQUEST_TIMEOUT :
return "ERROR_SERVICE_REQUEST_TIMEOUT";
case ERROR_SERVICE_DOES_NOT_EXIST :
return "ERROR_SERVICE_DOES_NOT_EXIST";
default :
return String("WinError code:")+String().fromInt(mLastError);
}
}

View File

@@ -0,0 +1,52 @@
#ifndef _WATCHDOG_SERVICECONTROLMANAGER_HPP_
#define _WATCHDOG_SERVICECONTROLMANAGER_HPP_
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _WATCHDOG_SERVICEHANDLE_HPP_
#include <watchdog/ServiceHandle.hpp>
#endif
#ifndef _WATCHDOG_CREATESERVICEPARAMS_HPP_
#include <watchdog/CreateServiceParams.hpp>
#endif
class ServiceControlManager
{
public:
enum Access{Connect=SC_MANAGER_CONNECT,Enumerate=SC_MANAGER_ENUMERATE_SERVICE,QueryLock=SC_MANAGER_QUERY_LOCK_STATUS,
ModifyBootConfig=SC_MANAGER_MODIFY_BOOT_CONFIG,StandardRightsRead=STANDARD_RIGHTS_READ,
StandardRightsWrite=STANDARD_RIGHTS_WRITE,StandardRightsExecute=STANDARD_RIGHTS_EXECUTE,
AllAccess=SC_MANAGER_ALL_ACCESS,CreateService=SC_MANAGER_CREATE_SERVICE,
Lock=SC_MANAGER_LOCK};
ServiceControlManager(Access access=AllAccess,const String &machineName=String(),const String &databaseName=String());
virtual ~ServiceControlManager();
bool createService(CreateServiceParams &csp,ServiceHandle &serviceHandle);
bool deleteService(const String &serviceName);
bool startService(const String &serviceName,Block<String> &serviceArgs=Block<String>());
bool isOkay(void)const;
String getLastErrorCode(void)const;
private:
ServiceHandle mServiceHandle;
DWORD mLastError;
};
inline
ServiceControlManager::ServiceControlManager(Access access,const String &machineName,const String &databaseName)
: mLastError(0)
{
mServiceHandle.setHandle(::OpenSCManager(machineName.isNull()?(char*)0:machineName.str(),databaseName.isNull()?(char*)0:databaseName.str(),access),ServiceHandle::Delete);
if(!mServiceHandle.isOkay())mLastError=::GetLastError();
}
inline
ServiceControlManager::~ServiceControlManager()
{
}
inline
bool ServiceControlManager::isOkay(void)const
{
return mServiceHandle.isOkay();
}
#endif

View File

@@ -0,0 +1,92 @@
#ifndef _WATCHDOG_SERVICEHANDLE_HPP_
#define _WATCHDOG_SERVICEHANDLE_HPP_
#ifndef _COMMON_WINSVC_HPP_
#include <common/winsvc.hpp>
#endif
class ServiceHandle
{
public:
enum Disposition{Assume,Delete};
ServiceHandle();
ServiceHandle(SC_HANDLE handle,Disposition disposition=Assume);
virtual ~ServiceHandle();
SC_HANDLE getHandle(void)const;
void setHandle(SC_HANDLE handle,Disposition disposition);
Disposition getDisposition(void)const;
void setDisposition(Disposition disposition);
bool isOkay(void)const;
private:
void closeHandle(void);
SC_HANDLE mSCHandle;
Disposition mDisposition;
};
inline
ServiceHandle::ServiceHandle()
: mSCHandle(0), mDisposition(Delete)
{
}
inline
ServiceHandle::ServiceHandle(SC_HANDLE handle,Disposition disposition)
: mSCHandle(handle), mDisposition(disposition)
{
}
inline
ServiceHandle::~ServiceHandle()
{
}
inline
SC_HANDLE ServiceHandle::getHandle(void)const
{
return mSCHandle;
}
inline
void ServiceHandle::setHandle(SC_HANDLE handle,Disposition disposition)
{
closeHandle();
mSCHandle=handle;
mDisposition=disposition;
}
inline
ServiceHandle::Disposition ServiceHandle::getDisposition(void)const
{
return mDisposition;
}
inline
void ServiceHandle::setDisposition(Disposition disposition)
{
mDisposition=disposition;
}
inline
bool ServiceHandle::isOkay(void)const
{
return mSCHandle?true:false;
}
inline
void ServiceHandle::closeHandle()
{
if(!mSCHandle)
{
mDisposition=Delete;
return;
}
if(Assume==mDisposition)
{
mSCHandle=0;
mDisposition=Delete;
return;
}
::CloseServiceHandle(mSCHandle);
mSCHandle=0;
}
#endif

View File

@@ -0,0 +1,32 @@
#ifndef _WATCHDOG_WATCHDOGSERVICE_HPP_
#define _WATCHDOG_WATCHDOGSERVICE_HPP_
#ifndef _WATCHDOG_SERVICE_HPP_
#include <watchdog/service.hpp>
#endif
#ifndef _THREAD_MESSAGETHREAD_HPP_
#include <thread/mthread.hpp>
#endif
#ifndef _THREAD_THREADCALLBACK_HPP_
#include <thread/tcallbck.hpp>
#endif
class WatchDogService : public Service, private MessageThread
{
public:
WatchDogService();
virtual ~WatchDogService();
protected:
virtual bool initialize(void);
virtual void controlStop(void);
virtual void controlPause(void);
virtual void controlContinue(void);
virtual void controlInterrogate(void);
virtual void controlShutdown(void);
private:
DWORD threadHandler(ThreadMessage &threadMessage);
void thHandleStart();
ThreadCallback<WatchDogService> mThreadHandler;
Event mServiceEvent;
};
#endif

50
watchdog/main.cpp Normal file
View File

@@ -0,0 +1,50 @@
#include <common/windows.hpp>
#include <common/string.hpp>
#include <common/winsvc.hpp>
#include <common/file.hpp>
#include <thread/event.hpp>
#include <WatchDog/WatchDogService.hpp>
#include <WatchDog/Evaluator.hpp>
int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int nCmdShow)
{
ServiceControlManager serviceControlManager;
ServiceHandle service;
CreateServiceParams createServiceParams;
String strPathBinaryFile;
String strCommandLine;
String serviceName;
String serviceDisplayName;
serviceName="WatchDog";
serviceDisplayName="WatchDog Service";
strCommandLine=lpszCmdLine;
if(strCommandLine=="register")
{
String strDependencies;
// strDependencies="MSSQLServer"; do a better job with this one.
::GetModuleFileName(::GetModuleHandle(0),strPathBinaryFile,String::MaxString);
createServiceParams.setServiceName(serviceName);
createServiceParams.setDisplayName(serviceDisplayName);
createServiceParams.setDesiredAccess(SERVICE_ALL_ACCESS);
createServiceParams.setServiceType(SERVICE_WIN32_OWN_PROCESS);
createServiceParams.setStartType(SERVICE_AUTO_START);
createServiceParams.setErrorControl(SERVICE_ERROR_IGNORE);
createServiceParams.setBinaryPathName(strPathBinaryFile);
createServiceParams.setDependencies(strDependencies);
if(!serviceControlManager.createService(createServiceParams,service))
::OutputDebugString(serviceControlManager.getLastErrorCode()+String("\n"));
}
else if(strCommandLine=="unregister")
{
if(!serviceControlManager.deleteService(serviceName))
::OutputDebugString(serviceControlManager.getLastErrorCode()+String("\n"));
}
else
{
WatchDogService service;
service.startServiceControlDispatcher(serviceName);
}
return 0;
}

24
watchdog/scraps.txt Normal file
View File

@@ -0,0 +1,24 @@
/* for(int i=0;i<moduleInfoList.size();i++)
{
String strModuleFileName;
processAPI.getModuleFileName(processInfoList[index].processID(),moduleInfoList[i].module(),strModuleFileName);
MODULEINFO moduleInfo;
HANDLE hProcess;
hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,false, processInfoList[index].processID().processID());
// processAPI.getModuleInformation(hProcess,moduleInfoList[i].module(),&moduleInfo,sizeof(MODULEINFO));
::CloseHandle(hProcess);
::OutputDebugString(strModuleFileName+String("\n"));
// ::OutputDebugString(moduleInfoList[i].moduleFileName());
} */
// Service::getInstance().startServiceControlDispatcher(serviceName);
// Service service;
// service.startServiceControlDispatcher();
// if(!serviceControlManager.startService(serviceName))
// ::OutputDebugString(serviceControlManager.getLastErrorCode()+String("\n"));

114
watchdog/service.cpp Normal file
View File

@@ -0,0 +1,114 @@
#include <watchdog/service.hpp>
Service::Service()
: mhServiceStatus(0), mServiceStatus(Stopped)
{
}
Service::~Service()
{
}
bool Service::startServiceControlDispatcher(const String &serviceName)
{
SERVICE_TABLE_ENTRY serviceTableEntry[2];
bool retCode;
::memset(&serviceTableEntry,0,sizeof(serviceTableEntry));
mServiceName=serviceName;
serviceTableEntry[0].lpServiceName=(char*)serviceName.str();
serviceTableEntry[0].lpServiceProc=(CBThunkSvcMain::LPFNSERVICEMAIN)CBThunkSvcMain::getAddress();
retCode=::StartServiceCtrlDispatcher((SERVICE_TABLE_ENTRY*)&serviceTableEntry);
return retCode;
}
void Service::setStatus(ServiceStatus status,DWORD exitCode,DWORD checkPoint,DWORD waitHint)
{
SERVICE_STATUS serviceStatus;
mServiceStatus=status;
::memset(&serviceStatus,0,sizeof(serviceStatus));
serviceStatus.dwServiceType=SERVICE_WIN32;
serviceStatus.dwCurrentState=status;
serviceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE|SERVICE_ACCEPT_SHUTDOWN;
serviceStatus.dwWin32ExitCode=0;
serviceStatus.dwCheckPoint=0;
serviceStatus.dwWaitHint=0;
::SetServiceStatus(mhServiceStatus,&serviceStatus);
if(Stopped==status)mServiceEvent.setEvent();
}
// **********************************************************************************************
// *************************************** VIRTUALS *********************************************
// **********************************************************************************************
void Service::serviceMain(DWORD dwArgc,LPTSTR *pszArg)
{
mhServiceStatus=::RegisterServiceCtrlHandler(mServiceName,(CBThunkCtrlHandler::LPFNCONTROLHANDLER)CBThunkCtrlHandler::getAddress());
setStatus(StartPending);
if(!initialize())
{
setStatus(Stopped);
return;
}
setStatus(Running);
mServiceEvent.waitEvent();
}
void Service::controlHandler(DWORD control)
{
switch(control)
{
case SERVICE_CONTROL_STOP :
controlStop();
setStatus(Stopped,NO_ERROR,1,1000);
break;
case SERVICE_CONTROL_PAUSE :
controlPause();
setStatus(Paused,NO_ERROR,1,1000);
break;
case SERVICE_CONTROL_CONTINUE :
controlContinue();
setStatus(Running);
break;
case SERVICE_CONTROL_INTERROGATE :
controlInterrogate();
setStatus(mServiceStatus);
break;
case SERVICE_CONTROL_SHUTDOWN :
controlShutdown();
setStatus(Stopped,NO_ERROR,1,1000);
break;
}
}
bool Service::initialize(void)
{
return true;
}
void Service::controlStop(void)
{
return;
}
void Service::controlPause(void)
{
return;
}
void Service::controlContinue(void)
{
return;
}
void Service::controlInterrogate(void)
{
return;
}
void Service::controlShutdown(void)
{
return;
}

57
watchdog/service.hpp Normal file
View File

@@ -0,0 +1,57 @@
#ifndef _WATCHDOG_SERVICE_HPP_
#define _WATCHDOG_SERVICE_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_WINSVC_HPP_
#include <common/winsvc.hpp>
#endif
#ifndef _THREAD_EVENT_HPP_
#include <thread/event.hpp>
#endif
#ifndef _WATCHDOG_CREATESERVICEPARAMS_HPP_
#include <watchdog/CreateServiceParams.hpp>
#endif
#ifndef _WATCHDOG_SERVICEHANDLE_HPP_
#include <watchdog/ServiceHandle.hpp>
#endif
#ifndef _WATCHDOG_SERVICECONTROLMANAGER_HPP_
#include <watchdog/ServiceControlManager.hpp>
#endif
#ifndef _WATCHDOG_CBTHUNKSVCMAIN_HPP_
#include <watchdog/CBThunkSvcMain.hpp>
#endif
#ifndef _WATCHDOG_CBTHUNKCTRLHANDLER_HPP_
#include <watchdog/CBThunkCtrlHandler.hpp>
#endif
class Service : private CBThunkSvcMain, private CBThunkCtrlHandler
{
public:
Service();
virtual ~Service();
bool startServiceControlDispatcher(const String &serviceName);
protected:
virtual bool initialize(void);
virtual void controlStop(void);
virtual void controlPause(void);
virtual void controlContinue(void);
virtual void controlInterrogate(void);
virtual void controlShutdown(void);
private:
enum ServiceStatus{Stopped=SERVICE_STOPPED,StartPending=SERVICE_START_PENDING,
StopPending=SERVICE_STOP_PENDING,Running=SERVICE_RUNNING,ContinuePending=SERVICE_CONTINUE_PENDING,
PausePending=SERVICE_PAUSE_PENDING,Paused=SERVICE_PAUSED};
void setStatus(ServiceStatus status,DWORD exitCode=0,DWORD checkPoint=0,DWORD waitHint=0);
void serviceMain(DWORD dwArgc,LPTSTR *pszArg);
void controlHandler(DWORD control);
String mServiceName;
SERVICE_STATUS_HANDLE mhServiceStatus;
Event mServiceEvent;
ServiceStatus mServiceStatus;
};
#endif

135
watchdog/watchdog.dsp Normal file
View File

@@ -0,0 +1,135 @@
# Microsoft Developer Studio Project File - Name="watchdog" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=watchdog - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "watchdog.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "watchdog.mak" CFG="watchdog - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "watchdog - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "watchdog - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "watchdog - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "watchdog - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /Gz /MTd /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "STRICT" /D "__FLAT__" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "watchdog - Win32 Release"
# Name "watchdog - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CBThunkCtrlHandler.cpp
# End Source File
# Begin Source File
SOURCE=.\CBThunkSvcMain.cpp
# End Source File
# Begin Source File
SOURCE=.\CreateServiceParams.cpp
# End Source File
# Begin Source File
SOURCE=.\Evaluator.cpp
# End Source File
# Begin Source File
SOURCE=.\main.cpp
# End Source File
# Begin Source File
SOURCE=.\service.cpp
# End Source File
# Begin Source File
SOURCE=.\ServiceControlManager.cpp
# End Source File
# Begin Source File
SOURCE=.\watchdogservice.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

134
watchdog/watchdog.dsw Normal file
View File

@@ -0,0 +1,134 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "common"=..\common\common.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "hookproc"=..\hookproc\hookproc.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "image"=..\image\image.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "psapint"=..\psapint\psapint.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "smtplib"=..\smtp\Smtplib.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "socket"=..\socket\socket.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "thread"=..\thread\thread.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "watchdog"=.\watchdog.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name common
End Project Dependency
Begin Project Dependency
Project_Dep_Name thread
End Project Dependency
Begin Project Dependency
Project_Dep_Name hookproc
End Project Dependency
Begin Project Dependency
Project_Dep_Name psapint
End Project Dependency
Begin Project Dependency
Project_Dep_Name image
End Project Dependency
Begin Project Dependency
Project_Dep_Name smtplib
End Project Dependency
Begin Project Dependency
Project_Dep_Name socket
End Project Dependency
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

63
watchdog/watchdog.h Normal file
View File

@@ -0,0 +1,63 @@
//
// Values are 32 bit values layed out as follows:
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---+-+-+-----------------------+-------------------------------+
// |Sev|C|R| Facility | Code |
// +---+-+-+-----------------------+-------------------------------+
//
// where
//
// Sev - is the severity code
//
// 00 - Success
// 01 - Informational
// 10 - Warning
// 11 - Error
//
// C - is the Customer code flag
//
// R - is a reserved bit
//
// Facility - is the facility code
//
// Code - is the facility's status code
//
//
// Define the facility codes
//
//
// Define the severity codes
//
//
// MessageId: EVMSG_INSTALLED
//
// MessageText:
//
// The %1 service was installed.
//
#define EVMSG_INSTALLED 0x00000064L
//
// MessageId: EVMSG_REMOVED
//
// MessageText:
//
// The %1 service was removed.
//
#define EVMSG_REMOVED 0x00000065L
//
// MessageId: EVMSG_NOTREMOVED
//
// MessageText:
//
// The %1 service could not be removed.
//
#define EVMSG_NOTREMOVED 0x00000066L

18
watchdog/watchdog.mc Normal file
View File

@@ -0,0 +1,18 @@
MessageId=100
SymbolicName=EVMSG_INSTALLED
Language=English
The %1 service was installed.
.
MessageId=
SymbolicName=EVMSG_REMOVED
Language=English
The %1 service was removed.
.
MessageId=
SymbolicName=EVMSG_NOTREMOVED
Language=English
The %1 service could not be removed.
.

BIN
watchdog/watchdog.opt Normal file

Binary file not shown.

46
watchdog/watchdog.plg Normal file
View File

@@ -0,0 +1,46 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: watchdog - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\WINNT\Profiles\sean\LOCALS~1\Temp\RSP7.tmp" with contents
[
/nologo /Gz /MTd /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "STRICT" /D "__FLAT__" /Fp"Debug/watchdog.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"D:\work\watchdog\main.cpp"
]
Creating command line "cl.exe @C:\WINNT\Profiles\sean\LOCALS~1\Temp\RSP7.tmp"
Creating temporary file "C:\WINNT\Profiles\sean\LOCALS~1\Temp\RSP8.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/watchdog.pdb" /debug /machine:I386 /out:"Debug/watchdog.exe" /pdbtype:sept
.\Debug\CBThunkCtrlHandler.obj
.\Debug\CBThunkSvcMain.obj
.\Debug\CreateServiceParams.obj
.\Debug\Evaluator.obj
.\Debug\main.obj
.\Debug\service.obj
.\Debug\ServiceControlManager.obj
.\Debug\watchdogservice.obj
\work\exe\mscommon.lib
\work\exe\msthread.lib
\work\exe\mshook.lib
\work\exe\psapint.lib
\work\exe\msimage.lib
\work\exe\smtplib.lib
\work\exe\mssocket.lib
]
Creating command line "link.exe @C:\WINNT\Profiles\sean\LOCALS~1\Temp\RSP8.tmp"
<h3>Output Window</h3>
Compiling...
main.cpp
Linking...
<h3>Results</h3>
watchdog.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

2
watchdog/watchdog.rc Normal file
View File

@@ -0,0 +1,2 @@
LANGUAGE 0x9,0x1
1 11 MSG00001.bin

BIN
watchdog/watchdog.reg Normal file

Binary file not shown.

View File

@@ -0,0 +1,68 @@
#include <watchdog/watchdogservice.hpp>
#include <watchdog/Evaluator.hpp>
#include <common/process.hpp>
#include <common/regkey.hpp>
WatchDogService::WatchDogService()
: MessageThread(false)
{
mThreadHandler.setCallback(this,&WatchDogService::threadHandler);
insertHandler(&mThreadHandler);
}
WatchDogService::~WatchDogService()
{
removeHandler(&mThreadHandler);
}
bool WatchDogService::initialize(void)
{
start();
return true;
}
void WatchDogService::controlStop(void)
{
stop();
mServiceEvent.waitEvent();
}
void WatchDogService::controlPause(void)
{
}
void WatchDogService::controlContinue(void)
{
}
void WatchDogService::controlInterrogate(void)
{
}
void WatchDogService::controlShutdown(void)
{
stop();
}
DWORD WatchDogService::threadHandler(ThreadMessage &threadMessage)
{
switch(threadMessage.message())
{
case ThreadMessage::TM_VOID :
break;
case ThreadMessage::TM_CREATE :
thHandleStart();
break;
case ThreadMessage::TM_DESTROY :
mServiceEvent.setEvent();
break;
case ThreadMessage::TM_USER :
break;
}
return 0;
}
void WatchDogService::thHandleStart()
{
Evaluator::evaluate();
}