В этой статье приведен сценарий использования 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);
}
Сценарий включает следующие шаги:
KnHandleCreateUserObject() для создания дескриптора ресурса. Поставщик ресурса сохраняет дескриптор ресурса в контексте пользовательского ресурса.OpenResource().KnHandleCreateBadge() для создания объекта контекста передачи ресурса и настройки приемника уведомлений на прием уведомлений о закрытии и прекращении существования объекта контекста передачи ресурса. Поставщик ресурса сохраняет дескриптор объекта контекста передачи ресурса и указатель на контекст пользовательского ресурса в контексте передачи ресурса.nk_handle_desc(), упаковывает дескриптор ресурса, маску прав дескриптора и указатель на объект контекста передачи ресурса в транспортный контейнер дескриптора.OpenResource() завершается успешно. Клиент извлекает дескриптор и маску прав дескриптора из транспортного контейнера дескриптора функциями nk_get_handle() и nk_get_rights() соответственно. Маска прав дескриптора не требуется клиенту для обращения к ресурсу и передается, чтобы клиент мог узнать свои права доступа к ресурсу.UseResource().UseResource(). Перед вызовом этого метода клиент упаковывает дескриптор в транспортный контейнер дескриптора макросом nk_handle_desc().nk_is_handle_dereferenced(), проверяет, что выполнена операция разыменования, а не передача дескриптора.nk_get_badge_op(), которая извлекает указатель на контекст передачи ресурса из транспортного контейнера дескриптора, если в полученной маске прав установлены флаги, соответствующие запрашиваемой операции.UseResource() завершается успешно. Клиент получает результат выполнения операции над ресурсом.CloseResource().CloseResource(). Перед вызовом этого метода клиент упаковывает дескриптор в транспортный контейнер дескриптора макросом nk_handle_desc(). После вызова метода CloseResource() клиент удаляет дескриптор функцией KnHandleClose().nk_is_handle_dereferenced(), проверяет, что выполнена операция разыменования, а не передача дескриптора.nk_get_badge(), извлекает указатель на контекст передачи ресурса из транспортного контейнера дескриптора.KnHandleRevokeSubtree(). В качестве аргументов этой функции используются дескриптор ресурса, которым владеет поставщик ресурса, и дескриптор объекта контекста передачи ресурса. Поставщик ресурса получает доступ к этим дескрипторам через указатель на контекст передачи ресурса. (Технически не требуется отзывать дескриптор, которым владеет клиент, так как клиент его уже удалил. Но поставщик ресурса не может быть уверен в том, что клиент удалил дескриптор, поэтому выполняется отзыв).CloseResource() завершается успешно.KnNoticeGetEvent() получает уведомление, что объект контекста передачи ресурса закрыт, и удаляет дескриптор объекта контекста передачи ресурса функцией KnHandleClose().KnNoticeGetEvent() получает уведомление, что объект контекста передачи ресурса прекратил свое существование, и освобождает память, которая была выделена под контекст передачи ресурса.KnHandleClose() и освобождает память, которая была выделена под контекст пользовательского ресурса.