Thursday, June 2, 2011

Verifier Checks: A filter has completed an operation but changed the TargetFileObject or the TargetInstance

So I'm back from my vacation and I can tell it was a good one since I don't remember anything about file system filters or driver development in general :). I'll have to re-read this blog and maybe things will start coming back to me… Anyway, joking aside, I need to make this a pretty short post since I'm way behind on my emails and so I'm just going to talk about a verifier check that is new to Win7. The message is:

FILTER VERIFIER ERROR: A filter has completed an operation but changed the TargetFileObject or the TargetInstance. This change will be ignored and nobody above will see this. Please make sure the design doesn't rely on this working!(Filter = Xxx, Cbd = Xxx)

The TargetFileObject and TargetInstance are members of the FLT_IO_PARAMETER_BLOCK structure, usually found inside a FLT_CALLBACK_DATA structure. This is how they are usually used in a minifilter:

  • the TargetFileObject member can be changed by a minifilter to target the operation at a different FILE_OBJECT for all filters below (and of course for the filesystem). This is quite useful in some scenarios, like SFO type filters and filters that want to redirect some but not all operations to a different FILE_OBJECT.
  • the TargetInstance member is used by a minifilter when it wants to send the request to a different volume (it cannot be used to send the request from InstanceA to InstanceB on the same volume since that would bypass all filters with altitudes between InstanceA and InstanceB which is illegal). So TargetInstance must be set to an instance at the same altitude (therefore on a different volume). The net effect of this is that all filters below the filter on the first volume will not see the IO and it will be shown instead to filters below the new instance on the new volume.

FltMgr must be notified about any change to these two members through a call to FltSetCallbackDataDirty(). If FltSetCallbackDataDirty() is not called, FltMgr might ignore the changes in some cases and the behavior is undefined.

So now that we've explained why anyone would want to change these values, let's talk about the Verifier Check. The check simply means that FltMgr detected that a minifilter changed one of these members but then completed the operation. The effect of this is that the changes will be ignored, because they only impact filters below the minifilter and since the operation has been completed by the minifilter no filters below it will ever see it so there is no point to changing these members in the first place anyway. FltMgr reports this error because it might lead on referencing issues (the minifilter may have added references to the new FileObject or Instance) or potentially erroneous runtime filter behavior.

In general there are two possible reasons for seeing this error:

  • There is a bug in the filter where it doesn't mean to complete this operation after it changed the TargetFileObject or TargetInstance, so the solution in this case is to fix the code and not complete the operation and just send it down.
  • The operation was supposed to be completed but there is common code executed before the operation is completed where TargetFileObject or TargetInstance are changed. The fix in this case if obviously to change to code so that it the operation will be completed then the code that changes TargetFileObject or TargetInstance is not executed.