/******************************************************************************/
/*
/*    NT Service Class
/*
/*    copyright 2003  , Stefan Voitel - Berlin / Germany
/*
/*    stefan.voitel@winways.de	
/******************************************************************************/

#ifndef _NT_SERVICE_CLASS_H
#define _NT_SERVICE_CLASS_H

#include <afx.h>
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

#include <iostream>

#include "cService.h"

#ifndef SERVICE_CLASS_INCLUDED
#define SERVICE_CLASS_INCLUDED

#define REG_CONFIG   "SYSTEM\\CurrentControlSet\\Services\\%s\\ServiceConfig"
#define REG_EVENTLOG "SYSTEM\\CurrentControlSet\\Services\\EventLog\\System"

class TService {
 protected:
   TService();
  ~TService();

   bool          Execute                 (void);
   bool          ConsoleMode             (void);

   bool          Start                   (void);
   bool          Stop                    (void);
   bool          Install                 (void);
   bool          Remove                  (void);
   virtual bool  Help                    (DWORD context = 0);

   bool          Terminated              (void) {return m_Terminated;}
   void          Terminate               (void) {m_Terminated = true;}


   const char   *LastError               (void) const  {return m_ErrorString;}
   void          PrintLastError          (const char *Caption = NULL);

   enum cfValType {
      cfBinary  = REG_BINARY,
      cfDword   = REG_DWORD,
      cfString  = REG_SZ
      };

   bool SetConfigValue (char* key,BYTE *val,DWORD nval,cfValType t = cfString);
   bool GetConfigValue (char* key,BYTE *buf,DWORD *nbuff,cfValType *t);

   enum evLogType  {
      evError   = EVENTLOG_ERROR_TYPE,
      evWarning = EVENTLOG_WARNING_TYPE,
      evInfo    = EVENTLOG_INFORMATION_TYPE
      };

   void LogEvent       (char* e,evLogType t = evInfo,WORD cat = 0);

   virtual const char*    GetName        (void) = 0;
   virtual void           ServiceProc    (void) = 0;

   virtual const char*    GetDisplayName (void)         {return GetName();}
   virtual bool           Init           (void)         {return true;}
   virtual void           Cleanup        (void)         {return;}
   virtual void           LogoffEvent    (void)         {return;}
   virtual void           ShutdownEvent  (void)         {Terminate();}

  private:

   typedef SC_HANDLE tSvcHandle;

   SERVICE_STATUS_HANDLE  m_StatusHandle;
   DWORD                  m_StatusCode;
   HANDLE                 m_EventLog;
   bool                   m_Terminated;
   char                   m_ErrorString[512];

   bool                   shopen         (tSvcHandle &hService);
   void                   shclose        (tSvcHandle hService);
   bool                   succeeded      (BOOL	ReturnValue);

   void                   SetStatus      (DWORD status);
   static void  WINAPI    ServiceMain    (DWORD argc,char* argv[]);
   static void  WINAPI    ServiceHandler (DWORD ServiceControl);
   static BOOL  WINAPI    ConsoleHandler (DWORD dwCtrlType);
};

#endif // SERVICE_CLASS_INCLUDED
#endif