How to Create a Windows NT/Windows 2000 Service

Source: Internet
Author: User

I recently read an article about creating a service program under NT/2000 and translated it as follows to help me understand it. Some of them may not be suitable for translation, I hope my friends who have read this article can help me correct it! (The original post is at the bottom)

A Windows Service Program is an EXE (executable program) specially designed to communicate with the SCM (Service Control Manager) of Windows NT/2000 ). The Service Control Manager (SCM) maintains a database with installed services and driver services, and provides a unified and secure control mode. SCM starts running at computer boot and can be used as a remote process call (PRC) server. As a program developer, when we want to write a simple service program, the program we want to implement is divided into the following four parts.

1. Win32/console main program.
2. a function called servicemain () serves as the main program service and is the entry point of a service.
3. A Service Control Handler completes communication with SCM.
4. A service is used to install/uninstall a function and register EXE as a system service.


First, let's look at the main program of some console applications (it can also be winmain (), Gui Program)


# Include "winsvc. H" // header file for services. (header file used by the Service Program)

Main ()
{
Service_table_entry table [] = {"service1", servicemain}, {null, null }};
Startservicectrldispatcher (table );
}


The only thing the main () function does is to fill in an array such as the service_table_entry structure.


Typedef struct _ service_table_entry {
Lpwstr lpservicename;
Lpservice_main_functionw lpserviceproc;
} Service_table_entry, * lpservice_table_entry;


The element in the array [0] [0] position is the service name (any string name you like ). The name of the element service main function at the position of the array [0] [1]. It was already specified in a list at the beginning. It is actually a function pointer pointing to the main function of the service, and the name of the function pointer can be arbitrary. Now, let's take the first step: Call the startservicectrldispatcher () function using the service_table_entry array. Pay attention to the form of function declaration (I do not know how to translate this sentence ). The element at the [1] [0] position and the element at the [1] [1] position are both null, indicating that this is the end of the array. (Not required), we can add multiple array elements to this list, if we have multiple services to run in one EXE at the same time.


A typical declaration method of servicemain () functions:


Void winapi servicemain (DWORD argc, lptstr * argv)


Now let's take a look at our servicemain () function.
The main steps of this function are as follows:

1. Fill the service_status struct with appropriate values for communication with SCM.
2. register the Service Control Handler, as mentioned above
3. Call the actual processing function


Before proceeding, We need to declare two global variables here:


Service_status m_servicestatus;
Service_status_handle m_servicestatushandle;


The servicemain () function can receive command line parameters, just like any c ++ main () function. The first parameter indicates the number of parameters that will be passed to the service. Here there is always at least one parameter (that is, the name of the application ). The second parameter is the pointer to the string pointer array. The first pointer element in the array always points to the service name. The service_status data structure is used to fill the status of the current service and report it to SCM. We can use the API function setservicestatus () to complete the above work. Service_status data members can be set to the following values:


Dwservicetype = service_win32;
Dwcurrentstate = service_start_pending; // means trying to start (initially)
Dwcontrolsaccepted = service_accept_stop; // accepts stop/start only in Service Control Program. usually in the control panel (NT)/Administrator tools (2000 ). we can also set our service to accept pause and continue functionality also.


At the beginning of servicemain (), we should set dwcurrentstate in the service_status structure to service_start_pending. This is to inform SCM (our) that the service is about to start running. If any errors occur during use, we should set service_stopped to notify SCM. By default, SCM will look for an activity from the service (the activity does not know how to translate here). If the activity does not show any progress within two minutes, SCM will kill it.


The API function registerservicectrlhandler () is a service used to set the Service Control Handler to SCM. This function previously had two parameters: a service name (string) and a pointer to the Service Control Handler. Service Control Handler functions must be declared in advance.


Once we get there, we can now set dwcurrentstate to service_running to notify the service that execution has started. The next task is to call the actual processing process.


Now let's analyze our service control processing functions together

This service control processing function is used to complete the communication between SCM and (our) service programs. For example, a user's operations on the service, such, start, stop, pause, or continue. It basically contains interactive statements that process all situations. Here, we will call the appropriate steps to clean up and terminate the process. This function receives an operation code with the following values: service_control_pause, service_control_continue, service_control_stop, and service_control_interrogate. We need to write every step as appropriate.


Service installer/uninstaller

To install a service, we need to make some entries in the system registry. Windows has some API functions to do this, instead of using the registry functions. These API functions are createservice () and deleteservice (). For these two functions, we need to have the appropriate permissions to open the SCM database. I prefer SC _manager_all_access. To install a service, you must first open SCM through openscmanager (null, null, SC _manager_all_access), and then call createservice () using the path of the executable file of our service (), here we must also give the name of our service. We need this name if we want to delete a special service. When deleting a service, we first need to open a specific service through the service name, and then call deleteservice () for it (). This is what we need. For more details, see the code.


Thank you

Anish c. v.


The original article is as follows:


How to Create a Windows NT/Windows 2000 Service


A Windows Service is an EXE specially designed to communicate with the SCM (Service Control Manager) of Windows NT/2000. the Service Control Manager (SCM) maintains a database of installed services and driver services, and provides a unified and secure means of controlling them. SCM is started at system boot and it is a Remote Procedure Call (RPC) server. as a developer to try a simple service, we can divide the program in to four parts.

1. Main Program of Win 32/console application.
2. a so called servicemain (), main program of service. Entry point of a service.
3. A Service Control Handler, a function to communicate with SCM.
4. A service installer/uninstaller, to register an EXE as a service.


Firstly let us take a look at the main program of the console application (it can also be a winmain ()).

# Include "winsvc. H" // header file for services.

Main ()
{
Service_table_entry table [] = {"service1", servicemain}, {null, null }};
Startservicectrldispatcher (table );
}

The only thing done by the main () is to fill a service_table_entry array. the position [0] [0] contains the name of the service (any string you like ). position [0] [1] contains the name of the Service main function, I specified in the list earlier. it actually is a function pointer to the service main function. the name can be any thing. now we start the first step to a service by calling startservicectrldispatcher () with the service_table_entry array. note that the function signature shocould be of the form. the [1] [0] and [1] [1] positions are null, just to say the end of the array. (not a must ). we can add more entries to the list if we have more than one service running from the same exe.

The declaration of a typical servicemain ()

Void winapi servicemain (DWORD argc, lptstr * argv)

Now let us analyze our servicemain function.

The main steps of this function are
 
1. Fill the service_status structure with appropriate values to communicate with the SCM.
2. register the Service Control Handler function said earlier in the list.
3. Call the actual processing functions.


For proceeding we need two global variables here.

Service_status m_servicestatus;
Service_status_handle m_servicestatushandle;

The servicemain () can accept command line arguments just as any c ++ main () function. the first parameter contains the number of arguments being passed to the service. there will always be at least one argument. the second parameter is a pointer to an array of string pointers. the first item in the array always points to the service name. the service_status data structure is used to fill the current state of the service and has y it to the SCM. we use an API function setservicestatus () for the purpose. the data members of service_status to look for are


Dwservicetype = service_win32;
Dwcurrentstate = service_start_pending; // means trying to start (initially)
Dwcontrolsaccepted = service_accept_stop; // accepts stop/start only in Service Control Program. usually in the control panel (NT)/Administrator tools (2000 ). we can also set our service to accept pause and continue functionality also.


In the beginning of the servicemain () We shoshould set the dwcurrentstate of service_status to service_start_pending. this signals the SCM that the service is starting. if any error occurs in the way we shoshould handle y the SCM by passing service_stopped. by default the SCM will look for an activity from the service and if it fails to show any progress with in 2 minutes SCM kills that service.


The API function registerservicectrlhandler () is used to set the Service Control Handler function of the service with the SCM. the function takes two parameters as earlier, one service name (string) and the pointer to the Service Control Handler function. that function shocould with the signature.


Once we get till here we now set dwcurrentstate as service_running to running y that the service has started to function. The next step is to call the actual processing steps.


Now let us analyze our Service Control Handler Function

The Service Control Handler function is used by the SCM to communicate to the service program about a user action on the service like a start, stop, pause or continue. it basically contains a switch statement to deal with each case. here we will call appropriate steps to clean up and terminate the process. this function has es an opcode which can have values like service_control_pause, service_control_continue, service_control_stop, service_control_interrogate, etc. we have to write appropriate steps on each.


Now service installer/uninstaller

For installing a service we need to make some entries in the system registry. windows has some API's to do these steps, instead of using the registry functions. they are createservice () and deleteservice (). for both these functions we need to open the SCM database with appropriate rights. I prefer SC _manager_all_access. for installing a service first open the SCM by openscmanager (null, null, SC _manager_all_access ). then invoke the createservice () with appropriate binary file path of our service. here also we have to give the name of our service. we need this name if we want to delete a special service. in deleting a service we need to open the specific service first by its name and then invoke the deleteservice () on it. that's all what we need. take a look at the code given with it for more details.


Thank you

Anish c. v.


Http://www.codeguru.com/Cpp/W-P/system/ntservices/article.php/c5701/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.