Настройка контекстов

После создания нового контекста драйвер мини-фильтра может подключить его к объекту, вызвав одну из следующих подпрограмм набора:

Подпрограмма набора выполняет следующие действия в зависимости от значения параметра Operation :

  • Если операция == FLT_SET_CONTEXT_KEEP_IF_EXISTS:

    • Если мини-фильтр еще не задал контекст одного типа для объекта, подпрограмма набора:
      • Присоединяет только что выделенный контекст к объекту.
      • Увеличивает число ссылок.
    • Кроме того, если мини-фильтр уже задал контекст, подпрограмма set:
      • Возвращает STATUS_FLT_CONTEXT_ALREADY_DEFINED (код ошибки NTSTATUS).
      • Не заменяет существующий контекст.
      • Не увеличивает число ссылок.
      • Сохраняет указатель на существующий контекст в параметре OldContext , если он не имеет значения NULL. Если этот указатель больше не нужен, драйвер минифильтра должен освободить его, вызвав FltReleaseContext.
  • Если операция == FLT_SET_CONTEXT_REPLACE_IF_EXISTS:

    • Подпрограмма набора всегда присоединяет новый контекст к объекту.
    • Если драйвер минифильтра уже задал контекст, задайте подпрограмму:
      • Удаляет существующий контекст, задает новый контекст и увеличивает число ссылок в новом контексте.
      • Если параметр OldContext не имеет значения NULL, он получает указатель на удаленный контекст. Если этот указатель больше не нужен, драйвер минифильтра должен освободить его, вызвав FltReleaseContext.

После установки типа контекста мини-фильтр может получить контекст во время последующих операций ввода-вывода, чтобы определить, нужно ли выполнять какие-либо действия.

Каждый успешный набор контекстов должен в конечном итоге быть удален.

В следующем примере кода, взятом из примера минифильтра CTX, подпрограмма CtxInstanceSetup создает и задает контекст экземпляра:

status = FltAllocateContext(
           FltObjects->Filter,              //in: Filter
           FLT_INSTANCE_CONTEXT,            //in: ContextType
           CTX_INSTANCE_CONTEXT_SIZE,       //in: ContextSize
           NonPagedPool,                    //in: PoolType
           &instanceContext);               //out: ReturnedContext
...
status = FltSetInstanceContext(
           FltObjects->Instance,            //in: Instance
           FLT_SET_CONTEXT_KEEP_IF_EXISTS,  //in: Operation
           instanceContext,                 //in: NewContext
           NULL);                           //out: OldContext

if (instanceContext != NULL) {
  FltReleaseContext(instanceContext);
}
return status;

Обратите внимание, что после вызова FltSetInstanceContext вызывается FltReleaseContext для освобождения счетчика ссылок, заданного FltAllocateContext (не FltSetInstanceContext). Это объясняется в разделе "Выпуск контекстов".