NT驱动开发学习笔记002

来源:互联网 发布:wi fi分析工具 mac 编辑:程序博客网 时间:2024/06/11 05:32

 

 

题外话:

今天继续坚持写笔记,原来例程是某个系统对外提供的功能接口或服务的集合,呵呵。


NT驱动开发学习笔记二2011.05.05


NT驱动的入口函数DriverEntry

NTSTATUS DriverEntry(

IN PDRIVER_OBJECT  pDriverObject, //驱动对象指针

IN PUNICODE_STRING  pRegistryPath) //设备服务在注册表中键名的字符串(全路径)


本函数主要是要对驱动程序初始化工作,由系统进程调用,系统进程就是任务管理器看到的一个名为System的进程。

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

驱动入口函数主要负责3个工作:设置卸载例程函数 和 设置IRP派遣函数,这两个设置是对驱动对象的设置,还要创建设备

可以看出,DriverEntry 都是做一些初始化工作,最好放在INITSegment里。


 

创建设备例程CreateDevice

一般会把 创建设备对象 、 创建符号链接 和 设置设备对象 三个过程封装在一个CreateDevice函数里(INIT Segment),传进驱动对象指针,然后在入口函数调用。


①创建设备对象:

NT式驱动中,创建设备对象是由下面内核函数完成的:

ntStatus = IoCreateDevice(

pDriverObject, //IN 驱动对象指针

sizeof(DEVICE_EXTENSION), //IN 设备扩展的大小

&szDeviceName,  //IN 驱动的设备名称

FILE_DEVICE_UNKNOWN, //IN 驱动类型

0, TRUE,  //IN 设备对象特征通常为0IN 设置设备对象是否为内核对象使用

&pDeviceObject); //OUT 生成的设备的指针的地址,这里要注意了

OUT PDEVICE_OBJECT  *DeviceObject


 

函数会返回一个NTSTATUS的数据,其是一个ULONG类型,利用NT_SUCCESS可以检查状态是否为 STATUS_SUCESS,如下:

if(!NT_SUCCESS(ntStatus))

{//这是一个通用的过程,判断了不同的情况输出

if (ntStatus==STATUS_INSUFFICIENT_RESOURCES)

KdPrint(("STATUS_INSUFFICIENT_RESOURCES 资源不足"));

if (ntStatus==STATUS_OBJECT_NAME_EXISTS )

KdPrint(("STATUS_OBJECT_NAME_EXISTS 指定对象名存在"));

if (ntStatus==STATUS_OBJECT_NAME_COLLISION)

KdPrint(("STATUS_OBJECT_NAME_COLLISION 对象名有冲突"));

KdPrint(("IoCreateDevice Failed.../r/n"));

return ntStatus;}


②创建设备的符号链接:

NT式驱动中,设备都有一个符号链接,ring0层找到指定设备

ntStatus = IoCreateSymbolicLink(

&szSymLinkName, //IN 设备符号链接名称

&szDeviceName); //IN 设备名称

if(!NT_SUCCESS(ntStatus))

{

KdPrint(("IoCreateSymbolicLink Failed..."));

//删除设备对象,注意:设备符号链接创建失败就吧驱动对象删除了吧,避免很多问题

IoDeleteDevice(pDeviceObject);

return ntStatus;

}


 

③设置设备对象:

NT式驱动中,有两种常用的访问用户模式数据方式:DO_BUFFERED_IODO_DERECT_IO(参考IRP派遣),通过设备扩展传递“类似全局变量”(注意是双引号)

//设置使用缓冲方式访问用户模式数据

pDeviceObject->Flags |= DO_BUFFERED_IO;

注意:这里设置使得设备支持缓冲区模式的IOCTL


 

//获取设备扩展指针

pDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;

注意DeviceExtension本来的类型是PVOID,所以要强制转换


 

//设置设备扩展

pDeviceExtension->pDeviceObject = pDeviceObject;

pDeviceExtension->szDeviceName = szDeviceName;

pDeviceExtension->szSymLinkName = szSymLinkName;

注意:这里传递的参数方便驱动卸载例程使用

 

 

原创粉丝点击