Certain minifilters need to perform I/O of theirown. This I/O is only seen byminifilters below the current minifilter in the minifilter stack of theVolume. For instance, an anti-virusminifilter may wish to read a file before an open has completed. In the new minifilter model, a minifilterwill be able to generate I/O in one of two ways: using general routines similarto today's routines, and using simplified routines that provide an interfacesimilar to the ZwXxx routines.
某些过滤驱动需要执行它们自己的IO操作,这些IO操作只会被当前minifilter驱动的下层minifilter驱动看到。例如,一个反病毒驱动希望在文件打开完成之前读取文件。在新的minifilter驱动模型,minifilter驱动能够使用以下两种方法创建IO操作:使用类似现在例程的general例程,使用类似ZwXXX例程的simplified例程。
The general routines that the system provides tominifilters for I/O generation are:
生成IO操作的general例程包括:
NTSTATUS
FLTAPI
FltAllocateCallbackData (
INPFLT_INSTANCE Instance,
INPFILE_OBJECT FileObject OPTIONAL,
OUTPFLT_CALLBACK_DATA *RetNewCallbackData
);
VOID
FLTAPI
FltPerformSynchronousIo(
IN PFLT_CALLBACK_DATA CallbackData
);
NTSTATUS
FLTAPI
FltPerformAsynchronousIo(
IN PFLT_CALLBACK_DATA CallbackData,
IN PFLT_COMPLETED_ASYNC_IO_CALLBACKCallbackRoutine,
IN PVOID CallbackContext
);
Using the general routines, a minifilter can callFltAllocateCallbackData() to allocate a CallbackData for the operation, and then fill in the appropriate parameters inthe CallbackData for the desired operation. The minifilter then calls FltPerformSynchronousIo() or FltPerformAsynchronousIo() to actually initiate the I/O. The instance parameter should always be for the current instance doingthe I/O operation.
使用general例程,minifilter驱动可以调用FltAllocateCallbackData()为IO操作分配CallbackData,然后填充CallbackData中合适的参数,接下来调用FltPerformSynchronousIo()或者FltPerformAsynchronousIo发起IO操作,instance参数应该始终是IO操作的当前实例。
In addition Filter Manager exports some commonutility routines. Examples:
另外驱动管理器导出了一些常用的实用例程,例如:
NTSTATUS
FLTAPI
FltCreateFile(
IN PFLT_FILTER Filter,
IN PFLT_INSTANCE Instance OPTIONAL,
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength,
IN ULONG Flags
);
If InstanceHandle is omitted,the CREATE will be sent to the top of the stack (so the minifilter initiatingthe operation will itself see the I/O recursively.) This is discouraged unlessabsolutely necessary as it can cause deadlocks and stack overflows ifminifilters misuse it.
如果InstanceHandle未指定,CREATE操作将被发送到过滤栈的顶层,所以发起IO操作的minifilter驱动将看到自己发送的IO请求,这是不推荐的操作,因为这会引起死锁,并且如果错误的使用,线程栈将溢出。
If InstanceHandle is provided(this should always be your own instance), then the create is initiated withthe minifilter just below the caller of this API, by passing all legacyminifilters above the Filter Manager and minifilters above the caller.
如果指定InstanceHandle(应该是你自己的实例),那么创建操作将发往minifilter调用者的下层,而上层的minifilter驱动将不会收到此IO操作。
The FileHandle returned by this API can be usedin all Zw* calls that accept a file handle as a parameter. If the Instanceparameter is non-NULL in a call to FltCreateFile(), it isguaranteed that all future I/O (via the Zw APIs, FltClose() etc.), on this handle will only be seen by the instances below the InitiatingInstance.
API返回的FileHandle句柄可以使用在Zw*函数中,如果FltCreateFile 函数中Instance参数非空,所有的在此FileHandle句柄的IO操作将只会被下层的minifilter实例处理。
FltReadFile() and FltWriteFile() are support routines to allow minifilters to generate IOs that areonly seen by instances below them when they have only the FileObject torepresent the file. These routines areanalogous to “rolling an IRP” in the legacy filter model.
当只有FileObject代表文件时,可以使用FltReadFile() 和 FltWriteFile()创建IO操作,并且这些IO操作只会被下层的过滤器实例处理。这些例程类似以前旧的过滤模型中自己发送IRP的读写方式。
IMPORTANTNOTE: Filters need NOT use FltReadFile()/FltWriteFile() to initiate I/O on the handle returned by FltCreateFile(). For handles created via FltCreateFile(), the normal Zw*() APIs will be targeted to the correct instancerelative to the InitiatingInstance specified.
FltReadFile()/FltWriteFile()不应该使用FltCreateFile()返回的句柄。
NTSTATUS
FLTAPI
FltReadFile (
INPFLT_INSTANCE InitiatingInstance,
INPFILE_OBJECT FileObject,
INPLARGE_INTEGER ByteOffset OPTIONAL,
IN ULONGLength,
OUT PVOIDBuffer,
IN FLT_IO_OPERATION_FLAGS Flags,
OUT PULONGBytesRead OPTIONAL,
INPFLT_COMPLETED_ASYNC_IO_CALLBACK CallbackRoutine OPTIONAL,
IN PVOIDCallbackContext OPTIONAL
);
NTSTATUS
FLTAPI
FltWriteFile(
IN PFLT_INSTANCE InitiatingInstance,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN ULONG Length,
IN PVOID Buffer,
IN FLT_IO_OPERATION_FLAGS Flags,
OUT PULONG BytesWritten OPTIONAL,
IN PFLT_COMPLETED_ASYNC_IO_CALLBACKCallbackRoutine OPTIONAL,
INPVOID CallbackContext OPTIONAL
);
By default, all minifilter-initiated I/O is sentto the next attached instance for the given volume, bypassing any instancesattached above the minifilter initiating the I/O.
Minifilter initiated I/O can be synchronous orasynchronous. When the I/O isasynchronous, the minifilter provides a callback routine that the system willcall when the I/O is completed.
默认情况下,所有minifilter驱动发起的IO操作发给紧挨着的下层附加的实例,而忽略所有上层附加的实例。
Minifilter驱动可以发起同步或异步的IO操作,当IO为异步操作时,minifilter驱动提供一个回调函数,当IO操作完成时,系统将会调用这个回调函数。