15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Функция CreateService.

Функция CreateService создаёт объект сервиса и добавляет его в базу данных менеджера управления сервисами (SCM).

 

SC_HANDLE CreateService(
  SC_HANDLE hSCManager,
  LPCTSTR lpServiceName,
  LPCTSTR lpDisplayName,
  DWORD dwDesiredAccess,
  DWORD dwServiceType,
  DWORD dwStartType,
  DWORD dwErrorControl,
  LPCTSTR lpBinaryPathName,
  LPCTSTR lpLoadOrderGroup,
  LPDWORD lpdwTagId,
  LPCTSTR lpDependencies,
  LPCTSTR lpServiceStartName,
  LPCTSTR lpPassword
);

Параметры

hSCManager
Дескриптор базы данных менеджера управления сервисами (SCM). Этот дескриптор можно получить при помощи функции OpenSCManager с правом доступа SC_MANAGER_CREATE_SERVICE. Более подробно см. Безопасность сервисов и права доступа.
lpServiceName
Указатель на строку (завершающуюся нулём), содержащую имя создаваемого сервиса. Максимальная длина строки не должна превышать 256 символов. В имени сервиса нельзя использовать символы "/" и "\".
lpDisplayName
Указатель на строку (завершающуюся нулём), содержащую имя, которое будет отображаться в пользовательских приложениях. Максимальная длина строки не должна превышать 256 символов.
dwDesiredAccess
Тип доступа к сервису. Перед тем, как разрешить запрашиваемый доступ, система проверит привелегии вызвавшего процесса. Список значений см. Безопасность сервисов и права доступа.
dwServiceType
Тип сервиса. Этот параметр может содержать одно из следующих значений:
Тип Описание
SERVICE_FILE_SYSTEM_DRIVER Сервис драйвера файловой системы.
SERVICE_KERNEL_DRIVER Сервис драйвера.
SERVICE_WIN32_OWN_PROCESS Сервис, который запускается в собственном процессе.
SERVICE_WIN32_SHARE_PROCESS Сервис, который делает доступным процесс для других сервисов.


Если указать SERVICE_WIN32_OWN_PROCESS или SERVICE_WIN32_SHARE_PROCESS, и если при этом сервис запускается с правами системы, то Вы можете так же указать следующий тип:

Тип Описание
SERVICE_INTERACTIVE_PROCESS Сервис может взаимодействовать с рабочим столом.

См. Интерактивные сервисы.

dwStartType
Тип запуска сервиса. Этот параметр может иметь одно из следующих значений:
Тип Описание
SERVICE_AUTO_START Сервис запускается автоматически менеджером управления сервисами при старте системы.
SERVICE_BOOT_START Драйвер устройства стартует при загрузке системы. Это значение доступно только для сервисов драйверов.
SERVICE_DEMAND_START Сервис запускается из менеджера управления сервисами, когда процесс вызывает функцию StartService.
SERVICE_DISABLED Сервис не должен запускаться. Попытка запуска такого сервиса приведёт к коду ошибки ERROR_SERVICE_DISABLED.
SERVICE_SYSTEM_START Драйвер устройства запускается функцией IoInitSystem. Это значение доступно только для сервисов драйверов.
dwErrorControl
Степень контроля ошибок, а так же действия, которые будут предприняты, в случае ошибки запуска сервиса. Этот параметр может иметь следующие значения:
Значение Описание
SERVICE_ERROR_IGNORE Запускающая программа записывает ошибку в лог, но продолжает операцию запуска.
SERVICE_ERROR_NORMAL Запускающая программа записывает ошибку в лог и выводит диалоговое окошко с сообщением об ошибке, но продолжает операцию запуска.
SERVICE_ERROR_SEVERE Запускающая программа записывает ошибку в лог. Если была запущена предыдущая конфигурация системы, то операция запуска продолжается. Иначе, система будет перезапущена с предыдущей конфигурацией.
SERVICE_ERROR_CRITICAL Запускающая программа записывает ошибку в лог, если это возможно. Если была запущена предыдущая конфигурация системы, то операция запуска будет остановлена. Иначе, система будет перезапущена с предыдущей конфигурацией.
lpBinaryPathName
Указатель на строку (заканчивающуюся нулём), которая содержит полный путь к исполняемому файлу сервиса. Если путь содержит пробелы, то он должен быть заключён в кавычки. Например, "d:\\my share\\myservice.exe" необходимо указать как
"\"d:\\my share\\myservice.exe\"".

Путь так же может содержать аргументы для автоматически-запускаемого сервиса. Например, "d:\\myshare\\myservice.exe arg1 arg2". Эти параметры передаются в точку входа сервиса (обычно в функцию main).

lpLoadOrderGroup
Указатель на строку (заканчивающуюся нулём), которая содержит имя группы, членом которой является сервис. Если сервис не является членом группы, то можно указать NULL или пустую строку.

Запускающая программа использует порядок загрузки групп, для загрузки групп сервисов в указанном порядке относительно других групп. Список групп содержится в значении ServiceGroupOrder, которое находится в следующем ключе реестра:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control

lpdwTagId
Указатель на переменную, в которую будет записан уникальное значение тэга, которое идентифицирует группу, указанную в параметре lpLoadOrderGroup. Если Вы не собираетесь менять существующий тэг, то укажите в этом параметре NULL.

Этот тэг можно использовать для указания порядка загрузки сервисов в группе, указав вектор в значении GroupOrderList ключа реестра:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control

Тэги доступны только для сервисов драйверов, которые имеют типы запуска SERVICE_BOOT_START или SERVICE_SYSTEM_START.

lpDependencies
Указатель на массив (завершающийся двумя нулями) имён (разделённых нулями) сервисов или групп сервисов, которые система должна запустить до запуска этого сервиса. Если сервис не зависит от других сервисов, то в этом параметре нужно указать NULL или пустую строку. Зависимость от группы означает, что этот сервис может быть запущен только тогда, когда как минимум один из сервисов группы удалось запустить после попытки старта всех членов группы.

Для группы необходимо использовать префикс SC_GROUP_IDENTIFIER, чтобы отличить от имени сервис, так как сервисы и группы сервисов используют одно и тоже пространство имён.

lpServiceStartName
Указатель на строку (завершающуюся нулём), которая содержит имя аккаунта, с правами которого будет запущен сервис. Если тип сервиса SERVICE_WIN32_OWN_PROCESS, то использовать имя аккаунта необходимо в виде DomainName\UserName. Процесс сервиса будет авторизирован в системе как этот пользователь. Если аккаунт присутствует в текущем домене, то можно просто указать .\UserName.

Если этот параметр задать как NULL, то CreateService будет использовать Системный аккаунт. Если тип сервиса указать как SERVICE_INTERACTIVE_PROCESS, то сервис должен быть запущен с правами системы.

Windows XP: Если указать в этом параметре NT AUTHORITY\LocalService, то CreateService использует системный аккаунт. Если же этот параметр задать как NT AUTHORITY\NetworkService, то CreateService будет использовать аккаунт NetworkService.

Windows NT 4.0 и выше: Если тип сервиса SERVICE_WIN32_SHARE_PROCESS, ты необходимо запускать сервис с правами системы. В Windows 2000 и позже, можно запускать процесс, доступный другим сервисам под любым пользователем.

Если тип сервиса SERVICE_KERNEL_DRIVER или SERVICE_FILE_SYSTEM_DRIVER, то этот параметр должен содержать имя объекта драйвера, которое система использует для загрузки драйвера устройства, либо указать NULL, если драйвер использует имя объекта драйвера созданное подсистемой ввода/вывода (I/O).

lpPassword
Указатель на строку (заканчивающуюся нулём), которая содержит пароль к аккаунту, указанному в параметре lpServiceStartName. Если аккаунт не имеет пароля либо если сервис запускается с правами LocalService, NetworkService, или системы, то можно указать на пустую строку. Более подробно см. Service Record List.

Для сервисов драйверов пароль игнорируется.

Возвращаемое значение

В случае успеха, функция вернёт дескриптор сервиса.

В случае ошибки, функция вернёт NULL. Для получения более подробной информации об ошибке, можно воспользоваться функцией GetLastError.

По умолчанию, в менеджере управления сервисами установлены следующие коды ошибок. Так же, при помощи менеджера управления сервисами можно установить и другие коды ошибок.

 

Значение Описание
ERROR_ACCESS_DENIED Менеджер управления сервисами не дал разрешения на выполнение операции SC_MANAGER_CREATE_SERVICE.
ERROR_CIRCULAR_DEPENDENCY Указана зацикленная зависимость.
ERROR_DUPLICATE_SERVICE_NAME Отображаемое имя уже присутствует в базе менеджера управления сервисами как имя сервиса либо как другое отображаемое имя.
ERROR_INVALID_HANDLE Не правильный дескриптор менеджера управления сервисами.
ERROR_INVALID_NAME Не правильное имя сервиса.
ERROR_INVALID_PARAMETER Неправильно указан параметр.
ERROR_INVALID_SERVICE_ACCOUNT Аккаунт, указанный в параметре lpServiceStartName не существует.
ERROR_SERVICE_EXISTS Указанный сервис уже существует в базе данных.


Замечания

Функция CreateService создаёт объект сервиса и прописывает его в базе менеджера управления сервисами создав в реестре ключ с таким же именем что и имя сервиса в следующем ключе:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services

В этом ключе записываются значения, указанные в функциях CreateService, ChangeServiceConfig, и ChangeServiceConfig2. Эти значения перечислены в следующей таблице:

 

Значение Описание
DependOnGroup Группы, указанные в lpDependencies, от которых зависит сервис.
DependOnService Другие сервисы, указанные в lpDependencies, от которых зависит указанный сервис.
Description Описание, указанное в ChangeServiceConfig2.
DisplayName Отображаемое имя, указанное в lpDisplayName.
ErrorControl Уровень контроля ошибок, указанный в dwErrorControl.
FailureActions Действия в случае ошибки, указанные в ChangeServiceConfig2.
Group Порядок загрузки групп, указанный в lpLoadOrderGroup.
ImagePath Имя исполняемого файла, указанного в lpBinaryPathName.
ObjectName Имя аккаунта, указанного в lpServiceStartName.
Start Как запускаться сервису. Указано в dwStartType.
Tag Тэг идентификации, указанный в lpdwTagId.
Type Тип сервиса, указанный в dwServiceType.


Программы установки и сам сервис могут создавать дополнительные ключи для дополнительной информации о сервисе.

Полученный дескриптор будет доступным только для того процесса, который вызвал CreateService. Закрыть его можно при помощи функции CloseServiceHandle.

Если Вы создаёте процесс, доступный другим процессам, то избегайте вызова таких функций как ExitProcess. А так же не выгружайте DLL сервиса.

Пример использования

См. Установка сервиса.

Дополнительные сведенья

Windows NT/2000/XP: Присутствует в Windows NT 3.1 и позже.
Unicode: Существует как Unicode, так и ANSI версия этой функции.
Заголовок: Объявлена в Winsvc.h; включена в Windows.h.
Библиотека: Advapi32.lib.