Similar presentations:
Работа с сервисами в Windows. Тема 6.2
1.
Тема 6.2. Работа ссервисами в Windows
2.
Открытие доступа к базе данных сервисов• Для установки связи с менеджером сервисов и открытия доступа
к базе данных сервисов используется функция OpenSCManager,
которая имеет следующий прототип:
SC_HANDLE OpenSCManager( LPCTSTR lpMachineName, // имя
компьютера
LPCTSTR lpDatabaseName, // имя базы данных сервисов
DWORD dwDesiredAccess // тип доступа );
• В случае успешного завершения функция возвращает дескриптор
базы данных сервисов, а в случае неудачи — null.
3.
Открытие доступа к базе данных сервисовПараметры функции OpenSCManager:
• Параметр lpMachineName должен содержать адрес строки с
именем компьютера, на котором находится база данных
сервисов.
• Имени компьютера должны предшествовать символы \\.
• Если этот параметр содержит null или указывает на пустую строку,
то предполагается, что база данных расположена на локальном
компьютере.
4.
Открытие доступа к базе данных сервисовПараметры функции OpenSCManager:
• Параметр lpDatabaseName должен содержать адрес строки с
именем базы данных сервисов.
• Если этот параметр равен null, тo открывается активная база
данных сервисов.
5.
Открытие доступа к базе данных сервисовПараметры функции OpenSCManager:
• Параметр dwDesiredAccess должен содержать тип доступа к базе
данных.
• Этот параметр может принимать любую комбинацию следующих
флагов:
• sc_manager_all_access — любой из нижеперечисленных доступов;
• sc_manager_connect — связь с менеджером сервисов;
• sc_manager_create_service — установка сервиса;
• sc_manager_enumerate_service — просмотр сервисов в базе данных;
• sc_manager_lock — запирание базы данных сервисов;
• sc_manager_query_lock_status — определение состояния базы данных.
• Флаг sc_manager_connect считается установленным по умолчанию, а
флаг sc_manager_all_access включает в себя флаг
STANDARD_RIGHTS_REQUIRED.
6.
Открытие доступа к базе данных сервисов• Для использования в этом параметре также определены флаги,
обозначающие следующие родовые права доступа к базе данных
сервисов:
• generic_read — включает следующие флаги: standard_rights_read,
sc_manager_enumerate_service и sc_manager_query_lock_status;
• generic_write — включает флаги standard_rights_write и
sc_manager_create_service;
• generic_execute — включает следующие флаги: standard_rights_execute,
sc_manager_connect и sc_manager_lock.
7.
Открытие доступа к базе данных сервисов• После окончания работы с менеджером сервисов или сервисом
нужно закрыть его дескриптор.
• Для этой цели предназначена функция CloseServiceHandle,
которая имеет следующий прототип:
BOOL CloseServiceHandle( SC_HANDLE hSCObject // дескриптор
менеджера сервисов или сервиса );
• В случае успешного завершения эта функция возвращает
ненулевое значение, а в случае неудачи — false.
• Единственным параметром этой функции является дескриптор
менеджера сервисов или дескриптор сервиса.
8.
Установка сервиса• Для установки сервисов в базу данных используется функция createService, которая имеет
следующий прототип:
SC_HANDLE CreateService( SC_HANDLE hSCManager // дескриптор базы данных сервисов
LPCTSTR IpServiceName // внутреннее имя сервиса
LPCTSTR lpDisplayName // внешнее имя сервиса
DWORD dwDesiredAccess // разрешаемый доступ к сервису
DWORD dwServiceType // тип сервиса
DWORD dwStartType // способ запуска сервиса
DWORD dwErrorControl // режим обработки ошибок
LPCTSTR lpBinaryPathName // имя бинарного файла сервиса
LPCTSTR lpLoadOrderGroup // имя группы загрузки сервисов
LPDWORD lpdwTagld // тег сервиса в группе
LPCTSTR lpDependencies // массив имен сервисов
LPCTSTR IpServiceStartName // имя пользователя
LPCTSTR lpPassword // пароль пользователя
);
9.
Установка сервиса• В случае успешного завершения функция возвращает дескриптор
установленного сервиса, а в случае неудачи — null.
• Параметр hscManager должен содержать дескриптор менеджера
сервисов, который был предварительно открыт функцией
OpenSCManager.
10.
Установка сервиса• Параметр lpServiceName должен указывать на строку с именем
сервиса, которое используется менеджером сервисов.
• Имена сервисов не чувствительны к верхнему и нижнему
регистрам.
• Длина имени не может превышать 256 символов.
• Имя сервиса не может содержать символы / и \.
• Параметр lpDisplayName должен указывать на имя сервиса,
которое используется в панели управления Windows для ссылок
на сервис.
• В этом имени различаются верхний и нижний регистры, а его
длина не может превышать 256 символов.
11.
Установка сервиса• В параметре dwDesiredAccess должны быть установлены флаги, которые определяют доступ
к сервису.
• Возможна любая комбинация следующих флагов:
delete — разрешено удаление сервиса;
service_change_config — разрешено изменять конфигурацию сервиса;
service_enumerate_dependents — разрешено просматривать зависимые сервисы;
service_interrogate — разрешено запрашивать состояние сервиса;
service_pause_continue — разрешено приостанавливать и возобновлять сервис;
service_query_config — разрешено запрашивать конфигурацию сервиса;
service_query_status — разрешено запрашивать состояние сервиса;
service_start — разрешено запускать сервис;
service_stop — разрешено останавливать сервис;
service_user_defined_control — разрешено использовать управляющие команды пользователя.
• Для обеспечения возможности работы с атрибутами защиты сервиса нужно установить
комбинированный флаг standard_rights_required — стандартные права доступа, который
также включает флаг delete.
• Также можно использовать флаг service_all_access — полный доступ, который включает
флаг standard_rights_required и все перечисленные выше флаги.
12.
Установка сервиса• Дополнительно существуют следующие родовые права доступа,
которые можно установить в этом параметре:
• generic_read — включает флаги standard_rights_read, service_
query_config, service_query_status, service_interrogate и service_
enumerate_dependents;
• generic_write — включает флаги standard_rights_write и service_
change_config;
• generic_execute — включает флаги standard_rights_execute, service_start,
service_stop, service_pause_continue и service_user_defined_control.
13.
Установка сервиса• В параметре dwServiceType задается тип сервиса.
• Этот параметр может принимать одно из следующих значений:
• service_win32_own_process — отдельный процесс;
• service_win32_share_process — разделяет процесс с другими сервисами;
• service_kernel_driver — драйвер ядра;
• service_file_system_driver — драйвер файловой системы.
• В случае если сервис не является драйвером, то может быть
также установлен флаг service_interactive_process —
интерактивный процесс, который разрешает сервису
взаимодействовать с рабочим столом.
14.
Установка сервиса• В параметре dwstartType должен быть установлен режим запуска
сервиса.
• Этот параметр может принимать одно из следующих значений:
• service_boot_start — запуск драйвера при загрузке системы;
• service_system_start — запуск драйвера функцией ioinitsystem;
• service_auto_start — запуск сервиса менеджером сервисов при загрузке
системы;
• service_demand_start — запуск сервиса функцией startservice;
• service_disabled — сервис не может быть запущен.
• Первые два флага могут быть установлены только для драйверов.
15.
Установка сервиса• В параметре dwErrorcontroi устанавливается режим обработки
ошибок, произошедших во время запуска сервиса, если этот сервис
запускается во время загрузки системы.
• В этом параметре должно быть установлено одно из следующих
значений:
• service_error_ignore — игнорировать ошибку;
• service_error_normal — игнорировать ошибку и сообщить об этом в окне
ошибок;
• service_error_severe — продолжить или перезагрузиться в безопасной
конфигурации;
• service_error_critical — прервать загрузку и перезагрузиться в безопасной
конфигурации.
• В последнем случае если ошибка произошла при загрузке системы в
безопасной конфигурации, то загрузка прекращается.
16.
Установка сервиса• Параметр lpBinaryPathName должен указывать на имя исполняемого ехефайла, который содержит сервис.
• Рекомендуется, чтобы это имя заканчивалось символом \.
• Параметр lpLoadOrderGroup должен указывать на имя группы, содержащей
порядок загрузки сервисов и в которую входит сервис.
• Если сервис не зависит от других сервисов, то в этом параметре должно
быть установлено значение NULL.
• В параметре lpdwTagid должен быть задан адрес переменной типа dword, по
которому функция помещает тег сервиса в группе загрузки.
• Этот тег может в дальнейшем использоваться для определения порядка
запуска сервисов.
• Если тег не используется, то этот параметр нужно установить в null.
• При тег может использоваться только для драйверов, для которых задан
режим загрузки service_boot_start или service_system_start.
17.
Установка сервиса• Параметр lpDependencies должен указывать на массив строк,
каждая из которых содержит имя сервиса или имя группы
сервисов, которые система должна запустить перед запуском
устанавливаемого сервиса.
• Если сервис не зависит от других сервисов, то в этом параметре
должно быть установлено значение null.
• Имя группы должно начинаться с префикса sc_group_identifier,
чтобы отличить это имя от имени сервиса.
18.
Установка сервиса• Параметр lpServicestartName должен указывать на строку с именем
сервиса.
• Если сервис является процессом, то этот параметр должен указывать
на имя пользователя, под которым будет запущен сервис.
• Если сервис запускается под текущим локальным именем, то этот
параметр должен быть установлен в null.
• Сервис, взаимодействующий с рабочим столом, должен быть запущен
только под текущим именем пользователя.
• Параметр lpPassword должен указывать на строку с паролем
пользователя, под именем которого запускается сервис.
• Если сервис запускается под именем текущего пользователя, то в этом
параметре должно быть установлено значение null.
19.
20.
• После окончания работы с сервисом нужно закрыть егодескриптор, используя для этого функцию CloseServiceHandle.
• Эта функция не уничтожает сервис, а только разрывает связь
прикладной программы с этим сервисом.
• Для удаления сервиса из базы данных нужно использовать
функцию DeleteService.
21.
Открытие доступа к сервису• Для открытия доступа к уже установленному сервису
используется функция openservice, которая имеет следующий
прототип:
SC_HANDLE OpenService( SC_HANDLE hSCManager, // дескриптор
базы данных сервисов
LPCTSTR IpServiceName, // имя сервиса
DWORD dwDesiredAccess // требуемый доступ к сервису
);
• В случае успешного завершения функция возвращает дескриптор
сервиса, а в случае неудачи — null.
22.
Открытие доступа к сервису• Параметр hscManager должен содержать дескриптор базы
данных сервисов, связь с которой была предварительно
установлена вызовом функции OpenSCManager.
• Параметр lpServiceName должен указывать на строку с именем
сервиса.
• В параметре dwDesiredAccess устанавливаются флаги доступа к
сервису.
• Флаги доступа, которые можно установить в этом параметре,
совпадают с флагами, которые можно установить в параметре
dwDesiredAccess функции createservice.
23.
Запуск сервиса• Для запуска сервиса используется функция startservice, которая
имеет следующий прототип:
BOOL Startservice( SC_HANDLE hService, // дескриптор сервиса
DWORD dwNumServiceArgs, // количество аргументов
LPCTSTR *lpServiceArgVectors // массив аргументов
• В случае удачного завершения функция возвращает ненулевое
значение, а в случае неудачи — false.
24.
Запуск сервиса• В параметре hservice должен быть установлен дескриптор сервиса,
который был предварительно получен функциями CreateService или
OpenService.
• Параметр dwNumServiceArgs должен содержать количество
аргументов, которые передаются сервису.
• Каждый из аргументов является символьной строкой. Если аргументов
нет, то в параметре должно быть установлено значение ноль.
• Параметр lpServiceArgVectors должен содержать адрес массива,
каждый элемент которого является указателем на строку.
• Эти строки и являются аргументами, которые передаются функции
сервиса serviceMain.
• Если аргументов нет, то этот параметр должен быть установлен в null.
25.
Запуск сервиса• Во время работы функции startservice менеджер сервисов
устанавливает следующие состояния сервиса в структуре
service_status:
• в поле dwcurrentstate устанавливает значение service_start_pending;
• в поле dwControisAccepted устанавливает значение ноль, что запрещает
обработку управляющих команд;
• в поле dwcheckPoint устанавливает значение ноль;
• в поле dwWaitHint устанавливает значение, равное двум секундам.
• Во время работы функции startservice менеджер запросов
блокирует базу данных сервисов.
26.
Определение и изменение состояниясервиса
• Для определения состояния сервиса используется функция
QueryServicestatus, которая имеет следующий прототип:
BOOL QueryServicestatus( SC_HANDLE hService, // дескриптор сервиса
LPSERVICE_STATUS IpServiceStatus // адрес структуры
SERVICE_STATUS
);
• В случае успешного завершения функция возвращает ненулевое
значение, а в случае неудачи — false.
• В параметре hservice должен быть установлен дескриптор сервиса,
который предварительно получен функцией CreateService ИЛИ
OpenService.
27.
Определение и изменение состояниясервиса
• Параметр ipservicestatus должен указывать на структуру типа service_status, которая
содержит информацию о состоянии сервиса.
• Эта структура имеет следующий формат:
typedef struct _SERVICE_STATUS {
DWORD dwServiceType; // тип сервиса
DWORD dwCurrentState; // текущее состояние сервиса
DWORD dwControlsAccepted; // допускаемое управление
DWORD dwWin32ExitCode; // код возврата для Win32
DWORD dwServiceSpecificExitCode; // специфический код возврата сервиса
DWORD dwCheckPoint; // контрольная точка
DWORD dwWaitHint; // период ожидания команды управления
}
SERVICE_STATUS, * LPSERVICE_STATUS;
28.
Определение и изменение конфигурациисервиса
• Под конфигурацией сервиса понимается информация, которая описывает
внутреннее и внешнее имена сервиса, режимы его запуска и работы.
• Для определения конфигурации сервиса используется функция
QueryServiceConfig, которая имеет следующий прототип:
BOOL QueryServiсеСonfig(
SC_HANDLE hService, // дескриптор сервиса
LPQUERY_SERVICE_CONFIG IpServiceConfig, // указатель на буфер
DWORD dwBufferSize, // размер буфера
LPDWORD lpdwBytesNeeded // необходимая длина буфера
);
• В случае успешного завершения функция возвращает ненулевое значение, а
в случае неудачи — false.
29.
Определение и изменение конфигурациисервиса
• Параметр hService должен содержать дескриптор сервиса,
который был предварительно открыт при помощи функции
CreateService или OpenService.
• Параметр IpServiceConf ig должен указывать на область памяти, в
которую функция поместит информацию о конфигурации сервиса
в случае своего успешного завершения.
30.
Определение и изменение конфигурациисервиса
• Эта информация будет храниться в формате, который определяется следующей структурой:
typedef struct _QUERY_SERVICE_CONFIG {
DWORD dwServiceType; // тип сервиса
DWORD dwStartType; // режим запуска сервиса
DWORD dwErrorControl; // режим обработки ошибок при запуске
LPSTR lpBinaryPathName; // имя бинарного файла сервиса
LPSTR lpLoadOrderGroup; // информация о порядке загрузки сервисов
DWORD dwTagld; // тег сервиса в группе загрузки
LPSTR lpDependencies ; // информация о порядке запуска сервисов
LPSTR IpServiceStartName// имя пользователя, который запускает сервис
LPSTR lpDisplayName; // имя сервиса в окне управления сервисами
} QUERY_SERVICE_CONFIG, *LPQUERY_SERVICE_CONFIG;
• В поля этой структуры записываются те значения, которые были установлены в
соответствующих параметрах при вызовах функций CreateService И OpenService.
31.
• Для изменения конфигурации сервиса можно использовать функцию ChangeServiceConfig, которая имеетследующий прототип:
BOOL ChangeServiceConfig(
SC_HANDLE hService, // дескриптор сервиса
DWORD dwServiceType, // тип сервиса
DWORD dwStartType, // режим запуска сервиса
DWORD dwErrorControl, // режим обработки ошибок при запуске
LPCSTR lpBinaryPathName, // имя бинарного файла сервиса
LPCSTR lpLoadOrderGroup, // информация о порядке загрузки сервисов
LPDWORD lpdwTagld, // тег сервиса в группе загрузки
LPCSTR lpDependencies, // информация о порядке запуска сервисов
LPCSTR IpServiceStartName, // имя пользователя
LPCSTR lpPassword, // пароль пользователя
LPCSTR lpDisplayName // имя сервиса в окне управления сервисами
);
• В случае удачного завершения функция возвращает ненулевое значение, а в случае неудачи — false.
32.
Определение имени сервиса• Назовем внутренним именем сервиса то имя, под которым сервис хранится в базе
данных сервисов, а также используется менеджером сервисов для ссылок на этот
сервис.
• Узнать внутреннее имя сервиса можно при помощи функции GetServiceKeyName,
которая имеет следующий прототип:
BOOL GetServiceKeyName (
SC_HANDLE hSCManager, // дескриптор базы данных сервисов
LPCSTR lpDisplayName, // указатель на внешнее имя сервиса
LPSTR IpServiceName, // указатель на внутреннее имя сервиса
LPDWORD lpdwBuffer // размер памяти для внутреннего имени
);
• В случае успешного завершения функция возвращает ненулевое значение, а в
случае неудачи — false.
33.
Определение имени сервиса• В параметре hscManager должен быть установлен дескриптор базы
данных сервисов, которая была предварительно открыта функцией
OpenSCManager.
• Параметр lpDispiayName должен указывать на строку с именем
сервиса, которое используется в окне управления сервисами,
вызываемом из Start | Settings | Control Panel | Administrative Tools |
Services (Пуск | Настройка j Панель управление | Администрирование
| Службы).
• Параметр lpServiceName должен указывать на область памяти, куда
функция запишет внутреннее имя сервиса, т. е. имя, которое
используется для ссылок менеджером сервисов.
• В случае удачного завершения функция записывает в эту память
внутреннее имя сервиса.
34.
Определение имени сервиса• Параметр lpdwBuffer должен указывать на двойное слово, в
котором установлена длина области памяти, на которую
указывает параметр lpServiceName.
• Функция записывает по этому адресу фактическую длину
внутреннего имени сервиса, исключая завершающий пустой
символ.
35.
• Внешнее имя сервиса - то имя, которое используется для ссылок на сервис вокне управления сервисами.
• Узнать внешнее имя сервиса можно с помощью функции
GetServiceDisplayName, которая имеет следующий прототип:
BOOL GetServiceDisplayName{
SC_HANDLE hSCManager, // дескриптор базы данных сервисов
LPCSTR IpServiceName, // указатель на внутреннее имя сервиса
LPSTR lpDisplayName, // указатель на внешнее имя сервиса
LPDWORD lpdwBuffer // размер памяти для внешнего имени
);
• В случае успешного завершения функция возвращает ненулевое значение, а
в случае неудачи — false.
36.
• В параметре hscManager должен быть установлен дескриптор базыданных сервисов, которая была предварительно открыта функцией
OpenSCManager.
• Параметр IpServiceName должен указывать на строку с внутренним
именем сервиса, под которым сервис хранится в базе данных.
• Параметр lpDisplayName должен указывать на область памяти, куда
функция запишет внешнее имя сервиса, т. е. имя, которое
используется для ссылок на сервис в окне управления сервисами.
• Параметр lpdwBuffer должен указывать на переменную типа dword, в
котором установлена длина области памяти, на которую указывает
параметр lpDisplayName.
• Функция записывает по этому адресу фактическую длину внешнего
имени сервиса, исключая завершающий пустой символ.
37.
38.
Управление сервисом• Приложение может послать сервису управляющую команду, которая будет
передана обработчику управляющих команд сервиса.
• Для этой цели используется функция controiservice, которая имеет
следующий прототип:
BOOL Controiservice(
SC_HANDLE hService, // дескриптор сервиса
DWORD dwControl, // управляющий код
LPSERVICE_STATUS IpServiceStatus // адрес структуры
SERVICE_STATUS
);
• В случае успешного завершения функция controiservice возвращает
ненулевое значение, а в случае неудачи — false.
39.
Управление сервисом• Параметр hservice должен содержать дескриптор сервиса,
который был предварительно получен вызовом функции
CreateService или OpenService.
• Параметр dwcontroi должен содержать код управляющей
команды, который может принимать одно из следующих
значений:
• service_control_stop — остановить сервис;
• service_control_pause — приостановить сервис;
• SERVICE_CONTROL_CONTINUE — ВОЗОбнОВИТЬ СерВИС,
• SERVICE_CONTROL_INTERROGATE — обновить состояние сервиса.
40.
Управление сервисом• Сервису можно послать управляющие команды, коды которых
заданы пользователем.
• Для задания таких команд зарезервирован диапазон от 128 до
255.
• Сервис может обрабатывать такие команды только в том случае,
если при создании сервиса в параметре dwDesiredAccess
установлен флаг SERVICE_USER_DEFINED_CONTROL.
41.
42.
Удаление сервисов• Для удаления сервиса из базы данных сервисов служит функция
DeleteService, которая имеет следующий прототип:
• BOOL DeleteService(
• SC_HANDLE hService // дескриптор сервиса
• В случае успешного завершения функция возвращает ненулевое
значение, а в случае неудачи — false.
• Единственный параметр hservice этой функции должен содержать
дескриптор сервиса, который был предварительно получен вызовом
функции CreateService или OpenService.
• Если сервис работает, то он не удаляется из базы данных до тех пор,
пока не будет остановлен.
43.
Блокирование базы данных сервисов• Для получения монопольного доступа к базе данных сервисов процесс может
заблокировать доступ других процессов к этой базе данных, используя функцию
LockserviceDatabase, которая имеет следующий прототип:
• SC_LOCK LockserviceDatabase(
• SC_HMIDLE hSCManager // дескриптор базы данных сервисов
• );
• В случае успешного завершения функция возвращает дескриптор блокирования
базы данных сервисов, а в случае неудачи — null.
• Единственный параметр hSCManager этой функции должен содержать дескриптор
базы данных сервисов, доступ к которой блокируется функцией.
• Эта база данных сервисов должна быть предварительно открыта для доступа
вызовом функции openscManager.
• Причем база данных сервисов должна быть открыта С КЛЮЧОМ
SC_MANAGER_LOCK.
44.
Блокирование базы данных сервисов• Для разблокирования доступа к базе данных сервисов используется
функция unockserviceDatabase, которая имеет следующий прототип:
• BOOL UnlockServiceDatabase(
• SC_LOCK hSCLock // дескриптор блокирования базы данных сервисов );
• В случае успешного завершения функция возвратит ненулевое
значение, а в случае неудачи — false.
• Единственный параметр этой функции должен содержать дескриптор
блокирования базы данных сервисов, который был предварительно
получен вызовом функции LockserviceDatabase.
45.
Блокирование базы данных сервисов• Для того чтобы узнать заблокирована база данных сервисов или нет, используется
функция QueryServiceLockstatus, которая имеет следующий прототип:
BOOL QueryServiceLockstatus(
SC_HANDLE hSCManager, // дескриптор базы данных сервисов
LPQUERY_SERVICE_LOCK_STATUS IpLockstatus, // информация о блокировке
DWORD dwBufSize, // размер буфера для информации
LPDWORD lpdwBytesNeeded // количество необходимых байтов
);
• В случае успешного завершения функция возвращает ненулевое значение, а в
случае неудачи — false.
• Параметр hscManager должен содержать дескриптор базы данных сервисов,
который был предварительно получен вызовом функции OpenSCManager.
• Причем база данных сервисов должна быть открыта с ключом
SC_MANAGER_QUERY_LOCK_STATUS.
46.
Блокирование базы данных сервисов• Параметр IpLockstatus должен указывать на область памяти, куда
система поместит информацию о блокировании базы данных
сервисов.
• Эта информация будет записана в структуру типа
query_service_lock_status, которая имеет следующий формат:
typedef Struct _QUERY_SERVICE_LOCK_STATUSA {
DWORD flsLocked; // состояние блокировки
LPSTR lpLockOwner; // владелец блокировки
DWORD dwLockDuration; // время блокировки
}
QUERY_SERVICE_LOCK_STATUS, *LPQUERY_SERVICE_LOCK_STATUS;
47.
Блокирование базы данных сервисов• В поле flsLocked хранится состояние блокировки базы данных
сервисов.
• Если значение этого поля равно нулю, то база данных не
заблокирована.
• В противном случае база данных заблокирована.
• Если база данных сервисов заблокирована, то в поле lpLockOwner
записывается адрес строки, которая содержит имя пользователя,
заблокировавшего базу данных.
• Если база данных сервисов заблокирована, то в поле dwLockDuration
хранится целое число без знака, которое определяет
продолжительность блокирования базы данных в секундах.
48.
Блокирование базы данных сервисов• В параметре dwBufsize должен быть установлен размер памяти,
на которую указывает параметр ipLockstatus.
• Параметр lpdwBytesNeeded должен указывать на двойное слово,
в которое функция в случае своего неудачного завершения
поместит необходимый размер буфера для информации о
блокировании базы данных сервисов.