Общая схема обмена сообщениями
Рассмотрим две сущности ("клиент" и "сервер"), между которыми установлен IPC-канал. Пусть cl
— клиентский IPC-дескриптор этого канала, sr
— серверный IPC-дескриптор этого канала.
Приведенный ниже код предназначен для демонстрации механизма IPC. Обычно в коде сущности системные вызовы не используются напрямую. Для удобного обмена сообщениями предназначены специальные NK-сгенерированные методы, которые, в свою очередь, используют системные вызовы.
Код сущности-клиента:
client.c
…
// Получение клиентского IPC-дескриптора cl с помощью локатора сервисов
…
// Отправка запроса
Call(cl, &RequestBuffer, &ResponseBuffer);
…
Код сущности-сервера:
server.c
…
// Получение серверного IPC-дескриптора sr с помощью локатора сервисов
…
// Получение запроса
Recv(sr, &RequestBuffer);
…
// Обработка запроса
…
// Отправка ответа
Reply(sr, &ResponseBuffer);
…
Обмен сообщениями происходит следующим образом:
- Один из потоков клиента выполняет системный вызов
Call()
, передав в аргументах дескрипторcl
(клиентский дескриптор используемого канала), указатель на буфер с сообщением-запросом и указатель на буфер для ответа. - Сообщение-запрос передается подсистеме Kaspersky Security System для проверки. Если Kaspersky Security System возвращает решение "разрешено", переходим к пункту 3. В противном случае вызов
Call()
завершается с кодом ошибкиrcSecurityDisallow
, переходим к пункту 9. - Если сервер ожидает запрос от этого клиента (уже выполнил вызов
Recv()
, передав первым аргументомsr
), переходим к пункту 4. В противном случае поток клиента остается заблокированным до тех пор, пока один из потоков сервера не выполнит системный вызовRecv()
с первым аргументомsr
. - Сообщение-запрос копируется в адресное пространство сервера. Поток сервера разблокируется, а вызов
Recv()
завершается с кодомrcOk
. - Сервер обрабатывает полученное сообщение. Поток клиента остается заблокированным.
- Сервер выполняет системный вызов
Reply()
, передав в аргументах дескрипторsr
и указатель на буфер с сообщением-ответом. - Сообщение-ответ передается подсистеме Kaspersky Security System для проверки. Если Kaspersky Security System возвращает решение "разрешено", переходим к пункту 8. В противном случае вызовы
Call()
иReply()
завершаются с кодом ошибкиrcSecurityDisallow
- Сообщение-ответ копируется в адресное пространство клиента. Поток сервера разблокируется, вызов
Reply()
завершается с кодомrcOk
. Поток клиента разблокируется, вызовCall()
завершается с кодомrcOk
. - Обмен завершен.
Если в процессе передачи запроса произошла ошибка (нехватка памяти, неверный формат сообщения и т.п.), то потоки разблокируются, а вызовы Call()
и Reply()
возвращают код ошибки.