FFL
1.0
Finfly Foundation Library
|
00001 /* $Id: service.h 2920 2013-01-14 19:37:00Z roma $ */ 00003 #ifndef _FFL_CSSC_SERVICE_H_ 00004 #define _FFL_CSSC_SERVICE_H_ 00005 00006 #include <winsock2.h> 00007 #include <WS2tcpip.h> 00008 #include <windows.h> 00009 #include <string> 00010 00011 namespace ffl 00012 { 00013 00014 namespace cssc 00015 { 00016 00114 class service 00115 { 00116 public: 00117 00119 enum type 00120 { 00121 FILE_SYSTEM_DRIVER = SERVICE_FILE_SYSTEM_DRIVER, 00122 KERNEL_DRIVER = SERVICE_KERNEL_DRIVER, 00123 WIN32_OWN_PROCESS = SERVICE_WIN32_OWN_PROCESS, 00124 WIN32_SHARE_PROCESS = SERVICE_WIN32_SHARE_PROCESS, 00125 }; 00126 00131 static const char* spell(type _type) throw(); 00132 00134 enum status 00135 { 00136 CONTINUE_PENDING = SERVICE_CONTINUE_PENDING, 00137 PAUSE_PENDING = SERVICE_PAUSE_PENDING, 00138 PAUSED = SERVICE_PAUSED, 00139 RUNNING = SERVICE_RUNNING, 00140 START_PENDING = SERVICE_START_PENDING, 00141 STOP_PENDING = SERVICE_STOP_PENDING, 00142 STOPPED = SERVICE_STOPPED, 00143 }; 00144 00145 static const char* spell(status _status) throw(); 00146 00148 enum accept 00149 { 00150 NOTHING = 0, 00151 00157 NETBINDCHANGE = SERVICE_ACCEPT_NETBINDCHANGE, 00163 PARAMCHANGE = SERVICE_ACCEPT_PARAMCHANGE, 00165 PAUSE_CONTINUE = SERVICE_ACCEPT_PAUSE_CONTINUE, 00166 #if WINVER >= 0x0502 00167 00174 PRESHUTDOWN = SERVICE_ACCEPT_PRESHUTDOWN, 00175 #endif 00176 00181 SHUTDOWN = SERVICE_ACCEPT_SHUTDOWN, 00182 00188 STOP = SERVICE_ACCEPT_STOP, 00194 HARDWAREPROFILECHANGE = SERVICE_ACCEPT_HARDWAREPROFILECHANGE, 00200 POWEREVENT = SERVICE_ACCEPT_POWEREVENT, 00206 #if WINVER >= 0x601 00207 SESSIONCHANGE = SERVICE_ACCEPT_SESSIONCHANGE, 00216 TIMECHANGE = SERVICE_ACCEPT_TIMECHANGE, 00217 #endif 00218 #if WINVER >= 0x0601 00219 00226 TRIGGEREVENT = SERVICE_ACCEPT_TRIGGEREVENT, 00227 #endif 00228 00229 #if WINVER >= 0x0602 00230 00235 USERMODEREBOOT = SERVICE_ACCEPT_USERMODEREBOOT, 00236 #endif 00237 00238 }; 00239 00242 class context 00243 { 00244 public: 00245 00246 context(service::type _type) throw(); 00247 00248 virtual void initialize(service* _s, const char* _name) throw(...) = 0; 00249 00250 virtual void terminate() throw(){} 00251 00256 void pending(service::status _s, long _wait) throw(); 00257 00262 void state(service::status _s, service::accept _a = NOTHING) throw(); 00263 00270 void error() throw(); 00271 00281 void error(int _code) throw(); 00282 00285 void checkpoint() throw(); 00286 00287 protected: 00288 00289 SERVICE_STATUS Status; 00290 00291 virtual void send() throw() = 0; 00292 00293 }; 00294 00296 class scm:public context 00297 { 00298 public: 00299 00300 scm(service::type _type) throw():context(_type){} 00301 00302 void initialize(service* _s, const char* _name) throw(...); 00303 00304 private: 00305 00306 SERVICE_STATUS_HANDLE Handle; 00307 00323 static DWORD WINAPI handler(DWORD _control, DWORD _event, LPVOID _data, LPVOID _context) throw(); 00324 00325 void send() throw(); 00326 00327 }; 00328 00333 class console:public context 00334 { 00335 public: 00336 00337 console(service::type _type) throw():context(_type){} 00338 00346 void initialize(service* _s, const char* _n) throw(...); 00347 00349 void terminate() throw(); 00350 00351 private: 00352 00354 static BOOL WINAPI handler(DWORD) throw(); 00355 00357 void send() throw(); 00358 00363 std::string Name; 00364 00371 static service* Service; 00372 00373 }; 00374 00375 service(context& _c) throw():Context(_c){} 00376 00384 virtual void stop() throw(){} 00385 00386 template<class S, class C> class main 00387 { 00388 public: 00389 00390 main(service::type _type) throw():Context(_type), Service(Context){} 00391 00392 void run(int _argc, const char* _argv[]) throw() 00393 { 00394 try 00395 { 00396 Context.initialize(&Service, _argc > 0 ? _argv[0]:""); 00397 } 00398 catch(...) 00399 { 00400 return; 00401 } 00402 Service.run(_argc, _argv); 00403 Context.terminate(); 00404 } 00405 00406 private: 00407 00408 S Service; 00409 00410 C Context; 00411 00412 }; 00413 00414 protected: 00415 00416 context& Context; 00417 00418 }; 00419 00420 } 00421 00422 } 00423 00428 #define FFL_CSSC_SERVICE(T) \ 00429 VOID WINAPI service_entry(DWORD _argc, LPSTR* _argv) throw() \ 00430 { \ 00431 service::main<T, service::scm>(service::WIN32_OWN_PROCESS).run(_argc, (const char**)_argv);\ 00432 } \ 00433 void console_entry(int _argc, const char** _argv) throw() \ 00434 { \ 00435 service::main<T, service::console>(service::WIN32_OWN_PROCESS).run(_argc, _argv); \ 00436 } \ 00437 int main(int _argc, const char** _argv) throw() \ 00438 { \ 00439 SERVICE_TABLE_ENTRY s[2]; \ 00440 s[0].lpServiceName = ""; \ 00441 s[0].lpServiceProc = service_entry; \ 00442 s[1].lpServiceName = 0; \ 00443 s[1].lpServiceProc = 0; \ 00444 if(!StartServiceCtrlDispatcher(s)) \ 00445 { \ 00446 DWORD e = GetLastError(); \ 00447 if(e == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) \ 00448 console_entry(_argc, _argv); \ 00449 } \ 00450 return 0; \ 00451 } 00452 00453 #endif 00454