NTService.h
上传用户:chenchao
上传日期:2007-01-09
资源大小:22k
文件大小:13k
源码类别:

Telnet服务器

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 1997 by Joerg Koenig
  3. // All rights reserved
  4. //
  5. // Distribute freely, except: don't remove my name from the source or
  6. // documentation (don't take credit for my work), mark your changes (don't
  7. // get me blamed for your possible bugs), don't alter or remove this
  8. // notice.
  9. // No warrantee of any kind, express or implied, is included with this
  10. // software; use at your own risk, responsibility for damages (if any) to
  11. // anyone resulting from the use of this software rests entirely with the
  12. // user.
  13. //
  14. // Send bug reports, bug fixes, enhancements, requests, flames, etc., and
  15. // I'll try to keep a version up to date.  I can be reached as follows:
  16. //    J.Koenig@adg.de                 (company site)
  17. //    Joerg.Koenig@rhein-neckar.de    (private site)
  18. /////////////////////////////////////////////////////////////////////////////
  19. //
  20. // MODIFIED BY TODD C. WILSON FOR THE ROAD RUNNER NT LOGIN SERVICE.
  21. // HOWEVER, THESE MODIFICATIONS ARE BROADER IN SCOPE AND USAGE AND CAN BE USED
  22. // IN OTHER PROJECTS WITH NO CHANGES.
  23. // MODIFIED LINES FLAGGED/BRACKETED BY "//!! TCW MOD"
  24. //
  25. /////////////////////////////////////////////////////////////////////////////
  26. // last revised: $Date: 5.05.98 21:22 $, $Revision: 2 $
  27. #ifndef NTService_h
  28. #define NTService_h
  29. class CNTService {
  30. static BOOL m_bInstance; // only one CNTService object per application
  31. protected: // data members
  32. LPCTSTR m_lpServiceName;
  33. LPCTSTR m_lpDisplayName;
  34. DWORD m_dwCheckPoint;
  35. DWORD m_dwErr;
  36. BOOL m_bDebug; // TRUE if -d was passed to the program
  37. SERVICE_STATUS m_ssStatus; // current status of the service
  38. SERVICE_STATUS_HANDLE m_sshStatusHandle;
  39. DWORD m_dwControlsAccepted; // bit-field of what control requests the
  40. // service will accept
  41. // (dflt: SERVICE_ACCEPT_STOP)
  42. PSID m_pUserSID; // the current user's security identifier
  43. BOOL m_bWinNT; // TRUE, if this is running on WinNT FALSE on Win95
  44. BOOL m_fConsoleReady;
  45. // parameters to the "CreateService()" function:
  46. DWORD m_dwDesiredAccess; // default: SERVICE_ALL_ACCESS
  47. DWORD m_dwServiceType; // default: SERVICE_WIN32_OWN_PROCESS
  48. DWORD m_dwStartType; // default: SERVICE_AUTO_START
  49. DWORD m_dwErrorControl; // default: SERVICE_ERROR_NORMAL
  50. LPCTSTR m_pszLoadOrderGroup; // default: NULL
  51. DWORD m_dwTagID; // retrieves the tag identifier
  52. LPCTSTR m_pszDependencies; // default: NULL
  53. LPCTSTR m_pszStartName; // default: NULL
  54. LPCTSTR m_pszPassword; // default: NULL
  55. public: // construction/destruction
  56. // If <DisplayName> is not set, then it defaults to <ServiceName>.
  57. CNTService(LPCTSTR ServiceName, LPCTSTR DisplayName = 0);
  58. ~CNTService();
  59. private: // forbidden functions
  60. CNTService( const CNTService & );
  61. CNTService & operator=( const CNTService & );
  62. public: // overridables
  63. // You have to override the following two functions.
  64. // "Run()" will be called to start the real
  65. // service's activity. You must call
  66. // ReportStatus(SERVICE_RUNNING);
  67. // before you enter your main-loop !
  68. // "Stop()" will be called to stop the work of
  69. // the service. You should break out of the mainloop
  70. // and return control to the CNTService class.
  71. //
  72. // In most cases these functions look like these:
  73. //
  74. // void CMyService :: Run(DWORD argc, LPTSTR * argv) {
  75. // ReportStatus(SERVICE_START_PENDING);
  76. // // do some parameter processing ...
  77. // ReportStatus(SERVICE_START_PENDING);
  78. // // do first part of initialisation ...
  79. // ReportStatus(SERVICE_START_PENDING);
  80. // // do next part of initialisation
  81. // // ...
  82. // m_hStop = CreateEvent(0, TRUE, FALSE, 0);
  83. // ReportStatus(SERVICE_RUNNING);
  84. // while( WaitForSingleObject(m_hStop, 10) != WAIT_OBJECT_0 ) {
  85. // // do something
  86. // }
  87. // if( m_hStop )
  88. // CloseHandle(m_hStop);
  89. // }
  90. //
  91. // void CMyService :: Stop() {
  92. // if( m_hStop )
  93. // SetEvent(m_hStop);
  94. // ReportStatus(SERVICE_STOP_PENDING);
  95. // }
  96. virtual void Run(DWORD argc, LPTSTR * argv) = 0;
  97. virtual void Stop() = 0;
  98. // Pause() and Continue() do nothing by default.
  99. // You can override them to handle a control request.
  100. // Pause() should report the status SERVICE_PAUSED
  101. // and Continue() should report the status SERVICE_RUNNING
  102. // (see ReportStatus() below).
  103. // Note that normally these functions will never be called. If
  104. // you want a service, that accepts PAUSE and CONTINUE control
  105. // requests, you have to to add SERVICE_ACCEPT_PAUSE_CONTINUE
  106. // to the m_dwControlsAccepted data member.
  107. virtual void Pause();
  108. virtual void Continue();
  109. // Shutdown() will be called, if the service manager
  110. // requests for the SERVICE_CONTROL_SHUTDOWN control.
  111. // This control type occurs, when the system shuts down.
  112. // If you want to process this notification, you have to
  113. // add SERVICE_ACCEPT_SHUTDOWN to the m_dwControlsAccepted
  114. // data member (and to override this function). The default
  115. // implementation of Shutdown() does nothing.
  116. virtual void Shutdown();
  117. // Call "RegisterService()" after you have constructed
  118. // a CNTService object:
  119. // A typical "main()" function of a service looks like this:
  120. //
  121. // int main( int argc, char ** argv ) {
  122. // CMyService serv;
  123. // exit(serv.RegisterService(argc, argv));
  124. // }
  125. //
  126. // Where "CMyService" is a CNTService derived class.
  127. // RegisterService() checks the parameterlist. The
  128. // following parameters will be detected:
  129. // -i install the service (calls
  130. // "InstallService()" - see below)
  131. //
  132. // -l <account>
  133. // <account> is the name of a user,
  134. // under which the service shall run.
  135. // This option is useful with -i only.
  136. // <account> needs to have the advanced
  137. // user-right "Log on as a service"
  138. // (see User-Manager)
  139. // <account> should have the following
  140. // format: "<Domain><user>"
  141. // "EuroS2Teamjko" for instance.
  142. // The domain "." is predefined as the
  143. // local machine. So one might use
  144. // ".jko" too.
  145. //
  146. // -p <password>
  147. // The password of the user, under which
  148. // the service shall run. Only useful
  149. // with -i and -l together.
  150. //
  151. // -u uninstall the service (calls
  152. // "RemoveService()" - see below)
  153. //
  154. // -d debug the service (run as console
  155. // process; calls "DebugService()"
  156. // see below)
  157. //
  158. // -e end the service (if it is running)
  159. //
  160. // -s start the service (if it is not running)
  161. // (Note that *you* normally cannot start
  162. // an NT-service from the command-line.
  163. // The SCM can.)
  164. //
  165. // Do not use -l and -p, if your service is of type
  166. // SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
  167. // Furthermore you canot use -i and -s together. Instead
  168. // you have to start the command twice, first you install
  169. // the service, then you start it.
  170. // If none of the flags -i, -u, -e, -s and -d is set, then the
  171. // program starts as an NT service (only the SCM can start it
  172. // this way!).
  173. // NOTE: If UNICODE is #define'd, then <argc> and <argv>
  174. // will be ignored and the original commandline
  175. // of the program will be used to parse the
  176. // arguments !
  177. virtual BOOL RegisterService(int argc, char ** argv);
  178. // "StartDispatcher()" registers one service-procedure
  179. // to the service control dispatcher (using the predefined
  180. // "ServiceMain()" function below).
  181. // Override this funtion, if you want to develop a
  182. // multithreaded NT-Service.
  183. virtual BOOL StartDispatcher();
  184. // Override "InstallService()" to manipulate the
  185. // installation behavior.
  186. // This function will only be called, if the
  187. // "-i" flag was passed to "RegisterService()"
  188. // (see above)
  189. // After "InstallService()" has completed, you
  190. // should be able to see the service in the
  191. // "services" control-panel-applet.
  192. virtual BOOL InstallService();
  193. // RemoveService() removes a service from the system's
  194. // service-table.
  195. // It first tries to stop the service.
  196. // This function will be called only if the -u
  197. // flag was passed to the program. (see "RegisterService()"
  198. // above)
  199. // After removal of the service, it should no longer
  200. // appear in the "services" control-panel-applet.
  201. virtual BOOL RemoveService();
  202. // EndService() stops a running service (if the service
  203. // is running as a service! Does not end a service
  204. // running as a console program (see DebugService()
  205. // below))
  206. virtual BOOL EndService();
  207. // Start the service. Does the same as if the
  208. // SCM launches the program. Note that this method
  209. // will create a new instance of the program.
  210. virtual BOOL StartupService();
  211. // Run a service as a console application. This makes it
  212. // easier to debug the service.
  213. // This function will be called only if the -d flag
  214. // was passed to the program(see "RegisterService()" above).
  215. // It transparently calls "Run()". You can simulate a
  216. // stop-request by pressing either Ctrl-C or Ctrl-Break (that
  217. // will call the "Stop()" method).
  218. virtual BOOL DebugService(int argc, char **argv,BOOL faceless=FALSE); //!! TCW MOD - added FACELESS parm to allow Win95 usage.
  219. protected: // implementation
  220. // Override "RegisterApplicationLog()", if you want to register
  221. // a different message file and/or differend supported types
  222. // than the default.
  223. // The proposed message file is the application itself.
  224. // The proposed types are:
  225. // EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE
  226. // This method will be called from inside "InstallService()" (see above)
  227. // Thus if you support errors only (for instance):
  228. // void CMyService :: RegisterApplicationLog(LPCTSTR filename, DWORD ) {
  229. // CNTService::RegisterApplicationLog(filename, EVENTLOG_ERROR_TYPE);
  230. // }
  231. // This method will never be called on Win95.
  232. virtual void RegisterApplicationLog(
  233. LPCTSTR lpszProposedMessageFile,
  234. DWORD dwProposedTypes
  235. );
  236. // "DeregisterApplicationLog()" is called from inside "RemoveService()"
  237. // (see above) to clear the registry-entries made by
  238. // "RegisterApplicationLog()"
  239. virtual void DeregisterApplicationLog();
  240. public: // helpers
  241. // Retrieve a human-readable error message. The message
  242. // will be stored in <Buf> which is of size <Size>.
  243. // Returns a pointer to <Buf>.
  244. LPTSTR GetLastErrorText(LPTSTR Buf, DWORD Size);
  245. // report status to the service-control-manager.
  246. // <CurState> can be one of:
  247. // SERVICE_START_PENDING - the service is starting
  248. // SERVICE_RUNNING - the service is running
  249. // SERVICE_STOP_PENDING - the service is stopping
  250. // SERVICE_STOPPED - the service is not running
  251. // SERVICE_PAUSE_PENDING - the service pause is pending
  252. // SERVICE_PAUSE - the service is paused
  253. // SERVICE_CONTINUE_PENDING - the service is about to continue
  254. BOOL ReportStatus(
  255. DWORD CurState, // service's state
  256. DWORD WaitHint = 3000, // expected time of operation in milliseconds
  257. DWORD ErrExit = 0 //!! TCW MOD - set to nonzero to flag *FATAL* error
  258. );
  259. // AddToMessageLog() writes a message to the application event-log.
  260. // (use EventViewer from the menu "Administrative Tools" to watch the log).
  261. // The <EventType> parameter can be set to one of the following values:
  262. // EVENTLOG_ERROR_TYPE Error event
  263. // EVENTLOG_WARNING_TYPE Warning event
  264. // EVENTLOG_INFORMATION_TYPE Information event
  265. // EVENTLOG_AUDIT_SUCCESS Success Audit event
  266. // EVENTLOG_AUDIT_FAILURE Failure Audit event
  267. // See "ReportEvent()" in the help-topics for further information.
  268. virtual void AddToMessageLog(
  269. LPTSTR Message,
  270. WORD EventType = EVENTLOG_ERROR_TYPE,
  271. DWORD dwEventID = DWORD(-1)
  272. );
  273. public: // default handlers
  274. // The following functions will be used by default.
  275. // You can provide other handlers. If so, you have to
  276. // overload several of the "virtual"s above.
  277. static void WINAPI ServiceCtrl(DWORD CtrlCode);
  278. static void WINAPI ServiceMain(DWORD argc, LPTSTR * argv);
  279. static BOOL WINAPI ControlHandler(DWORD CtrlType);
  280. //!! TCW MOD - added console support for Faceless Apps. Needed sometimes when something goes wrong.
  281. public:
  282. BOOL OsIsWin95() const { return ! m_bWinNT; }
  283. void SetupConsole();
  284. };
  285. // Retrieve the one and only CNTService object:
  286. CNTService * AfxGetService();
  287. #endif // NTService_h