summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2009-03-28 11:33:16 +0100
committerAndreas Baumann <abaumann@yahoo.com>2009-03-28 11:33:16 +0100
commite81b985ddc74ea3584deb08e513d92c1621aff1c (patch)
treeda7fa4e6faddc8dd585131f09848c864b05a6611 /docs
parenta6f2b7dab1f4efde7952e8b8ee3f3f50bcf63753 (diff)
downloadwolfbones-e81b985ddc74ea3584deb08e513d92c1621aff1c.tar.gz
wolfbones-e81b985ddc74ea3584deb08e513d92c1621aff1c.tar.bz2
more service documentation
Diffstat (limited to 'docs')
-rw-r--r--docs/service/ModuleDD.txt646
-rw-r--r--docs/service/README6
2 files changed, 650 insertions, 2 deletions
diff --git a/docs/service/ModuleDD.txt b/docs/service/ModuleDD.txt
new file mode 100644
index 0000000..24df0d5
--- /dev/null
+++ b/docs/service/ModuleDD.txt
@@ -0,0 +1,646 @@
+
+
+ MODULE DD
+
+ WINDOWS SERVICES
+
+ Part 1: STORY
+
+
+
+What we have in this Module?
+
+ 1. Windows Services Story
+ 2. Service Control Manager (SCM)
+ 3. Database of Installed Services
+ 4. Automatically Starting Services
+ 5. Starting Services on Demand
+ 6. Stopping Services
+ 7. Service Record List
+ 8. SCM Handles
+ 9. Service Programs
+ 10. Service Entry Point
+ 11. Service ServiceMain Function
+ 12. Service Control Handler Function
+ 13. Receiving Events in a Service
+
+
+ [INS: [INS:
+
+ IFRAME: [6]google_ads_frame
+
+ :INS] :INS]
+
+
+ [INS: [INS:
+
+ IFRAME: [7]google_ads_frame
+
+ :INS] :INS]
+
+ My Training Period: xx hours. Before you begin, read some
+ [8]instruction here.
+
+
+ Abilities:
+ * Able to understand the Windows services concepts.
+ * Able to understand the Service Control Manager (SCM).
+ * Able to use the Windows Task Manager and Services snap-in.
+ * Able to understand the security aspects of Windows services.
+
+Windows Services Story
+
+
+ There are two Windows service types:
+
+
+ 1. Service application and
+ 2. Driver service.
+
+
+ A service application conforms to the interface rules of the Service
+ Control Manager (SCM). It can be started:
+
+
+ 1. Automatically at system boot.
+ 2. By a user through the Services control panel applet or
+ 3. By an application that uses the service functions.
+
+
+ Services can execute even when no user is logged on to the system. For
+ normal applications such as your word processor program, we need to
+ manually launch the program or automatically start it through the
+ program Startup setting. A driver service conforms to the device driver
+ protocols. It is similar to a service application, but it does not
+ interact with the SCM. For simplicity, here, the term service refers to
+ a service application. The following is the Services control panel that
+ can be launched through Services menu:
+
+
+ Start -> Programs -> Administrative Tools -> Services. To manage or
+ control any service, you can select the service -> right click your
+ mouse -> select Properties context menu.
+
+
+ You can also access the Services through the Control Panel: Start ->
+ Settings -> Control Panel. Notice at the bottom of the Services snap-in
+ there are Extended and Standard view. (Tenouk's Windows XP Pro)
+
+
+ Controlling Windows Services through Services snap-in
+
+
+ The following is a service property page for Windows Automatic Update
+ service.
+
+
+ Controlling Windows Services: Service property page
+
+
+ The running services (processes) can be seen through the Task Manager
+ as shown in the following figure.
+
+
+ Controlling Windows Services through Task Manager
+
+
+ The SCM maintains a database of installed services and driver services,
+ and provides a unified and secure means of controlling them. The
+ database includes information on how each service or driver service
+ should be started. It also enables system administrators to customize
+ security requirements for each service and thereby control access to
+ the service. The following types of programs use the functions provided
+ by the SCM.
+
+
+ Type
+
+ Description
+
+ Service program
+
+ A program that provides executable code for one or more services.
+ Service programs use functions that connect to the SCM and send status
+ information to the SCM.
+
+ Service configuration program
+
+ A program that queries or modifies the services database. Service
+ configuration programs use functions that open the database, install or
+ delete services in the database, and query or modify the configuration
+ and security parameters for installed services. Service configuration
+ programs manage both services and driver services.
+
+ Service control program
+
+ A program that starts and controls services and driver services.
+ Service control programs use functions that send requests to the SCM,
+ which carries out the request.
+
+
+ Table 1
+
+
+Service Control Manager
+
+
+ The SCM is started at system boot. It is a remote procedure call (RPC)
+ server, so that service configuration and service control programs can
+ manipulate services on remote machines. The service functions provide
+ an interface for the following tasks performed by the SCM:
+ 1. Maintaining the database of installed services.
+ 2. Starting services and driver services either upon system startup or
+ upon demand.
+ 3. Enumerating installed services and driver services.
+ 4. Maintaining status information for running services and driver
+ services.
+ 5. Transmitting control requests to running services.
+ 6. Locking and unlocking the service database.
+
+
+Database of Installed Services
+
+
+ The SCM maintains a database of installed services in the registry. The
+ database is used by the SCM and programs that add, modify, or configure
+ services. The following is the registry key for this database.
+
+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
+
+ This key contains a subkey for each installed service and driver
+ service. The name of the subkey is the name of the service, as
+ specified by the CreateService() function when the service was
+ installed by a service configuration program. An initial copy of the
+ database is created when the system is installed. The database contains
+ entries for the device drivers required during system boot. The
+ database includes the following information about each installed
+ service and driver service:
+ 1. The service type. This indicates whether the service executes in
+ its own process or shares a process with other services. For driver
+ services, this indicates whether the service is a kernel driver or
+ a file system driver.
+ 2. The start type. This indicates whether the service or driver
+ service is started automatically at system startup (auto-start
+ service) or whether the SCM starts it when requested by a service
+ control program (demand-start service). The start type can also
+ indicate that the service or driver service is disabled, in which
+ case it cannot be started.
+ 3. The error control level. This specifies the severity of the error
+ if the service or driver service fails to start during system
+ startup and determines the action that the startup program will
+ take.
+ 4. The fully qualified path of the executable file. The filename
+ extension is .exe for services and .sys for driver services.
+ 5. Optional dependency information used to determine the proper order
+ for starting services or driver services. For services, this
+ information can include a list of services that the SCM must start
+ before it can start the specified service, the name of a load
+ ordering group that the service is part of, and a tag identifier
+ that indicates the start order of the service in its load ordering
+ group. For driver services, this information includes a list of
+ drivers that must be started before the specified driver.
+ 6. For services, an optional account name and password. The service
+ program runs in the context of this account. If no account is
+ specified, the service executes in the context of the LocalSystem
+ account.
+ 7. For driver services, an optional driver object name (for example,
+ \FileSystem\Rdr or \Driver\Xns), used by the I/O system to load the
+ device driver. If no name is specified, the I/O system creates a
+ default name based on the driver service name.
+
+
+ Note: This database is also known as the ServicesActive database or
+ the SCM database. You must use the functions provided by the SCM,
+ instead of modifying the database directly.
+
+
+Automatically Starting Services
+
+
+ During system boot, the SCM starts all auto-start services and the
+ services on which they depend (service dependency). For example, if an
+ auto-start service depends on another demand-start service, the
+ demand-start service is also started automatically. The load order is
+ determined by the following:
+
+
+ 1. The order of groups in the load ordering group list,
+ ServiceGroupOrder, in the following [9]registry key:
+
+ HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
+
+ 2. The order of services within a group specified in the tags order
+ vector, GroupOrderList, in the following [10]registry key:
+
+ HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
+
+ 3. The dependencies listed for each service.
+
+
+ When the boot is complete, the system executes the boot verification
+ program specified by BootVerificationProgram value of the following
+ [11]registry key:
+
+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
+
+ By default, this value is not set. The system simply reports that the
+ boot was successful after the first user has logged on. You can supply
+ a boot verification program that checks the system for problems and
+ reports the boot status to the SCM using the NotifyBootConfigStatus()
+ function. After a successful boot, the system saves a clone of the
+ database in the last-known-good (LKG) configuration. The system can
+ restore this copy of the database if changes made to the active
+ database cause the system reboot to fail. The following is the
+ [12]registry key for this database:
+
+ HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX\Services
+
+ Where XXX is the value saved in the following [13]registry key value:
+
+ HKEY_LOCAL_MACHINE\System\Select\LastKnownGood.
+
+ If an auto-start service with a SERVICE_ERROR_CRITICAL error control
+ level fails to start, the SCM reboots the machine using the LKG
+ configuration. If the LKG configuration is already being used, the boot
+ fails.
+
+
+Starting Services on Demand
+
+
+ The user can start a service with the Services control panel utility.
+ The user can specify arguments for the service in the Start parameters
+ field. A service control program can start a service and specify its
+ arguments with the StartService() function. When the service is
+ started, the SCM performs the following steps:
+
+
+ 1. Retrieve the account information stored in the database.
+ 2. Log on the service account.
+ 3. Create the service in the suspended state.
+ 4. Assign the logon token to the process.
+ 5. Allow the process to execute.
+
+
+ [INS: [INS:
+
+ IFRAME: [14]google_ads_frame
+
+ :INS] :INS]
+
+Stopping Services
+
+
+ The user can stop a service with the Services control panel utility. A
+ service control program can stop a service with the ControlService()
+ function, by sending a SERVICE_CONTROL_STOP request to the service
+ through the SCM. If the SCM receives a SERVICE_CONTROL_STOP request for
+ a service, it instructs the service to stop by forwarding the stop code
+ on to the service's ServiceMain() function. However, if the SCM
+ determines that other services that are running are dependent on the
+ specified service, it does not forward the stop request. Instead, it
+ returns the ERROR_DEPENDENT_SERVICES_RUNNING error code. To
+ programmatically stop a service with dependent services, you must first
+ enumerate and stop its dependent services.
+
+
+Service Record List
+
+
+ As each service entry is read from the database of installed services,
+ the SCM creates a service record for the service. A service record
+ includes:
+ 1. Service name.
+ 2. Start type (auto-start or demand-start).
+ 3. Service status (see the SERVICE_STATUS structure)
+ 4. Type.
+ 5. Current state.
+ 6. Acceptable control codes.
+ 7. Exit code.
+ 8. Wait hint.
+ 9. Pointer to dependency list.
+
+
+ The user name and password of an account are specified at the time the
+ service is installed. The SCM stores the user name in the registry and
+ the password in a secure portion of the Local Security Authority (LSA).
+ The system administrator can create accounts with passwords that never
+ expire. Alternatively, the system administrator can create accounts
+ with passwords that expire and manage the accounts by changing the
+ passwords periodically. The SCM keeps two copies of a user account's
+ password, a current password and a backup password. The password
+ specified the first time the service is installed is stored as the
+ current password and the backup password is not initialized. When the
+ SCM attempts to run the service in the security context of the user
+ account, it uses the current password. If the current password is used
+ successfully, it is also saved as the backup password. If the password
+ is modified with the ChangeServiceConfig() function, or the Services
+ control panel utility, the new password is stored as the current
+ password and the previous password is stored as the backup password. If
+ the SCM attempts to start the service and the current password fails,
+ then it uses the backup password. If the backup password is used
+ successfully, it is saved as the current password. The SCM updates the
+ service status when a service sends it status notifications using the
+ SetServiceStatus() function. The SCM maintains the status of a driver
+ service by querying the I/O system, instead of receiving status
+ notifications, as it does from a service. A service can register
+ additional type information by calling the SetServiceBits() function.
+ The NetServerGetInfo() and NetServerEnum() functions obtain the
+ supported service types.
+
+
+SCM Handles
+
+
+ The SCM supports handle types to allow access to the following objects.
+ 1. The database of installed services.
+ 2. A service.
+ 3. The database lock.
+
+
+ An SCManager object represents the database of installed services. It
+ is a container object that holds service objects. The OpenSCManager()
+ function returns a handle to an SCManager object on a specified
+ computer. This handle is used when installing, deleting, opening, and
+ enumerating services and when locking the services database. A service
+ object represents an installed service. The CreateService() and
+ OpenService() functions return handles to installed services. The
+ OpenSCManager(), CreateService(), and OpenService() functions can
+ request different types of access to SCManager and service objects. The
+ requested access is granted or denied depending on the access token of
+ the calling process and the security descriptor associated with the
+ SCManager or service object.
+
+ The CloseServiceHandle() function closes handles to SCManager and
+ service objects. When you no longer need these handles, be sure to
+ close them. A lock object is created during SCM initialization to
+ serialize access to the database of installed services. The SCM
+ acquires the lock before starting a service or driver service. Service
+ configuration programs use the LockServiceDatabase() function to
+ acquire the lock before reconfiguring a service and use the
+ UnlockServiceDatabase() function to release the lock.
+
+
+Service Programs
+
+
+ A service program contains executable code for one or more services. A
+ service created with the type SERVICE_WIN32_OWN_PROCESS only contains
+ the code for one service. A service created with the type
+ SERVICE_WIN32_SHARE_PROCESS contains code for more than one service,
+ enabling them to share code. A service can be configured to execute in
+ the context of a user account from either the built-in (local),
+ primary, or trusted domain. It can also be configured to run in a
+ special service user account. The following topics describe the
+ interface requirements of the SCM that a service program must include
+ and additional programming considerations. These sections do not apply
+ to driver services.
+ 1. Service Entry Point.
+ 2. Service ServiceMain() Function
+ 3. Service Control Handler Function.
+
+
+Service Entry Point
+
+
+ Services are generally written as console applications. The entry point
+ of a console application is its main function. The main function
+ receives arguments from the ImagePath value from the registry key for
+ the service. When the SCM starts a service program, it waits for it to
+ call the StartServiceCtrlDispatcher() function. You can use the
+ following guidelines.
+ 1. A service of type SERVICE_WIN32_OWN_PROCESS should call
+ StartServiceCtrlDispatcher() immediately, from its main thread. You
+ can perform any initialization after the service starts.
+ 2. If the service type is SERVICE_WIN32_SHARE_PROCESS and there is
+ common initialization for all services in the program, you can
+ perform the initialization in the main thread before calling
+ StartServiceCtrlDispatcher(), as long as it takes less than 30
+ seconds. Otherwise, you must create another thread to do the common
+ initialization, while the main thread calls
+ StartServiceCtrlDispatcher(). You should still perform any
+ service-specific initialization after the service starts.
+
+
+ The StartServiceCtrlDispatcher() function takes a SERVICE_TABLE_ENTRY
+ structure for each service contained in the process. Each structure
+ specifies the service name and the entry point for the service. If
+ StartServiceCtrlDispatcher() succeeds, the calling thread does not
+ return until all running services in the process have terminated. The
+ SCM sends control requests to this thread through a named pipe. The
+ thread acts as a control dispatcher, performing the following tasks:
+
+ IFRAME: [15]google_ads_frame
+
+ 1. Create a new thread to call the appropriate entry point when a new
+ service is started.
+ 2. Call the appropriate handler function to handle service control
+ requests.
+
+
+Service ServiceMain Function
+
+
+ When a service control program requests that a new service run, the SCM
+ starts the service and sends a start request to the control dispatcher.
+ The control dispatcher creates a new thread to execute the
+ ServiceMain() function for the service. The ServiceMain() function
+ should perform the following tasks:
+
+
+ 1. Call the RegisterServiceCtrlHandlerEx() function immediately to
+ register a HandlerEx() function to handle control requests for the
+ service. The return value of RegisterServiceCtrlHandlerEx() is a
+ service status handle that will be used in calls to notify the SCM
+ of the service status.
+ 2. Perform initialization. If the execution time of the initialization
+ code is expected to be very short (less than one second),
+ initialization can be performed directly in ServiceMain().
+
+
+ If the initialization time is expected to be longer than one second,
+ call the SetServiceStatus() function, specifying the
+ SERVICE_START_PENDING service state and a wait hint in the
+ SERVICE_STATUS structure. As initialization continues, the service
+ should make additional calls to SetServiceStatus() to report progress.
+ Sending multiple SetServiceStatus() calls is useful for debugging
+ services.
+
+
+ 3. When initialization is complete, call SetServiceStatus(),
+ specifying the SERVICE_RUNNING state in the SERVICE_STATUS
+ structure.
+ 4. Perform the service tasks, or, if there are no pending tasks,
+ return. Any change in the state of the service warrants a call to
+ SetServiceStatus() to report new status information.
+ 5. If an error occurs while the service is initializing or running,
+ the service should call SetServiceStatus(), specifying the
+ SERVICE_STOP_PENDING state in the SERVICE_STATUS structure, if
+ cleanup will be lengthy. Once cleanup is complete, call
+ SetServiceStatus() from the last thread to terminate, specifying
+ SERVICE_STOPPED in the SERVICE_STATUS structure. Be sure to set the
+ dwServiceSpecificExitCode and dwWin32ExitCode members of the
+ SERVICE_STATUS structure to identify the error.
+
+
+Service Control Handler Function
+
+
+ Each service has a control handler, the HandlerEx() function, that is
+ invoked by the control dispatcher when the service process receives a
+ control request from a service control program. Therefore, this
+ function executes in the context of the control dispatcher. Whenever
+ HandlerEx() is invoked, the service must call the SetServiceStatus()
+ function to report its status to the SCM. This must be done regardless
+ of whether the status changed. The service control program can send
+ control requests using the ControlService() function. All services must
+ accept and process the SERVICE_CONTROL_INTERROGATE control code. You
+ can enable or disable acceptance of the other control codes by calling
+ SetServiceStatus(). To receive the SERVICE_CONTROL_DEVICEEVENT control
+ code, you must call the RegisterDeviceNotification() function. Services
+ can also handle additional user-defined control codes.
+
+ The control handler must return within 30 seconds, or the SCM will
+ return an error. If a service needs to do lengthy processing when the
+ service is executing the control handler, it should create a secondary
+ thread to perform the lengthy processing, and then return. This
+ prevents the service from tying up the control dispatcher. For example,
+ when handling the stop request for a service that will take a long
+ time, create another thread to handle the stop process. The control
+ handler should simply call SetServiceStatus() with the
+ SERVICE_STOP_PENDING message and return.
+
+ When the user shuts down the system, all control handlers that have
+ called SetServiceStatus() with the SERVICE_ACCEPT_SHUTDOWN control code
+ receive the SERVICE_CONTROL_SHUTDOWN control code. They are notified in
+ the order that they appear in the database of installed services. By
+ default, a service has approximately 20 seconds to perform cleanup
+ tasks before the system shuts down. After this time expires, system
+ shutdown proceeds regardless of whether service shutdown is complete.
+ Note that if the system is left in the shutdown state (not restarted or
+ powered down), the service continues to run.
+
+ If the service needs more time to clean up, it sends STOP_PENDING
+ status messages, along with a wait hint, so the service controller
+ knows how long to wait before reporting to the system that service
+ shutdown is complete. However, there is a limit to how long the service
+ controller will wait, to prevent a service from stopping shutdown. To
+ change this time limit, modify the WaitToKillServiceTimeout value in
+ the following [16]registry key:
+
+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
+
+ Note that during service shutdown, the SCM does not take dependencies
+ into consideration. The SCM enumerates the list of running services and
+ sends the SERVICE_CONTROL_SHUTDOWN command. Therefore, a service may
+ fail because another service it depends on has already stopped.
+ [INS: [INS:
+
+ IFRAME: [17]google_ads_frame
+
+ :INS] :INS]
+
+
+Receiving Events in a Service
+
+
+ A service that is a console application can register a console control
+ handler to receive notification when a user logs off. However, there is
+ no event sent when an interactive user logs on. To determine whether an
+ interactive user is logged on, verify that the process specified in the
+ following [18]key is running:
+
+ HKEY_LOCAL_MACHINE\SOFTWARE\
+
+ Microsoft\
+
+ Windows NT\
+
+ CurrentVersion\
+
+ Winlogon
+
+ This process is started when an interactive user logs onto a system.
+ Therefore, if this process is running, there is an interactive user
+ logged on. The system broadcasts device change events to all services.
+ These events can be received by a service in a window procedure or in
+ its service control handler. To specify which events your service
+ should receive, use the RegisterDeviceNotification() function.
+
+ Be sure to handle Plug and Play device events as quickly as possible.
+ Otherwise, the system may become unresponsive. If your event handler is
+ to perform an operation that may block execution (such as I/O), it is
+ best to start another thread to perform the operation asynchronously.
+ When a service calls RegisterDeviceNotification(), the service also
+ specifies either a window handle or a service status handle. If a
+ service specifies a window handle, the window procedure receives the
+ notification events. If a service specifies its service status handle,
+ its service control handler receives the notification events. Device
+ notification handles returned by RegisterDeviceNotification() must be
+ closed by calling the UnregisterDeviceNotification() function when they
+ are no longer needed.
+
+
+
+ Further reading and digging:
+
+
+ 1. Structure, enum, union and typedef story can be found [19]C/C++
+ struct, enum, union & typedef.
+ 2. For Multibytes, Unicode characters and Localization please refer to
+ [20]Locale, wide characters & Unicode (Story) and [21]Windows users
+ & groups programming tutorials (Implementation).
+ 3. Windows data types are [22]Windows data types.
+ 4. [23]Microsoft Visual C++, online MSDN.
+ 5. [24]Check the best selling C / C++ and Windows books at Amazon.com.
+
+
+
+ [INS: [INS:
+
+ IFRAME: [25]google_ads_frame
+
+ :INS] :INS]
+
+ |< [26]Dynamic Link Library, DLL 4 | [27]Main | [28]Windows Services
+ Programming 2 >| [29]Site Index | [30]Download |
+ __________________________________________________________________
+
+ [31][comment.png] 2003-2009 © Tenouk. All rights reserved.
+
+ [32]web page hit counter
+
+References
+
+ 1. http://www.tenouk.com/ModuleCC2.html
+ 2. http://www.tenouk.com/cnwin32tutorials.html
+ 3. http://www.tenouk.com/ModuleDD1.html
+ 4. http://www.tenouk.com/Sitemap.html
+ 5. http://www.tenouk.com/download.html
+ 6. file://localhost/home/abaumann/ModuleDD_files/ads.html
+ 7. file://localhost/home/abaumann/ModuleDD_files/ads_002.html
+ 8. http://www.tenouk.com/visualcpluscompilerinstruction.html
+ 9. http://www.tenouk.com/ModuleO.html
+ 10. http://www.tenouk.com/ModuleO.html
+ 11. http://www.tenouk.com/ModuleO.html
+ 12. http://www.tenouk.com/ModuleO.html
+ 13. http://www.tenouk.com/ModuleO.html
+ 14. file://localhost/home/abaumann/ModuleDD_files/ads_003.html
+ 15. file://localhost/home/abaumann/ModuleDD_files/ads_004.html
+ 16. http://www.tenouk.com/ModuleO.html
+ 17. file://localhost/home/abaumann/ModuleDD_files/ads_005.html
+ 18. http://www.tenouk.com/ModuleO.html
+ 19. http://www.tenouk.com/Module11.html
+ 20. http://www.tenouk.com/ModuleG.html
+ 21. http://www.tenouk.com/ModuleM.html
+ 22. http://www.tenouk.com/ModuleC.html
+ 23. http://msdn.microsoft.com/visualc/
+ 24. http://www.tenouk.com/cplusbook.html
+ 25. file://localhost/home/abaumann/ModuleDD_files/ads_006.html
+ 26. http://www.tenouk.com/ModuleCC2.html
+ 27. http://www.tenouk.com/cnwin32tutorials.html
+ 28. http://www.tenouk.com/ModuleDD1.html
+ 29. http://www.tenouk.com/Sitemap.html
+ 30. http://www.tenouk.com/download.html
+ 31. http://www.tenouk.com/comment.html
+ 32. http://www.statcounter.com/
diff --git a/docs/service/README b/docs/service/README
index 704f704..de62560 100644
--- a/docs/service/README
+++ b/docs/service/README
@@ -12,8 +12,10 @@ The normal foreground mode in the console should also be possible
and act on events:
Good links:
-- http://www.codeproject.com/KB/winsdk/console_event_handling.aspx: how
- to handle the events in foreground/console mode
+- console_event_handling.txt: how to handle the events in foreground/
+ console mode
- the Sphynx searchd.cpp: especially service description, console events
- POCO: on some design questions
- Microsoft Knowledge Base: best source as always
+- ModuleDD.txt: good introduction to the history of Windows services
+ and how they work