// 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 $
*/
// 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;
// // 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;
// 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));
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;
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));
// // 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;
// 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;
// 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
¤ Dauer der Verarbeitung: 0.33 Sekunden
(vorverarbeitet)
¤
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.