Управление объектами
В этом разделе рассматривается правильное использование типов объектов API Windows filtering Platform (ПППП).
Сеансы
API МПП ориентирован на сеанс, и большинство вызовов функций выполняются в контексте сеанса. Новый сеанс клиента создается путем вызова FwpmEngineOpen0. Сеанс завершается либо после вызова FwpmEngineClose0 , либо завершения клиентского процесса. При уничтожении сеанса либо с помощью запуска RPC ядро базовой фильтрации (BFE) сначала прерывает любую существующую транзакцию.
При создании нового сеанса вызывающий объект может создать динамический сеанс, передав флаг FWPM_SESSION_FLAG_DYNAMICв FwpmEngineOpen0. Все объекты, добавленные во время динамического сеанса, автоматически удаляются при завершении сеанса.
Транзакции
API МПП является транзакционной, и большинство вызовов функций выполняются в контексте транзакции. Вызывающие абоненты могут использовать FwpmTransactionBegin0, FwpmTransactionCommit0 и FwpmTransactionAbort0 для явного управления транзакциями. Однако если вызов функции выполняется за пределами явной транзакции, он будет выполняться в неявной транзакции. Если транзакция выполняется, когда сеанс завершается, он автоматически прерывается. Неявные транзакции никогда не прерываются принудительно.
Транзакции доступны только для чтения или чтения и записи и применяют строгую семантику atomic Consistent Isolated Durable (ACID).
Каждый сеанс клиента может одновременно выполнять только одну транзакцию. Если вызывающий объект пытается начать вторую транзакцию перед фиксацией или прерыванием первой, BFE возвращает ошибку.
Если операция завершается сбоем во время транзакции, она не влияет на общее состояние транзакции. Например, предположим, что клиент начинает транзакцию и успешно вызывает FwpmFilterAdd0 три раза до сбоя четвертого вызова. Теперь у клиента есть возможность:
- Прервана транзакция, в этом случае ни один из фильтров не будет добавлен.
- Фиксация транзакции, в этом случае будут добавлены первые три фильтра.
- Продолжая больше операций, включая потенциально повторную попытку сбоя FwpmFilterAdd0.
При запуске транзакции BFE будет ожидать истечения срока действия TxnWaitTimeoutInMSec сеанса. Если блокировка не получена в течение этого времени, получение блокировки (и вызов FwpmTransactionBegin0 ) завершится сбоем. Это позволяет клиентам не отвечать на запросы на неопределенный срок. Если клиент не указал время ожидания блокировки, значение по умолчанию — 15 секунд.
Каждая транзакция также имеет время ожидания блокировки. Это максимальное количество времени, которое может владеть блокировкой. Если владелец не освобождает блокировку в течение этого времени, транзакция принудительно прерывается, что приводит к освобождению блокировки. Время ожидания блокировки невозможно настроить. Это бесконечно для вызывающих вызовов в режиме ядра и один час для абонентов в пользовательском режиме. Если транзакция принудительно прервана, следующий вызов, выполненный в этой транзакции, завершится сбоем с FWP_E_TXN_ABORTED.
Время существования объектов
Объекты могут иметь одно из четырех возможных времени существования:
- Dynamic — объект является динамическим, только если он добавляется с помощью динамического дескриптора сеанса. Динамические объекты живут до тех пор, пока они не будут удалены или сеанс владения завершится.
- Статические — объекты по умолчанию являются статическими. Статические объекты живут до их удаления, остановки 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.