Коди керування, що сприймаються

Параметр dwControlsAccepted визначає коди керування, які служба сприймає і обробляє в своєму обробнику керування. Можливі значення перераховані в таблиці 5; декілька значень можуть об’єднуватися порозрядним „або”. Приведена нижче версія serverSK для служби сприймає всі три значення. Додаткові значення описані в документації MSDN.

 

Таблиця 5. Коди керування, які сприймаються службою

Значення Дія
SERVICE_ACCEPT_STOP Дозволяється SERVICE_CONTROL_STOP
SERVICE_ACCEPT_PAUSR_CONTINUE Дозволяється SERVICE_CONTROL_PAUSE і SERVICE_CONTROL_CONTINUE
SERVICE_ACCEPT_SHUTDOWN (функція ControlService не може видавати цей код керування) Служба повідомляє, коли система закінчує роботу. Таким чином, система може послати службі значення SERVICE_CONTROL_ SHUTDOWN

 

Код служби

Коли обробник зареєстрований і встановлений стан служби SERVICE_START_PENDING, служба може ініціалізувати себе і встановити стан знову. В прикладі перетворення serverSK після того, як сокети ініціалізовані і сервер буде готовий до прийому клієнтів, слідує встановити стан SERVICE_RUNNING.

Обробник керування служби

Обробник керування служби, який вказаний в функції RegisterServiceCtrlHandler, має наступну форму:

 

VOID WINAPI ServerCtrlHandler (DWORD fdwControl)

 

Єдиний параметр цієї функції, fdwControl, містить сигнал керування, який передається диспетчером SCM для обробки. Таким чином, обробник керування є узагальненою формою обробника керування консолі.

Сигнали керування можуть мати слідуючи значення:

 

SERVICE_CONTROL_STOP

SERVICE_CONTROL_PAUSE

SERVICE_CONTROL_CONTINUE

SERVICE_CONTROL_INTERROGATE

SERVICE_CONTROL_SHUTDOWN

 

Також допускаються значення користувача в діапазоні 128-255, але тут вони не розглядаються.

Обробник викликається диспетчером SCM в тому ж потоці, що і головна програма, і звичайно будується на базі оператора switch.

Керування службами Windows NT

Наступна задача після написання коду – передача служби під керуванням SCM, щоб її можна було запускати, закінчувати і виконувати інші керуючі операції.

Для цього потрібно виконати декілька дій з відкриття SCM, створення служби під керуванням SCM і потім з її запуску. Ці дії не керують службою безпосередньо; вони представляють собою команди для SCM, який працює з вказаною службою.

Відкриття SCM

Для створення служби необхідний окремий процес, який грає роль „адміністратора”. Перша дія – відкриття SCM і отримання дескриптору, який потім дозволяє створити службу.

 

SC_HANDLE OpenSCManager (

LPCTSTR lpMachineName,

LPCTSTR lpDatabaseName,

DWORD dwDesiredAddress)

 

Параметри

lpMachineName рівний NULL, якщо SCM знаходиться в локальній системі, хоча можна звертатися до SCM і на інших машинах в мережі.

lpDatabaseName – також звичайно NULL.

dwDesiredAddress – звичайно SC_MANAGER_ALL_ACCESS, але можна задати більш обмежені права доступу, як описано в вбудованій документації.

 

Створення і видалення служби

 

Нові служби фіксуються в слідую чому розділі системного реєстру:

 

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

 

Для створення служби слідує визвати функцію Create Service, вказавши дескриптор SC_HANDLE, отриманий при виклику OpenSCManager.

 

SC_HANDLE CreatrService (

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 – дескриптор SC_HANDLE, який отриманий від OpenSCManager.

lpServiceName – ім’я, по якому в подальшому ми будемо посилатися на службу, це одне із імен логічних служб, які вказані в таблиці при виклику StartServiceCtrlDispatcher. Замітимо, що для кожної логічної служби потрібний окремий виклик CreateService.

lpDisplayName – ім’я, під яким служба буде відображатися в реєстрі і в аплеті Служби, який відкривається на панелі керування в розділі Средства адміністрування. Це ім’я з’являється зразу після успішного виклику CreateService.

dwDesiredAccess може мати значення SERVICE_ALL_ACCESS або бути комбінацією GENERIC_READ, GENERIC_WRITE і GENERIC_EXECUTE. Більш детально це описано в вкладеній документації.

dwServiceType має значення, які представленні в таблиці 1.

dwStartType визначає порядок запуску служби. В наших прикладах використовується зачення SERVICE_DEMAND_START; інші значення (SERVICE_BOOT_START і SERVICE_SYSTEM_START) дозволяють запускати служби драйверів пристроїв в ході початкового запуску системи, а SERVICI_AUTO_START визначає, що служба повинна автоматично запускатися при запуску системи.

lpBinaryPathName вказує на виконуючий файл служби; розширення.exe вказувати не потрібно.

Інші параметри визначають ім’я облікового запису і пароль, групи для об’єднувальних служб і залежності в випадку декількох взаємозалежних служб.

Для отримання дескриптора іменованої служби використовується функція OpenService, для видалення служби із системного реєстру – DeleteService, а для закриття дескриптора – CloseServiceHandle.

Запуск служби

Зразу після створення служба ще не працює. Запустіть функцію ServiceMain (), вказавши дескриптор, який отриманий від CreateService, і параметри командного рядка argc, argv, які вимагає „головна” функція служби (тобто функція, яка вказана в таблиці служб).

 

BOOL StartService (

SC_HANDLE hService,

DWORD argc,

LPTSTR argv [])

 

Керування служби

 

Для керуючої дії над службою диспетчером SCM повинен бути викликаний обробник керування службою з відповідним кодом керування.

 

BOOL ControlService (

SC_HANDLE hService,

DWORD ControlCode,

LPSERVICE_STATUS pServStat)

 

Якщо доступ дозволений, ControlCode має одне із наступних значень:

 

SERVICE_CONTROL_STOP

SERVICE_CONTROL_PAUSE

SERVICE_CONTROL_CONTINUE

SERVICE_CONTROL_INTERROGATE

SERVICE_CONTROL_SHUTDOWN

або вказане користувачем значення в діапазоні 128-255. Це ті ж значення, які використовувалися для прапора fdwControl в функції ServerCtrlHandler.

pServStat вказує на структуру SERVICE_STATUS, яка отримує поточний стан. Ця ж структура, що використовується в функції SetServiceStatus.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: