Windows Minifilter驱动 - DriverEntry (3)

来源:互联网 发布:水弹玩具狙击枪 淘宝 编辑:程序博客网 时间:2024/05/14 12:16

驱动里面的DriverEntry就相当于main()或者DllMain()函数,这是个入口点。当驱动被加载的时候,DriverEntry会被调用。

VS2013给我们生成的DriverEntry函数如下:

NTSTATUSDriverEntry (    _In_ PDRIVER_OBJECT DriverObject,    _In_ PUNICODE_STRING RegistryPath    )/*++Routine Description:    This is the initialization routine for this miniFilter driver.  This    registers with FltMgr and initializes all global data structures.Arguments:    DriverObject - Pointer to driver object created by the system to        represent this driver.    RegistryPath - Unicode string identifying where the parameters for this        driver are located in the registry.Return Value:    Routine can return non success error codes.--*/{    NTSTATUS status;    UNREFERENCED_PARAMETER( RegistryPath );    PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,                  ("MyMiniFilter!DriverEntry: Entered\n") );    //    //  Register with FltMgr to tell it our callback routines    //    status = FltRegisterFilter( DriverObject,                                &FilterRegistration,                                &gFilterHandle );    FLT_ASSERT( NT_SUCCESS( status ) );    if (NT_SUCCESS( status )) {        //        //  Start filtering i/o        //        status = FltStartFiltering( gFilterHandle );        if (!NT_SUCCESS( status )) {            FltUnregisterFilter( gFilterHandle );        }    }    return status;}

FltRegisterFilter

这是DriverEntry里面需要调用的第一个函数,用来注册当前这个minifilter。下面是SDN上的描述:

翻译一下:

每一个minifilter驱动必须在DriverEntry里面调用FltRegisterFilter来把它自己注册到minifilter驱动的全局列表里面,同时给Filter管理器提供一个回调函数列表和其他的一些信息。

FltRegisterFilter通过*RetFilter返回一个不透明的指针,这个指针指向当前minifilter。这个指针唯一地标识minifilter驱动并且一旦加载后就保持不变。minifilter驱动需要保存这个指针,因为这是FltStartFiltering和FltUnregisterFilter所需要的参数。

调用FltRegisterFilter之后,minifilter驱动通常需要调用FltStartFiltering来开始过滤I/O操作。

一个minifilter驱动只能调用FltRegisterFilter来注册它自己,不可以注册其他的minifilter驱动。

如果想要反注册它自己,minifilter驱动可以调用FltUnregisterFilter。

参数:

1. PDRIVER_OBJECT Driver: minifilter驱动对象,也就是DriverEntry的第一个参数,有系统生成并传递进来。

2. const FLT_REGISTRATION *Registration: 回调和其他信息,看下面详细说明。

3. PFLT_FILTER *RetFilter:传出参数,这个参数会被其他函数用的,比如FltStartFiltering和FltUnregisterFilter。

重点需要介绍第二个参数Registration。

////  This defines what we want to filter with FltMgr//CONST FLT_REGISTRATION FilterRegistration = {    sizeof( FLT_REGISTRATION ),         //  Size    FLT_REGISTRATION_VERSION,           //  Version    0,                                  //  Flags    NULL,                               //  Context    Callbacks,                          //  Operation callbacks    MyMiniFilterUnload,                           //  MiniFilterUnload    MyMiniFilterInstanceSetup,                    //  InstanceSetup    MyMiniFilterInstanceQueryTeardown,            //  InstanceQueryTeardown    MyMiniFilterInstanceTeardownStart,            //  InstanceTeardownStart    MyMiniFilterInstanceTeardownComplete,         //  InstanceTeardownComplete    NULL,                               //  GenerateFileName    NULL,                               //  GenerateDestinationFileName    NULL                                //  NormalizeNameComponent};

上面的代码就列出了一些minifilter的信息,比较重要的就是Callbacks,

////  operation registration//CONST FLT_OPERATION_REGISTRATION Callbacks[] = {    { IRP_MJ_WRITE,        0,        MyMiniFilterPreOperation,        MyMiniFilterPostOperation },#if 0 // TODO - List all of the requests to filter.    { IRP_MJ_CREATE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_CREATE_NAMED_PIPE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_CLOSE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_READ,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_WRITE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_QUERY_INFORMATION,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_SET_INFORMATION,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_QUERY_EA,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_SET_EA,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_FLUSH_BUFFERS,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_QUERY_VOLUME_INFORMATION,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_SET_VOLUME_INFORMATION,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_DIRECTORY_CONTROL,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_FILE_SYSTEM_CONTROL,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_DEVICE_CONTROL,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_INTERNAL_DEVICE_CONTROL,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_SHUTDOWN,      0,      MyMiniFilterPreOperationNoPostOperation,      NULL },                               //post operations not supported    { IRP_MJ_LOCK_CONTROL,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_CLEANUP,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_CREATE_MAILSLOT,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_QUERY_SECURITY,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_SET_SECURITY,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_QUERY_QUOTA,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_SET_QUOTA,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_PNP,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_RELEASE_FOR_SECTION_SYNCHRONIZATION,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_ACQUIRE_FOR_MOD_WRITE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_RELEASE_FOR_MOD_WRITE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_ACQUIRE_FOR_CC_FLUSH,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_RELEASE_FOR_CC_FLUSH,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_NETWORK_QUERY_OPEN,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_MDL_READ,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_MDL_READ_COMPLETE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_PREPARE_MDL_WRITE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_MDL_WRITE_COMPLETE,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_VOLUME_MOUNT,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },    { IRP_MJ_VOLUME_DISMOUNT,      0,      MyMiniFilterPreOperation,      MyMiniFilterPostOperation },#endif // TODO    { IRP_MJ_OPERATION_END }};

if 0 这一段是向导生成的,列出了我们是所有可以挂载回调函数的事件,需要注意的是必须以{ IRP_MJ_OPERATION_END }结束。上面的代码只是注册了IRP_MJ_WRITE的回调。
回调包含Pre和Post两种,从字面意思就可以知道一个是在把IRP往下传递之前,一个是IRP传下去又回来之后。


FltStartFiltering

这个函数用来通知Filter管理器minifilter驱动已经可以开始过滤I/O操作了。

A minifilter driver typically calls FltStartFiltering from itsDriverEntry routine after it has completed its global initialization and calledFltRegisterFilter. FltStartFiltering notifies the Filter Manager that the minifilter driver is ready to begin attaching to volumes and filtering I/O requests. After the minifilter driver calls this routine, the Filter Manager treats the minifilter driver as a fully active minifilter driver, presenting it with volumes to attach to, as well as I/O requests. The minifilter driver must be prepared to begin receiving these notifications and I/O requests even beforeFltStartFiltering returns.


总结:

minifilter DriverEntry()里面主要需要做2个事情,

1. 注册当前minifilter驱动,这样filter管理器就会知道这个驱动;

2. 通知Filter管理器开始过滤。




0 0
原创粉丝点击