Сервисы в Delphi на чистом API



Автор: Павел

Часть 1. Основные понятия

Вот так получилось нужно было по работе написать сервис но не хотелось пользоваться классами Delphi, так как код написанный с применением оных большой, а хотелось чего-нибудь поменьше, то есть на API, но к сожелению видно этим никто не занимался в Delphi (примеров на Си более чем достаточно), вот и родилась идея этого обзора. Что же это сервис(еще их называют службами)??? Попробую рассказать как умею...

В любой операционной системе, нужны программы которые работают в фоновом режиме (это нужно например для различных серверов СУБД, сетевые приложения, программ мониторинга следящих за чем то и т.д. и т.п), в Unix-системах такие программы называются демонами, в DOS они назывались TSR (Terminate and Stay Resident). В NT и 2000(далее я буду называть их только для NT, что подразумевает под сообой и 2000) Windows такие программы называются сервисами (или службами).Сервис NT (Windows NT service) - процесс, обладающий специальным интерфейсом для взаимодействия с операционной системой Windows NT. Сервисы бывают двух типов - сервисы Win32, взаимодействующие с операционной системой посредством диспетчера управления сервисами (Service Control Manager - SCM), и драйвера, работающие по протоколу драйвера устройства Windows NT. Я буду рассказывать только про сервисы Win32. Сервисы доступны в панели управления. Запустив Service Applet, вы увидите список доступных сервисов. Вы можете запускать, останавливать, ставить сервисы на паузу. Нажав кнопку Startup, Вы можете изменить поведение сервиса при запуске. Сервисы могут запускаться автоматически при старте компьютера, быть абсолютно выключеными или иметь возможность запуска вручную. Если сервис запускается вручную, то пользователь может указать параметры запуска. Для управления сервисами Вам нужны права администратора или права power user. ОС использует много сервисов и информацию о каждом из них пишет в реестр в ключ "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services".Там содержатся следующие сведения:

Тип службы

Указывает на то, реализован ли в данной программе только один сервис (эксклюзивный) или же их несколько. Эксклюзивный сервис может работать в любом контексте безопасности. Несколько сервисов внутри одного приложения могут работать только в контексте LocalSystem.

Способ запуска

Автоматический - сервис запускается при старте системы. По требованию - сервис запускается пользователем вручную. Деактивированный - сервис не может быть запущен.

Имя исполняемого EXE-файла

Порядок запуска по отношению к другим сервисам.

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

Контекст безопасности

Здесь хранится сетевое имя и пароль. По умолчанию контекст безопасности соответствует LocalSystem.

Любая программа, имеющее соответствующие права, может взаимодействовать с сервисом. Это подразумевает изменение состояния сервиса (Вы можете изменить состояния сервиса используя Service Applet), то есть перевод его в одно из трех состояний - активный (сервис работает), приостоновленный (работа сервиса приостановлена), полная остановка и осуществляется при помощи посылки запросов SCM. Запросы бывают трех типов:

  • Сообщения от сервисов (фиксация их состояний).
  • Запросы, связанные с изменением конфигурации сервиса или получением информации о нем.
  • Запросы приложений на изменение состояния сервиса.

Для управления сервисом необходимо в первую очередь получить дескриптор с помощью функции OpenService. Функция StartService запускает сервис. Изменение состояния сервиса производится вызовом функции ControlService. С помощью определенных функций вы можете изменить информацию о сервисе, тем самым и в реестре. OpenSCManager, CreateService, OpenService, CloseServiceHandle - для создания (открытия) сервиса. QueryServiceConfig, QueryServiceObjectSecurity, EnumDependentServices, EnumServicesStatus - для получения информации о сервисе. ChangeServiceConfig, SetServiceObjectSecurity, LockServiceDatabase, UnlockServiceDatabase, QueryServiceLockStatus - для изменения конфигурационной информации сервиса.

В принципе как было сказано сервис - это в принципе обычный exe-файл поддерживающий интерфейс SCM, только имеющий определенное строение. Для того чтобы стать сервисом программа должна быть построена соответствующим образом(т.е. иметь набор определенных функций). В следующей части я подробно расскажу об этом.

Описание функций для работы с сервисами (постепенно будут добавлены описания для всех функций), большая часть из них объявлена в WinSvc.Pas.

  • ChangeServiceConfig Изменяет параметры конфигурации сервиса
  • ChangeServiceConfig2 Изменяет необязательные параметры конфигурации сервиса
  • CloseServiceHandle Закрывает указанный дескриптор к сервисному объекту
  • ControlService Посылает сервису управляющий код
  • CreateService Создает сервисный объект
  • DeleteService Удаляет сервис из базы данных диспетчеров сервисов
  • EnumDependentServices Перечисляет зависимые сервисы
  • EnumServicesStatus Перечисляет сервисы
  • EnumServicesStatusEx Перечисляет сервисы
  • GetServiceDisplayName Возвращает отображаемое имя сервиса
  • GetServiceKeyName Возвращает имя сервиса
  • Handler Функция обработки управляющих кодов
  • HandlerEx Функция обработки управляющих кодов
  • LockServiceDatabase Блокирует базу данных сервисов
  • NotifyBootConfigStatus Уведомляет о приеме загрузочной информации
  • OpenSCManager Подключает приложение к менеджеру сервисов
  • OpenService Открывает сервис
  • QueryServiceConfig Запрашивает параметры конфигурации
  • QueryServiceConfig2 Запрашивает необязательные параметры конфигурации
  • QueryServiceLockStatus Запрашивает статус блокировки
  • QueryServiceObjectSecurity Запрашивает дескриптор безопасности
  • QueryServiceStatus Запрашивает статус сервиса
  • QueryServiceStatusEx Запрашивает статус сервиса
  • RegisterServiceCtrlHandler Регистрирует обработчик запросов
  • RegisterServiceCtrlHandlerEx Регистрирует обработчик запросов
  • ServiceMain Главная функция сервиса
  • SetServiceBits Обноволяет статус сервиса для диспетчера сервисов
  • SetServiceObjectSecurity Изменяет дескриптор безопасности сервисного объекта
  • SetServiceStatus Устанавливает статус сервиса
  • StartService Запускает сервис
  • StartServiceCtrlDispatcher Запускает поток
  • UnlockServiceDatabase Разблокирование базы данных

Также при написание сервиса используются такие структуры(описания их то же постепенно будут добавлятся).

  • ENUM_SERVICE_STATUS
  • ENUM_SERVICE_STATUS_PROCESS
  • QUERY_SERVICE_CONFIG
  • QUERY_SERVICE_LOCK_STATUS
  • SC_ACTION
  • SERVICE_DESCRIPTION
  • SERVICE_FAILURE_ACTIONS
  • SERVICE_STATUS
  • SERVICE_STATUS_PROCESS
  • SERVICE_TABLE_ENTRY

Но вот и все для основных понятий...Вообще сервисы довольно сильно облегчают жизнь программисту, и понимание их работы (даже не используя) полезны, не только программистам, но и системным администраторам и пользователям.

В статье использованы материалы из Microsoft SDK(Эта статья входит в рамки проекта DSDN).

С удовольствием выслушаю все комментария и замечания по поводу данной статьи. Сразу хочу предупредить, я не отвечаю на письма где меня просят выслать что либо или будет ли продолжение(и подобные письма не несущие какой-то содержательной части), я их читаю, но отвечать на них у меня времени нет. Также , если кто обнаружит неточности, да и просто грамматические ошибки в статье, за это прошу заранее извинение.

Желаю удачи в темных делах
С уважением Алексей


Далее: Скрытие или отображение процесса из списка процессов »»