符号链接与设备接口名

来源:互联网 发布:https seo 编辑:程序博客网 时间:2024/06/10 00:17

符号链接和设备对象一样,也是内核对象的一种。调用WdfDeviceCreateSymbolicLink创建符号链接,其参数是设备句柄和符号链接名。系统将因此创建一个符号链接内核对象,并指向设备句柄送代表的设备对象的名称——–这和文件系统中的“快捷方式”本质上很像。

//创建符号链接,应用程序根据符号链接查看并使用内核设备

//除了创建符号链接外,更好的方法是使用WdfDeviceCreateDeviceInterface创建设备接口

//设备接口能保证名字不会冲突,但不具有可读性,所以仍采用符号链接形式

nLen=wcslen(wcsDosDeviceName);

wcsDosDeviceName[nLen-1]+=nInstance;

status=WdfDeviceCreateSymbolicLink(device,&DosDeviceName);

设备接口也是符号链接,但命名方式更复杂。它首先根据接口GUID为设备创建接口类(如果已存在则不会创建),然后在接口类下创建接口实例。在驱动程序中创建设备接口和创建符号链接,有一个非常明显的区别:符号链接的目标对象是功能设备对象,而设备接口的目标对象是物理设备对象(二者位于同一个设备栈)。
GUID能最大限度地保证唯一性。另外,设备接口还具有一个特点,即可以被启动和禁止。这样,设备接口具有三个优点:第一,具有COM接口属性,可以通过COM接口方式引用;第二,内核驱动加强了对暴露给用户程序的设备接口的管理,可以随时启用、禁止;第三,由于是基于GUID的,因此再多的设备接口也不怕重名。
这里多说一句:很多人在谈到符号链接和设备接口的区别时会说到一点,就是符号链接名是程序员想出来的“可读名称”,容易重名。这自然是一个事实,但其实并不能将此作为一个很重要的区别或缺点。文件系统中存在的所有文件,都是用户可读的,难道因此要把这些文件名用GUID来代替?

调用WdfDeviceCreateDeviceInterface完成接口创建

NTSTATUS WdfDeviceCreateDeviceInterface(

IN WDFDEVICE Device, //框架设备对象句柄

IN CONST GUID* InterfaceClassGUID //接口类GUID,此GUID若不存在,将被创建

IN OPTIONAL PCUNICODE_STRING ReferenceString //引用字符串,将和类GUID一起组合到被创建的接口名称中

);

这个函数被调用时,系统会首先到注册表中检查interfaceclassguid所代表的接口类是否已注册,如果没有注册就先注册;然后在这个接口类下创建一个设备接口实例,这个接口实例名称到底什么样子由系统说了算,但可以确定的是,这个名称包含了三部分内容:接口类GUID(字符串)、可选的引用字符串,以及设备ID的一部分。

首先定义一个GUID,可以使用GUID Generator工具。如:

GUID DeviceInterface = {0xdb713b3f,0xea3f,0x4d74,0x89,0x46,0x12,0x32,0xdb,0x12,0xfc,0x12};

然后开始创建设备接口:

//WdfDeviceCreateDeviceInterface需设置一个引用字符串,内容随便用来将同一个接口类中的多个设备接口区别开

nLen = wcslen(wcsRefString);

wcsRefString[nLen-1]+=nInstance;

//创建设备接口实例

status = WdfDeviceCreateDeviceInterface(device,

&DeviceInterface,

&RefString);

//下面获取系统为这个接口实例赋予的符号链接名

if(NT_SUCCESS(status))

{

status=WdfDeviceRetrieveDeviceInterfaceString(device,

  &DeviceInterface,  &RefString,  string);

if(status==STATUS_SUCCESS)

{

UNICODE_STRING name;

WdfStringGetUnicodeString(string,&name);

KDBG(DPFLTR_INFO_LEVEL,”Interface Name: %wZ”,&name);

}

}

(注意:路径字符“\“和”/“不能用于引用字符串,就是说输入的符号链接名不能包含\ /这些字符

0 0
原创粉丝点击