Returning FLT_PREOP_SYNCHRONIZE

Note

A minifilter driver should not use FLT_PREOP_SYNCHRONIZE to hold a resource across pre- and post-operation calls (same as it should not hold a resource across an I/O call). To do so is unsafe as it can result in deadlocks.

If a minifilter driver's pre-operation callback routine synchronizes an I/O operation by returning FLT_PREOP_SYNCHRONIZE, Filter Manager calls that filter's post-operation callback routine during I/O completion:

  • If the filter is not draining, Filter Manager calls that filter's post-operation callback routine in the same thread context as the pre-operation callback, at IRQL <= APC_LEVEL. (Note that this thread context is not necessarily the context of the originating thread.)
  • If the filter is draining, Filter Manager does not sync back to the original thread.

Note

If a filter's pre-operation callback routine returns FLT_PREOP_SYNCHRONIZE, it must implement a post-operation callback routine for the operation.

If the filter's pre-operation callback routine returns FLT_PREOP_SYNCHRONIZE, it can return a non-NULL value in its CompletionContext output parameter. This parameter is an optional context pointer that is passed to the corresponding post-operation callback routine. The post-operation callback routine receives this pointer in its CompletionContext input parameter.

A minifilter driver's pre-operation callback routine should return FLT_PREOP_SYNCHRONIZE only for IRP-based I/O operations. However, this status value can be returned for other operation types. If it is returned for an I/O operation that is not an IRP-based I/O operation, Filter Manager treats this return value as if it were FLT_PREOP_SUCCESS_WITH_CALLBACK. To determine whether an operation is an IRP-based I/O operation, use the FLT_IS_IRP_OPERATION macro.

Filters should not return FLT_PREOP_SYNCHRONIZE for create operations, because these operations are already synchronized by Filter Manager. If a minifilter driver has registered pre-operation and post-operation callback routines for IRP_MJ_CREATE operations, the post-create callback routine is called at IRQL = PASSIVE_LEVEL, in the same thread context as the pre-create callback routine.

Minifilter drivers must never return FLT_PREOP_SYNCHRONIZE for asynchronous read or write operations. Doing so can severely degrade both minifilter driver and system performance and can even cause deadlocks if, for example, the modified page writer thread is blocked. Before returning FLT_PREOP_SYNCHRONIZE for an IRP-based read or write operation, a minifilter driver should verify that the operation is synchronous by calling FltIsOperationSynchronous.

The following types of I/O operations cannot be synchronized:

FLT_PREOP_SYNCHRONIZE cannot be returned for any of these operations.