Использование базового API (dcm_api.h)
Сведения о функциях API приведены в таблице ниже.
Динамическое создание IPC-канала на стороне сервера
Динамическое создание IPC-канала на стороне сервера включает следующие шаги:
- Создать подключение к
DCM
вызовом функцииDcmInit()
. - Опубликовать предоставляемые службы в
DCM
, используя функциюDcmPublishEndpoint()
.В параметре
serverHandle
функцииDcmPublishEndpoint()
нужно указать дескриптор, идентифицирующий сервер. В качестве дескриптора, идентифицирующего сервер, можно использовать дескриптор этого серверного процесса, полученный последовательностью вызовов функцийKosTaskGetSelf()
иKosTaskGetHandle()
из API task.h, или дескриптор, созданный вызовом функцииKnHandleCreateUserObject()
из API handle_api.h. (При вызове функцииKnHandleCreateUserObject()
в параметреrights
должны быть указаны флагиOCAP_HANDLE_TRANSFER
иOCAP_HANDLE_GET_SID
.) Можно опубликовать несколько служб, указывая один и тот же или разные дескрипторы, идентифицирующие сервер. (Клиенты могут получить потомков этих дескрипторов через опциональный параметрoutServerHandle
функцииDcmReadPubQueue()
.) После публикации служб дескриптор, идентифицирующий сервер, можно закрыть.В результате вызова функции
DcmPublishEndpoint()
создается DCM-дескриптор, позволяющий получать запросы клиентов на создание IPC-каналов для использования заданной службы с заданным интерфейсом.Чтобы отменить публикацию службы, нужно вызовом функции
DcmCloseHandle()
закрыть DCM-дескриптор, созданный при ее публикации. Также публикация всех опубликованных служб сервера будет отменена, если сервер завершится. - Получить запрос клиента на создание IPC-канала вызовом функции
DcmListen()
.Вызовы функции
DcmListen()
с одним и тем же DCM-дескриптором в параметреpubHandle
позволяют получить только те запросы клиентов, которые направлены на создание IPC-каналов для использования той службы с тем интерфейсом, которые были заданы при создании этого DCM-дескриптора на шаге 2.Через опциональные параметры
outClientHandle
иoutClientName
функцииDcmListen()
можно получить дескриптор, идентифицирующий клиента, и имя клиента соответственно. (Дескриптор, идентифицирующий клиента, является потомком дескриптора, указанного в параметреclientHandle
функцииDcmCreateConnection()
, вызванной на стороне клиента.) Эти данные можно использовать, чтобы принять решение о принятии или отклонении запроса клиента. При этом дескриптор, идентифицирующий клиента, может быть использован, например, для получения сведений о клиенте от других процессов или для получения SID по этому дескриптору для сравнения с другими имеющимся у сервера дескрипторами, идентифицирующими клиентов. После принятия решения можно закрыть дескриптор, идентифицирующий клиента.В результате вызова функции
DcmListen()
создается DCM-дескриптор, позволяющий принять или отклонить запрос клиента на создание IPC-канала. - Принять запрос клиента на создание IPC-канала вызовом функции
DcmAccept()
.В параметре
connectionId
функцииDcmAccept()
нужно указать DCM-дескриптор, полученный на шаге 3.В параметре
sessionHandle
функцииDcmAccept()
нужно указать callable-дескриптор для передачи клиенту. Чтобы создать callable-дескриптор, нужно вызвать функциюKnHandleCreateUserObjectEx()
из API handle_api.h. (При вызове функцииKnHandleCreateUserObjectEx()
в параметреrights
должны быть указаны флагиOCAP_IPC_CALL
иOCAP_HANDLE_TRANSFER
, а в параметрахipcChannel
иriid
требуется указать серверный IPC-дескриптор создаваемого IPC-канала и идентификатор службы (RIID) соответственно. Серверный IPC-дескриптор используется для инициализации IPC-транспорта и управления обработкой IPC-запросов на стороне сервера. Для создания серверного дескриптора можно использовать функциюKnHandleCreateListener()
из API handle_api.h. Идентификатор службы является константой в автоматически генерируемом транспортном коде, например,FsDriver_operationsComp_fileOperations_iid
.) После принятия запроса клиента callable-дескриптор можно закрыть.Передачу callable-дескриптора клиенту можно ассоциировать с объектом контекста передачи ресурса, указав дескриптор этого объекта в параметре
badgeHandle
функцииDcmAccept()
. Это позволит, используя API notice_api.h, отследить, когда будут закрыты или отозваны потомки callable-дескриптора, которые образуют поддерево наследования дескрипторов, корневой узел которого порожден передачей клиенту этого callable-дескриптора. (Переданный callable-дескриптор может быть закрыт клиентом, но также закрытие этого дескриптора выполняется в результате завершения клиента.) Чтобы создать объект контекста передачи ресурса, нужно вызвать функциюKnHandleCreateBadge()
из API handle_api.h.Через параметр
context
функцийKnHandleCreateUserObjectEx()
иKnHandleCreateBadge()
можно задать данные для ассоциации с callable-дескриптором и передачей callable-дескриптора соответственно (аналогично контексту пользовательского ресурса и контексту передачи ресурса). Сервер сможет получить указатель на эти данные при разыменовании callable-дескриптора. (Несмотря на то что callable-дескриптор является IPC-дескриптором, он помещается ядром в полеbase_.self
фиксированной части IPC-запроса.)Один и тот же callable-дескриптор можно использовать, чтобы принять несколько запросов одного или нескольких клиентов.
Чтобы отклонить запрос клиента на создание IPC-канала, нужно вызовом функции
DcmCloseHandle()
закрыть DCM-дескриптор, полученный на шаге 3. (При этом вызов функцииDcmConnect()
на стороне клиента завершится с ошибкойrcNotConnected
.) В случае принятия запроса клиента DCM-дескриптор, полученный на шаге 3, нужно также закрыть, но после вызова функцииDcmAccept()
.
Динамическое создание IPC-канала на стороне клиента
Динамическое создание IPC-канала на стороне клиента включает следующие шаги:
- Создать подключение к
DCM
вызовом функцииDcmInit()
. - Создать DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации служб с заданным интерфейсом.
Чтобы выполнить этот шаг, нужно вызвать функцию
DcmSetSubscription()
.Опциональные параметры
endpointName
,serverName
иserverHandle
функцииDcmSetSubscription()
нужно использовать, чтобы включить фильтрацию уведомлений по квалифицированному имени службы, имени сервера и дескриптору, идентифицирующему сервер, соответственно. (Дескриптор, идентифицирующий сервер, является потомком дескриптора, указанного в параметреserverHandle
функцииDcmPublishEndpoint()
, вызванной на стороне сервера. Клиент может получить этот дескриптор, например, от другого процесса.)В результате вызова функции
DcmSetSubscription()
создается DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации служб с заданным интерфейсом. При этом формируется очередь уведомлений о публикации служб, которые были опубликованы до вызоваDcmSetSubscription()
и соответствуют критериям фильтрации. Если больше не требуется получать уведомления о публикации и отмене публикации служб с заданным интерфейсом, то этот DCM-дескриптор нужно закрыть вызовом функцииDcmCloseHandle()
. - Извлечь уведомление о публикации службы из очереди этих уведомлений вызовом функции
DcmReadPubQueue()
.В параметре
subscrHandle
функцииDcmReadPubQueue()
нужно указать DCM-дескриптор, полученный на шаге 2.Через опциональные параметры
outServerHandle
,outServerName
иoutEndpointName
функцииDcmReadPubQueue()
можно получить дескриптор, идентифицирующий сервер, имя сервера и квалифицированное имя службы соответственно. (Дескриптор, идентифицирующий сервер, является потомком дескриптора, указанного в параметреserverHandle
функцииDcmPublishEndpoint()
, вызванной на стороне сервера.) Эти данные можно использовать, чтобы принять решение о выполнении запроса на создание IPC-канала с сервером. При этом дескриптор, идентифицирующий сервер, может быть использован, например, для получения сведений о сервере от других процессов или для получения SID по этому дескриптору для сравнения с другими имеющимися у клиента дескрипторами, идентифицирующими серверы.Значение, полученное через параметр
outPubStatus
функцииDcmReadPubQueue()
, отражает, что служба опубликована, или публикация службы отменена. Уведомление об отмене публикации службы появляется, если сервер отменил публикацию этой службы, а также при завершении сервера. - Создать DCM-дескриптор, позволяющий выполнить запрос на создание IPC-канала с сервером.
Чтобы выполнить этот шаг, нужно вызвать функцию
DcmCreateConnection()
.В параметре
serverHandle
функцииDcmCreateConnection()
нужно указать дескриптор, идентифицирующий сервер. Этот дескриптор может быть получен на шаге 3 через параметрoutServerHandle
функцииDcmReadPubQueue()
или другим способом (например, от другого процесса).В параметре
clientHandle
функцииDcmCreateConnection()
нужно указать дескриптор, идентифицирующий клиента. В качестве дескриптора, идентифицирующего клиента, можно использовать дескриптор этого клиентского процесса, полученный последовательностью вызовов функцийKosTaskGetSelf()
иKosTaskGetHandle()
из API task.h, или дескриптор, созданный вызовом функцииKnHandleCreateUserObject()
из API handle_api.h. (При вызове функцииKnHandleCreateUserObject()
в параметреrights
должны быть указаны флагиOCAP_HANDLE_TRANSFER
иOCAP_HANDLE_GET_SID
.) Можно создать несколько DCM-дескрипторов, позволяющих выполнить запрос на создание IPC-канала, указывая в параметреclientHandle
функцииDcmCreateConnection()
один и тот же или разные дескрипторы, идентифицирующие клиента. (Серверы могут получить потомков этих дескрипторов через опциональный параметрoutClientHandle
функцииDcmListen()
.) После создания DCM-дескриптора, позволяющего выполнить запрос на создание IPC-канала, дескриптор, идентифицирующий клиента, можно закрыть.В результате вызова функции
DcmCreateConnection()
создается DCM-дескриптор, позволяющий выполнить запрос на создание IPC-канала с сервером для использования заданной службы с заданным интерфейсом. - Выполнить запрос на создание IPC-канала с сервером вызовом функции
DcmConnect()
.В параметре
connectionId
нужно указать DCM-дескриптор, полученный на шаге 4.В результате вызова функции
DcmConnect()
клиент получает через параметрoutSessionHandle
callable-дескриптор. Клиент использует этот дескриптор для инициализации IPC-транспорта. При этом в функции инициализации прокси-объекта клиент указывает значениеINVALID_RIID
в качестве идентификатор службы (RIID).После получения callable-дескриптора DCM-дескриптор, полученный на шаге 4, нужно закрыть вызовом функции
DcmCloseHandle()
.
Прерывание блокирующих вызовов функций
Чтобы прервать блокирующий вызов функции DcmConnect()
, DcmReadPubQueue()
или DcmListen()
из другого потока исполнения, нужно вызвать функцию DcmInterruptBlockingCall()
.
Использование уведомлений
Используя функции DcmSubscribeToEvents()
и DcmUnsubscribeFromEvents()
совместно с функциями из API notice_api.h, можно получать уведомления о том, что произошли следующие события: публикация или отмена публикации сервером службы в DCM
(флаг DCM_PUBLICATION_CHANGED
), получение сервером запроса от клиента на создание IPC-канала (флаг DCM_CLIENT_CONNECTED
), прерывание блокирующего вызова функции DcmConnect()
, DcmReadPubQueue()
или DcmListen()
(флаг DCM_BLOCKING_CALL_INTERRUPTED
), прием или отклонение сервером запроса клиента на создание IPC-канала (флаг DCM_CLIENT_RELEASED_BY_SERVER
). (Флаги маски событий и идентификатор записи вида "ресурс – маска событий" DCM_EVENT_ID
определены в заголовочном файле sysroot-*-kos/include/dcm/dcm_api.h
из состава KasperskyOS SDK.) Функции DcmSubscribeToEvents()
и DcmUnsubscribeFromEvents()
позволяют настроить приемник уведомлений, соответственно добавляя и удаляя отслеживаемые объекты, идентифицируемые DCM-дескрипторами.
Удаление динамически созданных IPC-каналов
Динамически созданный IPC-канал будет удален при закрытии callable-дескриптора и серверного IPC-дескриптора этого IPC-канала.
Удаление подключения к DCM
Если использовать DCM
больше не требуется, нужно вызвать функцию DcmFini()
, чтобы удалить подключение к DCM
и тем самым освободить связанные с этим подключением ресурсы.
Сведения о функциях API
Функции dcm_api.h
Функция |
Сведения о функции |
---|---|
|
Назначение Создает подключение к Параметры Нет. Возвращаемые значения В случае успеха возвращает Если IPC-канал до Дополнительные сведения Потокобезопасная функция. Неблокирующий вызов. |
|
Назначение Удаляет подключение к Параметры Нет. Возвращаемые значения Нет. Дополнительные сведения Потокобезопасная функция. Неблокирующий вызов. |
|
Назначение Настраивает приемник уведомлений, чтобы он получал уведомления о событиях, связанных с объектом, идентифицируемым заданным DCM-дескриптором. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Настраивает приемник уведомлений, чтобы он не получал уведомления о событиях, связанных с объектом, идентифицируемым заданным DCM-дескриптором. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Закрывает DCM-дескриптор, полученный вызовом функции Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Прерывает блокирующий вызов функции Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Создает DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации служб с заданным интерфейсом. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Извлекает уведомление о публикации или отмене публикации службы из очереди этих уведомлений. Параметры
Возвращаемые значения В случае успеха возвращает Если блокирующий вызов был прерван вызовом функции Дополнительные сведения Неблокирующий вызов, если в параметре |
|
Назначение Создает DCM-дескриптор, позволяющий выполнить запрос на создание IPC-канала с сервером для использования заданной службы с заданным интерфейсом. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Выполняет запрос на создание IPC-канала с сервером. Параметры
Возвращаемые значения В случае успеха возвращает Если в параметре Если блокирующий вызов был прерван вызовом функции Дополнительные сведения Неблокирующий вызов, если в параметре |
|
Назначение Публикует службу в Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить запрос клиента на создание IPC-канала. Параметры
Возвращаемые значения В случае успеха возвращает Если блокирующий вызов был прерван вызовом функции Дополнительные сведения Неблокирующий вызов, если в параметре |
|
Назначение Принимает запрос клиента на создание IPC-канала. Параметры
Возвращаемые значения В случае успеха возвращает |