/******************************************************************************/
/*
/* NT Service Class
/*
/* copyright 2003 , Stefan Voitel - Berlin / Germany
/*
/* stefan.voitel@winways.de
/******************************************************************************/
namespace ModuleTService {
TService* Service; //
};
// -----------------------------------------------------------------------------
#pragma warning (disable : 100)
#if defined (__BORLANDC__)
#pragma argsused
#endif
void WINAPI TService::ServiceMain (DWORD argc, char* argv[]) {
using namespace ModuleTService;
Service->m_StatusHandle = RegisterServiceCtrlHandler(Service->GetName(),
ServiceHandler);
if (Service->succeeded (Service->m_StatusHandle != NULL)) {
Service->SetStatus (SERVICE_START_PENDING);
if (Service->Init()) {
Service->SetStatus (SERVICE_RUNNING);
Service->ServiceProc();
Service->SetStatus (SERVICE_STOP_PENDING);
Service->Cleanup();
Service->SetStatus (SERVICE_STOPPED);
}
else Service->SetStatus (SERVICE_STOPPED);
}
else Service->SetStatus (SERVICE_STOPPED);
}
#pragma warning (default : 100)
// ----------------------------
void WINAPI TService::ServiceHandler (DWORD control) {
using namespace ModuleTService;
switch (control) {
case SERVICE_CONTROL_INTERROGATE:
Service->SetStatus (Service->m_StatusCode);
break;
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
Service->SetStatus (SERVICE_STOP_PENDING);
Service->m_Terminated = true;
break;
}
}
// ----------------------------
BOOL WINAPI TService::ConsoleHandler (DWORD dwCtrlType) {
using namespace ModuleTService;
if (dwCtrlType == CTRL_LOGOFF_EVENT)
Service->LogoffEvent ();
else Service->ShutdownEvent ();
return TRUE;
}
// -----------------------------------------------------------------------------
TService::TService() :
m_StatusHandle(NULL),m_StatusCode(SERVICE_STOPPED),m_Terminated(false) {
ModuleTService::Service = this;
ZeroMemory (m_ErrorString,sizeof(m_ErrorString));
succeeded(SetConsoleCtrlHandler (ConsoleHandler,TRUE));
}
// ----------------------------
TService::~TService() {
if (m_EventLog)
DeregisterEventSource (m_EventLog);
}
// ----------------------------
bool TService::shopen (tSvcHandle &hService) {
bool success = false;
tSvcHandle hSCM;
if ((hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS)) != NULL) {
hService = OpenService(hSCM,GetName(),SERVICE_ALL_ACCESS);
success = succeeded (hService != NULL);
CloseServiceHandle (hSCM);
}
else succeeded (false);
return success;
}
// ----------------------------
void TService::shclose (tSvcHandle hService) {
CloseServiceHandle (hService);
}
// ----------------------------
void TService::SetStatus (DWORD status) {
m_StatusCode = status;
SERVICE_STATUS ss;
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ss.dwCurrentState = m_StatusCode;
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;
ss.dwWin32ExitCode = NOERROR;
ss.dwServiceSpecificExitCode = NOERROR;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 3000;
if (! succeeded (SetServiceStatus (m_StatusHandle,&ss)))
LogEvent (m_ErrorString,evWarning);
}
// ----------------------------
bool TService::succeeded (BOOL success) {
DWORD SysError = success ? ERROR_SUCCESS : GetLastError();
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,NULL,SysError,
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
m_ErrorString,sizeof(m_ErrorString),NULL);
return SysError == ERROR_SUCCESS;
}
// -----------------------------------------------------------------------------
bool TService::Execute () {
m_EventLog = RegisterEventSource (NULL,GetName());
SERVICE_TABLE_ENTRY entries[2];
entries[0].lpServiceName = (char*) GetName();
entries[0].lpServiceProc = ServiceMain;
entries[1].lpServiceName = NULL;
entries[1].lpServiceProc = NULL;
bool success = succeeded (StartServiceCtrlDispatcher(entries));
if (! success)
LogEvent (m_ErrorString,evError);
return success;
}
// ----------------------------
bool TService::ConsoleMode (void) {
m_EventLog = RegisterEventSource(NULL,GetName());
bool success = false;
if (Init()) {
ServiceProc();
Cleanup ();
success = true;
}
return success;
}
// -----------------------------------------------------------------------------
bool TService::Start() {
bool success = false;
tSvcHandle hService;
if (shopen (hService)) {
success = succeeded (StartService (hService,0,NULL));
shclose (hService);
}
return success;
}
// ----------------------------
bool TService::Stop() {
bool success = false;
tSvcHandle hService;
if (shopen (hService)) {
SERVICE_STATUS state;
success = succeeded (ControlService (hService,SERVICE_CONTROL_STOP,&state));
shclose (hService);
}
return success;
}
// ----------------------------
bool TService::Remove() {
Stop();
bool success = false;
tSvcHandle hService;
if (shopen (hService)) {
success = succeeded (DeleteService (hService));
shclose (hService);
HKEY hKey;
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,REG_EVENTLOG,0,KEY_ALL_ACCESS,&hKey)
== ERROR_SUCCESS) {
RegDeleteKey (hKey,GetName());
RegCloseKey (hKey);
}
}
return success;
}
// ----------------------------
bool TService::Install() {
bool success = false;
SC_HANDLE hService,hSCManager;
char imagePath[MAX_PATH];
GetModuleFileName(NULL,imagePath,MAX_PATH);
if (succeeded ((hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS))
!= NULL)) {
if (succeeded ((hService = ::CreateService (hSCManager,
GetName(),GetDisplayName(),
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,
imagePath,NULL,NULL,NULL,NULL,NULL)) != NULL)) {
CloseServiceHandle (hService);
success = true;
}
CloseServiceHandle (hSCManager);
}
if (success) {
UINT f = EVENTLOG_ERROR_TYPE|EVENTLOG_WARNING_TYPE|EVENTLOG_INFORMATION_TYPE;
char szKey [MAX_PATH];
wsprintf (szKey,"%s\\%s",REG_EVENTLOG,GetName());
HKEY hKey;
if (RegCreateKey (HKEY_LOCAL_MACHINE,szKey,&hKey) == ERROR_SUCCESS) {
char mod[MAX_PATH];
DWORD len = GetModuleFileName (NULL,mod,MAX_PATH);
RegSetValueEx(hKey,"TypesSupported",0,REG_DWORD,(BYTE*) &f,sizeof(DWORD));
RegSetValueEx(hKey,"EventMessageFile",0,REG_SZ,(BYTE*) mod,len+1);
RegCloseKey (hKey);
}
}
return success;
}
// ----------------------------
bool TService::Help (DWORD context) {
char file [MAX_PATH +6],*p;
GetModuleFileName (NULL,file,MAX_PATH);
if ((p = strrchr (file,'.')) != NULL)
strcpy (p,".hlp");
return WinHelp (NULL,file,context ? HELP_CONTEXT : HELP_CONTENTS,context) != 0;
}
// -----------------------------------------------------------------------------
void TService::PrintLastError (const char *cap) {
DWORD n;
if (cap != NULL && *cap) {
WriteConsole (GetStdHandle(STD_ERROR_HANDLE),"\r\n",2,&n,NULL);
WriteConsole (GetStdHandle(STD_ERROR_HANDLE),cap,(DWORD)strlen(cap),&n,NULL);
}
char oem[sizeof(m_ErrorString)];
ZeroMemory (oem,sizeof(oem));
CharToOemBuff (m_ErrorString,oem,(DWORD) strlen(m_ErrorString));
WriteConsole (GetStdHandle(STD_ERROR_HANDLE),"\r\n",2,&n,NULL);
WriteConsole (GetStdHandle(STD_ERROR_HANDLE),oem,(DWORD) strlen(oem),&n,NULL);
}
// ----------------------------
void TService::LogEvent (char* str,evLogType type,WORD Category) {
if (m_EventLog != NULL) {
const char* msgs[1];
msgs[0] = str;
ReportEvent (m_EventLog,(WORD) type,Category,0,NULL,1,0,msgs,NULL);
}
}
// -----------------------------------------------------------------------------
bool TService::SetConfigValue (char* key,BYTE *b,DWORD n,cfValType t) {
char RegPath[255];
HKEY hk;
DWORD disp;
bool success = false;
wsprintf (RegPath,REG_CONFIG,GetName());
if (succeeded (RegCreateKeyEx (HKEY_LOCAL_MACHINE,RegPath,0,NULL,
REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hk,&disp)
== ERROR_SUCCESS)) {
ZeroMemory (b,n);
success = succeeded (RegSetValueEx (hk,key,0,(DWORD)t,b,n) == ERROR_SUCCESS);
RegCloseKey (hk);
}
return success;
}
// ----------------------------
bool TService::GetConfigValue (char* key,BYTE *b,DWORD *n,cfValType *t) {
char RegPath[255];
HKEY hk;
DWORD disp;
bool success = false;
wsprintf (RegPath,REG_CONFIG,GetName());
if (succeeded (RegCreateKeyEx (HKEY_LOCAL_MACHINE,RegPath,0,NULL,
REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hk,&disp)
== ERROR_SUCCESS)) {
ZeroMemory (b,*n);
success = succeeded (RegQueryValueEx (hk,key,0,(DWORD*)t,b,n)
== ERROR_SUCCESS);
RegCloseKey (hk);
}
return success;
}
// -----------------------------------------------------------------------------
// EOF