KasperskyOS Community Edition 1.0

Общая схема обмена сообщениями

Рассмотрим две сущности ("клиент" и "сервер"), между которыми установлен 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);

Обмен сообщениями происходит следующим образом:

  1. Один из потоков клиента выполняет системный вызов Call(), передав в аргументах дескриптор cl (клиентский дескриптор используемого канала), указатель на буфер с сообщением-запросом и указатель на буфер для ответа.
  2. Сообщение-запрос передается подсистеме Kaspersky Security System для проверки. Если Kaspersky Security System возвращает решение "разрешено", переходим к пункту 3. В противном случае вызов Call() завершается с кодом ошибки rcSecurityDisallow, переходим к пункту 9.
  3. Если сервер ожидает запрос от этого клиента (уже выполнил вызов Recv(), передав первым аргументом sr), переходим к пункту 4. В противном случае поток клиента остается заблокированным до тех пор, пока один из потоков сервера не выполнит системный вызов Recv() с первым аргументом sr.
  4. Сообщение-запрос копируется в адресное пространство сервера. Поток сервера разблокируется, а вызов Recv() завершается с кодом rcOk.
  5. Сервер обрабатывает полученное сообщение. Поток клиента остается заблокированным.
  6. Сервер выполняет системный вызов Reply(), передав в аргументах дескриптор sr и указатель на буфер с сообщением-ответом.
  7. Сообщение-ответ передается подсистеме Kaspersky Security System для проверки. Если Kaspersky Security System возвращает решение "разрешено", переходим к пункту 8. В противном случае вызовы Call() и Reply() завершаются с кодом ошибки rcSecurityDisallow (см. пункт 3).
  8. Сообщение-ответ копируется в адресное пространство клиента. Поток сервера разблокируется, вызов Reply() завершается с кодом rcOk. Поток клиента разблокируется, вызов Call() завершается с кодом rcOk.
  9. Обмен завершен.

Если в процессе передачи запроса произошла ошибка (нехватка памяти, неверный формат сообщения и т.п.), то потоки разблокируются, а вызовы Call() и Reply() возвращают код ошибки.