您的位置:首页 > 其它

【Window内核驱动开发】——通过符号链接获取真实设备

2016-11-28 16:57 1001 查看
【我的】Window驱动开发——通过符号链接获取真实设备
作者:zcr214 时间:2016/5/5

 

我们想要把驱动绑定到指定的盘符,实际是绑定到它对应的真实设备卷,实际上windows用户看到的C盘D盘只是符号链接名,而真实设备通常是/Device/HarddiskVolume2,/Device/HarddiskVolume3等,符号链接名可以任意更改,但是真实设备卷却是不变的。而实际用户并不会知道哪个盘符对应哪个卷,所以需要我们通过符号链接来获取到真实设备卷。

1.    符号链接名与设备名

windows下的设备是以"\Device\[设备名]”形式命名的。例如磁盘分区的C盘,D盘的设备名称就是"\Device\HarddiskVolume2”,"\Device\HarddiskVolume3”。

当然也可以不指定设备名称,那么I/O管理器会自动分配一个数字作为设备的名称。例如"\Device\00000001",设备名并不容易记忆。

符号链接可以理解为设备的别名,更重要的是设备名,只能被内核模式下的其他驱动所识别,而别名可以被用户模式下的应用程序识别。“C:”就是一个符号链接名。而在驱动中,符号链接名是这样写的:

L”\\??\\c:”  对应 \??\c:

L”\\DosDevices\\HelloDDK”  对应 \DosDevices\HelloDDK

2.    ZwOpenSymbolicLinkObject()打开符号链接对象

WDK提供了打开符号链接对象的接口函数ZwOpenSymbolicLinkObject(),其原型如下:
NTSTATUS
NTAPI
ZwOpenSymbolicLinkObject(
    _Out_PHANDLE LinkHandle,
    _In_ACCESS_MASK DesiredAccess,
    _In_POBJECT_ATTRIBUTES ObjectAttributes
);
和之前讲的打开注册表对象类似,需要指定访问权限,初始化一个对象属性OBJECT_ATTRIBUTES,初始化的方式也同样使用
InitializeObjectAttributes(
&obj_attr,
SymbolicLinkName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
这里需要重点注意的是符号链接名,一定要初始化正确,并且是UNICODE_STRING类型,例如C盘,则初始化符号链接名为
UNICODE_STRINGSymbolicLinkName=RTL_CONSTANT_STRING("\\??\\c:");
如果是动态的,则一定要指派长度与Buffer真实长度一致。
完成obj_attr的初始化之后就可以打开符号链接对象了。
status=ZwOpenSymbolicLinkObject(&h,GENERIC_READ,&obj_attr);
       如果成功,返回符号链接对象操作句柄。

 

3.    ZwQuerySymbolicLinkObject()获取到设备目标

利用获取到的符号链接对象,获取真实设备名,保存于UNICDOE_STRING结构中,其原型如下:

NTSTATUS
NTAPI
ZwQuerySymbolicLinkObject(
    _In_HANDLE LinkHandle,
    _Inout_PUNICODE_STRING LinkTarget,
    _Out_opt_PULONG ReturnedLength
);

LinkHandle是之前得到的操作句柄。

LinkTarget用于保存真实设备信息。

ReturnedLength保存长度。

当然在获取设备信息之前,需要初始化一个LinkTarget,并将其内容清空。

RtlZeroMemory(LinkTarget->Buffer,LinkTarget->MaximumLength);

status=ZwQuerySymbolicLinkObject(h,LinkTarget,NULL);

 

如果status为成功,那么设备信息已经获取到了,保存在LinkTarget中。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息