Troubleshooting System Services


Starting, Stopping, Disabling, and Resuming Services

The most common tasks associated with managing services are starting, stopping, and disabling a service, and changing the startup method to manual. For example, you might need to start a service in order to use certain server-based applications, or you might need to stop or pause a service in order to perform testing or to troubleshoot a problem.

You can perform the following actions either locally or remotely by using the Services snap-in:

  • Start a service. Right-click the name of the service, and then click Properties. On the General tab, click Start. Only services with a startup type of Automatic or Manual can be started; disabled services cannot.
  • Disable a service. Right-click the name of the service, and then click Properties. On the General tab, in the Startup type list, click Disabled. Disabling a service is useful for troubleshooting problems with a computer.
  • Stop a service. Right-click the name of the service, and then click Properties. On the General tab, click Stop. Note that some services do not allow themselves to be stopped after they are started. The Event Log service, for example, stops only when the computer shuts down.
  • Pause or resume a service. Right-click the name of the service, and then click Properties. On the General tab, click Pause. To resume the service, click Resume.
  • Restart a service. Right-click the name of a running or paused service, and then click Properties. On the General tab, click Resume. Restarting a service causes the snap-in to stop the service and then start the service. This is simply a convenience feature; it can be very useful when you are debugging your own service.

Configuring General Service Properties

The Services snap-in can be used to reconfigure a service. To reconfigure a service, open the Services snap-in, right-click the service, and then click Properties. The Properties dialog box contains four tabs; each tab allows you to reconfigure parts of the selected service. Use the General tab to examine and reconfigure general information about a service.

A service is identified by two string names: an internal name (service name) used for programmatic purposes and a display name (a string that is presented to administrators and users). After being added to the computer’s service database, a service’s internal name cannot be altered.

The administrator can change the startup type to one of the following:

Automatic: If a service’s startup type is Automatic, the SCM spawns the service when the operating system is restarted. Automatic services run before any user interactively logs on to the computer. In fact, many computers are set up only to run services; no one ever logs on to the computer interactively.

Manual. If a service’s startup type is Manual, the SCM does not start the service when the computer is restarted. An administrator can start the service manually by using a service control program such as Sc.exe or Net.exe; this is essentially an explicit call to StartService. A manual service, otherwise known as a demand-start service, will also start when another service that depends on the manual service is started.

Disabled. If a service’s startup type is Disabled, the SCM does not start the service under any circumstance. For example, you disable the DHCP Client service when you manually assign an IP address to your computer rather than have it dynamically obtain an IP address from a computer running the DHCP Server service. Disabling a service is also quite useful when you are troubleshooting a system because it allows you to isolate a certain variable or service as a problem.

Any attempt to start a disabled service by using the StartService API will fail and the ERROR_SERVICE_DISABLED message will be returned.


Using Command-Line Tools to Manage and Configure Services

Net.exe

In addition to the Services snap-in, Windows ships with three command-line service control programs.

This tool is limited in that it allows you to control only those services residing on the local computer. Using Net.exe, you can start, stop, pause, and continue services.

For example, to stop the Background Intelligent Transfer Service (BITS), type the following at the command prompt:

net stop bits

This command displays the following information:

The Background Intelligent Transfer Service service is stopping.

The Background Intelligent Transfer Service service was stopped successfully.

To start the BITS service, type the following at the command line:

net start bits

This command displays the following information:

The Background Intelligent Transfer Service service is starting.

The Background Intelligent Transfer Service service was started successfully.

 

 


SC.exe

Another service control program is the command-line tool Sc.exe. It is located in the systemroot\System32 folder and implements calls to all of the Windows service control API functions. You can set the parameters to these functions by specifying them on the command line. Sc.exe also displays service status and retrieves the values stored in the status structure fields. The tool also lets you specify the name of a remote computer so that you can call the service API functions or view the service status structures on the remote computer. You can also alter the path to the service by using the Sc.exe tool.

SC Commands

Sc.exe implements calls to all of the Windows service control API functions. It also displays service status and retrieves the values stored in the status structure fields. The tool also allows you to specify the name of a remote computer so that you can call the service API functions to view the service status structures on the remote computer.

 

Sc.exe command

Sc.exe command description

Query

Queries the status for a service or enumerates the status for types of services.

Queryex

Queries the extended status for a service or enumerates the status for types of services.

Start

Starts a service.

Pause

Sends a PAUSE control request to a service.

Interrogate

Sends an INTERROGATE control request to a service.

Continue

Sends a CONTINUE control request to a service.

Stop

Sends a STOP request to a service.

Config

Changes the configuration of a service (persistent).

Description

Changes the description of a service.

Failure

Changes the actions taken by a service when it fails.

Qc

Queries the configuration information about a service.

Qdescription

Queries the description of a service.

Qfailure

Queries the actions taken by a service when it fails.

Delete

Deletes a service from the registry.

Create

Creates a service and adds it to the registry.

Control

Sends a control to the service.

Sdshow

Displays a service’s security descriptor.

Sdset

Sets a service’s security descriptor.

GetDisplayName

Gets the DisplayName for the service.

GetKeyName

Gets the ServiceKeyName for a service.

EnumDepend

Enumerates service dependencies.

Boot

Indicates whether the last boot should be saved as the Last Known Good configuration.

Lock

Locks the SCM database.

QueryLock

Queries the LockStatus for the SCM database.

 

      


Detecting Services That Stop Responding

Determining that a service has stopped responding, or has “hung,” can be very difficult. If a service stops responding in any state except SERVICE_STOPPED, the Services snap-in and Net.exe report its state as running. For example, if a service stops responding when it is in the SERVICE_STOP_PENDING state, the net start command reports the status as running and the Services snap-in reports it as stopped.

If you attempt to start a service after it has stopped responding in the SERVICE_STOP_PENDING or SERVICE_START_PENDING state, Net.exe tells you that the service is already running.

To find out accurately all the services that are not running on a computer, use the following command:

sc query type= service state= inactive

To find out accurately if a specific service is not running, use the following command:

sc query service name

Services have a tendency to hang in the SERVICE_ START_PENDING state. For example, you can determine if a service has stopped responding if a service is hung on start or hung in the SERVICE_START_PENDING state, and not responding to its Handler(Ex) routine.

Services can hang in the SERVICE_RUNNING state if the service locks up or takes too long while processing a service control.

Services also have a tendency to hang in the SERVICE_STOP_PENDING state if there are problems with the service shutdown logic and the service never calls SetServiceStatus (SERVICE_STOPPED) as a result.

Sometimes a service appears to be hung because the SCM is waiting for a service to change its state. The SCM waits for a service to start in two cases:

  • The service is being automatically started (versus explicitly demand-started from a StartService call).
  • The service is being started by the SCM because StartService was called for a service that depends on it.

In both cases, the SCM will wait 80 seconds plus the service’s wait hint (specified by the service in its most recent SetServiceStatus call) for the service to change its state from SERVICE_START_PENDING or for the service to call SetServiceStatus again with an updated checkpoint.

If the service takes longer to start than the SCM’s total wait, the SCM marks the service as failed (hung on start), logs an event, EVENT_SERVICE_START_HUNG, and moves on. This event is logged only if the service error level is not ignored. If the service error is ignored, you will see a message box the next time Windows starts. Because SCM does not stop such a hung service, you can use Sc.exe to look for services that remain in the SERVICE_START_PENDING state and determine which services are not responding.

If the service calls SetServiceStatus at some point during that interval and specifies an updated checkpoint (the dwCheckPoint field in the SERVICE_STATUS structure), the SCM resets its wait hint time. An updated checkpoint is the service’s way of telling the SCM that it is still in the SERVICE_START_PENDING state but is making progress.

The wait hint time can be detected through the dwWaitHint field of the SERVICE_STATUS structure passed in. You can verify the value of the WAIT_HINT during the START_PENDING state. For example, to query the WAIT_HINT of a hung service, type the following at the command line:

sc query service

where service is the service that is not responding. The wait hint is valid only when the service is in its SERVICE_START_PENDING state.

For example, to find the wait hint of the BITS service when it is not responding, type the following at the command line:

sc start bits

This command gives you the following information:

SERVICE_NAME: bits

        TYPE               : 20 WIN32_SHARE_PROCESS

        STATE              : 2 START_PENDING

                                (NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)

        WIN32_EXIT_CODE    : 0  (0x0)

        SERVICE_EXIT_CODE : 0  (0x0)

        CHECKPOINT         : 0x0

        WAIT_HINT          : 0x7d0

        PID                : 636

        FLAGS              :

 

The state is set to SERVICE_START_PENDING and the wait hint is set to 0x7d0, or 2,000 milliseconds.


Analyzing Service Failures

A service failure occurs when the service process exits unexpectedly rather than simply failing to respond. A service can have optional FailureActions and FailureCommand entries in its registry subkey that the SCM records during the service’s startup. The SCM registers with the operating system so that the operating system signals the SCM when a service process exits. When a service process stops unexpectedly, the SCM determines which services ran in the process and takes the recovery steps specified by their failure-related registry entries.

The actions or recovery steps that a service can configure for the SCM to carry out include restarting the service, running a program, and restarting the computer. Furthermore, a service can specify the failure actions that take place the first time the service process fails, the second time, and subsequent times. It can also indicate a delay period that the SCM waits before initiating the actions after the service process fails. You can easily manage the recovery actions for a service on the Recovery tab of the service’s Properties dialog box in the Services snap-in, or by using the sc failure and sc qfailure commands.


Querying Service Configuration

The sc qc service name command queries the configuration information for the service. Administrators can use this command to determine the binary name of any service and find out if it shares a process with other services. The command lists information about the service configuration from the QUERY_SERVICE_CONFIG structure.

The following sample output shows information displayed by the sc qc service name command, followed by the corresponding field from the QUERY_SERVICE_CONFIG structure.
     

 

TYPE                       dwServiceType

START_TYPE                 dwStartType

ERROR_CONTROL              dwErrorControl

BINARY_PATH_NAME           lpBinaryPathName

LOAD_ORDER_GROUP           lpLoadOrderGroup

TAG                        dwTagId

DISPLAY_NAME               lpDisplayName

DEPENDENCIES               lpDependencies

SERVICE_START_NAME         lpServiceStartName

 

  **   The following example queries the configuration of the service named Background Intelligent Transfer Service.**

**    * sc qc bits***

This command displays the following information:

[SC] GetServiceConfig SUCCESS

SERVICE_NAME: bits

        TYPE               : 20 WIN32_SHARE_PROCESS

        START_TYPE         : 3   DEMAND_START

        ERROR_CONTROL      : 1   NORMAL

        BINARY_PATH_NAME   : C:\WINNT\System32\svchost.exe -k netsvcs

        LOAD_ORDER_GROUP   :

        TAG                : 0

        DISPLAY_NAME       : Background Intelligent Transfer Service

        DEPENDENCIES       : Rpc
        SERVICE_START_NAME : LocalSystem

BITS runs in a shared process. It will not be auto-started. The binary file name is C:\Winnt\System32\Svchost.exe -k netsvcs. This service depends on the Remote Procedure Call (RPC) service, and will run in the LocalSystem security context. Because this command displays the results from a call to QueryServiceConfig, a more detailed explanation of these results can be found in the SDK documentation about QueryService Config.

 

 


Querying Service Status

The sc query command obtains and displays information about a specified service or driver. It also enumerates the status of types of services and drivers. The sc query command displays the contents of the SERVICE_STATUS structure.

The following sample output shows information displayed by the sc query service name command, followed by the corresponding field from the SERVICE_STATUS structure.

TYPE                dwServiceType

STATE               dwCurrentState, dwControlsAccepted

WIN32_EXIT_CODE     dwWin32ExitCode

SERVICE_EXIT_CODE   dwServiceSpecificExitCode

CHECKPOINT          dwCheckPoint

WAIT_HINT           dwWaitHint

 

Using the sc query command after starting the computer will tell you whether an attempt was made to start this service. If the service was started successfully, the WIN32_EXIT_CODE field will contain a zero (0). If the service failed to start when an attempt was made, this field will contain an exit code provided by the service when it was unable to start.

To query the status of the BITS service, type the following at the command line:

**     sc query bits**

This command displays the following information:

SERVICE_NAME: bits

        TYPE               : 20 WIN32_SHARE_PROCESS

        STATE              : 4 RUNNING

                                (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)

        WIN32_EXIT_CODE    : 0  (0x0)

        SERVICE_EXIT_CODE : 0  (0x0)

        CHECKPOINT         : 0x0

        WAIT_HINT          : 0x0

 

To query a service that has not started — for example, the Computer Browser service — type the following at the command line:

***     sc query browser***

This command displays the following information:

SERVICE_NAME: browser

        TYPE               : 20 WIN32_SHARE_PROCESS

        STATE              : 1 STOPPED

                                (NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)

        WIN32_EXIT_CODE    : 1077       (0x435)

        SERVICE_EXIT_CODE : 0  (0x0)

        CHECKPOINT         : 0x0

        WAIT_HINT          : 0x0

 

Notice that there is an exit code for this service, even though it has not yet been run. Typing net helpmsg 1077 at the command line returns the following information for error 1077:

No attempts to start the service have been made since the last boot.

 

The net helpmsg command can be used to display the text for most Windows Server error messages. This particular exit code indicates that this service has not started. Although obvious in this case, this particular exit code is a useful one to look for if you are expecting your service to be auto-started or perhaps when another auto-start service has a dependency on your service.

       


Using the Sc Queryex Command

If you need to query extended information, use the sc queryex command. This will provide all the information from the sc query command, in addition to PID and FLAG info.

The sc queryex command displays the contents of the SERVICE_STATUS structure.

The following sample output shows information displayed by the sc queryex service name command, followed by the corresponding field from the SERVICE_STATUS structure:

TYPE                dwServiceType

STATE               dwCurrentState, dwControlsAccepted

WIN32_EXIT_CODE     dwWin32ExitCode

SERVICE_EXIT_CODE   dwServiceSpecificExitCode

CHECKPOINT          dwCheckPoint

WAIT_HINT           dwWaitHint

PID                 dwProcessID

FLAGS               dwServiceFlags

 

For example, to display PID and FLAGS information, type the following at the command line:

**    * sc queryex bits***

This command displays the following information:

SERVICE_NAME: bits

        TYPE               : 20 WIN32_SHARE_PROCESS

        STATE              : 4 RUNNING

                                (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)

        WIN32_EXIT_CODE    : 0  (0x0)

        SERVICE_EXIT_CODE : 0  (0x0)

        CHECKPOINT         : 0x0

        WAIT_HINT          : 0x0

        PID                : 636

 

        FLAGS              :

       


Forcibly stopping a service which is "STOP_PENDING"

If you have a service that is stuck in a STOP_PENDING state you may find that you're unable to start or stop it. This is where the extended information available in Sc Queryex can be useful.

Since all services have an associated process (though the process may not be obvious at times) one of the useful pieces of extended information is the service PID or Process ID. Once you have discerned the PID of the service you want to stop you can use the Taskkill command to kill the process, putting the service back into a stopped state.

To stop a service using its PID, type the following at the command line :

taskkill /pid pid /F

You should now be able to start the service as normal.


Windows PowerShell

Windows PowerShell® is a task-based command-line shell and scripting language designed especially for system administration. Built on the .NET Framework, Windows PowerShell helps IT professionals and power users control and automate the administration of the Windows operating system and applications that run on Windows.

Built-in Windows PowerShell commands, called cmdlets, let you manage the computers in your enterprise from the command line. Windows PowerShell providers let you access data stores, such as the registry and certificate store, as easily as you access the file system. In addition, Windows PowerShell has a rich expression parser and a fully developed scripting language.  Below are some examples of how to leverage Windows PowerShell to manage system services. 

How to Start a Windows Service - Performance Logs and Alerts

# PowerShell cmdlet to check a service's status
$srvName = "PLA"
$servicePrior = Get-Service $srvName
$srvName + " is now " + $servicePrior.status

How to Stop a Windows Service :

# PowerShell cmdlet to stop the named service "Themes"
 Clear-Host
 $SrvName = "Themes"
$SrvName + " is now " + (Get-Service $SrvName).status
Stop-Service $SrvName
$SrvName + " is now " + (Get-Service $SrvName).status

To restart a service:

# Production restart service
Clear-Host
Restart-Service -name "Themes"
Stop Service - Force Parameter

For more information on Windows PowerShell, please see http://technet.microsoft.com/en-us/library/bb978526.aspx


Setting Service Recovery Options

The Recovery tab in a service’s Properties dialog box enables an administrator to define a set of actions to take in the event of a service failure, in which the service exits while the service is in a state other than stopped. There are three service failure recovery options: first failure, second failure, and subsequent failures. The underlying API allows an unrestricted number of specific failures before the response specified in the Subsequent failures list takes place; however, the Services snap-in only exposes two.

There are four settings available for configuring service recovery options:

  • Take No Action. If this service fails, no action will be taken. This is the default for all services.
  • Restart the Service. If this service fails, the service will be restarted.
  • Run a Program. If this service fails, a program selected by an administrator will run in the service’s context. If this option is selected, the fields under Run program are enabled and additional parameters, such as the program to be run, need to be specified.
  • Restart the Computer. If this service fails, the computer will be restarted. If this option is selected, the Restart Computer Options button is enabled and additional parameters — such as the length of time to wait until the computer is restarted — can be specified. The SCM sends a message to all computers with active sessions connected to the computer before the computer restarts.

Starting Services

The SCM maintains a database of installed services and device drivers in the registry. The database is used by the SCM and programs that add, modify, or configure services. The registry subkey for this database is HKLM\SYSTEM\CurrentControlSet\Services.

This subkey contains a subkey for each installed service and driver. The name of the subkey is the name the service or driver had when the SCM installed it.

An initial copy of the SCM database is created during Windows Server 2003 setup. The database includes all the service-related parameters defined for a service, in addition to fields that track the service’s status. Additionally, the database contains records for the device drivers required during system restart. The Type entries are found in the registry in the service subkeys under the HKLM\SYSTEM\CurrentControlSet\Services subkey.

There are four values that apply to device drivers:

    • 1 (SERVICE_KERNEL_DRIVER)
    • 2 (SERVICE_FILE_SYSTEM_DRIVER)
    • 4 (SERVICE_ADAPTER)
    • 8 (SERVICE_RECOGNIZER_DRIVER)

The value of the Start entry determines if and when the service or driver is loaded during system startup.


Starting Service Processes

When the SCM starts a service process, the following occurs:

  1. The process immediately invokes a service function, StartServiceCtrlDispatcher, which accepts a list of entry points into services, with one entry point for each service in the process. Each entry point is identified by the name of the service the entry point corresponds to.
  2. StartServiceCtrlDispatcher creates a named pipe communications connection to the SCM and then sits in a loop waiting for commands to come through the pipe.
  3. The SCM sends a service-start command each time it starts a service the process owns. For each start command it receives, the function creates a thread, called a service thread, to invoke the starting service’s entry point.
  4. The StartServiceCtrlDispatcher service function waits indefinitely for commands from the SCM and returns control to the process’s main function only when all the process’s service threads have terminated, allowing the service process to clean up resources before exiting.
  5. The first action of a service’s entry point (ServiceMain routine) is to call the RegisterServiceCtrlHandler(Ex) API, which takes a pointer to the service’s Handler(Ex) function. The Handler(Ex) function is designed to receive and handle control messages sent to the service, which are passed along from the SCM.
  6. The StartServiceCtrlDispatcher service function stores the table in local process memory, and the RegisterServiceCtrlHandler finishes populating it with the service’s HandlerEx pointer and SERVICE_STATUS_HANDLE. The service entry point continues initializing the service, which can include allocating memory, creating communications end points, and reading private configuration data from the registry. A convention most services follow is to store their service-specific parameters under a Parameters subkey in their service registry subkey.
  7. While the entry point is initializing the service, it might periodically send status messages to the SCM to indicate how the service’s startup is progressing. After the entry point finishes initialization, a service thread usually sits in a loop waiting for requests from client applications. For example, a Web server would initialize a Transmission Control Protocol (TCP) listen socket and wait for inbound Hypertext Transmission Protocol (HTTP) connection requests.
  8. A service process’s main thread, which invokes and runs inside of StartServiceCtrlDispatcher, receives SCM commands directed at services in the process and uses the table of the services’ handler functions to locate and invoke the service function responsible for responding to a command. SCM commands include stop, pause, resume, interrogate, shut down, and application-defined commands.

Automatically Starting Services

During service initialization, the SCM starts all services that have Start registry entries with a value of 2 (SERVICE_AUTO_START) and the services on which they depend. For example, if services that are automatically started depend on a manually started service, the demand-start service is also started automatically. The load order is determined by the following:

  1. The order of service groups in the load-ordering group list subkey, HKLM\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder.

The order of drivers within a group specified in the HKLM\SYSTEM\CurrentControlSet\Control\GroupOrderList subkey.

The dependencies listed for each service.

When the startup process is complete, the system executes the boot verification program specified in the HKLM\SYSTEM\CurrentControlSet\Control\BootVerificationProgram subkey.

By default, this value is not set. The system reports that the startup process was successful after the auto-start sequence completes.

After the computer has started successfully, the operating system saves a clone of the database in the Last Known Good configuration. The system can restore this copy of the database if changes made to the active database cause restarting the computer to fail.

For more information about the Last Known Good configuration, see “Accepting the Boot and Last Known Good Configuration” later in this chapter.

The following sequence describes how services are automatically started:

  1. The SCM starts all services that have a Start registry entry with a value of 2 (SERVICE_AUTO_START). The SCM also starts auto-start device drivers.

The algorithm for starting services in the correct order proceeds in various stages, whereby a stage corresponds to a group, and stages proceed in the sequence defined by the group order stored in the List registry entry in the HKLM\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder subkey. The value of the List entry includes the names of groups in the order that the SCM starts them.

For more information about the ServiceGroupOrder subkey, see “Service Groups” earlier in this chapter.

The SCM marks all the service entries that belong to the stage’s group for startup.

The SCM loops through the marked services, verifying whether it can start each service. The verification consists of determining whether the service has a dependency on another group, as specified by the existence of the DependOnGroup entry in the subkey for a service.

  • If a dependency exists, the group on which the service is dependent must have already been initialized, and at least one service in that group must have successfully started.
  • If the service depends on a group that starts later than the service’s group in the group startup sequence, the SCM logs a circular dependency error for the service.

The SCM checks to see whether the service depends on one or more services and whether those services have already started. Service dependencies are indicated by the value of the DependOnService entry in the subkey for a service.

  • If a service depends on other services that belong to groups that come later in the List entry in the HKLM\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder subkey, the SCM also returns a circular dependency error such as “Detected circular dependencies demand starting,” and does not start the service.
  • If the service depends on any services from the same group that have not yet started, the service is skipped.

When the dependencies of a service have been satisfied, the SCM makes a final check to see whether the service is part of the current boot configuration before starting the service.

When the SCM starts a service, it first determines the name of the file that runs the service’s process by reading the value of the ImagePath entry in the service’s registry subkey.

It then examines the value of the Type entry in the service’s subkey, and if that value is 32 (that is, the service shares a process), the SCM ensures that the process the service runs in — if already started — is logged on by using the same account as specified for the service being started. A service’s ObjectName registry entry stores the user account where the service runs. The SCM will fail to start a service with a missing ObjectName and will return the error ERROR_INVALID_SERVICE_ACCOUNT.

The SCM verifies that the service’s process has not already been started in a different account by checking to see whether the value of the service’s ImagePath entry has a record in an internal SCM database identified as the image database.

  •  If the image database does not have a record for the ImagePath entry, the SCM creates one. When the SCM creates a new record, it stores the logon account name used for the service and the data from the value of the service’s ImagePath entry. The SCM requires services to have an ImagePath entry.
  • If a service does not have an ImagePath entry, the SCM returns an error stating that it could not find the service’s path and is not able to start the service.
  • If the SCM locates an existing image database record with matching data from the value of the ImagePath entry, the SCM ensures that the user account information for the service it is starting is the same as the information stored in the database record. A process can be logged on as only one account, so the SCM returns an error (ERROR_DIFFERENT_SERVICE_ACCOUNT) when a service specifies a different account name than another service that has already started in the same process.

The SCM logs on a service if the service’s configuration specifies the service’s process should be started. The SCM logs on services that do not run in the system account by calling the LogonUserEx API, implemented by the Local Security Authority (Lsass.exe). Lsass.exe normally requires a password, but the SCM indicates to Lsass.exe that the password is stored as a Local Security Authority (LSA) secret in the registry subkey HKLM\SECURITY\Policy\Secrets.

When the SCM calls LogonUserEx, it specifies a service logon as the logon type. Lsass.exe looks up the password in the Secrets subkey in HKLM\SECURITY\Secrets that has a name in the form _SC_<service name>. The SCM directs Lsass.exe to store a logon password as a secret when a service control program configures a service’s logon information by using the CreateService or ChangeServiceConfig APIs.

When a logon is successful, LogonUserEx returns a handle to an access token to the caller. Windows Server 2003 uses access tokens to represent your security context, and the SCM later associates the access token with the process that implements the service.

After a successful logon, the SCM loads the account’s profile information, if it is not already loaded, by calling LoadUserProfile, which is implemented in Userenv.dll from systemroot\System32. The ProfileImagePath registry entry in the HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\user profile key> subkey contains the location on disk of a registry hive that loads into the registry, making the information in the hive the HKEY_CURRENT_USER key for the service.

The SCM proceeds to start the service’s process if the process has not already been started (for a previous service, for example). The SCM starts the process in a suspended state and creates a named pipe through which it communicates with the service process, and it assigns the pipe the name \Pipe\Net\NetControlPipeX, where X is a number that is incremented each time the SCM creates a pipe.

The SCM resumes the service process and waits for the service to connect to its SCM pipe.

  • If the pipe exists, the value of the ServicesPipeTimeout registry entry in the HKLM\SYSTEM\CurrentControlSet\Control subkey determines the length of time that the SCM waits for a service to connect before it gives up and terminates the process.
  • If the ServicesPipeTimeout entry does not exist, the SCM uses a default time-out of 30 seconds. The SCM uses the same time-out value for all its service communications.

When a service connects to the SCM through the pipe, the SCM sends the service a start command. If the service fails to respond positively to the start command within the time-out period, the SCM gives up and moves on to start the next service.

When a service does not respond to a start request, the SCM will stop the process if the process does not contain other running services. The SCM will stop the process if an OWN_PROCESS service fails or if the first SHARED_PROCESS service to be started in a process fails. In the latter case, the SCM will return ERROR_SERVICE_REQUEST_TIMEOUT (for demand-start requests) and log EVENT_CONNECTION_TIMEOUT.

A hung auto-start service — for example, a service stuck in SERVICE_START_PENDING forever — is not stopped by the SCM, but will generate an event log message (EVENT_SERVICE_START_HUNG) and possibly a message box popup.

Thus, the SCM continues looping through the services belonging to a group until all the services have either started or returned errors (the services could fail to start for other reasons). Looping is the way the SCM automatically orders services within a group according to the value of their DependOnService entries. Looping helps the SCM send start parameters to a dependent service while the arguments are held in the stack until the dependent service is started. The SCM will start the services that other services depend on in earlier loops, skipping the dependent services until subsequent loops.

After the SCM completely checks for all the groups in the List entry in the HKLM\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder subkey, it performs a check for all the remaining (that is, ungrouped) services.

When the dependencies of a service have been satisfied, the SCM makes a final check to see whether the service is part of the Last Known Good configuration before starting the service.


Starting a Device Driver

The SCM adds entries to the SCM database for device drivers in addition to services. The SCM starts drivers configured as auto-start and detects startup failures for drivers configured as boot-start and system-start. The I/O Manager loads drivers configured as boot-start and system-start before any user-mode processes start, and therefore any drivers having these start types are loaded before the SCM starts itself.

If a service the SCM starts has a value of 1 (SERVICE_KERNEL_DRIVER) or 2 (SERVICE_FILE_SYSTEM_DRIVER) for its Type registry entry, the service is a device driver, and the SCM loads the driver.

The SCM enables the load driver security privilege for the SCM process and then invokes the kernel API NtLoadDriver, passing in the value of the ImagePath entry in the driver’s registry subkey.


Starting Services and Drivers in Safe Mode

When the operating system is started in Safe Mode, the SCM ensures that each service and driver is either identified by name or by group in the appropriate subkey in the SafeBoot registry subkey. There are two safe boot registry subkeys, Minimal and Network, located in the HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot subkey. The one that the SCM checks depends on which mode the user selected during a restart of the computer.

  • If you select Safe Mode or Safe Mode with Command Prompt at the special boot menu (which you can access by pressing F8 when prompted in the boot process), the SCM references the HKLM\SYSTEM\CurrentControlSet\SafeBoot\Minimal subkey.
  • If you select Safe Mode with Networking, the SCM references the HKLM\SYSTEM\CurrentControlSet\SafeBoot\Network subkey. The existence of an Option entry of data type string in the SafeBoot subkey indicates not only that the system booted in Safe Mode but also the mode the user selected.

The minimum services and drivers started under Safe Mode or Safe Mode with Command Prompt are the following:

  • Cryptographic Services
  • Event Log
  • Help and Support
  • Logical Disk Manager Administrative Service
  • Net Logon
  • Plug and Play
  • Remote Procedure Call (RPC)
  • Windows Management Instrumentation

The minimum services and drivers started under Safe Mode with Networking are the following:

  • AFD Networking Support Environment
  • Computer Browser
  • DHCP Client
  • DNS Client
  • Event Log
  • Help and Support
  • Logical Disk Manager
  • NetBIOS Interface
  • NetBIOS over TCP/IP
  • Net Logon
  • Network Connections
  • Plug and Play
  • Remote Procedure Call (RPC)
  • Server
  • TCP/IP NetBIOS Helper
  • TCP/IP Protocol Driver
  • Terminal Services
  • Windows Management Instrumentation
  • Workstation