对于初次涉及驱动开发的朋友,首先说一下下开发前的心理建设,开发的耗时一般都很长,过程很繁琐,成就感真的就只有完成整个驱动后的那一会快感。着重说明这是一件单身汉干的事,不要老是想着对象,否则及其容易出问题,找不出来的那种,开玩笑哈,只是说驱动开发过程中面向过程的思想比较重。
好了,说正经的,单刀直入就从工程创建说起,零碎的东西就三言两语带过哈!
一般安装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中的东西极多,各个驱动的要求区别也大,没想好怎么具体说明,想好了哆再写下一篇!~