Gerenciamento de Objetos

Esta seção aborda o uso correto dos tipos de objeto da API da Plataforma de Filtragem do Windows (WFP).

Sessões

A API do WFP é orientada à sessão e a maioria das chamadas de função é feita dentro do contexto de uma sessão. Uma nova sessão de cliente é criada chamando FwpmEngineOpen0. A sessão termina quando o cliente chama FwpmEngineClose0 ou o processo do cliente é encerrado. Quando uma sessão é destruída, seja de propósito ou pelo rundown RPC, o BFE (Mecanismo de Filtragem Base) anula primeiro qualquer transação existente.

Ao criar uma nova sessão, o chamador pode criar uma sessão dinâmica passando o sinalizador FWPM_SESSION_FLAG_DYNAMIC para FwpmEngineOpen0. Todos os objetos adicionados durante uma sessão dinâmica são excluídos automaticamente quando a sessão termina.

Transactions

A API do WFP é transacional e a maioria das chamadas de função é feita dentro do contexto de uma transação. Os chamadores podem usar FwpmTransactionBegin0, FwpmTransactionCommit0 e FwpmTransactionAbort0 para controlar explicitamente as transações. No entanto, se uma chamada de função for feita fora de uma transação explícita, ela será executada dentro de uma transação implícita. Se uma transação estiver em andamento, quando uma sessão for encerrada, ela será anulada automaticamente. As transações implícitas nunca são anuladas à força.

As transações são somente leitura ou leitura/gravação e impõem uma rigorosa semântica ACID (Atomic Consistent Consistent Isolated Durable).

Cada sessão do cliente pode ter apenas uma transação em andamento por vez. Se o chamador tentar iniciar uma segunda transação antes de confirmar ou anular a primeira, a BFE retornará um erro.

Se uma operação falhar durante o curso de uma transação, ela não afetará o estado geral da transação. Por exemplo, suponha que o cliente inicie uma transação e chame FwpmFilterAdd0 três vezes antes de uma quarta chamada falhar. O cliente agora tem a opção de:

  • Anulando a transação, nesse caso, nenhum dos filtros será adicionado.
  • Confirmando a transação, nesse caso, os três primeiros filtros serão adicionados.
  • Continuando com mais operações, incluindo potencialmente repetir o FwpmFilterAdd0 com falha.

Ao iniciar uma transação, o BFE aguardará até que o txnWaitTimeoutInMSec da sessão expire para adquirir o bloqueio. Se o bloqueio não for adquirido nesse momento, a aquisição do bloqueio (e a chamada FwpmTransactionBegin0 ) falharão. Isso impede que os clientes falhem indefinidamente em responder. Se o cliente não especificou um tempo limite de bloqueio, ele usará como padrão 15 segundos.

Cada transação também tem um tempo limite de bloqueio. Essa é a quantidade máxima de tempo que ele pode possuir o bloqueio. Se o proprietário não liberar o bloqueio nesse momento, a transação será anulada à força, fazendo com que o bloqueio seja liberado. O tempo limite de bloqueio não é configurável. Ele é infinito para chamadores no modo kernel e uma hora para chamadores no modo de usuário. Se uma transação for anulada à força, a próxima chamada feita dentro dessa transação falhará com FWP_E_TXN_ABORTED.

Tempos de vida do objeto

Os objetos podem ter um dos quatro tempos de vida possíveis:

  • Dinâmico — um objeto é dinâmico somente se for adicionado usando um identificador de sessão dinâmica. Os objetos dinâmicos ficam ativos até serem excluídos ou a sessão proprietária terminar.
  • Estático — os objetos são estáticos por padrão. Os objetos estáticos ficam ativos até serem excluídos, o BFE é interrompido ou o sistema é desligado.
  • Persistente — Objetos persistentes são criados passando o sinalizador de FWPM_*_FLAG_PERSISTENT apropriado para uma função Fwpm*Add0 . Os objetos persistentes ficam ativos até serem excluídos.
  • Interno — Os objetos internos são predefinidos pelo BFE e não podem ser adicionados ou excluídos. Eles vivem para sempre.

Os filtros em camadas de modo kernel podem ser marcados como filtros de tempo de inicialização passando o sinalizador apropriado para FwpmFilterAdd0. Os filtros de tempo de inicialização são adicionados ao sistema quando o driver TCP/IP é iniciado e removidos quando o BFE conclui a inicialização. Objetos persistentes são adicionados quando o BFE é iniciado.

Em muitos casos, um provedor de política pode não querer que sua política persistente seja imposta se o provedor tiver sido desabilitado. Ao adicionar um provedor, o chamador pode especificar um nome de serviço opcional do Windows. Ao adicionar objetos persistentes, o chamador pode, opcionalmente, especificar o provedor que "possui" esse objeto. No início do serviço, a BFE só adicionará objetos persistentes ao sistema se eles não estiverem associados a um provedor ou se o provedor associado não tiver nenhum nome de serviço do Windows ou se o serviço Windows associado estiver definido como inicialização automática.

Associações de objeto

Alguns objetos têm referências a outros objetos. Por exemplo, um filtro sempre faz referência a uma camada e pode referenciar um texto explicativo e um contexto de provedor. Os objetos não podem se referir a objetos que podem ter um tempo de vida mais curto. Portanto, um objeto dinâmico não pode se referir a um objeto dinâmico de uma sessão diferente. Um objeto estático não pode se referir a um objeto dinâmico. Um objeto persistente não pode se referir a um objeto dinâmico, a um objeto estático ou a um objeto persistente pertencente a um provedor diferente.

Um objeto não pode ser excluído até que todos os objetos que fazem referência a ele tenham sido excluídos pela primeira vez.

LUIDs e GUIDs

Todos os FWPM (objetos de API WFP) do modo de usuário são identificados por um GUID (identificador global exclusivo) e referenciam outros objetos por seus GUIDs. O GUID só precisa ser exclusivo dentro do tipo de objeto. Por exemplo, um filtro e um contexto de provedor podem ter o mesmo GUID, mas dois filtros não podem. Ao adicionar um novo objeto, os chamadores podem atribuir o GUID do objeto ou deixá-lo inicializado como zero e permitir que o BFE atribua o GUID.

Todos os FWPS (objetos de API WFP) do modo kernel são identificados por um LUID (identificador local exclusivo) e referenciam outros objetos por seu LUID. A opção de GUID para LUID permite que o WFP conserva o pool não paginado e otimize o processamento em tempo de execução. A largura do LUID depende do tipo de objeto e varia de um UINT16 a um UINT64. LuIDs são sempre atribuídos pelo BFE.