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 no 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, de propósito ou pelo rundown do RPC, o BFE (Mecanismo de Filtragem Base) anula pela primeira vez 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.
Transações
A API WFP é transacional e a maioria das chamadas de função é feita dentro do contexto de uma transação. Os chamadores podem usar FwpmTransactionBegin0, FwpmTransactionCommit0e 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. 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 Atomic Consistent Isolated Durable (ACID).
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 com êxito 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 FwpmFilterAdd0com falha.
Ao iniciar uma transação, a 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 não respondam indefinidamente. Se o cliente não especificar um tempo limite de bloqueio, ele usará como padrão 15 segundos.
Cada transação também tem um tempo limite de bloqueio. Esse é o período máximo de tempo que ele pode ter 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 do 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âmico. Os objetos dinâmicos vivem até que sejam excluídos ou a sessão proprietária seja encerrada.
- Estático – os objetos são estáticos por padrão. Os objetos estáticos vivem até serem excluídos, o BFE é interrompido ou o sistema é desligado.
- Persistente – objetos persistentes são criados passando o sinalizador FWPM_*_FLAG_PERSISTENT apropriado para uma função Fwpm*Add0. Os objetos persistentes vivem 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 no 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 objetos
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. 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, 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 objetos de API WFP (FWPM) no modo de usuário são identificados por um identificador global exclusivo (GUID) e referenciam outros objetos por seus guid de. 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 zero e permitir que o BFE atribua o GUID .
Todos os FWPS (objetos de API WFP) do modo kernel são identificados por um identificador localmente exclusivo (luid) e referenciam outros objetos por seu LUID. A mudança de GUID para LUID permite que o WFP conserve o pool não paged 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 pela BFE.