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

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

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

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

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

#include<ntifs.h>
//创建驱动设备对象
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事件,得到一个句柄,然后用ReadFileWriteFile,或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小时内回复。 

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值