Windows驱动开发第9课(驱动设备与符号链接)

您所在的位置:网站首页 设备安装图纸中,什么标志新建设备 Windows驱动开发第9课(驱动设备与符号链接)

Windows驱动开发第9课(驱动设备与符号链接)

2024-07-04 20:29| 来源: 网络整理| 查看: 265

一、驱动设备与符号链接是什么?        驱动设备不是驱动对象,而是驱动对象创建的,初学者经常把这两个在概念上搞混。那么符号链接又是什么?为什么会有符号链接?这个要从Windows下的设备命名说起,Windows下的设备命名是这样的:“\Device\设备名”,这个有点怪前面Device是固定的-常量,后面设备名是自己起的-变量。如果没有给设备起名字,I/O管理器也会随机分配一段数字为设备名,例如:“\Device\000001”

这样的名字不容易记忆,更重要的是设备名只能在内核模式下被识别。所以就有了符号链接,可以理解为设备的别名,可以在用户层被识别。为了更好的理解,我打个比喻:“就拿人名来说吧,我们大部分人都有乳名,有的地方叫小名,就是刚出生时起的不正式的名字(以前有叫狗娃,狗蛋的,现在文明些了有叫果果,糖糖)”。但是这样的名字上不了台面,只能在家里用,家里就相当于内核驱动层,等长大一些了要上学了就要有个学名,学校的同学老师就相当于用户应用层,如果哪个同学叫你狗娃你肯定会不高兴了,所以我们在写驱动的时候最好创建一个符号链接,这是一个好习惯。

驱动中符号链接名是这样写的: L"//??//HelloDDK" --->/??/HelloDDK L"//DosDevices//HelloDDK"--->/DosDevices/HelloDDK 在应用程序中,符号链接名: L".//HelloDDK"-->//./HelloDDK

二、在上一节课的代码里新建一个C文件,把驱动设备与符号链接的代码单独放在这个文件里,代码如下:

#include //创建驱动设备对象 NTSTATUS CreateDevice(PDRIVER_OBJECT driver) //driver是驱动对象 { NTSTATUS status; UNICODE_STRING MyDriver; //驱动字符串 PDEVICE_OBJECT device=NULL;//用于存放设备对象 RtlInitUnicodeString(&MyDriver, L"\\DEVICE\\MyDriver");//驱动设备名字 status = IoCreateDevice(driver, sizeof(driver->DriverExtension), &MyDriver, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &device); if (status == STATUS_SUCCESS)//STATUS_SUCCESS) { KdPrint(("zdsoft:驱动设备对象创建成功\n")); //创建符号链接 UNICODE_STRING uzSymbolName; //符号链接名字 RtlInitUnicodeString(&uzSymbolName, L"\\??\\MyDriver"); //CreateFile status = IoCreateSymbolicLink(&uzSymbolName, &MyDriver); if (status == STATUS_SUCCESS) { KdPrint(("zdsoft:创建符号链接 %wZ 成功 ", &uzSymbolName)); } else { KdPrint(("zdsoft:创建符号链接 %wZ 失败 status=%X", &uzSymbolName, status)); } } else { KdPrint(("zdsoft:驱动设备对象创建失败,删除设备\n")); IoDeleteDevice(device); } return status; }

然后这里解说一下这段代码里的IoCreateDevice函数,如下:

IoCreateDevice( 共有7个参数

driver,//第一个参数,用于在驱动程序和新设备对象之间建立连接,这样I/O管理器就可以向设备发送指定的IRP。

sizeof(driver->DriverExtension),//第二个参数,设备扩展结构的大小。

&MyDriver, // 第三个参数,驱动设备名字。

FILE_DEVICE_UNKNOWN, //第四个参数,未知设备, 虚拟驱动设备的固定写法。

FILE_DEVICE_SECURE_OPEN,//第五个参数,在打开操作中检查设备对象的安全属性

FALSE,//第六个参数,指出设备是否是排斥的。

&device //第七个参数,返回驱动设备指针,当前是一个空值,

);

如果创建成功,则返回0,只有0表示成功。驱动设备指针则保存在&device变量里。 RtlInitUnicodeString(&uzSymbolName, L"\\??\\MyDriver");//作用:初始化设备名称指针。//当用户应用层使用CreateFile时就会打开这个符号链接,同时驱动层相应的会产生一个IRP_MJ_CREATE事件,得到一个句柄,然后用ReadFile、WriteFile,或DeviceIoControl(读写)向驱动程序发出请求。

status = IoCreateSymbolicLink(&uzSymbolName, &MyDriver);//创建符号链接,成功则返回0

然后在main.c文件里为该函数添加一个说明,在入口函数里调用该函数。如下图:

 

 然后当我们卸载驱动时要删除符号链接,删除符号链接代码如下:

void DeleteDevice(PDRIVER_OBJECT pDriver) { KdPrint(("zdsoft:进入了 DeleteDevice例程")); if (pDriver->DeviceObject)//如果驱动设备不为空,说明创建了驱动设备 { //删除符号链接 UNICODE_STRING uzSymbolName; //符号链接名字 RtlInitUnicodeString(&uzSymbolName, SymbolLinkName); KdPrint(("zdsoft:删除符号链接=%wZ", &uzSymbolName)); IoDeleteSymbolicLink(&uzSymbolName); KdPrint(("zdsoft:删除驱动设备")); IoDeleteDevice(pDriver->DeviceObject);//删除设备对象 } KdPrint(("zdsoft:退出 DeleteDevice例程")); }

同上,也在main.c文件里为该函数添加说明,在卸载函数里调用该函数,如图(图2):

到此,已经完成了所有的代码,编译生成后复制到虚拟机里测试效果如下图(图3):

 

好了,今天的这节课就到这里,希望看到此文章的朋友给个关注,谢谢!有不懂的可以留言,一般24小时内回复。 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3