FFL  1.0
Finfly Foundation Library
service.h
См. документацию.
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                                 
 Указатель Классы Пространства имен Файлы Функции Переменные Определения типов Перечисления Элементы перечислений Макросы