KasperskyOS Community Edition 1.3

Содержание

[Topic api]

Коды возврата

Общие сведения

В решении на базе KasperskyOS коды возврата функций различных API (например, API библиотек libkos и kdf, драйверов, транспортного кода, прикладного ПО) имеют тип 32-битного знакового целого числа. Этот тип определен в заголовочном файле sysroot-*-kos/include/rtl/retcode.h из состава KasperskyOS SDK так:

typedef __INT32_TYPE__ Retcode;

Множество кодов возврата состоит из кода успеха со значением 0 и кодов ошибок. Код ошибки интерпретируется как структура данных, формат которой описан в заголовочном файле sysroot-*-kos/include/rtl/retcode.h из состава KasperskyOS SDK. Этот формат предусматривает наличие нескольких полей, которые содержат не только сведения о результатах вызова функции, но и следующую дополнительную информацию:

  • Флаг в поле Customer, сигнализирующий о том, что код ошибки определен разработчиками решения на базе KasperskyOS, а не разработчиками ПО из состава KasperskyOS SDK.

    Благодаря флагу в поле Customer разработчики решения на базе KasperskyOS и разработчики ПО из состава KasperskyOS SDK могут определять коды ошибок из непересекающихся множеств.

  • Глобальный идентификатор кода ошибки в поле Space.

    Глобальные идентификаторы позволяют определять непересекающиеся множества кодов ошибок. Коды ошибок могут быть общими и специфичными. Общие коды ошибок могут использоваться в API любых компонентов решения и в API любых составных частей компонентов решения (например, драйвер или VFS могут быть составной частью компонента решения). Специфичные коды ошибок используются в API одного или нескольких компонентов решения или в API одной или нескольких составных частей компонентов решения.

    Например, идентификатору RC_SPACE_GENERAL соответствуют коды общих ошибок, идентификатору RC_SPACE_KERNEL соответствуют коды ошибок ядра, идентификатору RC_SPACE_DRIVERS соответствуют коды ошибок драйверов.

  • Локальный идентификатор кода ошибки в поле Facility.

    Локальные идентификаторы позволяют определять непересекающиеся подмножества кодов ошибок в рамках множества кодов ошибок, которые соответствуют одному глобальному идентификатору. Например, множество кодов ошибок с глобальным идентификатором RC_SPACE_DRIVERS включает непересекающиеся подмножества кодов ошибок с локальными идентификаторами RC_FACILITY_I2C, RC_FACILITY_USB, RC_FACILITY_BLKDEV.

Глобальные и локальные идентификаторы специфичных кодов ошибок назначаются разработчиками решения на базе KasperskyOS и разработчиками ПО из состава KasperskyOS SDK независимо друг от друга. То есть формируется два множества глобальных идентификаторов. Каждый глобальный идентификатор имеет уникальное смысловое значение в рамках одного множества. Каждый локальный идентификатор имеет уникальное смысловое значение в рамках множества локальных идентификаторов, относящихся к одному глобальному идентификатору. Общие коды ошибок могут использоваться в любых API.

Такой централизованный подход позволяет избежать появления в решении на базе KasperskyOS одинаковых кодов ошибок с разными смысловыми значениями. Это нужно, чтобы исключить проблему транзита кодов ошибок через разные API. Например, такая проблема возникает, когда драйверы вызывают функции библиотеки kdf, получают коды ошибок и возвращают эти коды через свои API. Если формировать коды ошибок без централизованного подхода, то один и тот же код ошибки может иметь разные смысловые значения для библиотеки kdf и для драйвера. В таких условиях драйверы возвращают корректные коды ошибок, если только выполняется преобразование кодов ошибок библиотеки kdf в коды ошибок каждого из драйверов. То есть коды ошибок в решении на базе KasperskyOS назначаются так, чтобы не выполнять конвертацию этих кодов при транзите через разные API.

Приведенные здесь сведения о кодах возврата не относятся к функциям интерфейса POSIX и API стороннего ПО, используемого в решениях на базе KasperskyOS.

Общие коды возврата

Коды возврата, которые являются общими для API любых компонентов решения и их составных частей, определены в заголовочном файле sysroot-*-kos/include/rtl/retcode.h из состава KasperskyOS SDK. Описание общих кодов возврата приведено в таблице ниже.

Общие коды возврата

Код возврата

Описание

rcOk (соответствует значению 0)

Функция завершилась успешно.

rcInvalidArgument

Параметр функции некорректен.

rcNotConnected

Нет соединения между клиентской и серверной сторонами взаимодействия.

Например, отсутствует серверный IPC-дескриптор.

rcOutOfMemory

Недостаточно памяти для выполнения операции.

rcBufferTooSmall

Недостаточный размер буфера.

rcInternalError

Функция завершилась с внутренней ошибкой, которая связана с некорректной логикой.

Примерами внутренних ошибок являются: выход значений за допустимые пределы, появление нулевых указателей и значений там, где этого быть не должно.

rcTransferError

Ошибка отправки IPC-сообщения.

rcReceiveError

Ошибка приема IPC-сообщения.

rcSourceFault

IPC-сообщение не было передано из-за источника IPC-сообщения.

rcTargetFault

IPC-сообщение не было передано из-за приемника IPC-сообщения.

rcIpcInterrupt

IPC прервано другим потоком процесса.

rcRestart

Сигнализирует, что функцию нужно вызвать повторно.

rcFail

Функция завершилась с ошибкой.

rcNoCapability

Операция над ресурсом недоступна.

rcNotReady

Инициализация не выполнена.

rcUnimplemented

Функция не реализована.

rcBufferTooLarge

Большой размер буфера.

rcBusy

Ресурс временно недоступен.

rcResourceNotFound

Ресурс не найден.

rcTimeout

Время ожидания истекло.

rcSecurityDisallow

Операция запрещена механизмами безопасности.

rcFutexWouldBlock

Операция приведет к блокировке.

rcAbort

Операция прервана.

rcInvalidThreadState

В обработчике прерывания вызвана недопустимая функция.

rcAlreadyExists

Множество элементов уже содержит добавляемый элемент.

rcInvalidOperation

Операция не может быть выполнена.

rcHandleRevoked

Права доступа к ресурсу отозваны.

rcQuotaExceeded

Квота на ресурс превышена.

rcDeviceNotFound

Устройство не найдено.

rcOverflow

Произошло переполнение.

rcAlreadyDone

Операция уже выполнена.

rcNotRun

Операция не была запущена.

Определение кодов ошибок

Чтобы определить код ошибки, разработчику решения на базе KasperskyOS нужно использовать макрос MAKE_RETCODE(), определенный в заголовочном файле sysroot-*-kos/include/rtl/retcode.h из состава KasperskyOS SDK. При этом через параметр customer нужно передать символьную константу RC_CUSTOMER_TRUE.

Пример:

#define LV_EBADREQUEST MAKE_RETCODE(RC_CUSTOMER_TRUE, RC_SPACE_APPS, RC_FACILITY_LogViewer, 5, "Bad request")

Описание ошибки, которое передается через параметр desc, не используется макросом MAKE_RETCODE(). Это описание требуется, чтобы создать базу данных кодов ошибок при сборке решения на базе KasperskyOS. В настоящее время механизм для создания и использования такой базы данных не реализован.

Чтение полей структуры кода ошибки

Макросы RC_GET_CUSTOMER(), RC_GET_SPACE(), RC_GET_FACILITY() и RC_GET_CODE(), определенные в заголовочном файле sysroot-*-kos/include/rtl/retcode.h из состава KasperskyOS SDK, позволяют читать поля структуры кода ошибки.

Макросы RETCODE_HR_PARAMS() и RETCODE_HR_FMT(), определенные в заголовочном файле sysroot-*-kos/include/rtl/retcode_hr.h из состава KasperskyOS SDK, используются для форматированного вывода сведений об ошибке.

В начало
[Topic return_codes]

Библиотека libkos

Библиотека libkos является базовой библиотекой KasperskyOS, предоставляющей набор API, через которые программы и другие библиотеки (например, libc, kdf) используют службы ядра. API, предоставляемые библиотекой libkos, обеспечивают для разработчиков решения следующие возможности:

  • управление процессами, потоками исполнения, виртуальной памятью;
  • управление доступом к ресурсам;
  • осуществление ввода-вывода;
  • создание IPC-каналов;
  • управление электропитанием;
  • получение статистических сведений о системе;
  • другие возможности, поддерживаемые службами ядра.

На аппаратных платформах с процессорной архитектурой Arm входные и выходные параметры API библиотеки libkos нельзя сохранять в памяти типа "Device memory", поскольку это может привести к неопределенному поведению. (Исключениями являются: параметр addr функции KnVmQuery() из API vmm_api.h, параметры reg и baseReg функций из API mmio.h, параметр va функции KnHalFlushCache() из API hal_api.h, параметр va функции KosCpuCacheFlush() из API cpucache.h.) Параметры API библиотеки libkos нужно сохранять в памяти типа "Normal memory". Чтобы копировать данные из памяти типа "Device memory" в память типа "Normal memory" и обратно, нужно использовать функцию RtlPedanticMemcpy(), объявленную в заголовочном файле sysroot-*-kos/include/rtl/string_pedantic.h из состава KasperskyOS SDK.

В этом разделе

Управление дескрипторами (handle_api.h)

Управление виртуальной памятью (vmm_api.h)

Выделение и освобождение памяти (alloc.h)

Использование DMA (dma.h)

Ввод-вывод через память (mmio.h)

Управление обработкой прерываний (irq.h)

Управление потоками исполнения (высокоуровневый API thread.h)

Управление потоками исполнения (низкоуровневый API thread_api.h)

Управление процессами (высокоуровневый API task.h)

Управление процессами (низкоуровневый API task_api.h)

Инициализация IPC-транспорта для межпроцессного взаимодействия и управление обработкой IPC-запросов (transport-kos.h, transport-kos-dispatch.h)

Инициализация IPC-транспорта для обращения к модулю безопасности (transport-kos-security.h)

Генерация случайных чисел (random_api.h)

Получение и изменение значений времени (time_api.h)

Использование уведомлений (notice_api.h)

Динамическое создание IPC-каналов (cm_api.h, ns_api.h)

Использование примитивов синхронизации (event.h, mutex.h, rwlock.h, semaphore.h, condvar.h)

Управление изоляцией памяти для ввода-вывода (iommu_api.h)

Использование очередей (queue.h)

Использование барьеров памяти (barriers.h)

Выполнение системных вызовов (syscalls.h)

Прерывание IPC (ipc_api.h)

Использование сессий (session.h)

Использование объектов KosObject (objects.h)

Использование контейнеров объектов KosObject (objcontainer.h)

Использование строк KosString (strings.h)

Управление драйвером XHCI DbC ядра KasperskyOS (xhcidbg_api.h)

Получение данных аудита безопасности (vlog_api.h)

Использование фьютексов (sync.h)

Получение IPC-дескрипторов и идентификаторов служб для использования статически созданных IPC-каналов (sl_api.h)

Управление электропитанием (pm_api.h)

В начало
[Topic libkos]

Управление дескрипторами (handle_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.

API предназначен для выполнения операций с дескрипторами. Дескрипторы имеют тип Handle, который определен в заголовочном файле sysroot-*-kos/include/handle/handletype.h из состава KasperskyOS SDK.

Локальность дескрипторов

Каждый процесс получает дескрипторы из своего пространства дескрипторов независимо от других процессов. Пространства дескрипторов разных процессов абсолютно идентичны, то есть представляют собой одно и то же множество значений. Поэтому дескриптор является уникальным (имеет уникальное значение) только в рамках пространства дескрипторов одного процесса, который владеет этим дескриптором. То есть разные процессы могут иметь: одинаковые дескрипторы, которые идентифицируют разные ресурсы, или разные дескрипторы, которые идентифицируют один и тот же ресурс.

В этом разделе

Маска прав дескриптора

Создание дескрипторов

Передача дескрипторов

Копирование дескрипторов

Разыменование дескрипторов

Отзыв дескрипторов

Закрытие дескрипторов

Получение идентификатора безопасности (SID)

Пример использования OCap

В начало
[Topic handles_manage]

Маска прав дескриптора

Маска прав дескриптора имеет размер 32 бита и состоит из общей и специальной части. Общая часть описывает права, неспецифичные для любых ресурсов (флаги этих прав определены в заголовочном файле sysroot-*-kos/include/services/ocap.h из состава KasperskyOS SDK). Например, в общей части находится флаг OCAP_HANDLE_TRANSFER, который определяет право на передачу дескриптора. Специальная часть описывает права, специфичные для пользовательского или системного ресурса. Флаги прав специальной части для системных ресурсов определены в заголовочном файле ocap.h. Структура специальной части для пользовательских ресурсов определяется поставщиком ресурсов с использованием макроса OCAP_HANDLE_SPEC(), который определен в заголовочном файле ocap.h. Поставщику ресурсов необходимо экспортировать публичные заголовочные файлы с описанием флагов специальной части.

При создании дескриптора системного ресурса маска прав задается ядром KasperskyOS, которое применяет маски прав из заголовочного файла ocap.h. Применяются маски прав с именами вида OCAP_*_FULL (например, OCAP_IOPORT_FULL, OCAP_TASK_FULL, OCAP_FILE_FULL) и вида OCAP_IPC_* (например, OCAP_IPC_SERVER, OCAP_IPC_LISTENER, OCAP_IPC_CLIENT).

При создании дескриптора пользовательского ресурса маска прав задается пользователем.

При передаче дескриптора маска прав задается пользователем, но передаваемые права доступа не могут быть повышены относительно прав доступа, которые имеет процесс.

В начало
[Topic libkos_handles_rights]

Создание дескрипторов

Сведения о функциях API приведены в таблице ниже.

Создание дескрипторов системных ресурсов

Дескрипторы системных ресурсов создаются при создании этих ресурсов, например, при регистрации прерывания или региона памяти MMIO, создании буфера DMA, потока исполнения или процесса.

Создание дескрипторов пользовательских ресурсов

Дескрипторы пользовательских ресурсов создаются поставщиками ресурсов с использованием функции KnHandleCreateUserObject() или KnHandleCreateUserObjectEx().

Через параметр context нужно задать контекст пользовательского ресурса. Контекст пользовательского ресурса – данные, позволяющие поставщику ресурса идентифицировать ресурс и его состояние, когда запрашивается доступ к ресурсу другими процессами. В общем случае это набор разнотипных данных (структура). Например, для файла контекст может включать имя, путь, положение курсора. Контекст пользовательского ресурса используется в качестве контекста передачи ресурса или совместно с несколькими контекстами передачи ресурса.

Через параметр rights нужно задать маску прав дескриптора.

Создание IPC-дескрипторов

IPC-дескриптор (англ. IPC handle) – это дескриптор, который идентифицирует IPC-канал. IPC-дескрипторы используются для выполнения системных вызовов. Клиентский IPC-дескриптор нужен для выполнения системного вызова Call(). Серверный IPC-дескриптор требуется для выполнения системных вызовов Recv() и Reply(). Серверный IPC-дескриптор, который имеет расширенные права, позволяющие добавлять IPC-каналы в набор идентифицируемых этим дескриптором IPC-каналов, называется слушающим дескриптором (англ. listener handle). Клиентский IPC-дескриптор, который идентифицирует одновременно IPC-канал до сервера и службу этого сервера, называется callable-дескриптором (англ. callable handle).

Сервер создает callable-дескриптор и передает его клиенту, чтобы клиент мог использовать службу сервера. Клиент инициализирует IPC-транспорт, используя полученный callable-дескриптор. При этом в функции инициализации прокси-объекта клиент указывает значение INVALID_RIID в качестве идентификатор службы (RIID). Чтобы создать callable-дескриптор, нужно вызвать функцию KnHandleCreateUserObjectEx(), указав в параметрах ipcChannel и riid серверный IPC-дескриптор и идентификатор службы (RIID) соответственно. Через параметр context можно задать данные для ассоциации с callable-дескриптором. Сервер сможет получить указатель на эти данные при разыменовании callable-дескриптора. (Несмотря на то что callable-дескриптор является IPC-дескриптором, он помещается ядром в поле base_.self фиксированной части IPC-запроса.)

Чтобы создать и ассоциировать между собой клиентский, серверный и слушающий IPC-дескрипторы, нужно вызвать функцию KnHandleConnect() или KnHandleConnectEx(). Эти функции используются для статического создания IPC-каналов. Функция KnHandleConnect() создает IPC-дескрипторы из пространства дескрипторов вызывающего процесса. При этом клиентский IPC-дескриптор может быть передан другому процессу. Функция KnHandleConnectEx() может создать IPC-дескрипторы как из пространства дескрипторов вызывающего процесса, так и из пространств дескрипторов других процессов: клиента и сервера.

При вызове функции KnHandleConnect() или KnHandleConnectEx() со значением INVALID_HANDLE в параметре, задающем слушающий дескриптор, создается новый слушающий дескриптор. При этом серверный и слушающий IPC-дескрипторы в выходных параметрах являются одним и тем же дескриптором. Если вызвать функцию KnHandleConnect() или KnHandleConnectEx(), указав слушающий дескриптор, то созданный серверный IPC-дескриптор обеспечит возможность получать IPC-запросы по всем IPC-каналам, ассоциированным с этим слушающим дескриптором. В этом случае серверный и слушающий IPC-дескрипторы в выходных параметрах являются разными дескрипторами. (Первый IPC-канал, ассоциированный со слушающим дескриптором, создается при вызове функции KnHandleConnect() или KnHandleConnectEx() со значением INVALID_HANDLE в параметре, задающем слушающий дескриптор. Второй и последующие IPC-каналы, ассоциированные со слушающим дескриптором, создаются при втором и последующих вызовах функции KnHandleConnect() или KnHandleConnectEx() с указанием слушающего дескриптора, полученного при первом вызове.)

Чтобы создать слушающий дескриптор, не связанный с клиентским и серверным IPC-дескрипторами, нужно вызвать функцию KnHandleCreateListener(). (Функции KnHandleConnect() и KnHandleConnectEx() создают слушающий дескриптор, связанный с клиентским и серверным IPC-дескрипторами.) Функцию KnHandleCreateListener() удобно использовать, чтобы создать слушающий дескриптор, с которым впоследствии будут связаны callable-дескрипторы.

Чтобы создать клиентский IPC-дескриптор для обращения к модулю безопасности Kaspersky Security Module через интерфейс безопасности, нужно вызвать функцию KnHandleSecurityConnect(). Эта функция вызывается библиотекой libkos при инициализации IPC-транспорта для обращения к модулю безопасности.

Сведения о функциях API

Функции handle_api.h

Функция

Сведения о функции

KnHandleCreateUserObject()

Назначение

Создает дескриптор.

Параметры

  • [in] type – тип дескриптора. Фиктивный параметр, который должен принимать значение от константы HANDLE_TYPE_USER_FIRST до константы HANDLE_TYPE_USER_LAST, определенных в заголовочном файле sysroot-*-kos/include/handle/handletype.h из состава KasperskyOS SDK.
  • [in] rights – маска прав дескриптора.
  • [in,optional] context – указатель на данные, которые нужно ассоциировать с дескриптором, или RTL_NULL, если эта ассоциация не требуется.
  • [out] handle – указатель на дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnHandleCreateUserObjectEx()

Назначение

Создает дескриптор.

Параметры

  • [in] type – тип дескриптора. Фиктивный параметр, который должен принимать значение от константы HANDLE_TYPE_USER_FIRST до константы HANDLE_TYPE_USER_LAST, определенных в заголовочном файле sysroot-*-kos/include/handle/handletype.h из состава KasperskyOS SDK.
  • [in] rights – маска прав дескриптора.
  • [in,optional] context – указатель на данные, которые нужно ассоциировать с дескриптором, или RTL_NULL, если эта ассоциация не требуется.
  • [in,optional] ipcChannel – серверный IPC-дескриптор или INVALID_HANDLE, если не требуется создавать callable-дескриптор.
  • [in,optional] riid – идентификатор службы (RIID) или INVALID_RIID, если не требуется создавать callable-дескриптор.
  • [out] handle – указатель на дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnHandleConnect()

Назначение

Создает и связывает между собой клиентский, серверный и слушающий IPC-дескрипторы.

Параметры

  • [in,optional] ls – слушающий дескриптор или INVALID_HANDLE, чтобы создать его.
  • [out,optional] outLs – указатель на слушающий дескриптор. Можно указать RTL_NULL, если через параметр ls задан слушающий дескриптор.
  • [out,optional] outSr – указатель на серверный IPC-дескриптор или RTL_NULL, чтобы не создавать серверный IPC-дескриптор, если через параметр ls задан слушающий дескриптор.
  • [out] outCl – указатель на клиентский IPC-дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnHandleConnectEx()

Назначение

Создает и связывает между собой клиентский, серверный и слушающий IPC-дескрипторы.

Параметры

  • [in] server – дескриптор серверного процесса.
  • [in,optional] srListener – слушающий дескриптор из пространства дескрипторов серверного процесса или INVALID_HANDLE, чтобы создать его.
  • [in] client – дескриптор клиентского процесса.
  • [out,optional] outSrListener – указатель на слушающий дескриптор из пространства дескрипторов серверного процесса. Можно указать RTL_NULL, если через параметр srListener задан слушающий дескриптор.
  • [out,optional] outSrEndpoint – указатель на серверный IPC-дескриптор из пространства дескрипторов серверного процесса или RTL_NULL, чтобы не создавать серверный IPC-дескриптор, если через параметр srListener задан слушающий дескриптор.
  • [out] outClEndpoint – указатель на клиентский IPC-дескриптор из пространства дескрипторов клиентского процесса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnHandleSecurityConnect()

Назначение

Создает клиентский IPC-дескриптор для обращения к модулю безопасности Kaspersky Security Module через интерфейс безопасности.

Параметры

  • [out] client – указатель на дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnHandleCreateListener()

Назначение

Создает слушающий дескриптор, не связанный с клиентским и серверным IPC-дескрипторами.

Параметры

  • [out] listener – указатель на слушающий дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_handles_create]

Передача дескрипторов

Сведения о функциях API приведены в таблице ниже.

Общие сведения о передаче дескрипторов

Передача дескрипторов между процессами осуществляется, чтобы потребители ресурсов получили доступ к требуемым ресурсам. По причине локальности дескрипторов передача дескриптора инициирует на стороне принимающего процесса создание дескриптора из его пространства дескрипторов. Этот дескриптор регистрируется как потомок отправленного дескриптора и идентифицирует тот же ресурс.

Один дескриптор может быть передан многократно одному или нескольким процессам. Каждая передача порождает нового потомка переданного дескриптора на стороне принимающего процесса. Процесс может передавать дескрипторы, которые он получил от других процессов или ядра KasperskyOS. Поэтому у дескриптора может быть несколько поколений потомков. Иерархия порождения дескрипторов для каждого ресурса хранится в ядре KasperskyOS в виде дерева наследования дескрипторов.

Процесс может передавать дескрипторы как пользовательских, так и системных ресурсов, если права доступа этих дескрипторов разрешают выполнять передачу (в маске прав установлен флаг OCAP_HANDLE_TRANSFER). У потомка может быть меньше прав доступа, чем у предка. Например, передающий процесс имеет права доступа к файлу на чтение и запись, а передает права доступа только на чтение. Передающий процесс также может запретить принимающему процессу дальнейшую передачу дескриптора. Права доступа задаются в передаваемой маске прав дескриптора.

Условия для передачи дескрипторов

Чтобы процессы могли передавать дескрипторы между собой, должны выполняться следующие условия:

  1. Между процессами создан IPC-канал.
  2. Политика безопасности решения (security.psl) разрешает взаимодействие классов процессов.
  3. Реализованы интерфейсные методы для передачи дескрипторов.

API task.h позволяет родительскому процессу передавать дескрипторы дочернему процессу, который еще не запущен.

В IDL-описании сигнатуры интерфейсных методов для передачи дескрипторов имеют входные (in) и/или выходные (out) параметры типа Handle или array с элементами типа Handle. Через входные параметры одного метода можно передать до 255 дескрипторов. Столько же дескрипторов можно получить через выходные параметры.

Пример IDL-описания, где заданы сигнатуры интерфейсных методов для передачи дескрипторов:

package IpcTransfer interface { PublishResource1(in Handle handle, out UInt32 result); PublishResource7(in Handle handle1, in Handle handle2, in Handle handle3, in Handle handle4, in Handle handle5, in Handle handle6, in Handle handle7, out UInt32 result); OpenResource(in UInt32 ID, out Handle handle); }

Для каждого параметра типа Handle компилятор NK генерирует в структурах IPC-запросов *_req и/или IPC-ответов *_res поле типа nk_handle_desc_t (далее также транспортный контейнер дескриптора). Этот тип объявлен в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK и представляет собой структуру, состоящую из трех полей: поля дескриптора handle, поля маски прав дескриптора rights и поля контекста передачи ресурса badge.

Контекст передачи ресурса

Контекст передачи ресурса – данные, позволяющие серверу идентифицировать ресурс и его состояние, когда запрашивается доступ к ресурсу через потомков переданного дескриптора. В общем случае это набор разнотипных данных (структура). Например, для файла контекст передачи может включать имя, путь, положение курсора. Сервер получает указатель на контекст передачи ресурса при разыменовании дескриптора.

Сервер независимо от того, является ли она поставщиком ресурса или нет, может ассоциировать каждую передачу дескриптора с отдельным контекстом передачи ресурса. Этот контекст передачи ресурса связывается только с теми потомками дескриптора (поддеревом наследования дескриптора), которые порождены в результате конкретной его передачи. Это позволяет определять состояние ресурса по отношению к отдельной передаче дескриптора этого ресурса. Например, в случае множественного доступа к одному файлу контекст передачи файла позволяет определить, какому именно открытию этого файла соответствует полученный IPC-запрос.

Если сервер является поставщиком ресурса, то по умолчанию каждая передача дескриптора этого ресурса ассоциируется с контекстом пользовательского ресурса. То есть контекст пользовательского ресурса используется в качестве контекста передачи ресурса для каждой передачи дескриптора, если эта передача не ассоциируется с отдельным контекстом передачи ресурса.

Сервер, который является поставщиком ресурса, может использовать совместно контекст пользовательского ресурса и контексты передачи ресурса. Например, имя, путь и размер файла хранятся в контексте пользовательского ресурса, а положение курсора хранится в нескольких контекстах передачи ресурса, так как каждый клиент может работать с разными частями файла. Технически совместное использование контекста пользовательского ресурса и контекстов передачи ресурса достигается тем, что контексты передачи ресурса хранят указатель на контекст пользовательского ресурса.

Если клиент использует несколько разнотипных ресурсов сервера, контексты передачи ресурсов (или контексты пользовательских ресурсов, если они используются в качестве контекстов передачи ресурсов) должны быть типизированными объектами KosObject (об объектах KosObject см. "Использование объектов KosObject (objects.h)"). Это нужно, чтобы сервер мог проверить, что клиент при использовании ресурса передал в интерфейсный метод дескриптор того ресурса, который соответствует этому методу. Такая проверка требуется, поскольку клиент может ошибочно передать в интерфейсный метод дескриптор ресурса, который не соответствует этому методу. Например, клиент получил дескриптор файла и передал его в интерфейсный метод для работы с томами.

Чтобы ассоциировать передачу дескриптора с контекстом передачи ресурса, сервер помещает в поле badge структуры nk_handle_desc_t дескриптор объекта контекста передачи ресурса. Объект контекста передачи ресурса – объект ядра, в котором хранится указатель на контекст передачи ресурса. Чтобы создать объект контекста передачи ресурса, нужно вызвать функцию KnHandleCreateBadge(). Работа этой функции связана с механизмом уведомлений, так как серверу нужно знать, когда объект контекста передачи ресурса будет закрыт и удален. Эти сведения требуются серверу, чтобы освободить или использовать повторно память, которая отведена для хранения контекста передачи ресурса.

Объект контекста передачи ресурса будет закрыт, когда будут закрыты или отозваны потомки дескриптора, которые образуют поддерево наследования дескрипторов, корневой узел которого порожден передачей этого дескриптора в ассоциации с этим объектом. (Переданный дескриптор может быть закрыт не только целенаправленно, но и, например, при неожиданном завершении работы принимающего клиента.) Получив уведомление о закрытии объекта контекста передачи ресурса, сервер закрывает дескриптор этого объекта. После этого объект контекста передачи ресурса будет удален. Получив уведомление, что объект контекста передачи ресурса удален, сервер освобождает или использует повторно память, которая отведена для хранения контекста передачи ресурса.

Один объект контекста передачи ресурса может быть ассоциирован только с одной передачей дескриптора.

Упаковка данных в транспортный контейнер дескриптора

Чтобы упаковать дескриптор, маску прав дескриптора и дескриптор объекта контекста передачи ресурса в транспортный контейнер дескриптора, нужно использовать макрос nk_handle_desc(), который определен в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK. Этот макрос принимает переменное число параметров.

Если не передавать макросу ни одного параметра, то в поле дескриптора handle структуры nk_handle_desc_t будет записано значение NK_INVALID_HANDLE. Если передать макросу один параметр, то этот параметр интерпретируется как дескриптор. Если передать макросу два параметра, то первый параметр интерпретируется как дескриптор, второй параметр интерпретируется как маска прав дескриптора. Если передать макросу три параметра, то первый параметр интерпретируется как дескриптор, второй параметр интерпретируется как маска прав дескриптора, третий параметр интерпретируется как дескриптор объекта контекста передачи ресурса.

Извлечение данных из транспортного контейнера дескриптора

Чтобы извлечь дескриптор, маску прав дескриптора и указатель на контекст передачи ресурса из транспортного контейнера дескриптора, нужно использовать соответственно функции nk_get_handle(), nk_get_rights() и nk_get_badge_op() (или nk_get_badge()), которые определены в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK. Функции nk_get_badge_op() и nk_get_badge() нужно использовать только при разыменовании дескрипторов.

Сценарии передачи дескрипторов

Сценарий передачи дескрипторов от клиента к серверу включает следующие шаги:

  1. Клиент упаковывает дескрипторы и маски прав дескрипторов в поля структуры IPC-запросов *_req типа nk_handle_desc_t.
  2. Клиент вызывает интерфейсный метод для передачи дескрипторов серверу. При вызове этого метода выполняется системный вызов Call().
  3. Сервер получает IPC-запрос, выполняя системный вызов Recv().
  4. Диспетчер на стороне сервера вызывает метод, который соответствует IPC-запросу. Этот метод извлекает дескрипторы и маски прав дескрипторов из полей структуры IPC-запросов *_req типа nk_handle_desc_t.

Сценарий передачи дескрипторов от сервера к клиенту включает следующие шаги:

  1. Клиент вызывает интерфейсный метод для получения дескрипторов от сервера. При вызове этого метода выполняется системный вызов Call().
  2. Сервер получает IPC-запрос, выполняя системный вызов Recv().
  3. Диспетчер на стороне сервера вызывает метод, который соответствует IPC-запросу. Этот метод упаковывает дескрипторы, маски прав дескрипторов и дескрипторы объектов контекстов передачи ресурсов в поля структуры IPC-ответов *_res типа nk_handle_desc_t.
  4. Сервер отвечает на IPC-запрос, выполняя системный вызов Reply().
  5. На стороне клиента интерфейсный метод возвращает управление. После этого клиент извлекает дескрипторы и маски прав дескрипторов из полей структуры IPC-ответов *_res типа nk_handle_desc_t.

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

Сведения о функциях API

Функции handle_api.h

Функция

Сведения о функции

KnHandleCreateBadge()

Назначение

Создает объект контекста передачи ресурса и настраивает механизм уведомлений для контроля жизненного цикла этого объекта.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] eventId – идентификатор записи вида "ресурс – маска событий" в приемнике уведомлений.
  • [in,optional] context – указатель на данные, которые нужно ассоциировать с передачей дескриптора, или RTL_NULL, если эта ассоциация не требуется.
  • [out] handle – указатель на дескриптор объекта контекста передачи ресурса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Приемник уведомлений настраивается на получение уведомлений о событиях, которые соответствуют флагам маски событий EVENT_OBJECT_DESTROYED и EVENT_BADGE_CLOSED.

В начало
[Topic libkos_handles_transfer]

Копирование дескрипторов

Копирование дескриптора представляет собой операцию, похожую на передачу дескриптора, но выполняемую внутри процесса. Потомок дескриптора создается в том же процессе и из того же пространства дескрипторов. Права потомка дескриптора могут быть меньше либо равны правам оригинального дескриптора. Копирование дескриптора можно ассоциировать с объектом контекста передачи ресурса. Это позволит отследить через механизм уведомлений, когда будут закрыты или отозваны все потомки дескриптора, образующие поддерево наследования дескрипторов, корневой узел которого порожден копированием. Также это обеспечит возможность отозвать этих потомков.

Чтобы выполнить копирование дескриптора, нужно вызвать функцию KnHandleCopy(). При этом в маске прав дескриптора должен быть установлен флаг OCAP_HANDLE_COPY.

Сведения о функциях API приведены в таблице ниже.

Функции handle_api.h

Функция

Сведения о функции

KnHandleCopy()

Назначение

Копирует дескриптор.

В результате копирования вызывающий процесс получает потомка дескриптора.

Параметры

  • [in] inHandle – оригинальный дескриптор.
  • [in] newRightsMask – маска прав потомка дескриптора.
  • [in,optional] copyBadge – дескриптор объекта контекста передачи ресурса или INVALID_HANDLE, если не требуется ассоциировать копирование дескриптора с этим объектом.
  • [out] outHandle – указатель на потомка дескриптора.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_handle_copy]

Разыменование дескрипторов

Разыменование дескриптора – это операция, при которой клиент отправляет серверу дескриптор, а сервер получает указатель на контекст передачи ресурса, маску прав отправленного дескриптора и предка отправленного клиентом дескриптора, которым сервер уже владеет. Разыменование выполняется, когда потребитель ресурсов, вызывая методы работы с ресурсом (например, чтение, запись, закрытие доступа), передает поставщику ресурсов дескриптор, который был получен от этого поставщика ресурсов при открытии доступа к ресурсу.

Разыменование дескрипторов требует выполнения тех же условий и использует те же механизмы и типы данных, что и передача дескрипторов. Сценарий разыменования дескриптора включает следующие шаги:

  1. Клиент упаковывает дескриптор в поле структуры IPC-запросов *_req типа nk_handle_desc_t.
  2. Клиент вызывает интерфейсный метод для отправки дескриптора серверу с целью выполнения действий с ресурсом. При вызове этого метода выполняется системный вызов Call().
  3. Сервер принимает IPC-запрос, выполнив системный вызов Recv().
  4. Диспетчер на стороне сервера вызывает метод, который соответствует IPC-запросу. Этот метод проверяет, что выполнена именно операция разыменования, а не передача дескриптора. Затем вызванный метод опционально проверяет, что права доступа разыменованного дескриптора (который отправлен клиентом) разрешают запрашиваемые действия с ресурсом, и извлекает указатель на контекст передачи ресурса из поля структуры запросов *_req типа nk_handle_desc_t.

Для выполнения проверок сервер использует функции nk_is_handle_dereferenced() и nk_get_badge_op(), которые объявлены в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK.

types.h (фрагмент)

/** * Функция возвращает отличное от нуля значение, если * дескриптор в транспортном контейнере дескриптора * desc получен в результате операции разыменования * дескриптора. Функция возвращает нуль, если дескриптор * в транспортном контейнере дескриптора desc получен * в результате операции передачи дескриптора. */ static inline nk_bool_t nk_is_handle_dereferenced(const nk_handle_desc_t *desc) /** * Функция извлекает указатель на контекст передачи ресурса * badge из транспортного контейнера дескриптора desc, * если в маске прав, которая помещена в транспортном * контейнере дескриптора desc, установлены флаги operation. * В случае успеха функция возвращает NK_EOK, иначе возвращает код ошибки. */ static inline nk_err_t nk_get_badge_op(const nk_handle_desc_t *desc, nk_rights_t operation, nk_badge_t *badge)

В общем случае серверу не требуется дескриптор, который получен в результате разыменования, поскольку сервер, как правило, сохраняет дескрипторы, которыми владеет, например, в составе контекстов пользовательских ресурсов. Но при необходимости сервер может извлечь этот дескриптор из транспортного контейнера дескриптора.

В начало
[Topic libkos_handles_dereference]

Отзыв дескрипторов

Процесс может отозвать потомков дескриптора, которым он владеет. Отзыв дескрипторов осуществляется на основе дерева наследования дескрипторов.

Отзыв дескрипторов не закрывает их, но через отозванные дескрипторы невозможно обращаться к ресурсам. Любая функция, которая принимает дескриптор, завершается с ошибкой rcHandleRevoked, если эта функция вызвана с отозванным дескриптором.

Чтобы отозвать потомков дескриптора, нужно вызвать функцию KnHandleRevoke() или KnHandleRevokeSubtree(). Функция KnHandleRevokeSubtree() использует объект контекста передачи ресурса, который создается при передаче дескрипторов.

Если каждый из дескрипторов системного ресурса во всех процессах, которые владеют этими дескрипторами, будет закрыт (см. "Закрытие дескрипторов") или отозван, то этот системный ресурс будет удален.

Сведения о функциях API приведены в таблице ниже.

Функции handle_api.h

Функция

Сведения о функции

KnHandleRevoke()

Назначение

Закрывает дескриптор и отзывает его потомков.

Параметры

  • [in] handle – дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnHandleRevokeSubtree()

Назначение

Отзывает дескрипторы, которые образуют поддерево наследования заданного дескриптора.

Параметры

  • [in] handle – дескриптор. Дескрипторы, образующие поддерево наследования этого дескриптора, отзываются.
  • [in] badge – дескриптор, идентифицирующий объект контекста передачи ресурса, который определяет поддерево наследования дескрипторов для отзыва. Корневым узлом этого поддерева является дескриптор, который порожден передачей или копированием дескриптора, заданного через параметр handle, в ассоциации с объектом контекста передачи ресурса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_handles_revoke]

Закрытие дескрипторов

Процесс может закрыть дескрипторы, которыми он владеет. Закрытие дескриптора прекращает ассоциацию идентификатора с ресурсом, тем самым освобождая идентификатор. Закрытие дескриптора не делает недействительными его предков и потомков (в отличие от отзыва дескриптора, который делает недействительными его потомков). То есть через предков и потомков закрытого дескриптора обеспечивается доступ к ресурсу, который они идентифицируют. Также закрытие дескриптора не нарушает целостность дерева наследования дескрипторов, которое относится к ресурсу, идентифицируемому этим дескриптором. Место закрытого дескриптора занимает его предок. То есть предок закрытого дескриптора становится непосредственным предком потомков закрытого дескриптора.

Чтобы закрыть дескриптор, нужно вызвать функцию KnHandleClose().

Если каждый из дескрипторов системного ресурса во всех процессах, которые владеют этими дескрипторами, будет отозван (см. "Отзыв дескрипторов") или закрыт, то этот системный ресурс будет удален.

Сведения о функциях API приведены в таблице ниже.

Функции handle_api.h

Функция

Сведения о функции

KnHandleClose()

Назначение

Закрывает дескриптор.

Параметры

  • [in] handle – дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_handles_delete]

Получение идентификатора безопасности (SID)

Получив значения идентификаторов безопасности для разных дескрипторов, можно определить, идентифицируют ли эти дескрипторы разные ресурсы или один и тот же ресурс.

Чтобы получить идентификатор безопасности по дескриптору, нужно вызвать функцию KnHandleGetSidByHandle(). При этом в маске прав дескриптора должен быть установлен флаг OCAP_HANDLE_GET_SID.

Сведения о функциях API приведены в таблице ниже.

Функции handle_api.h

Функция

Сведения о функции

KnHandleGetSidByHandle()

Назначение

Позволяет получить идентификатор безопасности (SID) по дескриптору.

Параметры

  • [in] handle – дескриптор.
  • [out] sid – указатель на идентификатор безопасности (SID).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_handle_get_sid]

Пример использования OCap

В этом примере приведен сценарий использования OCap, в котором поставщик ресурсов предоставляет следующие методы доступа к своим ресурсам:

  • OpenResource() – открытие доступа к ресурсу;
  • UseResource() – использование ресурса;
  • CloseResource() – закрытие доступа к ресурсу.

Потребитель ресурсов использует эти методы.

IDL-описание:

package SimpleOCap interface { OpenResource(in UInt32 ID, out Handle handle); UseResource(in Handle handle, in UInt8 param, out UInt8 result); CloseResource(in Handle handle); }

Сценарий включает следующие шаги:

  1. Поставщик ресурсов создает контекст пользовательского ресурса и вызывает функцию KnHandleCreateUserObject() для создания дескриптора ресурса. Поставщик ресурсов сохраняет дескриптор ресурса в контексте пользовательского ресурса.
  2. Потребитель ресурсов вызывает метод открытия доступа к ресурсу OpenResource().
    1. Поставщик ресурсов создает контекст передачи ресурса и вызывает функцию KnHandleCreateBadge() для создания объекта контекста передачи ресурса и настройки приемника уведомлений на получение уведомлений о закрытии и удалении объекта контекста передачи ресурса. Поставщик ресурсов сохраняет дескриптор объекта контекста передачи ресурса и указатель на контекст пользовательского ресурса в контексте передачи ресурса.
    2. Поставщик ресурсов, используя макрос nk_handle_desc(), упаковывает дескриптор ресурса, маску прав дескриптора и указатель на объект контекста передачи ресурса в транспортный контейнер дескриптора.
    3. Выполняется передача дескриптора от поставщика ресурсов к потребителю ресурсов, в результате которой потребитель ресурсов получает потомка дескриптора, которым владеет поставщик ресурсов.
    4. Вызов метода OpenResource() завершается успешно. Потребитель ресурсов извлекает дескриптор и маску прав дескриптора из транспортного контейнера дескриптора функциями nk_get_handle() и nk_get_rights() соответственно. Маска прав дескриптора не требуется потребителю ресурсов для обращения к ресурсу и передается, чтобы потребитель ресурсов мог узнать свои права доступа к ресурсу.
  3. Потребитель ресурсов вызывает метод использования ресурса UseResource().
    1. Дескриптор, который получен от поставщика ресурсов на шаге 2, используется в качестве параметра метода UseResource(). Перед вызовом этого метода потребитель ресурсов упаковывает дескриптор в транспортный контейнер дескриптора макросом nk_handle_desc().
    2. Выполняется разыменование дескриптора, в результате которого поставщик ресурсов получает указатель на контекст передачи ресурса.
    3. Поставщик ресурсов, используя функцию nk_is_handle_dereferenced(), проверяет, что выполнена операция разыменования, а не передача дескриптора.
    4. Поставщик ресурсов проверяет, что права доступа разыменованного дескриптора (который отправлен потребителем ресурсов) разрешают запрашиваемую операцию с ресурсом, и извлекает указатель на контекст передачи ресурса из транспортного контейнера дескриптора. Для этого поставщик ресурсов использует функцию nk_get_badge_op(), которая извлекает указатель на контекст передачи ресурса из транспортного контейнера дескриптора, если в полученной маске прав установлены флаги, соответствующие запрашиваемой операции.
    5. Поставщик ресурсов, используя контекст передачи ресурса и контекст пользовательского ресурса, выполняет запрашиваемую потребителем ресурсов операцию с ресурсом. Затем поставщик ресурсов отправляет потребителю ресурсов результат выполнения этой операции.
    6. Вызов метода UseResource() завершается успешно. Потребитель ресурсов получает результат выполнения операции с ресурсом.
  4. Потребитель ресурсов вызывает метод закрытия доступа к ресурсу CloseResource().
    1. Дескриптор, который получен от поставщика ресурсов на шаге 2, используется в качестве параметра метода CloseResource(). Перед вызовом этого метода потребитель ресурсов упаковывает дескриптор в транспортный контейнер дескриптора макросом nk_handle_desc(). После вызова метода CloseResource() потребитель ресурсов закрывает дескриптор функцией KnHandleClose().
    2. Выполняется разыменование дескриптора, в результате которого поставщик ресурсов получает указатель на контекст передачи ресурса.
    3. Поставщик ресурсов, используя функцию nk_is_handle_dereferenced(), проверяет, что выполнена операция разыменования, а не передача дескриптора.
    4. Поставщик ресурсов, используя функцию nk_get_badge(), извлекает указатель на контекст передачи ресурса из транспортного контейнера дескриптора.
    5. Поставщик ресурсов отзывает дескриптор, которым владеет потребитель ресурсов, функцией KnHandleRevokeSubtree(). В качестве параметров этой функции используются дескриптор ресурса, которым владеет поставщик ресурсов, и дескриптор объекта контекста передачи ресурса. Поставщик ресурсов получает доступ к этим дескрипторам через указатель на контекст передачи ресурса. (Технически не требуется отзывать дескриптор, которым владеет потребитель ресурсов, так как потребитель ресурсов его уже закрыл. Но поставщик ресурсов не может быть уверен в том, что потребитель ресурсов закрыл дескриптор, поэтому выполняется отзыв).
    6. Вызов метода CloseResource() завершается успешно.
  5. Поставщик ресурсов освобождает память, которая была выделена для контекста передачи ресурса и контекста пользовательского ресурса.
    1. Поставщик ресурсов вызовом функции KnNoticeGetEvent() получает уведомление, что объект контекста передачи ресурса закрыт, и закрывает дескриптор объекта контекста передачи ресурса функцией KnHandleClose().
    2. Поставщик ресурсов вызовом функции KnNoticeGetEvent() получает уведомление, что объект контекста передачи ресурса удален, и освобождает память, которая была выделена для контекста передачи ресурса.
    3. Поставщик ресурсов закрывает дескриптор ресурса функцией KnHandleClose() и освобождает память, которая была выделена для контекста пользовательского ресурса.
В начало
[Topic libkos_handles_simple_scenario]

Управление виртуальной памятью (vmm_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_api.h из состава KasperskyOS SDK.

API предназначен для выделения и освобождения памяти, создания разделяемой памяти, а также подготовки сегментов ELF-образа к загрузке в память процесса.

В этом разделе

Выделение и освобождение памяти

Создание разделяемой памяти

Подготовка сегментов ELF-образа к загрузке в память процесса

В начало
[Topic libkos_vmm_api]

Выделение и освобождение памяти

Сведения о функциях API приведены в таблице ниже.

Использование API

Страницы виртуальной памяти могут быть свободными, зарезервированными или зафиксированными. Свободные страницы, которые были использованы для выделения региона виртуальной памяти, становятся зарезервированными. Зарезервированные страницы могут как отображаться, так и не отображаться на физическую память. Зарезервированные страницы, которые отображаются на физическую память, являются зафиксированными.

Фиксация страниц региона виртуальной памяти, который выделен вызовом функции KnVmAllocate(), может выполняться тремя способами:

  1. В полном объеме при выделении региона.
  2. В полном объеме или частично после выделения региона (вызовом функции KnVmCommit()).
  3. По мере обращения к виртуальным адресам (в "ленивом" режиме).

При использовании первого способа весь требуемый объем физической памяти выделяется сразу после резервирования региона виртуальной памяти. При использовании второго и третьего способов регион виртуальной памяти резервируется без выделения физической памяти. Это позволяет экономить физическую память, если зарезервированный регион виртуальной памяти фактически не потребуется или будет использован частично. Также выделение региона виртуальной памяти без фиксации быстрее, чем с фиксацией.

В "ленивом" режиме физическая память выделяется при фактическом обращении к региону виртуальной памяти. При этом фиксируется страница, содержащая адрес обращения, и несколько страниц до или после нее.

Если вызвать функцию KnVmAllocate() с флагами VMM_FLAG_COMMIT и VMM_FLAG_LOCKED, то будет зарезервирован регион виртуальной памяти с фиксацией в полном объеме. Если вызвать функцию KnVmAllocate() с флагом VMM_FLAG_COMMIT, но без флага VMM_FLAG_LOCKED, то будет зарезервирован регион виртуальной памяти с фиксацией в "ленивом" режиме. Если вызвать функцию KnVmAllocate() с флагом VMM_FLAG_LOCKED, но без флага VMM_FLAG_COMMIT, то будет зарезервирован регион виртуальной памяти без фиксации, а последующий вызов функции KnVmCommit() обеспечит фиксацию этого региона в полном объеме. Если вызвать функцию KnVmAllocate() без флагов VMM_FLAG_COMMIT и VMM_FLAG_LOCKED, то будет зарезервирован регион виртуальной памяти без фиксации, а последующий вызов функции KnVmCommit() обеспечит фиксацию этого региона в "ленивом" режиме.

При отображении буфера MDL, буфера DMA или региона памяти MMIO на память процесса выделяется регион виртуальной памяти. Этот регион выделяет функция, выполняющая отображение.

В начале и/или конце региона виртуальной памяти может располагаться охранная страница. Эта страница никогда не фиксируется, и при обращении к ней возникает исключение, которое сигнализирует о выходе за границы региона.

Чтобы изменить права доступа к региону виртуальной памяти, нужно вызвать функцию KnVmProtect(). Можно полностью закрыть, а затем снова открыть доступ к региону с сохранением содержимого.

Чтобы освободить физическую память, сохранив резервирование виртуальных адресов, нужно вызвать функцию KnVmDecommit() или KnVmReset(). При этом содержимое региона виртуальной памяти будет потеряно. После освобождения физической памяти вызовом функции KnVmDecommit() для последующего использования региона виртуальной памяти нужно вызвать функцию KnVmCommit(). После освобождения физической памяти вызовом функции KnVmReset() регион виртуальной памяти можно использовать без дополнительных действий. Этот регион виртуальной памяти будет соответствовать выделенному вызовом функции KnVmAllocate() с флагом VMM_FLAG_COMMIT, но без флага VMM_FLAG_LOCKED.

Функции KnVmProtect(), KnVmDecommit() и KnVmReset() нельзя использовать, если на регион виртуальной памяти отображен буфер MDL, буфер DMA или регион памяти MMIO.

Чтобы освободить регион виртуальной памяти, нужно вызвать функцию KnVmUnmap(). В результате вызова этой функции зарезервированные страницы становятся свободными независимо от того, зафиксированы они или нет, а также освобождается физическая память, отображенная на зафиксированные страницы.

Функция KnVmUnmap() освобождает виртуальные адреса региона, на который отображен буфер MDL, но не удаляет буфер MDL. Также эту функцию нельзя использовать, если на регион виртуальной памяти отображен буфер DMA или регион памяти MMIO.

Функции KnVmCommit(), KnVmProtect(), KnVmDecommit(), KnVmReset() и KnVmUnmap() можно применять как для всего выделенного региона виртуальной памяти, так и для его части.

Приведенные в этом разделе функции являются базой для реализации функций выделения и освобождения памяти библиотеки libkos, а также таких интерфейсов POSIX, как malloc(), calloc(), realloc(), free(), mmap(), munmap().

Сведения о функциях API

Функции vmm_api.h

Функция

Сведения о функции

KnVmAllocate()

Назначение

Выделяет (резервирует и опционально фиксирует) регион виртуальной памяти.

Параметры

  • [in,optional] addr – странично выровненный желаемый базовый адрес региона виртуальной памяти или 0, чтобы этот адрес был выбран автоматически.
  • [in] size – размер региона виртуальной памяти в байтах. Должен быть кратен размеру страницы памяти.
  • [in] flags – флаги, задающие параметры региона виртуальной памяти. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает базовый адрес выделенного региона виртуальной памяти, иначе возвращает RTL_NULL.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • VMM_FLAG_COMMIT – фиксация региона виртуальной памяти в "ленивом" режиме, когда страницы физической памяти выделяются по мере обращения к виртуальным адресам.
  • VMM_FLAG_LOCKED – фиксация региона виртуальной памяти с выделением всего требуемого объема физической памяти.
  • VMM_FLAG_READ, VMM_FLAG_WRITE, VMM_FLAG_EXECUTE и VMM_FLAG_RWX_MASK – флаги, задающие права доступа к региону виртуальной памяти.
  • VMM_FLAG_LOW_GUARD, VMM_FLAG_HIGH_GUARD – добавление охранной страницы в начало и конец региона виртуальной памяти соответственно. Размер охранной страницы не включается в размер региона виртуальной памяти.
  • VMM_FLAG_GROW_DOWN – определение направления, в котором выполняется отображение виртуальной памяти на физическую при "ленивом" режиме фиксации. Если флаг установлен, выполняется отображение страницы виртуальной памяти, содержащей адрес обращения, и нескольких предыдущих страниц. Если флаг не установлен, выполняется отображение страницы виртуальной памяти, содержащей адрес обращения, и нескольких последующих страниц.

Допустимые комбинации флагов, задающих права доступа к региону виртуальной памяти:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.

KnVmCommit()

Назначение

Фиксирует регион виртуальной памяти.

Параметры

  • [in] addr – странично выровненный базовый адрес региона виртуальной памяти.
  • [in] size – размер региона виртуальной памяти в байтах. Должен быть кратен размеру страницы памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnVmDecommit()

Назначение

Отменяет фиксацию региона виртуальной памяти.

Параметры

  • [in] addr – странично выровненный базовый адрес региона виртуальной памяти.
  • [in] size – размер региона виртуальной памяти в байтах. Должен быть кратен размеру страницы памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnVmProtect()

Назначение

Изменяет права доступа к региону виртуальной памяти.

Параметры

  • [in] addr – странично выровненный базовый адрес региона виртуальной памяти.
  • [in] size – размер региона виртуальной памяти в байтах. Должен быть кратен размеру страницы памяти.
  • [in] newFlags – флаги, задающие права доступа к региону виртуальной памяти. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре newFlags можно указать следующие комбинации флагов:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.
  • 0 – доступ запрещен.

KnVmUnmap()

Назначение

Освобождает регион виртуальной памяти.

Параметры

  • [in] addr – странично выровненный базовый адрес региона виртуальной памяти.
  • [in] size – размер региона виртуальной памяти в байтах. Должен быть кратен размеру страницы памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnVmQuery()

Назначение

Позволяет получить сведения о странице виртуальной памяти.

Параметры

  • [in] addr – адрес, входящий в страницу виртуальной памяти.
  • [out] info – указатель на структуру, содержащую сведения о странице виртуальной памяти. Тип структуры определен в заголовочном файле sysroot-*-kos/include/vmm/info.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnVmReset()

Назначение

Отменяет фиксацию региона виртуальной памяти.

Параметры

  • [in] addr – странично выровненный базовый адрес региона виртуальной памяти.
  • [in] size – размер региона виртуальной памяти в байтах. Должен быть кратен размеру страницы памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_vmm_api_base]

Создание разделяемой памяти

Сведения о функциях API приведены в таблице ниже.

Использование API

Для создания разделяемой памяти используется буфер MDL. Буфер MDL – это буфер, состоящий из одного или нескольких регионов физической памяти, которые могут быть отображены на память нескольких процессов одновременно. Для отображения буфера MDL на память процесса используется объект ядра – таблица описания памяти. Таблица описания памяти (англ. Memory Descriptor List, MDL) – структура данных, содержащая адреса и размеры регионов физической памяти, из которых состоит буфер MDL. Дескриптор буфера MDL идентифицирует таблицу описания памяти.

Чтобы создать разделяемую память, процессу нужно создать буфер MDL, отобразить его на свою память и передать дескриптор буфера MDL через IPC другим процессам, которым также нужно отобразить этот буфер MDL на свою память.

Чтобы создать буфер MDL, нужно вызвать функцию KnPmmMdlCreate(), KnPmmMdlCreateFromBuf() или KnPmmMdlCreateFromVm(). Функция KnPmmMdlCreateFromBuf() создает буфер MDL и копирует в него данные. Функция KnPmmMdlCreateFromVm() создает буфер MDL и отображает его на память вызывающего процесса.

Чтобы зарезервировать регион виртуальной памяти и отобразить на него буфер MDL, нужно вызвать функцию KnPmmMdlMap(). Буфер MDL можно отобразить на несколько регионов виртуальной памяти одного процесса.

Буфер MDL можно использовать для передачи больших объемов данных между процессами без создания разделяемой памяти. В этом случае необходимо обеспечить, чтобы буфер MDL не отображался на память нескольких процессов одновременно. Взаимодействующие процессы должны поочередно отображать буфер MDL в свою память, считывать и/или записывать данные и освобождать регион виртуальной памяти, на который отображен этот буфер MDL.

Модуль безопасности Kaspersky Security Module не может контролировать данные, которые передаются между процессами через буфер MDL.

Удаление буфера MDL

Чтобы удалить буфер MDL, нужно выполнить следующие шаги:

  1. Освободить регионы виртуальной памяти, на которые отображается буфер MDL, во всех процессах, которые используют этот буфер MDL.

    Чтобы выполнить этот шаг, нужно использовать функцию KnVmUnmap().

  2. Закрыть или отозвать каждый дескриптор буфера MDL во всех процессах, которые владеют этими дескрипторами.

    Чтобы выполнить этот шаг, нужно использовать функцию KnHandleClose() и/или KnHandleRevoke(), которые объявлены в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.

Сведения о функциях API

Функции vmm_api.h

Функция

Сведения о функции

KnPmmMdlCreate()

Назначение

Создает буфер MDL.

Параметры

  • [in] size – размер буфера MDL в байтах. Должен быть кратен размеру страницы памяти.
  • [in] flags – флаги, задающие права доступа к буферу MDL. Тип параметра и флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [out] outHandle – указатель на дескриптор буфера MDL.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие комбинации флагов:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.

KnPmmMdlCreateFromVm()

Назначение

Создает буфер MDL из физической памяти, отображенной на заданный регион виртуальной памяти, и отображает созданный буфер MDL на этот регион.

Параметры

  • [in] addr – странично выровненный базовый адрес региона виртуальной памяти.
  • [in] size – размер региона виртуальной памяти в байтах. Должен быть кратен размеру страницы памяти.
  • [in] flags – флаги, задающие права доступа к буферу MDL. Тип параметра и флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [out] outHandle – указатель на дескриптор буфера MDL.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Функцию можно использовать, если заданный регион виртуальной памяти выделен с фиксацией.

В параметре flags можно указать следующие комбинации флагов:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.

KnPmmMdlCreateFromBuf()

Назначение

Создает буфер MDL и копирует в него данные из заданного буфера.

Параметры

  • [in] offset – смещение в буфере MDL, с которого нужно начать запись данных, в байтах.
  • [in] size – размер буфера MDL в байтах. Должен быть кратен размеру страницы памяти. Также должно выполняться условие: size>=bufSize+offset.
  • [in] flags – флаги, задающие права доступа к буферу MDL. Тип параметра и флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [in] buf – указатель на буфер с данными.
  • [in] bufSize – размер буфера с данными в байтах.
  • [out] outHandle – указатель на дескриптор буфера MDL.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие комбинации флагов:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.

KnPmmMdlGetSize()

Назначение

Позволяет получить размер буфера MDL.

Параметры

  • [in] handle – дескриптор буфера MDL.
  • [out] size – размер буфера MDL в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnPmmMdlMap()

Назначение

Резервирует регион виртуальной памяти и отображает на него буфер MDL.

Параметры

  • [in] handle – дескриптор буфера MDL.
  • [in] offset – смещение в буфере MDL, с которого нужно начать отображение, в байтах. Должно быть кратно размеру страницы памяти.
  • [in] length – размер части буфера MDL, которую нужно отобразить, в байтах. Должен быть кратен размеру страницы памяти. Также должно выполняться условие: length<=размер буфера MDL-offset.
  • [in,optional] hint – странично выровненный желаемый базовый адрес региона виртуальной памяти или 0, чтобы этот адрес был выбран автоматически.
  • [in] prots – флаги, задающие параметры региона виртуальной памяти. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [out] addr – указатель на базовый адрес региона виртуальной памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре prots можно указать следующие флаги:

  • VMM_FLAG_READ, VMM_FLAG_WRITE, VMM_FLAG_EXECUTE и VMM_FLAG_RWX_MASK – флаги, задающие права доступа к региону виртуальной памяти.
  • VMM_FLAG_LOW_GUARD, VMM_FLAG_HIGH_GUARD – добавление охранной страницы в начало и конец региона виртуальной памяти соответственно.

Допустимые комбинации флагов, задающих права доступа к региону виртуальной памяти:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.

KnPmmMdlClone()

Назначение

Создает буфер MDL на основе существующего.

Буфер MDL создается из тех же регионов физической памяти, что и оригинальный.

Параметры

  • [in] origin – дескриптор оригинального буфера MDL.
  • [in] offset – смещение в оригинальном буфере MDL, с которого нужно начать дублирование, в байтах. Должно быть кратно размеру страницы памяти.
  • [in] length – размер части оригинального буфера MDL, которую нужно дублировать, в байтах. Должен быть кратен размеру страницы памяти. Также должно выполняться условие: length<=размер оригинального буфера MDL-offset.
  • [out] clone – указатель на дескриптор созданного буфера MDL.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_vmm_api_mdl]

Подготовка сегментов ELF-образа к загрузке в память процесса

Сведения о функциях API приведены в таблице ниже.

Использование API

Буферы MDL используются не только для создания разделяемой памяти, но и для загрузки сегментов ELF-образа в память нового процесса. (Загрузку сегментов ELF-образа выполняет, например, инициализирующая программа Einit.)

Функции KnVmSegInitFromVm() и KnVmSegInitFromBuf() создают буфер MDL и помещают в него сегмент ELF-образа для последующей загрузки этого сегмента в память нового процесса.

Удаление буферов MDL, содержащих сегменты ELF-образа

Чтобы буферы MDL, содержащие сегменты ELF-образа, были удалены, необходимо, чтобы завершился новый процесс, на память которого эти буферы MDL отображены. А также до или после завершения этого процесса нужно выполнить следующие шаги:

  1. Освободить регионы виртуальной памяти, на которые отображены буферы MDL, в процессе, который создал эти буферы MDL.

    Этот шаг нужно выполнить только для тех буферов MDL, которые созданы с использованием функции KnVmSegInitFromVm().

    Чтобы выполнить этот шаг, нужно использовать функцию KnVmUnmap().

  2. Закрыть дескрипторы буферов MDL в процессе, который создал эти буферы MDL.

    Чтобы выполнить этот шаг, нужно использовать функцию KnHandleClose(), которая объявлена в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.

Сведения о функциях API

Функции vmm_api.h

Функция

Сведения о функции

KnVmSegInitFromVm()

Назначение

Создает буфер MDL из физической памяти, отображенной на заданный регион виртуальной памяти, который содержит сегмент ELF-образа.

Параметры

  • [out] seg – указатель на структуру, описывающую сегмент ELF-образа. Эта структура содержит дескриптор буфера MDL (поле h) и используется для загрузки сегмента ELF-образа в память процесса. Тип структуры определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_types.h из состава KasperskyOS SDK.
  • [in,optional] loadAddr – странично выровненный адрес загрузки сегмента ELF-образа в память процесса или 0, чтобы этот адрес был выбран автоматически.
  • [in] addr – странично выровненный базовый адрес региона виртуальной памяти.
  • [in] size – размер региона виртуальной памяти в байтах. Должен быть кратен размеру страницы памяти.
  • [in] flags – флаги, задающие права доступа к буферу MDL. Тип параметра и флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Функцию можно использовать, если заданный регион виртуальной памяти выделен с фиксацией.

В параметре flags можно указать следующие комбинации флагов:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.

KnVmSegInitFromBuf()

Назначение

Создает буфер MDL и копирует в него сегмент ELF-образа из заданного буфера.

Параметры

  • [out] seg – указатель на структуру, описывающую сегмент ELF-образа. Эта структура содержит дескриптор буфера MDL (поле h) и используется для загрузки сегмента ELF-образа в память процесса. Тип структуры определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_types.h из состава KasperskyOS SDK.
  • [in,optional] loadAddr – странично выровненный адрес загрузки сегмента ELF-образа в память процесса или 0, чтобы этот адрес был выбран автоматически.
  • [in] offset – смещение в буфере MDL, с которого нужно начать запись сегмента ELF-образа, в байтах.
  • [in] size – размер сегмента ELF-образа в байтах. Должен быть кратен размеру страницы памяти.
  • [in] flags – флаги, задающие права доступа к буферу MDL. Тип параметра и флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [in] fileOffset – смещение сегмента в ELF-образе в байтах.
  • [in] buildId – указатель на идентификатор сборки. Компоновщик записывает этот идентификатор ELF-образ.
  • [in] buildIdSize – размер идентификатора сборки в байтах.
  • [in] buf – указатель на буфер, содержащий сегмент ELF-образа.
  • [in] bufSize – размер буфера, содержащего сегмент ELF-образа, в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие комбинации флагов:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.

В начало
[Topic libkos_vmm_api_elf]

Выделение и освобождение памяти (alloc.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/alloc.h из состава KasperskyOS SDK.

API предназначен для выделения и освобождения памяти. Выделенная память представляет собой зафиксированный регион виртуальной памяти, к которому разрешен доступ на чтение и запись.

Сведения о функциях API приведены в таблице ниже.

Функции alloc.h

Функция

Сведения о функции

KosMemAllocEx()

Назначение

Выделяет память.

Параметры

  • [in] size – размер выделяемой памяти в байтах. Если указать нулевой размер, функция возвращает указатель, который можно передать функции KosMemFree().
  • [in] align – значение, задающее выравнивание выделяемой памяти. Должно быть степенью двойки. Адрес выделяемой памяти может быть невыровненным (align=1) или выровненным (align=2,4,...,2^N) на границу 2^N-байтовой последовательности (например, двухбайтовой, четырехбайтовой).
  • [in] zeroed – значение, задающее инициализацию выделяемой памяти (1 – инициализировать нулями, 0 – не инициализировать).

Возвращаемые значения

В случае успеха возвращает указатель на выделенную память, иначе возвращает RTL_NULL.

KosMemAlloc()

Назначение

Выделяет память.

Параметры

  • [in] size – размер выделяемой памяти в байтах. Если указать нулевой размер, функция возвращает указатель, который можно передать функции KosMemFree().

Возвращаемые значения

В случае успеха возвращает указатель на выделенную памяти, иначе возвращает RTL_NULL.

KosMemZalloc()

Назначение

Выделяет память и инициализирует ее нулями.

Параметры

  • [in] size – размер выделяемой памяти в байтах. Если указать нулевой размер, функция возвращает указатель, который можно передать функции KosMemFree().

Возвращаемые значения

В случае успеха возвращает указатель на выделенную память, иначе возвращает RTL_NULL.

KosMemFree()

Назначение

Освобождает память.

Параметры

  • [in] ptr – указатель на освобождаемую память. Если указать RTL_NULL, функция не выполняет никаких действий.

Возвращаемые значения

Нет.

KosMemRealloc()

Назначение

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

Параметры

  • [in,optional] ptr – указатель на ранее выделенную память или RTL_NULL, если требуется только выделить память без копирования содержимого ранее выделенной памяти.
  • [in] size – размер вновь выделяемой памяти в байтах. Содержимое ранее выделенной памяти копируется во вновь выделенную память в том объеме, который вмещается во вновь выделенную память. Если указать нулевой размер, функция возвращает указатель, который можно передать функции KosMemFree().

Возвращаемые значения

В случае успеха возвращает указатель на выделенную память, иначе возвращает RTL_NULL.

KosMemReallocEx()

Назначение

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

Параметры

  • [in,optional] ptr – указатель на ранее выделенную память или RTL_NULL, если требуется только выделить память без копирования содержимого ранее выделенной памяти.
  • [in] size – размер вновь выделяемой памяти в байтах. Содержимое ранее выделенной памяти копируется во вновь выделенную память в том объеме, который вмещается во вновь выделенную память. Если указать нулевой размер, функция возвращает указатель, который можно передать функции KosMemFree().
  • [in] zeroed – значение, задающее инициализацию выделяемой памяти (1 – инициализировать нулями, 0 – не инициализировать). Если через параметр ptr передать RTL_NULL, а в параметре zeroed указать 1, то выделенная память будет инициализирована нулями. Если размер вновь выделенной памяти меньше или равен размеру ранее выделенной памяти, то значение параметра zeroed не влияет на содержимое вновь выделенной памяти. Если размер вновь выделенной памяти больше размера ранее выделенной памяти, и в параметре zeroed указано значение 1, то фрагмент вновь выделенной памяти, который не занят скопированным содержимым из ранее выделенной памяти, может быть инициализирован нулями. Чтобы этот фрагмент гарантированно был инициализирован нулями, нужно выполнить следующее. Изначально память нужно выделить функцией KosMemZalloc(), функцией KosMemAllocEx() со значением 1 в параметре zeroed или функцией KosMemReallocEx() со значением 1 в параметре zeroed и значением RTL_NULL в параметре ptr. Все последующие вызовы KosMemReallocEx() нужно выполнять со значением 1 в параметре zeroed.

Возвращаемые значения

В случае успеха возвращает указатель на выделенную память, иначе возвращает RTL_NULL.

В начало
[Topic libkos_alloc_api]

Использование DMA (dma.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/io/dma.h из состава KasperskyOS SDK.

API предназначен для организации обмена данными между устройствами и оперативной памятью в режиме прямого доступа к памяти (англ. Direct Memory Access, DMA), при котором процессор не используется.

Сведения о функциях API приведены в таблице ниже.

Использование API

Типовой сценарий использования API включает следующие шаги:

  1. Создание буфера DMA.

    Буфер DMA –это буфер, состоящий из одного или нескольких регионов физической памяти (блоков), используемых для DMA. Буфер DMA, состоящий из нескольких блоков, можно использовать, если устройство поддерживает режим "scatter/gather DMA". Буфер DMA, состоящий из одного блока, можно использовать, если устройство поддерживает режим "scatter/gather DMA" или "continuous DMA". Вероятность создать буфер DMA, состоящий из одного большого блока, ниже, чем вероятность создать буфер DMA, состоящий из нескольких небольших блоков. Это особенно актуально при высокой фрагментации физической памяти.

    Если устройство поддерживает только режим "continuous DMA", то даже при задействовании IOMMU нужно использовать буфер DMA, состоящий из одного блока.

    Чтобы выполнить этот шаг, нужно вызвать функцию KnIoDmaCreate() или KnIoDmaCreateContinuous(). Функция KnIoDmaCreateContinuous() создает буфер DMA, состоящий из одного блока. Функция KnIoDmaCreate() создает буфер DMA, состоящий из одного блока, если значение 2^order равно значению size/размер страницы памяти, или значение 2^order является ближайшим большим к значению size/размер страницы памяти в упорядоченном по возрастанию множестве {2^(order-1);size/размер страницы памяти;2^order}. Если значение size/размер страницы памяти больше значения 2^order, функция KnIoDmaCreate() может создать буфер DMA, состоящий из нескольких блоков.

    Дескриптор буфера DMA можно передать другому процессу через IPC.

  2. Отображение буфера DMA на память процессов.

    Один буфер DMA может быть отображен на несколько регионов виртуальной памяти одного или нескольких процессов, которые владеют дескриптором этого буфера DMA. В результате отображения процессы получают доступ к буферу DMA на чтение и/или запись.

    Чтобы зарезервировать регион виртуальной памяти и отобразить на него буфер DMA, нужно вызвать функцию KnIoDmaMap().

    Дескриптор, полученный при вызове функции KnIoDmaMap(), нельзя передать другому процессу через IPC.

  3. Открытие доступа к буферу DMA для устройства вызовом функции KnIoDmaBegin() или KnIoDmaBeginEx().

    Вызов функции KnIoDmaBegin() или KnIoDmaBeginEx() необходим, чтобы создать объект ядра, содержащий адреса и размеры блоков, из которых состоит буфер DMA. Эти сведения необходимы устройству, чтобы использовать буфер DMA. Устройство может работать как с физическими, так и с виртуальными адресами в зависимости от того, задействован ли IOMMU. Если IOMMU задействован, нужно использовать функцию KnIoDmaBegin() или KnIoDmaBeginEx(), и объект будет содержать виртуальные и физические адреса блоков. Если IOMMU не задействован, нужно использовать функцию KnIoDmaBegin(), и объект будет содержать только физические адреса блоков.

    При задействовании IOMMU устройство должно быть прикреплено к домену IOMMU.

    Дескриптор, полученный при вызове функции KnIoDmaBegin() или KnIoDmaBeginEx(), нельзя передать другому процессу через IPC.

  4. Получение сведений о буфере DMA.

    На этом шаге нужно получить адреса и размеры блоков из объекта ядра, созданного вызовом функции KnIoDmaBegin() или KnIoDmaBeginEx(). Полученные адреса и размеры в дальнейшем требуется передать устройству, используя, например, MMIO. После получения этих сведений устройство может записывать в буфер DMA и/или читать из него.

    Чтобы выполнить этот шаг, нужно вызвать одну из следующих функций:

    • KnIoDmaGetInfo();
    • KnIoDmaGetPhysInfo();
    • KnIoDmaContinuousGetDmaAddr();
    • KnIoDmaContinuousGetPhysAddr().

    Функции KnIoDmaGetInfo() и KnIoDmaGetPhysInfo() позволяют получить номер страницы памяти (frame) и порядок (order) для каждого блока. (Номер страницы памяти, умноженный на размер страницы памяти, дает адрес блока. Значение 2^order представляет собой размер блока в страницах памяти.) Через выходной параметр outInfo эти функции передают объект KosObject, который содержит структуру со сведениями о буфере DMA (об объектах KosObject см. "Использование объектов KosObject (objects.h)"). Тип структуры определен в заголовочном файле sysroot-*-kos/include/io/io_dma.h из состава KasperskyOS SDK. Функция KnIoDmaGetInfo() заполняет данными все поля структуры, а функция KnIoDmaGetPhysInfo() заполняет данными только поля count и descriptors, записывая в остальные поля нули. При использовании функции KnIoDmaGetInfo() массив descriptors содержит номера виртуальных страниц памяти, если IOMMU задействован, и номера физических страниц памяти, если IOMMU не задействован. При использовании функции KnIoDmaGetPhysInfo() массив descriptors содержит номера физических страниц памяти независимо от того, задействован IOMMU или нет.

    Функции KnIoDmaContinuousGetDmaAddr() и KnIoDmaContinuousGetPhysAddr() можно использовать, если буфер DMA состоит из одного блока. Эти функции позволяет получить адрес блока. (В качестве размера блока нужно принять размер буфера DMA, заданный при его создании.) Функция KnIoDmaContinuousGetDmaAddr() передает через выходной параметр addr виртуальный адрес, если IOMMU задействован, и физический адрес, если IOMMU не задействован. Функция KnIoDmaContinuousGetPhysAddr() передает через выходной параметр addr физический адрес независимо от того, задействован IOMMU или нет.

    На Raspberry Pi 4 B функция KnIoDmaGetPhysInfo() позволяет получить действительные номера физических страниц, а функция KnIoDmaGetInfo() позволяет получить номера физических страниц со смещением, обусловленным тем, что некоторые устройства используют при DMA трансляцию VPU (Visual Processing Unit). Аналогично функции KnIoDmaContinuousGetPhysAddr() и KnIoDmaContinuousGetDmaAddr() позволяют получить действительный и смещенный физический адрес соответственно.

Закрытие доступа к буферу DMA для устройства

Закрыть доступ к буферу DMA для устройства можно только при задействовании IOMMU. Если удалить объект ядра, созданный при вызове функции KnIoDmaBegin() или KnIoDmaBeginEx(), то доступ устройства к буферу DMA будет закрыт. Чтобы удалить этот объект, нужно закрыть его дескриптор.

Удаление буфера DMA

Чтобы удалить буфер DMA, нужно выполнить следующие шаги:

  1. Освободить регионы виртуальной памяти, зарезервированные при вызовах функции KnIoDmaMap().

    Чтобы выполнить этот шаг, нужно закрыть дескрипторы, которые были получены при вызовах функции KnIoDmaMap().

    Этот шаг нужно выполнить для всех процессов, на память которых отображен буфер DMA.

  2. Удалить объект ядра, созданный вызовом функции KnIoDmaBegin() или KnIoDmaBeginEx().

    Чтобы выполнить этот шаг, нужно закрыть дескриптор, который был получен при вызове функции KnIoDmaBegin() или KnIoDmaBeginEx().

  3. Закрыть или отозвать каждый дескриптор буфера DMA во всех процессах, которые владеют этими дескрипторами.

Сведения о функциях API

Функции dma.h

Функция

Сведения о функции

KnIoDmaCreate()

Назначение

Создает буфер DMA.

Параметры

  • [in] order – параметр, задающий минимальное число страниц памяти (2^order) в блоке.
  • [in] size – размер буфера DMA в байтах. Должен быть кратен размеру страницы памяти.
  • [in] flags – флаги, задающие параметры буфера DMA. Тип параметра и флаги определены в заголовочном файле sysroot-*-kos/include/io/io_dma.h из состава KasperskyOS SDK.
  • [out] outRid – указатель на дескриптор буфера DMA.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • DMA_DIR_TO_DEVICE – устройство имеет доступ к буферу DMA на чтение.
  • DMA_DIR_FROM_DEVICE – устройство имеет доступ к буферу DMA на запись.
  • DMA_DIR_BIDIR – устройство имеет доступ к буферу DMA на чтение и запись.
  • DMA_ZONE_DMA32 – для создания буфера DMA разрешено использовать только первые четыре гигабайта физической памяти.
  • DMA_ATTR_WRITE_BACK, DMA_ATTR_WRITE_THROUGH, DMA_ATTR_CACHE_DISABLE, DMA_ATTR_WRITE_COMBINE, DMA_RULE_CACHE_VOLATILE, DMA_RULE_CACHE_FIXED – управление кешированием.

KnIoDmaCreateContinuous()

Назначение

Создает буфер DMA, состоящий из одного блока.

Параметры

  • [in] size – размер буфера DMA в байтах. Должен быть кратен размеру страницы памяти.
  • [in] flags – флаги, задающие параметры буфера DMA. Тип параметра и флаги определены в заголовочном файле sysroot-*-kos/include/io/io_dma.h из состава KasperskyOS SDK.
  • [out] outRid – указатель на дескриптор буфера DMA.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • DMA_DIR_TO_DEVICE – устройство имеет доступ к буферу DMA на чтение.
  • DMA_DIR_FROM_DEVICE – устройство имеет доступ к буферу DMA на запись.
  • DMA_DIR_BIDIR – устройство имеет доступ к буферу DMA на чтение и запись.
  • DMA_ZONE_DMA32 – для создания буфера DMA разрешено использовать только первые четыре гигабайта физической памяти.
  • DMA_ATTR_WRITE_BACK, DMA_ATTR_WRITE_THROUGH, DMA_ATTR_CACHE_DISABLE, DMA_ATTR_WRITE_COMBINE, DMA_RULE_CACHE_VOLATILE, DMA_RULE_CACHE_FIXED – управление кешированием.

KnIoDmaMap()

Назначение

Резервирует регион виртуальной памяти и отображает на него буфер DMA.

Параметры

  • [in] rid – дескриптор буфера DMA.
  • [in] offset – смещение в буфере DMA, с которого нужно начать отображение, в байтах. Должно быть кратно размеру страницы памяти.
  • [in] length – размер части буфера DMA, которую нужно отобразить, в байтах. Должен быть кратен размеру страницы памяти. Также должно выполняться условие: length<=размер буфера DMA-offset.
  • [in,optional] hint – странично выровненный желаемый базовый адрес региона виртуальной памяти или 0, чтобы этот адрес был выбран автоматически.
  • [in] vmflags – флаги, задающие права доступа к региону виртуальной памяти. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [out] addr – указатель на базовый адрес региона виртуальной памяти.
  • [out] handle – указатель на дескриптор, который используется для освобождения региона виртуальной памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре vmflags можно указать следующие флаги:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_WRITE – доступ на запись.

KnIoDmaModify()

Назначение

Изменяет параметры кеширования буфера DMA.

Параметры

  • [in] rid – дескриптор буфера DMA.
  • [in] newAttr – флаги, задающие параметры кеширования буфера DMA. Флаги определены в заголовочном файле sysroot-*-kos/include/io/io_dma.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Функцию можно использовать, если выполняются следующие условия:

  1. Буфер DMA был создан с указанием флага DMA_RULE_CACHE_VOLATILE.
  2. Буфер DMA не отображен на виртуальную память.
  3. Предыдущий вызов функции (если он был) был выполнен с указанием флага DMA_RULE_CACHE_VOLATILE.

В параметре newAttr можно указать следующие флаги:

  • DMA_ATTR_WRITE_BACK, DMA_ATTR_WRITE_THROUGH, DMA_ATTR_CACHE_DISABLE, DMA_ATTR_WRITE_COMBINE, DMA_RULE_CACHE_VOLATILE – управление кешированием.

KnIoDmaGetInfo()

Назначение

Позволяет получить сведения о буфере DMA.

Сведения включают адреса и размеры блоков.

Параметры

  • [in] rid – дескриптор буфера DMA.
  • [out] outInfo – указатель на адрес объекта, содержащий структуру со сведениями о буфере DMA. Тип структуры определен в заголовочном файле sysroot-*-kos/include/io/io_dma.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Чтобы удалить объект, полученный через параметр outInfo, нужно использовать функцию KosPutObject() из API objects.h.

KnIoDmaGetPhysInfo()

Назначение

Позволяет получить физические адреса и размеры блоков буфера DMA.

Параметры

  • [in] rid – дескриптор буфера DMA.
  • [out] outInfo – указатель на адрес объекта, содержащего структуру со сведениями о буфере DMA. Тип структуры определен в заголовочном файле sysroot-*-kos/include/io/io_dma.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Чтобы удалить объект, полученный через параметр outInfo, нужно использовать функцию KosPutObject() из API objects.h.

KnIoDmaContinuousGetDmaAddr()

Назначение

Позволяет получить адрес блока для буфера DMA, состоящего из одного блока.

Параметры

  • [in] rid – дескриптор буфера DMA.
  • [out] addr – указатель на адрес блока. Тип адреса определен в заголовочном файле sysroot-*-kos/include/hal/mtypes.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIoDmaContinuousGetPhysAddr()

Назначение

Позволяет получить физический адрес блока для буфера DMA, состоящего из одного блока.

Параметры

  • [in] rid – дескриптор буфера DMA.
  • [out] addr – указатель на физический адрес блока. Тип адреса определен в заголовочном файле sysroot-*-kos/include/hal/mtypes.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIoDmaBegin()

Назначение

Открывает доступ к буферу DMA для устройства.

Параметры

  • [in] rid – дескриптор буфера DMA.
  • [out] handle – указатель на дескриптор объекта ядра, содержащего адреса и размеры блоков, которые необходимы устройству, чтобы использовать буфер DMA.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIoDmaBeginEx()

Назначение

Открывает доступ к буферу DMA для устройства.

Параметры

  • [in] rid – дескриптор буфера DMA.
  • [in] domain – дескриптор домена IOMMU.
  • [out] handle – указатель на дескриптор объекта ядра, содержащего адреса и размеры блоков, которые необходимы устройству, чтобы использовать буфер DMA.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_dma_api]

Ввод-вывод через память (mmio.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/io/mmio.h из состава KasperskyOS SDK.

API предназначен для работы с памятью MMIO. Память MMIO – это физические адреса, на которые отображены регистры и память устройств. (Для адресации физической памяти и доступа к регистрам и памяти устройств используются части одного пространства физических адресов.)

Сведения о функциях API приведены в таблице ниже.

Использование API

Типовой сценарий использования API включает следующие шаги:

  1. Регистрация региона памяти MMIO, соответствующего устройству, с которым нужно работать.

    Чтобы выполнить этот шаг, нужно вызвать функцию KnRegisterPhyMem().

    Дескриптор региона памяти MMIO можно передать другому процессу через IPC.

  2. Отображение региона памяти MMIO на память процесса.

    В один момент времени регион памяти MMIO может быть отображен только на один регион виртуальной памяти только одного процесса. (В разные моменты времени регион памяти MMIO может отображаться на виртуальную память разных процессов, владеющих дескриптором этого региона.) В результате отображения процесс получает доступ к региону памяти MMIO на чтение и/или запись.

    Чтобы зарезервировать регион виртуальной памяти и отобразить на него регион памяти MMIO, нужно вызвать функцию KnIoMapMem().

    Дескриптор, полученный при вызове функции KnIoMapMem(), нельзя передать другому процессу через IPC.

  3. Чтение данных из региона памяти MMIO и запись данных в него через память процесса.

    8-, 16- и 32-битные слова, считанные из региона памяти MMIO или записанные в него, представляют собой значения регистров устройства или содержимое памяти устройства.

    Чтобы выполнить этот шаг, нужно использовать функции IoReadMmReg8|16|32(), IoReadMmBuffer8|16|32(), IoWriteMmReg8|16|32(), IoWriteMmBuffer8|16|32().

Дерегистрация региона памяти MMIO

Чтобы дерегистрировать регион памяти MMIO, нужно выполнить следующие шаги:

  1. Освободить регион виртуальной памяти, выделенный при вызове функции KnIoMapMem().

    Чтобы выполнить этот шаг, нужно вызвать функцию KnHandleClose(), указав дескриптор, который был получен при вызове функции KnIoMapMem(). (Функция KnHandleClose() объявлена в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.)

  2. Закрыть или отозвать каждый дескриптор региона памяти MMIO во всех процессах, которые владеют этими дескрипторами.

    Чтобы выполнить этот шаг, нужно использовать функцию KnHandleClose() и/или KnHandleRevoke(), которые объявлены в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.

Сведения о функциях API

Функции mmio.h

Функция(и)

Сведения о функции(ях)

KnRegisterPhyMem()

Назначение

Регистрирует регион памяти MMIO.

Параметры

  • [in] addr – странично выровненный базовый адрес региона памяти MMIO.
  • [in] size – размер региона памяти MMIO. Должен быть кратен размеру страницы памяти.
  • [out] outRid – указатель на дескриптор региона памяти MMIO.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIoMapMem()

Назначение

Резервирует регион виртуальной памяти и отображает на него регион памяти MMIO.

Параметры

  • [in] rid – дескриптор региона памяти MMIO.
  • [in] prot – флаги, задающие права доступа к региону виртуальной памяти. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [in] attr – флаги, задающие параметры кеширования. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [out] addr – указатель на базовый адрес региона виртуальной памяти.
  • [out] handle – указатель на дескриптор, который используется для освобождения региона виртуальной памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре prot можно указать следующие флаги:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_WRITE – доступ на запись.

В параметре attr можно указать следующие флаги:

  • VMM_FLAG_WRITE_BACK, VMM_FLAG_WRITE_THROUGH, VMM_FLAG_WRITE_COMBINE, VMM_FLAG_CACHE_DISABLE – управление кешированием.

    Рекомендуется указать флаг VMM_FLAG_CACHE_DISABLE.

IoReadMmReg8()

IoReadMmReg16()

IoReadMmReg32()

Назначение

Позволяют получить 8-, 16- или 32-битное слово из региона памяти MMIO.

Параметры

  • [in] reg – виртуальный адрес для чтения слова.

Возвращаемые значения

8-, 16- или 32-битное слово из региона памяти MMIO.

IoReadMmBuffer8()

IoReadMmBuffer16()

IoReadMmBuffer32()

Назначение

Сохраняют в буфер последовательность 8-, 16-или 32-битных слов из региона памяти MMIO.

Параметры

  • [in] baseReg – виртуальный адрес первого слова в последовательности.
  • [out] dst – указатель на буфер для сохранения последовательности слов.
  • [in] cnt – число слов в последовательности.

Возвращаемые значения

Нет.

Дополнительные сведения

Функции можно использовать, если процессор имеет архитектуру x86 или x86-64.

IoWriteMmReg8()

IoWriteMmReg16()

IoWriteMmReg32()

Назначение

Записывают 8-, 16- или 32-битное слово в регион памяти MMIO.

Параметры

  • [in] reg – виртуальный адрес для записи слова.
  • [in] data – слово для записи.

Возвращаемые значения

Нет.

IoWriteMmBuffer8()

IoWriteMmBuffer16()

IoWriteMmBuffer32()

Назначение

Записывают в регион памяти MMIO последовательность 8-, 16-или 32-битных слов из буфера.

Параметры

  • [in] baseReg – виртуальный адрес для записи последовательности слов.
  • [in] src – указатель на буфер с последовательностью слов.
  • [in] cnt – число слов в последовательности.

Возвращаемые значения

Нет.

Дополнительные сведения

Функции можно использовать, если процессор имеет архитектуру x86 или x86-64.

В начало
[Topic libkos_mmio_api]

Управление обработкой прерываний (irq.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/io/irq.h из состава KasperskyOS SDK.

API позволяет управлять обработкой аппаратных прерываний. Аппаратное прерывание – это сигнал процессору от устройства о необходимости немедленно переключиться с исполнения текущей программы на обработку события, связанного с этим устройством. Например, нажатие клавиши на клавиатуре вызывает аппаратное прерывание, которое обеспечивает требуемую реакцию на это нажатие (к примеру, ввод символа).

Аппаратное прерывание возникает при обращении устройства к контроллеру прерываний. Это обращение может осуществляться через линию аппаратного прерывания между устройством и контроллером прерываний или через память MMIO. Во втором случае устройство выполняет запись в память MMIO, вызывая прерывание MSI (англ. Message Signaled Interrupt).

В настоящее время функции для управления обработкой прерываний MSI не реализованы.

Каждой линии аппаратного прерывания соответствует одно прерывание с уникальным номером.

Сведения о функциях API приведены в таблице ниже.

Использование API

Чтобы связать прерывание с его обработчиком, нужно выполнить следующие шаги:

  1. Регистрация прерывания вызовом функции KnRegisterIrq().

    Одно прерывание можно зарегистрировать несколько раз в одном или нескольких процессах.

    Дескриптор прерывания можно передать другому процессу через IPC.

  2. Привязка потока исполнения к прерыванию вызовом функции KnIoAttachIrq().

    Этот шаг выполняется потоком исполнения, в контексте которого будет выполняться обработка прерывания.

    Используя дескриптор, полученный при вызове функции KnRegisterIrq(), можно привязать к прерыванию только один поток исполнения. Чтобы привязать к прерыванию несколько потоков исполнения в одном или нескольких процессах, нужно использовать разные дескрипторы этого прерывания, полученные при отдельных вызовах функции KnRegisterIrq(). В этом случае функцию KnIoAttachIrq() нужно вызывать с одними и теми же флагами в параметре flags.

    Дескриптор, полученный при вызове функции KnIoAttachIrq(), нельзя передать другому процессу через IPC.

Чтобы запретить (маскировать) прерывание, нужно вызвать функцию KnIoDisableIrq(). Чтобы разрешить (демаскировать) прерывание, нужно вызвать функцию KnIoEnableIrq(). И хотя эти функции принимают дескриптор прерывания, через который к прерыванию привязан только один поток исполнения, их действие распространяется на все потоки исполнения, привязанные к этому прерыванию. Эти функции нужно вызывать вне потоков исполнения, привязанных к прерыванию. После регистрации прерывания и привязки к нему потока исполнения это прерывание не требуется демаскировать.

Чтобы инициировать отвязывание потока исполнения от прерывания, нужно вызвать функцию KnIoDetachIrq() вне потока исполнения, привязанного к прерыванию. Отвязывание выполняет поток исполнения, привязанный к прерыванию, вызовом функции KnThreadDetachIrq(), объявленной в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h. из состава KasperskyOS SDK.

Обработка прерывания

После выполнения привязки к прерыванию поток исполнения вызывает функцию Call(), объявленную в заголовочном файле sysroot-*-kos/include/coresrv/syscalls.h из состава KasperskyOS SDK. В результате этого вызова поток исполнения блокируется. При возникновении прерывания или вызове функции KnIoDetachIrq() ядро KasperskyOS отправляет IPC-сообщение процессу, содержащему этот поток. Это IPC-сообщение содержит запрос на обработку прерывания или запрос на отвязывание потока исполнения от прерывания. Когда процесс получает IPC-сообщение, функция Call() в потоке исполнения, привязанном к прерыванию, возвращает управление и предоставляет потоку содержимое IPC-сообщения. Поток исполнения извлекает из IPC-сообщения запрос и обрабатывает прерывание либо выполняет отвязывание от прерывания. Если выполняется обработка прерывания, то по ее завершении сведения об успехе или неуспехе обработки добавляются в ответное IPC-сообщение, которое отправляется ядру следующим вызовом функции Call() в цикле.

При обработке прерывания нужно использовать функции IoGetIrqRequest() и IoSetIrqAnswer(), которые объявлены в заголовочном файле sysroot-*-kos/include/io/io_irq.h из состава KasperskyOS SDK. Эти функции позволяют извлекать из IPC-сообщений и добавлять в IPC-сообщения данные для информационного обмена между ядром и потоком исполнения, привязанным к прерыванию.

Типовой цикл обработки прерывания включает следующие шаги:

  1. Добавление в IPC-сообщение, которое будет отправлено ядру, сведений об успехе или неуспехе обработки прерывания вызовом функции IoSetIrqAnswer().
  2. Отправка IPC-сообщения ядру и получение IPC-сообщения от ядра.

    Чтобы выполнить этот шаг, нужно вызвать функции Call(). В параметре handle требуется указать дескриптор, полученный при вызове функции KnIoAttachIrq(). Через параметр msgOut необходимо задать IPC-сообщение, которое будет отправлено ядру, а через параметр msgIn необходимо задать IPC-сообщение, которое будет получено от ядра.

  3. Извлечение запроса из IPC-сообщения, полученного от ядра, вызовом функции IoGetIrqRequest().
  4. Обработка прерывания или отвязывание от прерывания в зависимости от запроса.

    Если запрос требует выполнить отвязывание от прерывания, то нужно выйти из цикла обработки прерывания и вызвать функцию KnThreadDetachIrq().

Дерегистрация прерывания

Чтобы дерегистрировать прерывание, нужно выполнить следующие шаги:

  1. Выполнить отвязывание потока исполнения от прерывания.

    Чтобы выполнить этот шаг, нужно вызвать функцию KnThreadDetachIrq().

  2. Закрыть дескриптор, полученный при вызове функции KnIoAttachIrq().

    Чтобы выполнить этот шаг, нужно вызвать функцию KnHandleClose(). (Функция KnHandleClose() объявлена в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.)

  3. Закрыть или отозвать каждый дескриптор прерывания во всех процессах, которые владеют этими дескрипторами.

    Чтобы выполнить этот шаг, нужно использовать функцию KnHandleClose() и/или KnHandleRevoke(), которые объявлены в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.

Одно прерывание может быть зарегистрировано несколько раз, а выполнение этих шагов аннулирует только одну регистрацию. Оставшиеся регистрации продолжают действовать. Каждую регистрацию одного прерывания нужно аннулировать отдельно.

Сведения о функциях API

Функции irq.h

Функция

Сведения о функции

KnRegisterIrq()

Назначение

Регистрирует прерывание.

Параметры

  • [in] irq – номер прерывания.
  • [out] outRid – указатель на дескриптор прерывания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIoAttachIrq()

Назначение

Привязывает вызывающий поток исполнения к прерыванию.

Параметры

  • [in] rid – дескриптор прерывания.
  • [in] flags – флаги, задающие параметры прерывания. Флаги определены в заголовочных файлах sysroot-*-kos/include/io/io_irq.h и sysroot-*-kos/include/hal/irqmode.h из состава KasperskyOS SDK.
  • [out] handle – указатель на клиентский IPC-дескриптор, который используется обработчиком прерывания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • IRQ_LEVEL_LOW – прерывание возникает при низком уровне сигнала.
  • IRQ_LEVEL_HIGH – прерывание возникает при высоком уровне сигнала.
  • IRQ_EDGE_RAISE – прерывание возникает при повышении уровня сигнала.
  • IRQ_EDGE_FALL – прерывание возникает при снижении уровня сигнала.
  • IRQ_PRIO_LOW – прерывание имеет низкий приоритет.
  • IRQ_PRIO_NORMAL – прерывание имеет средний приоритет.
  • IRQ_PRIO_HIGH – прерывание имеет высокий приоритет.
  • IRQ_PRIO_RT – прерывание имеет наивысший приоритет.

KnIoDetachIrq()

Назначение

Отправляет потоку исполнения запрос, в результате выполнения которого поток должен выполнить отвязывание от прерывания.

Параметры

  • [in] rid – дескриптор прерывания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIoEnableIrq()

Назначение

Разрешает (демаскирует) прерывание.

Параметры

  • [in] rid – дескриптор прерывания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIoDisableIrq()

Назначение

Запрещает (маскирует) прерывание.

Параметры

  • [in] rid – дескриптор прерывания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_irq_api]

Управление потоками исполнения (высокоуровневый API thread.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/thread.h из состава KasperskyOS SDK.

Основные возможности API:

  • создавать, завершать, блокировать потоки исполнения;
  • возобновлять исполнение заблокированных потоков;
  • регистрировать функции, вызываемые при создании и завершении потоков исполнения.

Сведения о функциях API приведены в таблице ниже.

Библиотека libkos также предоставляет низкоуровневый API для управления потоками исполнения, который определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK. Низкоуровневый API следует использовать, если только недостаточно возможностей высокоуровневого API.

Создание потоков исполнения

Чтобы создать поток исполнения, нужно вызвать функцию KosThreadCreate() или KosThreadCreateDetached(). Эти функции создают стандартный поток исполнения, приоритет которого может принимать значения от 0 до 15. (О стандартных потоках исполнения см. "Управление потоками исполнения (низкоуровневый API thread_api.h)".)

Завершение потоков исполнения

Завершение потока исполнения представляет собой его перманентное удаление из планировщика. Поток исполнения завершается в следующих случаях:

  • Осуществлен выход из функции, выполняемой потоком исполнения.

    Должен быть осуществлен выход оператором return из корневой (не из вложенной) функции, выполняемой потоком исполнения.

  • Вызвана функция KosThreadTerminate() или KosThreadExit().

    Функция KosThreadExit() завершает поток исполнения, даже если вызвана не из корневой функции, выполняемой потоком исполнения, а из вложенной.

  • Завершился или перешел в "замороженное" состояние процесс.

    О "замороженном" состоянии процесса см. "Управление процессами (низкоуровневый API task_api.h)".

Коды завершения потоков исполнения определяются разработчиком решения на базе KasperskyOS. Эти коды нужно указывать в параметре exitCode функций KosThreadTerminate() и KosThreadExit(), а также при вызове оператора return в функции, выполняемой потоком исполнения. Чтобы получить код завершения потока исполнения, нужно вызвать функцию KosThreadWait(). В случае успеха эта функция возвращает код завершения потока исполнения, иначе возвращает -1, поэтому коды завершения потоков исполнения должны быть отличными от -1, чтобы избежать неоднозначности.

Регистрация функций, вызываемых при создании и завершении потоков исполнения

Чтобы зарегистрировать функцию, вызываемую при создании и завершении потоков процесса, нужно вызвать из этого процесса функцию KosThreadCallbackRegister().

Зарегистрированная функция вызывается в следующих случаях:

  • при создании потока исполнения вызовом функции KosThreadCreate();
  • при завершении потока исполнения, созданного вызовом функции KosThreadCreate(), в результате выхода из функции, выполняемой этим потоком;
  • при завершении потока исполнения вызовом функции KosThreadExit().

Можно зарегистрировать несколько функций, и каждая из них будет вызвана при создании и завершении потока исполнения. При создании потока исполнения зарегистрированная функция вызывается с аргументом KosThreadCallbackReasonCreate в параметре reason. При завершении потока исполнения зарегистрированная функция вызывается с аргументом KosThreadCallbackReasonDestroy в параметре reason.

Гарантирование невозможности вызвать функцию несколько раз

Только при первом вызове функции KosThreadOnce() вызывается заданная через параметр initRoutine callback-функция. При повторных вызовах функции KosThreadOnce() (даже из других потоков исполнения) этого не происходит, и функция KosThreadOnce() просто возвращает управление. Например, это обеспечивает однократную инициализацию драйвера, в том случае, когда несколько программных компонентов используют этот драйвер и запускают его инициализацию независимо друг от друга.

Особенности потоков исполнения, привязанных к прерываниям

После привязки к прерыванию поток исполнения становится потоком исполнения реального времени с классом планирования FIFO и приоритетом выше 31. (О привязке потока исполнения к прерыванию см. "Управление обработкой прерываний (irq.h)". О классе планирования потоков реального времени FIFO см. "Управление потоками исполнения (низкоуровневый API thread_api.h)".)

Для потоков исполнения, привязанных к прерываниям, нельзя применять многие функции API, в том числе KosThreadCreate(), KosThreadSuspend(), KosThreadResume(), KosThreadTerminate(), KosThreadWait(), KosThreadSleep(), KosThreadYield().

Задание и получение базового адреса TLS потоков исполнения

Локальная память потока исполнения (англ. Thread Local Storage, TLS) – это память процесса, где поток исполнения может хранить данные изолированно от других потоков исполнения. Задать и получить базовый адрес TLS позволяют функции KosThreadTlsSet() и KosThreadTlsGet() соответственно. Эти функции предназначены для использования библиотекой libc.

Получение базового адреса и размера стека потоков исполнения

Получить базовый адрес и размер стека потока исполнения позволяет функция KosThreadGetStack(). Эта функция предназначена для использования библиотекой libc.

Освобождение ресурсов завершившихся потоков исполнения

Ресурсами потока исполнения являются его стек, контекст и TCB (о TCB см. "Управление потоками исполнения (низкоуровневый API thread_api.h)"). Чтобы ресурсы потока исполнения были освобождены после его завершения, нужно вызвать функцию KosThreadWait() для ожидания завершения этого потока исполнения. (Исключением являются начальный поток процесса и поток исполнения, созданный функцией KosThreadCreateDetached().) Также ресурсы потоков исполнения освобождаются при завершении процесса, в который они входят.

Сведения о функциях API

Функции thread.h

Функция

Сведения о функции

KosThreadCallbackRegister()

Назначение

Регистрирует функцию, вызываемую при создании и завершении потоков исполнения вызывающего процесса.

Параметры

  • [in] callback – указатель на функцию.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadCallbackUnregister()

Назначение

Дерегистрирует функцию, вызываемую при создании и завершении потоков исполнения вызывающего процесса.

Параметры

  • [in] callback – указатель на функцию.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadCreate()

Назначение

Создает поток исполнения.

Параметры

  • [out] handle – указатель на дескриптор потока исполнения.
  • [in] priority – приоритет потока исполнения.
  • [in,optional] stackSize – размер стека потока исполнения в байтах или 0, чтобы был использован размер по умолчанию, заданный при создании процесса.
  • [in] routine – указатель на функцию, выполняемую потоком исполнения. Тип параметра определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.
  • [in,optional] context – указатель на параметры, передаваемые функции, заданной через параметр routine, или RTL_NULL, если этой функции не требуется передавать параметры.
  • [in] suspended – значение, задающее, что поток исполнения будет создан заблокированным (1) или незаблокированным (0).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadCreateDetached()

Назначение

Создает незаблокированный поток исполнения и закрывает его дескриптор.

Параметры

  • [in] priority – приоритет потока исполнения.
  • [in,optional] stackSize – размер стека потока исполнения в байтах или 0, чтобы был использован размер по умолчанию, заданный при создании процесса.
  • [in] routine – указатель на функцию, выполняемую потоком исполнения. Тип параметра определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.
  • [in,optional] context – указатель на параметры, передаваемые функции, заданной через параметр routine, или RTL_NULL, если этой функции не требуется передавать параметры.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadCurrentId()

Назначение

Позволяет получить идентификатор (TID) вызывающего потока исполнения.

Параметры

Нет.

Возвращаемые значения

Идентификатор потока исполнения. Тип идентификатора определен в заголовочном файле sysroot-*-kos/include/thread/tidtype.h из состава KasperskyOS SDK.

KosThreadSuspend()

Назначение

Блокирует вызывающий поток исполнения.

Параметры

  • [in] handle – дескриптор потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadResume()

Назначение

Возобновляет исполнение заблокированного потока.

Параметры

  • [in] handle – дескриптор потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadExit()

Назначение

Завершает вызывающий поток исполнения.

Параметры

  • [in] exitCode – код завершения потока исполнения.

Возвращаемые значения

Нет.

KosThreadWait()

Назначение

Блокирует вызывающий поток исполнения до завершения заданного потока исполнения.

Параметры

  • [in] handle – дескриптор потока исполнения.
  • [in] timeout – время ожидания завершения потока исполнения в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.

Возвращаемые значения

В случае успеха возвращает код завершения потока исполнения, иначе возвращает -1.

KosThreadSleep()

Назначение

Блокирует вызывающий поток исполнения на заданное время.

Параметры

  • [in] mdelay – время блокировки потока исполнения в миллисекундах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadYield()

Назначение

Отдает квант времени вызывающего потока исполнения следующему в очереди.

Параметры

Нет.

Возвращаемые значения

Нет.

Дополнительные сведения

Вызов функции KosThreadYield() идентичен вызову функции KosThreadSleep() с нулевым значением параметра mdelay.

KosThreadTerminate()

Назначение

Завершает поток исполнения.

Параметры

  • [in] handle – дескриптор потока исполнения.
  • [in] exitCode – код завершения потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadTlsGet()

Назначение

Позволяет получить базовый адрес локальной памяти потока исполнения (TLS) для вызывающего потока исполнения.

Параметры

Нет.

Возвращаемые значения

Указатель на TLS или RTL_NULL, если у потока исполнения нет TLS.

KosThreadTlsSet()

Назначение

Задает базовый адрес локальной памяти потока исполнения (TLS) для вызывающего потока исполнения.

Параметры

  • [in] tls – указатель на TLS.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosThreadGetStack()

Назначение

Позволяет получить базовый адрес и размер стека потока исполнения.

Параметры

  • [in] handle – дескриптор потока исполнения.
  • [out] size – указатель на размер стека в байтах.

Возвращаемые значения

Указатель на стек потока исполнения.

KosThreadOnce()

Назначение

Гарантирует, что заданная функция будет вызвана только один раз.

Параметры

  • [in] onceControl – указатель на переменную, которая отражает, была ли уже вызвана заданная функция. Эту переменную нужно инициализировать значением KOS_THREAD_ONCE_INIT.
  • [in] initRoutine – указатель на функцию, которая должна быть вызвана только один раз.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_thread_high_api]

Управление потоками исполнения (низкоуровневый API thread_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.

Основные возможности API:

  • создавать, завершать, блокировать потоки исполнения;
  • возобновлять исполнение заблокированных потоков;
  • изменять приоритеты и классы планирования потоков исполнения;
  • обрабатывать исключения;
  • отвязывать потоки исполнения от прерываний;
  • выполнять привязку потоков исполнения к процессорам (вычислительным ядрам).

Функции API, которые принимают на вход или возвращают идентификатор потока исполнения (TID), являются устаревшими и в будущем будут удалены. Эти функции не описаны в этом разделе.

Сведения о функциях API приведены в таблице ниже.

Библиотека libkos также предоставляет высокоуровневый API для управления потоками исполнения, который определен в заголовочном файле sysroot-*-kos/include/kos/thread.h из состава KasperskyOS SDK. Рекомендуется использовать именно этот API. Низкоуровневый API следует использовать, если недостаточно возможностей высокоуровневого API.

Создание потоков исполнения. Классы планирования потоков исполнения

Чтобы создать поток исполнения, нужно вызвать функцию KnThreadCreateByHandle(). Через параметр flags этой функции для создаваемого потока исполнения можно задать следующие классы планирования:

  • класс планирования стандартных потоков;
  • класс планирования потоков реального времени FIFO (англ. First In, First Out);
  • класс планирования потоков реального времени RR (англ. Round-Robin).

Приоритет стандартного потока исполнения может принимать значения от 0 до 15. Чем выше приоритет стандартного потока исполнения, тем больше размер квантов времени, выделяемых этому потоку, и тем чаще эти кванты выделяются. Один стандартный поток исполнения с высоким приоритетом может занимать несколько мест подряд в очереди потоков исполнения. Стандартные потоки исполнения не могут вытеснять другие стандартные потоки исполнения, а также потоки исполнения реального времени независимо от соотношения приоритетов. Если в очереди появляется поток исполнения реального времени, то текущий стандартный поток исполнения немедленно передает ему управление. Если в очереди нет потоков исполнения реального времени, то текущий стандартный поток исполнения передает управление следующему, если завершился, стал заблокированным, исчерпал свой квант времени или отдал его следующему.

Приоритет потока исполнения реального времени может принимать значения от 0 от 31. Более приоритетные потоки исполнения реального времени вытесняют менее приоритетные. Также потоки исполнения реального времени вытесняют стандартные потоки исполнения независимо от соотношения приоритетов. Передача управления от текущего потока исполнения реального времени следующему в очереди осуществляется в следующих случаях:

  • Текущий поток исполнения реального времени с классом планирования FIFO завершился или стал заблокированным, либо в очереди появился поток исполнения реального времени с более высоким приоритетом.

    Пока поток исполнения реального времени с классом планирования FIFO не будет завершен, заблокирован или вытеснен потоком исполнения реального времени с более высоким приоритетом, он может сколь угодно долго не передавать управление следующему.

  • Текущий поток исполнения реального времени с классом планирования RR завершился, стал заблокированным или исчерпал свой квант времени, либо в очереди появился поток исполнения реального времени с более высоким приоритетом.

    Поток исполнения реального времени с классом планирования RR, который не был завершен, заблокирован или вытеснен потоком исполнения реального времени с более высоким приоритетом, передает управление следующему по истечении своего кванта времени, если следующий является потоком исполнения реального времени с таким же приоритетом. В противном случае осуществляется передача управления снова себе.

  • Текущий поток исполнения реального времени отдал свой квант времени следующему в очереди потоку исполнения реального времени с таким же приоритетом.

    Поток исполнения реального времени может отдать свой квант времени следующему, если следующий является потоком исполнения реального времени с таким же приоритетом. В противном случае осуществляется передача управления снова себе.

Исполнение потоков реального времени с более низким приоритетом начинается только после того, как каждый из потоков реального времени с более высоким приоритетом завершился или стал заблокированным. Потоки исполнения реального времени с одним приоритетом образуют очередь по принципу FIFO.

Класс планирования потока исполнения можно изменить вызовом функции KnThreadSetSchedPolicyByHandle(). Также эта функция позволяет изменить размер кванта времени, выделенного потоку исполнения реального времени с классом планирования RR. Это значение является единственным параметром класса планирования потоков реального времени RR, который по умолчанию имеет значение 10 мс, но может принимать значения от 2 мс до 100 мс. Класс планирования стандартных потоков и класс планирования потоков реального времени FIFO не имеют параметров.

Приоритет потока исполнения можно изменить вызовом функции KnThreadSetSchedPolicyByHandle() или KnThreadSetPriorityByHandle().

После привязки к прерыванию поток исполнения становится потоком исполнения реального времени с классом планирования FIFO и приоритетом выше 31 независимо от того, какой класс планирования и приоритет были у этого потока исполнения до привязки к прерыванию. (О привязке потока исполнения к прерыванию см. "Управление обработкой прерываний (irq.h)".)

Для потоков исполнения, привязанных к прерываниям, нельзя применять многие функции API, в том числе KnThreadCreateByHandle(), KnThreadSetPriorityByHandle(), KnThreadSuspendCurrent(), KnThreadResumeByHandle(), KnThreadTerminateByHandle(), KnThreadWaitByHandle(), KnSleep(), KnThreadSetSchedPolicyByHandle().

Создание дескрипторов потоков исполнения

Дескриптор потока исполнения создается при создании потока исполнения вызовом функции KnThreadCreateByHandle(). Также поток исполнения (в том числе начальный) может создать свой дескриптор вызовом функции KnThreadOpenCurrent().

Дескриптор потока исполнения нельзя передать другому процессу через IPC.

Обработка исключений

Чтобы зарегистрировать функцию обработки исключений для потока исполнения, нужно вызвать функцию KnThreadSetExceptionHandler(). Эта функция дерегистрирует предыдущую функцию обработки исключений и возвращает ее идентификатор. Сохранив этот идентификатор, в дальнейшем можно снова зарегистрировать предыдущую функцию обработки исключений.

Чтобы получить сведения о последнем исключении потока исполнения, в обработчике исключений нужно вызвать функцию KnThreadGetLastException().

Отвязывание потоков исполнения от прерываний

Чтобы отвязать поток исполнения от прерывания, нужно вызвать функцию KnThreadDetachIrq(). (Подробнее об использовании функции KnThreadDetachIrq() см. "Управление обработкой прерываний (irq.h)".)

После отвязывания от прерывания поток исполнения получает класс планирования и приоритет, которые были у этого потока исполнения до привязки к прерыванию.

Привязка потоков исполнения к процессорам (вычислительным ядрам)

Чтобы ограничить набор процессоров (вычислительных ядер), которые могут быть использованы для исполнения потока, нужно задать для этого потока маску сходства. Маска сходства (англ. Affinity Mask) – битовая маска, указывающая на каких процессорах (вычислительных ядрах) должен исполняться поток.

Чтобы создавать, корректировать и выполнять другие операции с масками сходства, нужно использовать API, определенный в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.

Чтобы задать маску сходства потока исполнения, нужно вызвать функцию KnThreadSetAffinityByHandle().

Завершение потоков исполнения

Завершение потока исполнения представляет собой его перманентное удаление из планировщика. Поток исполнения завершается в следующих случаях:

  • Осуществлен выход из функции, выполняемой потоком исполнения.

    Должен быть осуществлен выход оператором return из корневой (не из вложенной) функции, выполняемой потоком исполнения.

  • Вызвана функция KnThreadTerminateByHandle() или KnThreadExit().

    Функция KnThreadExit() завершает поток исполнения, даже если вызвана не из корневой функции, выполняемой потоком исполнения, а из вложенной.

  • Завершился или перешел в "замороженное" состояние процесс.

    О "замороженном" состоянии процесса см. "Управление процессами (низкоуровневый API task_api.h)".

Коды завершения потоков исполнения определяются разработчиком решения на базе KasperskyOS . Эти коды нужно указывать в параметре code функций KnThreadTerminateByHandle() и KnThreadExit(), а также при вызове оператора return в функции, выполняемой потоком исполнения. Чтобы получить код завершения потока исполнения, нужно вызвать функцию KnThreadWaitByHandle().

Получение адреса TCB и задание базового адреса TLS потоков исполнения

Блок управления потоком исполнения (англ. Thread Control Block, TCB) – структура, содержащая сведения о потоке исполнения, которые используются ядром для управления этим потоком исполнения. Тип структуры определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK. TCB содержит базовый адрес локальной памяти потока исполнения (TLS). Получить адрес TCB позволяет функция KnThreadGetTcb(). Задать базовый адрес TLS позволяет функция KnThreadSetTls(). Эти функции предназначены для использования библиотекой libc.

Получение сведений о потоке исполнения

Получить базовый адрес и размер стека потока исполнения, а также идентификатор потока исполнения (TID) позволяет функция KnThreadGetInfoByHandle(). Эта функция предназначена для использования библиотекой libc.

Освобождение ресурсов завершившихся потоков исполнения

Ресурсами потока исполнения являются его стек, контекст и TCB. Чтобы ресурсы потока исполнения были освобождены после его завершения, нужно до или после завершения этого потока исполнения закрыть его дескриптор вызовом функции KnHandleClose(), которая объявлена в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK. (Исключением является начальный поток процесса, ресурсы которого освобождаются без вызова функции KnHandleClose(), если начальный поток не создавал свой дескриптор вызовом функции KnThreadOpenCurrent().) Также ресурсы потоков исполнения освобождаются при завершении процесса, в который они входят.

Сведения о функциях API

Функции thread_api.h

Функция

Сведения о функции

KnThreadCreateByHandle()

Назначение

Создает поток исполнения.

Параметры

  • [out,optional] thread – указатель на дескриптор потока исполнения. Если указать RTL_NULL, дескриптор будет закрыт автоматически после создания потока исполнения.
  • [in] priority – приоритет потока исполнения.
  • [in,optional] stackSize – размер стека потока исполнения в байтах или 0, чтобы был использован размер по умолчанию, заданный при создании процесса.
  • [in] startRoutine – параметр, который должен иметь значение RTL_NULL.
  • [in] routine – указатель на функцию, выполняемую потоком исполнения.
  • [in,optional] context – указатель на параметры, передаваемые функции, заданной через параметр routine, или RTL_NULL, если этой функции не требуется передавать параметры.
  • [in] flags – флаги, задающие параметры создания потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • ThreadFlagCreateSuspended – создание потока исполнения в заблокированном состоянии.
  • ThreadFlagCreateSchedOther – создание стандартного потока исполнения.
  • ThreadFlagCreateSchedFifo – создание потока исполнения реального времени с классом планирования FIFO.
  • ThreadFlagCreateSchedRR – создание потока исполнения реального времени с классом планирования RR.

По умолчанию создается стандартный поток исполнения.

Дескрипторы потоков исполнения нельзя передавать между процессами через IPC.

KnThreadOpenCurrent()

Назначение

Создает дескриптор вызывающего потока исполнения.

Параметры

  • [out] thread – указатель на дескриптор потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadGetPriorityByHandle()

Назначение

Позволяет получить приоритет потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [out] priority – указатель на приоритет потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadSetPriorityByHandle()

Назначение

Задает приоритет потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] priority – приоритет потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadSuspendCurrent()

Назначение

Блокирует вызывающий поток исполнения.

Параметры

Нет.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadResumeByHandle()

Назначение

Возобновляет исполнение заблокированного потока.

Параметры

  • [in] thread – дескриптор потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadTerminateByHandle()

Назначение

Завершает поток исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] code – код завершения потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadExit()

Назначение

Завершает вызывающий поток исполнения.

Параметры

  • [in] code – код завершения потока исполнения.

Возвращаемые значения

Код ошибки.

KnThreadGetInfoByHandle()

Назначение

Позволяет получить сведения о потоке исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [out] info – указатель на структуру, содержащую базовый адрес стека потока исполнения и его размер в байтах, а также идентификатор потока исполнения (TID).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadWaitByHandle()

Назначение

Блокирует вызывающий поток исполнения до завершения заданного потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] msDelay – время ожидания завершения потока исполнения в миллисекундах или INFINITE_TIMEOUT, что задать неограниченное время ожидания.
  • [out] exitCode – указатель на код завершения потока исполнения.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnSleep()

Назначение

Блокирует вызывающий поток исполнения на заданное время.

Параметры

  • [in] mdelay – время блокировки потока исполнения в миллисекундах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadGetTcb()

Назначение

Позволяет получить адрес блока управления потоком исполнения (TCB) для вызывающего потока исполнения.

Параметры

Нет.

Возвращаемые значения

Указатель на TCB. Тип данных для хранения TCB определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

KnThreadSetTls()

Назначение

Задает базовый адрес локальной памяти потока исполнения (TLS) для вызывающего потока исполнения.

Параметры

  • [in] tls – указатель на TLS.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadDetachIrq()

Назначение

Отвязывает вызывающий поток исполнения от прерывания, обрабатываемого в его контексте.

Параметры

Нет.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadSetExceptionHandler()

Назначение

Регистрирует функцию обработки исключений для вызывающего потока исполнения.

Параметры

  • [in,optional] handler – идентификатор функции обработки исключений или RTL_NULL, чтобы дерегистрировать предыдущую зарегистрированную функцию обработки исключений без регистрации новой. Тип параметра определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

Возвращаемые значения

Идентификатор предыдущей зарегистрированной функции обработки исключений или RTL_NULL при ее отсутствии. Тип возвращаемого значения определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

KnThreadGetLastException()

Назначение

Позволяет получить сведения о последнем исключении вызывающего потока исполнения.

Параметры

  • [out] exception – указатель на структуру, содержащую сведения об исключении. Тип структуры определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KnThreadGetAffinityByHandle()

Назначение

Позволяет получить маску сходства потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [out] mask – указатель на структуру, содержащую маску сходства потока исполнения. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadSetAffinityByHandle()

Назначение

Задает маску сходства потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] mask – указатель на структуру, содержащую маску сходства потока исполнения. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadGetSchedPolicyByHandle()

Назначение

Позволяет получить сведения о классе планирования потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [out] policy – указатель на класс планирования потока исполнения. Тип данных для хранения класса планирования потока исполнения определен в заголовочном файле sysroot-*-kos/include/thread/tidtype.h из состава KasperskyOS SDK.
  • [out,optional] param – указатель на параметры класса планирования потока исполнения или RTL_NULL.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре param можно указать RTL_NULL, если не требуется получать параметры класса планирования потока исполнения.

В параметре param необходимо указать RTL_NULL, если класс планирования потока исполнения не имеет параметров.

KnThreadSetSchedPolicyByHandle()

Назначение

Задает класс планирования и приоритет потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] policy – класс планирования потока исполнения. Тип параметра определен в заголовочном файле sysroot-*-kos/include/thread/tidtype.h из состава KasperskyOS SDK.
  • [in] prio – приоритет потока исполнения.
  • [in,optional] param – указатель на параметры класса планирования потока исполнения или RTL_NULL.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре param можно указать RTL_NULL, если требуется задать параметры класса планирования потока исполнения, применяемые по умолчанию.

В параметре param необходимо указать RTL_NULL, если класс планирования потока исполнения не имеет параметров.

В начало
[Topic libkos_thread_low_api]

Управление процессами (высокоуровневый API task.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/task.h из состава KasperskyOS SDK.

API позволяет создавать, запускать и завершать процессы, а также статически создавать IPC-каналы и передавать дескрипторы.

Сведения о функциях API приведены в таблице ниже.

Библиотека libkos также предоставляет низкоуровневый API для управления процессами, который определен в заголовочном файле sysroot-*-kos/include/coresrv/task/task_api.h из состава KasperskyOS SDK. Низкоуровневый API следует использовать, если только недостаточно возможностей высокоуровневого API.

Создание процессов

Чтобы создать процесс, нужно вызвать одну из следующих функций:

  • KosTaskInitEx();
  • KosTaskInit();
  • KosTaskInitFromSegEx();
  • KosTaskInitFromSeg();
  • KosTaskLaunch().

Через входной параметр params эти функции принимают параметры создаваемого процесса в виде структуры, содержащей следующие поля:

  • eiid – указатель на имя класса процесса.
  • endpointsCount – число предоставляемых служб.

    Поле может иметь нулевое значение, если процесс не предоставляет службы.

  • endpoints – указатель на массив структур, содержащих характеристики предоставляемых служб (имена и идентификаторы служб, имена интерфейсов).

    Тип структуры определен в заголовочном файле sysroot-*-kos/include/services/handle/if_connection.h из состава KasperskyOS SDK.

    Поле может иметь значение RTL_NULL, если процесс не предоставляет службы.

  • args – указатель на массив параметров запуска программы.

    Последним элементом массива должно быть значение RTL_NULL.

  • envs – указатель на массив переменных окружения программы.

    Последним элементом массива должно быть значение RTL_NULL.

  • flags – флаги:
  • componentTree – указатель на структуру, содержащую сведения из формальной спецификации компонента решения.

    Тип структуры определен в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK. Эта структура является элементом автоматически генерируемого транспортного кода.

    Если поле имеет значение, отличное от RTL_NULL, то значения в полях eiid, endpointsCount и endpoints будут проигнорированы, а имя класса процесса и параметры предоставляемых служб (включая параметры служб вложенных компонентов) будут взяты из формальной спецификации компонента решения.

Функции KosTaskInitEx(), KosTaskInit(), KosTaskInitFromSegEx() и KosTaskInitFromSeg() через выходной параметр outTask передают указатель на адрес объекта, описывающего дочерний процесс. Этот объект представляет собой структуру, которая создается в памяти как родительского, так и дочернего процесса. Разработчику решения на базе KasperskyOS не требуется выполнять операции с полями этой структуры, но указатель на нее нужно использовать в качестве идентификатора процесса при вызове функций API. Дочерний процесс может получить адрес описывающего его объекта вызовом функции KosTaskGetSelf().

Если для доступа к службам, предоставляемым серверным процессом, используются статически созданные IPC-каналы, то объект, описывающий этот серверный процесс, должен быть связан со структурами, содержащими сведения о службах из формальной спецификации компонента решения. Это необходимо, чтобы при создании статического IPC-канала клиентские процессы получили сведения о службах, предоставляемых серверным процессом. Чтобы связать объект, описывающий дочерний серверный процесс, со структурами, содержащими сведения о службах из формальной спецификации компонента решения, нужно передать эти сведения через поле componentTree параметра params при вызове функций KosTaskInit*() или функции KosTaskLaunch(). Серверный процесс, который уже запущен, может связать описывающий его объект со структурами, содержащими сведения о службах из формальной спецификации компонента решения, вызовом функции KosTaskSetComponentTree(). Это требуется, если у запущенного серверного процесса нет родительского процесса.

При вызове функции KosTaskInitEx(), KosTaskInit() или KosTaskLaunch() ELF-образ из заданного исполняемого файла в ROMFS загружается в память создаваемого процесса. Если ELF-образ содержит таблицу символов .symtab и таблицу строк .strtab, то они загружаются в память процесса. Используя эти таблицы, ядро получает имена функций для формирования данных обратной трассировки стека (сведений о стеке вызовов).

Чтобы получить сведения об ELF-образе, загруженном в память процесса, нужно вызвать функцию KosTaskGetElfSegs().

При вызове функции KosTaskInit() или KosTaskLaunch() в качестве имени процесса и имени исполняемого файла используется одно из следующих значений:

  • Значение поля eiid, если значение поля componentTree равно RTL_NULL.
  • Имя класса процессов из формальной спецификации компонента решения, если значение поля componentTree отлично от RTL_NULL.

Таким же образом эти значения применяются в качестве имени процесса и/или имени исполняемого файла, если вызвать функцию KosTaskInitEx() или KosTaskInitFromSegEx() со значением RTL_NULL в параметре name и/или параметре path. И аналогично эти значения применяются в качестве имени процесса, если вызвать функцию KosTaskInitFromSeg() со значением RTL_NULL в параметре name.

Для использования функций KosTaskInitFromSegEx() и KosTaskInitFromSeg() необходимо, чтобы заранее были созданы буферы MDL, которые содержат сегменты ELF-образа. Сегменты ELF-образа для загрузки в память создаваемого процесса нужно задать через параметр segs.

Через параметры entry и relocBase функции KosTaskInitFromSegEx() необходимо задать точку входа в программу и смещение загрузки ELF-образа соответственно. Точка входа в программу представляет собой сумму адреса, указанного в поле e_entry заголовка ELF-образа, и смещения загрузки ELF-образа. Генерацию случайного смещения загрузки ELF-образа и расчет адреса точки входа в программу с учетом этого смещения выполняет функция KnElfCreateVmSegEx(), объявленная в заголовочном файле sysroot-*-kos/include/coresrv/elf/elf_api.h из состава KasperskyOS SDK. (Смещение загрузки ELF-образа должно быть случайным значением с целью поддержки ASLR. Об ASLR см. "Управление процессами (низкоуровневый API task_api.h)".)

С помощью функции KosTaskInitFromSegEx() в память создаваемого процесса можно загрузить таблицу символов .symtab и таблицу строк .strtab, а также заголовок ELF-образа. Загрузку заголовка ELF-образа нужно выполнить, если требуется, чтобы данные из него были доступны в создаваемом процессе.

Данные, передаваемые функции KosTaskInitFromSegEx() через параметры segs, entry, relocBase и параметры, связанные с загрузкой таблицы символов .symtab и таблицы строк .strtab, подготавливаются функцией KnElfCreateVmSegEx(), объявленной в заголовочном файле sysroot-*-kos/include/coresrv/elf/elf_api.h из состава KasperskyOS SDK.

Функция KosTaskInitFromSeg() является упрощенной версией функции KosTaskInitFromSegEx() и не позволяет загружать в память процесса таблицу символов .symtab, таблицу строк .strtab и заголовок ELF-образа, а также не позволяет задавать смещение загрузки ELF-образа (устанавливает нулевое смещение).

Функция KosTaskLaunch() создает и сразу запускает процесс без возможности статического создания IPC-каналов.

Статическое создание IPC-каналов

Перед запуском процессов можно создать IPC-каналы между ними. Между одним клиентским и одним серверным процессом можно создать несколько IPC-каналов с разными именами. Между одним серверным и несколькими клиентскими процессами можно создать IPC-каналы с одним именем.

Чтобы создать IPC-канал с именем, соответствующим имени класса серверного процесса, нужно вызвать функцию KosTaskConnect().

Чтобы создать IPC-канал с заданным именем, нужно вызывать функцию KosTaskConnectToService().

Чтобы использовать созданный IPC-канал, на стороне клиентского процесса нужно получить клиентский IPC-дескриптор вызовом функции ServiceLocatorConnect(), а на стороне серверного процесса нужно получить серверный IPC-дескриптор вызовом функции ServiceLocatorRegister(). Через параметр channelName эти функции принимают имя IPC-канала. (Функции ServiceLocatorConnect() и ServiceLocatorRegister() объявлены в заголовочном файле sysroot-*-kos/include/coresrv/sl/sl_api.h из состава KasperskyOS SDK.)

Передача дескрипторов

Родительский процесс может передать один или несколько дескрипторов дочернему процессу, который еще не запущен. (Общие сведения о передаче дескрипторов приведены в разделе "Передача дескрипторов".)

Чтобы передать дескриптор дочернему процессу, нужно вызвать функцию KosTaskTransferResource(), указав среди прочего дескриптор объекта контекста передачи ресурса, а также маску прав и условное имя потомка передаваемого дескриптора.

Чтобы найти потомка дескриптора, переданного родительским процессом, нужно вызвать функцию KosTaskLookupResource(), указав условное имя потомка дескриптора, которое было задано родительским процессом при вызове функции KosTaskTransferResource().

Запуск процессов

Чтобы создать и сразу запустить процесс без статического создания IPC-каналов, нужно вызвать функцию KosTaskLaunch().

Чтобы запустить уже созданный процесс, перед запуском которого могут быть созданы требуемые этому процессу IPC-каналы, нужно вызвать функцию KosTaskRunEx() или KosTaskRun().

Через параметр fsBackend функции KosTaskRunEx() нужно задать, как осуществляется поддержка файловой системы ROMFS для запускаемого процесса: ядром или системной программой fsusr. Использование программы fsusr обеспечивает размещение образа ROMFS в пользовательском пространстве. В пользовательском пространстве можно разместить образ ROMFS существенно большего размера, чем в пространстве ядра.

Чтобы можно было использовать файловую систему ROMFS, размещенную в пользовательском пространстве, нужно включить программу fsusr в решение на базе KasperskyOS и создать IPC-канал с именем kl.core.FSUsr от процесса, которому требуется использовать эту файловую систему, к процессу с именем kl.core.FSUsr. (Клиентская часть программы fsusr входит в библиотеку libkos.) Чтобы проверить, поставляется ли программа fsusr в составе KasperskyOS SDK, нужно убедиться в наличии исполняемого файла sysroot-*-kos/bin/fsusr.

Чтобы задать, как осуществляется поддержка файловой системы в уже запущенном процессе, нужно вызывать функцию KosTaskSetSelfFSBackend(). Эта функция может быть использована следующим образом. Родительский процесс задает, что для него файловую систему ROMFS поддерживает программа fsusr, и вызовом функции KnFsChange() загружает требуемый образ ROMFS. (Функция KnFsChange() объявлена в заголовочном файле sysroot-*-kos/include/coresrv/fs/fs_api.h из состава KasperskyOS SDK.) Затем родительский процесс выполняет запуск дочернего процесса вызовом функции KosTaskRunEx(), указав, что для дочернего процесса файловую систему ROMFS поддерживает программа fsusr. В результате дочерний процесс по умолчанию будет использовать образ ROMFS, размещенный в пользовательском пространстве родительским процессом.

Если родительскому процессу не требуется завершать дочерний процесс или ожидать его завершения, то после запуска дочернего процесса описывающий его объект нужно удалить, обнулив число ссылок на него с использованием функции KosTaskPut(). Функция KosTaskLaunch() вызывает функцию KosTaskPut() после запуска дочернего процесса.

Завершение процессов

API позволяет завершать и ожидать завершения дочерних процессов.

Чтобы завершить дочерний процесс, нужно вызвать функцию KosTaskStop() или KosTaskStopAndWait().

Чтобы ожидать, пока дочерний процесс завершится по собственной инициативе, нужно вызвать функцию KosTaskWait().

Чтобы объект ядра, который описывает дочерний процесс, был удален после завершения этого процесса, нужно до или после завершения дочернего процесса закрыть его дескриптор в родительском процессе. Дескриптор дочернего процесса закрывается при удалении в памяти родительского процесса объекта, описывающего дочерний процесс. Чтобы удалить объект, описывающий дочерний процесс, нужно обнулить число ссылок на этот объект, используя функцию KosTaskPut(). Функция KosTaskLaunch() вызывает функцию KosTaskPut() после запуска дочернего процесса.

Подробнее о завершении процессов см. "Управление процессами (низкоуровневый API task_api.h)".

Сведения о функциях API

Функции task.h

Функция

Сведения о функции

KosTaskInitEx()

Назначение

Создает процесс.

Параметры

  • [in] params – указатель на структуру, содержащую параметры процесса.
  • [in] name – указатель на имя процесса.
  • [in] path – указатель на имя исполняемого файла в ROMFS.
  • [out] outTask – указатель на адрес объекта, описывающего процесс.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskInit()

Назначение

Создает процесс.

Параметры

  • [in] params – указатель на структуру, содержащую параметры процесса.
  • [out] outTask – указатель на адрес объекта, описывающего процесс.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskInitFromSegEx()

Назначение

Создает процесс.

Параметры

  • [in] params – указатель на структуру, содержащую параметры процесса.
  • [in] name – указатель на имя процесса.
  • [in] path – указатель на имя исполняемого файла в ROMFS.
  • [in] count – число загружаемых сегментов ELF-образа.
  • [in] relocBase – смещение загрузки ELF-образа в байтах.
  • [in] entry – адрес точки входа в программу.
  • [in,out] segs – указатель на массив структур, описывающих сегменты ELF-образа. Тип структуры определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_types.h из состава KasperskyOS SDK. Если задать поле loadAddr этой структуры равным 0, то адрес загрузки сегмента ELF-образа будет выбран автоматически и записан в поле loadAddr.
  • [in] symTabIndex – индекс сегмента ELF-образа, содержащего таблицу символов .symtab. Нумерация начинается с нуля.
  • [in] symTabSize – размер таблицы символов .symtab в байтах.
  • [in] strTabIndex – индекс сегмента ELF-образа, содержащего таблицу строк .strtab. Нумерация начинается с нуля.
  • [in] strTabSize – размер таблицы строк .strtab в байтах.
  • [in] elfHdrData – указатель на буфер, содержащий заголовок ELF-образа.
  • [in] elfHdrSize – размер заголовка ELF-образа в байтах.
  • [out] outTask – указатель на адрес объекта, описывающего процесс.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskInitFromSeg()

Назначение

Создает процесс.

Параметры

  • [in] params – указатель на структуру, содержащую параметры процесса.
  • [in] name – указатель на имя процесса.
  • [in] count – число загружаемых сегментов ELF-образа.
  • [in] entry – адрес точки входа в программу.
  • [in,out] segs – указатель на массив структур, описывающих сегменты ELF-образа. Тип структуры определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_types.h из состава KasperskyOS SDK. Если задать поле loadAddr этой структуры равным 0, то адрес загрузки сегмента ELF-образа будет выбран автоматически и записан в поле loadAddr.
  • [out] outTask – указатель на адрес объекта, описывающего процесс.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskGetElfSegs()

Назначение

Позволяет получить сведения об ELF-образе, загруженном в память процесса.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [out] segsBuf – указатель на массив для сохранения структур, описывающих сегменты ELF-образа. Тип структуры определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_types.h из состава KasperskyOS SDK.
  • [in] segsBufSize – размер буфера для сохранения массива структур, описывающих сегменты ELF-образа, в байтах.
  • [out] segsCount – указатель на число загруженных сегментов ELF-образа.
  • [out] symTabIndex – указатель на индекс сегмента ELF-образа, содержащего таблицу символов .symtab. Нумерация начинается с нуля.
  • [out] symTabSize – указатель на размер таблицы символов .symtab в байтах.
  • [out] strTabIndex – указатель на индекс сегмента ELF-образа, содержащего таблицу строк .strtab. Нумерация начинается с нуля.
  • [out] strTabSize – указатель на размер таблицы строк .strtab в байтах.
  • [out] hdrBuf – указатель на буфер для сохранения заголовка ELF-образа.
  • [in] hdrBufSize – размер буфера для сохранения заголовка ELF-образа в байтах.
  • [out] hdrSize – размер заголовка ELF-образа в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskConnect()

Назначение

Создает IPC-канал.

Параметры

  • [in] cl – указатель на объект, описывающий клиентский процесс.
  • [in] sr – указатель на объект, описывающий серверный процесс.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskConnectToService()

Назначение

Создает IPC-канал с заданным именем.

Параметры

  • [in] cl – указатель на объект, описывающий клиентский процесс.
  • [in] sr – указатель на объект, описывающий серверный процесс.
  • [in] name – указатель на имя IPC-канала.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskSetArgs()

Назначение

Задает параметры запуска программы.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [in] args – указатель на массив параметров запуска программы. Последним элементом массива должно быть значение RTL_NULL.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Функция используется библиотекой libkos при создании процессов.

KosTaskGetArgsList()

Назначение

Позволяет получить параметры запуска программы.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [out] args – указатель на адрес массива параметров запуска программы или RTL_NULL, если этих параметров нет.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Чтобы удалить массив параметров запуска программы, нужно вызвать функцию KosTaskFreeArgsList().

KosTaskFreeArgsList()

Назначение

Удаляет массив параметров запуска программы, полученный вызовом KosTaskGetArgsList().

Параметры

  • [in] args – указатель на массив параметров запуска программы.

Возвращаемые значения

Нет.

KosTaskSetEnv()

Назначение

Задает переменные окружения программы.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [in] envs – указатель на массив переменных окружения программы. Последним элементом массива должно быть значение RTL_NULL.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Функция используется библиотекой libkos при создании процессов.

KosTaskGetEnvList()

Назначение

Позволяет получить переменные окружения программы.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [out] envs – указатель на адрес массива переменных окружения программы или RTL_NULL, если этих переменных нет.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Чтобы удалить массив переменных окружения программы, нужно вызвать функцию KosTaskFreeEnvList().

KosTaskFreeEnvList()

Назначение

Удаляет массив переменных окружения программы, полученный вызовом функции KosTaskGetEnvList().

Параметры

  • [in] envs – указатель на массив переменных окружения программы.

Возвращаемые значения

Нет.

KosTaskRunEx()

Назначение

Запускает процесс.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [in] fsBackend – параметр, который задает, как осуществляется поддержку файловой системы ROMFS для запускаемого процесса: ядром или системной программой.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskRun()

Назначение

Запускает процесс.

Параметры

  • [in] task – указатель на объект, описывающий процесс.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskStop()

Назначение

Завершает процесс.

Параметры

  • [in] task – указатель на объект, описывающий процесс.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskStopAndWait()

Назначение

Завершает процесс и ожидает окончания завершения этого процесса.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [in] timeout – время ожидания в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskWait()

Назначение

Ожидает завершения процесса.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [in] timeout – время ожидания в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [out] retcode – указатель на код завершения процесса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskGetHandle()

Назначение

Позволяет получить дескриптор процесса.

Параметры

  • [in] task – указатель на объект, описывающий процесс.

Возвращаемые значения

Дескриптор процесса.

KosTaskLaunch()

Назначение

Создает и запускает процесс.

Параметры

  • [in] params – указатель на структуру, содержащую параметры процесса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskGetSelf()

Назначение

Позволяет получить адрес объекта, описывающего вызывающий процесс.

Параметры

Нет.

Возвращаемые значения

Указатель на объект, описывающий процесс, или RTL_NULL, если этот объект удален.

Дополнительные сведения

Функция увеличивает на единицу число ссылок на объект, описывающий процесс, поэтому после вызова этой функции нужно вызвать функцию KosTaskPut().

KosTaskPut()

Назначение

Уменьшает на единицу число ссылок на объект, описывающий процесс.

Параметры

  • [in] task – указатель на объект, описывающий процесс.

Возвращаемые значения

Нет.

KosTaskAddEndpoints()

Назначение

Регистрирует службы.

Параметры

  • [in,out] task – указатель на объект, описывающий процесс.
  • [in] endpoints – указатель на массив структур, описывающих службы. Тип структуры определен в заголовочном файле sysroot-*-kos/include/services/handle/if_connection.h из состава KasperskyOS SDK.
  • [in] count – число служб.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Функция используется библиотекой libkos при создании процессов.

KosTaskSetSelfFSBackend()

Назначение

Задает, как осуществляется поддержка файловой системы ROMFS для вызывающего процесса: ядром или системной программой.

Параметры

  • [in] fsBackend – параметр, который задает, как осуществляется поддержка файловой системы ROMFS: ядром или системной программой.

Возвращаемые значения

Нет.

KosTaskGetSelfFSBackend()

Назначение

Позволяет получить сведения о том, как осуществляется поддержка файловой системы ROMFS для вызывающего процесса: ядром или системной программой.

Параметры

Нет.

Возвращаемые значения

Значение, которое отражает, как осуществляется поддержка файловой системы ROMFS: ядром или системной программой.

KosTaskSetComponentTree()

Назначение

Создает структуры со сведениями о службах из формальной спецификации компонента решения и связывает эти структуры с объектом, описывающим процесс.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [in] root – указатель на структуру, содержащую сведения из формальной спецификации компонента решения. Тип структуры определен в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK. Эта структура является элементом автоматически генерируемого транспортного кода.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskTransferResource()

Назначение

Передает дескриптор процессу, который еще не запущен.

Параметры

  • [in] task – указатель на объект, описывающий процесс.
  • [in] srcHandle – передаваемый дескриптор.
  • [in] srcBadge – дескриптор объекта контекста передачи ресурса.
  • [in] dstRights – маска прав потомка передаваемого дескриптора.
  • [in] handleName – имя потомка передаваемого дескриптора.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosTaskLookupResource()

Назначение

Выполняет поиск дескриптора по имени, заданному функцией KosTaskTransferResource().

Параметры

  • [in] handleName – имя дескриптора.

Возвращаемые значения

В случае успеха возвращает дескриптор, иначе возвращает INVALID_HANDLE.

В начало
[Topic libkos_task_high_api]

Управление процессами (низкоуровневый API task_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/task/task_api.h из состава KasperskyOS SDK.

Основные возможности API:

  • создавать, запускать и завершать процессы;
  • обрабатывать исключения;
  • получать сведения о процессах, включая информацию о причинах их завершения;
  • задавать приоритеты и классы планирования начальных потоков процессов.

Сведения о функциях API приведены в таблице ниже.

Библиотека libkos также предоставляет высокоуровневый API для управления процессами, который определен в заголовочном файле sysroot-*-kos/include/kos/task.h из состава KasperskyOS SDK. Рекомендуется использовать именно этот API. Низкоуровневый API следует использовать, если недостаточно возможностей высокоуровневого API.

Создание и запуск процессов

Чтобы создать процесс, нужно вызвать функцию KnTaskCreate() или KnTaskCreateEx(). Эти функции создают "пустой" процесс, то есть процесс, в память которого не загружен ELF-образ программы. Перед запуском такого процесса нужно выполнить следующие шаги:

  1. Создать начальное значение генератора случайных чисел вызовом функции KosRandomGenerate(), которая объявлена в заголовочном файле sysroot-*-kos/include/kos/random/random_api.h из состава KasperskyOS SDK.

    Этот шаг необходим для выполнения следующего шага.

  2. Задать начальное значение генератора случайных чисел вызовом функции KnTaskReseedAslr().

    Этот шаг необходим для рандомизации размещения адресного пространства процесса. Рандомизация размещения адресного пространства (англ. Address Space Layout Randomization, ASLR) – это размещение структур данных (ELF-образа, динамических библиотек, стека и кучи) в памяти процесса по случайным адресам с целью усложнения эксплуатации уязвимостей, которые связаны с заранее известной злоумышленнику структурой адресного пространства процесса.

    Функция KnTaskReseedAslr() задает начальное значение генератора случайных чисел, который используется для автоматического выбора базового адреса выделяемого региона виртуальной памяти в таких функциях, как KnVmAllocate(), KnPmmMdlMap(), KnIoDmaMap(), KnTaskVmReserve(). Создание стека и кучи в процессе, а также загрузка динамических библиотек в его память выполняются операционной системой с использованием функции KnVmAllocate(). При этом в параметре addr указывается ноль, чтобы адрес выделенного региона виртуальной памяти был выбран автоматически, то есть был случайным значением.

  3. Стереть из памяти начальное значение генератора случайных чисел, созданное на шаге 1.

    Этот шаг необходим для целей безопасности. Чтобы выполнить этот шаг, нужно вызвать функцию RtlRandomMemSanitize(), которая объявлена в заголовочном файле sysroot-*-kos/include/rtl/random.h из состава KasperskyOS SDK.

  4. Загрузить сегменты ELF-образа в память процесса с использованием функции KnTaskLoadSeg().

    В поле loadAddr параметра seg нужно указать адрес загрузки сегмента ELF-образа. С целью поддержки ASLR (дополнительно к шагу 2) адрес загрузки сегмента ELF-образа, указанный в ELF-файле, должен быть увеличен на смещение загрузки ELF-образа. Смещение загрузки ELF-образа должно быть случайным значением. Генерацию случайного смещения загрузки ELF-образа и расчет адресов загрузки сегментов ELF-образа с учетом этого смещения выполняет функция KnElfCreateVmSegEx(), объявленная в заголовочном файле sysroot-*-kos/include/coresrv/elf/elf_api.h из состава KasperskyOS SDK.

    В результате этого шага буферы MDL, которые содержат сегменты ELF-образа, будут отображены на виртуальную память процесса.

  5. [Опционально] Загрузить таблицу символов .symtab и таблицу строк .strtab в память процесса вызовом функции KnTaskLoadElfSyms().

    Адреса загрузки сегментов ELF-образа с таблицей символов .symtab и таблицей строк .strtab должны быть рассчитаны так же, как и адреса загрузки других сегментов ELF-образа. Этот расчет выполняет функция KnElfCreateVmSegEx(), объявленная в заголовочном файле sysroot-*-kos/include/coresrv/elf/elf_api.h из состава KasperskyOS SDK.

    Используя таблицу символов .symtab и таблицу строк .strtab, ядро получает имена функций для формирования данных обратной трассировки стека (сведений о стеке вызовов).

  6. Задать точку входа в программу и смещение загрузки ELF-образа вызовом функции KnTaskSetInitialState().

    Точка входа в программу представляет собой сумму адреса, указанного в поле e_entry заголовка ELF-образа, и смещения загрузки ELF-образа. Генерацию случайного смещения загрузки ELF-образа и расчет адреса точки входа в программу с учетом этого смещения выполняет функция KnElfCreateVmSegEx(), объявленная в заголовочном файле sysroot-*-kos/include/coresrv/elf/elf_api.h из состава KasperskyOS SDK.

  7. [Опционально] Загрузить в память процесса заголовок ELF-образа вызовом функции KnTaskSetElfHdr().

    Этот шаг нужно выполнить, если требуется, чтобы данные из заголовка ELF-образа были доступны в созданном процессе.

Дескриптор процесса можно передать другому процессу через IPC.

По умолчанию начальный поток процесса является стандартным потоком исполнения, приоритет которого может принимать значения от 0 до 15. (О классах планирования потоков исполнения см. "Управление потоками исполнения (низкоуровневый API thread_api.h)".) Чтобы изменить класс планирования и/или приоритет начального потока процесса, нужно вызвать функцию KnTaskSetInitialPolicy(). Чтобы изменить приоритет начального потока процесса, нужно вызвать функцию KnTaskSetInitialThreadPriority(). Функции KnTaskSetInitialPolicy() и KnTaskSetInitialThreadPriority() можно использовать после задания точки входа в программу. Также эти функции можно использовать после запуска процесса.

Чтобы запустить процесс, нужно вызвать функцию KnTaskResume(). Запущенный процесс нельзя приостановить.

Перед запуском процесс получает данные от своего родительского процесса через страницу статических соединений. Страница статических соединений (англ. Static Connection Page, SCP) – набор структур, содержащих данные для статического создания IPC-каналов, параметры запуска и переменные окружения программы. Родительский процесс записывать данные в SCP дочернего процесса вызовом функции KnTaskSetEnv(). Дочерний процесс при запуске считывает данные из SCP вызовом функции KnTaskGetEnv(), а затем удаляет SCP вызовом функции KnTaskFreeEnv(). Все три функции не требуется явно вызывать, так как их вызовы выполняет библиотека libkos.

Завершение процессов

Завершение процесса включает в себя:

  • Завершение всех потоков процесса.
  • Освобождение памяти процесса.
  • Освобождение системных и пользовательских ресурсов, которыми процесс владеет эксклюзивно.

    При завершении процесса все дескрипторы, которыми он владеет, закрываются. Если закрытый дескриптор был единственным дескриптором ресурса, то этот ресурс освобождается.

Процесс завершается по следующим причинам:

  • По собственной инициативе.

    Вызвана функция KnTaskExit(), или завершены все потоки процесса.

  • По внешнему запросу.

    Вызвана функция KnTaskTerminate().

  • В результате необработанного исключения (аварийно).

    Вызовом функции KnTaskPanic() процесс может специально инициировать возникновение исключения, которое не может быть обработано и приводит к завершению этого процесса. Это требуется, чтобы процесс мог гарантированно завершить себя. (Например, если в процессе есть потоки исполнения, привязанные к прерываниям, то функция KnTaskExit() не может завершить этот процесс, а функция KnTaskPanic() позволяет сделать это.)

Коды завершения процессов определяются разработчиком решения на базе KasperskyOS. Эти коды нужно указывать в параметре status функции KnTaskExit(). Если процесс завершился в результате завершения всех его потоков, то кодом завершения этого процесса будет код завершения его начального потока. Чтобы получить код завершения процесса, который завершился по собственной инициативе, нужно вызвать функцию KnTaskGetExitCode().

Чтобы получить сведения о причине завершения процесса, нужно вызвать функцию KnTaskGetExitStatus(). Эта функция позволяет определить, был ли процесс завершен по собственной инициативе, по внешнему запросу или аварийно.

Чтобы получить сведения о необработанном исключении, которое привело к аварийному завершению процесса, нужно вызвать функцию KnTaskGetExceptionInfo(). Эти сведения включают код исключения и контекст потока исполнения, в котором это исключение возникло.

Если процесс создан вызовом функции KnTaskCreateEx() с флагом TaskExceptionFreezesTask в параметре flags, то в результате необработанного исключения этот процесс не завершится, а перейдет в "замороженное" состояние. "Замороженное" состояние процесса – это такое состояние процесса, при котором исполнение его потоков завершилось в результате необработанного исключения, но ресурсы не освободились, чтобы можно было получить сведения об этом процессе. Чтобы получить контекст потока исполнения, входящего в процесс, который находится в "замороженном" состоянии, нужно вызвать функцию KnTaskGetThreadContext(). Чтобы получить сведения о регионе виртуальной памяти, принадлежащем процессу, который находится в "замороженном" состоянии, нужно вызвать функцию KnTaskGetNextVmRegion(). Эти сведения включают такую информацию, как базовый адрес и размер региона виртуальной памяти, права доступа к нему. Перед переходом процесса в "замороженное" состояние выполняется вывод данных обратной трассировки стека (сведений о стеке вызовов) для потока исполнения, в котором возникло необработанное исключение. Чтобы завершить процесс, который находится в "замороженном" состоянии, нужно вызвать функцию KnTaskTerminateAfterFreezing().

Чтобы объект ядра, который описывает процесс, был удален после завершения этого процесса, нужно до или после завершения этого процесса закрыть или отозвать каждый его дескриптор во всех процессах, которые владеют этими дескрипторами. Чтобы выполнить это, нужно использовать функцию KnHandleClose() и/или KnHandleRevoke(), которые объявлены в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.

Обработка исключений

Чтобы зарегистрировать функцию обработки исключений, нужно вызвать функцию KnTaskSetExceptionHandler(). Эта функция дерегистрирует предыдущую функцию обработки исключений и возвращает ее идентификатор. Сохранив этот идентификатор, в дальнейшем можно снова зарегистрировать предыдущую функцию обработки исключений.

Функция обработки исключений вызывается при возникновении исключения в любом потоке процесса. В случае успешной обработки исключения эта функция возвращает значение, отличное от ноля, в противном случае она возвращает ноль. Входным параметром функции обработки исключений является структура, содержащая сведения об исключении. Тип этой структуры определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

Если функции обработки исключений, зарегистрированной на уровне процесса, не удалось успешно обработать исключение, будет вызвана функция обработки исключений, зарегистрированная на уровне потока исполнения, в котором возникло это исключение. (Об обработке исключений на уровне потоков исполнения см. "Управление потоками исполнения (низкоуровневый API thread_api.h)".)

Резервирование памяти в дочернем процессе

API включает функции KnTaskVmReserve() и KnTaskVmFree(), которые позволяют соответственно резервировать и освобождать регионы виртуальной памяти в дочернем процессе, для которого еще не задана точка входа в программу. Эти функции являются только частью функциональности, нацеленной на повышение уровня контроля родительского процесса за виртуальным адресным пространством дочернего процесса. В настоящее время эта функциональность находится в разработке.

Получение адреса GSI

Общая системная информация (англ. Global System Information, GSI) – структура, содержащая системные сведения, такие как число отсчетов таймера с момента запуска ядра, число отсчетов таймера в секунду, число процессоров (вычислительных ядер) в активном состоянии, данные о процессорном кеше. Тип структуры определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK. Получить адрес GSI позволяет функция KnTaskGetGsi(). Эта функция предназначена для использования библиотекой libc.

Получение адреса PCB

Блок управления процессом (англ. Process Control Block, PCB) – структура, содержащая сведения о процессе, которые используются ядром для управления этим процессом. Тип структуры определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK. Получить адрес PCB позволяет функция KnTaskGetPcb(). Эта функция предназначена для использования библиотекой libc.

Сведения о функциях API

Функции task_api.h

Функция

Сведения о функции

KnTaskCreate()

Назначение

Создает процесс.

Параметры

  • [in] name – указатель на имя процесса.
  • [in] eiid – указатель на имя класса процесса.
  • [in] path – параметр, который должен иметь значение RTL_NULL.
  • [in,optional] stackSize – размер стека потока исполнения, используемый по умолчанию при создании потоков процесса, в байтах. Если указать 0, то по умолчанию стек будет иметь размер 1 МБ.
  • [in] priority – приоритет начального потока исполнения. Тип параметра определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.
  • [out] outHandle – указатель на дескриптор процесса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskCreateEx()

Назначение

Создает процесс.

Параметры

  • [in] name – указатель на имя процесса.
  • [in] eiid – указатель на имя класса процесса.
  • [in] path – параметр, который должен иметь значение RTL_NULL.
  • [in,optional] stackSize – размер стека потока исполнения, используемый по умолчанию при создании потоков процесса, в байтах. Если указать 0, то по умолчанию стек будет иметь размер 1 МБ.
  • [in] priority – приоритет начального потока исполнения. Тип параметра определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.
  • [in] flags – флаги, задающие параметры создания процесса.
  • [out] outHandle – указатель на дескриптор процесса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • TaskExceptionTerminatesTask – процесс завершается в результате необработанного исключения.
  • TaskExceptionFreezesTask – процесс переходит в "замороженное" состояние в результате необработанного исключения. Этот флаг нельзя указывать совместно с флагом TaskExceptionTerminatesTask.
  • TaskEmpty – создание "пустого" процесса. Этот флаг должен быть обязательно установлен.

KnTaskGetGsi()

Назначение

Позволяет получить адрес GSI для вызывающего процесса.

Параметры

Нет.

Возвращаемые значения

Указатель на GSI. Тип данных для хранения GSI определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK.

KnTaskGetPcb()

Назначение

Позволяет получить адрес блока управления процессом (PCB) для вызывающего процесса.

Параметры

Нет.

Возвращаемые значения

Указатель на PCB. Тип данных для хранения PCB определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK.

KnTaskGetEnv()

Назначение

Позволяет получить адрес SCP вызывающего процесса.

Параметры

  • [out] envSize – указатель на размер SCP в байтах.

Возвращаемые значения

Указатель на SCP или RTL_NULL, если у процесса нет SCP.

KnTaskSetEnv()

Назначение

Записывает данные в SCP процесса.

Параметры

  • [in] task – дескриптор процесса.
  • [in] env – указатель на буфер с данными для записи в SCP.
  • [in] envSize – размер данных для записи в SCP в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskFreeEnv()

Назначение

Удаляет SCP вызывающего процесса.

Параметры

Нет.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskSetElfHdr()

Назначение

Записывает заголовок ELF-образа в PCB процесса.

Параметры

  • [in] h – дескриптор процесса.
  • [in] hdrData – указатель на буфер, содержащий заголовок ELF-образа.
  • [in] hdrSize – размер заголовка ELF-образа в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskResume()

Назначение

Запускает процесс.

Параметры

  • [in] task – дескриптор процесса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskExit()

Назначение

Завершает вызывающий процесс.

Параметры

  • [in] status – код завершения процесса.

Возвращаемые значения

Код ошибки.

Дополнительные сведения

Не завершает процесс, если в нем есть потоки исполнения, привязанные к прерываниям.

KnTaskTerminate()

Назначение

Завершает процесс.

Параметры

  • [in] task – дескриптор процесса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskGetExitStatus()

Назначение

Позволяет получить сведения о причине завершения процесса.

Параметры

  • [in] task – дескриптор завершившегося процесса.
  • [out] status – указатель на значение, отражающее причину завершения процесса. Тип данных для хранения этого значения определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Через параметры status можно получить следующие значения:

  • TaskExitUnexpected – процесс завершился аварийно.
  • TaskExitNormal – процесс завершился по собственной инициативе.
  • TaskExitTerminated – процесс завершился по внешнему запросу.

KnTaskGetExceptionInfo()

Назначение

Позволяет получить сведения о необработанном исключении, которое привело к аварийному завершению процесса.

Параметры

  • [in] task – дескриптор аварийно завершившегося процесса.
  • [out] excType – указатель на код исключения, который неспецифичен для любой процессорной архитектуры. Тип данных для хранения этого кода определен в заголовочном файле sysroot-*-kos/include/hal/exc_codes.h из состава KasperskyOS SDK.
  • [out] excNo – указатель на код исключения, который специфичен для используемой процессорной архитектуры. Тип данных для хранения этого кода определен в заголовочном файле sysroot-*-kos/include/hal/exc_codes.h из состава KasperskyOS SDK.
  • [out] exceptionContext – указатель на структуру, содержащую контекст потока исполнения, в котором возникло исключение. Тип структуры определен в заголовочном файле sysroot-*-kos/include/hal/*/frame.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskGetThreadContext()

Назначение

Позволяет получить контекст потока исполнения, входящего в процесс, который находится в "замороженном" состоянии.

Параметры

  • [in] task – дескриптор процесса, который находится в "замороженном" состоянии.
  • [in] index – индекс потока исполнения. Используется для перечисления потоков исполнения. Нумерация начинается с нуля. Нулевой индекс имеет поток исполнения, в котором возникло необработанное исключение.
  • [out] context – указатель на структуру, содержащую идентификатор (TID) и контекст потока исполнения. Тип структуры определен в заголовочном файле sysroot-*-kos/include/thread/context.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskGetNextVmRegion()

Назначение

Позволяет получить сведения о регионе виртуальной памяти, принадлежащем процессу, который находится в "замороженном" состоянии.

Параметры

  • [in] task – дескриптор процесса, который находится в "замороженном" состоянии.
  • [in] after – адрес, после которого размещен регион виртуальной памяти.
  • [out] next – указатель на базовый адрес региона виртуальной памяти.
  • [out] size – указатель на размер региона виртуальной памяти в байтах.
  • [out] flags – указатель на флаги, отражающие параметры региона виртуальной памяти. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [out] outHandle – указатель на дескриптор буфера MDL, отображенного на регион виртуальной памяти. Функция KnTaskGetNextVmRegion() создает буфер MDL из физической памяти, отображенной на регион виртуальной памяти (даже если уже существует буфер MDL, который отображен на этот регион виртуальной памяти).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskTerminateAfterFreezing()

Назначение

Завершает процесс, который находится в "замороженном" состоянии.

Параметры

  • [in] task – дескриптор процесса, который находится в "замороженном" состоянии.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskGetExitCode()

Назначение

Позволяет получить код завершения процесса, который завершился по собственной инициативе.

Параметры

  • [in] task – дескриптор завершившегося процесса.
  • [out] exitCode – указатель на код завершения процесса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskGetId()

Назначение

Позволяет получить идентификатор процесса (PID) для вызывающего процесса.

Параметры

Нет.

Возвращаемые значения

Идентификатор процесса. Тип идентификатора определен в заголовочном файле sysroot-*-kos/include/task/pidtype.h из KasperskyOS SDK.

KnTaskGetName()

Назначение

Позволяет получить имя вызывающего процесса.

Параметры

  • [out] name – указатель на буфер для сохранения имени процесса.
  • [in] msize – размер буфера для сохранения имени процесса в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskGetPath()

Назначение

Позволяет получить имя исполняемого файла (в ROMFS), из которого создан вызывающий процесс.

Параметры

  • [out] path – указатель на буфер для сохранения имени исполняемого файла.
  • [in] msize – размер буфера для сохранения имени исполняемого файла в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskGetInitialThreadPriority()

Назначение

Позволяет получить приоритет начального потока процесса.

Параметры

  • [in] task – дескриптор процесса.
  • [out] priority – указатель на приоритет начального потока процесса. Тип данных для хранения приоритета потока исполнения определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskSetInitialThreadPriority()

Назначение

Задает приоритет начального потока процесса.

Параметры

  • [in] task – дескриптор процесса.
  • [in] priority – приоритет начального потока процесса. Тип параметра определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskSetExceptionHandler()

Назначение

Регистрирует функцию обработки исключений для вызывающего процесса.

Параметры

  • [in,optional] handler – идентификатор функции обработки исключений или RTL_NULL, чтобы дерегистрировать предыдущую зарегистрированную функцию без регистрации новой. Тип параметра определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK.

Возвращаемые значения

Идентификатор предыдущей зарегистрированной функции обработки исключений или RTL_NULL при ее отсутствии. Тип возвращаемого значения определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK.

KnTaskLoadSeg()

Назначение

Загружает сегмент ELF-образа в память процесса.

Параметры

  • [in] h – дескриптор процесса.
  • [in] seg – указатель на структуру, описывающую сегмент ELF-образа. Если задать поле loadAddr этой структуры равным 0, то адрес загрузки сегмента ELF-образа будет выбран автоматически. Тип структуры определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_types.h из состава KasperskyOS SDK.
  • [out] actual – указатель на адрес загрузки сегмента ELF-образа.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskVmReserve()

Назначение

Резервирует регион виртуальной памяти в процессе.

Параметры

  • [in] task – дескриптор процесса.
  • [in,optional] hint – странично выровненный желаемый базовый адрес региона виртуальной памяти или RTL_NULL, чтобы этот адрес был выбран автоматически.
  • [in] size – размер региона виртуальной памяти в байтах.
  • [in] flags – флаги, задающие параметры региона виртуальной памяти. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [out] addr – указатель на базовый адрес зарезервированного региона виртуальной памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • VMM_FLAG_LOCKED – фиксация региона виртуальной памяти с выделением всего требуемого объема физической памяти. При вызове функции KnTaskVmReserve() с этим флагом фиксация не выполняется. Этот флаг имеет эффект при последующих действиях с зарезервированным регионом виртуальной памяти, которые связаны с его фиксацией.
  • VMM_FLAG_READ, VMM_FLAG_WRITE, VMM_FLAG_EXECUTE и VMM_FLAG_RWX_MASK – флаги, задающие права доступа к региону виртуальной памяти.
  • VMM_FLAG_LOW_GUARD, VMM_FLAG_HIGH_GUARD – добавление охранной страницы в начало и конец региона виртуальной памяти соответственно. Размер охранной страницы не включается в размер региона виртуальной памяти.

Допустимые комбинации флагов, задающих права доступа к региону виртуальной памяти:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – доступ на чтение и запись.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – доступ на чтение и исполнение.
  • VMM_FLAG_RWX_MASK или VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – доступ на чтение, запись и исполнение.

KnTaskVmFree()

Назначение

Освобождает регион виртуальной памяти, зарезервированный вызовом функции KnTaskVmReserve().

Параметры

  • [in] task – дескриптор процесса.
  • [in] base – странично выровненный базовый адрес региона виртуальной памяти.
  • [in] size – размер региона виртуальной памяти в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskSetInitialState()

Назначение

Задает точку входа в программу и смещение загрузки ELF-образа.

Параметры

  • [in] h – дескриптор процесса.
  • [in] state – указатель на структуру, содержащую адрес точки входа в программу и смещение загрузки ELF-образа в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskLoadElfSyms()

Назначение

Загружает таблицу символов .symtab и таблицу строк .strtab в память процесса.

Параметры

  • [in] h – дескриптор процесса.
  • [in] symTabSeg – указатель на структуру, описывающую сегмент ELF-образа с таблицей символов .symtab. Тип структуры определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_types.h из состава KasperskyOS SDK.
  • [in] symTabSize – размер таблицы символов .symtab в байтах.
  • [in] strTabSeg – указатель на структуру, описывающую сегмент ELF-образа с таблицей строк .strtab. Тип структуры определен в заголовочном файле sysroot-*-kos/include/coresrv/vmm/vmm_types.h из состава KasperskyOS SDK.
  • [in] strTabSize – размер таблицы строк .strtab в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskSetInitialPolicy()

Назначение

Задает класс планирования и приоритет начального потока процесса.

Параметры

  • [in] task – дескриптор процесса.
  • [in] policy – класс планирования начального потока процесса. Тип параметра определен в заголовочном файле sysroot-*-kos/include/thread/tidtype.h из состава KasperskyOS SDK.
  • [in] priority – приоритет начального потока процесса. Тип параметра определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.
  • [in,optional] param – указатель на параметры класса планирования начального потока или RTL_NULL. Тип данных для хранения этих параметров определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре param можно указать RTL_NULL, если требуется задать параметры класса планирования начального потока процесса, применяемые по умолчанию.

В параметре param необходимо указать RTL_NULL, если класс планирования начального потока процесса не имеет параметров.

KnTaskReseedAslr()

Назначение

Задает начальное значение генератора случайных чисел для поддержки ASLR в заданном процессе.

Параметры

  • [in] task – дескриптор процесса.
  • [in] seed – указатель на буфер с начальным значением генератора случайных чисел.
  • [in] seedSize – размер буфера с начальным значением генератора случайных чисел (в байтах).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskGetElfSyms()

Назначение

Позволяет получить адреса и размеры таблицы символов .symtab и таблицы строк .strtab для вызывающего процесса.

Параметры

  • [out] relocBase – указатель на смещение загрузки ELF-образа в байтах. Смещение загрузки ELF-образа нужно сложить с адресом символа из таблицы символов .symtab, чтобы получить адрес этого символа в памяти процесса.
  • [out] syms – указатель на адрес таблицы символов .symtab.
  • [out] symsCnt – указатель на размер таблицы символов .symtab в байтах.
  • [out] strs – указатель на адрес таблицы строк .strtab.
  • [out] strsCnt – указатель на размер таблицы строк .strtab в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Если таблица символов .symtab и таблица строк .strtab не загружены в память процесса вызовом функции KnTaskLoadElfSyms(), то функция KnTaskGetElfSyms() возвращает rcOk (при отсутствии других ошибок). В этом случае полученные адреса таблиц имеют значения RTL_NULL, а полученные размеры таблиц имеют нулевые значения.

Функция предназначена для механизма, который выводит данные обратной трассировки стека и работает в процессе, а не в ядре. В настоящее время этот механизм находится в разработке.

KnTaskGetIdByHandle()

Назначение

Позволяет получить идентификатор процесса (PID).

Параметры

  • [in] task – дескриптор процесса.
  • [out] taskId – указатель на идентификатор процесса. Тип идентификатора определен в заголовочном файле sysroot-*-kos/include/task/pidtype.h из KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnTaskPanic()

Назначение

Инициирует возникновение исключения, которое не может быть обработано и приводит к завершению вызывающего процесса.

Параметры

Нет.

Возвращаемые значения

Нет.

KnTaskTransferResource()

Назначение

Передает дескриптор процессу, который еще не запущен.

Параметры

  • [in] task – дескриптор процесса.
  • [in] srcHandle – передаваемый дескриптор.
  • [in] srcBadge – дескриптор объекта контекста передачи ресурса.
  • [in] dstRights – маска прав потомка передаваемого дескриптора.
  • [out] outDstHandle – указатель на потомка переданного дескриптора (из пространства дескрипторов процесса, который получил дескриптор).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В отличие от функции KosTaskTransferResource() из API task.h функция KnTaskTransferResource() не копирует значение потомка переданного дескриптора в SCP процесса, которому передан дескриптор. Функция KosTaskTransferResource() выполняет это, чтобы процесс, который получил потомка переданного дескриптора, мог найти его вызовом функции KosTaskLookupResource() из API task.h.

В начало
[Topic libkos_task_low_api]

Инициализация IPC-транспорта для межпроцессного взаимодействия и управление обработкой IPC-запросов (transport-kos.h, transport-kos-dispatch.h)

API определены в заголовочных файлах transport-kos.h и transport-kos-dispatch.h из состава KasperskyOS SDK, которые расположены по пути sysroot-*-kos/include/coresrv/nk.

Возможности API:

Сведения о функциях API приведены в таблицах ниже.

В этом разделе приведены примеры использования API. В этих примерах программы, которые являются серверами, имеют следующую формальную спецификацию:

FsDriver.edl

task class FsDriver components { operationsComp : Operations }

Operations.cdl

component Operations endpoints { fileOperations : FileIface }

FileIface.idl

package FileIface interface { Open(in array<UInt8, 1024> path); Read(out sequence<UInt8, 2048> content); }

Инициализация IPC-транспорта для межпроцессного взаимодействия

Чтобы инициализировать IPC-транспорт для взаимодействия с другими процессами, нужно вызвать функцию NkKosTransport_Init() или NkKosTransportSync_Init(), объявленные в заголовочном файле transport-kos.h.

Пример использования функции NkKosTransport_Init() на стороне клиента:

int main(int argc, const char *argv[]) { /* Объявить структуру с параметрами IPC-транспорта */ NkKosTransport driver_transport; /* Объявить прокси-объект. (Тип прокси-объекта является автоматически * сгенерированным транспортным кодом.) */ struct FileIface_proxy file_operations_proxy; /* Объявить структуры для сохранения фиксированной части IPC-запроса и * IPC-ответа для метода службы. (Типы структур являются автоматически * сгенерированным транспортным кодом.) */ struct FileIface_Open_req req; struct FileIface_Open_res res; /* Получить клиентский IPC-дескриптор и идентификатор службы */ Handle driver_handle; rtl_uint32_t file_operations_riid; if (KnCmConnect("FsDriver", "operationsComp.fileOperations", INFINITE_TIMEOUT, &driver_handle, &file_operations_riid) == rcOk) { /* Инициализировать структуру с параметрами IPC-транспорта */ NkKosTransport_Init(&driver_transport, driver_handle, NK_NULL, 0); /* Инициализировать прокси-объект. (Метод инициализации прокси-объекта * является автоматически сгенерированным транспортным кодом.) */ FileIface_proxy_init(&file_operations_proxy, &driver_transport.base, (nk_iid_t) file_operations_riid); } ... /* Вызвать метод службы. (Метод является автоматически * сгенерированным транспортным кодом.) */ strncpy(req.path, "/example/file/path", sizeof(req.path)); if (FileIface_Open(file_operations_proxy.base, &req, NULL, &res, NULL) != NK_EOK) { ... } ... }

Если клиенту требуется использовать несколько служб, то нужно инициализировать столько же прокси-объектов. При инициализации каждого прокси-объекта нужно указать IPC-транспорт, ассоциированный через клиентский IPC-дескриптор с нужным сервером. При инициализации нескольких прокси-объектов, относящихся к службам одного сервера, можно указать один и тот же IPC-транспорт, который ассоциирован с этим сервером.

Пример использования функции NkKosTransport_Init() на стороне сервера:

int main(int argc, const char *argv[]) { ... /* Объявить структуру с параметрами IPC-транспорта */ NkKosTransport transport; /* Получить слушающий дескриптор. (Идентификатор службы * FsDriver_operationsComp_fileOperations_iid является * автоматически сгенерированным транспортным кодом.) */ Handle handle; char client[32]; char endpoint[32]; Retcode rc = KnCmListen(RTL_NULL, INFINITE_TIMEOUT, client, endpoint); if (rc == rcOk) rc = KnCmAccept(client, endpoint, FsDriver_operationsComp_fileOperations_iid, INVALID_HANDLE, &handle); ... /* Инициализировать структуру с параметрами IPC-транспорта */ NkKosTransport_Init(&transport, handle, NK_NULL, 0); ... /* Цикл обработки IPC-запросов */ do { ... /* Получить IPC-запрос */ rc = nk_transport_recv(&transport.base, ...); if (rc == NK_EOK) { /* Обработать IPC-запрос вызовом диспетчера. (Диспетчер * является автоматически сгенерированным транспортным * кодом.) */ rc = FsDriver_entity_dispatch(...); if (rc == NK_EOK) { /* Отправить IPC-ответ */ rc = nk_transport_reply(&transport.base, ...); } } } while (rc == NK_EOK) return EXIT_SUCCESS; }

Если сервер обрабатывает IPC-запросы, поступающие через несколько IPC-каналов, то нужно учитывать следующие особенности:

  • Если слушающий дескриптор ассоциирован со всеми IPC-каналами, то для IPC-взаимодействия со всеми клиентами можно использовать один IPC-транспорт, ассоциированный с этим слушающим дескриптором.
  • Если IPC-каналы ассоциированы с разными слушающими дескрипторами, то для IPC-взаимодействия с каждой группой клиентов, соответствующих одному слушающему дескриптору, нужно использовать отдельный IPC-транспорт, ассоциированный с этим слушающим дескриптором. При этом обработку IPC-запросов можно выполнять в параллельных потоках исполнения, если реализация методов служб потокобезопасна.

Функция NkKosTransportSync_Init() позволяет инициализировать IPC-транспорт с поддержкой прерывания блокирующих системных вызовов Call() и Recv(). (Прерывание этих вызовов может потребоваться, например, чтобы корректно завершить процесс, который их выполняет.) Чтобы прерывать системные вызовы Call() и Recv(), нужно использовать API ipc_api.h.

Функция NkKosSetTransportTimeouts(), объявленная в заголовочном файле transport-kos.h, позволяет задать для IPC-транспорта максимальное время блокировки системных вызовов Call() и Recv().

Запуск цикла обработки IPC-запросов

Цикл обработки IPC-запроса на сервере включает следующие стадии:

  1. Получение IPC-запроса.
  2. Обработка IPC-запроса.
  3. Отправка IPC-ответа.

Каждую стадию этого цикла можно выполнять отдельно, последовательно вызывая функции nk_transport_recv(), диспетчер, nk_transport_reply(). (Функции nk_transport_recv() и nk_transport_reply() объявлены в заголовочном файле sysroot-*-kos/include/nk/transport.h из состава KasperskyOS SDK.) А можно вызвать функцию NkKosTransport_Dispatch(), NkKosDoDispatch() или NkKosDoDispatchEx(), внутри которых этот цикл выполняется полностью. (Функция NkKosTransport_Dispatch() объявлена в заголовочном файле transport-kos.h, функции NkKosDoDispatch() и NkKosDoDispatchEx() объявлены в заголовочном файле transport-kos-dispatch.h.) Использовать функцию NkKosDoDispatch() или NkKosDoDispatchEx() удобнее по сравнению с функцией NkKosTransport_Dispatch(), поскольку нужно выполнять меньше подготовительных операций (в том числе не требуется инициализировать IPC-транспорт).

Для инициализации структуры, передаваемой функции NkKosDoDispatch() или NkKosDoDispatchEx() через параметр info, можно использовать макросы, определенные в заголовочном файле transport-kos-dispatch.h. Используя параметр syncHandle функции NkKosDoDispatchEx(), можно прерывать системный вызов Recv(). Через параметр cb функции NkKosDoDispatchEx() можно задать callback-функции, вызываемые после выполнения системных вызовов Recv() и Reply(), а также после выхода из цикла обработки IPC-запросов (все функции задавать не требуется). Callback-функция, соответствующая указателю enterDispatchProcessing, вызывается сразу после выполнения системного вызова Recv(). Callback-функция, соответствующая указателю leaveDispatchProcessing, вызывается сразу после выполнения системного вызова Reply(). Callback-функция, соответствующая указателю stopDispatchLoop, вызывается сразу после выхода из цикла обработки IPC-запросов. Каждой из этих callback-функций передается указатель callbackContext. Эти callback-функции могут использоваться, например, в реализации пула потоков исполнения.

Функции NkKosTransport_Dispatch(), NkKosDoDispatch() и NkKosDoDispatchEx() можно вызывать из параллельных потоков исполнения, если реализация методов служб потокобезопасна.

Пример использования функции NkKosDoDispatch():

/* Функция реализует метод службы. */ static nk_err_t Open_impl(...) { ... } /* Функция реализует метод службы. */ static nk_err_t Read_impl(...) { ... } /* Функция инициализирует указатели на функции, реализующие методы службы. * (Эти указатели используются диспетчером для вызова функций, реализующих * методы службы. Типы структур являются автоматически сгенерированным * транспортным кодом.) */ static struct FileIface *CreateFileOperations() { static const struct FileIface_ops ops = { .Open = Open_impl, .Read = Read_impl }; static struct FileIface impl = { .ops = &ops }; return &impl; } int main(int argc, const char *argv[]) { ... /* Объявить структуру, которая требуется функции * NkKosDoDispatch() для использования транспортного кода. */ NkKosDispatchInfo info; /* Объявить стабы. (Типы стабов являются автоматически сгенерированным * транспортным кодом. */ struct Operations_component component; struct FsDriver_entity entity; /* Получить слушающий дескриптор */ Handle handle = ServiceLocatorRegister("driver_connection", NULL, 0, &iid); assert(handle != INVALID_HANDLE); /* Инициализировать стабы. (Методы инициализации стабов являются * автоматически сгенерированным транспортным кодом. Функция * CreateFileOperations() реализована разработчиком решения на * базе KasperskyOS, чтобы инициализировать * указатели на функции, реализующие методы службы.) */ Operations_component_init(&component, CreateFileOperations()); FsDriver_entity_init(&entity, &component); /* Инициализировать структуру, которая требуется функции * NkKosDoDispatch() для использования транспортного кода. */ info = NK_TASK_DISPATCH_INFO_INITIALIZER(FsDriver, entity); /* Запустить цикл обработки IPC-запросов */ NkKosDoDispatch(handle, info); return EXIT_SUCCESS; }

Пример использования функции NkKosTransport_Dispatch():

/* Функция реализует метод службы. */ static nk_err_t Open_impl(...) { ... } /* Функция реализует метод службы. */ static nk_err_t Read_impl(...) { ... } /* Функция инициализирует указатели на функции, реализующие методы службы. * (Эти указатели используются диспетчером для вызова функций, реализующих * методы службы. Типы структур являются автоматически сгенерированным * транспортным кодом.) */ static struct FileIface *CreateFileOperations() { static const struct FileIface_ops ops = { .Open = Open_impl, .Read = Read_impl }; static struct FileIface impl = { .ops = &ops }; return &impl; } int main(int argc, const char *argv[]) { ... /* Объявить структуру с параметрами IPC-транспорта */ NkKosTransport transport; /* Объявить стабы. (Типы стабов являются автоматически сгенерированным * транспортным кодом. */ struct Operations_component component; struct FsDriver_entity entity; /* Объявить объединения фиксированной части IPC-запросов и * IPC-ответов. (Типы объединений являются автоматически сгенерированным * транспортным кодом.) */ union FsDriver_entity_req req; union FsDriver_entity_res res; /* Объявить массив для арены IPC-ответов. (Размер массива является * автоматически сгенерированным транспортным кодом.) */ char res_buffer[FsDriver_entity_res_arena_size]; /* Объявить и инициализировать дескриптор арены IPC-ответов. * (Тип дескриптора и макрос его инициализации определены в заголовочном файле * sysroot-*-kos/include/nk/arena.h из состава KasperskyOS SDK.) */ struct nk_arena res_arena = NK_ARENA_INITIALIZER(res_buffer, res_buffer + sizeof(res_buffer)); /* Получить слушающий дескриптор */ Handle handle = ServiceLocatorRegister("driver_connection", NULL, 0, &iid); assert(handle != INVALID_HANDLE); /* Инициализировать структуру с параметрами IPC-транспорта */ NkKosTransport_Init(&transport, handle, NK_NULL, 0); /* Инициализировать стабы. (Методы инициализации стабов являются * автоматически сгенерированным транспортным кодом. Функция * CreateFileOperations() реализована разработчиком решения на * базе KasperskyOS, чтобы инициализировать * указатели на функции, реализующие методы службы.) */ Operations_component_init(&component, CreateFileOperations()); FsDriver_entity_init(&entity, &component); /* Запустить цикл обработки IPC-запросов. (Диспетчер FsDriver_entity_dispatch * является автоматически сгенерированным транспортным кодом.) */ NkKosTransport_Dispatch(&transport.base, FsDriver_entity_dispatch, &entity, &req, sizeof(FsDriver_entity_req), RTL_NULL, &res, &res_arena); return EXIT_SUCCESS; }

Копирование данных в арену IPC-сообщений

Чтобы скопировать строку в арену IPC-сообщений, нужно вызвать функцию NkKosCopyStringToArena(), объявленную в заголовочном файле transport-kos.h. Эта функция резервирует участок арены и копирует строку в этот участок.

Пример использования функции NkKosCopyStringToArena():

static nk_err_t Read_impl(struct FileIface *self, const struct FileIface_Read_req *req, const struct nk_arena* req_arena, struct FileIface_Read_res* res, struct nk_arena* res_arena) { /* Скопировать строку в арену IPC-ответов */ if (NkKosCopyStringToArena(&res_arena, &res.content, "CONTENT OF THE FILE") != rcOk) { ... } return NK_EOK; }

Сведения о функциях API

Функции transport-kos.h

Функция

Сведения о функции

NkKosTransport_Init()

Назначение

Инициализирует IPC-транспорт.

Параметры

  • [out] transport – указатель на структуру с параметрами IPC-транспорта.
  • [in] handle – клиентский или серверный IPC-дескриптор.
  • [in] view – параметр, который должен иметь значение NK_NULL.
  • [in] size – параметр, который должен иметь значение 0.

Возвращаемые значения

Нет.

NkKosTransportSync_Init()

Назначение

Инициализирует IPC-транспорт с поддержкой прерывания системных вызовов Call() и/или Recv().

Параметры

  • [out] transport – указатель на структуру с параметрами IPC-транспорта.
  • [in] handle – клиентский или серверный IPC-дескриптор.
  • [in,optional] callSyncHandle – дескриптор объекта синхронизации IPC для системных вызовов Call() или INVALID_HANDLE, если прерывание системных вызовов Call() не требуется.
  • [in,optional] recvSyncHandle – дескриптор объекта синхронизации IPC для системных вызовов Recv() или INVALID_HANDLE, если прерывание системных вызовов Recv() не требуется.

Возвращаемые значения

Нет.

NkKosSetTransportTimeouts()

Назначение

Задает для IPC-транспорта максимальное время блокировки системных вызовов Call() и Recv().

Параметры

  • [out] transport – указатель на структуру с параметрами IPC-транспорта.
  • [in] recvTimeout – максимальное время блокировки системных вызовов Recv() в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время блокировки.
  • [in] callTimeout – максимальное время блокировки системных вызовов Call() в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время блокировки.

Возвращаемые значения

Нет.

NkKosTransport_Dispatch()

Назначение

Запускает цикл обработки IPC-запросов.

Параметры

  • [in] transport – указатель на поле base структуры с параметрами IPC-транспорта.
  • [in] dispatch – указатель на диспетчер (dispatch-метод) из транспортного кода. Диспетчер имеет имя <имя класса процессов>_entity_dispatch.
  • [in] impl – указатель на стаб, который представляет собой структуру с типом <имя класса процессов>_entity из транспортного кода. Через эту структуру диспетчер получает указатели на функции, реализующие методы служб.
  • [out] req – указатель на объединение с типом <имя класса процессов>_entity_req из транспортного кода. Это объединение предназначено для сохранения фиксированной части IPC-запросов для любых методов служб, предоставляемых сервером.
  • [in] req_size – максимальный размер фиксированной части IPC-запросов в байтах. Определяется как sizeof(<имя класса процессов>_entity_req), где <имя класса процессов>_entity_req является типом из транспортного кода.
  • [in,out,optional] req_arena – указатель на дескриптор арены IPC-запросов или RTL_NULL, если арена IPC-запросов не используется. Тип дескриптора определен в заголовочном файле sysroot-*-kos/include/nk/arena.h из состава KasperskyOS SDK.
  • [out] res – указатель на объединение с типом <имя класса процессов>_entity_res из транспортного кода. Это объединение предназначено для сохранения фиксированной части IPC-ответов для любых методов служб, предоставляемых сервером.
  • [in,out,optional] res_arena – указатель на дескриптор арены IPC-ответов или RTL_NULL, если арена IPC-ответов не используется. Тип дескриптора определен в заголовочном файле sysroot-*-kos/include/nk/arena.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае неуспеха возвращает код ошибки.

NkKosCopyStringToArena()

Назначение

Резервирует участок арены и копирует строку в этот участок.

Параметры

  • [in,out] arena – указатель на дескриптор арены. Тип дескриптора определен в заголовочном файле sysroot-*-kos/include/nk/arena.h из состава KasperskyOS SDK.
  • [out] field – указатель на дескриптор участка арены, куда скопирована строка. Тип дескриптора определен в заголовочном файле sysroot-*-kos/include/nk/types.h.
  • [in] src – указатель на строку для копирования в арену IPC-сообщений.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Функции transport-kos-dispatch.h

Функция

Сведения о функции

NkKosDoDispatch()

Назначение

Запускает цикл обработки IPC-запросов.

Параметры

  • [in] h – серверный IPC-дескриптор.
  • [in] info – указатель на структуру, содержащую данные, которые требуются функции для использования транспортного кода (включая имена типов, размеры фиксированной части и арены IPC-сообщений).

Возвращаемые значения

Нет.

NkKosDoDispatchEx()

Назначение

Запускает цикл обработки IPC-запросов.

Параметры

  • [in] h – серверный IPC-дескриптор.
  • [in] info – указатель на структуру, содержащую данные, которые требуются функции для использования транспортного кода (включая имена типов, размеры фиксированной части и арены IPC-сообщений).
  • [in,optional] cb – указатель на структуру, содержащую указатели на callback-функции, вызываемые после выполнения системных вызовов Recv() и Reply(), а также после выхода из цикла обработки IPC-запросов. Помимо указателей на callback-функции эта структура содержит указатель, который передается этим callback-функциям при вызове. В параметре можно указать RTL_NULL, если не требуется задавать callback-функции.
  • [in,optional] syncHandle – дескриптор объекта синхронизации IPC или INVALID_HANDLE, если прерывание системного вызова Recv() не требуется.

Возвращаемые значения

Нет.

В начало
[Topic libkos_ipc_transport_api]

Инициализация IPC-транспорта для обращения к модулю безопасности (transport-kos-security.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/nk/transport-kos-security.h из состава KasperskyOS SDK.

API позволяет инициализировать IPC-транспорт для обращения к модулю безопасности Kaspersky Security Module через интерфейс безопасности. Поверх IPC-транспорта работает транспортный код.

Сведения о функциях API приведены в таблице ниже.

В этом разделе приведен пример использования API. В этом примере программа, которая обращается к модулю безопасности, имеет следующую формальную спецификацию:

Verifier.edl

task class Verifier security Approve

Approve.idl

package Approve interface { Check(in UInt32 port); }

Фрагмент описания политики в примере:

security.psl

... security src=Verifier, method=Check { assert (message.port > 80) } ...

Использование API

Чтобы инициализировать IPC-транспорт для обращения к модулю безопасности, нужно вызвать функцию NkKosSecurityTransport_Init().

Пример использования функции NkKosSecurityTransport_Init():

int main(void) { /* Объявить структуру с параметрами IPC-транспорта для обращения к * модулю безопасности */ NkKosSecurityTransport security_transport; /* Объявить прокси-объект. (Тип прокси-объекта является автоматически * сгенерированным транспортным кодом.) */ struct Approve_proxy security_proxy; /* Объявить структуры для сохранения фиксированной части IPC-запроса и IPC-ответа для * метода интерфейса безопасности. (Типы структур являются автоматически сгенерированным * транспортным кодом.) */ struct Approve_Check_req security_req; struct Approve_Check_res security_res; /* Инициализировать структуру с параметрами IPC-транспорта для обращения к * модулю безопасности */ if (NkKosSecurityTransport_Init(&security_transport, NK_NULL, 0) == NK_EOK) { /* Инициализировать прокси-объект. (Метод инициализации прокси-объекта и * идентификатор интерфейса безопасности Verifier_securityIid * являются автоматически сгенерированным транспортным кодом.) */ Approve_proxy_init(&security_proxy, &security_transport.base, Verifier_securityIid); } ... /* Вызвать метод интерфейса безопасности. (Метод является автоматически сгенерированным * транспортным кодом. Метод не передает через параметр security_res никакие данные. * Указать этот параметр нужно только потому, что этого требует реализация метода.) */ security_req.port = 80; nk_err_t result = Approve_Check(&security_proxy.base, &security_req, NULL, &security_res, NULL); if (result == NK_EOK) fprintf(stderr, "Granted"); if (result == NK_EPERM) fprintf(stderr, "Denied"); else fprintf(stderr, "Error"); return EXIT_SUCCESS; }

Если процессу требуется использовать несколько интерфейсов безопасности, то нужно инициализировать столько же прокси-объектов, указав один и тот же IPC-транспорт и уникальные идентификаторы интерфейсов безопасности.

Сведения о функциях API

Функции transport-kos-security.h

Функция

Сведения о функции

NkKosSecurityTransport_Init()

Назначение

Инициализирует IPC-транспорт для обращения к модулю безопасности Kaspersky Security Module через интерфейс безопасности.

Параметры

  • [out] transport – указатель на структуру с параметрами IPC-транспорта для обращения к модулю безопасности.
  • [in] view – параметр, который должен иметь значение NK_NULL.
  • [in] size – параметр, который должен иметь значение 0.

Возвращаемые значения

В случае успеха возвращает NK_EOK, иначе возвращает код ошибки.

В начало
[Topic libkos_ipc_security_transport_api]

Генерация случайных чисел (random_api.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/random/random_api.h из состава KasperskyOS SDK.

API позволяет генерировать случайные числа, а также включает функции, которые можно использовать, чтобы обеспечить высокую энтропию (высокий уровень непредсказуемости) начального значения генератора случайных чисел. Начальное значение генератора случайных чисел (англ. seed) определяет последовательность генерируемых случайных чисел. То есть после установки одного и того же начального значения генератор создает одинаковые последовательности случайных чисел. (Энтропия таких чисел полностью определяется энтропией начального значения, поэтому точнее их называть не случайными, а псевдослучайными.)

Генератор случайных чисел одного процесса не зависит от генераторов случайных чисел других процессов.

Сведения о функциях API приведены в таблице ниже.

Использование API

Чтобы сгенерировать последовательность случайных байтовых значений, нужно вызвать функцию KosRandomGenerate() или KosRandomGenerateEx().

Пример использования функции KosRandomGenerate():

size_t random_number; if (KosRandomGenerate(sizeof random_number, &random_number) == rcOk) { ... }

Функция KosRandomGenerateEx() позволяет получить уровень качества сгенерированных случайных значений через выходной параметр quality. Уровень качества может быть высоким или низким. Высококачественными считаются случайные значения, которые сгенерированы при выполнении всех следующих условий:

  1. На момент изменения начального значения генератора случайных чисел зарегистрирован хотя бы один источник энтропии, и успешно получены данные из всех зарегистрированных источников энтропии.

    Чтобы зарегистрировать источник энтропии, нужно вызвать функцию KosRandomRegisterSrc(). Через параметр callback эта функция принимает указатель на callback-функцию следующего типа:

    typedef Retcode (*KosRandomSeedMethod)(void *context, rtl_size_t size, void *output);

    Эта callback-функция должна, используя параметры context, получить данные размером size байт из источника энтропии и записать их в буфер output. Если функция возвращает rcOk, то считается, что данные из источника энтропии были получены успешно. Источником энтропии может быть, например, оцифрованный сигнал какого-либо датчика или аппаратный генератор случайных чисел.

    Чтобы дерегистрировать источник энтропии, нужно вызвать функцию KosRandomUnregisterSrc().

  2. Выполнена инициализация генератора случайных чисел, если до изменения начального значения генератора случайных чисел с выполнением условия 1 уровень качества был низким.

    Если уровень качества низкий, то сделать его высоким без инициализации генератора случайных чисел нельзя.

    Чтобы инициализировать генератор случайных чисел, нужно вызвать функцию KosRandomInitSeed(). Энтропию данных, передаваемых через параметр seed, должен гарантировать вызывающий процесс.

  3. Счетчик случайных байтовых значений, которые сгенерированы после изменения начального значения генератора случайных чисел с выполнением условия 1, не превышает заданный в системе лимит.
  4. Счетчик времени, которое прошло после изменения начального значения генератора случайных чисел с выполнением условия 1, не превышает заданный в системе лимит.

Если хотя бы одно из этих условий не выполняется, сгенерированные случайные значения считаются низкокачественными.

При запуске процесса начальное значение генератора случайных чисел задается системой автоматически. Затем начальное значение генератора случайных чисел изменяется в следующих случаях:

  • Генерация последовательности случайных значений.

    Каждый успешный вызов функции KosRandomGenerateEx() с параметром size больше нуля и каждый успешный вызов функции KosRandomGenerate() изменяют начальное значение генератора случайных чисел, но не каждое такое изменение выполняется с получением данных из зарегистрированных источников энтропии. Зарегистрированные источники энтропии используются только при нарушении условия 3 или 4. При этом, если зарегистрирован хотя бы один источник энтропии, то сбрасывается счетчик времени изменения начального значения генератора случайных чисел. А если данные из хотя бы одного источника энтропии получены успешно, то также сбрасывается счетчик сгенерированных случайных байтовых значений.

    Уровень качества может измениться с высокого на низкий.

  • Инициализация генератора случайных чисел.

    Каждый успешный вызов функции KosRandomInitSeed() изменяет начальное значение генератора случайных чисел, используя данные, переданные через параметр seed и полученные из зарегистрированных источников энтропии. При наличии хотя бы одного зарегистрированного источника энтропии сбрасываются счетчики сгенерированных случайных байтовых значений и времени изменения начального значения генератора случайных чисел. В противном случае сбрасывается только счетчик сгенерированных случайных байтовых значений.

    Уровень качества может измениться с высокого на низкий и наоборот.

  • Регистрация источника энтропии.

    Каждый успешный вызов функции KosRandomRegisterSrc() изменяет начальное значение генератора случайных чисел, используя данные только из регистрируемого источника энтропии. При этом сбрасывается счетчик сгенерированных случайных байтовых значений.

    Уровень качества не может измениться.

Возможный сценарий генерации случайных значений высокого качества включает следующие шаги:

  1. Зарегистрировать хотя бы один источник энтропии вызовом функции KosRandomRegisterSrc().
  2. Сгенерировать последовательность случайных значений вызовом функции KosRandomGenerateEx().
  3. Проверить уровень качества случайных значений.

    Если уровень качества низкий, инициализировать генератор случайных чисел вызовом функции KosRandomInitSeed() и перейти к шагу 2.

    Если уровень качестве высокий, перейти к шагу 4.

  4. Использовать случайные значения.

Чтобы получить уровень качества без генерации случайных значений, нужно вызвать функцию KosRandomGenerateEx() со значениями 0 и RTL_NULL в параметрах size и output соответственно.

Сведения о функциях API

Функции random_api.h

Функция

Сведения о функции

KosRandomInitSeed()

Назначение

Инициализирует генератор случайных чисел.

Параметры

  • [in] seed – указатель на байтовый массив, который используется, чтобы изменить начальное значение генератора случайных чисел. Массив должен иметь размер 32 байта.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRandomGenerate()

Назначение

Генерирует последовательность случайных байтовых значений.

Параметры

  • [in] size – размер буфера для сохранения последовательности (в байтах).
  • [out] output – указатель на буфер для сохранения последовательности.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRandomGenerateEx()

Назначение

Генерирует последовательность случайных байтовых значений.

Параметры

  • [in] size – размер буфера для сохранения последовательности (в байтах).
  • [out] output – указатель на буфер для сохранения последовательности.
  • [out] quality – указатель на булевое значение, которое истинно, если сгенерированные случайные значения имеют высокое качество, и ложно, если сгенерированные случайные значения имеют низкое качество.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRandomRegisterSrc()

Назначение

Регистрирует источник энтропии.

Параметры

  • [in] callback – указатель на функцию, которая позволяет получить данные из источника энтропии для изменения начального значения генератора случайных чисел.
  • [in,optional] context – указатель на параметры, передаваемые функции, заданной через параметр callback, или RTL_NULL, если параметров нет.
  • [in] size – размер данных (в байтах), которые нужно получить из источника энтропии при вызове функции, заданной через параметр callback. Должен быть не менее 32 байт.
  • [out] handle – адрес указателя, используемого для дерегистрации источника энтропии.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRandomUnregisterSrc()

Назначение

Дерегистрирует источник энтропии.

Параметры

  • [in] handle – указатель, который получен при регистрации источника энтропии.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_random_api]

Получение и изменение значений времени (time_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/time/time_api.h из состава KasperskyOS SDK.

Основные возможности API:

  • получать и изменять системное время;
  • получать монотонное время, отсчитанное с момента запуска ядра KasperskyOS;
  • получать разрешение источников системного и монотонного времени.

Сведения о функциях API приведены в таблице ниже.

Функции time_api.h

Функция

Сведения о функции

KnGetSystemTimeRes()

Назначение

Позволяет получить разрешение источника системного времени.

Параметры

  • [out] res – указатель на структуру, содержащую в поле nsec разрешение источника системного времени в наносекундах. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/rtc.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnSetSystemTime()

Назначение

Задает системное время.

Параметры

  • [in] time – указатель на структуру, содержащую следующие сведения: в поле sec – число секунд, прошедших с 1 января 1970 года; в поле nsec – число наносекунд, прошедших с момента, заданного в поле sec. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/rtc.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnGetSystemTime()

Назначение

Позволяет получить системное время.

Параметры

  • [out] time – указатель на структуру, содержащую следующие сведения: в поле sec – число секунд, прошедших с 1 января 1970 года; в поле nsec – число наносекунд, прошедших с момента, заданного в поле sec. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/rtc.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnGetUpTimeRes()

Назначение

Позволяет получить разрешение источника монотонного времени, отсчитываемого с момента запуска ядра KasperskyOS.

Параметры

  • [out] res – указатель на структуру, содержащую в поле nsec разрешение источника монотонного времени, отсчитываемого с момента запуска ядра KasperskyOS, в наносекундах. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/rtc.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnGetUpTime()

Назначение

Позволяет получить монотонное время, отсчитанное с момента запуска ядра KasperskyOS.

Параметры

  • [out] time – указатель на структуру, содержащую следующие сведения: в поле sec – число секунд, прошедших с момента запуска ядра KasperskyOS; в поле nsec – число наносекунд, прошедших с момента, заданного в поле sec. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/rtc.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnGetRtcTime()

Назначение

Позволяет получить системное время.

Параметры

  • [out] rt – указатель на структуру, содержащую следующие сведения о времени: год, месяц, день, часы, минуты, секунды, миллисекунды. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/rtc.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnGetMSecSinceStart()

Назначение

Позволяет получить монотонное время, отсчитанное с момента запуска ядра KasperskyOS.

Параметры

Нет.

Возвращаемые значения

Монотонное время, отсчитанное с момента запуска ядра KasperskyOS, в миллисекундах.

KnAdjSystemTime()

Назначение

Запускает постепенную корректировку системного времени.

Параметры

  • [in] adj – указатель на структуру, содержащую интервал времени, на который нужно скорректировать системное время (sec*10^9+nsec наносекунд) или RTL_NULL, если не требуется запускать корректировку, а нужно только получить сведения о ранее запущенной корректировке (через параметр prev). Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/rtc.h из состава KasperskyOS SDK.
  • [in] slew – скорость корректировки системного времени (микросекунд в секунду).
  • [out] prev – указатель на структуру, содержащую интервал времени, отражающий, на какое значение оставалось (или остается в случае указания RTL_NULL в параметре adj) скорректировать системное время, чтобы уже запущенная постепенная корректировка была полностью завершена (sec*10^9+nsec наносекунд). Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/rtc.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Если запустить новую корректировку до завершения ранее запущенной, то ранее запущенная будет прервана.

В начало
[Topic libkos_time_api]

Использование уведомлений (notice_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/handle/notice_api.h из состава KasperskyOS SDK.

API позволяет отслеживать события, которые связаны с ресурсами (как системными, так и пользовательскими), а также уведомлять о событиях, связанных с пользовательскими ресурсами, другие процессы и потоки исполнения.

Сведения о функциях API приведены в таблице ниже.

Использование API

Механизм уведомлений использует маску событий. Маска событий – значение, биты которого интерпретируются как события, которые должны отслеживаться или уже произошли. Маска событий имеет размер 32 бита и состоит из общей и специальной части. Общая часть описывает события, неспецифичные для любых ресурсов. Специальная часть описывает события, специфичные для ресурсов. Флаги специальной части для системных ресурсов и флаги общей части определены в заголовочном файле sysroot-*-kos/include/handle/event_descr.h из состава KasperskyOS SDK. (Например, флаг общей части EVENT_OBJECT_DESTROYED означает прекращение существования ресурса, а флаг специальной части EVENT_TASK_COMPLETED означает завершение процесса.) Флаги специальной части для пользовательского ресурса определяются поставщиком этого ресурса с использованием макросов OBJECT_EVENT_SPEC() и OBJECT_EVENT_USER(), которые определены в заголовочном файле sysroot-*-kos/include/handle/event_descr.h из состава KasperskyOS SDK. Поставщику ресурса необходимо экспортировать публичные заголовочные файлы с описанием флагов специальной части.

Типовой сценарий получения уведомлений о событиях, связанных с ресурсами, включает следующие шаги:

  1. Создание приемника уведомлений (объекта ядра KasperskyOS, в котором накапливаются уведомления) вызовом функции KnNoticeCreate().

    Идентификатор приемника уведомлений является указателем на объектом KosObject, который содержит дескриптор приемника уведомлений (об объектах KosObject см. "Использование объектов KosObject (objects.h)"). Уничтожение этого объекта приводит к уничтожению приемника уведомлений. Если требуется создать копию идентификатора приемника уведомлений (например, для использования в другом потоке исполнения), нужно инкрементировать счетчик ссылок на объект KosObject вызовом функции KosRefObject(), чтобы обеспечить существование этого объекта на время существования созданной копии идентификатора. Если копия идентификатора приемника уведомлений больше требуется, нужно декрементировать счетчик ссылок на объект KosObject вызовом функции KosPutObject(), чтобы обеспечить уничтожение этого объекта при отсутствии других ссылок.

  2. Добавление в приемник уведомлений записей вида "ресурс – маска событий", чтобы настроить его на получение уведомлений о событиях, которые связаны с интересующими ресурсами.

    Чтобы добавить запись вида "ресурс – маска событий" в приемник уведомлений, нужно вызвать функцию KnNoticeSubscribeToObject(). (В маске прав дескриптора ресурса, указанного в параметре object, должен быть флаг OCAP_HANDLE_GET_EVENT.) Для одного и того же ресурса можно добавить несколько записей вида "ресурс – маска событий", при этом не требуется, чтобы идентификаторы этих записей были уникальными. Отслеживаемые события для каждой записи вида "ресурс – маска событий" нужно задать маской событий, которая может соответствовать одному или нескольким событиям.

    Добавленные в приемник уведомлений записи вида "ресурс – маска событий" можно полностью или частично удалить, чтобы этот приемник не получал уведомления, соответствующие этим записям. Чтобы удалить из приемника уведомлений все записи вида "ресурс – маска событий", нужно вызвать функцию KnNoticeDropAndWake(). Чтобы удалить из приемника уведомлений записи вида "ресурс – маска событий", относящиеся к одному ресурсу, нужно вызвать функцию KnNoticeUnsubscribeFromObject(). Чтобы удалить из приемника уведомлений записи вида "ресурс – маска событий" с конкретным идентификатором, нужно вызвать функцию KnNoticeUnsubscribeFromEvent().

    Записи вида "ресурс – маска событий" можно добавлять в приемник уведомлений и удалять из него на протяжении всего времени жизни этого приемника уведомлений.

  3. Извлечение уведомлений из приемника с использованием функции KnNoticeGetEvent() или KnNoticeGetEventEx().

    При вызове функции KnNoticeGetEvent() или KnNoticeGetEventEx() можно задать время ожидания появления уведомлений в приемнике. Потоки, заблокированные в ожидании появления уведомлений в приемнике, возобновляют свое исполнение при появлении уведомлений, даже если эти уведомления соответствуют записям вида "ресурс – маска событий", добавленным в приемник во время ожидания.

    Потоки, заблокированные в ожидании появления уведомлений в приемнике, возобновляют свое исполнение и не будут заблокированы при последующих вызовах функции KnNoticeGetEvent() или KnNoticeGetEventEx(), если из этого приемника удалены все записи вида "ресурс – маска событий" вызовом функции KnNoticeDropAndWake(). Если после вызова функции KnNoticeDropAndWake() добавить в приемник уведомлений хотя бы одну запись вида "ресурс – маска событий", то потоки исполнения, получающие уведомления из этого приемника, будут снова заблокированы при вызове функции KnNoticeGetEvent() или KnNoticeGetEventEx() на заданное время ожидания при отсутствии уведомлений. Если все записи вида "ресурс – маска событий" удалены из приемника уведомлений с использованием функции KnNoticeUnsubscribeFromObject() и/или функции KnNoticeUnsubscribeFromEvent(), то исполнение потоков, ожидающих появления уведомлений в этом приемнике, не будет возобновлено до истечения времени ожидания, а также будет заблокировано на время ожидания при последующих вызовах функции KnNoticeGetEvent() или KnNoticeGetEventEx().

  4. Завершение работы с приемником уведомлений вызовом функции KnNoticeRelease().

    Функция KnNoticeRelease() удаляет из приемника уведомлений все записи вида "ресурс – маска событий" и делает невозможным добавление новых. При этом потоки, заблокированные в ожидании появления уведомлений в приемнике, возобновляют свое исполнение и не будут заблокированы при последующих вызовах функции KnNoticeGetEvent() или KnNoticeGetEventEx(). Кроме того, функция KnNoticeRelease() декрементирует счетчик ссылок на объект KosObject, содержащий дескриптор приемника уведомлений. При отсутствии других ссылок на этот объект приемник уведомлений будет уничтожен. Иначе приемник уведомлений будет существовать до удаления остальных ссылок.

Чтобы уведомить другие процессы и/или потоки исполнения о событиях, которые связаны с пользовательским ресурсом, нужно вызвать функцию KnNoticeSetObjectEvent(). В результате вызова этой функции появляются уведомления в приемниках, настроенных на получение уведомлений о событиях, заданных через параметр evMask, которые связаны с пользовательским ресурсом, заданным через параметр object. В параметре evMask нельзя указывать флаги общей части маски событий, так как о событиях, соответствующих общей части маски событий, может сигнализировать только ядро. Если процесс, вызывающий функцию KnNoticeSetObjectEvent(), создал дескриптор пользовательского ресурса, указанный в параметре object, то в параметре evMask можно указать флаги, которые определены макросами OBJECT_EVENT_SPEC() и OBJECT_EVENT_USER(). Если процесс, вызывающий функцию KnNoticeSetObjectEvent(), получил от другого процесса дескриптор пользовательского ресурса, указанный в параметре object, то в параметре evMask можно указать только те флаги, которые определены макросом OBJECT_EVENT_USER(), при этом в маске прав полученного дескриптора должен быть флаг OCAP_HANDLE_SET_EVENT.

Сведения о функциях API

Функции notice_api.h

Функция

Сведения о функции

KnNoticeCreate()

Назначение

Создает приемник уведомлений.

Параметры

  • [out] notice – указатель на идентификатор приемника уведомлений.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnNoticeSubscribeToObject()

Назначение

Добавляет запись вида "ресурс – маска событий" в приемник уведомлений, чтобы он получал уведомления о событиях, которые связаны с заданным ресурсом и соответствуют заданной маске событий.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] object – дескриптор ресурса.
  • [in] evMask – маска событий.
  • [in] evId – идентификатор записи вида "ресурс – маска событий".

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnNoticeGetEvent()

Назначение

Извлекает уведомления из приемника.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] msec – время ожидания появления уведомлений в приемнике в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [in] countMax – максимальное число уведомлений, извлекаемое за один вызов функции.
  • [out] events – указатель на набор уведомлений, которые представляют собой структуры, содержащие идентификатор записи вида "ресурс – маска событий" и маску событий, связанных с ресурсом.
  • [out] count – число извлеченных уведомлений.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если время ожидания появления уведомлений в приемники истекло, возвращает rcTimeout.

Если все записи вида "ресурс – маска событий" удалены из приемника уведомлений вызовом функции KnNoticeRelease() или KnNoticeDropAndWake(), возвращает rcResourceNotFound.

KnNoticeGetEventEx()

Назначение

Извлекает уведомления из приемника.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] msec – время ожидания появления уведомлений в приемнике в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [in] countMax – максимальное число уведомлений, извлекаемое за один вызов функции.
  • [out] events – указатель на набор уведомлений, которые представляют собой структуры, содержащие идентификатор записи вида "ресурс – маска событий", маску и счетчик событий, связанных с ресурсом.
  • [out] count – число извлеченных уведомлений.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если время ожидания появления уведомлений в приемники истекло, возвращает rcTimeout.

Если все записи вида "ресурс – маска событий" удалены из приемника уведомлений вызовом функции KnNoticeRelease() или KnNoticeDropAndWake(), возвращает rcResourceNotFound.

KnNoticeUnsubscribeFromObject()

Назначение

Удаляет записи вида "ресурс – маска событий", соответствующие заданному ресурсу, из приемника уведомлений, чтобы он не получал уведомления о событиях, соответствующих этим записям.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] object – дескриптор ресурса.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Уведомления, соответствующие удаленным записям вида "ресурс – маска событий", будут удалены из приемника.

KnNoticeUnsubscribeFromEvent()

Назначение

Удаляет записи вида "ресурс – маска событий" с заданным идентификатором из приемника уведомлений, чтобы он не получал уведомления о событиях, соответствующих этим записям.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] evId – идентификатор записи вида "ресурс – маска событий".

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Уведомления, соответствующие удаленным записям вида "ресурс – маска событий", будут удалены из приемника.

KnNoticeDropAndWake()

Назначение

Удаляет все записи вида "ресурс – маска событий" из заданного приемника уведомлений и возобновляет исполнение всех потоков, ожидающих появления уведомлений в заданном приемнике.

Параметры

  • [in] notice – идентификатор приемника уведомлений.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnNoticeRelease()

Назначение

Удаляет все записи вида "ресурс – маска событий" из заданного приемника уведомлений и делает невозможным добавление новых, возобновляет исполнение всех потоков, ожидающих появления уведомлений в заданном приемнике, декрементирует счетчик ссылок на объект KosObject, содержащий дескриптор заданного приемника уведомлений.

Параметры

  • [in] notice – идентификатор приемника уведомлений.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnNoticeSetObjectEvent()

Назначение

Сигнализирует, что произошли события, которые связаны с заданным пользовательским ресурсом и соответствуют заданной маске событий.

Параметры

  • [in] object – дескриптор пользовательского ресурса.
  • [in] evMask – маска событий, о которых требуется сигнализировать.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_notice_api]

Динамическое создание IPC-каналов (cm_api.h, ns_api.h)

API определены в следующих заголовочных файлах из состава KasperskyOS SDK:

  • sysroot-*-kos/include/coresrv/cm/cm_api.h;
  • sysroot-*-kos/include/coresrv/ns/ns_api.h.

API позволяют динамически создавать IPC-каналы.

Сведения о функциях API приведены в таблицах ниже.

Использование API

Чтобы серверы могли сообщать клиентам о предоставляемых службах, нужно включить в решение сервер имен, то есть системную программу NameServer (исполняемый файл sysroot-*-kos/bin/ns из состава KasperskyOS SDK). IPC-каналы от клиентов и серверов к серверу имен можно создать статически (эти IPC-каналы должны иметь имя kl.core.NameServer). Если этого не сделать, то при вызове клиентами и серверами функции NsCreate() будут выполнены попытки динамического создания этих IPC-каналов. Сервер имен не требуется включать в решение, если у клиентов изначально есть сведения об именах серверов и предоставляемых этими серверами служб.

Имена служб и интерфейсов нужно задавать в соответствии с формальными спецификациями компонентов решения. (О квалифицированном имени службы см. "Привязка методов моделей безопасности к событиям безопасности".) Вместо квалифицированного имени службы можно использовать какое-либо условное название этой службы. Имена клиентов и серверов задаются в init-описании. Также имя процесса можно получить вызовом функции KnTaskGetName() из API task_api.h.

Динамическое создание IPC-канала на стороне сервера включает следующие шаги:

  1. Подключиться к серверу имен вызовом функции NsCreate().
  2. Опубликовать предоставляемые службы на сервере имен, используя функцию NsPublishService().

    Чтобы отменить публикацию службы, нужно вызвать функцию NsUnPublishService().

  3. Получить запрос клиента на создание IPC-канала вызовом функции KnCmListen().

    Функция KnCmListen() позволяет получить первый запрос в очереди, но при этом не удаляет этот запрос, а помещает в конец очереди. Если в очереди всего один запрос, то вызов функции KnCmListen() несколько раз подряд дает один и тот же результат. Запрос удаляется из очереди при вызове функции KnCmAccept() или KnCmDrop().

  4. Принять запрос клиента на создание IPC-канала вызовом функции KnCmAccept().

    Чтобы отклонить запрос клиента, нужно вызвать функцию KnCmDrop().

    Слушающий дескриптор создается при вызове функции KnCmAccept() со значением INVALID_HANDLE в параметре listener. Если указать слушающий дескриптор, то созданный серверный IPC-дескриптор обеспечит возможность получать IPC-запросы по всем IPC-каналам, ассоциированным с этим слушающим дескриптором. (Первый IPC-канал, ассоциированный со слушающим дескриптором, создается при вызове функции KnCmAccept() со значением INVALID_HANDLE в параметре listener. Второй и последующие IPC-каналы, ассоциированные со слушающим дескриптором, создаются при втором и последующих вызовах функции KnCmAccept() с указанием дескриптора, полученного при первом вызове.) В параметре listener функции KnCmAccept() можно указать слушающий дескриптор, полученный с использованием функций KnHandleConnect(), KnHandleConnectEx() и KnHandleCreateListener() из API handle_api.h, а также функции ServiceLocatorRegister(), объявленной в заголовочном файле sysroot-*-kos/include/coresrv/sl/sl_api.h из состава KasperskyOS SDK. В параметре rsid функции KnCmAccept() нужно указать идентификатор службы (RIID), который является константой в автоматически генерируемом транспортном коде (например, FsDriver_operationsComp_fileOperations_iid).

Динамическое создание IPC-канала на стороне клиента включает следующие шаги:

  1. Подключиться к серверу имен вызовом функции NsCreate().
  2. Найти сервер, предоставляющий требуемую службу, используя функцию NsEnumServices().

    Чтобы получить полный список служб с заданным интерфейсом, нужно вызвать функцию несколько раз, инкрементируя индекс, пока не будет получена ошибка rcResourceNotFound.

  3. Выполнить запрос на создание IPC-канала с требуемым сервером вызовом функции KnCmConnect().

К серверу имен можно подключить несколько клиентов и серверов. Каждый клиент и сервер может создать несколько подключений к серверу имен. Сервер может отменить публикацию службы, выполненную другим сервером.

Чтобы удалить подключение к серверу имен, нужно вызвать функцию NsDestroy().

Удаление динамически созданных IPC-каналов

Динамически созданный IPC-канал будет удален при закрытии его клиентского и серверного IPC-дескрипторов.

Сведения о функциях API

Функции ns_api.h

Функция

Сведения о функции

NsCreate()

Назначение

Создает подключение к серверу имен.

Параметры

  • [in,optional] name – указатель на имя процесса сервера имен или RTL_NULL, чтобы задать имя по умолчанию (соответствует значению макроса NS_SERVER_NAME).
  • [in] msecs – время ожидания создания подключения к серверу имен в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [out] ns – указатель на идентификатор подключения к серверу имен.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

NsDestroy()

Назначение

Удаляет подключение к серверу имен.

Параметры

  • [in] ns – идентификатор подключения к серверу имен.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

NsPublishService()

Назначение

Публикует службу на сервере имен.

Параметры

  • [in] ns – идентификатор подключения к серверу имен.
  • [in] type – указатель на имя интерфейса службы.
  • [in,optional] server – указатель на имя сервера, предоставляющего службу, или RTL_NULL, чтобы использовать имя вызывающего процесса.
  • [in] service – указатель на квалифицированное имя службы.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

NsUnPublishService()

Назначение

Отменяет публикацию службы на сервере имен.

Параметры

  • [in] ns – идентификатор подключения к серверу имен.
  • [in] type – указатель на имя интерфейса службы.
  • [in,optional] server – указатель на имя сервера, предоставляющего службу, или RTL_NULL, чтобы использовать имя вызывающего процесса.
  • [in] service – указатель на квалифицированное имя службы.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

NsEnumServices()

Назначение

Перечисляет службы, опубликованные на сервере имен.

Параметры

  • [in] ns – идентификатор подключения к серверу имен.
  • [in] type – указатель на имя интерфейса служб.
  • [in] index – индекс для перечисления служб. Нумерация начинается с нуля.
  • [out] server – указатель на буфер для имени сервера, предоставляющего службу.
  • [in] serverSize – размер буфера для имени сервера, предоставляющего службу, в байтах.
  • [out] service – указатель на буфер для квалифицированного имени службы.
  • [in] serviceSize – размер буфера для квалифицированного имени службы в байтах.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Функции cm_api.h

Функция

Сведения о функции

KnCmConnect()

Назначение

Выполняет запрос на создание IPC-канала с сервером для использования заданной службы.

Параметры

  • [in] server – указатель на имя сервера.
  • [in] service – указатель на квалифицированное имя службы.
  • [in] msecs – время ожидания выполнения запроса в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [out] handle – указатель на клиентский IPC-дескриптор.
  • [out] rsid – указатель на идентификатор службы (RIID).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnCmListen()

Назначение

Позволяет получить запрос клиента на создание IPC-канала для использования службы.

Параметры

  • [in] filter – фиктивный параметр, который должен иметь значение RTL_NULL.
  • [in] msecs – время ожидания появления запроса клиента в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [out] client – указатель на имя клиента.
  • [out] service – указатель на квалифицированное имя службы.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnCmDrop()

Назначение

Отклоняет запрос клиента на создание IPC-канала для использования заданной службы.

Параметры

  • [in] client – указатель на имя клиента.
  • [in] service – указатель на квалифицированное имя службы.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnCmAccept()

Назначение

Принимает запрос клиента на создание IPC-канала для использования заданной службы.

Параметры

  • [in] client – указатель на имя клиента.
  • [in] service – указатель на квалифицированное имя службы.
  • [in] rsid – идентификатор службы (RIID).
  • [in,optional] listener – слушающий дескриптор или INVALID_HANDLE, чтобы создать его.
  • [out] handle – указатель на серверный IPC-дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_cm_ns_api]

Использование примитивов синхронизации (event.h, mutex.h, rwlock.h, semaphore.h, condvar.h)

Библиотека libkos предоставляет API, позволяющие использовать следующие примитивы синхронизации:

  • события (event.h);
  • мьютексы (mutex.h);
  • блокировки чтения-записи (rwlock.h);
  • семафоры (semaphore.h);
  • условные переменные (condvar.h).

Заголовочные файлы находятся в KasperskyOS SDK по пути sysroot-*-kos/include/kos.

API предназначены для синхронизации потоков исполнения, принадлежащих одному и тому же процессу.

События

Событие – примитив синхронизации, который используется для уведомления одного или нескольких потоков исполнения о выполнении требуемого этим потокам условия. Уведомляемый поток исполнения ожидает, когда событие перейдет из несигнального состояния в сигнальное, а уведомляющий поток исполнения изменяет состояние этого события.

Типовой сценарий использования API для работы с событиями включает следующие шаги:

  1. Инициализация события вызовом функции KosEventInit().
  2. Использование события потоками исполнения:
    • Ожидание перехода события из несигнального состояния в сигнальное вызовом функции KosEventWait() или KosEventWaitTimeout() (на стороне уведомляемых потоков исполнения).
    • Изменение состояния события вызовами функций KosEventSet() и KosEventReset() (на стороне уведомляющих потоков исполнения).

Сведения о функциях API для работы с событиями приведены в таблице ниже.

Функции event.h

Функция

Сведения о функции

KosEventInit()

Назначение

Инициализирует событие.

После инициализации событие находится в несигнальном состоянии.

Параметры

  • [out] event – указатель на событие. Тип события определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosEventSet()

Назначение

Устанавливает событие в сигнальное состояние.

Параметры

  • [out] event – указатель на событие. Тип события определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosEventReset()

Назначение

Устанавливает событие в несигнальное состояние.

Параметры

  • [out] event – указатель на событие. Тип события определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosEventWait()

Назначение

Ожидает перехода события из несигнального состояния в сигнальное сколь угодно долго.

Параметры

  • [in,out] event – указатель на событие. Тип события определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in] reset – значение, которое задает, нужно ли установить событие в несигнальное состояние после завершения ожидания (rtl_true – да, rtl_false – нет). Тип параметра определен в заголовочном файле sysroot-*-kos/include/rtl/stdbool.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosEventWaitTimeout()

Назначение

Ожидает перехода события из несигнального состояния в сигнальное не дольше заданного времени.

Параметры

  • [in,out] event – указатель на событие. Тип события определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in] reset – значение, которое задает, нужно ли установить событие в несигнальное состояние после завершения ожидания (rtl_true – да, rtl_false – нет). Тип параметра определен в заголовочном файле sysroot-*-kos/include/rtl/stdbool.h из состава KasperskyOS SDK.
  • [in] mdelay – время ожидания в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если время ожидания истекло, возвращает rcTimeout.

Мьютексы

Мьютекс – примитив синхронизации, который обеспечивает взаимоисключающее исполнение критических секций (участков кода, в которых осуществляется обращение к разделяемым между потоками исполнения ресурсам). Один поток захватывает мьютекс и исполняет критическую секцию, а другие потоки, чтобы исполнить критические секции, пытаются захватить этот мьютекс, ожидая его освобождения. Мьютекс может быть освобожден только тем потоком исполнения, которым он захвачен. Можно использовать рекурсивный мьютекс, который может быть захвачен одним потоком исполнения несколько раз.

Типовой сценарий использования API для работы с мьютексами включает следующие шаги:

  1. Инициализация мьютекса вызовом функции KosMutexInit() или KosMutexInitEx().
  2. Использование мьютекса потоками исполнения:
    1. Захват мьютекса вызовом функции KosMutexTryLock(), KosMutexLock() или KosMutexLockTimeout().
    2. Освобождение мьютекса вызовом функции KosMutexUnlock().

Сведения о функциях API для работы с мьютексами приведены в таблице ниже.

Функции mutex.h

Функция

Сведения о функции

KosMutexInit()

Назначение

Инициализирует мьютекс, который не является рекурсивным.

Параметры

  • [out] mutex – указатель на мьютекс. Тип мьютекса определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosMutexInitEx()

Назначение

Инициализирует мьютекс.

Параметры

  • [out] mutex – указатель на мьютекс. Тип мьютекса определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in] recursive – значение, которое задает, должен ли мьютекс быть рекурсивным (1 – да, 0 – нет).

Возвращаемые значения

Нет.

KosMutexTryLock()

Назначение

Захватывает мьютекс.

Если мьютекс уже захвачен, не ожидает его освобождения, а возвращает управление.

Параметры

  • [in,out] mutex – указатель на мьютекс. Тип мьютекса определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если мьютекс уже захвачен, возвращает rcBusy.

KosMutexLock()

Назначение

Захватывает мьютекс.

Если мьютекс уже захвачен, ожидает его освобождения сколь угодно долго.

Параметры

  • [in,out] mutex – указатель на мьютекс. Тип мьютекса определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosMutexUnlock()

Назначение

Освобождает мьютекс.

Параметры

  • [in,out] mutex – указатель на мьютекс. Тип мьютекса определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosMutexLockTimeout()

Назначение

Захватывает мьютекс.

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

Параметры

  • [in,out] mutex – указатель на мьютекс. Тип мьютекса определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in] mdelay – время ожидания в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если время ожидания истекло, возвращает rcTimeout.

Блокировки чтения-записи

Блокировка чтения-записи – примитив синхронизации, который используется, чтобы разрешить доступ к разделяемым между потоками исполнения ресурсам либо на запись для одного потока исполнения, либо на чтение для нескольких потоков исполнения одновременно.

Типовой сценарий использования API для работы с блокировками чтения-записи включает следующие шаги:

  1. Инициализация блокировки чтения-записи вызовом функции KosRWLockInit().
  2. Использование блокировки чтения-записи потоками исполнения:
    1. Захват блокировки чтения-записи для записи (вызовом функции KosRWLockWrite() или KosRWLockTryWrite()) или для чтения (вызовом функции KosRWLockRead() или KosRWLockTryRead()).
    2. Освобождение блокировки-чтения вызовом функции KosRWLockUnlock().

Сведения о функциях API для работы с блокировками чтения-записи приведены в таблице ниже.

Функции rwlock.h

Функция

Сведения о функции

KosRWLockInit()

Назначение

Инициализирует блокировку чтения-записи.

Параметры

  • [out] rwlock – указатель на блокировку чтения-записи. Тип блокировки чтения-записи определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosRWLockRead()

Назначение

Захватывает блокировку чтения-записи для чтения.

Если блокировка чтения-записи уже захвачена для записи, или есть потоки исполнения, ожидающие захвата этой блокировки чтения-записи для записи, то ожидает освобождения этой блокировки чтения-записи от захвата для записи сколь угодно долго.

Параметры

  • [in,out] rwlock – указатель на блокировку чтения-записи. Тип блокировки чтения-записи определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosRWLockTryRead()

Назначение

Захватывает блокировку чтения-записи для чтения.

Если блокировка чтения-записи уже захвачена для записи, или есть потоки исполнения, ожидающие захвата этой блокировки чтения-записи для записи, то не ожидает освобождения этой блокировки чтения-записи от захвата для записи, а возвращает управление.

Параметры

  • [in,out] rwlock – указатель на блокировку чтения-записи. Тип блокировки чтения-записи определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRWLockWrite()

Назначение

Захватывает блокировку чтения-записи для записи.

Если блокировка чтения-записи уже захвачена для записи или чтения, ожидает освобождения этой блокировки чтения-записи сколь угодно долго.

Параметры

  • [in,out] rwlock – указатель на блокировку чтения-записи. Тип блокировки чтения-записи определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosRWLockTryWrite()

Назначение

Захватывает блокировку чтения-записи для записи.

Если блокировка чтения-записи уже захвачена для записи или чтения, не ожидает освобождения этой блокировки чтения-записи, а возвращает управление.

Параметры

  • [in,out] rwlock – указатель на блокировку чтения-записи. Тип блокировки чтения-записи определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRWLockUnlock()

Назначение

Освобождает блокировку чтения-записи.

Параметры

  • [in,out] rwlock – указатель на блокировку чтения-записи. Тип блокировки чтения-записи определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

Дополнительные сведения

Если блокировка чтения-записи захвачена для чтения, то эта блокировка чтения-записи остается захваченной для чтения, пока все потоки исполнения, выполняющие чтение, не освободят ее.

Семафоры

Семафор – примитив синхронизации, основанный на счетчике, значение которого может быть атомарно изменено. Значение счетчика обычно отражает число доступных разделяемых между потоками исполнения ресурсов. Для исполнения критической секции поток ожидает, пока значение счетчика не станет больше нуля. Если значение счетчика больше нуля, то оно уменьшается на единицу, и поток исполняет критическую секцию. После исполнения критической секции поток исполнения сигнализирует семафор, в результате чего значение счетчика увеличивается.

Типовой сценарий использования API для работы с семафорами включает следующие шаги:

  1. Инициализация семафора вызовом функции KosSemaphoreInit().
  2. Использование семафора потоками исполнения:
    1. Ожидание семафора вызовом функции KosSemaphoreWait(), KosSemaphoreWaitTimeout() или KosSemaphoreTryWait().
    2. Сигнализация семафора вызовом функции KosSemaphoreSignal() или KosSemaphoreSignalN().
  3. Освобождение ресурсов семафора вызовом функции KosSemaphoreDeinit().

Сведения о функциях API для работы с семафорами приведены в таблице ниже.

Функции semaphore.h

Функция

Сведения о функции

KosSemaphoreInit()

Назначение

Инициализирует семафор.

Параметры

  • [out] semaphore – указатель на семафор. Тип семафора определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in] count – значение счетчика.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если значение в параметре count превышает константу KOS_SEMAPHORE_VALUE_MAX, возвращает rcInvalidArgument. (Константа KOS_SEMAPHORE_VALUE_MAX определена в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.)

KosSemaphoreDeinit()

Назначение

Освобождает ресурсы семафора.

Параметры

  • [in] semaphore – указатель на семафор. Тип семафора определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если есть потоки исполнения, ожидающие семафор, возвращает rcBusy.

KosSemaphoreSignal()

Назначение

Сигнализирует семафор с увеличением счетчика на единицу.

Параметры

  • [in,out] semaphore – указатель на семафор. Тип семафора определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSemaphoreSignalN()

Назначение

Сигнализирует семафор с увеличением счетчика на заданное число.

Параметры

  • [in,out] semaphore – указатель на семафор. Тип семафора определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in] n – натуральное число, на которое нужно увеличить счетчик.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSemaphoreWaitTimeout()

Назначение

Ожидает семафор не дольше заданного времени.

Параметры

  • [in,out] semaphore – указатель на семафор. Тип семафора определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in] mdelay – время ожидания семафора в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если время ожидания истекло, возвращает rcTimeout.

KosSemaphoreWait()

Назначение

Ожидает семафор сколь угодно долго.

Параметры

  • [in,out] semaphore – указатель на семафор. Тип семафора определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSemaphoreTryWait()

Назначение

Ожидает семафор.

Если счетчик семафора имеет нулевое значение, не ожидает увеличения счетчика этого семафора, а возвращает управление.

Параметры

  • [in,out] semaphore – указатель на семафор. Тип семафора определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если счетчик семафора имеет нулевое значение, возвращает rcBusy.

Условные переменные

Условная переменная – примитив синхронизации, который используется для уведомления одного или нескольких потоков исполнения о выполнении требуемого этим потокам условия. Условная переменная используется совместно с мьютексом. Уведомляющий и уведомляемый потоки захватывают мьютекс для исполнения критических секций. Уведомляемый поток при исполнении критической секции проверяет, выполняется ли требуемое ему условие (например, подготовлены ли данные уведомляющим потоком). Если условие выполняется, то уведомляемый поток исполняет критическую секцию и освобождает мьютекс. Если условие не выполняется, то уведомляемый поток блокируется на условной переменной, ожидая выполнения условия. При этом мьютекс автоматически освобождается. Уведомляющий поток при исполнении критической секции проверяет, выполняется ли условие, требуемое уведомляемому потоку. Если условие выполняется, то уведомляющий поток сигнализирует об этом через условную переменную и освобождает мьютекс. Уведомляемый поток, заблокированный в ожидании выполнения требуемого ему условия, возобновляет исполнение критической секции, автоматически захватывая мьютекс. После исполнения критической секции уведомляемый поток освобождает мьютекс.

Типовой сценарий использования API для работы с условными переменными включает следующие шаги:

  1. Инициализация условной переменной и мьютекса.

    Чтобы инициализировать условную переменную, нужно вызвать функцию KosCondvarInit().

  2. Использование условной переменной и мьютекса потоками исполнения.

Использование условной переменной и мьютекса на стороне уведомляемых потоков исполнения включает следующие шаги:

  1. Захват мьютекса.
  2. Проверка выполнения условия.
  3. Ожидание выполнения условия вызовом функции KosCondvarWait() или KosCondvarWaitTimeout().

    После возврата функции KosCondvarWait() или KosCondvarWaitTimeout() обычно нужно снова проверить, что условие выполняется, так как другой уведомляемый поток исполнения также получил сигнал и мог сделать условие снова недействительным. (Например, другой поток мог извлечь данные, подготовленные уведомляющим потоком). Для этого нужно использовать следующую конструкцию:

    while(<условие>) <вызов KosCondvarWait() или KosCondvarWaitTimeout()>
  4. Освобождение мьютекса.

Использование условной переменной и мьютекса на стороне уведомляющих потоков исполнения включает следующие шаги:

  1. Захват мьютекса.
  2. Проверка выполнения условия.
  3. Сигнализация о выполнении условия вызовом функции KosCondvarSignal() или KosCondvarBroadcast().
  4. Освобождение мьютекса.

Сведения о функциях API для работы с условными переменными приведены в таблице ниже.

Функции condvar.h

Функция

Сведения о функции

KosCondvarInit()

Назначение

Инициализирует условную переменную.

Параметры

  • [out] condvar – указатель на условную переменную. Тип условной переменной определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosCondvarWaitTimeout()

Назначение

Ожидает выполнения условия не дольше заданного времени.

Параметры

  • [in] condvar – указатель на условную переменную. Тип условной переменной определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in,out] mutex – указатель на мьютекс. Тип мьютекса определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in] mdelay – время ожидания выполнения условия в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.

Возвращаемые значения

В случае успеха возвращает rcOk.

Если время ожидания истекло, возвращает rcTimeout.

KosCondvarWait()

Назначение

Ожидает выполнения условия сколь угодно долго.

Параметры

  • [in] condvar – указатель на условную переменную. Тип условной переменной определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.
  • [in,out] mutex – указатель на мьютекс. Тип мьютекса определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosCondvarSignal()

Назначение

Сигнализирует о выполнении условия одному из потоков исполнения, ожидающих выполнения этого условия.

Параметры

  • [in,out] condvar – указатель на условную переменную. Тип условной переменной определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

KosCondvarBroadcast()

Назначение

Сигнализирует о выполнении условия всем потокам исполнения, ожидающим выполнения этого условия.

Параметры

  • [in,out] condvar – указатель на условную переменную. Тип условной переменной определен в заголовочном файле sysroot-*-kos/include/kos/sync_types.h из состава KasperskyOS SDK.

Возвращаемые значения

Нет.

В начало
[Topic libkos_sync_api]

Управление изоляцией памяти для ввода-вывода (iommu_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/iommu/iommu_api.h из состава KasperskyOS SDK.

API предназначен для управления изоляцией регионов физической памяти, используемых устройствами на шине PCIe для DMA. (Изоляция обеспечивается IOMMU.)

Сведения о функциях API приведены в таблице ниже.

Использование API

Без прикрепления к домену IOMMU устройство на шине PCIe не может использовать DMA. После прикрепления к домену IOMMU устройство может получить доступ ко всем буферам DMA, которые ассоциированы с этим доменом IOMMU. В один момент времени устройство может быть прикреплено только к одному домену IOMMU, но к одному домену IOMMU может быть прикреплено несколько устройств. Буфер DMA может быть ассоциирован с несколькими доменами IOMMU одновременно. Каждый домен IOMMU ассоциирован только с одним процессом, но с одним процессом может быть ассоциировано несколько доменов IOMMU. Возможность создания нескольких доменов IOMMU, ассоциированных с одним процессом, позволяет разграничить доступ к буферам DMA для разных устройств, управляемых одним процессом.

API позволяет создавать домены IOMMU, прикреплять устройства на шине PCIe к доменам IOMMU и откреплять устройства на шине PCIe от доменов IOMMU. Как правило, прикрепление устройства к домену IOMMU выполняется при инициализации драйвера. Открепление устройства от домена IOMMU обычно выполняется при возникновении ошибок во время инициализации драйвера или при финализации драйвера.

Ассоциация буфер DMA с доменом IOMMU создается при вызове функций KnIoDmaBegin() и KnIoDmaBeginEx(), входящих в API dma.h. Функция KnIoDmaBegin() ассоциирует буфер DMA с автоматически созданными доменом IOMMU. Каждый процесс может быть ассоциирован только с одним таким доменом IOMMU. Этот домен IOMMU создается при первом успешном вызове функции KnIommuAttachDevice() и существует на протяжении всего времени жизни процесса. Функция KnIoDmaBeginEx() ассоциирует буфер DMA с доменом IOMMU, созданным вызовом функции KnIommuCreateDomain(). Каждый процесс может быть ассоциирован с несколькими доменами IOMMU, созданными вызовами функции KnIommuCreateDomain(). Такие домены IOMMU могут быть удалены до завершения процесса закрытием их дескрипторов.

Чтобы прикрепить устройство к автоматически созданному домену IOMMU или выполнить обратную операцию, нужно вызвать функцию KnIommuAttachDevice() или KnIommuDetachDevice() соответственно.

Чтобы прикрепить устройство к домену IOMMU, созданному вызовом функции KnIommuCreateDomain(), или выполнить обратную операцию, нужно вызвать функцию KnIommuAttachDeviceToDomain() или KnIommuDetachDeviceFromDomain() соответственно.

Сведения о функциях API

Функции iommu_api.h

Функция

Сведения о функции

KnIommuAttachDevice()

Назначение

Прикрепляет устройство на шине PCIe к автоматически созданному домену IOMMU, ассоциированному с вызывающим процессом.

Параметры

  • [in] bdf – адрес устройства на шине PCIe в формате BDF.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Если IOMMU не задействован, возвращает rcOk.

KnIommuDetachDevice()

Назначение

Открепляет устройство на шине PCIe от автоматически созданного домена IOMMU, ассоциированного с вызывающим процессом.

Параметры

  • [in] bdf – адрес устройства на шине PCIe в формате BDF.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Если IOMMU не задействован, возвращает rcOk.

KnIommuCreateDomain()

Назначение

Создает домен IOMMU, ассоциированный с вызывающим процессом.

Параметры

  • [out] domain – указатель на дескриптор домена IOMMU.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIommuAttachDeviceToDomain()

Назначение

Прикрепляет устройство на шине PCIe к заданному домену IOMMU, ассоциированному с вызывающим процессом.

Параметры

  • [in] bdf – адрес устройства на шине PCIe в формате BDF.
  • [in] domain – дескриптор домена IOMMU.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIommuDetachDeviceFromDomain()

Назначение

Открепляет устройство на шине PCIe от заданного домена IOMMU, ассоциированного с вызывающим процессом.

Параметры

  • [in] bdf – адрес устройства на шине PCIe в формате BDF.
  • [in] domain – дескриптор домена IOMMU.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_iommu_api]

Использование очередей (queue.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/queue.h из состава KasperskyOS SDK.

API позволяет организовать обмен данными между потоками исполнения, принадлежащими одному процессу, через механизм очередей без блокировок. То есть для добавления или извлечения элементов очереди не требуется блокирование других потоков исполнения, добавляющих или извлекающих элементы этой очереди.

Сведения о функциях API приведены в таблице ниже.

Использование API

Типовой сценарий использования API включает следующие шаги:

  1. Создание абстракции очереди.

    Абстракция очереди состоит из структуры, содержащей метаданные об очереди, и буфера очереди, предназначенного для хранения элементов очереди. Буфер очереди логически разделен на равные участки, каждый из которых предназначен для отдельного элемента очереди. Число участков в буфере очереди соответствует максимальному числу элементов в очереди. Выравнивание адресов участков соответствует типам данных элементов очереди.

    Чтобы выполнить этот шаг, нужно вызвать функцию KosQueueCreate(). Эта функция может выделить память для буфера очереди или использовать уже выделенную память. Размер уже выделенной памяти должен быть достаточным, чтобы вместить максимальное число элементов в очереди. При этом нужно учитывать, что размер участка в буфере очереди округляется до ближайшего большего кратного значению выравнивания, заданному через параметр objAlign. Также начальный адрес уже выделенной памяти должен быть выровнен так, чтобы соответствовать типам данных элементов очереди. Если выравнивание адреса памяти, указанного в параметре buffer, меньше заданного через параметр objAlign, то функция вернет RTL_NULL.

  2. Обмен данными между потоками исполнения через добавление и извлечение элементов очереди.

    Чтобы добавить один элемент в конец очереди, нужно зарезервировать участок в буфере очереди вызовом функции KosQueueAlloc(), скопировать этот элемент в зарезервированный участок и вызвать функцию KosQueuePush().

    Чтобы добавить последовательность элементов в конец очереди, нужно зарезервировать требуемое количество участков в буфере очереди вызовами функции KosQueueAlloc(), скопировать элементы этой последовательности в зарезервированные участки и вызвать функцию KosQueuePushArray(). Порядок элементов последовательности не изменяется после добавления этой последовательности в очередь. То есть элементы добавляются очередь в том же порядке, в каком указатели на зарезервированные участки в буфере очереди помещены в массив, передаваемый через параметр objs функции KosQueuePushArray().

    Чтобы извлечь первый элемент очереди, нужно вызвать функцию KosQueuePop(). Эта функция возвращает указатель на зарезервированный участок в буфере очереди, который содержит первый элемент очереди. После использования извлеченного элемента (например, после проверки или сохранения значения элемента) нужно отменить резервирование занятого этим элементом участка в буфере очереди. Для этого нужно вызвать функцию KosQueueFree().

    Чтобы очистить очередь и отменить резервирование всех зарезервированных участков в буфере очереди, нужно вызвать функцию KosQueueFlush().

  3. Удаление абстракции очереди.

    Чтобы выполнить этот шаг, нужно вызвать функцию KosQueueDestroy(). Эта функция удаляет буфер очереди, если только память для этого буфера была выделена функцией KosQueueCreate(). В противном случае нужно отдельно выполнить удаление буфера очереди.

Сведения о функциях API

Функции queue.h

Функция

Сведения о функции

KosQueueCreate()

Назначение

Создает абстракцию очереди.

Параметры

  • [in] objCount – максимальное число элементов в очереди.
  • [in] objSize – размер элемента очереди в байтах.
  • [in] objAlign – выравнивание адресов участков в буфере очереди. Адреса участков в буфере очереди могут быть невыровненными (objAlign=1) или выровненными (objAlign=2,4,...,2^N) на границу 2^N-байтовой последовательности (например, двухбайтовой, четырехбайтовой).
  • [in,optional] buffer – указатель на выделенную память для буфера очереди или RTL_NULL, чтобы память была выделена автоматически.

Возвращаемые значения

В случае успеха возвращает идентификатор абстракции очереди, иначе возвращает RTL_NULL.

KosQueueDestroy()

Назначение

Удаляет абстракцию очереди.

Параметры

  • [in] queue – идентификатор абстракции очереди.

Возвращаемые значения

Нет.

KosQueueAlloc()

Назначение

Резервирует участок в буфере очереди.

Параметры

  • [in] queue – идентификатор абстракции очереди.

Возвращаемые значения

В случае успеха возвращает указатель на зарезервированный участок в буфере очереди, иначе возвращает RTL_NULL.

KosQueueFree()

Назначение

Отменяет резервирование заданного участка в буфере очереди.

Параметры

  • [in] queue – идентификатор абстракции очереди.
  • [in] obj – указатель на зарезервированный участок в буфере очереди.

Возвращаемые значения

Нет.

KosQueuePush()

Назначение

Добавляет элемент в конец очереди.

Параметры

  • [in] queue – идентификатор абстракции очереди.
  • [in] obj – указатель на зарезервированный участок в буфере очереди.

Возвращаемые значения

Нет.

KosQueuePushArray()

Назначение

Добавляет последовательность элементов в конец очереди.

Параметры

  • [in] queue – идентификатор абстракции очереди.
  • [in] objs – массив указателей на зарезервированные участки в буфере очереди.
  • [in] count – число элементов в последовательности.

Возвращаемые значения

Нет.

KosQueuePop()

Назначение

Извлекает первый элемент очереди.

Параметры

  • [in] queue – идентификатор абстракции очереди.
  • [in] timeout – время ожидания появления элемента в очереди в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.

Возвращаемые значения

В случае успеха возвращает указатель на зарезервированный участок в буфере очереди, который содержит первый элемент очереди. Иначе возвращает RTL_NULL.

KosQueueFlush()

Назначение

Очищает очередь и отменяет резервирование всех зарезервированных участков в буфере очереди.

Параметры

  • [in] queue – идентификатор абстракции очереди.

Возвращаемые значения

Нет.

В начало
[Topic libkos_queue_api]

Использование барьеров памяти (barriers.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/io/barriers.h из состава KasperskyOS SDK.

API позволяет устанавливать барьеры на чтение из памяти и/или на запись в память. Барьер памяти (англ. memory barrier) – это инструкция для компилятора и процессора, которая гарантирует, что операции доступа к памяти, указанные в исходном коде до установки барьера, будут выполнены до операций доступа к памяти, указанных в исходном коде после установки барьера. Использование барьеров памяти требуется, если важен порядок операций чтения из памяти и/или записи в память, поскольку действия компилятора и/или процессора, связанные с оптимизацией, могут привести к тому, что эти операции будут выполнены в порядке, отличном от указанного в исходном коде.

Сведения о функциях API приведены в таблице ниже.

Функции barriers.h

Функция

Сведения о функции

IoReadBarrier()

Назначение

Устанавливает барьер на чтение из памяти.

Параметры

Нет.

Возвращаемые значения

Нет.

IoWriteBarrier()

Назначение

Устанавливает барьер на запись в память.

Параметры

Нет.

Возвращаемые значения

Нет.

IoReadWriteBarrier()

Назначение

Устанавливает барьер на запись в память и чтение из памяти.

Параметры

Нет.

Возвращаемые значения

Нет.

В начало
[Topic libkos_barriers_api]

Выполнение системных вызовов (syscalls.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/syscalls.h из состава KasperskyOS SDK.

API позволяет выполнять системные вызовы Call(), Recv() и Reply() для отправки и получения IPC-сообщений.

Сведения о функциях API приведены в таблице ниже.

Использование API

Для передачи функциям API указателей на буферы с фиксированной частью и ареной IPC-сообщений используется заголовок IPC-сообщений, тип которого определен в заголовочном файле sysroot-*-kos/include/ipc/if_rend.h из состава KasperskyOS SDK. Перед вызовами функций API заголовки IPC-сообщений нужно связать с буферами, содержащими фиксированную часть и арену IPC-сообщений. Для этого нужно использовать функции PackInMsg() и PackOutMsg(), объявленные в заголовочном файле sysroot-*-kos/include/services/rtl/nk_msg.h из состава KasperskyOS SDK.

Функции Call(), CallEx(), Recv() и RecvEx() блокируют исполнение вызывающего потока, ожидая завершения системных вызовов. Функции CallEx() и RecvEx() позволяют задать время ожидания завершения системного вызова, по истечении которого незавершенный системный вызов прерывается, и поток, ожидающий его завершения, возобновляет исполнение. Также системный вызов прерывается, если при его выполнении возникла ошибка (например, из-за завершения серверного процесса). Завершение потока исполнения извне тоже прерывает системный вызов, завершения которого ожидает этот поток. Системный вызов, выполняемый функцией CallEx() или RecvEx(), можно прервать (например, для корректного завершения процесса) с использованием API ipc_api.h.

Если системный вызов был прерван с использованием API ipc_api.h, то функции CallEx() и RecvEx() возвращают код ошибки rcIpcInterrupt. Если отправка IPC-сообщения запрещена механизмами безопасности (модулем безопасности Kaspersky Security Module или механизмом безопасности на основе мандатных ссылок, реализуемым ядром KasperskyOS), то функции Call(), CallEx() и Reply() возвращают код ошибки rcSecurityDisallow.

Сведения о функциях API

Функции syscalls.h

Функция

Сведения о функции

Call()

Назначение

Выполняет системный вызов Call() с неограниченным временем ожидания его завершения.

Параметры

  • [in] handle – клиентский IPC-дескриптор.
  • [in] msgOut – указатель на заголовок IPC-запросов.
  • [in,out] msgIn – указатель на заголовок IPC-ответов.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

CallEx()

Назначение

Выполняет системный вызов Call() с заданным временем ожидания его завершения и возможностью прервать его выполнение.

Параметры

  • [in] handle – клиентский IPC-дескриптор.
  • [in] msgOut – указатель на заголовок IPC-запросов.
  • [in,out] msgIn – указатель на заголовок IPC-ответов.
  • [in] mdelay – время ожидания завершения системного вызова Call() в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [in,optional] syncHandle – дескриптор объекта синхронизации IPC или INVALID_HANDLE, если прерывание системного вызова Call() не требуется.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Reply()

Назначение

Выполняет системный вызов Reply().

Параметры

  • [in] handle – серверный IPC-дескриптор.
  • [in] msgOut – указатель на заголовок IPC-ответов.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Recv()

Назначение

Выполняет системный вызов Recv() с неограниченным временем ожидания его завершения.

Параметры

  • [in] handle – серверный IPC-дескриптор.
  • [in,out] msgIn – указатель на заголовок IPC-запросов.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

RecvEx()

Назначение

Выполняет системный вызов Recv() с заданным временем ожидания его завершения и возможностью прервать его выполнение.

Параметры

  • [in] handle – серверный IPC-дескриптор.
  • [in,out] msgIn – указатель на заголовок IPC-ответов.
  • [in] mdelay – время ожидания завершения системного вызова Recv() в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [in,optional] syncHandle – дескриптор объекта синхронизации IPC или INVALID_HANDLE, если прерывание системного вызова Recv() не требуется.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_syscalls_api]

Прерывание IPC (ipc_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/ipc/ipc_api.h из состава KasperskyOS SDK.

API позволяет прерывать системные вызовы Call() и Recv(), в ожидании завершения которых заблокирован один или несколько потоков процесса. Прерывать системные вызовы требуется, например, чтобы корректно завершить процесс, поскольку потоки, ожидающие завершения этих системных вызовов, возобновляют исполнение.

Сведения о функциях API приведены в таблице ниже.

Использование API

API позволяет прерывать системные вызовы в потоках процесса, которые заблокированы после вызова функции CallEx() или RecvEx() из API syscalls.h, если эти функции вызваны с указанием дескриптора объекта синхронизации IPC в параметре syncHandle. Чтобы создать объекта синхронизации IPC, нужно вызвать функцию KnIpcCreateSyncObject(). (Дескриптор объекта синхронизации IPC не может быть передан другому процессу, так как в маске прав этого дескриптора не установлен необходимый для этого флаг.)

Функция KnIpcSetInterrupt() переводит объект синхронизации IPC в состояние, при котором прерываются системные вызовы в тех потоках процесса, которые заблокированы после вызова функции CallEx() или RecvEx() с указанием дескриптора этого объекта синхронизации IPC в параметре syncHandle. Прерывание системного вызова возможно только на некоторых стадиях его выполнения. Системный вызов, выполняемый функцией CallEx(), может быть прерван только тогда, когда на сервере еще не вызвана функция Recv() или RecvEx() для того IPC-канала, клиентский IPC-дескриптор которого указан при вызове функции CallEx(). Системный вызов, выполняемый функцией RecvEx(), может быть прерван только во время ожидания IPC-запроса от клиента.

Функция KnIpcClearInterrupt() отменяет действие функции KnIpcSetInterrupt().

Чтобы удалить объект синхронизации IPC, нужно закрыть его дескриптор вызовом функции KnHandleClose(), объявленной в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK.

Сведения о функциях API

Функции ipc_api.h

Функция

Сведения о функции

KnIpcCreateSyncObject()

Назначение

Создает объект синхронизации IPC.

Параметры

  • [out] syncHandle – указатель на дескриптор объекта синхронизации IPC.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIpcSetInterrupt()

Назначение

Переводит заданный объект синхронизации IPC в состояние, при котором системные вызовы Call() и Recv() прерываются.

Параметры

  • [in] syncHandle – дескриптор объекта синхронизации IPC.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnIpcClearInterrupt()

Назначение

Переводит заданный объект синхронизации IPC в состояние, при котором системные вызовы Call() и Recv() не прерываются.

Параметры

  • [in] syncHandle – дескриптор объекта синхронизации IPC.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_ipc_api]

Использование сессий (session.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/session.h из состава KasperskyOS SDK.

API предназначен для применения в коде поставщиков ресурсов, предоставляющих доступ к пользовательским ресурсам через IPC, и в коде программ, использующих пользовательские ресурсы локально (без IPC). API позволяет организовать управление доступом к пользовательским ресурсам на основе сессий. Сессия представляет собой последовательность действий: открытие доступа к ресурсу, использование ресурса, закрытие доступа к ресурсу. Открытие доступа к ресурсу создает сессию. Закрытие доступа к ресурсу завершает сессию. В одной сессии может выполняться несколько операций с ресурсом одновременно. Ресурс может быть использован в режиме эксклюзивного или множественного доступа. Во втором случае ресурс должен быть открыт несколько раз (возможно с разными правами доступа), то есть ресурс будет использован через множество одновременно существующих сессий (параллельных сессий).

"Объект" в описании API – это объект KosObject, который представляет собой абстракцию ресурса (об объектах KosObject см. "Использование объектов KosObject (objects.h)"). Также тип сессий и контекст сессии являются объектами KosObject. (Контекст сессии содержит сведения об этой сессии, такие как права доступа к ресурсу, счетчик активных операций с ресурсом.)

Сведения о функциях API приведены в таблице ниже.

Создание типа сессий

Созданию сессий предшествует создание их типа. Чтобы создать тип сессий, нужно вызвать функцию KosSessionCreateType().

Через параметр objectType нужно задать тип объектов, для которых предназначены сессии создаваемого типа. Тип объектов должен наследовать тип с идентификатором kosSessionBaseObjectType.

Через параметр sessionType нужно задать тип контекстов сессий. Можно указать базовый тип контекстов сессий с идентификатором kosSessionBaseSessionType либо тип, который наследует его. Базовому типу контекстов сессий соответствует структура, содержащая такие данные, как указатель на объект, права доступа к ресурсу, маска прав дескриптора ресурса, передаваемая потребителям ресурсов, счетчик активных операций с ресурсом в сессии (тип этой структуры не экспортируется программам, а используется библиотекой libkos). Можно добавить в контекст сессии дополнительные сведения, создав собственный тип контекстов сессий, наследующий базовый. Например, контекст сессии использования устройства может дополнительно содержать указатели на функции, вызываемые программами решения для работы с устройством.

Через параметр ops нужно задать callback-функции, вызываемые при создании и завершении сессий. Callback-функции для идентификаторов open и close нужно задать обязательно. Callback-функцию для идентификатора closeComplete можно не задавать, поэтому этот идентификатор может иметь значение RTL_NULL.

Callback-функция, соответствующая идентификатору open, вызывается при создании сессии и получает указатели на объект, контекст сессии, данные, переданные функции KosSessionOpenObject() через параметр openCtx, и буфер для сохранения маски прав дескриптора ресурса, передаваемой потребителям ресурсов. В этой callback-функции можно, например, проверить состояние ресурса, задать передаваемую потребителям ресурсов маску прав дескриптора ресурса, выполнить запись данных в объект или контекст сессии. Если код возврата будет отличным от rcOk, сессия не будет создана.

Callback-функция, соответствующая идентификатору close, вызывается при завершении сессии независимо от того, завершены операции с ресурсом или нет (счетчик активных операций в закрываемой сессии может быть больше нуля), и получает указатели на объект и контекст сессии. В этой callback-функции можно, например, прервать активные операции в завершаемой сессии, выполнить запись данных в объект или контекст сессии. Код возврата может быть произвольным.

Callback-функция, соответствующая идентификатору closeComplete, вызывается при завершении сессии только после завершения всех операций с ресурсом (счетчик активных операций в завершаемой сессии равен нулю) и получает указатели на объект и контекст сессии. В этой callback-функции можно, например, выполнить запись данных в объект.

Регистрация объекта

После создания типа сессий нужно зарегистрировать требуемые объекты как объекты, с которыми могут быть связаны сессии этого типа. Чтобы зарегистрировать объект, нужно вызвать функцию KosSessionRegisterObject().

Нельзя зарегистрировать один объект для связывания с разными типами сессий одновременно.

После регистрации объект готов к открытию.

Открытие объекта

Открытие объекта создает сессию, связанную с этим объектом, и выполняется по запросу на открытие доступа к ресурсу. Это может быть запрос через IPC от потребителя ресурсов или локальный запрос от другого компонента программы.

Чтобы открыть объект, нужно вызвать функцию KosSessionOpenObject(). Через параметр requiredRights нужно задать права доступа к ресурсу в создаваемой сессии, а через параметр shareMode нужно задать права множественного доступа к ресурсу, которые устанавливают ограничения доступа к этому ресурсу для параллельных сессий. Например, если через параметр requiredRights заданы права на чтение и запись, а в параметре shareMode указан 0, то создаваемая сессия требует эксклюзивного доступа к ресурсу на чтение и запись. Если через параметр requiredRights заданы права на чтение и запись, а через параметр shareMode заданы права только на чтение, то создаваемая сессия требует доступа на чтение и запись и разрешает чтение в параллельных сессиях. Если через параметр requiredRights заданы права на чтение, а через параметр shareMode заданы права на чтение и запись, то создаваемая сессия требует доступа на чтение, а также разрешает чтение и запись в параллельных сессиях.

Если ресурс требуется использовать в режиме множественного доступа, то при втором и последующих открытиях объекта нужно учесть следующие условия:

  • Права доступа, задаваемые через параметр requiredRights, не могут превышать минимальных прав доступа, заданных через параметр shareMode для всех параллельных сессий, связанных с этим объектом.
  • Права доступа, задаваемые через параметр shareMode, должны включать все права доступа, заданные через параметр requiredRights для всех параллельных сессий, связанных с этим объектом.

В результате открытия объекта будет создан контекст сессии.

Если программа использует ресурсы локально, то после открытия объекта компонент программы, управляющий ресурсами, должен передать компоненту программы, использующему ресурсы, указатель на созданный контекст сессии. Запрашивая в дальнейшем операции с ресурсом, компонент программы, использующий ресурсы, должен передавать этот указатель компоненту программы, управляющему ресурсами, для идентификации сессии.

Поставщик ресурсов после открытия объекта должен передать потребителю дескриптор ресурса. В качестве контекста передачи ресурса должен использоваться контекст сессии, чтобы потребитель получил дескриптор ресурса, связанный с сессией. Запрашивая в дальнейшем операции с ресурсом, потребитель должен помещать полученный дескриптор ресурса в IPC-запросы, чтобы после разыменования этого дескриптора поставщик получал указатель на контекст сессии. Чтобы заполнить данными транспортный контейнер дескриптора ресурса для передачи потребителю ресурсов, нужно вызвать функцию KosSessionContextToIpcHandle(). Через параметр sessionCtx эта функция получает контекст сессии, а через параметр desc передает транспортный контейнер дескриптора ресурса.

Функция KosSessionContextToIpcHandle() помещает в транспортный контейнер дескриптора ресурса маску прав, заданную в callback-функции, которая вызывается при создании сессии. Права доступа, заданные в этой маске, не должны превышать права доступа в сессии, заданные через параметр requiredRights функции KosSessionOpenObject(). При этом одно и то же право доступа может соответствовать разным битам в маске прав и в значении, заданном через параметр requiredRights функции KosSessionOpenObject().

В качестве контекста передачи ресурса функция KosSessionContextToIpcHandle() задает контекст сессии. Контекст сессии будет автоматически удален (соответственно сессия будет завершена) после закрытия или отзыва дескрипторов ресурса, порожденных передачей дескриптора ресурса, который получен вызовом функции KosSessionContextToIpcHandle(). Если требуется предотвратить автоматическое завершение сессии для последующего завершения вызовом функции KosSessionCloseObject(), перед передачей дескриптора ресурса нужно инкрементировать счетчик ссылок на контекст этой сессии вызовом функции KosRefObject() из API objects.h. В этом случае после вызова функции KosSessionCloseObject() нужно декрементировать счетчик ссылок на контекст сессии вызовом функции KosPutObject() из API objects.h.

Выполнение операций с ресурсом

Операция с ресурсом (например, чтение, запись, получение параметров) выполняется по запросу через IPC от потребителя ресурсов или по локальному запросу от другого компонента программы.

Сценарий выполнения операции с ресурсом включает следующие шаги:

  1. Проверить права доступа к ресурсу.

    При обработке локального запроса нужно вызвать функцию KosSessionGetOpenRights(). Эта функция позволяет получить сведения о правах доступа к ресурсу в сессии, заданных через параметр requiredRights функции KosSessionOpenObject(), чтобы сравнить эти права с требуемыми для выполнения операции.

    При обработке IPC-запроса нужно вызвать функцию KosSessionIpcHandleToSession(), которая позволяет получить контекст сессии, а также проверяет, что маска прав дескриптора ресурса, который потребитель ресурсов поместил в IPC-запрос, соответствует запрашиваемой операции. Через параметр desc нужно передать функции полученный от потребителя ресурса транспортный контейнер дескриптора ресурса. В параметре operation нужно указать права доступа к ресурсу, требуемые для выполнения запрашиваемой операции. В параметре type можно указать идентификатор типа сессии, чтобы проверить, что тип контекста сессии соответствует типу сессии. Если в параметре type указать значение RTL_NULL, то перед приведением типа указателя, полученного через параметр sessionCtx, нужно проверить тип контекста сессии. Проверку типа контекста сессии нужно сделать обязательно, поскольку поставщик ресурсов может создавать сессии с контекстами разных типов, а потребитель ресурсов может ошибочно поместить в IPC-запрос дескриптор ресурса, который соответствует сессии с контекстом другого типа. Чтобы проверить тип контекста, нужно использовать API objects.h.

  2. Инкрементировать счетчик активных операций в сессии вызовом функции KosSessionRef().

    Функция проверяет, что сессия не завершена. В параметре type можно указать идентификатор типа сессии, чтобы проверить, что тип контекста сессии соответствует типу сессии. Через параметр object можно получить указатель на объект.

  3. Выполнить запрошенные действия с ресурсом.
  4. Декрементировать счетчик активных операций в сессии вызовом функции KosSessionPut().

Получение дескриптора ресурса

Дескриптор ресурса может потребоваться, например, для использования уведомлений или для обращения к модулю безопасности Kaspersky Security Module через интерфейс безопасности. Чтобы получить дескриптор ресурса по объекту или по контексту сессии, нужно вызвать функцию KosSessionGetObjectHandle() или KosSessionGetObjectHandleBySession() соответственно.

Перечисление сессий, связанных с объектом

Перечисление сессий, связанных с объектом, может потребоваться, например, чтобы сообщать о состоянии ресурса каждому из потребителей ресурсов, использующих этот ресурс. Чтобы перечислить сессии, связанные с объектом, нужно вызвать функцию KosSessionWalk(). Через параметр handler нужно задать callback-функцию, которая вызывается для каждой сессии при перечислении и получает указатели на объект, контекст сессии и данные, переданные функции KosSessionWalk() через параметр walkCtx. В этой callback-функции можно, например, отправить потребителям ресурсов уведомления о состоянии ресурса.

Закрытие объекта

Закрытие объекта завершает одну из сессий, связанных с этим объектом. Завершение сессии не будет выполнено, пока не будут завершены все операции в этой сессии, то есть счетчик активных операций не станет равным нулю. При завершении сессии автоматически отзываются дескрипторы ресурса, связанные с этой сессией.

Закрытие объекта выполняется по запросу на закрытие доступа к ресурсу. Это может быть запрос через IPC от потребителя ресурсов или локальный запрос от другого компонента программы. После выполнения запроса на закрытие доступа к ресурсу потребитель ресурсов должен закрыть дескриптор этого ресурса. (Если потребитель ресурсов завершится, не выполнив запрос на закрытие доступа к ресурсу, либо закроет дескриптор ресурса без выполнения этого запроса, то соответствующая сессия будет автоматически завершена при условии, что поставщик ресурсов дополнительно не инкременетировал счетчик ссылок на контекст этой сессии.)

Чтобы закрыть объект, нужно вызвать функцию KosSessionCloseObject() или KosSessionCloseObjectByIpcHandle().

Функция KosSessionCloseObject() завершает сессию, соответствующую контексту сессии, заданному через параметр sessionCtx.

Функция KosSessionCloseObjectByIpcHandle() завершает сессию, с которой связан дескриптор ресурса, помещенный потребителем ресурса в IPC-запрос на закрытие доступа к ресурсу. Через параметр desc нужно передать функции полученный транспортный контейнер дескриптора ресурса. В параметре type можно указать идентификатор типа сессии, чтобы проверить, что тип контекста сессии соответствует типу сессии.

Дерегистрация объекта

Дерегистрация объекта делает невозможным открытие этого объекта и завершает все связанные с ним сессии. Завершение сессии не будет выполнено, пока не будут завершены все операции в этой сессии, то есть счетчик активных операций не станет равным нулю. При завершении сессии автоматически отзываются дескрипторы ресурса, связанные с этой сессией. (Отзыв не закрывает дескрипторы ресурса, поэтому отозванные дескрипторы нужно закрыть.)

Чтобы дерегистрировать объект, нужно вызвать функцию KosSessionUnregisterObject().

Удаление типа сессий

Тип сессий нужно удалить, если отсутствуют зарегистрированные объекты, для которых можно использовать сессии этого типа, и больше регистраций не будет. Например, тип сессий требуется удалить при завершении работы поставщика ресурсов.

Чтобы удалить тип сессий, нужно вызвать функцию KosSessionDestroyType().

Сведения о функциях API

Функции session.h

Функция

Сведения о функции

KosSessionCreateType()

Назначение

Создает тип сессий.

Параметры

  • [in] objectType – идентификатор типа объектов, для которых предназначены сессии. Тип параметра определен в заголовочном файле sysroot-*-kos/include/kos/objects.h из состава KasperskyOS SDK.
  • [in] sessionType – идентификатор типа контекстов сессий. Тип параметра определен в заголовочном файле sysroot-*-kos/include/kos/objects.h из состава KasperskyOS SDK.
  • [in] ops – указатель на структуру, содержащую идентификаторы callback-функций, вызываемых при создании и завершении сессий.
  • [out] outType – указатель на идентификатор типа сессий.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionDestroyType()

Назначение

Удаляет тип сессий.

Параметры

  • [in] type – идентификатор типа сессий.

Возвращаемые значения

Нет.

KosSessionRegisterObject()

Назначение

Регистрирует объект как объект, с которым могут быть связаны сессии заданного типа.

Параметры

  • [in] type – идентификатор типа сессий.
  • [in] object – указатель на объект.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionUnregisterObject()

Назначение

Дерегистрирует объект, зарегистрированный вызовом функции KosSessionRegisterObject().

Параметры

  • [in] object – указатель на объект.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionOpenObject()

Назначение

Открывает объект.

Параметры

  • [in] object – указатель на объект.
  • [in,optional] openCtx – указатель на данные, которые будут переданы callback-функции, вызываемой при создании сессии. Можно указать RTL_NULL, если данные передавать не требуется. Callback-функция получит переданные данные через свой параметр ctx.
  • [in] requiredRights – значение, задающее права доступа к ресурсу в создаваемой сессии.
  • [in] shareMode – значение, задающее права множественного доступа к ресурсу.
  • [out] sessionCtx – указатель на адрес контекста сессии.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionCloseObject()

Назначение

Закрывает объект.

Параметры

  • [in] sessionCtx – указатель на контекст сессии.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionRef()

Назначение

Инкрементирует счетчик активных операций в сессии.

Параметры

  • [in,optional] type – идентификатор типа сессии или RTL_NULL, если не требуется проверять, что тип контекста сессии соответствует типу сессии.
  • [in] sessionCtx – указатель на контекст сессии.
  • [out,optional] object – указатель на адрес объекта или RTL_NULL, если адрес объекта не требуется.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionPut()

Назначение

Декрементирует счетчик активных операций в сессии.

Параметры

  • [in] sessionCtx – указатель на контекст сессии.

Возвращаемые значения

Нет.

KosSessionWalk()

Назначение

Перечисляет сессии, связанные с заданными объектом.

Параметры

  • [in] object – указатель на объект.
  • [in] handler – идентификатор callback-функции, вызываемой для каждой сессии при перечислении.
  • [in,optional] walkCtx – указатель на данные, которые будут переданы callback-функции, заданной через параметр handler. Можно указать RTL_NULL, если данные передавать не требуется. Callback-функция получит переданные данные через свой параметр walkCtx.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Если callback-функция, заданная через параметр handler, возвращает rtl_false, перечисление завершается.

Callback-функция, заданная через параметр handler, не должна вызывать функции KosSessionOpenObject(), KosSessionCloseObject(), KosSessionRegisterObject(), KosSessionUnregisterObject().

KosSessionGetOpenRights()

Назначение

Позволяет получить сведения о правах доступа к ресурсу в заданной сессии.

Эти права были заданы через параметр requiredRights функции KosSessionOpenObject().

Параметры

  • [in] sessionCtx – указатель на контекст сессии.

Возвращаемые значения

В случае успеха возвращает значение, отражающее права доступа к ресурсу, иначе возвращает 0.

KosSessionContextToIpcHandle()

Назначение

Заполняет данными транспортный контейнер дескриптора ресурса для передачи потребителю ресурса при обработке IPC-запроса на открытие доступа к ресурсу.

Параметры

  • [in] sessionCtx – указатель на контекст сессии.
  • [out] desc – указатель на транспортный контейнер дескриптора.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionIpcHandleToSession()

Назначение

Позволяет получить контекст сессии при обработке IPC-запроса от потребителя ресурсов.

Параметры

  • [in] desc – указатель на транспортный контейнер дескриптора.
  • [in] operation – значение, которое отражает права доступа к ресурса, необходимые для выполнения операций, чтобы проверить, что маска прав дескриптора, помещенного в IPC-запрос потребителем ресурсов, соответствует запрашиваемой операции.
  • [in,optional] type – идентификатор типа сессии или RTL_NULL, если не требуется проверять, что тип контекста сессии соответствует типу сессии.
  • [out] sessionCtx – указатель на адрес контекста сессии.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionCloseObjectByIpcHandle()

Назначение

Закрывает объект при обработке IPC-запроса от потребителя ресурса на закрытие доступа к ресурсу.

Параметры

  • [in] desc – указатель на транспортный контейнер дескриптора.
  • [in,optional] type – идентификатор типа сессии или RTL_NULL, если не требуется проверять, что тип контекста сессии соответствует типу сессии.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionGetObjectHandle()

Назначение

Позволяет получить дескриптор ресурса по объекту.

Параметры

  • [in] object – указатель на объект.
  • [out] handle – указатель на дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosSessionGetObjectHandleBySession()

Назначение

Позволяет получить дескриптор ресурса по контексту сессии.

Параметры

  • [in] sessionCtx – указатель на контекст сессии.
  • [out] handle – указатель на дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_session_api]

Использование объектов KosObject (objects.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/objects.h из состава KasperskyOS SDK.

API позволяет использовать типизированные объекты KosObject. Объект KosObject представляет собой регион памяти процесса, состоящий из сегментов со служебными и полезными данными. Служебные данные включают указатель на структуру, описывающую тип объекта, счетчик ссылок на объект и другие сведения об объекте. Состав полезных данных может быть любым в зависимости от назначения объекта. Например, сегменты полезных данных в объекте, который представляет собой абстракцию устройства, хранят структуры, которые содержат параметры функционирования устройства, указатели на низкоуровневые методы работы с ним, а также параметры программно-аппаратных интерфейсов для управления устройством.

Для объектов KosObject поддерживается механизм наследования типов. Например, абстракция устройства NS16550 UART содержит в разных сегментах полезных данных следующие структуры: специфичную для типа устройств NS16550 UART, специфичную для класса устройств UART, общие для любых устройств. Тип абстракции устройства NS16550 UART соответствует только той структуре, которая специфична для устройств NS16550 UART. Все остальные структуры соответствуют типам, которые унаследовал тип абстракции устройства NS16550 UART.

В API указателем на объект является указатель на сегмент полезных данных в этом объекте.

Сведения о функциях API приведены в таблице ниже.

Создание типа объектов

Созданию объектов предшествует создание их типа. Тип объектов представляет собой регион памяти процесса, содержащий структуру, которая включает такие данные, как имя типа, указатели на функции, вызываемые при создании и уничтожении объектов этого типа, указатель на родительский тип, счетчик ссылок на тип. В каждом объекте хранится указатель на такую структуру, что делает объекты типизированными.

Чтобы создать тип объектов, нужно вызвать функцию KosCreateObjectType() или KosCreateObjectTypeEx(). В отличие от функции KosCreateObjectType() функция KosCreateObjectTypeEx() позволяет создать тип, наследующий другие типы. Такой тип содержит адрес родительского типа, заданного через параметр parentType. При этом через параметр parentType можно задать тип, который также содержит адрес своего родительского типа. В итоге, используя функцию KosCreateObjectTypeEx(), можно создать дерево наследования типов. Каждый тип в этом дереве будет наследовать всю цепочку типов, образующих путь от корня дерева до этого типа.

В зависимости от того, используется наследование типов или нет, объекты могут быть простыми и составными. Объекты, которые соответствуют одному типу, являются простыми. Объекты, которые соответствуют цепочке наследования типов, являются составными. Составные объекты состоят из простых. Число простых объектов в составном равно числу типов в цепочке наследования. При этом эти простые объекты образуют цепочку наследования, соответствующую цепочке наследования их типов, то есть каждый объект, кроме первого в цепочке наследования, содержит адрес родительского объекта.

Через параметр defaultObjSize функций KosCreateObjectType() и KosCreateObjectTypeEx() нужно задать размер объектов по умолчанию (при создании объекта можно задать другой размер). В случае создания типа, наследующего другие типы, этот параметр имеет отношение только к последнему типу в цепочке наследования. Фактически параметр defaultObjSize задает минимальный размер сегмента полезных данных в простых объектах, поскольку действительный размер объектов будет больше заданного из-за выравнивания регионов памяти, наследования типов и наличия сегментов со служебными данными.

Через параметр ops функций KosCreateObjectType() и KosCreateObjectTypeEx() можно задать callback-функции, вызываемые при создании и уничтожении объектов (можно задать обе функции или только одну). При создании составного объекта внутри него создается набор простых объектов, а при уничтожении составного объекта внутри него уничтожается набор простых объектов. При создании и уничтожении каждого простого объекта вызываются отдельные callback-функции, заданные при создании типа этого объекта. Первым создается первый объект в цепочке наследования, последним создается последний объект цепочке наследования. Первым уничтожается последний объект в цепочке наследования, последним уничтожается первый объект в цепочке наследования.

Callback-функция, вызываемая при создании объекта, получает указатели на объект и данные, переданные функции KosCreateObjectEx() через параметр context. В этой callback-функции можно, например, выделить ресурсы, инициализировать данные в объекте. Если код возврата будет отличным от rcOk, объект не будет создан. Если при создании составного объекта не будет создан хотя бы один простой объект, то этот составной объект не будет создан. Также при создании составного объекта данные, переданные функции KosCreateObjectEx() через параметр context, получит только та callback-функция, которая вызывается при создании последнего простого объекта в цепочке наследования.

Callback-функция, вызываемая при уничтожении объекта, получает указатель на объект. В этой callback-функции можно, например, освободить ресурсы. Код возврата может быть произвольным.

Создание объекта

После создания типа объектов можно создавать объекты. Чтобы создать объект, нужно вызвать функцию KosCreateObject() или KosCreateObjectEx().

Через параметр type нужно задать тип объекта. Если задать тип, не наследующий другие типы, будет создан простой объект. Если задать тип, наследующий другие типы, будет создан составной объект, в котором последний простой объект в цепочке наследования будет иметь заданный тип.

Через параметр size нужно задать размер объекта или указать 0, чтобы был задан размер объекта по умолчанию, указанный в типе этого объекта. В случае создания составного объекта этот параметр имеет отношение только к последнему простому объекту в цепочке наследования. Фактически параметр size задает минимальный размер сегмента полезных данных в простом объекте, поскольку действительный размер объекта будет больше заданного из-за выравнивания региона памяти, наследования типов и наличия сегментов со служебными данными.

В отличие от функции KosCreateObject() у функции KosCreateObjectEx() есть параметр context, через который можно передать данные callback-функции, вызываемой при создании объекта. При создании составного объекта данные, переданные через параметр context, получит только та callback-функция, которая вызывается при создании последнего простого объекта в цепочке наследования.

Через параметр outObject функции KosCreateObject() и KosCreateObjectEx() передают указатель на созданный объект. Указатель на созданный составной объект представляет собой указатель на последний простой объект в цепочке наследования.

После создания объект можно использовать для записи данных в него и чтения данных из него.

Получение доступа к простым объектам в составном объекте

Чтобы получать доступ к простым объектам в составном объекте, нужно использовать функцию KosGetObjectParent() и/или функцию KosGetObjectAncestor(). Функция KosGetObjectParent() позволяет получить указатель на объект, который является непосредственным предком заданного объекта. Функция KosGetObjectAncestor() позволяет получить указатель на объект, который является предком заданного объекта и имеет заданный тип.

Управление временем жизни объектов и их типов

Объект существует, пока счетчик ссылок на него имеет значение больше нуля. Также тип объектов существует, пока счетчик ссылок на него имеет значение больше нуля. При создании объекта или типа объектов значение счетчика ссылок равно 1. В дальнейшем этот счетчик можно инкрементировать и декрементировать для управления временем жизни объекта или типа объектов. Например, после создания объекта можно декрементировать счетчик ссылок на его тип, поскольку при создании объекта библиотека libkos инкрементирует счетчик ссылок на тип этого объекта. В этом случае тип объекта будет уничтожен автоматически после уничтожения объекта, так как библиотека libkos декрементирует счетчик ссылок на тип объекта при уничтожении объекта. Также, к примеру, при сохранении адреса объекта в другом объекте нужно инкрементировать счетчик ссылок на первый объект, чтобы обеспечить его существование на время существования второго объекта. При уничтожении объекта, который содержит адрес другого объекта, нужно декрементировать счетчик ссылок на второй объект, чтобы обеспечить его уничтожение при отсутствии других ссылок.

Время жизни простого объекта в составном соответствует времени жизни этого составного объекта. Отдельно управлять временем жизни простого объекта в составном нельзя.

Чтобы инкрементировать счетчик ссылок на объект или тип объектов, нужно вызвать функцию KosRefObject() или KosRefObjectType() соответственно.

Чтобы декрементировать счетчик ссылок на объект или тип объектов, нужно вызвать функцию KosPutObject() или KosPutObjectType() соответственно.

Проверка типа объектов

Функции KosCheckParentType() и KosObjectTypeInheritsType() позволяют проверить, является ли один тип объектов родительским для другого.

Функция KosObjectOfType() проверяет, имеет ли объект заданный тип.

Функция KosObjectInheritsType() проверяет, имеет ли объект заданный тип или тип, наследующий заданный тип.

Получение типа и имени объекта

Чтобы получить тип объекта, нужно вызвать функцию KosObjectGetType().

Чтобы получить имя объекта, нужно вызвать функцию KosGetObjectName(). (Каждый простой объект в составном имеет имя этого составного объекта.)

Получение имени типа объектов

Чтобы получить имя типа объектов, нужно вызвать функцию KosObjectGetTypeName().

Сведения о функциях API

Функции objects.h

Функция

Сведения о функции

KosCreateObjectType()

Назначение

Создает тип объектов.

Параметры

  • [in] name – указатель на имя типа объектов.
  • [in] defaultObjSize – размер объектов по умолчанию, в байтах.
  • [in,optional] ops – указатель на структуру, содержащую указатели на callback-функции, вызываемые при создании и уничтожении объектов. Можно указать RTL_NULL, если не требуется задавать эти callback-функции.
  • [out] outType – указатель на идентификатор типа объектов.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosCreateObjectTypeEx()

Назначение

Создает тип объектов.

Параметры

  • [in] name – указатель на имя типа объектов.
  • [in] id – фиктивный параметр. Нужно указать 0.
  • [in] defaultObjSize – размер объектов по умолчанию, в байтах.
  • [in,optional] ops – указатель на структуру, содержащую указатели на callback-функции, вызываемые при создании и уничтожении объектов. Можно указать RTL_NULL, если не требуется задавать эти callback-функции.
  • [in,optional] parentType – идентификатор родительского типа объектов или RTL_NULL, если не требуется наследовать другие типы объектов.
  • [out] outType – указатель на идентификатор типа объектов.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosCreateObjectEx()

Назначение

Создает объект.

Параметры

  • [in] type – идентификатор типа объекта.
  • [in,optional] name – указатель на имя объекта или RTL_NULL, если не требуется задавать имя объекта.
  • [in,optional] size – размер объекта в байтах или 0, чтобы был задан размер объекта по умолчанию.
  • [in,optional] context – указатель на данные, которые будут переданы callback-функции, вызываемой при создании объекта. Можно указать RTL_NULL, если данные передавать не требуется. Callback-функция получит переданные данные через свой параметр context.
  • [out] outObject – указатель на адрес объекта.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

При создании объекта для него выделяется память, которая заполняется нулями.

KosRefObjectType()

Назначение

Инкрементирует счетчик ссылок на тип объектов.

Параметры

  • [in] type – идентификатор типа объектов.

Возвращаемые значения

Нет.

KosPutObjectType()

Назначение

Декрементирует счетчик ссылок на тип объектов.

Параметры

  • [in] type – идентификатор типа объектов.

Возвращаемые значения

Нет.

KosCheckParentType()

Назначение

Проверяет, является ли тип объектов type непосредственным потомком типа объектов parentType.

Параметры

  • [in] type – идентификатор типа объектов.
  • [in] parentType – идентификатор типа объектов.

Возвращаемые значения

В случае успешной проверки возвращает rtl_true, иначе возвращает rtl_false.

KosObjectTypeInheritsType()

Назначение

Проверяет, является ли тип объектов type потомком типа объектов parentType.

Параметры

  • [in] type – идентификатор типа объектов.
  • [in] parentType – идентификатор типа объектов.

Возвращаемые значения

В случае успешной проверки возвращает rtl_true, иначе возвращает rtl_false.

KosCreateObject()

Назначение

Создает объект.

Параметры

  • [in] type – идентификатор типа объекта.
  • [in,optional] name – указатель на имя объекта или RTL_NULL, если не требуется задавать имя объекта.
  • [in,optional] size – размер объекта в байтах или 0, чтобы был задан размер объекта по умолчанию.
  • [out] outObject – указатель на адрес объекта.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

При создании объекта для него выделяется память, которая заполняется нулями.

KosRefObject()

Назначение

Инкрементирует счетчик ссылок на объект.

Параметры

  • [in] object – указатель на объект.

Возвращаемые значения

Нет.

KosPutObject()

Назначение

Декрементирует счетчик ссылок на объект.

Параметры

  • [in] object – указатель на объект.

Возвращаемые значения

Нет.

KosGetObjectName()

Назначение

Позволяет получить имя объекта.

Параметры

  • [in] object – указатель на объект.

Возвращаемые значения

Возвращает идентификатор строки KosString c именем объекта. Тип возвращаемого значения определен в заголовочном файле sysroot-*-kos/include/kos/strings.h из состава KasperskyOS SDK.

Дополнительные сведения

Функция KosGetObjectName() инкрементирует счетчик ссылок на строку KosString c именем объекта. Если эта строка больше не требуется, нужно декрементировать число ссылок на нее вызовом функции KosPutString() из API strings.h.

KosGetObjectParent()

Назначение

Позволяет получить указатель на объект, который является непосредственным предком заданного объекта.

Параметры

  • [in] object – указатель на объект.

Возвращаемые значения

В случае успеха возвращает указатель на объект, который является непосредственным предком заданного объекта, иначе возвращает RTL_NULL.

KosGetObjectAncestor()

Назначение

Позволяет получить указатель на объект, который является предком заданного объекта и имеет заданный тип.

Параметры

  • [in] object – указатель на объект.
  • [in] type – идентификатор типа объекта.

Возвращаемые значения

В случае успеха возвращает указатель на объект, который является предком заданного объекта и имеет заданный тип, иначе возвращает RTL_NULL.

Дополнительные сведения

Если через параметр object задан объект, который имеет тип, заданный через параметр type, функция вернет указатель на этот объект.

KosObjectOfType()

Назначение

Проверяет, имеет ли объект заданный тип.

Параметры

  • [in] object – указатель на объект.
  • [in] type – идентификатор типа объектов.

Возвращаемые значения

В случае успешной проверки возвращает rtl_true, иначе возвращает rtl_false.

KosObjectInheritsType()

Назначение

Проверяет, имеет ли объект заданный тип либо тип, который наследует заданный тип.

Параметры

  • [in] object – указатель на объект.
  • [in] type – идентификатор типа объектов.

Возвращаемые значения

В случае успешной проверки возвращает rtl_true, иначе возвращает rtl_false.

KosObjectGetType()

Назначение

Позволяет получить идентификатор типа объекта.

Параметры

  • [in] object – указатель на объект.

Возвращаемые значения

Идентификатор типа объекта.

Дополнительные сведения

Инкрементирует счетчик ссылок на тип объекта. Если полученный идентификатор типа объекта больше не требуется, нужно декрементировать число ссылок на тип объекта вызовом функции KosPutObjectType().

KosObjectGetTypeName()

Назначение

Позволяет получить имя типа объектов.

Параметры

  • [in] type – идентификатор типа объектов.

Возвращаемые значения

Возвращает идентификатор строки KosString c именем типа объекта. Тип возвращаемого значения определен в заголовочном файле sysroot-*-kos/include/kos/strings.h из состава KasperskyOS SDK.

Дополнительные сведения

Функция KosObjectGetTypeName() инкрементирует счетчик ссылок на строку KosString c именем типа объектов. Если эта строка больше не требуется, нужно декрементировать число ссылок на нее вызовом функции KosPutString() из API strings.h.

В начало
[Topic libkos_objects_api]

Использование контейнеров объектов KosObject (objcontainer.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/objcontainer.h из состава KasperskyOS SDK.

API позволяет объединять объекты KosObject в контейнеры для удобства использования наборов этих объектов (об объектах KosObject см. "Использование объектов KosObject (objects.h)"). Контейнеры также являются объектами KosObject и могу быть элементами других контейнеров. Один и тот же объект KosObject может быть элементом нескольких контейнеров одновременно.

Сведения о функциях API приведены в таблице ниже.

Создание контейнера

Чтобы создать контейнер, нужно вызвать функцию KosCreateObjContainer(). В параметре parent можно указать идентификатор родительского контейнера, то есть контейнера, в который будет добавлен создаваемый контейнер.

Добавление объекта в контейнер

Чтобы добавить объект в контейнер, нужно вызвать функцию KosInsertObjContainerObject(). Объектом может быть другой контейнер. Через параметр name нужно задать имя объекта, которое этот объект будет иметь внутри контейнера. Это имя не связано с именем, которое было задано при создании объекта. Имя объекта внутри контейнера должно быть уникальным, чтобы однозначно идентифицировать этот объект среди других объектов в этом контейнере. Добавление объекта в контейнер инкрементирует счетчик ссылок на этот объект.

Удаление объекта из контейнера

Чтобы удалить объект из контейнера, нужно вызвать функцию KosRemoveObjContainerObjectByName() или KosRemoveObjContainerObject(). Удаление объекта из контейнера декрементирует счетчик ссылок на этот объект.

Поиск объекта в контейнере

Чтобы выполнить поиск объекта с заданным именем в контейнере, нужно вызвать функцию KosGetObjContainerObjectByName(). Поиск объекта в дочерних контейнерах не выполняется. Функция инкрементирует счетчик ссылок на найденный объект.

Перечисление объектов в контейнере

Перечисление может потребоваться, чтобы выполнить какие-либо действия с несколькими объектами в контейнере. Чтобы перечислить объекты в контейнере, нужно вызвать функцию KosWalkObjContainerObjects(). Через параметр walk нужно задать callback-функцию, которая вызывается для каждого объекта при перечислении и получает указатели на объект и данные, переданные функции KosWalkObjContainerObjects() через параметр context. Перечисление объектов в дочерних контейнерах не выполняется.

Перечисление имен объектов в контейнере

Чтобы перечислить имена объектов в контейнере, нужно использовать функцию KosEnumObjContainerNames(). Порядок перечисления имен объектов соответствует порядку добавления этих объектов в контейнер. Перечисление имен объектов в дочерних контейнерах не выполняется.

Получение числа объектов в контейнере

Чтобы получить число объектов в контейнере, нужно вызвать функцию KosCountObjContainerObjects(). Объекты в дочерних контейнерах не учитываются.

Очистка контейнера

Чтобы удалить все объекты из контейнера, нужно вызвать функцию KosClearObjContainer(). Функция декрементирует счетчики ссылок на удаленные из контейнера объекты.

Проверка, является ли объект контейнером

Чтобы проверить, является ли объект контейнером, нужно вызвать функцию KosIsContainer().

Удаление контейнера

Чтобы удалить контейнер, нужно вызвать функцию KosDestroyObjContainer(). Удаление контейнера декрементирует счетчики ссылок на объекты, которые в нем содержались.

Сведения о функциях API

Функции objcontainer.h

Функция

Сведения о функции

KosCreateObjContainer()

Назначение

Создает контейнер.

Параметры

  • [in,optional] parent – идентификатор родительского контейнера или RTL_NULL, если не требуется добавлять создаваемый контейнер в уже существующий.
  • [in] name – указатель на имя создаваемого контейнера.
  • [out] outContainer – идентификатор созданного контейнера.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosDestroyObjContainer()

Назначение

Удаляет контейнер.

Параметры

  • [in] container – идентификатор контейнера.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosInsertObjContainerObject()

Назначение

Добавляет объект в контейнер.

Параметры

  • [in] container – идентификатор контейнера.
  • [in] name – указатель на имя объекта.
  • [in] object – указатель на объект.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRemoveObjContainerObjectByName()

Назначение

Удаляет из контейнера объект с заданным именем.

Параметры

  • [in] container – идентификатор контейнера.
  • [in] name – указатель на имя объекта.
  • [in,optional] object – указатель на объект или RTL_NULL, если не требуется проверять, что имя объекта, заданное через параметр name, соответствует удаляемому объекту.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRemoveObjContainerObject()

Назначение

Удаляет объект из контейнера.

Параметры

  • [in] container – идентификатор контейнера.
  • [in] object – указатель на объект.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosGetObjContainerObjectByName()

Назначение

Выполняет поиск объекта с заданным именем в контейнере.

Параметры

  • [in] container – идентификатор контейнера.
  • [in] name – указатель на имя объекта, поиск которого нужно выполнить.
  • [out] outObject – указатель на адрес найденного объекта.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Если объект с заданным именем не найден, функция передает через параметр outObject значение RTL_NULL.

KosWalkObjContainerObjects()

Назначение

Перечисляет объекты в контейнере и вызывает заданную функцию для каждого объекта при перечислении.

Параметры

  • [in] container – идентификатор контейнера.
  • [in] walk – идентификатор callback-функции, вызываемой для каждого объекта при перечислении. Тип параметра определен в заголовочном файле sysroot-*-kos/include/kos/objects.h из состава KasperskyOS SDK.
  • [in,optional] context – указатель на данные, которые будут переданы callback-функции, заданной через параметр walk. Можно указать RTL_NULL, если данные передавать не требуется. Callback-функция получит эти данные через свой параметр context.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Callback-функция, заданная через параметр walk, не должна вызывать другие функции API.

Если callback-функция, заданная через параметр walk, возвращает значение с флагом KOS_OBJECT_WALK_FINISH, то функция KosWalkObjContainerObjects() прекращает перечисление.

Если callback-функция, заданная через параметр walk, возвращает значение с флагом KOS_OBJECT_WALK_REMOVE_OBJECT, то функция KosWalkObjContainerObjects() удаляет из контейнера соответствующий объект.

Флаги KOS_OBJECT_WALK_FINISH и KOS_OBJECT_WALK_REMOVE_OBJECT определены в заголовочном файле sysroot-*-kos/include/kos/objects.h из состава KasperskyOS SDK.

KosEnumObjContainerNames()

Назначение

Перечисляет имена объектов в контейнере.

Параметры

  • [in] container – идентификатор контейнера.
  • [in] index – индекс для перечисления имен объектов. Нумерация начинается с нуля.
  • [out] outStr – указатель на идентификатор строки KosString с именем объекта.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

Функция KosEnumObjContainerNames() инкрементирует счетчик ссылок на строку KosString c именем объекта. Если эта строка больше не требуется, нужно декрементировать число ссылок на нее вызовом функции KosPutString() из API strings.h.

KosCountObjContainerObjects()

Назначение

Позволяет получить число объектов в контейнере.

Параметры

  • [in] container – идентификатор контейнера.

Возвращаемые значения

Число объектов в контейнере.

KosClearObjContainer()

Назначение

Очищает контейнер.

Параметры

  • [in] container – идентификатор контейнера.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosIsContainer()

Назначение

Проверяет, является ли объект контейнером.

Параметры

  • [in] object – указатель на объект.

Возвращаемые значения

В случае успешной проверки возвращает rtl_true, иначе возвращает rtl_false.

В начало
[Topic libkos_objcontainer_api]

Использование строк KosString (strings.h)

API определен в заголовочном файле sysroot-*-kos/include/kos/strings.h из состава KasperskyOS SDK.

API позволяет использовать строки KosString, которые имеют следующие особенности:

  1. Строка KosString представляет собой C-строку (с терминирующим нулем), следующую за заголовком со служебными данными.
  2. Строки KosString хранятся в хеш-таблицах, представляющих собой массивы, элементами которых являются списки строк. (Указатели для создания связных списков строк хранятся в заголовках строк.) Каждый список состоит из одной или нескольких строк. В одном списке находятся строки, для которых остаток от деления хеш-значения строки на число списков в хеш-таблице имеет одинаковое значение. Основное свойство хеш-таблицы заключается в том, что вычислительная сложность поиска строки не зависит от степени заполнения этой таблицы, если все списки включают только одну строку.

    На практике при добавлении строк KosString в хеш-таблицу могут создаваться списки с несколькими строками, что приводит к варьированию вычислительной сложности поиска строк в хеш-таблице по следующей причине. При выполнении поиска для ключа вычисляется хеш-значение, которое преобразуется в индекс списка строк (вычислением остатка от деления хеш-значения на число списков), и, если в списке с рассчитанным индексом только одна строка, то после сравнения этой строки с ключом поиск будет завершен. Но если в списке с рассчитанным индексом несколько строк, то для завершения поиска может потребоваться сравнить ключ со всеми строками в этом списке. В таком случае вычислительная сложность поиска строки может быть больше, чем в случае с одной строкой в списке.

  3. Строки KosString из одной хеш-таблицы уникальны, то есть в одной хеш-таблице нет одинаковых строк. Если строки из одной хеш-таблицы имеют разные идентификаторы, то это разные строки. (В API идентификатор строки KosString представляет собой указатель на эту строку.) Это позволяет сравнивать строки не по содержимому, а по идентификаторам, что обеспечивает независимость вычислительной сложности сравнения от размеров строк.
  4. Размер строки KosString хранится в заголовке, а не рассчитывается на основе поиска терминирующего нуля, что обеспечивает независимость вычислительной сложности получения размера от фактического размера строки.
  5. Строки KosString нельзя изменять. Эта особенность является следствием особенностей 2-4. Изменение строки может привести к появлению одинаковых строк в одной хеш-таблице, несоответствию фактического размера строки и сохраненного в заголовке, а также несоответствию содержимого строки индексу списка строк, в котором эта строка находится в хеш-таблице.
  6. Строка KosString существует, пока счетчик ссылок на нее больше нуля. (Счетчик ссылок на строку хранится в заголовке.)

Сведения о функциях API приведены в таблице ниже.

Создание хеш-таблицы

Можно использовать хеш-таблицу по умолчанию, которая создается автоматически при инициализации библиотеки libkos. Эта таблица может включать не более 2039 списков строк с размером строк не более 65524 байт без учета терминирующего нуля.

Можно создать хеш-таблицу с требуемым максимальным числом списков строк и требуемым максимальным размером строк вызовом функции KosCreateStringRoot().

Хеш-таблица создается пустой, то есть не содержит строк.

Добавление строки KosString в хеш-таблицу

Чтобы добавить строку в хеш-таблицу по умолчанию, нужно вызывать функцию KosCreateString().

Чтобы добавить строку в заданную хеш-таблицу, нужно вызвать функцию KosCreateStringEx().

Если добавляемая строка уже есть в хеш-таблице, эти функции не добавляют новую строку, а передают через параметр outStr идентификатор уже существующей строки.

Поиск строки KosString в хеш-таблице

Чтобы выполнить поиск строки в хеш-таблице по умолчанию, нужно вызывать функцию KosGetString().

Чтобы выполнить поиск строки в заданной хеш-таблице, нужно вызывать функцию KosGetStringEx().

Поиск завершается успешно, если ключ и строка полностью совпадают.

Управление временем жизни строк KosString

Строка существует, пока счетчик ссылок на нее больше нуля. Функции KosCreateString() и KosCreateStringEx() добавляют в хеш-таблицу строку, счетчик ссылок на которую имеет значение 1. Если строка уже добавлена в хеш-таблицу, эти функции инкрементируют счетчик ссылок на эту строку. Функции KosGetString() и KosGetStringEx() инкрементируют счетчик ссылок на найденную строку. В дальнейшем этот счетчик можно инкрементировать и декрементировать для управления временем жизни строки. Передавая идентификатор строки другому компоненту программы, нужно инкрементировать счетчик ссылок на соответствующую строку, чтобы обеспечить существование этой строки на время, требуемое этому компоненту. Если строка больше не требуется, нужно декрементировать счетчик ссылок на эту строку, чтобы обеспечить ее уничтожение при отсутствии других ссылок.

Чтобы инкрементировать счетчик ссылок на строку, нужно вызвать функцию KosRefString() или KosRefStringEx().

Чтобы декрементировать счетчик ссылок на строку в хеш-таблице по умолчанию, нужно вызывать функцию KosPutString().

Чтобы декрементировать счетчик ссылок на строку в заданной хеш-таблице, нужно вызывать функцию KosPutStringEx().

Получение размера строки KosString

Чтобы получить размер строки без учета терминирующего нуля, нужно вызвать функцию KosGetStringLen().

Чтобы получить размер строки с учетом терминирующего нуля, нужно вызвать функцию KosGetStringSize().

Удаление хеш-таблицы

Чтобы удалить хеш-таблицу, нужно вызвать функцию KosDestroyStringRoot(). Таблица будет удалена только в том случае, если она пустая.

Сведения о функциях API

Функции strings.h

Функция

Сведения о функции

KosCreateStringRoot()

Назначение

Создает пустую хеш-таблицу.

Параметры

  • [in] numBuckets – максимальное число списков строк KosString.
  • [in] maxStrLength – максимальный размер строк KosString без учета терминирующего нуля, в байтах.

Возвращаемые значения

Идентификатор хеш-таблицы.

KosDestroyStringRoot()

Назначение

Удаляет пустую хеш-таблицу.

Параметры

  • [in] handle – идентификатор хеш-таблицы.

Возвращаемые значения

Нет.

KosGetString()

Назначение

Выполняет поиск строки KosString в хеш-таблице по умолчанию.

Параметры

  • [in] str – указатель на C-строку, содержащую ключ поиска.

Возвращаемые значения

В случае успеха возвращает идентификатор строки KosString, иначе возвращает RTL_NULL.

KosGetStringEx()

Назначение

Выполняет поиск строки KosString в заданной хеш-таблице.

Параметры

  • [in,optional] root – идентификатор хеш-таблицы или RTL_NULL, чтобы задать хеш-таблицу по умолчанию.
  • [in] str – указатель на C-строку, содержащую ключ поиска.

Возвращаемые значения

В случае успеха возвращает идентификатор строки KosString, иначе возвращает RTL_NULL.

KosCreateString()

Назначение

Добавляет строку KosString в хеш-таблицу по умолчанию.

Параметры

  • [in] str – указатель на C-строку, данные из которой нужно поместить в строку KosString.
  • [out] outStr – указатель на идентификатор строки KosString.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosCreateStringEx()

Назначение

Добавляет строку KosString в заданную хеш-таблицу.

Параметры

  • [in,optional] root – идентификатор хеш-таблицы или RTL_NULL, чтобы задать хеш-таблицу по умолчанию.
  • [in] str – указатель на C-строку, данные из которой нужно поместить в строку KosString.
  • [out] outStr – указатель на идентификатор строки KosString.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KosRefString()

Назначение

Инкрементирует счетчик ссылок на строку KosString.

Параметры

  • [in] str – идентификатор строки KosString.

Возвращаемые значения

Нет.

KosRefStringEx()

Назначение

Инкрементирует счетчик ссылок на строку KosString.

Параметры

  • [in,optional] root – фиктивный параметр. Нужно указать RTL_NULL.
  • [in] str – идентификатор строки KosString.

Возвращаемые значения

Нет.

KosPutString()

Назначение

Декрементирует счетчик ссылок на строку KosString в хеш-таблице по умолчанию.

Параметры

  • [in] str – идентификатор строки KosString.

Возвращаемые значения

Нет.

KosPutStringEx()

Назначение

Декрементирует счетчик ссылок на строку KosString в заданной хеш-таблице.

Параметры

  • [in,optional] root – идентификатор хеш-таблицы или RTL_NULL, чтобы задать хеш-таблицу по умолчанию.
  • [in] str – идентификатор строки KosString.

Возвращаемые значения

Нет.

KosGetStringLen()

Назначение

Позволяет получить размер строки KosString без учета терминирующего нуля.

Параметры

  • [in] str – идентификатор строки KosString.

Возвращаемые значения

Размер строки KosString без учета терминирующего нуля, в байтах.

Дополнительные сведения

Если параметр имеет значение RTL_NULL, возвращает 0.

KosGetStringSize()

Назначение

Позволяет получить размер строки KosString с учетом терминирующего нуля.

Параметры

  • [in] str – идентификатор строки KosString.

Возвращаемые значения

Размер строки KosString с учетом терминирующего нуля, в байтах.

Дополнительные сведения

Если параметр имеет значение RTL_NULL, возвращает 0.

В начало
[Topic libkos_strings_api]

Управление драйвером XHCI DbC ядра KasperskyOS (xhcidbg_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/xhcidbg/xhcidbg_api.h из состава KasperskyOS SDK.

API предназначен для использования в коде драйверов, реализующих стек USB (драйверов класса kusb), и позволяет останавливать и запускать драйвер XHCI DbC (Debug Capability) ядра KasperskyOS. (Ядро KasperskyOS включает драйвер XHCI DbC, который представляет собой упрощенный драйвер контроллера XHCI и используется ядром для диагностического вывода либо GDB-сервером ядра для взаимодействия с отладчиком GDB.) Если драйверу класс kusb нужно перезагрузить контроллер XHCI, то драйвер XHCI DbC ядра необходимо остановить вызовом функции KnXhcidbgStop() перед перезагрузкой и запустить вызовом функции KnXhcidbgStart() после перезагрузки. Если этого не сделать, перезагрузка контроллера XHCI приведет к невозможности выполнять диагностический вывод (или отладку) через порт USB.

Для аппаратных платформ Raspberry Pi 4 B и Radxa ROCK 3A API не реализован (функции возвращают rcUnimplemented).

Сведения о функциях API приведены в таблице ниже.

Функции xhcidbg_api.h

Функция

Сведения о функции

KnXhcidbgStart()

Назначение

Запускает драйвер XHCI DbC ядра KasperskyOS.

Параметры

Нет.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnXhcidbgStop()

Назначение

Останавливает драйвер XHCI DbC ядра KasperskyOS.

Параметры

Нет.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_xhcidbg_api]

Получение данных аудита безопасности (vlog_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/vlog/vlog_api.h из состава KasperskyOS SDK.

API позволяет выполнять чтение из журнала ядра KasperskyOS с данными аудита безопасности и используется в коде статической библиотеки sysroot-*-kos/lib/libklog_system_audit.a, компонуемой с системной программой Klog.

Сведения о функциях API приведены в таблице ниже.

Использование API

Сценарий использования API включает следующие шаги:

  1. Открытие журнала ядра с данными аудита безопасности вызовом функции KnAuOpen().
  2. Получение сообщений из журнала ядра с данными аудита безопасности вызовами функции KnAuRead().

    Журнал представляет собой циклический буфер, поэтому нужно не допускать перезаписи в нем, поскольку это приведет к потере еще не считанных данных аудита безопасности. Для контроля перезаписи в журнале через параметр outDropMsgs функции KnAuRead() передается число потерянных сообщений. (Счетчик этих сообщений обнуляется после считывания его значения при каждом вызове функции.) При наличии потерянных сообщений нужно либо увеличить скорость считывания сообщений из журнала, например, выполняя считывание из параллельных потоков исполнения, либо снизить скорость генерации сообщений, изменив профиль аудита безопасности.

  3. Закрытие журнала ядра с данными аудита безопасности вызовом функции KnAuClose().

Сведения о функциях API

Функции vlog_api.h

Функция

Сведения о функции

KnAuOpen()

Назначение

Открывает журнал ядра с данными аудита безопасности.

Параметры

  • [in] name – указатель на имя журнала ядра с данными аудита безопасности (нужно указать kss).
  • [out] outRID – указатель на дескриптор журнала ядра с данными аудита безопасности.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnAuClose()

Назначение

Закрывает журнал ядра с данными аудита безопасности.

Параметры

  • [in] rid – дескриптор журнала ядра с данными аудита безопасности.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnAuRead()

Назначение

Позволяет получить сообщение из журнала ядра с данными аудита безопасности.

Параметры

  • [in] rid – дескриптор журнала ядра с данными аудита безопасности.
  • [out] msg – указатель на буфер для сохранения сообщения. Тип сообщения определен в заголовочном файле sysroot-*-kos/include/vlog/audit.h. Размер буфера должен быть не меньше FULL_AUDIT_MESSAGE_LENGTH_MAX байт.
  • [out] outDropMsgs – указатель на число сообщений, которые были потеряны из-за перезаписи в журнале ядра с данными аудита безопасности.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_vlog_api]

Использование фьютексов (sync.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/sync/sync.h из состава KasperskyOS SDK.

API предназначен для работы с фьютексами и используется в коде функций API event.h, mutex.h, rwlock.h, semaphore.h, condvar.h. Фьютекс – низкоуровневый примитив синхронизации, для которого поддерживается две операции: блокировка потока исполнения с его добавлением в связанную с фьютексом очередь заблокированных потоков исполнения и возобновление исполнения потоков из связанной с фьютексом очереди заблокированных потоков исполнения. Фьютекс представляет собой объект ядра связанный с целочисленной переменной в пользовательском пространстве. Объект ядра обеспечивает возможность хранить очередь заблокированных потоков исполнения, связанную с фьютексом. Значение целочисленной переменной в пользовательском пространстве (значение фьютекса) атомарно изменяется синхронизируемыми потоками исполнения, чтобы сигнализировать об изменении состояния разделяемых ресурсов. Например, значение фьютекса может отражать, в каком состоянии находится событие (сигнальном или несигнальном), захвачен или освобожден мьютекс, какое значение имеет счетчик семафора. От значения фьютекса зависит, будет ли заблокирован поток исполнения, который пытается получить доступ к разделяемым ресурсам.

Сведения о функциях API приведены в таблице ниже.

Использование API

Чтобы использовать фьютекс, нужно создать только целочисленную переменную для хранения его значения. Функции API принимают указатель на эту переменную через параметр ftx. Создание и удаление объекта ядра, связанного с этой переменной, выполняется автоматически при использовании функций API.

Функция KnFutexWait() блокирует вызывающий поток исполнения, если значение фьютекса совпадает со значением параметра val. (Значение фьютекса может быть изменено другим потоком исполнения во время выполнения функции.) Поток исполнения блокируется на время mdelay, но исполнение этого потока может быть возобновлено до истечения времени mdelay вызовом функции KnFutexWake() из другого потока исполнения. Функция KnFutexWake() возобновляет исполнение потоков из связанной с фьютексом очереди заблокированных потоков исполнения. Число потоков, исполнение которых возобновляется, ограничено значением параметра nThreads. Возобновление исполнения потоков начинается с начала очереди.

Сведения о функциях API

Функции sync.h

Функция

Сведения о функции

KnFutexWait()

Назначение

Блокирует вызывающий поток исполнения, если значение фьютекса равно ожидаемому.

Параметры

  • [in] ftx – указатель на переменную со значением фьютекса.
  • [in] val – ожидаемое значение фьютекса.
  • [in] mdelay – максимальное время блокировки в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время блокировки.
  • [out,optional] outDelay – фактическое время блокировки в миллисекундах или RTL_NULL, если эти сведения не требуются.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если время блокировки потока исполнения истекло, возвращает rcTimeout.

Если значение фьютекса не равно ожидаемому, возвращает rcFutexWouldBlock.

KnFutexWake()

Назначение

Возобновляет исполнение потоков, заблокированных вызовами функции KnFutexWait() с заданным фьютексом.

Параметры

  • [in] ftx – указатель на переменную со значением фьютекса.
  • [in] nThreads – максимальное число потоков, исполнение которых может быть возобновлено.
  • [out,optional] wokenCnt – фактическое число потоков, исполнение которых возобновлено, или RTL_NULL, если эти сведения не требуются.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_futex_sync_api]

Получение IPC-дескрипторов и идентификаторов служб для использования статически созданных IPC-каналов (sl_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/sl/sl_api.h из состава KasperskyOS SDK.

API позволяет серверам получать слушающие дескрипторы, а клиентам получать клиентские IPC-дескрипторы и идентификаторы служб (RIIDs) для использования статически созданных IPC-каналов.

Закрытие полученного IPC-дескриптора приведет к недоступности IPC-канала. Если IPC-дескриптор был закрыт, то получить его повторно и восстановить доступ к IPC-каналу невозможно.

Сведения о функциях API приведены в таблице ниже.

Функции sl_api.h

Функция

Сведения о функции

ServiceLocatorRegister()

Назначение

Позволяет получить слушающий дескриптор по имени IPC-канала.

Параметры

  • [in] channelName – указатель на имя IPC-канала.
  • [in] endpoints – фиктивный параметр (устарел). Должен иметь значение RTL_NULL.
  • [in] endpointsSize – фиктивный параметр (устарел). Должен иметь значение 0.
  • [out] id – фиктивный параметр (устарел).

Возвращаемые значения

В случае успеха возвращает слушающий дескриптор, иначе возвращает INVALID_HANDLE.

ServiceLocatorConnect()

Назначение

Позволяет получить клиентский IPC-дескриптор по имени IPC-канала.

Параметры

  • [in] channelName – указатель на имя IPC-канала.

Возвращаемые значения

В случае успеха возвращает клиентский IPC-дескриптор, иначе возвращает INVALID_HANDLE.

ServiceLocatorGetRiid()

Назначение

Позволяет получить идентификатор службы (RIID).

Параметры

Возвращаемые значения

В случае успеха возвращает идентификатор службы (RIID), иначе возвращает INVALID_RIID. Тип возвращаемого значения определен в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK.

В начало
[Topic libkos_sl_api]

Управление электропитанием (pm_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/pm/pm_api.h из состава KasperskyOS SDK.

API позволяет изменять режим электропитания аппаратной платформы (например, выключать, перезагружать), а также включать и выключать процессоры (вычислительные ядра).

Сведения о функциях API приведены в таблице ниже.

Использование API

Чтобы выполнить запрос на изменение режима электропитания аппаратной платформы, нужно вызвать функцию KnPmRequest().

Функции KnPmSetCpusOnline() и KnPmGetCpusOnline() имеют параметр mask, через который передается маска процессов. Маска процессоров – битовая маска, отражающая набор процессоров (вычислительных ядер). Флаг, установленный в i-ом бите, отражает, что процессор с индексом i входит в набор (нумерация начинается с нуля). Для работы с маской процессоров нужно использовать функции, определенные в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h.

Чтобы включить и/или выключить процессоры, нужно вызвать функцию KnPmSetCpusOnline(), указав маску процессоров, отражающую требуемый набор активных процессоров. В этой маске должен быть установлен флаг, соответствующий процессору загрузки (англ. bootstrap processor), иначе функция завершится с ошибкой. Чтобы получить индекс процессора загрузки, нужно вызвать функцию KnPmGetBootstrapCpuNum().

Чтобы получить сведения о том, какие процессоры находятся в активном состоянии, нужно вызвать функцию KnPmGetCpusOnline(). Выходным параметром этой функции является маска процессоров, отражающая фактический набор активных процессоров.

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

Сведения о функциях API

Функции pm_api.h

Функция

Сведения о функции

KnPmRequest()

Назначение

Выполняет запрос на изменение режима электропитания аппаратной платформы.

Параметры

  • [in] request – значение, задающее требуемый режим электропитания аппаратной платформы. Тип параметра определен в заголовочном файле sysroot-*-kos/include/pm/pmstate.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnPmSetCpusOnline()

Назначение

Выполняет запрос на включение и/или выключение процессоров.

Параметры

  • [in] mask – указатель на маску процессоров, отражающую требуемый набор активных процессоров. Тип маски процессоров определен в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.
  • [in] timeoutMs – фиктивный параметр (устарел).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnPmGetCpusOnline()

Назначение

Позволяет получить сведения о том, какие процессоры находятся в активном состоянии.

Параметры

  • [out] mask – указатель на маску процессоров, отражающую фактический набор активных процессоров. Тип маски процессоров определен в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnPmGetBootstrapCpuNum()

Назначение

Позволяет получить индекс процессора загрузки.

Параметры

  • [out] num – указатель на индекс процессора загрузки. Тип индекса процессора определен в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic libkos_pm_api][Topic posix_api]

Ограничения поддержки POSIX

В KasperskyOS ограниченно реализован POSIX с ориентацией на стандарт POSIX.1-2008. Прежде всего ограничения связаны с обеспечением безопасности.

Отсутствует поддержка XSI и опциональной функциональности.

Ограничения затрагивают:

  • взаимодействие между процессами;
  • взаимодействие между потоками исполнения посредством сигналов;
  • асинхронный ввод-вывод;
  • использование робастных мьютексов;
  • работу с терминалом;
  • работу с оболочкой;
  • управление дескрипторами файлов;
  • использование таймеров;
  • получение системных параметров.

Ограничения представлены:

  • нереализованными интерфейсами;
  • интерфейсами, которые реализованы с отклонениями от стандарта POSIX.1-2008;
  • интерфейсами-заглушками, которые не выполняют никаких действий, кроме присвоения переменной errno значения ENOSYS и возвращения значения -1.

В KasperskyOS сигналы не могут прервать системные вызовы Call(), Recv(), Reply(), которые обеспечивают работу библиотек, реализующих интерфейс POSIX.

Ядро KasperskyOS не посылает сигналы.

На аппаратных платформах с процессорной архитектурой Arm входные и выходные параметры интерфейсов POSIX нельзя сохранять в памяти типа "Device memory", поскольку это может привести к неопределенному поведению. Параметры интерфейсов POSIX нужно сохранять в памяти типа "Normal memory". Чтобы копировать данные из памяти типа "Device memory" в память типа "Normal memory" и обратно, нужно использовать функцию RtlPedanticMemcpy(), объявленную в заголовочном файле sysroot-*-kos/include/rtl/string_pedantic.h из состава KasperskyOS SDK.

Ограничения взаимодействия между процессами

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

fork()

Создать новый (дочерний) процесс.

Не реализован.

unistd.h

pthread_

atfork()

Зарегистрировать обработчики, которые вызываются перед и после создания дочернего процесса.

Не реализован.

pthread.h

wait()

Ожидать остановки или завершения дочернего процесса.

Заглушка.

sys/wait.h

waitid()

Ожидать изменения состояния дочернего процесса.

Не реализован.

sys/wait.h

waitpid()

Ожидать остановки или завершения дочернего процесса.

Заглушка.

sys/wait.h

execl()

Запустить исполняемый файл.

Не реализован.

unistd.h

execle()

Запустить исполняемый файл.

Не реализован.

unistd.h

execlp()

Запустить исполняемый файл.

Не реализован.

unistd.h

execv()

Запустить исполняемый файл.

Не реализован.

unistd.h

execve()

Запустить исполняемый файл.

Не реализован.

unistd.h

execvp()

Запустить исполняемый файл.

Не реализован.

unistd.h

fexecve()

Запустить исполняемый файл.

Не реализован.

unistd.h

setpgid()

Перевести процесс в другую группу или создать группу.

Заглушка.

unistd.h

setsid()

Создать сессию.

Заглушка.

unistd.h

getpgrp()

Получить идентификатор группы вызывающего процесса.

Заглушка.

unistd.h

getpgid()

Получить идентификатор группы.

Заглушка.

unistd.h

getppid()

Получить идентификатор родительского процесса.

Заглушка.

unistd.h

getsid()

Получить идентификатор сессии.

Заглушка.

unistd.h

times()

Получить значения времени для процесса и его потомков.

Заглушка.

sys/times.h

kill()

Послать сигнал процессу или группе процессов.

Можно посылать только сигнал SIGTERM. Параметр pid игнорируется.

signal.h

pause()

Ожидать сигнала.

Заглушка.

unistd.h

sigpending()

Проверить наличие полученных заблокированных сигналов.

Не реализован.

signal.h

sigqueue()

Послать сигнал процессу.

Не реализован.

signal.h

sigtimedwait()

Ожидать сигнала из заданного набора сигналов.

Не реализован.

signal.h

sigwaitinfo()

Ожидать сигнала из заданного набора сигналов.

Не реализован.

signal.h

sem_init()

Создать неименованный семафор.

Нельзя создать неименованный семафор для синхронизации между процессами. Если передать ненулевое значение через параметр pshared, то только вернет значение -1 и присвоит переменной errno значение ENOTSUP.

semaphore.h

sem_open()

Создать/открыть именованный семафор.

Нельзя открыть именованный семафор, который был создан другим процессом. Именованные семафоры (как и неименованные) являются локальными, то есть они доступны только тому процессу, который их создал.

semaphore.h

pthread_

spin_init()

Создать спин-блокировку.

Нельзя создать спин-блокировку для синхронизации между процессами. Если передать значение PTHREAD_PROCESS_SHARED через параметр pshared, то это значение будет проигнорировано.

pthread.h

mmap()

Отобразить в память.

Нельзя выполнить отображение в память для взаимодействия между процессами. Если передать значения MAP_SHARED и PROT_WRITE через параметры flags и prot соответственно, то только вернет значение MAP_FAILED и присвоит переменной errno значение EACCES. Для остальных возможных значений параметра prot значение MAP_SHARED параметра flags игнорируется. Кроме того, через параметр prot нельзя передавать сочетания флагов PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC и при некоторых конфигурациях ядра KasperskyOS PROT_READ|PROT_EXEC. В этом случае только вернет значение MAP_FAILED и присвоит переменной errno значение ENOMEM.

sys/mman.h

mprotect()

Задать права доступа к памяти.

Для целей безопасности некоторые конфигурации ядра KasperskyOS запрещают предоставлять доступ к регионам виртуальной памяти на запись и исполнение одновременно. Если при использовании такой конфигурации ядра через параметр prot передать значение PROT_WRITE|PROT_EXEC, то только вернет значение -1 и присвоит переменной errno значение ENOTSUP.

sys/mman.h

pipe()

Создать неименованный канал.

Нельзя использовать неименованный канал для передачи данных между процессами. Неименованные каналы являются локальными, то есть они доступны только тому процессу, который их создал.

unistd.h

mkfifo()

Создать специальный файл FIFO (именованный канал).

Заглушка.

sys/stat.h

mkfifoat()

Создать специальный файл FIFO (именованный канал).

Не реализован.

sys/stat.h

Ограничения взаимодействия между потоками исполнения посредством сигналов

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

pthread_kill()

Послать сигнал потоку исполнения.

Нельзя послать сигнал потоку исполнения. Если передать номер сигнала через параметр sig, то только возвращается значение ENOSYS.

signal.h

siglongjmp()

Восстановить состояние потока управления и маску сигналов.

Не реализован.

setjmp.h

sigsetjmp()

Сохранить состояние потока управления и маску сигналов.

Не реализован.

setjmp.h

Ограничения асинхронного ввода-вывода

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

aio_cancel()

Отменить запросы ввода-вывода, которые ожидают обработки.

Не реализован.

aio.h

aio_error()

Получить ошибку операции асинхронного ввода-вывода.

Не реализован.

aio.h

aio_fsync()

Запросить выполнение операций ввода-вывода.

Не реализован.

aio.h

aio_read()

Запросить чтение из файла.

Не реализован.

aio.h

aio_return()

Получить статус операции асинхронного ввода-вывода.

Не реализован.

aio.h

aio_suspend()

Ожидать завершения операций асинхронного ввода-вывода.

Не реализован.

aio.h

aio_write()

Запросить запись в файл.

Не реализован.

aio.h

lio_listio()

Запросить выполнение набора операций ввода-вывода.

Не реализован.

aio.h

Ограничения использования робастных мьютексов

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

pthread_mutex_consistent()

Вернуть робастный мьютекс в консистентное состояние.

Не реализован.

pthread.h

pthread_mutexattr_getrobust()

Получить атрибут робастности мьютекса.

Не реализован.

pthread.h

pthread_mutexattr_setrobust()

Задать атрибут робастности мьютекса.

Не реализован.

pthread.h

Ограничения работы с терминалом

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

ctermid()

Получить путь к файлу управляющего терминала.

Только возвращает или передает через параметр s пустую строку.

stdio.h

tcsetattr()

Задать параметры терминала.

Скорость ввода, скорость вывода и другие параметры, специфичные для аппаратных терминалов, игнорируются.

termios.h

tcdrain()

Ожидать завершения вывода.

Только возвращает значение -1.

termios.h

tcflow()

Приостановить или возобновить прием или передачу данных.

Приостановка вывода и запуск приостановленного вывода не поддерживаются.

termios.h

tcflush()

Очистить очередь ввода или очередь вывода, или обе эти очереди.

Только возвращает значение -1.

termios.h

tcsendbreak()

Разорвать соединение с терминалом на заданное время.

Только возвращает значение -1.

termios.h

ttyname()

Получить путь к файлу терминала.

Только возвращает нулевой указатель.

unistd.h

ttyname_r()

Получить путь к файлу терминала.

Только возвращает значение ошибки.

unistd.h

tcgetpgrp()

Получить идентификатор группы процессов, использующих терминал.

Только возвращает значение -1.

unistd.h

tcsetpgrp()

Задать идентификатор группы процессов, использующих терминал.

Только возвращает значение -1.

unistd.h

tcgetsid()

Получить идентификатор группы процессов для лидера сессии, связанной с терминалом.

Только возвращает значение -1.

termios.h

Ограничения работы с оболочкой

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

popen()

Создать дочерний процесс для выполнения команды и неименованный канал с этим процессом.

Не реализован.

stdio.h

pclose()

Закрыть неименованный канал с дочерним процессом, созданным popen(), и ожидать завершения дочернего процесса.

Не реализован.

stdio.h

system()

Создать дочерний процесс для выполнения команды.

Заглушка.

stdlib.h

wordexp()

Раскрыть строку как в оболочке.

Не реализован.

wordexp.h

wordfree()

Освободить память, выделенную для результатов вызова wordexp().

Не реализован.

wordexp.h

Ограничения управления дескрипторами файлов

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

dup()

Сделать копию дескриптора открытого файла.

Поддерживаются дескрипторы обычных файлов, стандартных потоков ввода-вывода, сокетов и каналов. Не гарантируется, что будет получен наименьший свободный дескриптор.

fcntl.h

dup2()

Сделать копию дескриптора открытого файла.

Поддерживаются дескрипторы обычных файлов, стандартных потоков ввода-вывода, сокетов и каналов. Через параметр fildes2 нужно передавать дескриптор открытого файла.

fcntl.h

Ограничения использования таймеров

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

clock_gettime()

Получить значение времени.

Если передать значение CLOCK_PROCESS_CPUTIME_ID или CLOCK_THREAD_CPUTIME_ID через параметр clock_id, то только вернет значение -1 и присвоит переменной errno значение EINVAL.

time.h

clock()

Получить процессорное время, затраченное на исполнение вызывающего процесса.

Возвращает время с момента запуска ядра KasperskyOS в миллисекундах.

time.h

Получение системных параметров

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

confstr()

Получить системный параметр.

Заглушка.

unistd.h

В начало
[Topic posix_uns_ifaces]

Особенности реализации POSIX

В KasperskyOS реализация некоторых интерфейсов POSIX в части, которая не определяется стандартом POSIX.1-2008, отличается от реализации этих интерфейсов в Linux и других UNIX-подобных операционных системах. Сведения об этих интерфейсах приведены в таблице ниже.

Интерфейсы POSIX с особенностями реализации

Интерфейс

Назначение

Реализация

Заголовочный файл по стандарту POSIX.1-2008

bind()

Назначить имя сокету.

При использовании версии VFS, которая поддерживает только сетевые операции, файлы сокетов семейства AF_UNIX при вызове bind() сохраняются в специальной файловой системе, реализуемой этой версией VFS. Файл сокета может быть создан только в корне файловой системы или в директории /tmp, а также может быть повторно использован после закрытия сокета.

sys/socket.h

mmap()

Отобразить в память.

Флаг MAP_FIXED в параметре flags не поддерживается.

На аппаратных платформах с процессорной архитектурой AArch64 (Arm64) нельзя выполнить отображение более 4 ГБ.

sys/mman.h

read()

Выполнить чтение из файла.

Если размер буфера buf превышает размер считанных данных, то оставшаяся часть этого буфера заполняется нулями.

unistd.h

В начало
[Topic posix_ifaces_impl_features]

Совместное использование POSIX и API libkos

В потоке исполнения, созданном с помощью Pthreads, нельзя использовать следующие API libkos:

Следующие API libkos можно использовать совместно с Pthreads (и другими API POSIX):

Интерфейсы POSIX нельзя использовать в потоках исполнения, созданных с помощью API thread.h и thread_api.h.

API syscalls.h можно использовать в любых потоках исполнения, созданных с использованием Pthreads или API thread.h и thread_api.h.

В начало
[Topic posix_and_libkos]

Получение статистических сведений о системе через API библиотеки libc

Библиотека libc предоставляет API, которые позволяют получить статистические сведения о файловых системах и сетевых интерфейсах, управляемых VFS. Функции этих API приведены в таблице ниже.

Сведения о файловых системах и сетевых интерфейсах

Функция

Заголовочный файл из состава KasperskyOS SDK

Получаемые сведения

statvfs()

sysroot-*-kos/include/strict/posix/sys/statvfs.h

Сведения о файловой системе, такие как размер блока, число блоков, число свободных блоков

getvfsstat()

sysroot-*-kos/include/sys/statvfs.h

Сведения обо всех смонтированных файловых системах, идентичные предоставляемым функцией statvfs()

getifaddrs()

sysroot-*-kos/include/ifaddrs.h

Сведения о сетевых интерфейсах, такие как имя, IP-адрес, маска подсети

В начало
[Topic sys_inf_libc]

Динамическое создание IPC-каналов с использованием системной программы DCM

В составе KasperskyOS SDK поставляется системная программа DCM (Dynamic Connection Manager), которая позволяет динамически создавать IPC-каналы. Благодаря этой программе серверы могут сообщать клиентам о предоставляемых службах, а также передавать callable-дескрипторы для использования этих служб.

Для использования программы DCM в составе KasperskyOS SDK поставляются следующие файлы:

  • sysroot-*-kos/include/dcm/dcm_api.h – заголовочный файл, в котором определен базовый API.
  • sysroot-*-kos/include/dcm/groups/pub.h – заголовочный файл, в котором определен дополнительный API для серверов.
  • sysroot-*-kos/include/dcm/groups/subscr.h – заголовочный файл, в котором определен дополнительный API для клиентов.
  • sysroot-*-kos/include/dcm/dcm.h – заголовочный файл для включения в исходный код клиентов и серверов.
  • sysroot-*-kos/bin/dcm – исполняемый файл.
  • sysroot-*-kos/lib/libdcm.a – клиентская библиотека.
  • sysroot-*-kos/lib/libdcm_s.a – клиентская библиотека, собранная с флагом -fPIC для обеспечения возможности компоновки с динамической библиотекой.
  • sysroot-*-kos/include/kl/core/DCM.*dl – файлы формальной спецификации.

IPC-каналы от клиентов и серверов к DCM нужно создать статически.

Можно запустить несколько процессов программы DCM. При этом каждый клиент и сервер может быть соединен только с одним процессом программы DCM.

В API программы DCM используются идентификаторы, которые называются DCM-дескрипторами (англ. DCM handles). DCM-дескрипторы идентифицируют объекты, которые дают клиентам и серверам, использующим DCM, следующие возможности:

  • Клиенты могут получать уведомления о публикации и отмене публикации служб, а также выполнять запросы на создание IPC-каналов с серверами.
  • Серверы могут получать запросы клиентов на создание IPC-каналов, а также принимать или отклонять эти запросы.

Имена служб и интерфейсов служб нужно задавать в соответствии с формальными спецификациями компонентов решения. (О квалифицированном имени службы см. "Привязка методов моделей безопасности к событиям безопасности".) Вместо квалифицированного имени службы можно использовать какое-либо условное название этой службы. Имена клиентов и серверов задаются в init-описании.

В этом разделе

Использование базового API (dcm_api.h)

Использование дополнительного API для серверов (pub.h)

Использование дополнительного API для клиентов (subscr.h)

В начало
[Topic dcm_api]

Использование базового API (dcm_api.h)

Сведения о функциях API приведены в таблице ниже.

Динамическое создание IPC-канала на стороне сервера

Динамическое создание IPC-канала на стороне сервера включает следующие шаги:

  1. Создать подключение к DCM вызовом функции DcmInit().
  2. Опубликовать предоставляемые службы в 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-дескриптор, созданный при ее публикации. Также публикация всех опубликованных служб сервера будет отменена, если сервер завершится.

  3. Получить запрос клиента на создание IPC-канала вызовом функции DcmListen().

    Вызовы функции DcmListen() с одним и тем же DCM-дескриптором в параметре pubHandle позволяют получить только те запросы клиентов, которые направлены на создание IPC-каналов для использования той службы с тем интерфейсом, которые были заданы при создании этого DCM-дескриптора на шаге 2.

    Через опциональные параметры outClientHandle и outClientName функции DcmListen() можно получить дескриптор, идентифицирующий клиента, и имя клиента соответственно. (Дескриптор, идентифицирующий клиента, является потомком дескриптора, указанного в параметре clientHandle функции DcmCreateConnection(), вызванной на стороне клиента.) Эти данные можно использовать, чтобы принять решение о принятии или отклонении запроса клиента. При этом дескриптор, идентифицирующий клиента, может быть использован, например, для получения сведений о клиенте от других процессов или для получения SID по этому дескриптору для сравнения с другими имеющимся у сервера дескрипторами, идентифицирующими клиентов. После принятия решения можно закрыть дескриптор, идентифицирующий клиента.

    В результате вызова функции DcmListen() создается DCM-дескриптор, позволяющий принять или отклонить запрос клиента на создание IPC-канала.

  4. Принять запрос клиента на создание 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-канала на стороне клиента включает следующие шаги:

  1. Создать подключение к DCM вызовом функции DcmInit().
  2. Создать DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации служб с заданным интерфейсом.

    Чтобы выполнить этот шаг, нужно вызвать функцию DcmSetSubscription().

    Опциональные параметры endpointName, serverName и serverHandle функции DcmSetSubscription() нужно использовать, чтобы включить фильтрацию уведомлений по квалифицированному имени службы, имени сервера и дескриптору, идентифицирующему сервер, соответственно. (Дескриптор, идентифицирующий сервер, является потомком дескриптора, указанного в параметре serverHandle функции DcmPublishEndpoint(), вызванной на стороне сервера. Клиент может получить этот дескриптор, например, от другого процесса.)

    В результате вызова функции DcmSetSubscription() создается DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации служб с заданным интерфейсом. При этом формируется очередь уведомлений о публикации служб, которые были опубликованы до вызова DcmSetSubscription() и соответствуют критериям фильтрации. Если больше не требуется получать уведомления о публикации и отмене публикации служб с заданным интерфейсом, то этот DCM-дескриптор нужно закрыть вызовом функции DcmCloseHandle().

  3. Извлечь уведомление о публикации службы из очереди этих уведомлений вызовом функции DcmReadPubQueue().

    В параметре subscrHandle функции DcmReadPubQueue() нужно указать DCM-дескриптор, полученный на шаге 2.

    Через опциональные параметры outServerHandle, outServerName и outEndpointName функции DcmReadPubQueue() можно получить дескриптор, идентифицирующий сервер, имя сервера и квалифицированное имя службы соответственно. (Дескриптор, идентифицирующий сервер, является потомком дескриптора, указанного в параметре serverHandle функции DcmPublishEndpoint(), вызванной на стороне сервера.) Эти данные можно использовать, чтобы принять решение о выполнении запроса на создание IPC-канала с сервером. При этом дескриптор, идентифицирующий сервер, может быть использован, например, для получения сведений о сервере от других процессов или для получения SID по этому дескриптору для сравнения с другими имеющимися у клиента дескрипторами, идентифицирующими серверы.

    Значение, полученное через параметр outPubStatus функции DcmReadPubQueue(), отражает, что служба опубликована, или публикация службы отменена. Уведомление об отмене публикации службы появляется, если сервер отменил публикацию этой службы, а также при завершении сервера.

  4. Создать 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-канала с сервером для использования заданной службы с заданным интерфейсом.

  5. Выполнить запрос на создание 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

Функция

Сведения о функции

DcmInit()

Назначение

Создает подключение к DCM.

Параметры

Нет.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если IPC-канал до DCM отсутствует, возвращает rcNoCapability.

Дополнительные сведения

Потокобезопасная функция.

Неблокирующий вызов.

DcmFini()

Назначение

Удаляет подключение к DCM.

Параметры

Нет.

Возвращаемые значения

Нет.

Дополнительные сведения

Потокобезопасная функция.

Неблокирующий вызов.

DcmSubscribeToEvents()

Назначение

Настраивает приемник уведомлений, чтобы он получал уведомления о событиях, связанных с объектом, идентифицируемым заданным DCM-дескриптором.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] handle – DCM-дескриптор, полученный вызовом функции DcmSetSubscription(), DcmCreateConnection() или DcmPublishEndpoint().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmUnsubscribeFromEvents()

Назначение

Настраивает приемник уведомлений, чтобы он не получал уведомления о событиях, связанных с объектом, идентифицируемым заданным DCM-дескриптором.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] handle – DCM-дескриптор, полученный вызовом функции DcmSetSubscription(), DcmCreateConnection() или DcmPublishEndpoint().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmCloseHandle()

Назначение

Закрывает DCM-дескриптор, полученный вызовом функции DcmSetSubscription(), DcmCreateConnection(), DcmPublishEndpoint() или DcmListen() из основного API, а также DcmListenGroupPub() из дополнительного API для серверов.

Параметры

  • [in] handle – DCM-дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmInterruptBlockingCall()

Назначение

Прерывает блокирующий вызов функции DcmConnect(), DcmReadPubQueue() или DcmListen().

Параметры

  • [in] handle – DCM-дескриптор, указанный при вызове функции DcmConnect(), DcmReadPubQueue() или DcmListen().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmSetSubscription()

Назначение

Создает DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации служб с заданным интерфейсом.

Параметры

  • [in] endpointType – указатель на имя интерфейса служб.
  • [in,optional] endpointName – указатель на квалифицированное имя службы или RTL_NULL, чтобы не использовать фильтрацию уведомлений по квалифицированному имени службы.
  • [in,optional] serverName – указатель на имя сервера или RTL_NULL, чтобы не использовать фильтрацию уведомлений по имени сервера.
  • [in,optional] serverHandle – дескриптор, идентифицирующий сервер, или INVALID_HANDLE, чтобы не использовать фильтрацию уведомлений по конкретному серверу.
  • [out] outSubscrHandle – указатель на DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации служб с заданным интерфейсом.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmReadPubQueue()

Назначение

Извлекает уведомление о публикации или отмене публикации службы из очереди этих уведомлений.

Параметры

  • [in] subscrHandle – DCM-дескриптор, созданный вызовом функции DcmSetSubscription().
  • [in] msec – время ожидания появления уведомлений в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [out,optional] outServerHandle – указатель на дескриптор, идентифицирующий сервер, или RTL_NULL, если этот дескриптор не требуется.
  • [out,optional] outServerName – указатель на буфер для имени сервера или RTL_NULL, если это имя не требуется.
  • [in] serverNameSize – размер буфера для имени сервера в байтах или 0, если это имя не требуется.
  • [out,optional] outEndpointName – указатель на буфер для квалифицированного имени службы или RTL_NULL, если это имя не требуется.
  • [in] endpointNameSize – размер буфера для квалифицированного имени службы в байтах или 0, если это имя не требуется.
  • [out] outPubStatus – указатель на значение, отражающее, что служба опубликована (DcmEndpointPublished), или публикация службы отменена (DcmEndpointUnpublished).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если блокирующий вызов был прерван вызовом функции DcmInterruptBlockingCall(), возвращает rcAbort.

Дополнительные сведения

Неблокирующий вызов, если в параметре msec указан 0.

DcmCreateConnection()

Назначение

Создает DCM-дескриптор, позволяющий выполнить запрос на создание IPC-канала с сервером для использования заданной службы с заданным интерфейсом.

Параметры

  • [in] endpointType – указатель на имя интерфейса службы.
  • [in] endpointName – указатель на квалифицированное имя службы.
  • [in] serverHandle – дескриптор, идентифицирующий сервер.
  • [in] clientHandle – дескриптор, идентифицирующий клиента.
  • [out] outConnectionId – указатель на DCM-дескриптор, позволяющий выполнить запрос на создание IPC-канала с сервером для использования заданной службы с заданным интерфейсом.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmConnect()

Назначение

Выполняет запрос на создание IPC-канала с сервером.

Параметры

  • [in] connectionId – DCM-дескриптор, созданный вызовом функции DcmCreateConnection().
  • [in] msec – время ожидания выполнения запроса в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [out] outSessionHandle – указатель на callable-дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если в параметре msec указан 0, и сервер не обработал запрос на создание IPC-канала, возвращает rcNotReady.

Если блокирующий вызов был прерван вызовом функции DcmInterruptBlockingCall(), возвращает rcAbort.

Дополнительные сведения

Неблокирующий вызов, если в параметре msec указан 0.

DcmPublishEndpoint()

Назначение

Публикует службу в DCM.

Параметры

  • [in] endpointType – указатель на имя интерфейса службы.
  • [in] endpointName – указатель на квалифицированное имя службы.
  • [in] serverHandle – дескриптор, идентифицирующий сервер.
  • [out] outPubHandle – указатель на DCM-дескриптор, позволяющий получать запросы клиентов на создание IPC-каналов для использования заданной службы с заданным интерфейсом.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmListen()

Назначение

Позволяет получить запрос клиента на создание IPC-канала.

Параметры

  • [in] pubHandle – DCM-дескриптор, созданный вызовом функции DcmPublishEndpoint().
  • [in] msec – время ожидания появления запроса клиента в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [out] outConnectionId – указатель на DCM-дескриптор, позволяющий принять или отклонить запрос клиента на создание IPC-канала.
  • [out,optional] outClientHandle – указатель на дескриптор, идентифицирующий клиента, или RTL_NULL, если этот дескриптор не требуется.
  • [out,optional] outClientName – указатель на буфер для имени клиента или RTL_NULL, если это имя не требуется.
  • [in] clientNameSize – размер буфера для имени клиента в байтах или 0, если это имя не требуется.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если блокирующий вызов был прерван вызовом функции DcmInterruptBlockingCall(), возвращает rcAbort.

Дополнительные сведения

Неблокирующий вызов, если в параметре msec указан 0.

DcmAccept()

Назначение

Принимает запрос клиента на создание IPC-канала.

Параметры

  • [in] connectionId – DCM-дескриптор, полученный вызовом функции DcmListen().
  • [in] sessionHandle – callable-дескриптор для клиента.
  • [in,optional] badgeHandle – дескриптор объекта контекста передачи ресурса или INVALID_HANDLE, если не требуется ассоциировать передачу callable-дескриптора с этим объектом.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic dcm_api_base]

Использование дополнительного API для серверов (pub.h)

API позволяет серверам публиковать группы служб. С позиции сервера группа служб представляет собой набор предоставляемых этим сервером служб, для которых можно получать клиентские запросы на создание IPC-каналов, используя один DCM-дескриптор. Сервер может опубликовать несколько групп служб. Множества служб из разных групп, опубликованных сервером, не должны пересекаться.

Сведения о функциях API приведены в таблице ниже.

Чтобы опубликовать группу предоставляемых сервером служб в DCM, нужно вызвать функцию DcmPublishGroupEndpoints(). Через параметр endpoints функции DcmPublishGroupEndpoints() нужно задать квалифицированные имена и контексты группируемых служб, а также имена интерфейсов служб. (Массив структур, указатель на который задан через параметр endpoints, можно удалить после публикации.) Контекст службы представляет собой данные, которые используются сервером, чтобы при вызове функции DcmListenGroupPub() определить, какая именно служба из опубликованной группы требуется клиенту. В качестве контекста службы можно использовать числовой идентификатор либо указатель на какие-либо данные. В результате вызова функции DcmPublishGroupEndpoints() создается DCM-дескриптор, позволяющий получать запросы клиентов на создание IPC-каналов для использования служб из заданной группы с заданными интерфейсами.

Чтобы получить запрос клиента на создание IPC-канала для использования службы из опубликованной группы, нужно вызвать функцию DcmListenGroupPub(). В параметре pubHandle функции DcmListenGroupPub() нужно указать DCM-дескриптор, полученный вызовом функции DcmPublishGroupEndpoints(). Выходной параметр outContext функции DcmListenGroupPub() содержит указатель на контекст службы. В результате вызова функции DcmListenGroupPub() создается DCM-дескриптор, позволяющий принять или отклонить запрос клиента на создание IPC-канала для использования той службы группы, которой соответствует полученный контекст службы.

Чтобы отменить публикацию группы служб, нужно вызовом функции DcmCloseGroupPubHandle() закрыть DCM-дескриптор, созданный при ее публикации. Также публикация всех опубликованных групп служб сервера будет отменена, если сервер завершится.

Чтобы прервать блокирующий вызов функции DcmListenGroupPub() из другого потока исполнения, нужно вызвать функцию DcmInterruptGroupPubBlockingCall().

Используя функции DcmSubscribeToGroupPubEvent() и DcmUnsubscribeFromGroupPubEvent() совместно с функциями из API notice_api.h, можно получать уведомления о том, что произошли следующие события: получение сервером запроса от клиента на создание IPC-канала (флаг DCM_CLIENT_CONNECTED), прерывание блокирующего вызова функции DcmListenGroupPub() (флаг DCM_BLOCKING_CALL_INTERRUPTED). (Флаги маски событий и идентификатор записи вида "ресурс – маска событий" DCM_EVENT_ID определены в заголовочном файле sysroot-*-kos/include/dcm/dcm_api.h из состава KasperskyOS SDK.) Функции DcmSubscribeToGroupPubEvent() и DcmUnsubscribeFromGroupPubEvent() позволяют настроить приемник уведомлений, соответственно добавляя и удаляя отслеживаемые объекты, идентифицируемые DCM-дескрипторами.

Функции pub.h

Функция

Сведения о функции

DcmPublishGroupEndpoints()

Назначение

Публикует группу служб в DCM.

Параметры

  • [in] endpoints – указатель на массив структур, содержащих сведения о группируемых службах: указатели на квалифицированные имена служб, указатели на имена интерфейсов служб и контексты служб.
  • [in] endpointsCount – число группируемых служб.
  • [in] serverHandle – дескриптор, идентифицирующий сервер.
  • [out] outPubHandle – указатель на DCM-дескриптор, позволяющий получать запросы клиентов на создание IPC-каналов для использования служб из заданной группы с заданными интерфейсами.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmListenGroupPub()

Назначение

Позволяет получить запрос клиента на создание IPC-канала.

Параметры

  • [in] pubHandle – DCM-дескриптор, полученный вызовом функции DcmPublishGroupEndpoints().
  • [in] msec – время ожидания появления запроса клиента в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [out] outContext – указатель на контекст службы из группы.
  • [out] outConnectionId – указатель на DCM-дескриптор, позволяющий принять или отклонить запрос клиента на создание IPC-канала.
  • [out,optional] outClientHandle – указатель на дескриптор, идентифицирующий клиента, или RTL_NULL, если этот дескриптор не требуется.
  • [out,optional] outClientName – указатель на буфер для имени клиента или RTL_NULL, если это имя не требуется.
  • [in] clientNameSize – размер буфера для имени клиента в байтах или 0, если это имя не требуется.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если блокирующий вызов был прерван вызовом функции DcmInterruptGroupPubBlockingCall(), возвращает rcAbort.

Дополнительные сведения

Неблокирующий вызов, если в параметре msec указан 0.

DcmInterruptGroupPubBlockingCall()

Назначение

Прерывает блокирующий вызов функции DcmListenGroupPub().

Параметры

  • [in] pubHandle – DCM-дескриптор, указанный при вызове функции DcmListenGroupPub().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmCloseGroupPubHandle()

Назначение

Закрывает DCM-дескриптор, полученный вызовом функции DcmPublishGroupEndpoints().

Параметры

  • [in] pubHandle – DCM-дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmSubscribeToGroupPubEvent()

Назначение

Настраивает приемник уведомлений, чтобы он получал уведомления о событиях, связанных с объектом, идентифицируемым заданным DCM-дескриптором.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] pubHandle – DCM-дескриптор, полученный вызовом функции DcmPublishGroupEndpoints().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmUnsubscribeFromGroupPubEvent()

Назначение

Настраивает приемник уведомлений, чтобы он не получал уведомления о событиях, связанных с объектом, идентифицируемым заданным DCM-дескриптором.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] pubHandle – DCM-дескриптор, полученный вызовом функции DcmPublishGroupEndpoints().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic dcm_api_ext_server]

Использование дополнительного API для клиентов (subscr.h)

API позволяет клиентам получать уведомления о публикации и отмене публикации групп служб. С позиции клиента группа служб представляет собой набор служб одного сервера, уведомления о публикации и отмене публикации которых можно получать, используя один DCM-дескриптор. При этом действует ограничение о том, что сервер не может предоставлять несколько служб с одинаковым интерфейсом. Несколько серверов могут предоставлять одинаковые группы служб, требуемые клиенту. Сервер может предоставлять несколько групп служб, требуемых клиенту. Множества служб из разных групп, требуемых клиенту, могут пересекаться.

Сведения о функциях API приведены в таблице ниже.

Чтобы создать DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации групп служб с заданными интерфейсами, нужно вызвать функцию DcmSetGroupSubscription(). Через параметр endpointTypes нужно задать имена интерфейсов группируемых служб. В параметре endpointsCount нужно указать число группируемых служб, равное числу интерфейсов, заданных через параметр endpointTypes. (Уведомления будут содержать сведения о том числе служб, которое равно числу интерфейсов, так как действует ограничение, что каждому интерфейсу соответствует отдельная и единственная служба.)

Чтобы извлечь уведомление о публикации или отмене публикации группы служб из очереди этих уведомлений, нужно вызвать функцию DcmReadGroupPubQueue(). В параметре subscrHandle функции DcmReadGroupPubQueue() нужно указать DCM-дескриптор, полученный вызовом функции DcmSetGroupSubscription(). В параметре maxCount функции DcmReadGroupPubQueue() нужно указать число элементов в массиве, заданном через параметр outEndpoints. Значение этого параметра должно быть не меньше числа служб в группе. Значение, полученное через параметр outPubStatus функции DcmReadGroupPubQueue(), отражает, что группа служб опубликована, или публикация группы служб отменена. Уведомление о публикации группы служб появляется в очереди только в том случае, если сервер публикует все службы группы (сразу или по отдельности). Если сервер публикует только часть требуемых клиенту служб, то уведомление о публикации группы служб не появляется. Если сервер завершается или отменяет публикацию хотя бы одной службы из опубликованной группы служб, то клиент получает уведомление об отмене публикации этой группы служб.

Если больше не требуется получать уведомления о публикации и отмене публикации группы служб с заданными интерфейсами, то DCM-дескриптор, созданный вызовом функции DcmSetGroupSubscription(), нужно закрыть вызовом функции DcmCloseGroupSubscrHandle().

Чтобы прервать блокирующий вызов функции DcmReadGroupPubQueue() из другого потока исполнения, нужно вызвать функцию DcmInterruptGroupSubscrBlockingCall().

Используя функции DcmSubscribeToGroupSubscrEvent() и DcmUnsubscribeFromGroupSubscrEvent() совместно с функциями из API notice_api.h, можно получать уведомления о том, что произошли следующие события: публикация или отмена публикации сервером службы в DCM (флаг DCM_PUBLICATION_CHANGED), прерывание блокирующего вызова функции DcmReadGroupPubQueue() (флаг DCM_BLOCKING_CALL_INTERRUPTED). (Флаги маски событий и идентификатор записи вида "ресурс – маска событий" DCM_EVENT_ID определены в заголовочном файле sysroot-*-kos/include/dcm/dcm_api.h из состава KasperskyOS SDK.) Функции DcmSubscribeToGroupSubscrEvent() и DcmUnsubscribeFromGroupSubscrEvent() позволяют настроить приемник уведомлений, соответственно добавляя и удаляя отслеживаемые объекты, идентифицируемые DCM-дескрипторами.

Функции subscr.h

Функция

Сведения о функции

DcmSetGroupSubscription()

Назначение

Создает DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации групп служб с заданными интерфейсами.

Параметры

  • [in] endpointTypes – указатель на массив с именами интерфейсов группируемых служб.
  • [in] endpointsCount – число группируемых служб. Должно совпадать с числом интерфейсов, заданных через параметр endpointTypes.
  • [in,optional] serverName – указатель на имя сервера или RTL_NULL, чтобы не использовать фильтрацию уведомлений по имени сервера.
  • [in,optional] serverHandle – дескриптор, идентифицирующий сервер, или INVALID_HANDLE, чтобы не использовать фильтрацию уведомлений по конкретному серверу.
  • [out] outSubscrHandle – указатель на DCM-дескриптор, позволяющий получать уведомления о публикации и отмене публикации групп служб с заданными интерфейсами.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmReadGroupPubQueue()

Назначение

Извлекает уведомление о публикации или отмене публикации группы служб из очереди этих уведомлений.

Параметры

  • [in] subscrHandle – DCM-дескриптор, полученный вызовом функции DcmSetGroupSubscription().
  • [in] msec – время ожидания появления уведомлений в миллисекундах или INFINITE_TIMEOUT, чтобы задать неограниченное время ожидания.
  • [in] maxCount – число элементов в массиве, заданном через параметр outEndpoints. Должно быть не меньше числа служб в группе.
  • [out,optional] outServerHandle – указатель на дескриптор, идентифицирующий сервер, или RTL_NULL, если этот дескриптор не требуется.
  • [out,optional] outServerName – указатель на буфер для имени сервера или RTL_NULL, если это имя не требуется.
  • [in] serverNameSize – размер буфера для имени сервера в байтах или 0, если это имя не требуется.
  • [out] outEndpoints – указатель на массив структур, содержащих квалифицированные имена служб группы и имена интерфейсов служб группы.
  • [out] outEndpointsCount – указатель на число служб в группе.
  • [out] outPubStatus – указатель на значение, отражающее, что группа служб опубликована (DcmEndpointPublished), или публикация группы служб отменена (DcmEndpointUnpublished).

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Если блокирующий вызов был прерван вызовом функции DcmInterruptGroupSubscrBlockingCall(), возвращает rcAbort.

Дополнительные сведения

Неблокирующий вызов, если в параметре msec указан 0.

DcmInterruptGroupSubscrBlockingCall()

Назначение

Прерывает блокирующий вызов функции DcmReadGroupPubQueue().

Параметры

  • [in] subscrHandle – DCM-дескриптор, указанный при вызове функции DcmReadGroupPubQueue().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmCloseGroupSubscrHandle()

Назначение

Закрывает DCM-дескриптор, полученный вызовом функции DcmSetGroupSubscription().

Параметры

  • [in] subscrHandle – DCM-дескриптор.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmSubscribeToGroupSubscrEvent()

Назначение

Настраивает приемник уведомлений, чтобы он получал уведомления о событиях, связанных с объектом, идентифицируемым заданным DCM-дескриптором.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] subscrHandle – DCM-дескриптор, полученный вызовом функции DcmSetGroupSubscription().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

DcmUnsubscribeFromGroupSubscrEvent()

Назначение

Настраивает приемник уведомлений, чтобы он не получал уведомления о событиях, связанных с объектом, идентифицируемым заданным DCM-дескриптором.

Параметры

  • [in] notice – идентификатор приемника уведомлений.
  • [in] subscrHandle – DCM-дескриптор, полученный вызовом функции DcmSetGroupSubscription().

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

В начало
[Topic dcm_api_ext_client]

Компонент MessageBus

Компонент MessageBus реализует шину сообщений, которая обеспечивает прием, распределение и доставку сообщений между программами, работающими под KasperskyOS. Шина построена по принципу "издатель-подписчик". Использование шины сообщений позволяет избежать создания большого количества IPC-каналов для связывания каждой программы-подписчика с каждой программой-издателем.

Сообщения, передаваемые через шину MessageBus, не могут содержать данные. Эти сообщения могут использоваться только для уведомления подписчиков о событиях.

Компонент MessageBus представляет собой дополнительный уровень абстракции над KasperskyOS IPC, который позволяет упростить процесс разработки и развития ваших программ. MessageBus является отдельной программой, доступ к которой осуществляется через IPC, но при этом разработчикам предоставляется библиотека доступа к MessageBus, которая позволяет избежать использования IPC-вызовов напрямую. Чтобы получить доступ к API этой библиотеки, скомпонуйте вашу программу с библиотекой, используя CMake-команду target_link_libraries().

CMakeLists.txt

target_link_libraries (${TARGET_NAME} ${messagebus_CLIENT_LIB})

API библиотеки доступа предоставляет следующие интерфейсы:

IProviderFactory
Интерфейс. предоставляющий фабричные методы для получения доступа к экземплярам остальных интерфейсов.
IProviderControl
Интерфейс для регистрации и дерегистрации издателя и подписчика в шине.
IProvider (компонент MessageBus)
Интерфейс для передачи сообщения в шину.
ISubscriber
Интерфейс обратного вызова для передачи сообщения подписчику.
IWaiter
Интерфейс ожидания обратного вызова при появлении соответствующего сообщения.

Структура сообщения

Каждое сообщение содержит два параметра:

topic
Идентификатор темы сообщения.
id
Дополнительный параметр, специфицирующий сообщение.

Параметры topic и id уникальны для каждого сообщения. Интерпретация topic+id определяется контрактом между издателем и подписчиком. Например, если изменяются конфигурационные данные, с которыми работают издатель и подписчик, издатель высылает сообщение об изменении данных и id конкретной записи с новыми данными. Подписчик, пользуясь отличными от MessageBus механизмами, получает новые данные по ключу id.

Пример использования компонента MessageBus в решении на базе KasperskyOS см. в разделе "Пример messagebus".

В этом разделе

Интерфейс IProviderFactory

Интерфейс IProviderControl

Интерфейс IProvider (компонент MessageBus)

Интерфейсы ISubscriber, IWaiter и ISubscriberRunner

В начало
[Topic messagebus_component]

Интерфейс IProviderFactory

Интерфейс IProviderFactory предоставляет фабричные методы для получения интерфейсов, необходимых для работы с компонентом MessageBus.

Описание интерфейса IProviderFactory представлено в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/messagebus/i_messagebus_control.h.

Для получения экземпляра интерфейса IProviderFactory используется свободная функция InitConnection(), которая принимает имя IPC-канала вашей программы с программой MessageBus. Имя соединения задается в файле init.yaml.in при описании конфигурации решения. В случае успешного подключения выходной параметр содержит указатель на интерфейс IProviderFactory.

  • Для получения интерфейса регистрации и дерегистрации (см. "Интерфейс IProviderControl") издателей и подписчиков в шине сообщений используется метод IProviderFactory::CreateBusControl().
  • Для получения интерфейса, содержащего методы для отправки издателем сообщений в шину (см. "Интерфейс IProvider (компонент MessageBus)"), используется метод IProviderFactory::CreateBus().
  • Для получения интерфейсов, содержащих методы для получения подписчиком сообщений из шины (см. "Интерфейсы ISubscriber, IWaiter и ISubscriberRunner"), используются методы IProviderFactory::CreateCallbackWaiter и IProviderFactory::CreateSubscriberRunner().

    Мы не рекомендуем использовать интерфейс IWaiter, поскольку вызов метода этого интерфейса является блокирующим.

i_messagebus_control.h (фрагмент)

class IProviderFactory { ... virtual fdn::ResultCode CreateBusControl(IProviderControlPtr& controlPtr) = 0; virtual fdn::ResultCode CreateBus(IProviderPtr& busPtr) = 0; virtual fdn::ResultCode CreateCallbackWaiter(IWaiterPtr& waiterPtr) = 0; virtual fdn::ResultCode CreateSubscriberRunner(ISubscriberRunnerPtr& runnerPtr) = 0; ... }; ... fdn::ResultCode InitConnection(const std::string& connectionId, IProviderFactoryPtr& busFactoryPtr);
В начало
[Topic messagebus_component_iproviderfactory]

Интерфейс IProviderControl

Интерфейс IProviderControl предоставляет методы для регистрации и дерегистрации издателей и подписчиков в шине сообщений.

Описание интерфейса IProviderControl представлено в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/messagebus/i_messagebus_control.h.

Для получение экземпляра интерфейса используется интерфейс IProviderFactory.

Регистрация и дерегистрация издателя

Для регистрации издателя в шине сообщений используется метод IProviderControl::RegisterPublisher(). Метод принимает тему сообщения и помещает в выходной параметр уникальный идентификатор клиента шины. Если тема уже зарегистрирована в шине, то вызов будет отклонен, и идентификатор клиента не будет заполнен.

Для дерегистрации издателя в шине сообщений используется метод IProviderControl::UnregisterPublisher(). Метод принимает идентификатор клиента шины, полученный при регистрации. Если указан идентификатор, не зарегистрированный как идентификатор издателя, то вызов будет отклонен.

i_messagebus_control.h (фрагмент)

class IProviderControl { ... virtual fdn::ResultCode RegisterPublisher(const Topic& topic, ClientId& id) = 0; virtual fdn::ResultCode UnregisterPublisher(ClientId id) = 0; ... };

Регистрация и дерегистрация подписчика

Для регистрации подписчика в шине сообщений используется метод IProviderControl::RegisterSubscriber(). Метод принимает имя подписчика и список тем, на которые нужно подписаться, а в выходной параметр помещает уникальный идентификатор клиента шины.

Для дерегистрации подписчика в шине сообщений используется метод IProviderControl::UnregisterSubscriber(). Метод принимает идентификатор клиента шины, полученный при регистрации. Если указан идентификатор, не зарегистрированный как идентификатор подписчика, то вызов будет отклонен.

i_messagebus_control.h (фрагмент)

class IProviderControl { ... virtual fdn::ResultCode RegisterSubscriber(const std::string& subscriberName, const std::set<Topic>& topics, ClientId& id) = 0; virtual fdn::ResultCode UnregisterSubscriber(ClientId id) = 0; ... };
В начало
[Topic messagebus_component_icontrol]

Интерфейс IProvider (компонент MessageBus)

Интерфейс IProvider предоставляет методы для отправки издателем сообщений в шину.

Описание интерфейса IProvider представлено в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/messagebus/i_messagebus.h.

Для получение экземпляра интерфейса используется интерфейс IProviderFactory.

Отправка сообщения в шину

Для оправки сообщения в шину используется метод IProvider::Push(). Метод принимает идентификатор клиента шины, полученный при регистрации, и идентификатор сообщения. Если очередь сообщений в шине заполнена, то вызов будет отклонен.

i_messagebus.h (фрагмент)

class IProvider { public: ... virtual fdn::ResultCode Push(ClientId id, BundleId dataId) = 0; ... };
В начало
[Topic messagebus_component_iprovider]

Интерфейсы ISubscriber, IWaiter и ISubscriberRunner

Интерфейсы ISubscriber, IWaiter и ISubscriberRunner предоставляют методы для получения и обработки подписчиком сообщений из шины.

Описания интерфейсов ISubscriber, IWaiter и ISubscriberRunner представлены в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/messagebus/i_subscriber.h.

Для получение экземпляров интерфейсов IWaiter и ISubscriberRunner используется интерфейс IProviderFactory. Реализация callback-интерфейса ISubscriber предоставляется приложением-подписчиком.

Получение сообщения из шины

Для перевода подписчика в режим ожидания сообщения от шины, вы можете использовать метод IWaiter::Wait() или ISubscriberRunner::Run(). Методы принимают идентификатор клиента шины и указатель на callback-интерфейс ISubscriber. Если идентификатор клиента не зарегистрирован, то вызов будет отклонен.

Мы не рекомендуем использовать интерфейс IWaiter, поскольку вызов метода IWaiter::Wait() является блокирующим.

При получении сообщения из шины будет вызван метод ISubscriber::OnMessage(). Метод принимает тему и идентификатор сообщения.

i_subscriber.h (фрагмент)

class ISubscriber { ... virtual fdn::ResultCode OnMessage(const std::string& topic, BundleId id) = 0; }; ... class IWaiter { ... [[deprecated("Use ISubscriberRunner::Run method instead.")]] virtual fdn::ResultCode Wait(ClientId id, const ISubscriberPtr& subscriberPtr) = 0; }; ... class ISubscriberRunner { ... virtual fdn::ResultCode Run(ClientId id, const ISubscriberPtr& subscriberPtr) = 0; };
В начало
[Topic messagebus_component_isubwait]

Компонент LogRR

Компонент LogRR – система для журналирования информации о работе программ. Компонент включает в себя программу-сервер, которому другие программы передают сообщения о своем состоянии, и вспомогательные каналы вывода для журналирования. Для отправки сообщений серверу прикладные программы используют библиотеку logrr_clog (для C++ доступна библиотека logrr_cpp), которая фильтрует сообщения по уровню журналирования и отправляет их серверу. Сервер передаёт сообщения каналам вывода. Канал вывода сохраняет сообщения журнала в файлы.

В SDK API программы LogRR представлены статическими и динамическими библиотеками, компонуемыми с программами, информация о работе которых журналируется:

  • в программах на языке C используется библиотека logrr_clog и заголовочный файл sysroot-*-kos/include/component/logrr/clog/clog.h.
  • в программах на языке С++ используется библиотека logrr_cpp и заголовочный файл sysroot-*-kos/include/component/logrr/cpp/logger.h.

В этом разделе

Добавление сервера журналирования и каналов вывода в решение

Получение записей журнала при работе в QEMU

Отправка сообщений в журнал с помощью макросов

Дополнительные возможности при отправке сообщений в журнал

Уровни журналирования

API программы LogRR

В начало
[Topic logrr_component]

Добавление сервера журналирования и каналов вывода в решение

Программа LogrrServer отправляет сообщения одному или нескольким каналам вывода. Вы можете записывать сообщения журнала в файлы, используя канал вывода FsOutputChannel.

Добавление и настройка сервера журналирования

Команда создания и настройки сервера журналирования create_logrr_server() может содержать следующие параметры:

LOG_LEVEL
Устанавливает указанный уровень журналирования. Доступные значения LOG_LEVEL: CRITICAL, ERROR, WARNING, INFO, DEBUG и TRACE. По умолчанию, сервер журналирования обрабатывает сообщения с уровнем Info.
CONFIG_PATH
Указывает путь до конфигурационного файла сервера журналирования.
RECV_CORE_LOGS
Включает сбор журналов ядра.
WRITE_TO_CORE
Включает передачу журналов в ядро. Не исключает передачу журналов серверу журналирование и далее в канал вывода. Требуется для вывода журналов в UART.
OUTPUT_CHANNELS
Подключает один или несколько указанных каналов вывода к серверу.
DENY_DYNAMIC_CONN_TYPES
Включает отклонение динамических подключений к серверу журналирования.
DENY_STATIC_CONN_TYPES
Включает отклонение статических подключений к серверу журналирования.

Чтобы добавить программу LogrrServer в решение,

отредактируйте корневой файл с CMake-командами сборки решения или файл с CMake-командами сборки инициализирующей программы Einit:

CMakeLists.txt

find_package (logrr_server REQUIRED COMPONENTS ENTITY) # ... set (TASKS # ... ${logrr_server_ENTITY}) # ... # Добавление сервера, использующего канал вывода FsOutputChannel create_logrr_server( LOG_LEVEL DEBUG WRITE_TO_CORE ON OUTPUT_CHANNELS logrr.FsOutputChannel) # Добавление сервера и канала вывода в решение list(APPEND ENTITIES logrr_server::default_entity logrr_fs_output_channel::default_entity) # Создание статических IPC-каналов для программ-источников с сервером connect_to_logrr_server (ENTITIES ClientOne) build_kos_qemu_image (kos-qemu-image CONNECTIONS_CFG ${INIT_YAML_FILE} SECURITY_PSL ${SECURITY_PSL_FILE} PACK_DEPS ON ${TASKS})

Опцию PACK_DEPS требуется включить при вызове команды build_kos_qemu_image() или build_kos_hw_image() для включения автоматической сборки библиотек в образ диска.

Добавление и настройка каналов вывода

Команда создания и настройки канала вывода журналов в файлы create_logrr_fs_output_channel() может содержать следующие параметры:

CONFIG_PATH
Указывает путь до конфигурационного файла канала вывода.
SERVER_TARGET
Указывает сервер журналирования, к которому требуется подключить создаваемый канал вывода.
APP_LOG_DIR
Указывает директорию хранения файлов журналов для программ. Обязательный параметр.
SYS_LOG_DIR
Указывает директорию хранения файлов журналов системы. Если параметр не задан, файлы журналов системы не сохраняются.

Чтобы добавить канал вывода FsOutputChannel в решение,

отредактируйте корневой файл с CMake-командами сборки решения или файл с CMake-командами сборки инициализирующей программы Einit:

CMakeLists.txt

find_package (logrr_fs_output_channel REQUIRED COMPONENTS ENTITY) # Добавление канала вывода FsOutputChannel пишущего в файл create_logrr_fs_output_channel ( APP_LOG_DIR "/log/apps" SYS_LOG_DIR "/log/sys")

Создание IPC-каналов и разрешение взаимодействия программ

Система сборки обеспечивает автоматическое создание IPC-каналов, необходимых для работы системы журналирования, а также генерирует описание политики безопасности в части, которая разрешает взаимодействие между процессами.

Для создания статического подключения к серверу журналирования, вы можете использовать CMake-команду connect_to_logrr_server (ENTITIES <имена_программ_для_подключения>).

В начало
[Topic logrr_component_add]

Получение записей журнала при работе в QEMU

Клиентские библиотеки logrr_clog и logrr_cpp отправляют сообщения в ядру, которое пересылает их в UART-порт. Вы можете перенаправить данные из эмулируемого UART-порта в стандартный поток ввода-вывода, указав флаг -serial stdio при запуске QEMU. При этом сообщения журнала будут отображаться в терминале, в котором запущен QEMU.

Укажите флаги запуска QEMU в значении параметра QEMU_FLAGS, передаваемого команде build_kos_qemu_image():

CMakeLists.txt

build_kos_qemu_image (kos-qemu-image # ... QEMU_FLAGS "-m 4096 -serial stdio" # ... )
В начало
[Topic logrr_component_qemu]

Отправка сообщений в журнал с помощью макросов

Программа LogRR предоставляет макросы для быстрого доступа к функциям журналирования с определенным уровнем.

Пример использования макросов в программе на языке C:

C

#include <component/logrr/clog/clog.h> // ... CLOG(CRITICAL, "Critical message. Exit code = %d", 404); CLOG(ERROR, "Error message. Error code = %d", 13); CLOG(WARNING, "Warning message. Details: %s", "operation not permitted."); CLOG(INFO, "Info message. Status: %s", "connected."); CLOG(DEBUG, "Debug message."); CLOG(TRACE, "Trace message.");

Для использования этих макросов требуется скомпоновать программу с библиотекой logrr_clog.

Пример использования макросов в программе на языке C++:

C++

#include <component/logrr/cpp/logger.h> // ... LOG(CRITICAL, "Critical message. Exit code = {}", 404); LOG(ERROR, "Error message. Error code = {}", 13); LOG(WARNING, "Warning message. Details: {}", "operation not permitted."); LOG(INFO, "Info message. Status: {}", "connected."); LOG(DEBUG, "Debug message."); LOG(TRACE, "Trace message.");

Для использования этих макросов требуется скомпоновать программу с библиотекой logrr_cpp.

См. также

Дополнительные возможности при отправке сообщений в журнал

В начало
[Topic logrr_component_macros]

Дополнительные возможности при отправке сообщений в журнал

В большинстве случаев, для отправки сообщений в журнал достаточно использовать макросы быстрого доступа к функциям журналирования.

В этом разделе описаны дополнительные возможности API библиотеки logrr_cpp: объединение сообщений, отправка сообщений по условию и отложенная отправка.

Объединение сообщений

Чтобы поэтапно получить текст записи журнала из частей и затем отправить запись в журнал одним вызовом:

  1. Скомпонуйте программу с библиотекой logrr_cpp.
  2. Подключите заголовочный файл component/logrr/cpp/tools.h.

    C++

    #include <component/logrr/cpp/tools.h>
  3. Создайте экземпляр класса LogIface.

    C++

    auto logger = LogIface(logrr::LogLevel::Warning);
  4. Заполните буфер сообщений одним или несколькими вызовами метода LogIface::Push().

    C++

    logger.Push("a={}", a); // ... logger.Push(", b={}", b); // ... logger.Push(", c={}", c);
  5. Отправьте ранее полученные сообщения в журнал с помощью метода LogIface::Flush().

    C++

    logger.Flush();

Отправка сообщения в журнал по условию

Чтобы отправить сообщение в журнал только при выполнении указанного условия:

  1. Скомпонуйте программу с библиотекой logrr_cpp.
  2. Подключите заголовочный файл component/logrr/cpp/tools.h.

    C++

    #include <component/logrr/cpp/tools.h>
  3. Передайте логическое значение, один из перечислителей LogLevel и текст сообщения в макрос LOG_IF().

    C++

    LOG_IF(IsWorldBroken(), logrr::LogLevel::Critical, "World is broken!");

Отложенная отправка сообщений в журнал

Макрос LOG_DEFER(), объявленный в заголовочном файле component/logrr/cpp/tools.h, позволяет избежать дублирования кода для журналирования в блоках if...else.

Чтобы отправить предварительно отформатированное сообщение в журнал в момент выхода из функции:

  1. Скомпонуйте программу с библиотекой logrr_cpp.
  2. Подключите заголовочный файл component/logrr/cpp/tools.h.

    C++

    #include <component/logrr/cpp/tools.h>
  3. Добавьте вызов макроса LOG_DEFER() в начало кода функции, изменяющей значения, которые нужно отправить в журнал. В макрос передайте значение LogLevel, строку форматирования сообщения и аргументы для подстановки в строку форматирования.

    C++

    int DeferredLoggingExample() { auto logger = LOG_DEFER(logrr::LogLevel::Info, "a={}, b={}", a, b); if (someCondition) { a = 1; b = 2; return -1; } else { a = 3; b = 4; return 0; } }

В этом примере, сообщение отправляется в журнал при вызове деструктора объекта logger на выходе из функции DeferredLoggingExample(). В строку форматирования сообщения подставляются значения a и b, актуальные на момент выхода из функции.

В начало
[Topic logrr_component_additional]

Уровни журналирования

Атрибутом каждого сообщения в системе журналирования является уровень журналирования. Уровень используется при фильтрации сообщений в клиенте и настраивается через сервер.

Critical
Критический сбой в работе программы, после которого продолжение работы программы невозможно.
Error
Ошибка в работе программы, после которой все еще возможно продолжение работы. Этот уровень применяется для журналирования неожиданного завершения текущей операции. Не рекомендуется применять для журналирования ошибочных действий пользователя.
Warning
Проблемная ситуация, возникновение которой предусмотрено, и обрабатывается программой в обычном режиме.
Info (установлен по умолчанию)
Информация о текущем функционировании программы, без дополнительных подробностей. Например, переход в новое окно в пользовательском интерфейсе или успешная запись данных в базу.
Debug
Более подробный уровень журналирования, чем Info. Предоставляет больше деталей о событиях программы и может быть полезен при отладке.
Trace
Самый подробный уровень журналирования, используемый для наиболее детального отслеживания событий программы. При включении может значительно влиять на производительность.

Каждый последующий уровень включает в себя все предыдущие. Например, если сервер настроен на уровень Warning, то в журнал передаются сообщения с уровнями Critical, Error и Warning, а сообщения с уровнями Info, Debug и Trace игнорируются.

Установка уровня журналирования при отправке сообщения программой может осуществляться:

  • использованием макроса с параметром, соответствующем выбранному уровню;
  • передачей значения перечислителя LogrrLogLevel или LogLevel при вызове функций журналирования.
В начало
[Topic logrr_component_loglevels]

API программы LogRR

Библиотеки программы LogRR, предоставляют API для отправки сообщений в журнал через сервер журналирования, а также API для управления работой сервера журналирования.

В этом разделе справки

Библиотека logrr_clog

Библиотека logrr_cpp

В начало
[Topic logrr_api]

Библиотека logrr_clog

Библиотека logrr_clog предоставляет API для отправки сообщений в журнал.

Библиотека logrr_clog предназначена для использования в программах на языке C. В программах на языке C++ используйте библиотеку logrr_cpp.

Чтобы получить доступ к API этой библиотеки,

скомпонуйте вашу программу с библиотекой, используя CMake-команду target_link_libraries().

CMakeLists.txt

target_link_libraries (${TARGET_NAME} ${logrr_clog_LIB})

В этом разделе справки

Функция ClogLog() и макрос CLOG

Перечисляемый тип LogrrLogLevel

В начало
[Topic logrr_api_clog]

Функция ClogLog() и макрос CLOG

Функция ClogLog() выполняет запись в журнал.

Функция ClogLog() предназначена для использования в программах на языке C. В программах на языке C++ используйте функцию Logger::Log() или макросы LOG_*.

Описание функции ClogLog() и макросов для быстрого доступа к ней представлено в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/clog/clog.h.

component/logrr/clog/clog.h (фрагмент)

__attribute__((format(printf, 6, 7))) void ClogLog(const char *module, LogLevel level, const char *file, int line, const char *func, const char *message, ...); #define CLOG_TRACE_IMPL_EX(level, file, line, func, ...) \ ClogLog(LOG_MODULE, level, file, line, func, __VA_ARGS__) #define CLOG_TRACE_IMPL(level, ...) \ CLOG_TRACE_IMPL_EX((level), \ __FILENAME__, \ __LINE__, \ __func__, \ __VA_ARGS__) #define __CLOG_LEVEL_TRACE__ LogrrLogLevel_Trace #define __CLOG_LEVEL_DEBUG__ LogrrLogLevel_Debug #define __CLOG_LEVEL_INFO__ LogrrLogLevel_Info #define __CLOG_LEVEL_WARNING__ LogrrLogLevel_Warning #define __CLOG_LEVEL_ERROR__ LogrrLogLevel_Error #define __CLOG_LEVEL_CRITICAL__ LogrrLogLevel_Critical #define CLOG(level, ...) CLOG_TRACE_IMPL(__CLOG_LEVEL_ ## level ## __, __VA_ARGS__)

Параметры функции ClogLog():

level
Уровень журналирования LogrrLogLevel.
file
Имя файла.
line
Номер строки в файле.
func
Имя функции.
message
Текст сообщения или строка форматирования текста сообщения.
...
Параметры для подстановки в строку форматирования message.

Макрос быстрого доступа к функции ClogLog()

Вместо вызова функции ClogLog() вы можете использовать макрос, описание которого представлено в файле component/logrr/clog/clog.h. Этот макрос является вариационным (принимает переменное число параметров), что позволяет не указывать все параметры функции ClogLog(). При вызове макроса достаточно указать уровень журналирования и текст сообщения или строку форматирования сообщения со значениями параметров. Используемый уровень журналирования level определяется первым параметром макроса. Пример использования этого макроса представлен в разделе "Отправка сообщений в журнал с помощью макросов".

В начало
[Topic logrr_api_clog_macro]

Перечисляемый тип LogrrLogLevel

Перечисляемый тип LogrrLogLevel содержит поля, имена которых соответствуют уровням журналирования, доступным в программе LogRR.

Перечисляемый тип LogrrLogLevel предназначен для использования в программах на языке C. В программах на языке C++ используйте класс LogLevel.

Перечислители LogrrLogLevel могут передаваться в функцию ClogLog() для отправки сообщения с указанным уровнем.

Описание перечисления LogrrLogLevel представлено в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/core/log_level_c.h.

component/logrr/core/log_level_c.h (фрагмент)

typedef enum LogrrLogLevel { LogrrLogLevel_Critical, /*!< Critical errors when process can't continue to work. */ LogrrLogLevel_Error, /*!< Some issues that allow to continue application execution. */ LogrrLogLevel_Warning, /*!< Some regular errors that application can handle. */ LogrrLogLevel_Info, /*!< Some useful information about application work/state. */ LogrrLogLevel_Debug, /*!< Detailed log to understand/fix some specific issues. */ LogrrLogLevel_Trace, /*!< To "trace" some function execution. May affect performance. */ } LogLevel;
В начало
[Topic logrr_api_logrrloglevel]

Библиотека logrr_cpp

Библиотека logrr_cpp предоставляет API для отправки сообщений в журнал.

Библиотека logrr_cpp предназначена для использования в программах на языке C++. В программах на языке C используйте библиотеку logrr_clog.

Чтобы получить доступ к API этой библиотеки,

скомпонуйте вашу программу с библиотекой, используя CMake-команду target_link_libraries().

CMakeLists.txt

target_link_libraries (${TARGET_NAME} ${logrr_cpp_LIB})

В этом разделе справки

Метод Log() и макрос LOG

Класс LogLevel

Класс LogIface

В начало
[Topic logrr_api_cpp]

Метод Log() и макрос LOG

Метод logrr::Log() выполняет запись в журнал.

Параметры метода:

logLevel
Уровень журналирования LogLevel.
sourceLocation
Объект, определяющий местоположение в исходном коде (имя файла, имя функции, номер строки и номер столбца). В C++20 используется класс std::source_location, в более ранних версиях используется класс std::experimental::source_location.
format
Строка форматирования текста сообщения.
args
Параметры для подстановки в строку форматирования format.

Метод logrr::Log() предназначен для использования в программах на языке C++. В программах на языке C используйте статическую функцию ClogLog() или макрос CLOG.

Описание метода logrr::Log() и макроса быстрого доступа к нему представлены в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/cpp/logger.h.

component/logrr/cpp/logger.h (фрагмент)

namespace logrr { namespace details { __rtl_public void PrintErrorMessage(std::string_view fileName, std::uint32_t line, std::string_view exMsg) noexcept; } // namespace details __rtl_public void Init(std::string_view providerName) noexcept; __rtl_public bool ShouldLog(logrr::LogLevel logLevel) noexcept; __rtl_public void SendMessage( std::string_view module, LogLevel logLevel, std::string_view file, const uint32_t line, std::string_view function, std::string_view msg) noexcept; template <typename... Args> __rtl_public void Log( logrr::LogLevel logLevel, kos::rtl::SourceLocation sourceLocation, std::string_view format, Args&&... args) noexcept { Log(logLevel, sourceLocation.file_name(), sourceLocation.line(), sourceLocation.function_name(), format, std::forward<Args>(args)...); } template <typename... Args> __rtl_public void Log( std::string_view module, logrr::LogLevel logLevel, kos::rtl::SourceLocation sourceLocation, std::string_view format, Args&&... args) noexcept { Log(module, logLevel, sourceLocation.file_name(), sourceLocation.line(), sourceLocation.function_name(), format, std::forward<Args>(args)...); } template <typename... Args> __rtl_public void Log( logrr::LogLevel logLevel, std::string_view file, const uint32_t line, std::string_view function, std::string_view format, Args&&... args) noexcept { Log("", logLevel, file, line, function, format, std::forward<Args>(args)...); } template <typename... Args> __rtl_public void Log( std::string_view module, logrr::LogLevel logLevel, std::string_view file, const uint32_t line, std::string_view function, std::string_view format, Args&&... args) noexcept { if (ShouldLog(logLevel)) try { constexpr auto MaxLength = static_cast<std::size_t>(LOGRR_LOG_MESSAGE_MAX_SIZE - 1); if constexpr (!sizeof...(args)) { SendMessage(module, logLevel, file, line, function, format.substr(0, MaxLength)); } else { std::array<std::uint8_t, MaxLength> fmtBuf; const auto endIt{fmt::format_to_n( fmtBuf.begin(), MaxLength, format, std::forward<Args>(args)...).out}; const std::string_view formattedStr{ reinterpret_cast<const char*>(fmtBuf.data()), static_cast<std::size_t>(std::distance(fmtBuf.begin(), endIt))}; SendMessage(module, logLevel, file, line, function, formattedStr); } } catch (const std::exception& e) { details::PrintErrorMessage(file, line, e.what()); } } } // namespace logrr namespace { const std::string_view LOG_MODULE; } // namespace #define __CPPLOG_LEVEL_TRACE__ logrr::LogLevel::Trace #define __CPPLOG_LEVEL_DEBUG__ logrr::LogLevel::Debug #define __CPPLOG_LEVEL_INFO__ logrr::LogLevel::Info #define __CPPLOG_LEVEL_WARNING__ logrr::LogLevel::Warning #define __CPPLOG_LEVEL_ERROR__ logrr::LogLevel::Error #define __CPPLOG_LEVEL_CRITICAL__ logrr::LogLevel::Critical #define LOG_INIT(providerName) \ logrr::Init(providerName) #define CALL_LOG(level, ...) \ logrr::Log(LOG_MODULE, level, kos::rtl::SourceLocation::current(), __VA_ARGS__) #define CALL_LOG_SL(level, file, line, func, ...) \ logrr::Log(LOG_MODULE, level, file, line, func, __VA_ARGS__) #define LOG(level, ...) CALL_LOG(__CPPLOG_LEVEL_ ## level ## __, __VA_ARGS__) #define LOG_SL(level, file, line, func, ...) CALL_LOG_SL(__CPPLOG_LEVEL_ ## level ## __, file, line, func, __VA_ARGS__)

Макрос быстрого доступа к методу Log()

Вместо вызова статического метода Logger::Log() вы можете использовать макрос, описание которого представлено в файле component/logrr/cpp/logger.h. Этот макрос является вариационным (принимает переменное число параметров), что позволяет не указывать все параметры метода Logger::Log(). При вызове макроса достаточно указать только уровень журналирования и строку форматирования сообщения со значениями параметров. Используемый уровень журналирования logLevel определяется первым параметром макроса: Пример использования этого макросов представлен в разделе "Отправка сообщений в журнал с помощью макросов".

В начало
[Topic logrr_api_cpp_log]

Класс LogLevel

Класс LogLevel является перечислением (enum class) и содержит поля, имена которых соответствуют уровням журналирования, доступным в программе LogRR.

Класс LogLevel предназначен для использования в программах на языке C++. В программах на языке C используйте перечисляемый тип LogrrLogLevel.

Значения перечисления LogLevel могут передаваться в:

  • статический метод Log() класса Logger;
  • статические методы ChangeLogLevel() и ChangeGlobalLogLevel() структуры Controller;
  • конструктор класса LogIface;

Описание класса LogLevel представлено в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/core/log_level.h.

component/logrr/core/log_level.h (фрагмент)

enum class LogLevel : int8_t { Critical = 0, Error, Warning, Info, Debug, Trace };
В начало
[Topic logrr_api_cpp_loglevel]

Класс LogIface

Класс LogIface содержит методы, позволяющие поэтапно получить текст записи журнала из частей, и затем отправить запись в журнал одним вызовом:

  • Для установки уровня журналирования отправляемых сообщений используется метод SetLogLevel().
  • Для добавления текста к сообщению используется метод Push().
  • Для отправки составленного одним или несколькими вызовами метода Push() сообщения в журнал используется метод Flush().

    При вызове деструктора ~LogIface() в журнал также отправляется составленное вызовами Push() сообщение, если оно не было ранее отправлено с помощью Flush().

  • Для немедленной отправки отдельного сообщения (без использования составленного вызовами Push() текста) используется метод Log().

Чтобы создать экземпляр класса LogIface, передайте один из перечислителей LogLevel в конструктор класса. Пример использования функций класса LogIface представлен в подразделе "Объединение сообщений" раздела "Дополнительные возможности при отправке сообщений в журнал".

Описание класса LogIface представлено в файле /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/cpp/tools.h.

component/logrr/cpp/tools.h (фрагмент)

/** * @brief C++ provider interface for logrr for simple printing and queuing logs * */ class LogIface { // ... public: LogIface(logrr::LogLevel level, sl::source_location loc = sl::source_location::current()) : m_level(level), m_defaultSourceLocation(loc) {} void SetLogLevel(logrr::LogLevel new_level) { m_level = new_level; } /** * @brief Append new format with args to current message template * */ template <typename... Args> void Push(std::string_view frmt, Args&&... args) { AppendFormat(m_message, frmt, std::forward<Args>(args)...); } /** * @brief Log instantly through separate Log command * */ template <typename... Args> void Log(FormatWithLocation frmt, Args&&... args) { Flush_(frmt.loc, frmt.frmt, std::forward<Args>(args)...); } /** * @brief Flush current message, built with Push, to Log * */ void Flush(const sl::source_location& loc = sl::source_location::current()) { Flush_(loc, m_message); m_message.clear(); } ~LogIface() { if (!m_message.empty()) { Flush_(m_defaultSourceLocation, m_message); } } // ... };
В начало
[Topic logrr_api_cpp_logiface]

Компонент ExecutionManager

API определен в заголовочных файлах, расположенных в директории sysroot-*-kos/include/component/execution_manager/ из состава KasperskyOS SDK.

Сценарий использования компонента ExecutionManager описан в статье "Запуск процессов с помощью системной программы ExecutionManager".

Интерфейс execution_manager_proxy.h

API определен в заголовочном файле sysroot-*-kos/include/component/execution_manager/kos_ipc/execution_manager_proxy.h из состава KasperskyOS SDK.

Интерфейс содержит функцию CreateExecutionManager() для получения указателя на экземпляр интерфейса IExecutionManager, необходимого для работы с компонентом ExecutionManager. Через входной параметр cfg эта функция принимает параметры конфигурации в виде структуры ExecutionManagerConfig. Все поля этой структуры опциональны для заполнения.

struct ExecutionManagerConfig { // Имя IPC-канала для соединения с процессом ExecutionManager. char const* const mainConnection = KOS_EXECMGR_CONN_MAIN; // Имя службы, реализующей интерфейс IApplicationController. char const* const appControlInterface = KOS_EXECMGR_IFACE_AC; // Имя службы, реализующей интерфейс IStateProvider. char const* const appStateInterface = KOS_EXECMGR_IFACE_AS; // Имя службы, реализующей интерфейс ISystemController. char const* const systemControlInterface = KOS_EXECMGR_IFACE_SC; // Имя службы, реализующей интерфейс IProcessControl. char const* const processControlInterface = KOS_EXECMGR_IFACE_PC; // Имя класса процесса ExecutionManager. char const* const execmgrServerName = KOS_EXECMGR_SERVER_NAME; };

Функции execution_manager_proxy.h

Функция

Сведения о функции

CreateExecutionManager()

Назначение

Получение указателя на экземпляр интерфейса IExecutionManager, необходимого для работы с компонентом ExecutionManager.

Параметры

  • [in] cfg – структура ExecutionManagerConfig с параметрами конфигурации для соединения с процессом ExecutionManager.
  • [out] emp – указатель на экземпляр интерфейса IExecutionManager.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

Пример использования:

client.cpp

#include <component/execution_manager/kos_ipc/execution_manager_proxy.h> int main(int argc, const char *argv[]) { // ... execution_manager::ipc::ExecutionManagerConfig emCfg { // Имя IPC-канала для соединения с процессом ExecutionManager. // Должно совпадать со значением MAIN_CONN_NAME в файле // CMakeLists.txt для сборки компонента ExecutionManager. .mainConnection = "ExecMgrEntity", // Имя класса процесса ExecutionManager. .execmgrServerName = "kl.ExecMgrEntity" }; execution_manager::IExecutionManagerPtr emPtr; kos::Result res = CreateExecutionManager(emCfg, emPtr); if (res != kos::Ok) { std::cerr << fmt::format("[{}] Failed to create execution manager. res=0x{:x}\n", selfName, res); return EXIT_FAILURE; } // ... }

Интерфейс IExecutionManager

API определен в заголовочном файле sysroot-*-kos/include/component/execution_manager/i_execution_manager.h из состава KasperskyOS SDK.

Интерфейс IExecutionManager позволяет получить доступ к указателям на следующие интерфейсы:

  • IProcessControl – интерфейс, который позволяет запускать процесс из исполняемого файла, установленного компонентом PackageManager из KPA-пакета в решение на базе KasperskyOS, а также получать сведения о процессе (включая информацию о его завершении) и останавливать его.
  • IApplicationController – интерфейс, который позволяет запускать процесс из любого исполняемого файла, чье расположение в файловой системе известно, а также останавливать этот процесс.
  • IStateProvider – интерфейс для получения сведений о процессе, запущенном с использованием интерфейса IApplicationController.
  • ISystemController – интерфейс для управления системой.

Пример использования:

client.cpp

int main(int argc, const char *argv[]) { // ... alm::execution_manager::IProcessControlPtr pc; res = emPtr->GetProcessController(pc); if (res != kos::Ok) { std::cerr << fmt::format("[{}] Failed to create process controller. res=0x{:x}\n", selfName, res); return EXIT_FAILURE; } execmgr::IApplicationControllerPtr ac; if (ptr->GetApplicationController(ac) != kos::Ok) { std::cerr << "Can not get application controller" << std::endl; return EXIT_FAILURE; } execmgr::ISystemControllerPtr sc; if (ptr->GetSystemController(sc) != kos::Ok) { std::cerr << "Cannot get system controller" << std::endl; return EXIT_FAILURE; } // ... }

В этом разделе

Интерфейс IProcessControl

Интерфейс IApplicationController

Интерфейс IStateProvider

Интерфейс ISystemController

В начало
[Topic execmgr_component]

Интерфейс IProcessControl

API определен в заголовочном файле sysroot-*-kos/include/alm/execution_manager/i_process_control.h из состава KasperskyOS SDK.

API позволяет:

  • запускать процесс из исполняемого файла, установленного компонентом PackageManager из KPA-пакета в решение на базе KasperskyOS;
  • получать сведения о процессе (включая информацию о его завершении);
  • останавливать процесс.

Сведения о функциях API приведены в таблице ниже.

Запуск процесса

Чтобы запустить процесс, нужно вызвать функцию StartProcess(). Через входной параметр opts эта функция принимает параметры для запуска процесса в виде структуры StartOptions. Все поля этой структуры являются опциональными для инициализации.

struct StartOptions { // Дескриптор, который идентифицирует родительский процесс. IpcHandle parent{NK_INVALID_HANDLE, 0, NK_INVALID_HANDLE}; // Список пользовательских дескрипторов, // которые будут переданы процессу при его запуске. UserHandleItems userHandles; // Аргументы командной строки. Strings extraArgs; // Переменные окружения. Strings extraEnvs;};

При инициализации структуры StartOptions транспортный контейнер дескриптора parent заполняется значениями по умолчанию, которые означают отсутствие родительского процесса. Передавая в этом параметре запускаемому дочернему процессу дескриптор родительского процесса, можно создавать иерархию процессов.

Вектор userHandles является компонентом структуры StartOptions и содержит список пользовательских дескрипторов, которые будут переданы процессу при его запуске. Элементами списка являются пары, задаваемые в структуре UserHandleItem и состоящие из дескриптора и его имени. После запуска процесса переданные ему дескрипторы могут быть найдены с помощью функции KosTaskLookupResource() по их именам.

struct UserHandleItem { // Имя дескриптора. std::string id; // Дескриптор. IpcHandle handle; };

Входные параметры pkgId и runConfigId функции StartProcess() определены в манифесте KPA-пакета. Их значения могут быть получены с использованием функций из интерфейса IPackageManifest компонента PackageManager.

Остановка процесса

Чтобы остановить процесс, нужно вызвать функцию StopProcess(). Через входной параметр stopPolicy эта функция принимает политику остановки процесса из перечисления StopPolicy.

enum class StopPolicy : uint32_t { // Отправить процессу сигнал на остановку. Normal = 0, // Немедленно остановить процесс. Forced, };

Получение сведений о процессе

Чтобы запросить сведения о процессе, нужно вызвать функцию GetProcessState(). Через выходной параметр state эта функция возвращает сведения о процессе в виде структуры ProcessContext.

struct ProcessContext { // Состояние процесса. ProcessState state{}; // Системный статус завершения процесса. ExecutableExitStatus exitStatus{}; // Общий код завершения процесса. ExecutableExitCode exitCode{}; // Уточняющий код завершения процесса. ExecutableExitReason exitReason{}; };

Перечисление state является компонентом структуры ProcessContext и описывает состояние процесса.

enum class ProcessState : uint32_t { // Служебная константа. None = 0, // Процесс создан. Created, // Процесс инициализирован. Prepared, // Процесс запущен. Running, // Процесс аварийно остановлен. Failed, // Процесс остановлен, но данные о процессе доступны // для функции GetProcessState(). Finished, // Процесс завершен и не существует в системе. NotExisting, };

Перечисление exitStatus является компонентом структуры ProcessContext и описывает причину остановки процесса. Перечисление ExecutableExitStatus определено в заголовочном файле sysroot-*-kos/include/alm/execution_manager/execution_manager_types.h из состава KasperskyOS SDK.

enum class [[nodiscard]] ExecutableExitStatus : std::underlying_type_t<TaskExitStatus> { // Процесс ещё не запущен компонентом ExecutionManager. ExitUninitialized = TaskExitStatus::TaskExitUninitialized, // Процесс аварийно остановлен в результате необработанного исключения. ExitUnexpected = TaskExitStatus::TaskExitUnexpected, // Процесс завершил работу самостоятельно, в том числе // после получения сигнала на свою остановку при вызове // функции StopProcess() со значением Normal в политике остановки процесса. ExitNormal = TaskExitStatus::TaskExitNormal, // Процесс остановлен по внешнему запросу, в том числе вызовом функции // StopProcess() со значением Forced в политике остановки процесса. ExitTerminated = TaskExitStatus::TaskExitTerminated, };

Числовой параметр exitCode является компонентом структуры ProcessContext и содержит код возврата для процесса, который остановился самостоятельно, в том числе после получения сигнала на свою остановку. Значения для этого кода возврата определяются разработчиком решения на базе KasperskyOS.

Числовой параметр exitReason является компонентом структуры ProcessContext и содержит код возврата, который уточняет причину неудачной попытки запуска процесса, либо rcOk в случае успешного запуска. Параметр определен в заголовочном файле sysroot-*-kos/include/rtl_cpp/retcode.h из состава KasperskyOS SDK. В этом файле содержатся коды возврата, которые являются общими для API любых компонентов решения и их составных частей (см. "Коды возврата").

Функции i_process_control.h

Функция

Сведения о функции

StartProcess()

Назначение

Запускает процесс.

Параметры

  • [in] pkgId – идентификатор KPA-пакета.
  • [in] runConfigId – идентификатор конфигурации запуска.
  • [in] opts – структура StartOptions с параметрами запуска процесса.
  • [out] accessToken – ссылка на дескриптор, который идентифицирует запущенный процесс.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

StopProcess()

Назначение

Останавливает процесс.

Параметры

  • [in] accessToken – дескриптор, который идентифицирует запущенный процесс.
  • [in] stopPolicy – политика остановки процесса.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetProcessState()

Назначение

Запрашивает сведения о процессе.

Параметры

  • [in] accessToken – дескриптор, который идентифицирует запущенный процесс.
  • [out] state – ссылка на структуру ProcessContext, содержащую сведения о процессе.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

Пример использования:

client.cpp

int main(int argc, const char *argv[]) { // ... alm::execution_manager::IProcessControl::StartOptions startOptions{}; alm::execution_manager::IpcHandle procToken{}; // Идентификатор KPA-пакета. const std::string packageId{"application.Application"}; // Идентификатор конфигурации запуска. const std::string runConfigId{"app"}; kos::rtl::Result res = pc->StartProcess(packageId, runConfigId, startOptions, procToken); if (res != kos::rtl::Ok) { std::cerr << fmt::format("[{}] Failed to start process. res=0x{:x}\n", selfName, res); return EXIT_FAILURE; } alm::execution_manager::ProcessContext procContext{}; res = pc->GetProcessState(procToken, procContext); if (res != kos::rtl::Ok) { std::cerr << fmt::format("[{}] Failed to get process state. res=0x{:x}\n", selfName, res); return EXIT_FAILURE; } if (procContext.state == alm::execution_manager::ProcessState::Running) { std::cerr << fmt::format("[{}] Process state is Running.\n", selfName); } res = pc->StopProcess(procToken, alm::execution_manager::StopPolicy::Forced); if (res != kos::rtl::Ok) { std::cerr << fmt::format("[{}] Failed to stop process. res=0x{:x}\n", selfName, res); return EXIT_FAILURE; } // ... }
В начало
[Topic em_iprocesscontrol]

Интерфейс IApplicationController

API определен в заголовочном файле sysroot-*-kos/include/component/execution_manager/i_application_control.h из состава KasperskyOS SDK.

API позволяет запускать процесс из исполняемого файла, а также останавливать процесс.

Сведения о функциях API приведены в таблице ниже.

Чтобы запустить процесс, нужно вызвать функцию StartEntity(). Через входной параметр info эта функция принимает параметры для запуска процесса в виде структуры StartEntityInfo. Все поля этой структуры являются опциональными для инициализации. Через выходной параметр resInfo эта функция возвращает ссылку на структуру StartEntityResultInfo с результатами запуска процесса.

Чтобы остановить процесс, нужно вызвать функцию ShutdownEntity() или StopEntity(). Через входной параметр entId эти функции принимают дескриптор, идентифицирующий запущенный процесс.

struct IApplicationController { struct StartEntityInfo { // Имя процесса. Если не указано, то будет использовано имя класса процесса. // Если не указано имя класса процесса, то будет использовано имя исполняемого файла. std::string entityName; // Класс процесса. Если не указан, то будет использовано имя процесса. // Если не указано имя процесса, то будет использовано имя исполняемого файла. std::string eiid; // Аргументы командной строки. std::vector<std::string> args; // Переменные окружения. std::vector<std::string> envs; // Политика перезапуска процесса при его аварийном завершении. Возможные значения: // EntityRestartPolicy::DoNotRestart - не перезапускать. // EntityRestartPolicy::AlwaysRestart - всегда перезапускать. EntityRestartPolicy restartPolicy { EntityRestartPolicy::DoNotRestart }; }; struct StartEntityResultInfo { // Класс безопасности, присвоенный процессу. std::string eiid; // Дескриптор, идентифицирующий запущенный процесс. EntityId entId; // Идентификатор безопасности запущенного процесса. Uid sid; // Имя запущенного процесса. std::string taskName; }; };

Функции i_application_control.h

Функция

Сведения о функции

StartEntity()

Назначение

Запускает процесс.

Параметры

  • [in] runPath – путь к исполняемому файлу, который нужно запустить.
  • [in] info – структура с параметрами запуска процесса StartEntityInfo.
  • [out] resInfo – структура с результатами запуска процесса StartEntityResultInfo.
  • [out] containerPath – путь к изолированному хранилищу данных процесса.

Возвращаемые значения

В случае успеха возвращает kos::Ok, иначе возвращает код ошибки.

ShutdownEntity()

Назначение

Отправляет процессу сигнал на завершение.

Параметры

  • [in] entId – дескриптор, идентифицирующий запущенный процесс.

Возвращаемые значения

В случае успеха возвращает kos::Ok, иначе возвращает код ошибки.

StopEntity()

Назначение

Немедленно останавливает исполнение процесса.

Параметры

  • [in] entId – дескриптор, идентифицирующее запущенный процесс.

Возвращаемые значения

В случае успеха возвращает kos::Ok, иначе возвращает код ошибки.

Пример использования:

client.cpp

int main(int argc, const char *argv[]) { // ... const fs::path appPath{"/application"}; execmgr::IApplicationController::StartEntityResultInfo result; execmgr::IApplicationController::StartEntityInfo info; info.entityName = std::string{"application.Application"}; info.eiid = std::string{"application.Application"}; info.args = std::vector<std::string>{"1", "ARG1", "ARG2" , "ARG3"}; info.envs = std::vector<std::string>{"ENV1=10", "ENV2=envStr"}; std::cout << "Starting application from elf\n"; if (ac->StartEntity(appPath, info, result) != kos::Ok) { std::cerr << "Can not start application from " << appPath << std::endl; return EXIT_FAILURE; } std::cout << "Application started with process sid " << result.sid << "\n"; auto AppId = result.entId; if (ac->StopEntity(AppId) != kos::Ok) { std::cerr << "Cannot stop process " << appPath << std::endl; return EXIT_FAILURE; } // ... }
В начало
[Topic em_iapplicationcontroller]

Интерфейс IStateProvider

API определен в заголовочном файле sysroot-*-kos/include/component/execution_manager/i_state_control.h из состава KasperskyOS SDK.

API позволяет получать сведения о процессе, запущенном с использованием функции StartEntity() из API IApplicationController (см. "Интерфейс IApplicationController"), включая информацию о причине его завершения.

Сведения о функциях API приведены в таблице ниже.

Чтобы получить сведения о процессе, нужно вызвать функцию GetApplicationState(). Через входной параметр entityId эта функция принимает значение типа EntityId, которое идентифицирует запущенный процесс. Через выходной параметр appState эта функция возвращает сведения о процессе в виде структуры AppContext. Структура AppContext определена в заголовочном файле sysroot-*-kos/include/component/execution_manager/types.h из состава KasperskyOS SDK

struct AppContext { // Состояние процесса. AppState state{}; // Причина остановки процесса. alm::execution_manager::ExecutableExitStatus exitStatus{}; // Код возврата для процесса, // который остановился самостоятельно. alm::execution_manager::ExecutableExitCode exitCode{}; // Код возврата, который уточняет причину // неудачной попытки запуска процесса. alm::execution_manager::ExecutableExitReason exitReason{}; };

Перечисление state является компонентом структуры AppContext и описывает состояние процесса. Перечисление state определено в заголовочном файле sysroot-*-kos/include/component/execution_manager/types.h из состава KasperskyOS SDK.

enum class AppState : uint32_t { None = 0, // Процесс запущен. Started, // Процесс перезапущен. Restarted, // Процесс остановлен с помощью функции StopEntity() // из API IApplicationController. Stopped, // Процесс остановлен с помощью функции ShutdownEntity() // из API IApplicationController. Completed, // Процесс аварийно остановлен // в результате необработанного исключения. Failed, };

Перечисление exitStatus является компонентом структуры AppContext и описывает причину остановки процесса. Перечисление ExecutableExitStatus определено в заголовочном файле sysroot-*-kos/include/alm/execution_manager/execution_manager_types.h из состава KasperskyOS SDK.

enum class [[nodiscard]] ExecutableExitStatus : std::underlying_type_t<TaskExitStatus> { // Процесс ещё не запущен компонентом ExecutionManager. ExitUninitialized = TaskExitStatus::TaskExitUninitialized, // Процесс аварийно остановлен в результате необработанного исключения. ExitUnexpected = TaskExitStatus::TaskExitUnexpected, // Процесс завершил работу самостоятельно, // в том числе после получения сигнала на остановку // при вызове функции ShutdownEntity() из API IApplicationController. ExitNormal = TaskExitStatus::TaskExitNormal, // Процесс остановлен по внешнему запросу, в том числе вызовом // функции StopEntity() из API IApplicationController. ExitTerminated = TaskExitStatus::TaskExitTerminated, };

Числовой параметр exitCode является компонентом структуры AppContext и содержит код возврата для процесса, который остановился самостоятельно, в том числе после получения сигнала на свою остановку. Значения для этого кода возврата определяются разработчиком решения на базе KasperskyOS.

Числовой параметр exitReason является компонентом структуры AppContext и содержит код возврата, который уточняет причину неудачной попытки запуска процесса, либо rcOk в случае успешного запуска процесса. Параметр определен в заголовочном файле sysroot-*-kos/include/rtl_cpp/retcode.h из состава KasperskyOS SDK. В этом файле содержатся коды возврата, которые являются общими для API любых компонентов решения и их составных частей (см. "Коды возврата").

Функции i_state_control

Функция

Сведения о функции

GetApplicationState()

Назначение

Запрашивает сведения о процессе.

Параметры

  • [in] entityId – значение типа EntityId, которое идентифицирует запущенный процесс.
  • [out] appState – ссылка на структуру AppContext, содержащую сведения о процессе.

Возвращаемые значения

В случае успеха возвращает kos::Ok, иначе возвращает код ошибки.

Пример использования:

client.cpp

int main(int argc, const char *argv[]) { // ... execution_manager::AppContext appContext(); if (rc = m_sc->GetApplicationState(entityId, appContext), rc != kos::Ok) { KOS_LOGERROR("GetApplicationState: failure with entity {}: {}", entityName, RC_GET_CODE(rc)); return rc; } // ... }
В начало
[Topic em_istateprovider]

Интерфейс ISystemController

API определен в заголовочном файле sysroot-*-kos/include/component/execution_manager/i_system_control.h из состава KasperskyOS SDK.

API позволяет завершать работу системы.

Сведения о функциях API приведены в таблице ниже.

Функции i_system_control.h

Функция

Сведения о функции

StopAllEntities()

Назначение

Останавливает все запущенные процессы; затем завершает процесс ExecutionManager; а затем отправляет в ядро запрос на выключение устройства.

Параметры

Нет.

Возвращаемые значения

В случае успеха возвращает kos::Ok, иначе возвращает код ошибки.

Пример использования:

client.cpp

int main(int argc, const char *argv[]) { // ... if (sc->StopAllEntities() != kos::Ok) { std::cerr << "Cannot stop all processes\n"; return EXIT_FAILURE; } // ... }
В начало
[Topic em_isystemcontroller]

Компонент PackageManager

API определен в заголовочных файлах, расположенных в директории sysroot-*-kos/include/component/package_manager/ из состава KasperskyOS SDK.

Сценарий использования компонента PackageManager описан в статье "Сценарий использования компонента PackageManager".

Интерфейс package_manager_proxy.h

API определен в заголовочном файле sysroot-*-kos/include/component/package_manager/kos_ipc/package_manager_proxy.h из состава KasperskyOS SDK.

Интерфейс содержит функцию CreatePackageManager() для получения указателя на экземпляр интерфейса IPackageManager, необходимого для работы с компонентом PackageManager. Через входной параметр cfg эта функция принимает параметры конфигурации в виде структуры PackageManagerConfig. Все поля этой структуры опциональны для заполнения.

struct PackageManagerConfig { // Имя IPC-канала для соединения с процессом PackageManager. std::string const mainConnection = KOS_PKGMGR_CONN_MAIN; // Имя службы, реализующей интерфейс IPackageController. std::string const pkgControlInterface = KOS_PKGMGR_IFACE_PKGC; // Имя класса процесса PackageManager. std::string const pkgMgrServerName = KOS_PKGMGR_SERVER_NAME; };

Функции package_manager_proxy.h

Функция

Сведения о функции

CreatePackageManager()

Назначение

Получение указателя на экземпляр интерфейса IPackageManager, необходимого для работы с компонентом PackageManager.

Параметры

  • [in] cfg – структура PackageManagerConfig с параметрами конфигурации для соединения с процессом PackageManager.
  • [out] iPkgMgr – указатель на экземпляр интерфейса IPackageManager.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

Пример использования:

client.cpp

#include <component/package_manager/kos_ipc/package_manager_proxy.h> namespace pkgmgr = package_manager; int main(int argc, const char *argv[]) { // ... pkgmgr::IPackageManagerPtr iPkgMgr; std::string mainConnection{"PkgMgrEntity"}; std::string pkgControlInterface{"kl.package_manager.PackageManager.ipkgc"}; pkgmgr::ipc::PackageManagerConfig cfg{mainConnection, pkgControlInterface}; if (CreatePackageManager(cfg, iPkgMgr) != kos::rtl::Ok) return EXIT_FAILURE; // ... }

Интерфейс IPackageManager

API определен в заголовочном файле sysroot-*-kos/include/component/package_manager/i_package_manager.h из состава KasperskyOS SDK.

Интерфейс IPackageManager позволяет получить указатель на интерфейс IPackageController. Этот интерфейс предназначен для установки KPA-пакетов в решение на базе KasperskyOS, а также получения сведений о них.

Функции i_package_manager.h

Функция

Сведения о функции

GetPackageController()

Назначение

Получение указателя на экземпляр интерфейса IPackageController.

Параметры

  • [out] pkgController – указатель на экземпляр интерфейса IPackageController.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

Пример использования:

client.cpp

int main(int argc, const char *argv[]) { // ... pkgmgr::IPackageControllerPtr pkgc; if (iPkgMgr->GetPackageController(pkgc) != kos::rtl::Ok) return EXIT_FAILURE; // ... }

В этом разделе

Интерфейс IPackageController

Интерфейс IPackageManifest

В начало
[Topic packmgr_component]

Интерфейс IPackageController

API определен в заголовочном файле sysroot-*-kos/include/component/package_manager/i_package_control.h из состава KasperskyOS SDK.

API позволяет:

  • устанавливать KPA-пакет в решение на базе KasperskyOS и удалять KPA-пакет;
  • получать сведения об установленном KPA-пакете: уникальный идентификатор, данные из манифеста KPA-пакета, статус KPA-пакета (установлен или удален).

Сведения о функциях API приведены в таблице ниже.

Установка KPA-пакета

Чтобы установить KPA-пакет, нужно вызвать функцию InstallPackage(). Через входной параметр pkgInfo эта функция принимает данные для проверки сертификатов устанавливаемого KPA-пакета в виде структуры InstallPackageInfo. Все поля этой структуры являются опциональными для заполнения.

struct InstallPackageInfo { // Полное имя файла внешней подписи KPA-пакета. std::filesystem::path signaturePath = ""; // Полное имя файла индексного файла KPA-пакета. std::filesystem::path indexPath = ""; // Проверять ли сертификаты устанавливаемого KPA-пакета. bool signatureVerify = false; };

Если параметр signatureVerify установлен в значение true (проверять сертификаты устанавливаемого KPA-пакета), а имена файлов не указаны, то при установке KPA-пакета будут использованы значения по умолчанию: <имя_пакета>.kcat для файла внешней подписи KPA-пакета и <имя_пакета>.kidx для индексного файла KPA-пакета.

Удаление KPA-пакета

Чтобы удалить KPA-пакет, нужно вызвать функцию UninstallPackage().

Получение сведений об установленных KPA-пакетах

Чтобы получить уникальные идентификаторы установленных KPA-пакетов, нужно вызвать функцию ListInstalledPackages(). Через выходной параметр pkgUIDs функция возвращает список уникальных идентификаторов установленных пакетов.

Чтобы получить данные о манифесте KPA-пакета, нужно вызвать функцию GetManifest(). Через выходной параметр manifest функция возвращает указатель на экземпляр интерфейса IPackageManifest, используя который можно получить доступ к значениям ключей манифеста KPA-пакета. Подробнее см. "Интерфейс IPackageManifest".

Уведомления о статусах KPA-пакетов в решении на базе KasperskyOS

Компонент PackageManager реализует механизм уведомлений о статусах KPA-пакетов в решении на базе KasperskyOS, позволяя отслеживать изменения в их состоянии. Для получения уведомлений нужно создать очередь уведомлений используя функцию CreateEventQueue().

Чтобы извлекать уведомления из этой очереди, нужно использовать функцию GetEvents(). Через выходной параметр pkgEvents функция возвращает статус KPA-пакетов (с момента создания очереди) в виде структуры PackageEvent.

struct PackageEvent { enum class Type { // KPA-пакет установлен. INSTALL, // KPA-пакет удален. UNINSTALL, // Очередь уведомлений переполнена. OVERFLOWED, }; // Статус KPA-пакета. Type type; // Уникальный идентификатор KPA-пакета. std::string uid; };

Чтобы удалить очередь уведомлений, нужно вызвать функцию DestroyEventQueue().

Функции i_package_control.h

Функция

Сведения о функции

InstallPackage()

Назначение

Устанавливает KPA-пакет.

Параметры

  • [in] pkgName – имя KPA-пакета, который требуется установить.
  • [out] pkgUID – уникальный идентификатор установленного KPA-пакета.
  • [in] pkgInfo – структура InstallPackageInfo, которая содержит данные для проверки сертификатов устанавливаемого KPA-пакета.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

UninstallPackage()

Назначение

Удаляет KPA-пакет.

Параметры

  • [in] pkgUID – уникальный идентификатор KPA-пакета, который требуется удалить.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

ListInstalledPackages()

Назначение

Получает уникальные идентификаторы установленных KPA-пакетов.

Параметры

  • [out] pkgUIDs – массив уникальных идентификаторов установленных KPA-пакетов.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetManifest()

Назначение

Получает указатель на экземпляр интерфейса IPackageManifest, необходимого для получения данных о манифесте KPA-пакета.

Параметры

  • [in] pkgUID – уникальный идентификатор KPA-пакета, о манифесте которого требуется получить данные.
  • [out] manifest – указатель на экземпляр интерфейса IPackageManifest.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetItemDigest()

Назначение

Получает хеш-сумму файла компонента KPA-пакета из базы данных компонента PackageManager.

Параметры

  • [in] itemPath – полное имя файла компонента KPA-пакета, хеш-сумму которого требуется получить.
  • [out] digest – хеш-сумма файла компонента KPA-пакета.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetArtifactBlob()

Назначение

Получает содержимое компонента KPA-пакета.

Параметры

  • [in] pkgUID – уникальный идентификатор KPA-пакета, частью которого является запрашиваемый компонент.
  • [in] artifactType – тип компонента KPA-пакета. Подробнее см. "Список объектов components"
  • [in] artifactName – имя компонента KPA-пакета.
  • [out] blob – массив байтов, представляющий содержимое компонента KPA-пакета.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

CreateEventQueue()

Назначение

Создает очередь уведомлений о статусах KPA-пакетов.

Параметры

  • [out] queueHandle – ссылка на дескриптор очереди уведомлений.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

DestroyEventQueue()

Назначение

Удаляет очередь уведомлений о статусах KPA-пакетов.

Параметры

  • [in] queueHandle – дескриптор очереди уведомлений.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetEvents()

Назначение

Получает из очереди уведомлений статусы KPA-пакетов.

Параметры

  • [in] queueHandle – дескриптор очереди уведомлений.
  • [out] pkgEvents – структура PackageEvent со статусами KPA-пакетов.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

Пример использования:

client.cpp

#include <component/package_manager/kos_ipc/package_manager_proxy.h> namespace pkgmgr = package_manager; int main(int argc, const char *argv[]) { // ... // Создать очередь уведомлений о статусах KPA-пакетов. Handle eventQueue; if (pkgc->CreateEventQueue(eventQueue) != kos::rtl::Ok) return EXIT_FAILURE; // Установить KPA-пакет с именем test1. std::string uid1; const std::string pkgName1{"test1"}; const package_manager::InstallPackageInfo pkgInfo1{"", "", true}; if (pkgc->InstallPackage(pkgName1, uid1, pkgInfo1) != kos::rtl::Ok) return EXIT_FAILURE; // Установить KPA-пакет с именем test2. std::string uid2; const std::string pkgName2{"test2"}; const package_manager::InstallPackageInfo pkgInfo2{"/test2.kcat", "/test2.kidx", true}; if (pkgc->InstallPackage(pkgName2, uid2, pkgInfo2) != kos::rtl::Ok) return EXIT_FAILURE; // Получить указатель на экземпляр интерфейса IPackageManifest // для KPA-пакета с именем test1. pkgmgr::IPackageManifestPtr manifest; if (pkgc->GetManifest(uid1, manifest) != kos::rtl::Ok) return EXIT_FAILURE; // Получить уникальные идентификаторы установленных KPA-пакетов. std::vector<std::string> pkgUIDs; if (pkgc->ListInstalledPackages(pkgUIDs) != kos::rtl::Ok) return EXIT_FAILURE; // Удалить KPA-пакет с именем test1. if (pkgc->UninstallPackage(uid1) != kos::rtl::Ok) return EXIT_FAILURE; // Удалить KPA-пакет с именем test2. if (pkgc->UninstallPackage(uid2) != kos::rtl::Ok) return EXIT_FAILURE; // Получить из очереди уведомлений статусы KPA-пакетов. std::vector<package_manager::PackageEvent> pkgEvents; if (pkgc->GetEvents(eventQueue, pkgEvents) != kos::rtl::Ok) return EXIT_FAILURE; // Удалить очередь уведомлений. if (pkgc->DestroyEventQueue(eventQueue) != kos::rtl::Ok) return EXIT_FAILURE; if (KnHandleClose(eventQueue) != rcOk) return EXIT_FAILURE; // ... }
В начало
[Topic pm_ipackagecontroller]

Интерфейс IPackageManifest

API определен в заголовочном файле sysroot-*-kos/include/component/package_manager/i_package_manifest.h из состава KasperskyOS SDK.

API позволяет получать значения ключей манифеста KPA-пакета. Подробнее о доступных ключах манифеста KPA-пакета см. "Манифест KPA-пакета"

Сведения о функциях API приведены в таблице ниже.

Получение идентификатора программы

Чтобы получить идентификатор программы, установленной из KPA-пакета, нужно вызвать функцию GetPackageID().

Получение сведений о компонентах KPA-пакета

Чтобы получить сведения о компонентах KPA-пакета, нужно вызвать функцию GetApplicationsInfo(). Через выходной параметр applications функция возвращает сведения о компонентах KPA-пакета в виде вектора структур ApplicationInfo.

struct ApplicationInfo { // Имя компонента KPA-пакета. std::string name; // Путь к директории относительно пути /<имя пакета>/res, // в которую установлен компонент KPA-пакета. std::string path; // Неиспользуемый параметр. std::string iconPath; // Неиспользуемый параметр. std::string containerPath; // Неиспользуемый параметр. std::string etcPath; // Хеш-сумма файла компонента KPA-пакета. std::string digest; // Объект формата JSON. ManifestType extensions; // Тип компонента KPA-пакета. std::string type; };

Элемент структуры extensions описывает объект формата JSON. ManifestType является псевдонимом типа nlohmann:json.

Получение конфигураций запуска программы

Чтобы получить сведения о конфигурациях запуска программы, установленной из KPA-пакета, нужно вызвать функцию GetRunConfigurationsInfo(). Через выходной параметр runConfigurations функция возвращает сведения о конфигурациях запуска программы в виде вектора структур RunConfigurationInfo.

struct RunConfigurationInfo { // Уникальный в рамках данного KPA-пакета идентификатор конфигурации запуска. std::string id; // Имя конфигурации запуска. std::string name; // Класс безопасности программы. std::string eiid; // Путь к файлу компонента KPA-пакета. std::string path; // Список аргументов в виде массива строк. std::vector<std::string> args{}; // Список переменных окружения. std::vector<std::string> envs{}; // Указывает, является эта конфигурация запуска первичной при старте программы: // true – является первичной, false – не является. bool primary{false}; // Указывает, является эта конфигурация запускаемой автоматически: // true – является запускаемой автоматически, false – не является. bool autorun{false}; };

Получение сведений о программе

Чтобы получить сведения о программе, установленной из KPA-пакета, нужно вызвать функцию GetPackageInfo(). Через выходной параметр packageInfo функция возвращает сведения о конфигурациях запуска в виде структуры PackageInfo.

struct PackageInfo { // Уникальный идентификатор программы. std::string id; // Название программы. std::string name; // Версия программы. std::string version; // Неиспользуемый параметр. std::string title; // Неиспользуемый параметр. std::string summary; // Описание программы. std::string description; // Номер сборки программы. std::string buildNumber; // Логическое значение, указывающее на то, является ли программа системной: // true – является, false – не является. bool systemApplication; // Объект произвольного формата. ManifestType extensions; };

Получение сведений об изолированном хранилище программы

Чтобы получить сведения об изолированном хранилище программы, нужно вызвать функцию GetPrivateStorageInfo(). Через выходной параметр packageInfo функция возвращает сведения о конфигурациях запуска в виде структуры PrivateStorage.

struct PrivateStorage { // Размер хранилища данных программы в МБ. size_t size; // Тип файловой системы хранилища данных программы. std::string fsType; };

Получение сведений об объектах произвольного формата

Чтобы получить сведения об объектах произвольного формата, которые добавлены разработчиком KPA-пакета (ключ extensions из манифеста KPA-пакета), нужно вызвать функцию Get().

Функции i_package_manifest.h

Функция

Сведения о функции

GetPackageID()

Назначение

Получает уникальный идентификатор программы, установленной из KPA-пакета.

Параметры

  • [out] id – уникальный идентификатор программы.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetApplicationsInfo()

Назначение

Получает сведения о компонентах KPA-пакета.

Параметры

  • [out] applications – вектор структур ApplicationInfo, содержащих сведения о компонентах KPA-пакета.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetRunConfigurationsInfo()

Назначение

Получает сведения о конфигурациях запуска программы, установленной из KPA-пакета.

Параметры

  • [out] runConfigurations – вектор структур RunConfigurationInfo, содержащих сведения о конфигурациях запуска.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetPackageInfo()

Назначение

Получает сведения о программе, установленной из KPA-пакета.

Параметры

  • [out] packageInfo – структура PackageInfo, содержащая сведения о программе.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

GetPrivateStorageInfo()

Назначение

Получает сведения об изолированно хранилище программы.

Параметры

  • [out] packageInfo – структура PrivateStorage, содержащая сведения об изолированном хранилище программы.

Возвращаемые значения

В случае успеха возвращает kos::rtl::Ok, иначе возвращает код ошибки.

Get()

Назначение

Получает сведения об объектах произвольного формата, который добавлены в манифест разработчиком KPA-пакета.

Параметры

Нет.

Возвращаемые значения

Возвращает указатель на объект типа pkgmgr::IPackageManifest::ManifestType.

Пример использования:

client.cpp

#include <component/package_manager/kos_ipc/package_manager_proxy.h> namespace pkgmgr = package_manager; int main(int argc, const char *argv[]) { // ... // Получить указатель на экземпляр интерфейса IPackageManifest // для KPA-пакета с уникальным идентификатором uid1. pkgmgr::IPackageManifestPtr manifest; if (pkgc->GetManifest(uid1, manifest) != kos::rtl::Ok) return EXIT_FAILURE; // Получить уникальный идентификатор программы. std::string packageID; if (manifest->GetPackageID(packageID) != kos::rtl::Ok) return EXIT_FAILURE; std::cout << packageID << '\n'; // Получить сведения о компонентах KPA-пакета. std::vector<package_manager::IPackageManifest::ApplicationInfo> infos; manifest->GetApplicationsInfo(infos); for (auto &info: infos) { std::cout << info.name << " " << info.path << "\n"; } // Получить сведения об объектах произвольного формата. pkgmgr::IPackageManifest::ManifestType jsonManifest = manifest->Get(); std::cout << jsonManifest["package"]["description"] << '\n'; // Получить сведения о конфигурациях запуска программы, установленной из KPA-пакета. std::vector<package_manager::IPackageManifest::RunConfigurationInfo> runConfigurationInfos; manifest->GetRunConfigurationsInfo(runConfigurationInfos); for (auto &runConfigurationInfo : runConfigurationInfos) { std::cout << "RunConfiguration.id = " << runConfigurationInfo.id << ", autorun = " << runConfigurationInfo.autorun << "\n"; } // ... }
В начало
[Topic pm_ipackagemanifest]