Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/iPerf/src/     Datei vom 30.0.2026 mit Größe 17 kB image not shown  

Quelle  service.c   Sprache: C

 
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved.
//
//  MODULE:   service.c
//
//  PURPOSE:  Implements functions required by all services
//            windows.
//
//  FUNCTIONS:
//    main(int argc, char **argv);
//    service_ctrl(DWORD dwCtrlCode);
//    service_main(DWORD dwArgc, LPTSTR *lpszArgv);
//    CmdInstallService();
//    CmdRemoveService();
//    ControlHandler ( DWORD dwCtrlType );
//    GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
//
//  COMMENTS:
//
//  AUTHOR: Craig Link - Microsoft Developer Support
//

/*
 * modified Mar.07, 2002 by Feng Qin <fqin@ncsa.uiuc.edu>
 *          Mar.15, 2002
 *
 * removed some functions we don't use at all
 * add code to start the service immediately after service is installed
 * 
 * $Id: service.c,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
 */


#ifdef WIN32
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <tchar.h>

#include "service.h"



// internal variables
SERVICE_STATUS          ssStatus;       // current status of the service
SERVICE_STATUS_HANDLE   sshStatusHandle;
DWORD                   dwErr = 0;
TCHAR                   szErr[256];

//
//  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 clean;

    // 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 clean;


    ServiceStart( dwArgc, lpszArgv );

    clean:

    // try to report the stopped status to the service control manager.
    //
    if ( sshStatusHandle )
        (VOID)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.
        //
        // SERVICE_STOP_PENDING should be reported before
        // setting the Stop Event - hServerStopEvent - in
        // ServiceStop().  This avoids a race condition
        // which may result in a 1053 - The Service did not respond...
        // error.
        case SERVICE_CONTROL_STOP:
            ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
            ServiceStop();

            return;

            // Update the service status.
            //
        case SERVICE_CONTROL_INTERROGATE:
            break;

            // invalid control code
            //
        default:
            break;

    }
    ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);
//    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 ( 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];


    dwErr = GetLastError();

    // Use event logging to log the error.
    //
    hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));

    printf(lpszMsg);

    _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

        (VOID) DeregisterEventSource(hEventSource);
    }
}




///////////////////////////////////////////////////////////////////
//
//  The following code handles service installation and removal
//
//
//  FUNCTION: CmdInstallService()
//
//  PURPOSE: Installs the service and Starts it
//
//  PARAMETERS:
//    argc: number of arguments
// argv: all of the arguments including the program's name
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
void CmdInstallService(int argc, char **argv) {
    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 = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
        if ( !schService ) {
            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
        } else {
            _tprintf(TEXT("%s already installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
        }
        if ( schService ) {
            if ( QueryServiceStatus( schService, &ssStatus ) ) {
                int rc;
                if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) {
                    rc = StartService(schService, argc-1, argv+1);
                }


                if ( rc != 0 )
                    _tprintf(TEXT("%s started.\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:
//    TRUE: service exists and is removed
// FALSE: service doesn't exist
//
//  COMMENTS:
//
BOOL CmdRemoveService() {
    BOOL isExist = FALSE;
    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 ) {
            isExist = TRUE;
            // 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);
        }

        CloseServiceHandle(schSCManager);
    } else
        _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));

    return isExist;
}

//
//  FUNCTION: CmdStartService()
//
//  PURPOSE: Start service if it exists
//
//  PARAMETERS:
//    argc: number of arguments
// argv: arguments including program's name
//
//  RETURN VALUE:
//    TRUE: service exists and is started
// FALSE: service doesn't exist
//
//  COMMENTS:
//
BOOL CmdStartService(int argc, char **argv) {
    BOOL isExist = FALSE;
    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 ) {
            isExist = TRUE;
            if ( QueryServiceStatus( schService, &ssStatus ) ) {
                int rc;
                if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) {
                    rc = StartService(schService, argc-1, argv+1);
                }


                if ( rc != 0 )
                    _tprintf(TEXT("%s started.\n"), TEXT(SZSERVICEDISPLAYNAME) );
            }
            CloseServiceHandle(schService);            
        }
        CloseServiceHandle(schSCManager);
    } else
        _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));

    return isExist;
}




//
//  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;
}

/*--------------------------------------------------------------------
 * ServiceStart
 *
 * each time starting the service, this is the entry point of the service.
 * Start the service, certainly it is on server-mode
 * 
 *-------------------------------------------------------------------- */

VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) {
    
    // report the status to the service control manager.
    //
    if ( !ReportStatusToSCMgr(
                             SERVICE_START_PENDING, // service state
                             NO_ERROR,              // exit code
                             3000) )                 // wait hint
        goto clean;

    thread_Settings* ext_gSettings = new thread_Settings;

    // Initialize settings to defaults
    Settings_Initialize( ext_gSettings );
    // read settings from environment variables
    Settings_ParseEnvironment( ext_gSettings );
    // read settings from command-line parameters
    Settings_ParseCommandLine( dwArgc, lpszArgv, ext_gSettings );

    // report the status to the service control manager.
    //
    if ( !ReportStatusToSCMgr(
                             SERVICE_START_PENDING, // service state
                             NO_ERROR,              // exit code
                             3000) )                 // wait hint
        goto clean;

    // if needed, redirect the output into a specified file
    if ( !isSTDOUT( ext_gSettings ) ) {
        redirect( ext_gSettings->mOutputFileName );
    }

    // report the status to the service control manager.
    //
    if ( !ReportStatusToSCMgr(
                             SERVICE_START_PENDING, // service state
                             NO_ERROR,              // exit code
                             3000) )                 // wait hint
        goto clean;
    
    // initialize client(s)
    if ( ext_gSettings->mThreadMode == kMode_Client ) {
        client_init( ext_gSettings );
    }

    // start up the reporter and client(s) or listener
    {
        thread_Settings *into = NULL;
#ifdef HAVE_THREAD
        Settings_Copy( ext_gSettings, &into );
        into->mThreadMode = kMode_Reporter;
        into->runNow = ext_gSettings;
#else
        into = ext_gSettings;
#endif
        thread_start( into );
    }
    
    // report the status to the service control manager.
    //
    if ( !ReportStatusToSCMgr(
                             SERVICE_RUNNING,       // service state
                             NO_ERROR,              // exit code
                             0) )                    // wait hint
        goto clean;

    clean:
    // wait for other (client, server) threads to complete
    thread_joinall();
}


//
//  FUNCTION: ServiceStop
//
//  PURPOSE: Stops the service
//
//  PARAMETERS:
//    none
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//    If a ServiceStop procedure is going to
//    take longer than 3 seconds to execute,
//    it should spawn a thread to execute the
//    stop code, and return.  Otherwise, the
//    ServiceControlManager will believe that
//    the service has stopped responding.
//    
VOID ServiceStop() {
#ifdef HAVE_THREAD
    Sig_Interupt( 1 );
#else
    sig_exit(1);
#endif
}

#endif

86%


¤ Dauer der Verarbeitung: 0.37 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.