Hauptseite | Klassenhierarchie | Alphabetische Liste | Auflistung der Klassen | Auflistung der Dateien | Klassen-Elemente

# NTService.h

    00001
    00002 // Copyright (C) 1997 by Joerg Koenig
    00003 // All rights reserved
    00004 //
    00005 // Distribute freely, except: don't remove my name from the source or
    00006 // documentation (don't take credit for my work), mark your changes (don't
    00007 // get me blamed for your possible bugs), don't alter or remove this
    00008 // notice.
    00009 // No warrantee of any kind, express or implied, is included with this
    00010 // software; use at your own risk, responsibility for damages (if any) to
    00011 // anyone resulting from the use of this software rests entirely with the
    00012 // user.
    00013 //
    00014 // Send bug reports, bug fixes, enhancements, requests, flames, etc., and
    00015 // I'll try to keep a version up to date.  I can be reached as follows:
    00016 //    J.Koenig@adg.de                 (company site)
    00017 //    Joerg.Koenig@rhein-neckar.de    (private site)
    00019 //
    00020 // MODIFIED BY TODD C. WILSON FOR THE ROAD RUNNER NT LOGIN SERVICE.
    00021 // HOWEVER, THESE MODIFICATIONS ARE BROADER IN SCOPE AND USAGE AND CAN BE USED
    00022 // IN OTHER PROJECTS WITH NO CHANGES.
    00023 // MODIFIED LINES FLAGGED/BRACKETED BY "//!! TCW MOD"
    00024 //
    00026
    00027
    00028 // last revised: $Date: 2001/07/12 07:43:18 $, $Revision: 1.2 $
    00029
    00030
    00031 #ifndef NTService_h
    00032 #define NTService_h
    00033
    00034
    00035 class CNTService {
    00036    static BOOL          m_bInstance;         // only one CNTService object per application
    00037
    00038    protected:  // data members
    00039       LPCTSTR              m_lpServiceName;
    00040       LPCTSTR              m_lpDisplayName;
    00041       DWORD             m_dwCheckPoint;
    00042       DWORD             m_dwErr;
    00043       BOOL              m_bDebug;         // TRUE if -d was passed to the program
    00044       SERVICE_STATUS       m_ssStatus;       // current status of the service
    00045       SERVICE_STATUS_HANDLE   m_sshStatusHandle;
    00046       DWORD             m_dwControlsAccepted;   // bit-field of what control requests the
    00047                                           // service will accept
    00048                                           // (dflt: SERVICE_ACCEPT_STOP)
    00049       PSID              m_pUserSID;       // the current user's security identifier
    00050       BOOL              m_bWinNT;         // TRUE, if this is running on WinNT FALSE on Win95
    00051       BOOL              m_fConsoleReady;
    00052
    00053       // parameters to the "CreateService()" function:
    00054       DWORD       m_dwDesiredAccess;      // default: SERVICE_ALL_ACCESS
    00055       DWORD       m_dwServiceType;     // default: SERVICE_WIN32_OWN_PROCESS
    00056       DWORD       m_dwStartType;       // default: SERVICE_AUTO_START
    00057       DWORD       m_dwErrorControl;    // default: SERVICE_ERROR_NORMAL
    00058       LPCTSTR        m_pszLoadOrderGroup; // default: NULL
    00059       DWORD       m_dwTagID;           // retrieves the tag identifier
    00060       LPCTSTR        m_pszDependencies;      // default: NULL
    00061       LPCTSTR        m_pszStartName;         // default: NULL
    00062       LPCTSTR        m_pszPassword;       // default: NULL
    00063
    00064
    00065    public:     // construction/destruction
    00066          // If <DisplayName> is not set, then it defaults to <ServiceName>.
    00067       CNTService(LPCTSTR ServiceName, LPCTSTR DisplayName = 0);
    00068       ~CNTService();
    00069
    00070    private: // forbidden functions
    00071       CNTService( const CNTService & );
    00072       CNTService & operator=( const CNTService & );
    00073
    00074    public:     // overridables
    00075          // You have to override the following two functions.
    00076          // "Run()" will be called to start the real
    00077          // service's activity. You must call
    00078          //    ReportStatus(SERVICE_RUNNING);
    00079          // before you enter your main-loop !
    00080          // "Stop()" will be called to stop the work of
    00081          // the service. You should break out of the mainloop
    00082          // and return control to the CNTService class.
    00083          //
    00084          // In most cases these functions look like these:
    00085          //
    00086          //    void CMyService :: Run(DWORD argc, LPTSTR * argv) {
    00087          //       ReportStatus(SERVICE_START_PENDING);
    00088          //       // do some parameter processing ...
    00089          //       ReportStatus(SERVICE_START_PENDING);
    00090          //       // do first part of initialisation ...
    00091          //       ReportStatus(SERVICE_START_PENDING);
    00092          //       // do next part of initialisation
    00093          //       // ...
    00094          //       m_hStop = CreateEvent(0, TRUE, FALSE, 0);
    00095          //       ReportStatus(SERVICE_RUNNING);
    00096          //       while( WaitForSingleObject(m_hStop, 10) != WAIT_OBJECT_0 ) {
    00097          //          // do something
    00098          //       }
    00099          //       if( m_hStop )
    00100          //          CloseHandle(m_hStop);
    00101          //    }
    00102          //
    00103          //    void CMyService :: Stop() {
    00104          //       if( m_hStop )
    00105          //          SetEvent(m_hStop);
    00106          //       ReportStatus(SERVICE_STOP_PENDING);
    00107          //    }
    00108       virtual void   Run(DWORD argc, LPTSTR * argv) = 0;
    00109       virtual void   Stop() = 0;
    00110
    00111          // Pause() and Continue() do nothing by default.
    00112          // You can override them to handle a control request.
    00113          // Pause() should report the status SERVICE_PAUSED
    00114          // and Continue() should report the status SERVICE_RUNNING
    00115          // (see ReportStatus() below).
    00116          // Note that normally these functions will never be called. If
    00117          // you want a service, that accepts PAUSE and CONTINUE control
    00118          // requests, you have to to add SERVICE_ACCEPT_PAUSE_CONTINUE
    00119          // to the m_dwControlsAccepted data member.
    00120       virtual void   Pause();
    00121       virtual void   Continue();
    00122
    00123          // Shutdown() will be called, if the service manager
    00124          // requests for the SERVICE_CONTROL_SHUTDOWN control.
    00125          // This control type occurs, when the system shuts down.
    00126          // If you want to process this notification, you have to
    00127          // add SERVICE_ACCEPT_SHUTDOWN to the m_dwControlsAccepted
    00128          // data member (and to override this function). The default
    00129          // implementation of Shutdown() does nothing.
    00130       virtual void   Shutdown();
    00131
    00132          // Call "RegisterService()" after you have constructed
    00133          // a CNTService object:
    00134          // A typical "main()" function of a service looks like this:
    00135          //
    00136          //    int main( int argc, char ** argv ) {
    00137          //       CMyService serv;
    00138          //       exit(serv.RegisterService(argc, argv));
    00139          //    }
    00140          //
    00141          // Where "CMyService" is a CNTService derived class.
    00142          // RegisterService() checks the parameterlist. The
    00143          // following parameters will be detected:
    00144          //    -i       install the service (calls
    00145          //             "InstallService()" - see below)
    00146          //
    00147          //       -l <account>
    00148          //             <account> is the name of a user,
    00149          //             under which the service shall run.
    00150          //             This option is useful with -i only.
    00151          //             <account> needs to have the advanced
    00152          //             user-right "Log on as a service"
    00153          //             (see User-Manager)
    00154          //             <account> should have the following
    00155          //             format: "<Domain><user>"
    00156          //             "EuroS2Team\jko" for instance.
    00157          //             The domain "." is predefined as the
    00158          //             local machine. So one might use
    00159          //             ".\jko" too.
    00160          //
    00161          //       -p <password>
    00162          //             The password of the user, under which
    00163          //             the service shall run. Only useful
    00164          //             with -i and -l together.
    00165          //
    00166          //    -u       uninstall the service (calls
    00167          //             "RemoveService()" - see below)
    00168          //
    00169          //    -d       debug the service (run as console
    00170          //             process; calls "DebugService()"
    00171          //             see below)
    00172          //
    00173          //    -e       end the service (if it is running)
    00174          //
    00175          //    -s       start the service (if it is not running)
    00176          //             (Note that *you* normally cannot start
    00177          //             an NT-service from the command-line.
    00178          //             The SCM can.)
    00179          //
    00180          // Do not use -l and -p, if your service is of type
    00181          // SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
    00182          // Furthermore you canot use -i and -s together. Instead
    00183          // you have to start the command twice, first you install
    00184          // the service, then you start it.
    00185          // If none of the flags -i, -u, -e, -s and -d is set, then the
    00186          // program starts as an NT service (only the SCM can start it
    00187          // this way!).
    00188          // NOTE: If UNICODE is #define'd, then <argc> and <argv>
    00189          //    will be ignored and the original commandline
    00190          //    of the program will be used to parse the
    00191          //    arguments !
    00192       virtual BOOL   RegisterService(int argc, char ** argv);
    00193
    00194          // "StartDispatcher()" registers one service-procedure
    00195          // to the service control dispatcher (using the predefined
    00196          // "ServiceMain()" function below).
    00197          // Override this funtion, if you want to develop a
    00198          // multithreaded NT-Service.
    00199       virtual BOOL   StartDispatcher();
    00200
    00201          // Override "InstallService()" to manipulate the
    00202          // installation behavior.
    00203          // This function will only be called, if the
    00204          // "-i" flag was passed to "RegisterService()"
    00205          // (see above)
    00206          // After "InstallService()" has completed, you
    00207          // should be able to see the service in the
    00208          // "services" control-panel-applet.
    00209       virtual BOOL   InstallService();
    00210
    00211          // RemoveService() removes a service from the system's
    00212          // service-table.
    00213          // It first tries to stop the service.
    00214          // This function will be called only if the -u
    00215          // flag was passed to the program. (see "RegisterService()"
    00216          // above)
    00217          // After removal of the service, it should no longer
    00218          // appear in the "services" control-panel-applet.
    00219       virtual BOOL   RemoveService();
    00220
    00221
    00222          // EndService() stops a running service (if the service
    00223          // is running as a service! Does not end a service
    00224          // running as a console program (see DebugService()
    00225          // below))
    00226       virtual BOOL   EndService();
    00227
    00228          // Start the service. Does the same as if the
    00229          // SCM launches the program. Note that this method
    00230          // will create a new instance of the program.
    00231       virtual BOOL   StartupService();
    00232
    00233          // Run a service as a console application. This makes it
    00234          // easier to debug the service.
    00235          // This function will be called only if the -d flag
    00236          // was passed to the program(see "RegisterService()" above).
    00237          // It transparently calls "Run()". You can simulate a
    00238          // stop-request by pressing either Ctrl-C or Ctrl-Break (that
    00239          // will call the "Stop()" method).
    00240       virtual BOOL   DebugService(int argc, char **argv,BOOL faceless=FALSE);
    00241
    00242    protected:  // implementation
    00243          // Override "RegisterApplicationLog()", if you want to register
    00244          // a different message file and/or differend supported types
    00245          // than the default.
    00246          // The proposed message file is the application itself.
    00247          // The proposed types are:
    00248          // EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE
    00249          // This method will be called from inside "InstallService()" (see above)
    00250          // Thus if you support errors only (for instance):
    00251          //    void CMyService :: RegisterApplicationLog(LPCTSTR filename, DWORD ) {
    00252          //       CNTService::RegisterApplicationLog(filename, EVENTLOG_ERROR_TYPE);
    00253          //    }
    00254          // This method will never be called on Win95.
    00255       virtual void   RegisterApplicationLog(
    00256                      LPCTSTR lpszProposedMessageFile,
    00257                      DWORD dwProposedTypes
    00258                   );
    00259
    00260          // "DeregisterApplicationLog()" is called from inside "RemoveService()"
    00261          // (see above) to clear the registry-entries made by
    00262          // "RegisterApplicationLog()"
    00263       virtual void   DeregisterApplicationLog();
    00264
    00265    public:  // helpers
    00266          // Retrieve a human-readable error message. The message
    00267          // will be stored in <Buf> which is of size <Size>.
    00268          // Returns a pointer to <Buf>.
    00269       LPTSTR         GetLastErrorText(LPTSTR Buf, DWORD Size);
    00270
    00271          // report status to the service-control-manager.
    00272          // <CurState> can be one of:
    00273          //    SERVICE_START_PENDING      -  the service is starting
    00274          //    SERVICE_RUNNING            -  the service is running
    00275          //    SERVICE_STOP_PENDING    -  the service is stopping
    00276          //    SERVICE_STOPPED            -  the service is not running
    00277          //    SERVICE_PAUSE_PENDING      -  the service pause is pending
    00278          //    SERVICE_PAUSE           -  the service is paused
    00279          //    SERVICE_CONTINUE_PENDING   -  the service is about to continue
    00280       BOOL        ReportStatus(
    00281                      DWORD CurState,            // service's state
    00282                      DWORD WaitHint = 3000,     // expected time of operation in milliseconds
    00283                      DWORD ErrExit = 0
    00284                   );
    00285
    00286          // AddToMessageLog() writes a message to the application event-log.
    00287          // (use EventViewer from the menu "Administrative Tools" to watch the log).
    00288          // The <EventType> parameter can be set to one of the following values:
    00289          //    EVENTLOG_ERROR_TYPE        Error event
    00290          //    EVENTLOG_WARNING_TYPE      Warning event
    00291          //    EVENTLOG_INFORMATION_TYPE  Information event
    00292          //    EVENTLOG_AUDIT_SUCCESS     Success Audit event
    00293          //    EVENTLOG_AUDIT_FAILURE     Failure Audit event
    00294          // See "ReportEvent()" in the help-topics for further information.
    00295       virtual void   AddToMessageLog(
    00296                      LPTSTR   Message,
    00297                      WORD  EventType = EVENTLOG_ERROR_TYPE,
    00298                      DWORD dwEventID = DWORD(-1)
    00299                   );
    00300
    00301    public:     // default handlers
    00302          // The following functions will be used by default.
    00303          // You can provide other handlers. If so, you have to
    00304          // overload several of the "virtual"s above.
    00305       static void WINAPI   ServiceCtrl(DWORD CtrlCode);
    00306       static void WINAPI   ServiceMain(DWORD argc, LPTSTR * argv);
    00307       static BOOL WINAPI   ControlHandler(DWORD CtrlType);
    00308
    00310    public:
    00311       BOOL OsIsWin95() const { return ! m_bWinNT; }
    00312       void SetupConsole();
    00313
    00314 };
    00315
    00316
    00317 // Retrieve the one and only CNTService object:
    00318 CNTService * AfxGetService();
    00319
    00320
    00321 #endif   // NTService_h