You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
741 lines
27 KiB
741 lines
27 KiB
4 years ago
|
/***************************************************************************/
|
||
|
/* */
|
||
|
/* Project: OpenSLP - OpenSource implementation of Service Location */
|
||
|
/* Protocol Version 2 */
|
||
|
/* */
|
||
|
/* File: slpd_win32.c */
|
||
|
/* */
|
||
|
/* Abstract: Win32 specific part, to make SLPD run as a "service" */
|
||
|
/* */
|
||
|
/*-------------------------------------------------------------------------*/
|
||
|
/* */
|
||
|
/* Please submit patches to http://www.openslp.org */
|
||
|
/* */
|
||
|
/*-------------------------------------------------------------------------*/
|
||
|
/* */
|
||
|
/* Copyright (C) 2000 Caldera Systems, Inc */
|
||
|
/* All rights reserved. */
|
||
|
/* */
|
||
|
/* Redistribution and use in source and binary forms, with or without */
|
||
|
/* modification, are permitted provided that the following conditions are */
|
||
|
/* met: */
|
||
|
/* */
|
||
|
/* Redistributions of source code must retain the above copyright */
|
||
|
/* notice, this list of conditions and the following disclaimer. */
|
||
|
/* */
|
||
|
/* Redistributions in binary form must reproduce the above copyright */
|
||
|
/* notice, this list of conditions and the following disclaimer in */
|
||
|
/* the documentation and/or other materials provided with the */
|
||
|
/* distribution. */
|
||
|
/* */
|
||
|
/* Neither the name of Caldera Systems nor the names of its */
|
||
|
/* contributors may be used to endorse or promote products derived */
|
||
|
/* from this software without specific prior written permission. */
|
||
|
/* */
|
||
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
|
||
|
/* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
|
||
|
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
|
||
|
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA */
|
||
|
/* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
|
||
|
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
|
||
|
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
|
||
|
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
||
|
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
||
|
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
|
||
|
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||
|
/* */
|
||
|
/***************************************************************************/
|
||
|
|
||
|
|
||
|
#include "slpd.h"
|
||
|
|
||
|
/*=========================================================================*/
|
||
|
/* slpd includes */
|
||
|
/*=========================================================================*/
|
||
|
#include "slpd_cmdline.h"
|
||
|
#include "slpd_log.h"
|
||
|
#include "slpd_property.h"
|
||
|
#include "slpd_database.h"
|
||
|
#include "slpd_socket.h"
|
||
|
#include "slpd_incoming.h"
|
||
|
#include "slpd_outgoing.h"
|
||
|
#include "slpd_knownda.h"
|
||
|
|
||
|
|
||
|
/*=========================================================================*/
|
||
|
/* common code includes */
|
||
|
/*=========================================================================*/
|
||
|
#include "slp_linkedlist.h"
|
||
|
#include "slp_xid.h"
|
||
|
|
||
|
SERVICE_STATUS ssStatus; /* current status of the service */
|
||
|
SERVICE_STATUS_HANDLE sshStatusHandle;
|
||
|
BOOL bDebug = FALSE;
|
||
|
TCHAR szErr[256];
|
||
|
|
||
|
/*-------------------------------------------------------------------------*/
|
||
|
extern int G_SIGTERM;
|
||
|
/* see slpd_main.c */
|
||
|
/*-------------------------------------------------------------------------*/
|
||
|
|
||
|
|
||
|
/*-------------------------------------------------------------------------*/
|
||
|
void LoadFdSets(SLPList* socklist,
|
||
|
int* highfd,
|
||
|
fd_set* readfds,
|
||
|
fd_set* writefds);
|
||
|
/* see slpd_main.c */
|
||
|
/*-------------------------------------------------------------------------*/
|
||
|
|
||
|
|
||
|
/*------------------------------------------------------------------------*/
|
||
|
void HandleSigTerm();
|
||
|
/* see slpd_main.c */
|
||
|
/*------------------------------------------------------------------------*/
|
||
|
|
||
|
|
||
|
/*------------------------------------------------------------------------*/
|
||
|
void HandleSigAlrm();
|
||
|
/* see slpd_main.c */
|
||
|
/*------------------------------------------------------------------------*/
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
|
||
|
DWORD dwWin32ExitCode,
|
||
|
DWORD dwWaitHint)
|
||
|
/* */
|
||
|
/* 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 */
|
||
|
/* */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
static DWORD dwCheckPoint = 1;
|
||
|
BOOL fResult = TRUE;
|
||
|
|
||
|
/* when debugging we don't report to the SCM */
|
||
|
if(G_SlpdCommandLine.action != SLPD_DEBUG)
|
||
|
{
|
||
|
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)))
|
||
|
{
|
||
|
SLPDLog("SetServiceStatus failed");
|
||
|
}
|
||
|
}
|
||
|
return fResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
|
||
|
/* */
|
||
|
/* PURPOSE: copies error message text to string */
|
||
|
/* */
|
||
|
/* PARAMETERS: */
|
||
|
/* lpszBuf - destination buffer */
|
||
|
/* dwSize - size of buffer */
|
||
|
/* */
|
||
|
/* RETURN VALUE: */
|
||
|
/* destination buffer */
|
||
|
/* */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
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');
|
||
|
sprintf( lpszBuf, "%s (0x%x)", lpszTemp, GetLastError() );
|
||
|
}
|
||
|
|
||
|
if(lpszTemp)
|
||
|
{
|
||
|
LocalFree((HLOCAL) lpszTemp );
|
||
|
}
|
||
|
|
||
|
return lpszBuf;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
void ServiceStop()
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
G_SIGTERM = 1;
|
||
|
ReportStatusToSCMgr(SERVICE_STOPPED, /* service state */
|
||
|
NO_ERROR, /* exit code */
|
||
|
3000); /* wait hint */
|
||
|
}
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
void ServiceStart (int argc, char **argv)
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
fd_set readfds;
|
||
|
fd_set writefds;
|
||
|
int highfd;
|
||
|
int fdcount = 0;
|
||
|
time_t curtime;
|
||
|
time_t alarmtime;
|
||
|
struct timeval timeout;
|
||
|
WSADATA wsaData;
|
||
|
WORD wVersionRequested = MAKEWORD(1,1);
|
||
|
|
||
|
/*------------------------*/
|
||
|
/* Service initialization */
|
||
|
/*------------------------*/
|
||
|
if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state*/
|
||
|
NO_ERROR, /* exit code */
|
||
|
3000)) /* wait hint */
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
if(WSAStartup(wVersionRequested, &wsaData) != 0)
|
||
|
{
|
||
|
(void)ReportStatusToSCMgr(SERVICE_STOP_PENDING,
|
||
|
NO_ERROR,
|
||
|
0);
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
/*------------------------*/
|
||
|
/* Parse the command line */
|
||
|
/*------------------------*/
|
||
|
if(SLPDParseCommandLine(argc,argv))
|
||
|
{
|
||
|
ReportStatusToSCMgr(SERVICE_STOP_PENDING, /* service state */
|
||
|
NO_ERROR, /* exit code */
|
||
|
0); /* wait hint */
|
||
|
goto cleanup_winsock;
|
||
|
}
|
||
|
if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state */
|
||
|
NO_ERROR, /* exit code */
|
||
|
3000)) /* wait hint */
|
||
|
{
|
||
|
goto cleanup_winsock;
|
||
|
}
|
||
|
|
||
|
/*------------------------------*/
|
||
|
/* Initialize the log file */
|
||
|
/*------------------------------*/
|
||
|
if(SLPDLogFileOpen(G_SlpdCommandLine.logfile, 1))
|
||
|
{
|
||
|
SLPDLog("Could not open logfile %s\n",G_SlpdCommandLine.logfile);
|
||
|
goto cleanup_winsock;
|
||
|
}
|
||
|
|
||
|
/*------------------------*/
|
||
|
/* Seed the XID generator */
|
||
|
/*------------------------*/
|
||
|
SLPXidSeed();
|
||
|
|
||
|
/*---------------------*/
|
||
|
/* Log startup message */
|
||
|
/*---------------------*/
|
||
|
SLPDLog("****************************************\n");
|
||
|
SLPDLogTime();
|
||
|
SLPDLog("SLPD daemon started\n");
|
||
|
SLPDLog("****************************************\n");
|
||
|
SLPDLog("Command line = %s\n",argv[0]);
|
||
|
SLPDLog("Using configuration file = %s\n",G_SlpdCommandLine.cfgfile);
|
||
|
SLPDLog("Using registration file = %s\n",G_SlpdCommandLine.regfile);
|
||
|
if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state */
|
||
|
NO_ERROR, /* exit code */
|
||
|
3000)) /* wait hint */
|
||
|
{
|
||
|
goto cleanup_winsock;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------*/
|
||
|
/* Initialize for the first time */
|
||
|
/*--------------------------------------------------*/
|
||
|
if(SLPDPropertyInit(G_SlpdCommandLine.cfgfile) ||
|
||
|
SLPDDatabaseInit(G_SlpdCommandLine.regfile) ||
|
||
|
SLPDIncomingInit() ||
|
||
|
SLPDOutgoingInit() ||
|
||
|
SLPDKnownDAInit())
|
||
|
{
|
||
|
SLPDLog("slpd initialization failed\n");
|
||
|
goto cleanup_winsock;
|
||
|
}
|
||
|
SLPDLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces);
|
||
|
SLPDLog("Agent URL = %s\n",G_SlpdProperty.myUrl);
|
||
|
|
||
|
/* Service is now running, perform work until shutdown */
|
||
|
|
||
|
if(!ReportStatusToSCMgr(SERVICE_RUNNING, /* service state */
|
||
|
NO_ERROR, /* exit code */
|
||
|
0)) /* wait hint */
|
||
|
{
|
||
|
goto cleanup_winsock;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*-----------*/
|
||
|
/* Main loop */
|
||
|
/*-----------*/
|
||
|
SLPDLog("Startup complete entering main run loop ...\n\n");
|
||
|
G_SIGTERM = 0;
|
||
|
curtime = time(&alarmtime);
|
||
|
alarmtime = curtime + SLPD_AGE_INTERVAL;
|
||
|
while(G_SIGTERM == 0)
|
||
|
{
|
||
|
/*--------------------------------------------------------*/
|
||
|
/* Load the fdsets up with all valid sockets in the list */
|
||
|
/*--------------------------------------------------------*/
|
||
|
highfd = 0;
|
||
|
FD_ZERO(&readfds);
|
||
|
FD_ZERO(&writefds);
|
||
|
LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds);
|
||
|
LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds);
|
||
|
|
||
|
/*--------------------------------------------------*/
|
||
|
/* Before select(), check to see if we got a signal */
|
||
|
/*--------------------------------------------------*/
|
||
|
if(G_SIGALRM)
|
||
|
{
|
||
|
goto HANDLE_SIGNAL;
|
||
|
}
|
||
|
|
||
|
/*-------------*/
|
||
|
/* Main select */
|
||
|
/*-------------*/
|
||
|
timeout.tv_sec = SLPD_AGE_INTERVAL;
|
||
|
timeout.tv_usec = 0;
|
||
|
fdcount = select(highfd+1,&readfds,&writefds,0,&timeout);
|
||
|
if(fdcount > 0) /* fdcount will be < 0 when timed out */
|
||
|
{
|
||
|
SLPDIncomingHandler(&fdcount,&readfds,&writefds);
|
||
|
SLPDOutgoingHandler(&fdcount,&readfds,&writefds);
|
||
|
}
|
||
|
|
||
|
/*----------------*/
|
||
|
/* Handle signals */
|
||
|
/*----------------*/
|
||
|
HANDLE_SIGNAL:
|
||
|
curtime = time(&curtime);
|
||
|
if(curtime >= alarmtime)
|
||
|
{
|
||
|
HandleSigAlrm();
|
||
|
alarmtime = curtime + SLPD_AGE_INTERVAL;
|
||
|
}
|
||
|
|
||
|
} /* End of main loop */
|
||
|
|
||
|
/* Got SIGTERM */
|
||
|
HandleSigTerm();
|
||
|
|
||
|
cleanup_winsock:
|
||
|
WSACleanup();
|
||
|
|
||
|
cleanup:
|
||
|
;
|
||
|
}
|
||
|
|
||
|
/*==========================================================================*/
|
||
|
BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
|
||
|
/* */
|
||
|
/* PURPOSE: Handled console control events */
|
||
|
/* */
|
||
|
/* PARAMETERS: */
|
||
|
/* dwCtrlType - type of control event */
|
||
|
/* */
|
||
|
/* RETURN VALUE: */
|
||
|
/* True - handled */
|
||
|
/* False - unhandled */
|
||
|
/* */
|
||
|
/*==========================================================================*/
|
||
|
{
|
||
|
switch(dwCtrlType)
|
||
|
{
|
||
|
case CTRL_BREAK_EVENT: /* use Ctrl+C or Ctrl+Break to simulate */
|
||
|
case CTRL_C_EVENT: /* SERVICE_CONTROL_STOP in debug mode */
|
||
|
printf("Stopping %s.\n", G_SERVICEDISPLAYNAME);
|
||
|
ServiceStop();
|
||
|
return TRUE;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*==========================================================================*/
|
||
|
VOID WINAPI ServiceCtrl(DWORD dwCtrlCode)
|
||
|
/* */
|
||
|
/* PURPOSE: This function is called by the SCM whenever */
|
||
|
/* ControlService() is called on this service. */
|
||
|
/* */
|
||
|
/* PARAMETERS: */
|
||
|
/* dwCtrlCode - type of control requested */
|
||
|
/* */
|
||
|
/* RETURN VALUE: */
|
||
|
/* none */
|
||
|
/* */
|
||
|
/*==========================================================================*/
|
||
|
{
|
||
|
/* Handle the requested control code. */
|
||
|
/* */
|
||
|
|
||
|
switch(dwCtrlCode)
|
||
|
{
|
||
|
/* Stop the service. */
|
||
|
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(ssStatus.dwCurrentState, NO_ERROR, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*==========================================================================*/
|
||
|
void WINAPI SLPDServiceMain(DWORD argc, LPTSTR *argv)
|
||
|
/*==========================================================================*/
|
||
|
{
|
||
|
|
||
|
/* register our service control handler: */
|
||
|
sshStatusHandle = RegisterServiceCtrlHandler( G_SERVICENAME, ServiceCtrl);
|
||
|
|
||
|
if(sshStatusHandle != 0)
|
||
|
{
|
||
|
/* SERVICE_STATUS members that don't change */
|
||
|
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 */
|
||
|
{
|
||
|
ServiceStart(argc, argv);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* try to report the stopped status to the service control manager. */
|
||
|
|
||
|
if(sshStatusHandle)
|
||
|
(void)ReportStatusToSCMgr(SERVICE_STOPPED,
|
||
|
0,
|
||
|
0);
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
void SLPDCmdInstallService(int automatic)
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
SC_HANDLE schService;
|
||
|
SC_HANDLE schSCManager;
|
||
|
|
||
|
DWORD start_type;
|
||
|
TCHAR szPath[512];
|
||
|
|
||
|
if(GetModuleFileName( NULL, szPath, 512 ) == 0)
|
||
|
{
|
||
|
printf("Unable to install %s - %s\n",
|
||
|
G_SERVICEDISPLAYNAME,
|
||
|
GetLastErrorText(szErr, 256));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(automatic)
|
||
|
{
|
||
|
start_type = SERVICE_AUTO_START;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
start_type = SERVICE_DEMAND_START;
|
||
|
}
|
||
|
|
||
|
schSCManager = OpenSCManager(
|
||
|
NULL, /* machine (NULL == local) */
|
||
|
NULL, /* database (NULL == default) */
|
||
|
SC_MANAGER_ALL_ACCESS); /* access required */
|
||
|
|
||
|
if(schSCManager)
|
||
|
{
|
||
|
schService = CreateService(
|
||
|
schSCManager, /* SCManager database */
|
||
|
G_SERVICENAME, /* name of service */
|
||
|
G_SERVICEDISPLAYNAME, /* name to display */
|
||
|
SERVICE_ALL_ACCESS, /* desired access */
|
||
|
SERVICE_WIN32_OWN_PROCESS, /* service type */
|
||
|
start_type, /* start type */
|
||
|
SERVICE_ERROR_NORMAL, /* error control type */
|
||
|
szPath, /* service's binary */
|
||
|
NULL, /* no load ordering group */
|
||
|
NULL, /* no tag identifier */
|
||
|
"", /* dependencies */
|
||
|
NULL, /* LocalSystem account */
|
||
|
NULL); /* no password */
|
||
|
|
||
|
if(schService)
|
||
|
{
|
||
|
printf("%s installed.\n", G_SERVICEDISPLAYNAME );
|
||
|
CloseServiceHandle(schService);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("CreateService failed - %s\n", GetLastErrorText(szErr, 256));
|
||
|
}
|
||
|
|
||
|
CloseServiceHandle(schSCManager);
|
||
|
}
|
||
|
else
|
||
|
printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
}
|
||
|
|
||
|
static void SLPDHlpStopService(SC_HANDLE schService)
|
||
|
{
|
||
|
/* try to stop the service */
|
||
|
if(ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus))
|
||
|
{
|
||
|
printf("Stopping %s.", G_SERVICEDISPLAYNAME);
|
||
|
Sleep(1000);
|
||
|
|
||
|
while(QueryServiceStatus(schService, &ssStatus))
|
||
|
{
|
||
|
if(ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
|
||
|
{
|
||
|
printf(".");
|
||
|
Sleep(1000);
|
||
|
}
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(ssStatus.dwCurrentState == SERVICE_STOPPED)
|
||
|
printf("\n%s stopped.\n", G_SERVICEDISPLAYNAME);
|
||
|
else
|
||
|
printf("\n%s failed to stop.\n", G_SERVICEDISPLAYNAME);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
void SLPDCmdRemoveService()
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
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, G_SERVICENAME, SERVICE_ALL_ACCESS);
|
||
|
|
||
|
if(schService)
|
||
|
{
|
||
|
SLPDHlpStopService(schService);
|
||
|
|
||
|
/* now remove the service */
|
||
|
if(DeleteService(schService))
|
||
|
printf("%s removed.\n", G_SERVICEDISPLAYNAME );
|
||
|
else
|
||
|
printf("DeleteService failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
|
||
|
|
||
|
CloseServiceHandle(schService);
|
||
|
}
|
||
|
else
|
||
|
printf("OpenService failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
|
||
|
CloseServiceHandle(schSCManager);
|
||
|
}
|
||
|
else
|
||
|
printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
}
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
void SLPDCmdStartService()
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
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, G_SERVICENAME, SERVICE_ALL_ACCESS);
|
||
|
|
||
|
if(schService)
|
||
|
{
|
||
|
if( !StartService(schService, 0, NULL))
|
||
|
{
|
||
|
printf("OpenService failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
}
|
||
|
CloseServiceHandle(schService);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("OpenService failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
}
|
||
|
CloseServiceHandle(schSCManager);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
void SLPDCmdStopService()
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
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, G_SERVICENAME, SERVICE_ALL_ACCESS);
|
||
|
|
||
|
if(schService)
|
||
|
{
|
||
|
SLPDHlpStopService(schService);
|
||
|
CloseServiceHandle(schService);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("OpenService failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
}
|
||
|
CloseServiceHandle(schSCManager);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr,256));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
void SLPDCmdDebugService(int argc, char ** argv)
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
{
|
||
|
printf("Debugging %s.\n", G_SERVICEDISPLAYNAME);
|
||
|
|
||
|
SetConsoleCtrlHandler( ControlHandler, TRUE );
|
||
|
ServiceStart( argc, argv );
|
||
|
}
|
||
|
|
||
|
/*==========================================================================*/
|
||
|
void __cdecl main(int argc, char **argv)
|
||
|
/*==========================================================================*/
|
||
|
{
|
||
|
SERVICE_TABLE_ENTRY dispatchTable[] =
|
||
|
{
|
||
|
{ G_SERVICENAME, (LPSERVICE_MAIN_FUNCTION)SLPDServiceMain},
|
||
|
{ NULL, NULL}
|
||
|
};
|
||
|
|
||
|
/*------------------------*/
|
||
|
/* Parse the command line */
|
||
|
/*------------------------*/
|
||
|
if(SLPDParseCommandLine(argc,argv))
|
||
|
{
|
||
|
SLPDFatal("Invalid command line\n");
|
||
|
}
|
||
|
|
||
|
switch(G_SlpdCommandLine.action)
|
||
|
{
|
||
|
case SLPD_DEBUG:
|
||
|
SLPDCmdDebugService(argc, argv);
|
||
|
break;
|
||
|
case SLPD_INSTALL:
|
||
|
SLPDCmdInstallService(G_SlpdCommandLine.autostart);
|
||
|
break;
|
||
|
case SLPD_REMOVE:
|
||
|
SLPDCmdRemoveService();
|
||
|
break;
|
||
|
case SLPD_START:
|
||
|
SLPDCmdStartService();
|
||
|
break;
|
||
|
case SLPD_STOP:
|
||
|
SLPDCmdStopService();
|
||
|
break;
|
||
|
default:
|
||
|
SLPDPrintUsage();
|
||
|
StartServiceCtrlDispatcher(dispatchTable);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|