【Window内核驱动开发】——通过符号链接获取真实设备
2016-11-28 16:57
1001 查看
【我的】Window驱动开发——通过符号链接获取真实设备
作者:zcr214 时间:2016/5/5
我们想要把驱动绑定到指定的盘符,实际是绑定到它对应的真实设备卷,实际上windows用户看到的C盘D盘只是符号链接名,而真实设备通常是/Device/HarddiskVolume2,/Device/HarddiskVolume3等,符号链接名可以任意更改,但是真实设备卷却是不变的。而实际用户并不会知道哪个盘符对应哪个卷,所以需要我们通过符号链接来获取到真实设备卷。
当然也可以不指定设备名称,那么I/O管理器会自动分配一个数字作为设备的名称。例如"\Device\00000001",设备名并不容易记忆。
符号链接可以理解为设备的别名,更重要的是设备名,只能被内核模式下的其他驱动所识别,而别名可以被用户模式下的应用程序识别。“C:”就是一个符号链接名。而在驱动中,符号链接名是这样写的:
L”\\??\\c:” 对应 \??\c:
L”\\DosDevices\\HelloDDK” 对应 \DosDevices\HelloDDK
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);
如果成功,返回符号链接对象操作句柄。
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中。
作者: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中。
相关文章推荐
- 驱动开发之符号链接和设备名称
- 驱动中通过设备链接名取得磁盘符号的方法
- 驱动开发之符号链接和设备名称
- 驱动开发之符号链接和设备名称
- Window XP驱动开发(十六) 驱动程序调用驱动程序(通过设备指针)
- 驱动开发之符号链接和设备名称
- 驱动开发之符号链接和设备名称
- 浅谈 Linux 内核开发之 PCI 设备驱动
- 浅谈 Linux 内核开发之网络设备驱动
- 浅谈 Linux 内核开发之网络设备驱动
- Window XP驱动开发(十九) windows内核高级调试技巧(双机调试)
- Linux内核开发之简单字符设备驱动(下)
- 浅谈 Linux 内核开发之网络设备驱动
- Linux设备驱动开发详解--笔记3--Linux内核及内核编程
- Linux设备驱动开发详解-Note(8)---Linux 内核模块(2)
- 浅谈 Linux 内核开发之网络设备驱动
- 浅谈 Linux 内核开发之网络设备驱动
- 浅谈 Linux 内核开发之 PCI 设备驱动
- 浅谈 Linux 内核开发之 PCI 设备驱动
- 内核子系统或设备驱动可以直接编译到内核,也可以编译成模块,如果编译到内核,可以使用前一节介绍的方法通过内核启动参数来向它们传递参数,如果编译成模块,则可以通过命令行在插入模块时传递参数,或者在运行时,