The Service Structure

Now, it is time to consider the service structure and describe several API functions used for controlling services.

From the operating system's point of view, the service has the standard structure of the executable module. However, it starts in a way different from the standard one and has the following three distinct parts :

  • Main function of the processIts starting point specifies the normal starting address of the program. In the applications that will be presented and described further in this chapter, the starting address is labeled by the START label. In the easiest case, only the call to the startServiceCtrlDispatcher function must be placed here. This function registers services and starts the service control dispatcher for controlling all services. No, this is not a misprintwithin a single program, there may be several services representing normal functions. Each of these functions will be started by the dispatcher in its own thread. The only parameter of the StartServiceCtrlDispatcher function is the address of the array consisting of the following pairs: the service name and its entry point (address). This array must be terminated by two zeros (see the program presented in Listing 21.1).

  • Procedures or logical services specified using the StartServiceCtrlDispatcher functionThese must contain the following three components :

    • The call to the RegisterServiceCtrlHandler function registers the command handler procedure for this logical service.

    • The call to the SetServiceStatus function sets the service status started .

    • The actions, for which this logical service is intended, must be carried out. As mentioned before, some services are active and running from operating system startup to shutdown, but other services are started only for short periods. A logical service can start any number of threads. After the service carries out its functions and terminates its operation, it again must call the SetServiceStatus function to set its status to stopped .

  • Commands handlerThe service control dispatcher communicates with the handler, instructing it, for example, to stop the running service or to send the message on the service status.

Well, that's all that you need to know about the service structure. Now, it is necessary to describe the API functions used for working with services.

The StartServiceCtrlDispatcher function was already briefly described. In the next section, an example illustrating its use will be provided.

The RegisterServiceCtrlHandler function registers the command handler procedure. It returns the procedure handle. The function receives the following parameters:

  • First parameterThis is the address of the logical service name.

  • Second parameterThis is the address of the command handler procedure.

The SetServiceStatus function sets the service status. It accepts the following parameters:

  • First parameterThis is the handle to the command processing procedure.

  • Second parameterThis is the pointer to the structure consisting of seven 32-bit fields. These fields, briefly, are as follows :

    • The first field specifies the type of service. The default value is SERVICE_WIN32_OWN_PROCESS = 10h , which means that the service will operate as an individual process.

    • The second field defines the state of the service. For example, the value SERVICE_RUNNING = 4h means that the service has started.

    • The third field determines, which commands must be processed by the service. There are several constants, which can be combined using the OR operation to form the value of this field (see Listing 21.1).

    • The fourth field defines the error code the service uses to report an error that occurs when it is starting or stopping. Usually, this field is assumed to be zero.

    • The fifth field contains a service-specific error code. It is used if the previous field is not set to zero.

    • The sixth field must be periodically incremented when carrying out lengthy operations. In all other cases, it must be zero.

    • The seventh field must contain estimated the time required, in milliseconds , for a pending start, stop, pause, or continue operation. If the value of the second or sixth field doesn't change when the estimated period elapses, the system will assume that an error has occurred.

The preceding functions are required functions, which must be present in the service program. In the simplest case, the command handler will contain only the SetServiceStatus function, using which the service status will be determined depending on the received command. The structure of all components of a service will be presented in Listing 21.1.

However, the previously described API functions are not sufficient to make the service operate. To achieve this, the service must already be registered in the services database, which is Stored under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services key of the system registry. Only after that can the service start. Often, a separate program is used for registering the service in the services database. This approach is the one chosen for the program presented in Listing 21.1. However, most services are organized so that the operations carried out over the service depend on the command-line parameters.

Consider how the service is registered in the system registry. To achieve this, it is first necessary to open the services database, which is a part of system registry.

The OpenSCManager function opens the services database. It accepts several parameters.

  • First parameterThis is the name of the network workstation where the database that you want to open is located. If you want to open local registry, this parameter is set to zero.

  • Second parameterThis is the address of the services database name. To open the default services database, this parameter must be set to zero.

  • Third parameterThis parameter defines the required type of access. Usually, the SC_MANAGER_ALL_ACCESS = 0F003Fh constant is used for providing full access.

If the function completes successfully, it returns the database handle. If the database has been opened successfully, then, after carrying out all required operations, it must be closed. For this purpose, use the closeServiceHandle function whose only parameter is the service database handle.

To register the service in the service database, use the CreateService API function. This function has the following 13 parameters:

  • First parameterThe service database handle (see the description of the OpenSCManager function).

  • Second parameterThis is the address of the string that contains the name of one of the logical services, by which it will be possible to access that service. Thus, for each logical service it is necessary to call the CreateService function. The service will appear in the system registry under this name. This name also allows the service to be accessed programmatically.

  • Third parameterThis defines the so-called display name.

  • Fourth parameterPossible type of access to the service. In the example provided later in this chapter, the SERVICE_ALL_ACCESS = 0F01FFH (full access) value is used.

  • Fifth parameterType of service. In the example provided in this chapter, the SERVICE_WIN32_OWN_PROCESS = 10h constant is used.

  • Sixth parameterService startup type. In the example provided in this chapter, the SERVICE_DEMAND_START = 3 constant is used, which means that the service can be started on demand. It is also possible to use other constants, for example, SERVICE_BOOT_START = 0 , which means that the service must be started at system startup.

  • Seventh parameterThis defines the level of reaction to possible errors. The default value is SERVICE_ERROR_NORMAL = 1 .

  • Eighth parameterThis is the pointer to the string that contains the name of the service program. The name must specify the full path (e.g., D:\masm32\ BIN\mt.exe). The EXE filename extension is not necessary.

  • Ninth parameterThere are several groups of services in the operating system. These groups are loaded in a predefined order. If your service must be loaded only after specific services, it is necessary to specify the address of the service group name, to which your service will belong. The list of service group names can be found in Windows documentation. If loading order is not important, this parameter is set to zero.

  • Tenth parameterIt always must be zero because it is used only for drivers (see Chapter 27 for more details).

  • 11th parameterThis defines services or groups of services, on which your service depends. It must point to the array composed of names of services and service groups. This array must be terminated by two zeros.

  • 12th parameterThis parameter specifies the user account name, which must be used for starting the service. By default, this parameter is assumed to be zero, because it is supposed that the service will start as LocalSystem .

  • 13th parameterThe password of the account used by the service to log on to the system (see parameter 12). If the 12th parameter is set to zero, the 13th parameter must also be set to zero.

Now, consider the procedures required to start the service programmatically. Note that the service must previously be registered using the CreateService function. The order of operations is as follows:

  1. Open the services database using the OpenSCManager function.

  2. Open the service using the OpenService function.

  3. Start the service using the StartService function.

  4. Close the services database.

Now, consider some functions not described yet. The OpenService function accepts three parameters:

  • First parameterThe handle to the services database.

  • Second parameterThis parameter defines the name of the service to be opened. This name must correspond to the name, under which the service was previously registered in the system registry.

  • Third parameterThis parameter defines the level of access to the service. Usually, the SC_MANAGER_ALL_ACCESS value is used (for removing the service, the DELETE constant can be used).

The StartService , like the previous function, also accepts three parameters. The first parameter is the handle returned by the OpenService function. The second and third parameters are parameters passed to the service. Usually, these values are assumed to be zero, which means that this feature is not used.

Finally, it is necessary to consider another important aspect of service programminghow to programmatically delete the service from the system registry. To achieve this, it is necessary to carry out the following operations.

  1. Open the services database.

  2. Open the required service.

  3. If this service is started, it must be stopped before deletion. This can be achieved using the Controlservice function. If the service is not running, nothing bad will happen.

  4. Delete the service from the registry using the DeleteService function.

  5. Close the services database.

Now, it is time to describe functions that have not been covered yet The Controlservice function has three parameters:

  • First parameterThe handle to the service.

  • Second parameterThe command sent to the service. This command will be passed to the command handler. For example, to stop the service, it is necessary to set this parameter to SERVICE_CONTROL_STOP = 1 .

  • Third parameterThe address of the string containing the internal service name.

The DeleteService function accepts only one parameterthe handle to the previously opened service.



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net