minifilter 驱动开发总结

对于初次涉及驱动开发的朋友,首先说一下下开发前的心理建设,开发的耗时一般都很长,过程很繁琐,成就感真的就只有完成整个驱动后的那一会快感。着重说明这是一件单身汉干的事,不要老是想着对象,否则及其容易出问题,找不出来的那种,开玩笑哈,只是说驱动开发过程中面向过程的思想比较重。

 好了,说正经的,单刀直入就从工程创建说起,零碎的东西就三言两语带过哈!

一般安装vs的时候,都不会去吧驱动模块相关的东西安装上,所以先看看你的vs安装模板没哈;

然后就是一顿操作了,新建项目->windows driver->filter driver:filesystem mini-filter...

工程创建成功后,会有3个文件:inf安装文件、版本资源文件和初始化的代码文件;

进入.c中就可以看到已经有一套简单的模板了,风格跟c语言一样, 后面的开发也几乎就是在这个模板上做。为了方便,还是拆成声明和实现文件比较好。

我这里就使用刚做的加密驱动做示例了。

然后目光就聚焦到

NTSTATUS DriverEntry (_In_ PDRIVER_OBJECT DriverObject,
						_In_ PUNICODE_STRING RegistryPath )

这个就是驱动的main函数了。

windows 生成的文件中很多东西都是放在全局的,但是很多东西大可不比如此,个人习惯也不喜欢变量放在全局。

所以首先就是把Callbacks 放到了DriverEntry 中,并去掉一些冗余的东西,后面有需要再添加。

Callbacks 就是注册操作回调的,通俗点说,就是要注册了,内核中的一些操作才会响应到注册的函数中。

其他的都可以先不动,然后后面有需要再添加或者修改。

成品如下:

NPAGED_LOOKASIDE_LIST Pre2PostContextList ;
NTSTATUS DriverEntry (_In_ PDRIVER_OBJECT DriverObject,
						_In_ PUNICODE_STRING RegistryPath )
{
    NTSTATUS status;

    UNREFERENCED_PARAMETER( RegistryPath );
	CurProcNameInit();
    PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
                  ("czEncDec!DriverEntry: Entered\n") );

	ExInitializeNPagedLookasideList( &Pre2PostContextList, NULL, NULL, 0, sizeof( PRE_2_POST_CONTEXT ), 'ppBS', 0 );

	const FLT_OPERATION_REGISTRATION fltCallbacks[] =
	{
		{ IRP_MJ_CREATE, FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,// 0/*FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO*/,
											PreCreate,	PostCreate,NULL },

		{ IRP_MJ_READ, 0/*FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO*/,
											PreRead,	PostRead },
		{IRP_MJ_WRITE,0/*FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO*/,	// 指定不应为缓存的I / O操作调用其预操作和后操作回调例程
											PreWrite,	PostWrite},				// 预操作		// 后操作

		{ IRP_MJ_QUERY_INFORMATION, 0, 
											NULL,		PostQueryInfo },
		{ IRP_MJ_SET_INFORMATION,	0,
											PreSetInfo,	NULL },

		{ IRP_MJ_CLOSE, FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,
											PreClose,	NULL },
		{ IRP_MJ_OPERATION_END }
	};

	CONST FLT_CONTEXT_REGISTRATION Context_Array[] = {

		{ FLT_STREAM_CONTEXT, 0, CleanupContext, STREAM_CONTEXT_SIZE, STREAM_CONTEXT_TAG },

		{ FLT_CONTEXT_END }
	};

	CONST FLT_REGISTRATION FilterRegistration = {

		sizeof( FLT_REGISTRATION ),         //  Size
		FLT_REGISTRATION_VERSION,           //  Version
		0,                                  //  Flags

		Context_Array,                      //  Context
		fltCallbacks,                       //  Operation callbacks

		czEncDecUnload,                     //  MiniFilterUnload
		czEncDecInstanceSetup,              //  InstanceSetup
		czEncDecInstanceQueryTeardown,      //  InstanceQueryTeardown
		czEncDecInstanceTeardownStart,      //  InstanceTeardownStart
		czEncDecInstanceTeardownComplete,   //  InstanceTeardownComplete
		NULL,                               //  GenerateFileName
		NULL,                               //  GenerateDestinationFileName
		NULL                                //  NormalizeNameComponent

	};

	
	gud_init( DriverObject );

	status = CreateCommunicationPort( FilterRegistration );
	if ( !NT_SUCCESS( status ) ) {
		DbgPrint( "FltStartFiltering failed (%08x)", status );
		FltUnregisterFilter( gud->gFilterHandle );
		return status;
	}

    return status;
}

这里面有两个东西Context_Array和FilterRegistration。

Context_Array 是为了让打开的文件的流操作权限一致,毕竟是在弄加密驱动嘛,文件操作太多。

FilterRegistration注册关于驱动的信息。

然后吧,就是对应去处理preRead函数内部的响应操作了。

暂时写这么多吧,irp中的东西极多,各个驱动的要求区别也大,没想好怎么具体说明,想好了哆再写下一篇!~

你可能感兴趣的:(windows,kenel)