/*=========================================================================== 
    (c) Copyright 1999, Emmanuel KARTMANN, all rights reserved
  =========================================================================== 
    File           : ServiceManager.h
    $Header: $
    Author         : Emmanuel KARTMANN
    Creation       : Wednesday 12/1/99 4:57:15 PM
    Remake         : 
  ------------------------------- Description ------------------------------- 

           Declaration of the CServiceManager class.

  ------------------------------ Modifications ------------------------------ 
    $Log: $  
  =========================================================================== 
*/

#if !defined(AFX_SERVICEMANAGER_H__066D9109_A7C8_11D3_BFE2_0010E3B966CE__INCLUDED_)
#define AFX_SERVICEMANAGER_H__066D9109_A7C8_11D3_BFE2_0010E3B966CE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <winsvc.h>

typedef enum _NTSAction {
    NTS_LIST_PRINT,
    NTS_LIST_PRINT_NO_HEADER,
    NTS_LIST_STOP,
    NTS_LIST_START
} NTSAction;

/* -----------------------------------------------------------------
CLASS

    CServiceManager  

    Provides enhanced remote control functions for Windows NT Services.

DESCRIPTION

    This class  enhanced remote control functions for Windows NT 
    Services. 

USAGE

    To use this class:
    <UL>
        <LI>Create an instance of the class
        <LI>Call the Open() function (or OpenServiceControlManager())
        <LI>Call any of the following functions:
        <UL>
        <LI>StartService()
        <LI>StopService()
        <LI>QueryService()
        <LI>ListServices()
        </UL>
    </UL>

    Note: By default, this class prints log/error messages in stdout.
    To change this behavior, you must derive this class and override 
    functions Print() and PrintServiceInfo() with your own in the 
    derived class.

EXAMPLE

<PRE>
    CServiceManager oServiceManager;

    CString szMyRemoteMachine = "\\\\remotename";
    CString szMyServiceName = "MyService";

    if (oServiceManager.OpenService(szMyRemoteMachine, szMyServiceName)) {
        if (oServiceManager.StartService(NULL, // Use currently opened machine
                                         NULL, // Use currently opened service
                                         TRUE  // Start dependent services
                                         )) {

            cout << "Service started!\n";

        } else {

            cerr << "Cannot start service " << szMyServiceName << " on host " << szMyRemoteMachine << "\n";

        }
    } else {

        cerr << "Cannot connect to service " << szMyServiceName << " on host " << szMyRemoteMachine << "\n";

    }

</PRE>

ADMINISTRATIVE

  Author     Emmanuel KARTMANN

  Date       Monday 12/6/99

SEE ALSO

    

----------------------------------------------------------------- */

class CServiceManager  
{
public:

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> create an instance of the class
//
// <U>Parameters:</U> none (C++ constructor)
//
// <U>Return value :</U> none (C++ constructor)
//
// <U>Description  :</U> 
//
    CServiceManager();

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> delete an instance of the class
//
// <U>Parameters:</U> none (C++ destructor)
//
// <U>Return value :</U> none (C++ destructor)
//
// <U>Description  :</U> 
//
    virtual ~CServiceManager();

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> open a service (possibly remote)
//
// <U>Parameters:</U> 
//
//       [in] lpszMachineName
//                name of the remote machine
//       [in] lpszServiceName
//                name of the service (internal name OR display name)
//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> 
//
    BOOL Open(LPCTSTR lpszMachineName, LPCTSTR lpszServiceName);

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> start a service (possibly remote)
//
// <U>Parameters:</U> 
//
//       [in] lpszMachineName 
//                name of the remote machine, or NULL
//       [in] lpszServiceName 
//                name of the service (internal name OR display name), or NULL
//       [in] bStartDependents 
//                flag, TRUE if dependent service must be started too.
//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> If any of the parameters are NULL, this
//                       function reuses the currently open SCM/Service.
//
    BOOL StartService(LPCTSTR lpszMachineName = NULL, LPCTSTR lpszServiceName = NULL, BOOL bStartDependents = FALSE);

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> stop a service (possibly remote)
//
// <U>Parameters:</U> 
//
//       [in] lpszMachineName 
//                name of the remote machine
//       [in] lpszServiceName 
//                name of the service (internal name OR display name)
//       [in] bStopDependents 
//                flag, TRUE if dependent service must be stopped too.
//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> If any of the parameters are NULL, this
//                       function reuses the currently open SCM/Service.
//
    BOOL StopService(LPCTSTR lpszMachineName = NULL, LPCTSTR lpszServiceName = NULL, BOOL bStopDependents = FALSE);

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> fetch service information (possibly remote)
//
// <U>Parameters:</U> 
//
//       [in] lpszMachineName 
//                name of the remote machine, or NULL
//       [in] lpszServiceName 
//                name of the service (internal name OR display name), or NULL
//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> If any of the parameters are NULL, this
//                       function reuses the currently open SCM/Service.
//
    BOOL QueryService(LPCTSTR lpszMachineName = NULL, LPCTSTR lpszServiceName = NULL);

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> list the services installed on a machine (possibly remote)
//
// <U>Parameters:</U> 
//
//       [in] lpszMachineName 
//                name of the remote machine, or NULL
//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> If the parameter is NULL, this
//                       function reuses the currently open SCM.
//
    BOOL ListServices(LPCTSTR lpszMachineName = NULL);

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> print formatted data
//
// <U>Parameters:</U> 
//
//       [in] lpszFormat
//                printf-like format of the data (e.g. "%s %s %s")
//       [in] lpszParam1 
//                1st parameter for the data
//       [in] lpszParam2 
//                2nd parameter for the data
//       [in] lpszParam3 
//                3rd parameter for the data
//       [in] lpszParam4 
//                4th parameter for the data
//       [in] lpszParam5 
//                5th parameter for the data

//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> Derive this class and override this function
//                       if you don't want to print data in stdout.
//
    virtual BOOL Print(LPCTSTR lpszFormat, LPCTSTR lpszParam1 = NULL, LPCTSTR lpszParam2 = NULL, LPCTSTR lpszParam3 = NULL, LPCTSTR lpszParam4 = NULL, LPCTSTR lpszParam5 = NULL);

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> 
//
// <U>Parameters:</U> 
//
//       [in] nCount
//                service number
//       [in] lpszServiceName
//                service name (internal name)
//       [in] lpszDisplayName
//                service display name
//       [in] ServiceStatus
//                pointer 
//       [in] lpServiceConfig 
//                pointer to service configuration info
//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> Derive this class and override this function
//                       if you don't want to print data in stdout.
//
    virtual BOOL PrintServiceInfo(int nCount, SERVICE_STATUS *ServiceStatus, LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName, LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL);

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> open SCM on a machine (possibly remote)
//
// <U>Parameters:</U> 
//
//       [in] lpszMachineName 
//                name of the remote machine, or NULL
//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> 
//
    BOOL OpenServiceControlManager(LPCTSTR lpszMachineName = NULL);

/////////////////////////////////////////////////////////////////////
//
// <U>Purpose:</U> open a service on a machine
//
// <U>Parameters:</U> 
//
//       [in] lpszServiceName 
//                name of the service, or NULL
//
// <U>Return value :</U> BOOL = TRUE for success, FALSE otherwise
//
// <U>Description  :</U> 
//
    BOOL OpenService(LPCTSTR lpszServiceName = NULL);

protected:
    BOOL CloseServiceControlManager(void);
    BOOL CloseService(void);
	LPSTR GetStatusString(DWORD dwServiceStatus);
    LPSTR GetStartupString(DWORD dwServiceStartupType);
	BOOL QueryServiceConfiguration(LPCTSTR lpszMachineName = NULL, LPCTSTR lpszServiceName = NULL);
    BOOL QueryDependentServices(LPCTSTR lpszMachineName, LPCTSTR lpszServiceName, NTSAction nServiceAction = NTS_LIST_PRINT);
	LPQUERY_SERVICE_CONFIG QueryServiceConfiguration(SC_HANDLE m_schSCManager, SC_HANDLE m_schService);
	BOOL StopService(SC_HANDLE m_schSCManager, SC_HANDLE m_schService);
	BOOL StartService(SC_HANDLE m_schSCManager, SC_HANDLE m_schService);
    void SetMachineName(LPCTSTR lpszMachineName);
    void SetServiceName(LPCTSTR lpszServiceName);
    SC_HANDLE m_schSCManager;
    SC_HANDLE m_schService;
    TCHAR m_lpszMachineName[256];
    TCHAR m_lpszServiceName[256];
    static LPTSTR GetErrorText(DWORD errorCode, LPTSTR lpszBuf, DWORD dwSize);
};

#endif // !defined(AFX_SERVICEMANAGER_H__066D9109_A7C8_11D3_BFE2_0010E3B966CE__INCLUDED_)

