Управление объектами
В этом разделе рассматривается правильное использование типов объектов API платформы фильтрации Windows (МПП).
Сеансов
API МПП ориентирован на сеанс, и большинство вызовов функций выполняются в контексте сеанса. Новый сеанс клиента создается путем вызова FwpmEngineOpen0. Сеанс заканчивается либо после вызова клиентом FwpmEngineClose0, либо после завершения клиентского процесса. При уничтожении сеанса сначала прерывается любая существующая транзакция либо с помощью запуска RPC, подсистема базовой фильтрации (BFE).
При создании нового сеанса вызывающий объект может создать динамический сеанс, передав флаг FWPM_SESSION_FLAG_DYNAMIC в FwpmEngineOpen0. Все объекты, добавленные во время динамического сеанса, автоматически удаляются при завершении сеанса.
Операций
API МПП является транзакциональным, и большинство вызовов функций выполняются в контексте транзакции. Вызывающие элементы могут использовать FwpmTransactionBegin0, FwpmTransactionCommit0и FwpmTransactionAbort0 для явного управления транзакциями. Однако если вызов функции выполняется вне явной транзакции, он будет выполняться в неявной транзакции. Если транзакция выполняется, когда сеанс завершается, он автоматически прерывается. Неявные транзакции никогда не прерываются принудительно.
Транзакции доступны только для чтения или чтения и записи и применяют строгую семантику атомарного изолированного изолированного (ACID) .
Каждый сеанс клиента может одновременно выполнять только одну транзакцию. Если вызывающий объект пытается начать вторую транзакцию перед фиксацией или прерыванием первой, BFE возвращает ошибку.
Если операция завершается ошибкой во время транзакции, она не влияет на общее состояние транзакции. Например, предположим, что клиент начинает транзакцию и успешно вызывает FwpmFilterAdd0 три раза до сбоя четвертого вызова. Теперь клиент имеет возможность:
- Прерывание транзакции, в этом случае ни один из фильтров не будет добавлен.
- Фиксация транзакции, в этом случае будут добавлены первые три фильтра.
- Продолжая больше операций, включая потенциально повторную попытку FwpmFilterAdd0.
При запуске транзакции BFE будет ждать, пока сеанса txnWaitTimeoutInMSec истекает, чтобы получить блокировку. Если блокировка не приобретена в течение этого времени, приобретение блокировки (и вызов FwpmTransactionBegin0) завершится ошибкой. Это позволяет клиентам не отвечать на запросы на неопределенный срок. Если клиент не указал время ожидания блокировки, значение по умолчанию — 15 секунд.
Каждая транзакция также имеет время ожидания блокировки. Это максимальное время, которое может принадлежать блокировке. Если владелец не освобождает блокировку в течение этого времени, транзакция принудительно прерывается, что приводит к освобождению блокировки. Время ожидания блокировки не настраивается. Это бесконечно для вызывающих вызовов в режиме ядра и один час для абонентов в пользовательском режиме. Если транзакция принудительно прервана, следующий вызов, выполненный внутри этой транзакции, завершится ошибкой с FWP_E_TXN_ABORTED.
Время существования объектов
Объекты могут иметь одно из четырех возможных времен существования:
- Динамический — объект является динамическим, только если он добавляется с помощью динамического дескриптора сеанса. Динамические объекты живут до тех пор, пока они не будут удалены или сеанс владения завершится.
- Статические — объекты по умолчанию являются статическими. Статические объекты живут до их удаления, остановки BFE или завершения работы системы.
- Постоянные — постоянные объекты создаются путем передачи соответствующего флага FWPM_*_FLAG_PERSISTENT в функцию Fwpm*Add0. Постоянные объекты живут, пока они не будут удалены.
- Встроенные — встроенные объекты предопределяются BFE и не могут быть добавлены или удалены. Они живут вечно.
Фильтры в уровнях режима ядра можно пометить как фильтры во время загрузки, передав соответствующий флаг FwpmFilterAdd0. Фильтры во время загрузки добавляются в систему при запуске драйвера TCP/IP и удаляются после завершения инициализации BFE. Постоянные объекты добавляются при запуске BFE.
Во многих случаях поставщик политик может не требовать применения постоянной политики, если поставщик отключен. При добавлении поставщика вызывающий объект может указать необязательное имя службы Windows. При добавлении постоянных объектов вызывающий объект может дополнительно указать поставщика, которому принадлежит этот объект. При запуске службы BFE добавляет в систему только постоянные объекты, если они не связаны с поставщиком, или связанный поставщик не имеет имени службы Windows, или связанная служба Windows устанавливается автоматический запуск.
Связи объектов
Некоторые объекты имеют ссылки на другие объекты. Например, фильтр всегда ссылается на слой и может ссылать на выноску и контекст поставщика. Объекты не могут ссылаться на объекты, которые могут иметь более короткое время существования. Таким образом, динамический объект не может ссылаться на динамический объект из другого сеанса. Статический объект не может ссылаться на динамический объект. Постоянный объект не может ссылаться на динамический объект, статический объект или постоянный объект, принадлежащий другому поставщику.
Не удается удалить объект до тех пор, пока не будут удалены все объекты, ссылающиеся на него.
Идентификаторы LUID и GUID
Все объекты API ВПП пользовательского режима (FWPM) определяются глобально уникальным идентификатором (GUID) и ссылаются на другие объекты по GUID. Идентификатор GUID должен быть уникальным только в пределах типа объекта. Например, фильтр и контекст поставщика могут иметь одинаковые GUID, но два фильтра не могут. При добавлении нового объекта вызывающие объекты могут назначить GUID объекта или оставить его нулевой инициализацией и разрешить BFE назначить GUID.
Все объекты API ВПП в режиме ядра (FWPS) определяются локальным уникальным идентификатором (LUID) и ссылаются на другие объекты luID. Переход от GUID на LUID позволяет МПП сохранять нестраничный пул и оптимизировать обработку во время выполнения. Ширина LUID зависит от типа объекта и диапазонов от UINT16 до UINT64. luIDвсегда назначаются BFE.