Установка сервиса
Для установки сервиса в систему вы должны использовать функцию CreateService, которая вносит все необходимые дополнения в регистрационную базу данных.
Прототип функции CreateService мы привели ниже:
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 вы должны передать функции CreateService идентификатор базы данных системы управления сервисами, полученный от функции OpenSCManager, описанной выше.
Через параметры lpServiceName и lpDisplayName задаются, соответственно, имя сервиса, которое будет использовано для запуска и имя сервиса для отображения в списке установленных сервисов.
С помощью параметра dwDesiredAccess вы должны указать тип доступа, разрешенный при обращении к данному сервису. Здесь вы можете указать следующие значения:
Значение | Разрешенный тип доступа | ||
SERVICE_ALL_ACCESS | Полный доступ | ||
SERVICE_CHANGE_CONFIG | Изменение конфигурации сервиса функцией ChangeServiceConfig | ||
SERVICE_ENUMERATE_DEPENDENTS | Просмотр сервиса в списке сервисов, созданных на базе данного сервиса функцией EnumDependentServices | ||
SERVICE_INTERROGATE | Выдача сервису команды немедленного определения текущего состояния сервиса при помощи функции ControlService (эта функция будет описана ниже) | ||
SERVICE_PAUSE_CONTINUE | Временная остановка сервиса или продолжение работы после временной остановки | ||
SERVICE_QUERY_CONFIG | Определение текущей конфигурации функцией QueryServiceConfig | ||
SERVICE_QUERY_STATUS | Определение текущего состояния сервиса функцией QueryServiceStatus | ||
SERVICE_START | Запуск сервиса функцией StartService | ||
SERVICE_STOP | Остановка сервиса выдачей соответствующей команды функцией ControlService | ||
SERVICE_USER_DEFINE_CONTROL | Возможность передачи сервису команды, определенной пользователем, с помощью функции ControlService |
Через параметр dwServiceType необходимо передать тип сервиса. Здесь вы можете указывать те же самые флаги, что и в поле dwServiceType структуры SERVICE_STATUS, описанной выше:
Флаг |
Описание |
SERVICE_WIN32_OWN_PROCESS |
Сервис работает как отдельный процесс |
SERVICE_WIN32_SHARE_PROCESS |
Сервис работает вместе с другими сервисами в рамках одного и того же процесса |
SERVICE_KERNEL_DRIVER |
Сервис представляет собой драйвер операционной системы Microsoft Windows NT |
SERVICE_FILE_SYSTEM_DRIVER |
Сервис является драйвером файловой системы |
SERVICE_INTERACTIVE_PROCESS |
Сервисный процесс может взаимодействовать с программным интерфейсом рабочего стола Desktop |
Константа |
Способ запуска |
SERVICE_BOOT_START |
Используется только для сервисов типа SERVICE_KERNEL_DRIVER или SERVICE_FILE_SYSTEM_DRIVER (драйверы). Указывает, что драйвер должен загружаться при загрузке операционной системы |
SERVICE_SYSTEM_START |
Аналогично предыдущему, но драйвер запускается при помощи функции IoInitSystem, не описанной в нашей книге |
SERVICE_AUTO_START |
Драйвер или обычный сервис, который запускается при загрузке операционной системы |
SERVICE_DEMAND_START |
Драйвер или обычный сервис, который запускается функцией StartService |
SERVICE_DISABLED |
Отключение возможности запуска драйвера или обычного сервиса |
Значение |
Реакция на ошибку |
SERVICE_ERROR_IGNORE |
Протоколирование ошибки в системном журнале и продолжение процедуры запуска сервиса |
SERVICE_ERROR_NORMAL |
Протоколирование ошибки в системном журнале без продолжения процедуры запуска сервиса |
SERVICE_ERROR_SEVERE |
Протоколирование ошибки в системном журнале. Если это возможно, используется конфигурация, с которой сервис успешно был запущен в прошлый раз. В противном случае система перезапускается с использованием работоспособной конфигурации |
SERVICE_ERROR_CRITICAL |
Криичная ошибка. Сообщение при возможности записывается в системный журнал. Операция запуска отменяется, система перезапускается с с использованием работоспособной конфигурации |
В параметре lpBinaryPathName вы должны указать полный путь к загрузочному файлу сервиса.
Через параметр lpLoadOrderGroup передается указатель на имя группы порядка загрузки сервиса. Сделав сервис членом одной из групп порядка загрузки, вы можете определить последовательность загрузки вашего сервиса относительно других сервисов. Список групп порядка загрузки находится в регистрационной базе данных:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ServiceGroupOrder
Если относительный порядок загрузки не имеет значения, укажите для параметра lpLoadOrderGroup значение NULL.
Параметр lpdwTagId используется только в том случае, если значение параметра lpLoadOrderGroup не равно NULL.
Параметр lpDependencies должен содержать указатель на массив строк имен сервисов или групп порядка загрузки, которые должны быть запущены перед запуском данного сервиса. Последняя строка такого массива должна быть закрыта двумя двоичными нулями. Если зависимостей от других сервисов нет, для параметра lpDependencies можно указать значение NULL.
Последние два параметра функции lpServiceStartName и lpPassword указывают, соответственно, имя и пароль пользователя, с правами которого данный сервис будет работать в системе (имя указывается в форме “ИмяДомена\имяПользователя”). Если параметр lpServiceStartName указан как NULL, сервис подключится к системе как пользователь LocalSystem. При этом параметр lpPassword должен быть указан как NULL.
Ниже мы привели фрагмент исходного текста приложения, в котором выполняется установка сервиса из каталога c:\ntbk2\src\service\small\debug:
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
schService = CreateService(
schSCManager, MYServiceName, MYServiceName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
"c:\\ntbk2\\src\\service\\small\\debug\\small.exe",
NULL, NULL, "", NULL, NULL);
CloseServiceHandle(schSCManager);