Essay Assist
SPREAD THE LOVE...

The Service Control Manager (SCM) is a core component of Windows that provides a centralized way to control and communicate with services running in the system. It maintains a database of installed services and their status and handles requests to start, stop, pause and resume services automatically or on-demand. For any application to run as a service and take advantage of the SCM’s management features, it needs to register itself with the SCM by providing some basic metadata and functionality. This involves writing a service control manager entry for the application.

In this article, we will discuss the process of writing an entry for the Service Control Manager in Windows. This will allow an application to integrate with the SCM and run as a managed service. We will look at the key steps, data structures and API functions involved. By the end, you will know how to package up an application to run as a Windows service.

SERVICE DATABASE ENTRY

When registering a service with the SCM, the first thing that needs to be provided is a SERVICE_TABLE_ENTRY structure. This contains pointers to the main service handler functions that the SCM will call to start, stop and pause/resume the service. It also contains a name that uniquely identifies the service.

The SERVICE_TABLE_ENTRY structure is defined as:

typedef struct _SERVICE_TABLE_ENTRY{
LPTSTR lpServiceName;
LPSERVICE_MAIN_FUNCTION lpServiceProc;
} SERVICE_TABLE_ENTRY, *LPSERVICE_TABLE_ENTRY;

Read also:  SAMPLE ORDERS ESSAY WRITING SOCIETY

lpServiceName is a string pointer to the name that will identify the service. This needs to follow certain naming conventions like no spaces or special characters.

lpServiceProc points to the main function that implements the service control handler callbacks. It needs to have the following prototype:

VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv);

This function is called by the SCM when actions occur on the service like start, stop etc. It provides the entry point for the service to run and receive control requests.

To register a service, you need to define a SERVICE_TABLE_ENTRY object and pass it to the StartServiceCtrlDispatcher function along with the number of services being registered. For example:

SERVICE_TABLE_ENTRY ServiceTable[] =
{
{ L”MyTestService”, ServiceMain },
{ NULL, NULL }
};

StartServiceCtrlDispatcher(ServiceTable);

This registers the “MyTestService” with the SCM and sets ServiceMain as the handler callback function. StartServiceCtrlDispatcher will run as a system thread that monitors for service control requests and dispatches them to this function.

SERVICE STATUS & CONTROL HANDLER

When the ServiceMain callback gets invoked, it needs to implement the actual service logic based on the control code parameter. The ServiceStatus object is used to periodically report back status to the SCM.

The key data structures involved are:

SERVICE_STATUS
Used to report status back to SCM. It contains fields like current state, wait hint, process id etc.

SERVICE_STATUS_PROCESS
Extends SERVICE_STATUS to also return the main process id if running as a process service.

Read also:  MOST COMMON ERRORS IN ESSAY WRITING

DWORD ControlCode
Passed to ServiceMain to indicate service control action – START, STOP, PAUSE etc.

A typical ServiceMain function implementation would be:

VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
SERVICE_STATUS serviceStatus;
DWORD ControlCode;

// Initialize status
serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;

// Report initial status to SCM
SetServiceStatus(hServiceStatus, &serviceStatus);

while(1)
{
// Wait for service control requests
ControlCode = WaitForSingleObject(
hServiceStopEvent,
INFINITE);

ebnf
Copy
switch(ControlCode)
{
case SERVICE_CONTROL_STOP:
// Stop any running service tasks
// Change status
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(hServiceStatus, &serviceStatus);

// Complete stopping service work
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &serviceStatus);

return;

case SERVICE_CONTROL_PAUSE:

// Handle pause/resume requests

case SERVICE_CONTROL_CONTINUE:

case SERVICE_CONTROL_INTERROGATE:

case SERVICE_CONTROL_SHUTDOWN:

default:
break;
}

// Maintain service operation
ProcessServiceRequests();

// Report running status periodically
serviceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hServiceStatus, &serviceStatus);

}
}

This implements the basic start, stop handling and status reporting expected of a service. It loops wait for control requests and branches based on the code received from SCM.

SERVICE STARTUP & INSTALLATION

For the service to start automatically during system boot, some additional registration steps are required during installation.

The SCM database maintained in the registry contains details of all registered services – executable path, start parameters, dependencies etc.

During installation, the following keys need to be configured under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services{ServiceName}:

ImagePath – Path to the service executable
Type – SERVICE_WIN32_OWN_PROCESS
Start – SERVICE_AUTO_START
ErrorControl – SERVICE_ERROR_NORMAL

Optionally a DisplayName can also be provided for administrative tools.

Read also:  WEBSITE DEVELOPMENT CONTENT WRITING

Setting the Start value to SERVICE_AUTO_START tells the SCM to automatically start the service during boot. ErrorControl defines severity of errors reported.

The service’s executable path provided in ImagePath should match what’s passed to StartServiceCtrlDispatcher.

Finally, the INSTALLERS permission needs to be granted to the service’s executable to allow it automatic startup privileges:

sc.exe sdset “MyTestService” D:(A;;CCLCSWLOCRRC;;;AU)

Now when the system boots, SCM will find the service registered in its database, start the executable and pass control requests to its ServiceMain function. This achieves running the application as a managed Windows service.

MANAGING RUNNING SERVICES

Once a service is registered and running, it can be administrated using common SCM tools:

sc.exe – Command line service control utility

sc start/stop servicename
sc query servicename

Services MMC snap-in (services.msc) – GUI management console

These allow controlling service startup type, starting/stopping instances, and monitoring runtime status. The Event Viewer service logs can provide diagnostic information.

Some key best practices when writing services include:

Implement graceful shutdown handling
Use declarative auto-reset events for synchronisation
Independent startup to avoid dependencies
Log to Application event log
Restrict permissions of service account
Release resources during stop notifications

Following these guidelines helps build robust and manageable Windows services using the Service Control Manager APIs. Proper registration with SCM allows applications to take advantage of its centralized service management features.

Leave a Reply

Your email address will not be published. Required fields are marked *