The main() Function
The new main() function, which is called by the SCM, has the task of registering the service with the SCM and starting the service control dispatcher. This requires a call to the StartServiceCtrlDispatcher function with the name(s) and entry point(s) of one or more logical services.
BOOL StartServiceCtrlDispatcher (
LPSERVICE_TABLE_ENTRY lpServiceStartTable)
The single parameter, lpServiceStartTable, is the address of an array of SERVICE_TABLE_ENTRY items, where each item is a logical service name and entry point. The end of the array is indicated by a pair of NULL entries.The return is trUE if the registration was successful. Errors, which can be processed in the usual way, will occur if the service is already running or if there is a problem updating the registry (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services).The main thread of the service process that calls StartServiceCtrlDispatcher connects the thread to the SCM. The SCM registers the service with the calling thread as the service control dispatcher thread. The SCM does not return to the calling thread until all services have terminated. Notice, however, that the logical services are not actually started at this time; starting the service requires the StartService function, which is described later in the chapter.Program 13-1 shows a typical service main program with a single logical service.
Program 13-1. main: The Main Service Entry Point
#include "EvryThng.h"
void WINAPI ServiceMain (DWORD argc, LPTSTR argv []);
static LPTSTR ServiceName = _T ("SocketCommandLineService");
/* Main routine that starts the service control dispatcher. */
VOID _tmain (int argc, LPTSTR argv [])
{
SERVICE_TABLE_ENTRY DispatchTable [] =
{
{ ServiceName, ServiceMain },
{ NULL, NULL }
};
if (!StartServiceCtrlDispatcher (DispatchTable))
ReportError (_T ("Failed to start srvc ctrl dis."), 1, TRUE);
/* ServiceMain () will not run until started by the SCM. */
/* Return here only when all services have terminated. */
return;
}
