The CreateService function creates a service object and adds it to the specified service control manager database.
SC_HANDLE CreateService(
SC_HANDLE hSCManager, | // handle to service control manager database |
LPCTSTR lpServiceName, | // pointer to name of service to start |
LPCTSTR lpDisplayName, | // pointer to display name |
DWORD dwDesiredAccess, | // type of access to service |
DWORD dwServiceType, | // type of service |
DWORD dwStartType, | // when to start service |
DWORD dwErrorControl, | // severity if service fails to start |
LPCTSTR lpBinaryPathName, | // pointer to name of binary file |
LPCTSTR lpLoadOrderGroup, | // pointer to name of load ordering group |
LPDWORD lpdwTagId, | // pointer to variable to get tag identifier |
LPCTSTR lpDependencies, | // pointer to array of dependency names |
LPCTSTR lpServiceStartName, | // pointer to account name of service |
LPCTSTR lpPassword | // pointer to password for service account |
); |
Parameters
hSCManager
Identifies the service control manager database. This handle must have be opened using the OpenSCManager with SC_MANAGER_CREATE_SERVICE access.
lpServiceName
Points to a null-terminated string that names the service to install. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. Forward-slash (/) and back-slash (\) are invalid service name characters.
lpDisplayName
Points to a null-terminated string that is to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the service control manager. Display name comparisons are always case-insensitive.
dwDesiredAccess
Specifies the access to the service. Before granting the requested access, the system checks the access token of the calling process. Any or all of the following service object access types can be specified:
Access | Description |
SERVICE_ALL_ACCESS | Includes STANDARD_RIGHTS_REQUIRED in addition to all of the access types listed in this table. |
SERVICE_CHANGE_CONFIG | Enables calling of the ChangeServiceConfig function to change the service configuration. |
SERVICE_ENUMERATE_DEPENDENTS | Enables calling of the EnumDependentServices function to enumerate all the services dependent on the service. |
SERVICE_INTERROGATE | Enables calling of the ControlService function to ask the service to report its status immediately. |
SERVICE_PAUSE_CONTINUE | Enables calling of the ControlService function to pause or continue the service. |
SERVICE_QUERY_CONFIG | Enables calling of the QueryServiceConfig function to query the service configuration. |
SERVICE_QUERY_STATUS | Enables calling of the QueryServiceStatus function to ask the service control manager about the status of the service. |
SERVICE_START | Enables calling of the StartService function to start the service. |
SERVICE_STOP | Enables calling of the ControlService function to stop the service. |
SERVICE_USER_DEFINED_CONTROL | Enables calling of the ControlService function to specify a user-defined control code. |
The STANDARD_RIGHTS_REQUIRED constant (defined in the WINNT.H file) enables the following service object access types:
Standard rights | Description |
DELETE | Enables calling of the DeleteService function to delete the service. |
READ_CONTROL | Enables calling of the QueryServiceObjectSecurity function to query the security descriptor of the service object. |
WRITE_DAC|WRITE_OWNER | Enables calling of the SetServiceObjectSecurity function to modify the security descriptor of the service object. |
The dwDesiredAccess parameter can specify any or all of the following generic access types:
Generic access | Service access |
GENERIC_READ | Combines the following accesses: STANDARD_RIGHTS_READ, SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, and SERVICE_ENUMERATE_DEPENDENTS. |
GENERIC_WRITE | Combines the following accesses: STANDARD_RIGHTS_WRITE and SERVICE_CHANGE_CONFIG. |
GENERIC_EXECUTE | Combines the following accesses: STANDARD_RIGHTS_EXECUTE, SERVICE_START, SERVICE_STOP, SERVICE_PAUSE_CONTINUE, SERVICE_INTERROGATE, and SERVICE_USER_DEFINED_CONTROL. |
dwServiceType
A set of bit flags that specify the type of service. You must specify one of the following service type flags to indicate the service type. In addition, if you specify either of the SERVICE_WIN32 flags, you can also specify the SERVICE_INTERACTIVE_PROCESS flag to enable the service process to interact with the desktop.
Value | Meaning |
SERVICE_WIN32_OWN_PROCESS | A service-type flag that specifies a Win32 service that runs in its own process. |
SERVICE_WIN32_SHARE_PROCESS | A service-type flag that specifies a Win32 service that shares a process with other services. |
SERVICE_KERNEL_DRIVER | A service-type flag that specifies a Windows NT device driver. |
SERVICE_FILE_SYSTEM_DRIVER | A service-type flag that specifies a Windows NT file system driver. |
SERVICE_INTERACTIVE_PROCESS | A flag that enables a Win32 service process to interact with the desktop. |
dwStartType
Specifies when to start the service. This member can be one of the following values:
Value | Meaning |
SERVICE_BOOT_START | Specifies a device driver started by the operating system loader. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER. |
SERVICE_SYSTEM_START | Specifies a device driver started by the I/O system after boot devices such as the boot file system and disk driver have been initialized. The device driver started using this flag is not critical to the system boot. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER. |
SERVICE_AUTO_START | Specifies a device driver or service started by the service control manager automatically during system startup. |
SERVICE_DEMAND_START | Specifies a device driver or service started by the service control manager when a process calls the StartService function. |
SERVICE_DISABLED | Specifies a device driver or Win32 service that can no longer be started. |
dwErrorControl
Specifies the severity of the error if this service fails to start during startup, and determines the action taken by the startup program if failure occurs. One of the following values can be specified:
Value | Meaning |
SERVICE_ERROR_IGNORE | The startup (boot) program logs the error but continues the startup operation. |
SERVICE_ERROR_NORMAL | The startup program logs the error and displays a message but continues the startup operation. |
SERVICE_ERROR_SEVERE | The startup program logs the error. If the last-known-good configuration is being started, the startup operation continues. Otherwise, the system is restarted with the last-known-good configuration. |
SERVICE_ERROR_CRITICAL | The startup program logs the error, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known-good configuration. |
lpBinaryPathName
Points to a null-terminated string that contains the fully qualified path to the service binary file.
lpLoadOrderGroup
Points to a null-terminated string that names the load ordering group of which this service is a member. If the pointer is NULL or if it points to an empty string, the service does not belong to a group. The registry has a list of load ordering groups located at:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
\ServiceGroupOrder.
The startup program uses this list to load groups of services in a specified order with respect to the other groups in the list. You can place a service in a group so that another service can depend on the group.
The order in which a service starts is determined by the following criteria:
1.The order of groups in the registry's load-ordering group list. Services in groups in the load-ordering group list are started first, followed by services in groups not in the load-ordering group list and then services that do not belong to a group.
2.The service's dependencies listed in the lpDependencies parameter and the dependencies of other services dependent on the service.
lpdwTagId
Points to a 32-bit variable that receives a unique tag value for this service in the group specified in the lpLoadOrderGroup parameter. If no tag is requested, this parameter can be NULL.
You can use a tag for ordering service startup in a load ordering group by specifying a tag order vector in the registry located at:
HKEY_LOCAL_MACHINE\System\ CurrentControlSet
\Control\GroupOrderList.
Tags are only evaluated for SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER type services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types.
lpDependencies
Points to an array of null-separated names of services or load ordering groups that must start before this service. The array is double null-terminated. If the pointer is NULL or if it points to an empty string, the service has no dependencies. If a group name is specified, it must be prefixed by the SC_GROUP_IDENTIFIER character (defined in the WINSVC.H file) to differentiate it from a service name, because services and service groups share the same name space. Dependency on a service means that this service can only run if the service it depends on is running. Dependency on a group means that this service can run if at least one member of the group is running after an attempt to start all members of the group.
lpServiceStartName
Points to a null-terminated string. If the service type is SERVICE_WIN32_OWN_PROCESS, this name is the account name in the form of "DomainName\Username", which the service process will be logged on as when it runs. If the account belongs to the built-in domain, ".\Username" can be specified. Services of type SERVICE_WIN32_SHARE_PROCESS are not allowed to specify an account other than LocalSystem. If NULL is specified, the service will be logged on as the "LocalSystem" account, in which case, the lpPassword parameter must be NULL.
If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this name is the Windows NT driver object name (that is, \FileSystem\Rdr or \Driver\Xns), which the input and output (I/O) system uses to load the device driver. If NULL is specified, the driver is run with a default object name created by the I/O system, based on the service name.
lpPassword
Points to a null-terminated string that contains the password to the account name specified by the lpServiceStartName parameter, if the service type is SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS. If the pointer is NULL or if it points to an empty string, the service has no password. If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this parameter is ignored.
Return Values
If the function succeeds, the return value is a handle to the service.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
Errors
The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.
Value | Meaning |
ERROR_ACCESS_DENIED | The handle to the specified service control manager database does not have SC_MANAGER_CREATE_SERVICE access. |
ERROR_CIRCULAR_DEPENDENCY | A circular service dependency was specified. |
ERROR_DUP_NAME | The display name already exists in the service control manager database either as a service name or as another display name. |
ERROR_INVALID_HANDLE | The handle to the specified service control manager database is invalid. |
ERROR_INVALID_NAME | The specified service name is invalid. |
ERROR_INVALID_PARAMETER | A parameter that was specified is invalid. |
ERROR_INVALID_SERVICE_ACCOUNT | The user account name specified in the lpServiceStartName parameter does not exist. |
ERROR_SERVICE_EXISTS | The specified service already exists in this database. |
Remarks
The CreateService function creates a service object and installs it in the service control manager database by creating a service name key in the registry with the following form:
HKEY_LOCAL_MACHINE\System\CurrentControlSet
\Services\lpServiceName
where lpServiceName is the service name specified for this function. Information specified for this function is saved as values under this key. Setup programs and the service itself can create any subkey under this service name key for any service specific information.
If the appropriate access rights are enabled, the calling process can use the returned handle to identify the newly created service in the following functions:
ChangeServiceConfig, ControlService, DeleteService, QueryServiceConfig, QueryServiceObjectSecurity, QueryServiceStatus, SetServiceObjectSecurity, StartService
The returned handle is only valid for the process that called CreateService. It can be closed by calling the CloseServiceHandle function.
See Also
ChangeServiceConfig, CloseServiceHandle, ControlService, DeleteService, EnumDependentServices, OpenSCManager, QueryServiceConfig, QueryServiceObjectSecurity, QueryServiceStatus, SetServiceObjectSecurity, StartService