Windows System Programming Third Edition


The Service Control Handler



Download 3.41 Mb.
Page19/31
Date31.07.2017
Size3.41 Mb.
#24970
1   ...   15   16   17   18   19   20   21   22   ...   31

The Service Control Handler


The service control handler, the callback function specified in RegisterServiceCtrlHandlerEx, has the following form:

DWORD WINAPI HandlerEx (

DWORD dwControl,

DWORD dwEventType,

LPVOID lpEventData,

LPVOID lpContext)

The dwControl parameter indicates the actual control signal sent by the SCM that should be processed. Prior to NT5 and the introduction of RegisterServiceCtrlHandlerEx, this was the handler's only parameter.

There are 14 possible values for dwControl, including the controls mentioned in Table 13-3, although some controls are supported only on NT5 or XP. Five control values of interest in the example are listed here:

SERVICE_CONTROL_STOP

SERVICE_CONTROL_PAUSE

SERVICE_CONTROL_CONTINUE

SERVICE_CONTROL_INTERROGATE

SERVICE_CONTROL_SHUTDOWN

User-defined values in the range 128255 are also permitted but will not be used here.

dwEventType is usually 0, but nonzero values are used for device management, which is out of scope for this book. lpEventData provides additional data required by some of these events.

Finally, lpContext is user-defined data passed to RegisterServiceCtrlHandlerEx when the handler was registered.

The handler is invoked by the SCM in the same thread as the main program, and the function is usually written as a switch statement. This is shown in the examples.

Example: A Service "Wrapper"


Program 13-2 carries out the serverSK conversion discussed previously. The conversion to a service depends on carrying out all the tasks described earlier. The existing server code, with some very minor modifications, is placed in a function, ServiceSpecific. Therefore, the code shown here is essentially a wrapper around an existing server program whose entry point has been changed from main to ServiceSpecific.

Another addition, not shown here but included on the book's Web site, is the use of a log file because services frequently run "headless" without an interactive console. When a log file is specified on the command to ServiceMain, significant events will be logged to that file.


Program 13-2. SimpleService: A Service Wrapper

/* Chapter 13. serviceSK.c

serverSK modified to be a Windows service.

This is, however, a general-purpose wrapper. */
#include "EvryThng.h"

#include "ClntSrvr.h"

#define UPDATE_TIME 1000 /* One second between updates. */
VOID LogEvent (LPCTSTR, DWORD, BOOL);

void WINAPI ServiceMain (DWORD argc, LPTSTR argv []);

VOID WINAPI ServerCtrlHandlerEx(DWORD, DWORD, LPVOID, LPVOID);

void UpdateStatus (int, int); /* Calls SetServiceStatus. */

int ServiceSpecific (int, LPTSTR *); /* Former main program. */

volatile static BOOL ShutDown = FALSE, PauseFlag = FALSE;

static SERVICE_STATUS hServStatus;

static SERVICE_STATUS_HANDLE hSStat; /* Handle to set status. */


static LPTSTR ServiceName = _T ("SocketCommandLineService");

static LPTSTR LogFileName = _T ("CommandLineServiceLog.txt");


/* Main routine that starts the service control dispatcher. */

VOID _tmain (int argc, LPTSTR argv [])

{

SERVICE_TABLE_ENTRY DispatchTable [] =



{

{ ServiceName, ServiceMain },

{ NULL, NULL }

};
StartServiceCtrlDispatcher (DispatchTable);

return 0;

}
/* ServiceMain entry point, called when the service is created. */

void WINAPI ServiceMain (DWORD argc, LPTSTR argv [])

{

DWORD i, Context = 1;



/* Set the current directory and open a log file, appending to

an existing file. */


/* Set all server status data members. */

hServStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

hServStatus.dwCurrentState = SERVICE_START_PENDING;

hServStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |

SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;

hServStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIF0C_ERROR;

hServStatus.dwServiceSpecificExitCode = 0;

hServStatus.dwCheckPoint = 0;

hServStatus.dwWaitHint = 2 * CS_TIMEOUT;
hSStat = RegisterServiceCtrlHandlerEx (ServiceName,

ServerCtrlHandler, &Context);

SetServiceStatus (hSStat, &hServStatus);
/* Start service-specific work; generic work is complete. */

if (ServiceSpecific (argc, argv) != 0) {

hServStatus.dwCurrentState = SERVICE_STOPPED;

hServStatus.dwServiceSpecificExitCode = 1;

/* Server initialization failed. */

SetServiceStatus (hSStat, &hServStatus);

return;

}

/* We will only return here when the ServiceSpecific function



completes, indicating system shutdown. */

UpdateStatus (SERVICE_STOPPED, 0);

return;

}
void UpdateStatus (int NewStatus, int Check)



/* Set a new service status and checkpoint --

either specific value or increment. */

{

if (Check < 0) hServStatus.dwCheckPoint++;



else hServStatus.dwCheckPoint = Check;

if (NewStatus >= 0) hServStatus.dwCurrentState = NewStatus;

SetServiceStatus (hSStat, &hServStatus);

return;


}
/* Control handler function, invoked by the SCM to run */

/* in the same thread as the main program. */

/* The last three parameters are not used, and the pre-NT5 */

/* handlers would also work in this example. */

VOID WINAPI ServerCtrlHandlerEx (DWORD Control, DWORD EventType,

LPVOID lpEventData, LPVOID lpContext)

{

switch (Control) {



case SERVICE_CONTROL_SHUTDOWN:

case SERVICE_CONTROL_STOP:

ShutDown = TRUE; /* Set the global shutdown flag. */

UpdateStatus (SERVICE_STOP_PENDING, -1);

break;

case SERVICE_CONTROL_PAUSE:



PauseFlag = TRUE; /* Interrogated periodically. */

break;


case SERVICE_CONTROL_CONTINUE:

PauseFlag = FALSE;

break;

case SERVICE_CONTROL_INTERROGATE:



break;

default:


if (Control > 127 && Control < 256) /* User defined. */

break;


}

UpdateStatus (-1, -1); /* Increment checkpoint. */

return;

}
/* This is the service-specific function, or "main," and is



called from the more generic ServiceMain.

In general, you can take any server, such as ServerNP.c, and

rename "main" as "ServiceSpecific"; putting code right here.

But some changes are required to update status. */


int ServiceSpecific (int argc, LPTSTR argv [])

{

UpdateStatus (-1, -1); /* Increment the checkpoint. */



/* ... Initialize system ... */

/* Be sure to update the checkpoint periodically. */


return 0;

}


Directory: bitstream -> NAU
bitstream -> A mathematical theory of communication
bitstream -> Images of Fairfax in Modern Literature and Film Andrew Hopper
bitstream -> Amphitheater High School’s Outdoor Classroom: a study in the Application of Design
bitstream -> Ethics of Climate Change: Adopting an Empirical Approach to Moral Concern
bitstream -> The Age of Revolution in the Indian Ocean, Bay of Bengal and South China Sea: a maritime Perspective
bitstream -> Methodism and Culture
bitstream -> Review of coastal ecosystem management to improve the health and resilience of the Great Barrier Reef World Heritage Area
bitstream -> Present state of the area
NAU -> International significance of icao alphabet for flight safety
NAU -> Performance comparison of android runtime and dalvik environments on an android device

Download 3.41 Mb.

Share with your friends:
1   ...   15   16   17   18   19   20   21   22   ...   31




The database is protected by copyright ©ininet.org 2024
send message

    Main page