|
|
/*************************************************************************
* Microsoft Windows NT * * * * Copyright(c) Microsoft Corp., 1994 * * * * Revision History: * * * * Jan. 22,94 Koti Created * * * * Description: * * * * This file contains functions that enable LPD service to interact * * with the Service Controller * * * *************************************************************************/
#include "lpd.h"
#include <tcpsvcs.h>
/*****************************************************************************
* * * Service Entry(): * * Entry point called by the Service Controller. This function returns * * only when the service is stopped. * * * * Returns: * * Nothing * * * * Parameters: * * dwArgc (IN): number of arguments passed in * * lpszArgv (IN): arguments to this function (array of null-terminated * * strings). First arg is the name of the service and the * * remaining are the ones passed by the calling process. * * (e.g. net start lpd /p:xyz) * * * * History: * * Jan.22, 94 Koti Created * * * *****************************************************************************/
VOID ServiceEntry( DWORD dwArgc, LPTSTR *lpszArgv, PTCPSVCS_GLOBAL_DATA pGlobalData ) {
DWORD dwErrcode;
DBG_TRACEIN( "ServiceEntry" );
// Register our control handler
hSvcHandleGLB = RegisterServiceCtrlHandler( LPD_SERVICE_NAME, LPDCntrlHandler );
if ( hSvcHandleGLB == 0 ) { LOGIT(( "ServiceEntry: RegisterServiceCtrlHandler() failed %d\n", GetLastError() )); return; }
// Initialize events, objects; event logging etc.
if ( !InitStuff() ){ LPD_DEBUG( "ServiceEntry: InitStuff() failed\n" ); return; }
// Tell the Service Controller that we are starting
if (!TellSrvcController( SERVICE_START_PENDING, NO_ERROR, 1, LPD_WAIT_HINT )) { LPD_DEBUG( "ServiceEntry: TellSrvcController(SERVICE_START_PENDING)" " failed\n" ); EndLogging(); return; }
// Ok, this is where we start the service (and keep it running)
dwErrcode = StartLPD( dwArgc, lpszArgv );
if ( dwErrcode != NO_ERROR ) { LOGIT(( "ServiceEntry: StartLPD() failed %d\n", GetLastError() )); LpdReportEvent( LPDLOG_LPD_DIDNT_START, 0, NULL, dwErrcode ); EndLogging(); return; }
// Tell the Service Controller that we are up and running
// If we have trouble telling srv controller, stop LPD and return
if ( !TellSrvcController( SERVICE_RUNNING, NO_ERROR, 0, 0 ) ) { LPD_DEBUG( "TellSrvcController(): stopping LPD and quitting!\n" ); StopLPD(); TellSrvcController( SERVICE_STOPPED, NO_ERROR, 0, 0 ); EndLogging(); DBG_TRACEOUT( "ServiceEntry" ); return; }
LPD_DEBUG( "Started LpdSvc successfully\n" );
LpdReportEvent( LPDLOG_LPD_STARTED, 0, NULL, 0 );
// wait here until SetEvent is invoked (i.e. LPD is stopped or shutdown)
WaitForSingleObject( hEventShutdownGLB, INFINITE );
// Tell the Service Controller that we are going to stop now!
if ( !TellSrvcController( SERVICE_STOP_PENDING, NO_ERROR, 1, LPD_WAIT_HINT ) ) { LPD_DEBUG( "TellSrvcController( SERVICE_STOP_PENDING, .. ) failed\n" ); }
// Stop the LPD service
StopLPD(); FreeStrings(); DBG_DUMPLEAKS(); LPD_DEBUG( "ServiceEntry: Stopped LpdSvc successfully\n" ); LpdReportEvent( LPDLOG_LPD_STOPPED, 0, NULL, 0 ); EndLogging(); DBG_UNINIT();
#ifdef DBG
if( LogFile ){ stoplogging( LogFile ); } #endif
// if we can still connect, tell the Service Controller that we are gone!
if ( hSvcHandleGLB != 0 ) { TellSrvcController( SERVICE_STOPPED, NO_ERROR, 0, 0 ); }
} // end ServiceEntry()
/*****************************************************************************
* * * TellSrvcController(): * * This function updates the status of our service (LPD) with the Service * * Controller. * * * * Returns: * * TRUE if everything went ok * * FALSE if something went wrong * * * * Parameters: * * The four parameters correspond to the 2nd, 4th, 6th and 7th parameters * * respectively of the SERVICE_STATUS structure passed to the * * SetServiceStatus call. * * * * History: * * Jan.22, 94 Koti Created * * * *****************************************************************************/
BOOL TellSrvcController( DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) {
BOOL fResult;
LOGIT(( "Entering TellSrvcController %d\n", dwCurrentState ));
// initialize the service status structure
ssSvcStatusGLB.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssSvcStatusGLB.dwCurrentState = dwCurrentState; ssSvcStatusGLB.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN; ssSvcStatusGLB.dwWin32ExitCode = dwWin32ExitCode; ssSvcStatusGLB.dwServiceSpecificExitCode = NO_ERROR; ssSvcStatusGLB.dwCheckPoint = dwCheckPoint; ssSvcStatusGLB.dwWaitHint = dwWaitHint;
// Tell the Service Controller what our status is
fResult = SetServiceStatus( hSvcHandleGLB, &ssSvcStatusGLB );
DBG_TRACEOUT( "TellSrvcController" );
return (fResult);
} // end TellSrvcController()
/*****************************************************************************
* * * LPDCntrlHandler(): * * This function gets called (indirectly by the Service Controller) * * whenever there is a control request for the LPD service. Depending on * * the control request, this function takes appropriate action. * * * * Returns: * * Nothing * * * * Parameters: * * dwControl (IN): The requested control code. * * * * History: * * Jan.22, 94 Koti Created * * * *****************************************************************************/
VOID LPDCntrlHandler( DWORD dwControl ) {
BOOL fMustStopSrvc=FALSE; time_t now;
time( &now ); LOGIT(("Entering LPDCntrlHandler %d at %s", dwControl, ctime(&now) ));
switch( dwControl ) { // Treat _STOP and _SHUTDOWN in the same manner
case SERVICE_CONTROL_STOP: LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_STOP\n"));
case SERVICE_CONTROL_SHUTDOWN: LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_SHUTDOWN\n")); ssSvcStatusGLB.dwCurrentState = SERVICE_STOP_PENDING; ssSvcStatusGLB.dwCheckPoint = 0;
fMustStopSrvc = TRUE; break;
// don't accept any new connections: the service is now PAUSED
case SERVICE_CONTROL_PAUSE: LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_PAUSE\n")); ssSvcStatusGLB.dwCurrentState = SERVICE_PAUSED; break;
// the service was paused earlier: continue it now
case SERVICE_CONTROL_CONTINUE: LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_CONTINUE\n")); ssSvcStatusGLB.dwCurrentState = SERVICE_RUNNING; break;
// we don't do anything with this
case SERVICE_CONTROL_INTERROGATE: LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_INTERROGATE\n")); break;
default: LOGIT(("Unknown control word received in LPDCntrlHandler\n")); break; }
// Update the status (even if it didn't change!) with Service Controller
SetServiceStatus( hSvcHandleGLB, &ssSvcStatusGLB );
// If we must stop or shutdown the service, set our shutdown event
if ( fMustStopSrvc ) { fShuttingDownGLB = 1; SetEvent( hEventShutdownGLB ); LOGIT(("LPDCntrlHandler: fShuttingDownGLB=%d\n", fShuttingDownGLB )); }
DBG_TRACEOUT( "LPDCntrlHandler" );
} // end LPDCntrlHandler()
|