mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			746 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			746 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/****************************************************************************
 | 
						|
   MySqlWatch    - WinNT service program MySQL
 | 
						|
                 - Re-start MySql server in case of failure
 | 
						|
*****************************************************************************/
 | 
						|
#include <windows.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <process.h>
 | 
						|
#include <tchar.h>
 | 
						|
 | 
						|
 | 
						|
// name of the executable
 | 
						|
#define SZAPPNAME            "mysqlwatch"
 | 
						|
// internal name of the service
 | 
						|
#define SZSERVICENAME        "MySqlWatch"
 | 
						|
// displayed name of the service
 | 
						|
#define SZSERVICEDISPLAYNAME "MySqlWatch"
 | 
						|
// list of service dependencies - "dep1\0dep2\0\0"
 | 
						|
#define SZDEPENDENCIES       ""
 | 
						|
 | 
						|
 | 
						|
 | 
						|
VOID ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
 | 
						|
VOID ServiceStop(void);
 | 
						|
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
 | 
						|
void AddToMessageLog(LPTSTR lpszMsg);
 | 
						|
 | 
						|
// internal variables
 | 
						|
SERVICE_STATUS          ssStatus;       // current status of the service
 | 
						|
SERVICE_STATUS_HANDLE   sshStatusHandle;
 | 
						|
DWORD                   dwErr = 0;
 | 
						|
BOOL                    bDebug = FALSE;
 | 
						|
TCHAR                   szErr[256];
 | 
						|
 | 
						|
// internal function prototypes
 | 
						|
void WINAPI service_ctrl(DWORD dwCtrlCode);
 | 
						|
void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
 | 
						|
void CmdInstallService(void);
 | 
						|
void CmdRemoveService(void);
 | 
						|
void CmdDebugService(int argc, char **argv);
 | 
						|
BOOL WINAPI ControlHandler ( DWORD dwCtrlType );
 | 
						|
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: main
 | 
						|
//
 | 
						|
//  PURPOSE: entrypoint for service
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    argc - number of command line arguments
 | 
						|
//    argv - array of command line arguments
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//    main() either performs the command line task, or
 | 
						|
//    call StartServiceCtrlDispatcher to register the
 | 
						|
//    main service thread.  When the this call returns,
 | 
						|
//    the service has stopped, so exit.
 | 
						|
//
 | 
						|
void main(int argc, char **argv)
 | 
						|
{
 | 
						|
    SERVICE_TABLE_ENTRY dispatchTable[] =
 | 
						|
    {
 | 
						|
        { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main },
 | 
						|
        { NULL, NULL }
 | 
						|
    };
 | 
						|
 | 
						|
    if ( (argc > 1) &&
 | 
						|
         ((*argv[1] == '-') || (*argv[1] == '/')) )
 | 
						|
    {
 | 
						|
        if ( stricmp( "install", argv[1]+1 ) == 0 )
 | 
						|
        {
 | 
						|
            CmdInstallService();
 | 
						|
        }
 | 
						|
        else if ( stricmp( "remove", argv[1]+1 ) == 0 )
 | 
						|
        {
 | 
						|
            CmdRemoveService();
 | 
						|
        }
 | 
						|
        else if ( stricmp( "debug", argv[1]+1 ) == 0 )
 | 
						|
        {
 | 
						|
            bDebug = TRUE;
 | 
						|
            CmdDebugService(argc, argv);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            goto dispatch;
 | 
						|
        }
 | 
						|
        exit(0);
 | 
						|
    }
 | 
						|
 | 
						|
    // if it doesn't match any of the above parameters
 | 
						|
    // the service control manager may be starting the service
 | 
						|
    // so we must call StartServiceCtrlDispatcher
 | 
						|
    dispatch:
 | 
						|
        // this is just to be friendly
 | 
						|
        printf( "%s -install          to install the service\n", SZAPPNAME );
 | 
						|
        printf( "%s -remove           to remove the service\n", SZAPPNAME );
 | 
						|
        printf( "%s -debug <params>   to run as a console app for debugging\n", SZAPPNAME );
 | 
						|
        printf( "\nStartServiceCtrlDispatcher being called.\n" );
 | 
						|
        printf( "This may take several seconds.  Please wait.\n" );
 | 
						|
 | 
						|
        if (!StartServiceCtrlDispatcher(dispatchTable))
 | 
						|
            AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: service_main
 | 
						|
//
 | 
						|
//  PURPOSE: To perform actual initialization of the service
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    dwArgc   - number of command line arguments
 | 
						|
//    lpszArgv - array of command line arguments
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//    This routine performs the service initialization and then calls
 | 
						|
//    the user defined ServiceStart() routine to perform majority
 | 
						|
//    of the work.
 | 
						|
//
 | 
						|
void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
 | 
						|
{
 | 
						|
 | 
						|
    // register our service control handler:
 | 
						|
    //
 | 
						|
    sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
 | 
						|
 | 
						|
    if (!sshStatusHandle)
 | 
						|
        goto cleanup;
 | 
						|
 | 
						|
    // SERVICE_STATUS members that don't change in example
 | 
						|
    //
 | 
						|
    ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
 | 
						|
    ssStatus.dwServiceSpecificExitCode = 0;
 | 
						|
 | 
						|
 | 
						|
    // report the status to the service control manager.
 | 
						|
    //
 | 
						|
    if (!ReportStatusToSCMgr(
 | 
						|
        SERVICE_START_PENDING, // service state
 | 
						|
        NO_ERROR,              // exit code
 | 
						|
        3000))                 // wait hint
 | 
						|
        goto cleanup;
 | 
						|
 | 
						|
 | 
						|
    ServiceStart( dwArgc, lpszArgv );
 | 
						|
 | 
						|
cleanup:
 | 
						|
 | 
						|
    // try to report the stopped status to the service control manager.
 | 
						|
    //
 | 
						|
    if (sshStatusHandle)
 | 
						|
        ReportStatusToSCMgr(
 | 
						|
                            SERVICE_STOPPED,
 | 
						|
                            dwErr,
 | 
						|
                            0);
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: service_ctrl
 | 
						|
//
 | 
						|
//  PURPOSE: This function is called by the SCM whenever
 | 
						|
//           ControlService() is called on this service.
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    dwCtrlCode - type of control requested
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
void WINAPI service_ctrl(DWORD dwCtrlCode)
 | 
						|
{
 | 
						|
    // Handle the requested control code.
 | 
						|
    //
 | 
						|
    switch(dwCtrlCode)
 | 
						|
    {
 | 
						|
        // Stop the service.
 | 
						|
        //
 | 
						|
        case SERVICE_CONTROL_STOP:
 | 
						|
            ssStatus.dwCurrentState = SERVICE_STOP_PENDING;
 | 
						|
            ServiceStop();
 | 
						|
            break;
 | 
						|
 | 
						|
        // Update the service status.
 | 
						|
        //
 | 
						|
        case SERVICE_CONTROL_INTERROGATE:
 | 
						|
            break;
 | 
						|
 | 
						|
        // invalid control code
 | 
						|
        //
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: ReportStatusToSCMgr()
 | 
						|
//
 | 
						|
//  PURPOSE: Sets the current status of the service and
 | 
						|
//           reports it to the Service Control Manager
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    dwCurrentState - the state of the service
 | 
						|
//    dwWin32ExitCode - error code to report
 | 
						|
//    dwWaitHint - worst case estimate to next checkpoint
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    TRUE  - success
 | 
						|
//    FALSE - failure
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
 | 
						|
                         DWORD dwWin32ExitCode,
 | 
						|
                         DWORD dwWaitHint)
 | 
						|
{
 | 
						|
    static DWORD dwCheckPoint = 1;
 | 
						|
    BOOL fResult = TRUE;
 | 
						|
 | 
						|
 | 
						|
    if ( !bDebug ) // when debugging we don't report to the SCM
 | 
						|
    {
 | 
						|
        if (dwCurrentState == SERVICE_START_PENDING)
 | 
						|
            ssStatus.dwControlsAccepted = 0;
 | 
						|
        else
 | 
						|
            ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
 | 
						|
 | 
						|
        ssStatus.dwCurrentState = dwCurrentState;
 | 
						|
        ssStatus.dwWin32ExitCode = dwWin32ExitCode;
 | 
						|
        ssStatus.dwWaitHint = dwWaitHint;
 | 
						|
 | 
						|
        if ( ( dwCurrentState == SERVICE_RUNNING ) ||
 | 
						|
             ( dwCurrentState == SERVICE_STOPPED ) )
 | 
						|
            ssStatus.dwCheckPoint = 0;
 | 
						|
        else
 | 
						|
            ssStatus.dwCheckPoint = dwCheckPoint++;
 | 
						|
 | 
						|
 | 
						|
        // Report the status of the service to the service control manager.
 | 
						|
        //
 | 
						|
        if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) {
 | 
						|
            AddToMessageLog(TEXT("SetServiceStatus"));
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return fResult;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
 | 
						|
//
 | 
						|
//  PURPOSE: Allows any thread to log an error message
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    lpszMsg - text for message
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
void AddToMessageLog(LPTSTR lpszMsg)
 | 
						|
{
 | 
						|
    TCHAR   szMsg[256];
 | 
						|
    HANDLE  hEventSource;
 | 
						|
    LPTSTR  lpszStrings[2];
 | 
						|
 | 
						|
 | 
						|
    if ( !bDebug )
 | 
						|
    {
 | 
						|
        dwErr = GetLastError();
 | 
						|
 | 
						|
        // Use event logging to log the error.
 | 
						|
        //
 | 
						|
        hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
 | 
						|
 | 
						|
        _stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr);
 | 
						|
        lpszStrings[0] = szMsg;
 | 
						|
        lpszStrings[1] = lpszMsg;
 | 
						|
 | 
						|
        if (hEventSource != NULL) {
 | 
						|
            ReportEvent(hEventSource, // handle of event source
 | 
						|
                EVENTLOG_ERROR_TYPE,  // event type
 | 
						|
                0,                    // event category
 | 
						|
                0,                    // event ID
 | 
						|
                NULL,                 // current user's SID
 | 
						|
                2,                    // strings in lpszStrings
 | 
						|
                0,                    // no bytes of raw data
 | 
						|
                lpszStrings,          // array of error strings
 | 
						|
                NULL);                // no raw data
 | 
						|
 | 
						|
             DeregisterEventSource(hEventSource);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
//  The following code handles service installation and removal
 | 
						|
//
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: CmdInstallService()
 | 
						|
//
 | 
						|
//  PURPOSE: Installs the service
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
void CmdInstallService()
 | 
						|
{
 | 
						|
    SC_HANDLE   schService;
 | 
						|
    SC_HANDLE   schSCManager;
 | 
						|
 | 
						|
    TCHAR szPath[512];
 | 
						|
 | 
						|
    if ( GetModuleFileName( NULL, szPath, 512 ) == 0 )
 | 
						|
    {
 | 
						|
        _tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    schSCManager = OpenSCManager(
 | 
						|
                        NULL,                   // machine (NULL == local)
 | 
						|
                        NULL,                   // database (NULL == default)
 | 
						|
                        SC_MANAGER_ALL_ACCESS   // access required
 | 
						|
                        );
 | 
						|
    if ( schSCManager )
 | 
						|
    {
 | 
						|
        schService = CreateService(
 | 
						|
            schSCManager,               // SCManager database
 | 
						|
            TEXT(SZSERVICENAME),        // name of service
 | 
						|
            TEXT(SZSERVICEDISPLAYNAME), // name to display
 | 
						|
            SERVICE_ALL_ACCESS,         // desired access
 | 
						|
            SERVICE_WIN32_OWN_PROCESS,  // service type
 | 
						|
            SERVICE_DEMAND_START,       // start type
 | 
						|
            SERVICE_ERROR_NORMAL,       // error control type
 | 
						|
            szPath,                     // service's binary
 | 
						|
            NULL,                       // no load ordering group
 | 
						|
            NULL,                       // no tag identifier
 | 
						|
            TEXT(SZDEPENDENCIES),       // dependencies
 | 
						|
            NULL,                       // LocalSystem account
 | 
						|
            NULL);                      // no password
 | 
						|
 | 
						|
        if ( schService )
 | 
						|
        {
 | 
						|
            _tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
 | 
						|
            CloseServiceHandle(schService);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
 | 
						|
        }
 | 
						|
 | 
						|
        CloseServiceHandle(schSCManager);
 | 
						|
    }
 | 
						|
    else
 | 
						|
        _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: CmdRemoveService()
 | 
						|
//
 | 
						|
//  PURPOSE: Stops and removes the service
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
void CmdRemoveService()
 | 
						|
{
 | 
						|
    SC_HANDLE   schService;
 | 
						|
    SC_HANDLE   schSCManager;
 | 
						|
 | 
						|
    schSCManager = OpenSCManager(
 | 
						|
                        NULL,                   // machine (NULL == local)
 | 
						|
                        NULL,                   // database (NULL == default)
 | 
						|
                        SC_MANAGER_ALL_ACCESS   // access required
 | 
						|
                        );
 | 
						|
    if ( schSCManager )
 | 
						|
    {
 | 
						|
        schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
 | 
						|
 | 
						|
        if (schService)
 | 
						|
        {
 | 
						|
            // try to stop the service
 | 
						|
            if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) )
 | 
						|
            {
 | 
						|
                _tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
 | 
						|
                Sleep( 1000 );
 | 
						|
 | 
						|
                while( QueryServiceStatus( schService, &ssStatus ) )
 | 
						|
                {
 | 
						|
                    if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )
 | 
						|
                    {
 | 
						|
                        _tprintf(TEXT("."));
 | 
						|
                        Sleep( 1000 );
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
 | 
						|
                if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
 | 
						|
                    _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
 | 
						|
                else
 | 
						|
                    _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );
 | 
						|
 | 
						|
            }
 | 
						|
 | 
						|
            // now remove the service
 | 
						|
            if( DeleteService(schService) )
 | 
						|
                _tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
 | 
						|
            else
 | 
						|
                _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256));
 | 
						|
 | 
						|
 | 
						|
            CloseServiceHandle(schService);
 | 
						|
        }
 | 
						|
        else
 | 
						|
            _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
 | 
						|
 | 
						|
        CloseServiceHandle(schSCManager);
 | 
						|
    }
 | 
						|
    else
 | 
						|
        _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: CmdRestartService()
 | 
						|
//
 | 
						|
//  PURPOSE: Stops and removes the service
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
void CmdRestartService(char *szServiceName)
 | 
						|
{
 | 
						|
    SC_HANDLE   schService;
 | 
						|
    SC_HANDLE   schSCManager;
 | 
						|
 | 
						|
    schSCManager = OpenSCManager(
 | 
						|
                        NULL,                   // machine (NULL == local)
 | 
						|
                        NULL,                   // database (NULL == default)
 | 
						|
                        SC_MANAGER_ALL_ACCESS   // access required
 | 
						|
                        );
 | 
						|
    if ( schSCManager )
 | 
						|
    {
 | 
						|
        schService = OpenService(schSCManager, TEXT(szServiceName), SERVICE_ALL_ACCESS);
 | 
						|
        if (schService)
 | 
						|
        {
 | 
						|
            if(! ControlService( schService, SERVICE_CONTROL_INTERROGATE, &ssStatus ) )
 | 
						|
            //if(QueryServiceStatus( schService, &ssStatus )==0)
 | 
						|
            {
 | 
						|
                if(GetLastError()==ERROR_SERVICE_NOT_ACTIVE)
 | 
						|
                {
 | 
						|
 | 
						|
                   //AddToMessageLog(TEXT("Start service..."));
 | 
						|
                   StartService( schService, 0,NULL);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {  ;
 | 
						|
                   //AddToMessageLog(TEXT("QueryService..."));
 | 
						|
                   //AddToMessageLog(TEXT(GetLastErrorText(szErr,256)));
 | 
						|
                }
 | 
						|
            }
 | 
						|
            CloseServiceHandle(schService);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {    _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
 | 
						|
              AddToMessageLog(TEXT("OpenService..."));
 | 
						|
              AddToMessageLog(TEXT(GetLastErrorText(szErr,256)));
 | 
						|
 | 
						|
        }
 | 
						|
        CloseServiceHandle(schSCManager);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {    _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
 | 
						|
          AddToMessageLog(TEXT("OpenSCMManager.."));
 | 
						|
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
//  The following code is for running the service as a console app
 | 
						|
//
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: CmdDebugService(int argc, char ** argv)
 | 
						|
//
 | 
						|
//  PURPOSE: Runs the service as a console application
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    argc - number of command line arguments
 | 
						|
//    argv - array of command line arguments
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    none
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
void CmdDebugService(int argc, char ** argv)
 | 
						|
{
 | 
						|
    DWORD dwArgc;
 | 
						|
    LPTSTR *lpszArgv;
 | 
						|
 | 
						|
#ifdef UNICODE
 | 
						|
    lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
 | 
						|
#else
 | 
						|
    dwArgc   = (DWORD) argc;
 | 
						|
    lpszArgv = argv;
 | 
						|
#endif
 | 
						|
 | 
						|
    _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
 | 
						|
 | 
						|
    SetConsoleCtrlHandler( ControlHandler, TRUE );
 | 
						|
 | 
						|
    ServiceStart( dwArgc, lpszArgv );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: ControlHandler ( DWORD dwCtrlType )
 | 
						|
//
 | 
						|
//  PURPOSE: Handled console control events
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    dwCtrlType - type of control event
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    True - handled
 | 
						|
//    False - unhandled
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
 | 
						|
{
 | 
						|
    switch( dwCtrlType )
 | 
						|
    {
 | 
						|
        case CTRL_BREAK_EVENT:  // use Ctrl+C or Ctrl+Break to simulate
 | 
						|
        case CTRL_C_EVENT:      // SERVICE_CONTROL_STOP in debug mode
 | 
						|
            _tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
 | 
						|
            ServiceStop();
 | 
						|
            return TRUE;
 | 
						|
            break;
 | 
						|
 | 
						|
    }
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
//  FUNCTION: GetLastErrorText
 | 
						|
//
 | 
						|
//  PURPOSE: copies error message text to string
 | 
						|
//
 | 
						|
//  PARAMETERS:
 | 
						|
//    lpszBuf - destination buffer
 | 
						|
//    dwSize - size of buffer
 | 
						|
//
 | 
						|
//  RETURN VALUE:
 | 
						|
//    destination buffer
 | 
						|
//
 | 
						|
//  COMMENTS:
 | 
						|
//
 | 
						|
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
 | 
						|
{
 | 
						|
    DWORD dwRet;
 | 
						|
    LPTSTR lpszTemp = NULL;
 | 
						|
 | 
						|
    dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
 | 
						|
                           NULL,
 | 
						|
                           GetLastError(),
 | 
						|
                           LANG_NEUTRAL,
 | 
						|
                           (LPTSTR)&lpszTemp,
 | 
						|
                           0,
 | 
						|
                           NULL );
 | 
						|
 | 
						|
    // supplied buffer is not long enough
 | 
						|
    if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
 | 
						|
        lpszBuf[0] = TEXT('\0');
 | 
						|
    else
 | 
						|
    {
 | 
						|
        lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0');  //remove cr and newline character
 | 
						|
        _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
 | 
						|
    }
 | 
						|
 | 
						|
    if ( lpszTemp )
 | 
						|
        LocalFree((HLOCAL) lpszTemp );
 | 
						|
 | 
						|
    return lpszBuf;
 | 
						|
}
 | 
						|
 | 
						|
//-------------------------------------------------
 | 
						|
// this event is signalled when the
 | 
						|
// service should end
 | 
						|
//-------------------------------------------------
 | 
						|
HANDLE  hServerStopEvent = NULL;
 | 
						|
 | 
						|
 | 
						|
//-------------------------------------------------
 | 
						|
//  FUNCTION: ServiceStart
 | 
						|
//
 | 
						|
//  PURPOSE: Actual code of the service
 | 
						|
//           that does the work.
 | 
						|
//-------------------------------------------------
 | 
						|
void ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
 | 
						|
{
 | 
						|
    DWORD  dwWait,dwTimeout=1000*60*1;
 | 
						|
 | 
						|
    if (!ReportStatusToSCMgr(
 | 
						|
        SERVICE_START_PENDING, // service state
 | 
						|
        NO_ERROR,              // exit code
 | 
						|
        3000))                 // wait hint
 | 
						|
        goto cleanup;
 | 
						|
 | 
						|
    // create the event object. The control handler function signals
 | 
						|
    // this event when it receives the "stop" control code.
 | 
						|
    //
 | 
						|
    hServerStopEvent = CreateEvent(
 | 
						|
        NULL,    // no security attributes
 | 
						|
        TRUE,    // manual reset event
 | 
						|
        FALSE,   // not-signalled
 | 
						|
        NULL);   // no name
 | 
						|
 | 
						|
    if ( hServerStopEvent == NULL) goto cleanup;
 | 
						|
 | 
						|
 | 
						|
    // report the status to the service control manager.
 | 
						|
    //
 | 
						|
    if (!ReportStatusToSCMgr(
 | 
						|
        SERVICE_START_PENDING, // service state
 | 
						|
        NO_ERROR,              // exit code
 | 
						|
        3000))                 // wait hint
 | 
						|
        goto cleanup;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    // report the status to the service control manager.
 | 
						|
    //
 | 
						|
    if (!ReportStatusToSCMgr(
 | 
						|
        SERVICE_START_PENDING, // service state
 | 
						|
        NO_ERROR,              // exit code
 | 
						|
        3000))                 // wait hint
 | 
						|
        goto cleanup;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    // report the status to the service control manager.
 | 
						|
    //
 | 
						|
    if (!ReportStatusToSCMgr(
 | 
						|
        SERVICE_RUNNING,       // service state
 | 
						|
        NO_ERROR,              // exit code
 | 
						|
        0))                    // wait hint
 | 
						|
        goto cleanup;
 | 
						|
 | 
						|
    //
 | 
						|
    // End of initialization
 | 
						|
    // Service is now running, perform work until shutdown
 | 
						|
    //
 | 
						|
 | 
						|
    while ( 1 )
 | 
						|
    {
 | 
						|
 | 
						|
        dwWait = WaitForSingleObject(  hServerStopEvent, dwTimeout);
 | 
						|
        if(dwWait==WAIT_FAILED)
 | 
						|
        {
 | 
						|
           AddToMessageLog(TEXT("Error in WaitForSingleObject"));
 | 
						|
           break;
 | 
						|
        }
 | 
						|
        else if(dwWait==WAIT_TIMEOUT)
 | 
						|
        {
 | 
						|
            CmdRestartService("MySql");
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {   break;  //shutdown
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
  cleanup:
 | 
						|
 | 
						|
    if (hServerStopEvent)
 | 
						|
        CloseHandle(hServerStopEvent);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//-------------------------------------------------
 | 
						|
//  FUNCTION: ServiceStop
 | 
						|
//
 | 
						|
//  PURPOSE: Stops the service
 | 
						|
//-------------------------------------------------
 | 
						|
void ServiceStop()
 | 
						|
{
 | 
						|
    if ( hServerStopEvent )
 | 
						|
        SetEvent(hServerStopEvent);
 | 
						|
}
 | 
						|
//-the end ----------------------------------------
 |