API определен в заголовочном файле sysroot-*-kos/include/component/execution_manager/i_application_control.h из состава KasperskyOS SDK.
API позволяет запускать процесс из исполняемого файла, а также останавливать процесс.
Сведения о функциях API приведены в таблице ниже.
Чтобы запустить процесс, нужно вызвать функцию StartEntity(). Через входной параметр info эта функция принимает параметры для запуска процесса в виде структуры StartEntityInfo. Все поля этой структуры являются опциональными для инициализации. Через выходной параметр resInfo эта функция возвращает ссылку на структуру StartEntityResultInfo с результатами запуска процесса.
struct IApplicationController
{
struct StartEntityInfo
{
// Имя процесса. Если не указано, то будет использовано имя класса процесса.
// Если не указано имя класса процесса, то будет использовано имя исполняемого файла.
std::string entityName{};
// Класс процесса. Если не указан, то будет использовано имя процесса.
// Если не указано имя процесса, то будет использовано имя исполняемого файла.
std::string eiid{};
// Аргументы командной строки.
std::vector<std::string> args{};
// Переменные окружения, которые передаются запускаемому процессу.
std::vector<std::string> envs{};
// Переменные окружения, которые передаются в изолированное хранилище данных процесса.
std::vector<std::string> containerEnvs{};
// Флаг, который определяет поведение Execution Manager при запуске процесса:
// true – приостановить выполнение и ожидать события kEmAppReady от
// запущенного процесса, которое подтверждает его готовность к работе.
// false – продолжить работу сразу после запуска процесса,
// не дожидаясь подтверждения его готовности.
bool wait{false};
// Битовая маска флагов, управляющих поведением изолированного хранилища данных процесса:
// 0 – создать копию хранилища для запускаемого процесса;
// EM_FLAG_DO_NOT_COPY_CONTAINER – использовать хранилище родительского процесса
// вместо создания новой копии.
uint32_t flags{0};
// Политика обработки аварийного завершения процесса:
// CrashMode::None – не выполнять никаких действий;
// CrashMode::Dump – создать аварийный дамп;
// CrashMode::Panic – выключить или перезагрузить аппаратную платформу.
CrashMode mode{CrashMode::None};
};
struct StartEntityResultInfo
{
// Класс безопасности, присвоенный процессу.
std::string eiid;
// Дескриптор, идентифицирующий запущенный процесс.
EntityId entId{nk_handle_desc(INVALID_HANDLE)};
// Идентификатор безопасности запущенного процесса.
Uid sid{0};
// Имя запущенного процесса.
std::string taskName;
};
};
Если в поле mode структуры StartEntityInfo установлено значение Dump, то при аварийном завершении процесса автоматически формируется аварийный дамп с использованием системной программы DumpCollector. Системная программа DumpCollector должна быть включена в разрабатываемое решение на базе KasperskyOS. (Подробнее о механизме создания аварийного дампа см. в "Пример dump_collector".) Аварийный дамп содержит диагностические данные: трассировку стека, состояние регистров процессора, информацию о потоках и карту памяти процесса. Сформированный аварийный дамп выводится в консоль с использованием компонента LogRR.
Чтобы запустить процесс и передать ему список пользовательских дескрипторов нужно вызвать функцию StartEntityWithUserHandlesEx(). В качестве входного параметра эта функция принимает вектор userHandles, который содержит список пользовательских дескрипторов, передаваемых процессу при его запуске. Элементами вектора являются структуры UserHandleItem, состоящие из дескриптора и его имени. После запуска процесса переданные ему дескрипторы могут быть найдены с помощью функции KosTaskLookupResource() по их именам.
struct UserHandleItem
{
// Имя дескриптора.
std::string id;
// Дескриптор.
IpcHandle handle;
};
Функция StartEntityWithUserHandles() запускает процесс и передает ему список дескрипторов. Список дескрипторов задается в параметре userHandles, который представляет собой массив типа UserHandlesArray:
using UserHandlesArray = std::array<nk_handle_desc_t, EM_USER_HANDLES_MAX>;
Чтобы остановить процесс, нужно вызвать функцию ShutdownEntity() или StopEntity(). Через входной параметр entId эти функции принимают дескриптор, идентифицирующий запущенный процесс.
Функции i_application_control.h
Функция |
Сведения о функции |
|---|---|
|
Назначение Запускает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Запускает процесс и передает ему список дескрипторов. Имена дескрипторов генерируются автоматически. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Запускает процесс и передает ему список дескрипторов. Имена дескрипторов задаются пользователем. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Отправляет процессу сигнал на завершение. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Немедленно останавливает исполнение процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
Пример запуска и остановки процесса с использованием функций StartEntity() и StopEntity():
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;
}
// ...
}
Пример запуска процесса и передачи ему пользовательского дескриптора с использованием функции StartEntityWithUserHandlesEx():
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->StartEntityWithUserHandlesEx(
appPath,
info,
{
{
.id = "vfs",
.handle = nk_handle_desc(file, OCAP_FILEOP_READ | OCAP_FILEOP_WRITE | OCAP_FILEOP_STAT | OCAP_FILEOP_CLOSE | OCAP_HANDLE_TRANSFER),
},
},
result) != kos::Ok)
{
std::cerr << "Can not start entity from " << appPath << std::endl;
return EXIT_FAILURE;
}
// ...
}
application.cpp
int main(int argc, const char *argv[])
{
std::cout << "application" << " started\n";
// Проверяется, что пользовательский дескриптор получен
auto h = KosTaskLookupResource("vfs");
if (h == INVALID_HANDLE)
{
std::cout << "Can not receive vfs handle" << std::endl;
return EXIT_FAILURE;
}
// ...
}
В начало