GENERIC_SERVER  0.0.0.9
A light-weight, cross-platform, pluggable, extensible and secure framework for deploying C++ plug-ins.
 All Classes Files Functions Variables Typedefs Pages
service.cpp
1 #ifdef WINDOWS
2 /*
3  Copyright 2013 Broadcom Corporation
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License version 2.1 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <iostream>
20 #include <fstream>
21 #include <algorithm>
22 #include <vector>
23 #include <string>
24 #include <sstream>
25 #include <map>
26 #include <utility>
27 using namespace std;
28 #include "windows.h"
29 #include "time.h"
30 #include "generic_plugin.h"
31 #include "generic_server.h"
32 
33 VOID start_service(LPSTR *argv);
34 SERVICE_STATUS m_ServiceStatus;
35 SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
36 BOOL bRunning=true;
37 void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
38 void WINAPI ServiceCtrlHandler(DWORD Opcode);
39 BOOL InstallService(char *,char *);
40 BOOL DeleteService(char *);
41 BOOL notify_server();
42 
43 int main(int argc, char* argv[])
44 {
45  if(argc > 1)
46  {
47  if(strcmp(argv[1],"-i")==0)
48  {
49  if(argc != 4)
50  {
51  cout << "Usage: generic_server -i <GENERIC_SERVER_NAME> <GENERIC_SERVER_CONF_FILE>" << endl;
52  return(1);
53  }
54  if(InstallService(argv[2],argv[3]))
55  cout << "Service Installed Successfully: " << argv[2] << endl;
56  else
57  cout << "Error Installing Service: " << argv[2] << endl;
58  return(1);
59  }
60  else
61  if(strcmp(argv[1],"-d")==0)
62  {
63  if(argc != 3)
64  {
65  cout << "Usage: generic_server -d <GENERIC_SERVER_NAME>" << endl;
66  return(1);
67  }
68  if(DeleteService(argv[2]))
69  cout << "Service UnInstalled Successfully: " << argv[2] << endl;
70  else
71  cout << "Error UnInstalling Service: " << argv[2] << endl;
72  return(1);
73  }
74  }
75  SERVICE_TABLE_ENTRY DispatchTable[] = {{argv[1],ServiceMain},{NULL,NULL}};
76  if((StartServiceCtrlDispatcher(DispatchTable)) == 0)
77  cout << "Error starting service: " << GetLastError() << endl;
78  return 0;
79 }
80 /*************************************************************************************/
81 
82 void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
83 {
84  m_ServiceStatus.dwServiceType = SERVICE_WIN32;
85  m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
86  m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE;
87  m_ServiceStatus.dwWin32ExitCode = 0;
88  m_ServiceStatus.dwServiceSpecificExitCode = 0;
89  m_ServiceStatus.dwCheckPoint = 0;
90  m_ServiceStatus.dwWaitHint = 0;
91 
92  m_ServiceStatusHandle = RegisterServiceCtrlHandler(argv[0],
93  ServiceCtrlHandler);
94  if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
95  return;
96  if(argc == 0)
97  {
98  m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
99  SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
100  return;
101  }
102  m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
103  m_ServiceStatus.dwCheckPoint = 0;
104  m_ServiceStatus.dwWaitHint = 0;
105  SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
106  bRunning=true;
107  while(bRunning)
108  start_service(argv);
109  return;
110 }
111 /*************************************************************************************/
112 
113 void WINAPI ServiceCtrlHandler(DWORD Opcode)
114 {
116  ostringstream os;
117 
118  switch(Opcode)
119  {
120  case SERVICE_CONTROL_PAUSE:
121  m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
122  SetServiceStatus(m_ServiceStatusHandle,&m_ServiceStatus);
123  break;
124 
125  case SERVICE_CONTROL_CONTINUE:
126  m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
127  notify_server();
128  SetServiceStatus(m_ServiceStatusHandle,&m_ServiceStatus);
129  break;
130 
131  case SERVICE_CONTROL_STOP:
132  os << fwork->get_cur_time() << " Thr.ID: SERVICE STOP signal received. Shutting down.. ";
133  fwork->log(LOG_LOW,LOG_LOW,(char *) os.str().c_str());
134  m_ServiceStatus.dwWin32ExitCode = 0;
135  m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
136  m_ServiceStatus.dwCheckPoint = 0;
137  m_ServiceStatus.dwWaitHint = 0;
138 
139  SetServiceStatus(m_ServiceStatusHandle,&m_ServiceStatus);
140  bRunning=false;
141  break;
142 
143  case SERVICE_CONTROL_INTERROGATE:
144  GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0);
145 
146  break;
147  }
148  return;
149 }
150 /*************************************************************************************/
151 
152 BOOL notify_server()
153 {
154  SOCKET sock;
155  int status;
156  ostringstream os;
157  struct sockaddr_in sockaddr;
159 
160  sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
161  sockaddr.sin_family = AF_INET; /* Internet/IP */
162  sockaddr.sin_addr.s_addr = inet_addr((const char *)"127.0.0.1");
163  sockaddr.sin_port = (u_short)(u_short)htons(fwork->get_command_port());
164  if ( (status = connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) < 0)
165  {
166  os << fwork->get_cur_time() << " Thr.ID: SERVICE 07 cannot connect to COMMAND_PORT: " << fwork->get_command_port() << " " << status;
167  fwork->log(LOG_LOW,LOG_LOW,(char *) os.str().c_str());
168  return(0);
169  }
170  shutdown(sock,2);
171 #ifdef WINDOWS
172  closesocket(sock);
173 #else
174  close(sock);
175 #endif
176  return(0);
177 }
178 /*************************************************************************************/
179 
180 BOOL InstallService(char *service_name,char *conf_file)
181 {
182  char strDir[1024],strExe[1024];
183  SC_HANDLE schSCManager,schService;
184 
185  memset(strExe,0,1024);
186  GetCurrentDirectory(1024,strDir);
187  strcat(strExe,strDir);
188  strcat(strExe,"\\GENERIC_SERVER.exe ");
189  strcat(strExe,strDir);
190  strcat(strExe,"\\");
191  strcat(strExe,conf_file);
192  schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
193 
194  if (schSCManager == NULL)
195  return false;
196  LPCTSTR lpszBinaryPathName=strExe;
197 
198  schService = CreateService(schSCManager,service_name,
199  service_name, // GENERIC_SERVER name to display
200  SERVICE_ALL_ACCESS, // desired access
201  SERVICE_WIN32_OWN_PROCESS, // GENERIC_SERVER type
202  SERVICE_AUTO_START, // start type
203  SERVICE_ERROR_NORMAL, // error control type
204  lpszBinaryPathName, // GENERIC_SERVER's binary
205  NULL, // no load ordering group
206  NULL, // no tag identifier
207  NULL, // no dependencies
208  NULL, // LocalSystem account
209  NULL); // no password
210  if (schService == NULL)
211  return false;
212 
213  CloseServiceHandle(schService);
214  return true;
215 }
216 /*************************************************************************************/
217 
218 BOOL DeleteService(char *service_name)
219 {
220  SC_HANDLE schSCManager;
221  SC_HANDLE schService;
222  schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
223 
224  if (schSCManager == NULL)
225  return false;
226  schService=OpenService(schSCManager,service_name,SERVICE_ALL_ACCESS);
227  if (schService == NULL)
228  return false;
229  if(DeleteService(schService)==0)
230  return false;
231  if(CloseServiceHandle(schService)==0)
232  return false;
233 return true;
234 }
235 /*************************************************************************************/
236 #endif
int log(unsigned int, unsigned int, char *)
enables logging to framework managed log file.
Singleton class to manage framework state and provide utility functions. This class stores master Vec...
This is a singleton class and provides framework functionality.
This is the base class for all plugins. All plug-ins should derive from this class. This class has a bunch of virtual functions that all plug-in could/should implement. In addition to virtual functions, this class also provides a lot of utility functions for all plug-ins.
static generic_server * instance(void)
Instantiate tis singleton class only once and return pointer to instantiated object later on...