Registrando tipos de contexto

Um driver de minifiltro deve primeiro registrar cada tipo de contexto que ele usa. Depois que um minifiltro tiver registrado os tipos de contexto que ele usa, ele poderá criar um contexto.

Etapas para registrar um tipo de contexto

Um minifiltro chama FltRegisterFilter de sua rotina DriverEntry para registrar cada tipo de contexto que ele usa. Antes de chamar FltRegisterFilter, o driver de minifiltro faz o seguinte:

  • Cria uma matriz de comprimento variável de estruturas FLT_CONTEXT_REGISTRATION . A ordem dos elementos nessa matriz não importa; no entanto, o último elemento na matriz deve ser {FLT_CONTEXT_END}.
  • Armazena um ponteiro para a matriz criada no membro ContextRegistration da estrutura FLT_REGISTRATION . O minifiltro passa essa estrutura no parâmetro Registration de FltRegisterFilter.

Para cada tipo de contexto que o driver de minifiltro usa, ele deve fornecer pelo menos uma definição de contexto. A definição está na forma de uma estrutura FLT_CONTEXT_REGISTRATION , em que cada estrutura define o tipo, o tamanho e outras informações para o contexto.

Quando o driver de minifiltro chama FltAllocateContext para criar um novo contexto, o gerenciador de filtros usa o parâmetro Size , bem como os membros Size e Flags da estrutura FLT_CONTEXT_REGISTRATION, para selecionar a definição de contexto a ser usada:

  • Para contextos de tamanho fixo, o membro Size da estrutura FLT_CONTEXT_REGISTRATION especifica o tamanho, em bytes, da parte da estrutura de contexto definida pelo driver de minifiltro. O tamanho máximo de um contexto é MAXUSHORT (64 KB). Zero é um valor de tamanho válido. O gerenciador de filtros implementa contextos de tamanho fixo usando listas lookaside. O gerenciador de filtros cria duas listas lookaside para cada valor de tamanho: uma paginada e outra nãopagada.

  • Para contextos de tamanho variável, o membro Size deve ser definido como FLT_VARIABLE_SIZED_CONTEXTS. O gerenciador de filtros aloca contextos de tamanho variável diretamente do pool paginado ou nãopagado.

No membro Flags da estrutura FLT_CONTEXT_REGISTRATION, o sinalizador FLTFL_CONTEXT_REGISTRATION_NO_EXACT_SIZE_MATCH pode ser especificado. Se o driver de minifiltro usar contextos de tamanho fixo e esse sinalizador for especificado, o gerenciador de filtros alocará um contexto da lista lookaside se o tamanho do contexto for maior ou igual ao tamanho solicitado. Caso contrário, o tamanho do contexto deve ser igual ao tamanho solicitado.

Para um determinado tipo de contexto, o driver de minifiltro pode fornecer até três definições de contexto de tamanho fixo, cada uma com um tamanho diferente e uma definição de tamanho variável. Para obter mais informações, consulte FLT_CONTEXT_REGISTRATION.

Rotinas de retorno de chamada de minifiltro para gerenciamento de contexto

Opcionalmente, o driver de minifiltro pode fornecer as seguintes rotinas de retorno de chamada relacionadas ao contexto, que são armazenadas na estrutura FLT_REGISTRATION que é passada como um parâmetro para FltRegisterFilter:

Rotina de retorno de chamada Descrição
PFLT_CONTEXT_ALLOCATE_CALLBACK Em raras ocasiões, um minifiltro pode precisar definir sua própria rotina de retorno de chamada para alocar contextos, em vez de depender do gerenciador de filtros.
PFLT_CONTEXT_CLEANUP_CALLBACK A rotina de limpeza de um minifiltro a ser chamada antes que o contexto seja liberado.
PFLT_CONTEXT_FREE_CALLBACK Em raras ocasiões, um minifiltro pode precisar definir sua própria rotina de retorno de chamada para contextos livres, em vez de depender do gerenciador de filtros.

Exemplo de código de registro de contexto

O exemplo de código a seguir, que é obtido do driver de minifiltro de exemplo CTX, mostra uma matriz de estruturas de FLT_CONTEXT_REGISTRATION que são usadas para registrar contextos de instância, arquivo, fluxo e objeto de arquivo (identificador de fluxo).

const FLT_CONTEXT_REGISTRATION contextRegistration[] =
{
    { FLT_INSTANCE_CONTEXT,              //ContextType
      0,                                 //Flags
      CtxContextCleanup,                 //ContextCleanupCallback
      CTX_INSTANCE_CONTEXT_SIZE,         //Size
      CTX_INSTANCE_CONTEXT_TAG           //PoolTag
    },
    { FLT_FILE_CONTEXT,                  //ContextType
      0,                                 //Flags
      CtxContextCleanup,                 //ContextCleanupCallback
      CTX_FILE_CONTEXT_SIZE,             //Size
      CTX_FILE_CONTEXT_TAG               //PoolTag
    },
    { FLT_STREAM_CONTEXT,                //ContextType
      0,                                 //Flags
      CtxContextCleanup,                 //ContextCleanupCallback
      CTX_STREAM_CONTEXT_SIZE,           //Size
      CTX_STREAM_CONTEXT_TAG             //PoolTag
    },
    { FLT_STREAMHANDLE_CONTEXT,          //ContextType
      0,                                 //Flags
      CtxContextCleanup,                 //ContextCleanupCallback
      CTX_STREAMHANDLE_CONTEXT_SIZE,     //Size
      CTX_STREAMHANDLE_CONTEXT_TAG       //PoolTag
    },
    { FLT_CONTEXT_END }
};