您的位置:首页 > 其它

NT式驱动的基本结构

2015-01-25 20:44 197 查看

1、NT式驱动的基本结构

对于NT式驱动,主要的函数是DriverEntry例程、卸载例程以及各个IRP的派遣例程。

1.1、驱动加载过程与驱动入口函数(DriverEntry)

驱动程序有一个入口函数,也就是首先被执行的函数。这个函数通常被命名为DriverEntry,也可以指定另外的名字。
函数原型: NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject , IN PUNICODE_STRING pRegistryPath);

DriverEntry主要是对驱动程序进程初始化,是由系统进程调用的。在Windows中有一个特殊的进程是 系统进程(System),它在系统启动的时候就已经被创建了。见下图。



驱动加载的时候,系统进程启动新的线程,调用执行体组件中的对象管理器,创建一个驱动对象。这个驱动对象时一个DRIVER_OBJECT的结构体。另外,系统进程调用执行体组件中的配置管理程序,查询此驱动程序对应的注册表中的项。

在DriverEntry中,主要功能是对系统进程创建的驱动对象进行初始化。
系统线程调用驱动程序的DriverEntry例程时,同时传进两个参数,分别是pDriverObject和pRegistryPath
pDriverObject是指向刚才被创建驱动对象的指针,pRegistryPath是指向设备服务键的键名字符串的指针。

这个字符串的内容一般是:\REGISTRY\MACHINE\SYSTEM\ControlSet\Service\[服务名]
在驱动程序中,字符串用UNICODE字符串来表示,UNICODE是字符宽度为16位的宽字符集。UNICODE用数据结构UNICODE_STRING表示:

<pre name="code" class="cpp">typedef struct _UNICODE_STRING
{
USHORT Length;//记录这个字符串用多少字节记录,如果字符串有N个字符,Length = 2 * N;
USHORT MaximumLength;//记录buffer的大小,也就是这个结构最大能记录的字节数。并且大于等于Length
PWSTR  Buffer;//记录字符串的指针,但是与ASCII字符串不同,因为这里的字符串每个字符都是16位
} UNICODE_STRING *PUNICODE_STRING;



在驱动程序中使用KdPrint打印UNICODE的信息:

<pre name="code" class="cpp">KdPrint(("%S\n", pRegistryPath->Buffer));
KdPrint(("%ws\n",pRegistryPath->Buffer));



DriverEntry的返回值是NTSTATUS的数据,NTSTATUS是被定义为32位的无符号长整型。在驱动开发中,经常用NTSTATUS返回状态。其中0-0X7FFFFFFF是正确的状态,而0X80000000-0XFFFFFFFF是错误的状态。用一个宏用来检测状态是否正确:NT_SUCCESS
DriverEntry的返回值如果表示成功,则意味着加载驱动成功,否则意味着加载驱动失败,调用对象管理程序销毁驱动对象。
DriverEntry参数的修饰符“IN”。“IN”,“OUT”,“INOUT”在DDK中都被定义为空串,它们的功能类似于程序注释,当看到一个“IN”参数时,应该认为该参数是纯粹用于输入,“OUT”代表该参数用于函数的输出参数。“INOUT”代表该参数既可以输入也可以输出。

<pre name="code" class="cpp">extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS status;
KdPrint(("Enter DriverEntry\n"));
//注册其他驱动调用函数入口
pDriverObject->DriverUnload = HelloDDKUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
//创建驱动设备对象
status = CreatDevice(pDriverObject);

KdPrint(("DriverEntry end\n"));
return status;
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: