KasperskyOS Community Edition 1.1
Пример использования 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() и освобождает память, которая была выделена под контекст пользовательского ресурса.