znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
阅读:6367回复:7

minifilter 相关资料汇集

楼主#
更多 发布于:2007-07-05 17:22
新的过滤驱动框架 miniflter 相关


在2k下安装minfilter,需要fltmgr.sys 管理器,需要安装windows 2k sp4 更新汇集1

地址

http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=B54730CF-8850-4531-B52B-BF28B324C662


可加载的组

http://www.microsoft.com/taiwan/whdc/driver/filterdrv/alt-range.mspx

最新喜欢:

123218lzq123218...
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
沙发#
发布于:2007-07-05 17:24
Guest Article: Writing a File System Minifilter - Pitfalls, Hints and Tips
The NT Insider, Vol 12, Issue 4, September-October 2005 | Published: 16-Nov-05| Modified: 16-Nov-05

 

By Rod Widdowson

 

The availability of the IFS Kit for Windows 2003 SP1 in spring 2005 marked the official release of the Filter Manager. A beta version of the kit, that included the Filter Manager, had been available in beta format for quite some time. As a result, many people have had significant success developing minifilters. Since the documentation is now in excellent shape, rather than present an exhaustive "how to" article, this article provides some hints and tips based on our own experience.

"Quick to Write" Does Not Mean "Easy to Design"
It is vital to realize that just because the Filter Manager makes writing a file system filter faster, it does not make designing a file system filter easier. The Filter Manager does simplify the effort required to building a file system filter. It includes a body of "boiler plate" code that you no longer need to write. This makes it possible to go from design to working filter in weeks rather than months.

 

However, don't be lulled into thinking that the difficult parts of filter design are not still difficult. For example, you still have to understand how a file system filter fits into Windows and how it will interoperate with the various subsystems and other filters it will encounter. No matter how easy it is to construct your filter initially, you must still deal with the realities and responsibilities of "being" a file system filter driver.

 

Put another way, the Filter Manager is a great productivity tool for a skilled engineer. But like many such tools, the Filter Manager can be dangerous in the hands of an unskilled engineer. The world has enough bad software and, notwithstanding the opportunities it would give Peter to pontificate, it would be a shame if the Filter Manager was abused to create more bad software at a faster pace than before.

If You're Writing a Lot of Code ‑ Check the Documentation
The Filter Manager comes with a rich library of support functions including support functions for most operations a filter will need. For example, if you need to find out the file name of a renamed file, you can use FltGetDestinationFile NameInformation(). If you need to know the name of the share from which a file is being accessed, then you can use FltParseFileNameInformation().

 

My rule is if you find yourself writing a lot of code that is not specific to the job of your minifilter, the chances are there is an Flt function for you to call.

 

As a corollary, avoid Zw calls. There is nearly always an Flt version that will do the same job or even a better job. For instance, by default, Filter Manager library calls never re-enter the top of the stack, which means strange re-entrancy rules do not exist. Looking toward Windows Vista, there is room in the Filter Manager's structures to make it easier for minifilters to support Transactional NTFS whereas legacy filters will have to "go it alone".

 

It is equally important not to underestimate the work the Filter Manager can do for you and check the documentation carefully. Quite often it just "does the right thing", which surprised us more than once.  For instance, when we started writing our first minifilter, we wrote a great deal of code to enumerate all the file systems on startup. We wrote more code to explicitly tear down our contexts and instances on shutdown. Later we discovered that calling FltStartFiltering provokes multiple callbacks at InstanceCallbackSetup and that FltUnregisterFilter tears down all the instances and, hence, all the contexts. This discovery allowed us to significantly simplify startup and shutdown.

 

We know from conversations with others that this sort of "over programming" is not uncommon with people who are used to developing legacy filters.

Unload Frequently During Development
A frequent question on NTFSD is, "When I detach my minifilter, it just hangs. What has gone wrong?" In 99% of the cases the filter has not returned some structure such as contexts or other structures to the Filter Manager. Debugging this sort of problem when your filter is substantially complete is slow and incredibly frustrating. Therefore, we suggest the first thing you write when developing a new filter is the detach and unload code.  

 

Once your filter unloads cleanly, always unload after every test run. That way, as soon as you introduce a pool leak, the Driver Verifier will let you know. Similarly, as soon as you forget to dereference a context, the Filter Manager will let you know. We all know that these kinds of bugs are easier to find when they are "fresh".

Use Checked Kernel and Checked Filter Manager
Using the checked kernel, should be as second nature to you as using Driver Verifier. Here's a hint to make sure this is the case ‑ use the Filter Manager from the checked build. The Filter Manager is rich in ASSERTs that usually fire early enough to assist in bug tracking. See Figure 1 for a favorite ASSERT.

 

Without the checked Filter Manager, our minifilter was occasionally returning an "invalid parameter" status back from a file open. By using the checked build Filter Manager, the following assertion was provoked:

 

*** Assertion failed: FsRtlIsPagingFile((fileObject)) || ((fileObject)->FsContext == NULL && FlagOn((fileObject)->Flags, FO_STREAM_FILE | FO_DIRECT_DEVICE_OPEN)) || FltpIsWellKnownPagingFileName(fileObject)

***  Source File: d:\xpsprtm\base\fs\filtermgr\filter\fltmgr.c, line 756



 

Just looking at the assert provides a hint that the file object is invalid. Indeed, every time we saw this status, it is precisely because we had shared some code between the pre-write and pre-create code paths. This code would be of the form:

 

status = FltQueryInformationFile(FltObjects->Instance,

                            FltObjects->FileObject,

                            &fileInfo,

                            sizeof(FILE_ALL_INFORMATION),

                            FileAllInformation,

                            &length);

 

While this works fine in the pre-write path, in the pre-create path the FltObjects->FileObject is not completely set up, so it cannot be used.

Figure 1 - A Favorite ASSERT

 

Again, the best help the checked build Filter Manager gives is on unload. As mentioned above, if you left references on any contexts, the free build Filter Manager just hangs. If you are using the checked build version, it will list all the contexts that are still referenced. Microsoft promises that future releases of the Filter Manager will provide even more diagnostics (the "filter verifier"). We can't wait!

How Context Management Works
Context management is probably one of the most frustrating parts of maintaining a minifilter. Currently there are limited diagnostics to help if a context reference is held too long. This means finding a leaking context "in the field" is likely to be difficult, if not impossible. As noted above, your best protection is to unload frequently during development which helps find the bugs early. However, before development even starts, you should have a good understanding of what the calls do that manipulate contexts. Since the documentation of this has historically been weak, a brief summary is provided below.

 

Contexts are referenced data structures. The Filter Manager arranges that a context will continue to exist for as long as its reference count is non zero. As soon as something reduces the reference count to zero, the appropriate ContextCleanup Callback will be called (if you have registered one), and then the context will be deallocated. Hence, it is important to understand which operations have what effect on the reference count.

 

Creating, looking up, and explicitly referencing a context will all add a reference to the context. However, often times a context will also have a reference because it has been attached to a system data structure via one of the FltSetXXXContext calls. The reference count is decremented when such a context is detached. Since this often results in the count dropping to zero, the context will usually be cleaned up and deallocated.

 

Incrementing the reference count prior to it being manipulated (via FltReferenceContext or, more often, one of the FltGetContext calls) protects your code from having a context disappear while operations are ongoing. Protecting data structures in a multi-threaded environment is an important reason for reference counting.

 

Given that FltSetContext will attach a context to a data structure and add a reference count, what are the cases that will detach it? There are, in fact, four such cases.

The attached to system structure is about to go away. For example, when the file system calls FsRtlTeardownPer StreamContexts as part of tearing down the FCB, the Filter Manager will detach any attached stream contexts and dereference them.
The filter instance associated with the context is being detached.  Again taking the stream context example, during instance teardown after the InstanceTeardown callbacks have been made the filter manager will detach any stream contexts associated with this instance from their associated ADVANCED_FCB_HEADER and dereference them.
The minifilter itself detaches the context by calling FltDeleteContext or one of its variants.
The minifilter itself detaches the context by calling the appropriate FltSetXXXContext functions, and specifying FLT_SET_CONTEXT_REPLACE_ IF_EXISTS. In this case the old context is not dereferenced, which means it will not go away before the caller has a chance to inspect it. Therefore, the caller has to perform the dereference.
 

The documentation indicates that cases 1, 2, and 4 listed above are the most common reasons detaching occurs. Therefore, it is usually not necessary to call the FltDeleteXXXContext routines.

 

For most filters, every function that references a context will usually dereference it before returning. A notable exception is when a context is allocated in a pre-create call and is then associated to the FCB in the post-create call. If you can construct code to ensure that references do not span function calls, your code will be easier to understand and inspection will be a whole lot easier.

 

If you find situations when you need to hold a reference on a context for a long time, you should reexamine your structures and move whatever requires you to keep the context referenced into a secondary (possibly reference counted) structure.

 

For example, if a filter has a need to keep information on a per-file (rather than a per-stream) basis, then they need per-file contexts. (This feature will be available in Windows Vista.)

 

A naive implementation might have the per-file information in the stream context, and then link together all the stream contexts that share the file. They will need to be referenced for as long as they are linked in order to protect to the linked contexts.

 

A better solution would be to have an explicit per-file structure that contains the per-file information and a reference count. This per-file structure should be pointed to by every appropriate stream context. In the StreamContextCleanup Callback, the reference to the per-file structure is decremented, and, if required, the structure is deallocated.

 

In this way, the time during which stream contexts are referenced is kept to a minimum.

 

Remember, if you have a reference on a context you will not be told when the underlying system structure goes away. For example, in the case of Stream Contexts, as long as your filter has no reference on the context, the StreamContextCleanup Callback will be associated with the file system tearing down its FCB as described above. This is important if you want to keep information associated with the stream beyond the call to CLEANUP.

Instance Initialization and Teardown
As we have seen, instance initialization can either happen:

Explicitly - via FLTMC, the FltAttachVolume kernel function, or the FilterAttach user mode function; or
Automatically - as a result of a minifilter being loaded or a volume becoming otherwise available

Depending on precisely what triggers the call of InstanceSetupCallback, the process context will vary. This requires you to be careful before making any assumptions about the context in which your filter is being called.

 

Let's look at two examples.

 

FLTMC ATTACH myfilter C - InstanceSetup Callback will be called in the context of the process running fltmc.
FLTMC LOAD myfilter - InstanceSetup Callback will be called in the context of the system process.

This has several repercussions; many of them are quite subtle. For example, consider what impact the previous mode may have on probe. Therefore, it is important to test at least these two variants, along with the associated detach and teardown homologs.

Summary
The Filter Manager is currently available on Windows 2000 (with appropriate service packs and hot fixes), Windows XP SP2, and Windows Server 2003 SP1. At this point, unless the target customers are on NT or they cannot (or will not) move up to a version of the OS that supports the Filter Manager (in which case ‑ good luck!), there is no reason why most file systems filters should not be developed using the Filter Manager.  

 

The team that put together the minifilter framework has thought a great deal about the problems of building file system filters. Their efforts have provided a Filter Manager that will undoubtedly save a great deal of time. However, as I cautioned earlier, do not be seduced by the ease of writing the code. The design stage is still strewn with architectural pitfalls.

 

Rod Widdowson is Consulting Partner with Steading System Software LLP, a file system consultancy.  He can be reached at: rdw@steadingsoftware.com
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
板凳#
发布于:2007-07-05 17:26
File System Minifilter Drivers (Part 1)
For my first technical post I wanted to talk about the Windows component I have been learning about and working with the most, the Filter Manager.  After working on Nooks at college, I came to Microsoft aware of the difficulty in writing a driver for Windows.  When I get really frustrated I compare understanding IRPs to understanding quantum mechanics, but that isn’t exactly a fair comparison.

The Filter Manager was meant to create a simple mechanism for drivers to filter file system operations: file system minifilter drivers.  File system minifilter driver are located between the I/O manager and the base filesystem, not between the filesystem and the storage driver(s) like legacy file system filter drivers.

Now, I should mention that this isn’t a new mechanism; it has been around for a while.  But, undoubtedly some people are aware of it but haven’t used it yet (like me until recently) and I feel it is important that every driver writer be aware of how they work.  If a file system minifilter driver provides the functionality you need then you should write one; file system minifilter drivers are simpler than legacy drivers and hence less prone to bugs (at least theoretically).  If you already know how the Filter Manager works I won’t be providing any inside information or upcoming updates, so feel free to skip this post.

The old mechanism of filtering file system operations (between the filesystem and storage driver(s)) required handling IRPs and the creation/handling of device objects.  On the other hand, file system minifilter drivers that utilize the Filter Manager utilize a callback mechanism.  This callback mechanism specifies what IRPs you are interested in filtering.  The structure for doing this is extremely simple.

const FLT_OPERATION_REGISTRATION FilterCallbacks[] = {

 

    {IRP_MJ_CREATE,

     0,

     PreCreate,

     PostCreate,

     NULL},

 

    {IRP_MJ_WRITE,

     0,

     PreWrite,

     NULL,

     NULL},

 

    {IRP_MJ_CLOSE,

     0,

     PreClose,

     PostClose,

     NULL},

 

    {IRP_MJ_OPERATION_END}

};

This structure is passed to the Filter Manager (with some other registration information) in a call to FltRegisterFilter.  These callback functions (PreCreate, PostClose, etc.) then need to be defined in the driver and the filter manager ensures that the appropriate functions are called when it receives the IRPs you specified you wanted callbacks for.  The pre-callbacks are for IRPs going from the I/O manager to the base filesystem.  The function signature for pre-callbacks is:

typedef FLT_PREOP_CALLBACK_STATUS
  (*PFLT_PRE_OPERATION_CALLBACK) (
    IN OUT PFLT_CALLBACK_DATA Data,
    IN PCFLT_RELATED_OBJECTS FltObjects,
    OUT PVOID *CompletionContext
    );

Post-callbacks are for IRPs going in the opposite direction, from the base filesystem to the I/O manager and their function signature is:

typedef FLT_POSTOP_CALLBACK_STATUS
  (*PFLT_POST_OPERATION_CALLBACK) (
    IN OUT PFLT_CALLBACK_DATA Data,
    IN PCFLT_RELATED_OBJECTS FltObjects,
    IN PVOID CompletionContext,
    IN FLT_POST_OPERATION_FLAGS Flags
    );

There are a couple parameter differences between the pre- and post-callbacks, but the general idea is the same.  The Data parameter specifies information about an I/O operation.  Basically it represents the IRP information but in a simple to use container.  The FltObjects parameter provides pointers to objects related to the operation including the volume and file object.  The CompletionContext parameter is extremely helpful for passing information between the callbacks.  Any pre-callback can set CompletionContext and that pointer will be passed in to the post-callback.

 

The CompletionContext mechanism and context support are my two most used components of the Filter Manager.  While CompletionContext allows you to attach information to a specific IRP operation, the Filter Manager’s context support allows you to attach information to a volume, instance, file, stream, or stream handle (support for all of these are not yet completed, so check the latest information in MSDN to see what is currently supported).  While being able to transfer information to a post-callback is useful, sometimes higher-level tracking is required.  For instance, a filter driver wanting to track all operations across the lifetime of a particular file open would use stream handles (which operates at the file object level).

 

In my next post I will continue with a more in-depth discussion of the Filter Manager’s context support.  Anyone wanting to learn more about file system minifilter drivers should look at MSDN and the file system minifilter driver WHDC page.

Published Monday, March 27, 2006 12:24 PM by EricK
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
地板#
发布于:2007-07-05 17:27
File System Minifilter Drivers (Part 2)
In my last entry I covered some basic information about file system minifilter drivers.  This entry I want to talk about more about them, specifically their context support.  I don’t think I will make this as long as I previously planned on because I think I want to separate my discussion of callback rules and top tips into a separate entry.

A driver’s support for contexts begins with the call to FltRegisterFilter.  The FLT_REGISTRATION typed variable passed into that function includes a pointer to a FLT_CONTEXT_REGISTRATION structure.  This structure is pretty simple:

typedef struct _FLT_CONTEXT_REGISTRATION {

    FLT_CONTEXT_TYPE ContextType;

    FLT_CONTEXT_REGISTRATION_FLAGS Flags;

    PFLT_CONTEXT_CLEANUP_CALLBACK ContextCleanupCallback;

    SIZE_T Size;

    ULONG PoolTag;

    PFLT_CONTEXT_ALLOCATE_CALLBACK ContextAllocateCallback;

    PFLT_CONTEXT_FREE_CALLBACK ContextFreeCallback;

    PVOID Reserved1;

} FLT_CONTEXT_REGISTRATION, *PFLT_CONTEXT_REGISTRATION;

Most of this is explained well in MSDN so I won’t go into what each field is, but it is important to remember that if you register multiple context definitions (for the same context type) with varying sizes you need to specify FLTFL_CONTEXT_REGISTRATION_NO_EXACT_SIZE_MATCH so that the Filter Manager does not fail the allocations of your contexts.

After that it is easy to allocate a context using FltAllocateContext.  Currently the context types supported are: FLT_INSTANCE_CONTEXT, FLT_STREAM_CONTEXT, FLT_STREAMHANDLE_CONTEXT, and FLT_VOLUME_CONTEXT (file contexts are not yet supported).  Finally, after being allocated, a context can be set by calling the respective FltSetxxxContext routine.  The point of these contexts is to have an easy mechanism for attaching information to an instance, a stream, a stream handle, or a volume that is easily retrievable, reference counted, and garbage collected by the Filter Manager.

When I was using stream handle contexts in my first minifilter, the main problem I had was with reference counting.  At a basic level it is pretty simple.  The reference count on a context is increased whenever you call an FltGetxxxContext routine and you’ll need to call FltReleaseContext when you are done working with the context you retrieved.  You can also manually reference a context with FltReferenceContext.  The problem I had was in understanding what happens when you allocate and set a context.

The simple answer is that both increment the reference count.  So, in the MSDN entry for FltSetxxxContext it says you need to call FltReleaseContext for a successful or a failed FltSetxxxContext call.  The problem is that there is actually a bit of a difference in the failure and successful case.  If the set context fails you actually need to call FltReleaseContext twice to remove the reference from the allocation and the failed set context call to get the context to be garbage collected.  In the successful case you call FltReleaseContext to get rid of the reference count from the allocation and you are left with a reference count of one on the context.

The other thing to watch out for is close operations.  For instance, the reference count on my stream handle contexts was automatically decremented on a successful close of the file (in between the PreClose and PostClose callbacks).  If you understand what causes reference count events on your contexts and keep close track of them the Filter Manager’s support for reference counting and context cleanup callbacks are extremely helpful.

That is about all I have to say about context support in the Filter Manager.  The Filter Manager’s support for contexts makes them extremely powerful and easy to use, but also very generic.  They should be a good fit for any information you need to attach to a specific instance, stream, stream handle, or volume.

In my next post I will discuss some general rules of callbacks (specifically IRQL levels and the issues around handling that) and some of my general tips for working with the Filter Manager.

Published Friday, March 31, 2006 11:52 PM by EricK
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
dt1985324
驱动牛犊
驱动牛犊
  • 注册日期2008-05-06
  • 最后登录2009-02-10
  • 粉丝0
  • 关注0
  • 积分16分
  • 威望106点
  • 贡献值1点
  • 好评度20点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-07-02 08:32
只有3页...
stpaladin
驱动牛犊
驱动牛犊
  • 注册日期2008-06-19
  • 最后登录2010-12-29
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望39点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-07-04 11:10
问个问题,swapbuffers例子中,到底在那里加解密呢?它里面只有错误处理,没有做交换缓冲。
cxjnet
驱动牛犊
驱动牛犊
  • 注册日期2005-03-21
  • 最后登录2014-05-01
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望191点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-11-22 18:25
不错,收集了好资料
fbhyq
驱动牛犊
驱动牛犊
  • 注册日期2005-09-23
  • 最后登录2012-03-13
  • 粉丝0
  • 关注0
  • 积分374分
  • 威望161点
  • 贡献值0点
  • 好评度39点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2009-09-05 18:08
郁闷,今天发现minifilter注册回调函数里面,如下:

  { IRP_MJ_QUERY_INFORMATION,
       0,
       CtxPreQueryInfo,
       CtxPostQueryInfo
    },


为何总是无法拦截到 FileAllInformation 的信息呢?
游客

返回顶部