Видео-шпион gh05t (gh05t@yandex.ru) Хакер, номер #076, стр. 076-108-2 Правда, совсем без модулей мы далеко не уедем, так что добавляй в секцию uses: Windows и WinSvc, чтобы была возможность пользоваться стандартными виндовыми функциями, константами и типами. Также понадобятся несколько глобальных переменных. Для регистрации сервиса в главной функции - DispatchTable типа Service_Table_Entry. Для описания текущего статуса сервиса - MyServiceStatus типа SERVICE_STATUS. А для обращения к сервису - его хэндл в переменной ServiceStatusHandle типа SERVICE_STATUS_HANDLE. Инициализация Что ж, пришла пора нам реализовывать ServiceMain-функцию. И первое, что мы должны в ней сделать – это создать и инициализировать все переменные, используемые в дальнейшем. Начнем, пожалуй, со структуры MyServiceStatus, нужной для регистрации сервиса в системе. У нее 7 параметров и все мы должны заполнить: dwServiceType - тип сервиса. У нас шпион самый обычный, без выпендрежа, поэтому нас устроит значение SERVICE_WIN32; dwCurrentState - текущий «статус» сервиса. Так как нам предстоит долгая инициализация, установим пока это значение в SERVICE_START_PENDING (в режиме ожидания); dwControlsAccepted – параметр, определяющий, какие события от системы будет принимать сервис. Давай позволим пользователю останавливать и ставить сервис на паузу (SERVICE_ACCEPT_STOP or SERVICE_ACCEPT_PAUSE_CONTINUE), мы же не изверги, верно? dwWin32ExitCode, dwServiceSpecificExitCode - коды ошибок. У нас никаких ошибок пока нет ;), поэтому забиваем оба параметра нулями; dwCheckPoint - текущее состояние выполнения процесса. Это значение надо периодически увеличивать и сообщать об этом системе (SetServiceStatus), иначе система решит, что сервис завис. Ставим 0; dwWaitHint - время в миллисекундах, которое система ждет обновления статуса сервиса. Тут есть интересная фишка. Если поставить dwWaitHint:=0, то можно будет не париться по поводу увеличения dwCheckpoint. Нам лишний геморрой ни к чему, поэтому так мы и сделаем. Заполнив структуру, надо зарегистрировать с ее помощью наш сервис визуального наблюдения: MyServiceStatusHandle:= RegisterServiceCtrlHandler('OurVideoSpyService', @MyServiceCtrlHandler); В качестве параметров здесь передаются имя сервиса, указанное при заполнении DispatchTable и указатель на handler-функцию. Мы указали его статус как SERVICE_START_PENDING, поэтому он пока находится в состоянии ожидания. Запустить его на полную катушку можно будет лишь после инициализации остальных переменных, которые понадобятся нам уже для реализации, собственно, самого визуального наблюдения. Смело объявляй в ServiceMain следующие переменные: desk: hDC; bmScreen: Graphics.TBitmap; jpeg: TJPEGImage; smtp: TidSMTP; mes: TidMessage; attach: TIdAttachment; Первая переменная будет содержать хэндл контекста устройства - значение, которое понадобится в дальнейшем для получения снимка рабочего стола. Следующие две переменные необходимы для хранения оригинала снимка и его сжатой версии. А с помощью smtp мы будем отправлять сообщение mes, к которому прикрепим аттач в виде переменной типа TIdAttachment. |