驱动入口函数

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

这个驱动程序包含了三个函数:DriverEntry、HelloDDKUnload和HelloDDKDispatchRoutine。其中DriverEntry是驱动程序的入口函数,相当于C/C++程序的main函数,HelloDDKUnload函数是驱动卸载函数。而HelloDDKDispatchRuntine则是IRP的派遣函数,因为驱动程序主要是处理IO 请求,而IO请求大多是在派遣函数中处理的。

先来看看这个驱动程序的第一个函数:DriverEntry

/****************************************************************

* 函数名称:DriverEntry

* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象

* 参数列表:

pDriverObject:从I/O管理器中传来的驱动对象

pRegistryPath:驱动程序在注册表中的路径

* 返回值:返回初始化驱动状态

****************************************************************/

#pragma INITCODE

extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject,

IN PUNICODE_STRING pRegistryPath )

{

NTSTATUS status;

KdPrint( ( "Enter DriverEntry!\n" ) );

//注册其它驱动调用函数入口

pDriverObject->DriverUnload = ( PDRIVER_UNLOAD ) 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 = CreateDeivce( pDriverObject );

KdPrint( ( "DriverEntry end!\n" ) );

return status;

}

这个函数的第一句代码是一个#pragma预处理指令:

#pragma INITCODE

这段代码表明将此函数加入INIT内存区域。

在函数头中的“extern "C"”是指定编译器的编译方式,若不加此修饰,编译器则会按C++的编译方式来编译,会导致编译错误。

NTSTATUS是函数的返回状态,用来检测函数的状态是否正确,常用的NTSTATUS 值有:

#define STATUS_SUCCESS

#define STATUS_BUFFER_OVERFLOW

#define STATUS_UNSUCCESSFUL

#define STATUS_NOT_IMPLEMENTED

#define STATUS_ACCESS_VIOLATION

#define STATUS_INVALID_HANDLE

#define STATUS_INVALID_PARAMETER

接着是函数参数中的IN修饰,该修饰是定义参数的类型,“IN”修饰表示是一个输入参数,“OUT”修饰表示是一个输出参数,“INOUT”修饰表示是一个输入输出参数。

接下来就得了解了解驱动程序中的第一个结构体:PDRIVER_OBJECT,该结构体我在帮助文档里找了半天也没找到,最后在“wdm.h”中找到了其定义:

typedef struct _DRIVER_OBJECT {

CSHORT Type;

CSHORT Size;

PDEVICE_OBJECT DeviceObject;

ULONG Flags;

PVOID DriverStart;

ULONG DriverSize;

PVOID DriverSection;

PDRIVER_EXTENSION DriverExtension;

UNICODE_STRING DriverName;

PUNICODE_STRING HardwareDatabase;

PFAST_IO_DISPATCH FastIoDispatch;

PDRIVER_INITIALIZE DriverInit;

PDRIVER_STARTIO DriverStartIo;

PDRIVER_UNLOAD DriverUnload;

PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];

} DRIVER_OBJECT;

typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT;

该结构体共有15个成员,这个结构体表示的是一个驱动对象,是驱动的一个实例,类似于用户模式下的线程句柄一类。该对象在DriverEntry函数中被始化,然后由内核中的I/O管理器来加载,确切的加载函数是IoCreateDevice。

下面要说说该结构体中的几个重要成员:

DeviceObject:这是一个设备对象的结构体。一个驱动程序会创建多个设备对象,每个设备对象都有指向下一个设备对象的指针,最后一个设备象的指针为空。此处的DeviceObject指向驱动程序的第一个设备对象,

DriverName:驱动名称。其数据类型为UNICODE_STRING,该字符串一般为“\\driver\\[驱动名称]”,UNICODE_STRING字符串的赋值用RtlInitUnicodeString函数。

DriverUnload:指定驱动卸载时使用的回调函数地址。

MajorFunction:该成员是一个PDRIVER_DISPATCH结构体组数指针,其定义如下:

__drv_functionClass(DRIVER_DISPATCH)

__drv_requiresIRQL(PASSIVE_LEVEL)

__drv_sameIRQL

typedef

NTSTATUS

DRIVER_DISPATCH (

__in struct _DEVICE_OBJECT *DeviceObject,

__inout struct _IRP *Irp

);

typedef DRIVER_DISPATCH *PDRIVER_DISPATCH;

每个指针指向一个函数,这个函数就是处理IRP的派遣函数。

FastIoDispatch:文件驱动中用到的派遣函数。

派遣函数相当于WIN32子系统下的事件响应函数,驱动程序的主要功能是负责处理IO请求,而绝大多数的IO请求是在派遣函数中处理的。关于IRP派遣函数的相关解释另作笔记。

相关文档
最新文档