Writing a Control Handler Function Example
When a Handler function is called by the dispatcher thread, it handles the control code passed in the Opcode parameter and then calls the ReportSvcStatus function to update the service status. Every time a Handler function receives a control code, it is appropriate to report the service status regardless of whether the service acts on the control. In the following code fragment example, the SvcCtrlHandler() function is an example of a Handler function. Note that the ghSvcStopEvent variable is a global variable that should be initialized and used as demonstrated in Writing a ServiceMain() function.
// Purpose: Called by SCM whenever a control code is sent to the service using the ControlService function
// Parameters: dwCtrl - control code
// Return value: None
void WINAPI SvcCtrlHandler(DWORD dwCtrl)
{
// Handle the requested control code.
switch(dwCtrl)
{
case SERVICE_CONTROL_STOP:
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
// Signal the service to stop
SetEvent(ghSvcStopEvent);
return;
case SERVICE_CONTROL_INTERROGATE:
// Fall through to send current status
break;
default:
break;
}
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
}
Installing a Service Example
A service configuration program uses the CreateService() function to install a service in the SCM database. The SvcInstall() function in the following code fragment example shows how to install a service from the service program itself.
// Purpose: Installs a service in the SCM database
// Parameters: None
// Return value: None
void SvcInstall(void)
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
WCHAR szPath[MAX_PATH];
if(!GetModuleFileName(NULL, szPath, MAX_PATH))
{
wprintf(LCannot install service, error %u\n, GetLastError());
return;
}
else
wprintf(LService was installed successfully!\n);
// Get a handle to the SCM database
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (schSCManager == NULL)
{
wprintf(LOpenSCManager() failed, error %u\n, GetLastError());
return;
}
else
wprintf(LOpenSCManager() is pretty fine!\n);
// Create the service
schService = CreateService(
schSCManager, // SCM database
SVCNAME, // name of service
SVCNAME, // service 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, // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService == NULL)
{
wprintf(LCreateService() failed, error %u\n, GetLastError());
CloseServiceHandle(schSCManager);
return;
}
else
wprintf(LCreateService() is pretty fine!\n);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}