1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
// Classe abstraite CService (destructeur virtuel pur)
class CService
{
private :
LPCTSTR m_szSvcName; //Nom du service
LPCTSTR m_szDisplayName; //Libelle affiché du service
LPCTSTR m_szDescription; //Description du service
LPTHREAD_START_ROUTINE m_pfnThread; //Routine thread du service
LPVOID m_pfnParam; //param de la routine
HANDLE m_hTerminateEvent;
HANDLE m_hTerminateThread;
HANDLE m_hThread; //Handle du thread crée pour le service
SERVICE_STATUS_HANDLE m_dwStatus;
BOOL m_bPause;
BOOL m_bRunning;
DWORD m_dwDesiredAccess; //Flags de création du service
DWORD m_dwServiceType;
DWORD m_dwStartType;
DWORD m_dwErrorControl;
//Private copy constructor and operator= without defining them
CService( const CService& s );
CService& operator=( const CService& s );
//Objet unique global (utile dans les fonctions statiques)
static CService* m_pObj;
protected :
CService( LPCTSTR name, LPCTSTR displayName, LPCTSTR desc,
LPTHREAD_START_ROUTINE routine, LPVOID param,
DWORD dwDesiredAcces = SERVICE_ALL_ACCESS, DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS,
DWORD dwStartType = SERVICE_AUTO_START, DWORD dwErrorControl = SERVICE_ERROR_NORMAL) :
//Init list
m_hTerminateEvent(NULL), m_hTerminateThread(NULL), m_hThread(NULL), m_bPause(FALSE), m_bRunning(FALSE), m_dwStatus(0),
m_szSvcName(name), m_szDisplayName(displayName), m_szDescription(desc),
m_pfnThread(routine), m_pfnParam(param),
m_dwDesiredAccess(dwDesiredAcces), m_dwServiceType(dwServiceType), m_dwStartType(dwStartType), m_dwErrorControl(dwErrorControl)
{
//We should ensure that only one call to this constructeur will be allowed
assert( !m_pObj );
m_pObj = this;
}
virtual ~CService() = 0
{
if(m_hThread)
CloseHandle(m_hThread);
if(m_hTerminateEvent)
CloseHandle(m_hTerminateEvent);
if(m_hTerminateThread)
CloseHandle(m_hTerminateThread);
}
public:
void ErrorHandler(const char *s, DWORD err);
BOOL SendStatusToSCM(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode,
DWORD dwCheckPoint,
DWORD dwWaitHint);
static void CtrlHandler(DWORD controlCode);
static void Main(DWORD argc, LPTSTR *argv);
virtual BOOL Management(LPTSTR arg);
BOOL Start();
void Resume();
void Pause();
void Stop();
void Terminate(DWORD error);
void RemoteTerminate();
bool IsTerminated();
void Add();
void Delete();
};
//Classe CApp
class CApp : public CService
{
private:
//Request list
std::map<std::string, std::string> m_listReq;
CRITICAL_SECTION m_csListReq;
//Event to terminate programm
HANDLE m_hEventTerminate;
CServer m_srv;
int m_num;
//App version
static const std::string m_version;
//unique static object
static CApp* m_pApp;
//@IP / Port de connexion
std::string m_ipOut;
unsigned short m_portOut;
//Private copy constructor and operator= without defining them
CApp( const CApp& s );
CApp& operator=( const CApp& s );
//Private constructor = DP Singleton.
//Le compilo donne un warning car this dans la liste d'initialisation
CApp( unsigned short portIn, int nic, const std::string& ipOut, unsigned short portOut) :
CService( "SvcName", "SvcDisplayName", "SvcDescription", (LPTHREAD_START_ROUTINE) &CApp::_ServiceThread, this),
m_srv(portIn, nic, PROT_UDP, (PFN_CMD_MANAGER) &CApp::_CmdManager), //Call the specific "CServer" constructor
m_ipOut( ipOut ), m_portOut( portOut ),
{
//num machine
m_num = utils::GetTokenInt( utils::GetAddIp(nic), 4, '.' );
//Init critical sections
::InitializeCriticalSection( &m_csListReq );
//Create the TerminateEvent
m_hEventTerminate = ::CreateEvent(0, FALSE, FALSE, 0);
}
//Private Destructor : Not virtual because CApp is not designed to be inherited
~CApp() {
//Release any resources
::CloseHandle( m_hEventTerminate) ;
::DeleteCriticalSection( &m_csListReq );
}
public:
//Get our unique CApp instance (Design Pattern Singleton)
//Returns a pointer to the unique instance
static CApp* CreateInstance( unsigned short portIn, int nic, const std::string& ipOut, unsigned short portOut)
{
return ( m_pApp ? m_pApp : m_pApp = new CApp(portIn, nic, ipOut, portOut) );
}
void DeleteInstance() {
delete m_pApp; //ou delete this, ou sinon on aurait pu la faire static et donc appeler CApp::DeleteInstance
}
//Accesseurs
static CApp* GetInstance() {
return m_pApp;
}
int Init();
void Terminate();
bool IsTerminated();
//Each command message is managed by this static member function.
//Static because it is passed as a PFN_CMD_MANAGER parameter to our unique CServer object
static int _CmdManager(unsigned int id, const std::string& trame);
static DWORD _ServiceThread( LPDWORD param );
}; |
Partager