符号链接的用户相关性
2021-07-01
72
0
从前面的例子看,符号链接的命名貌似很简单。简单的符号链接(之所以称为简单,是因为还有一种使用GUID的符号链接,这在本书讨论范围之外)总是命名在\DosDevices\之下。但是实际上这会有一些问题。
比较高级的Windows系统(哪个版本的操作系统很难讲,可能必须判定补丁号),符号链接也带有用户相关性。换句话说,如果一个普通用户创建了符号链接“\DosDevices\MyCDOSL”,那么,其实其他的用户是看不见这个符号链接的。
但是读者又会发现,如果在DriverEntry中生成符号链接,则所有用户都可以看见。原因是DriverEntry总是在进程“System”中执行。系统用户生成的符号链接是大家都可以看见的。
当前用户总是取决于当前启动当前进程的用户。实际编程中并不一定要在DriverEntry中生成符号链接。一旦在一个不明用户环境下生成符号链接,就可能出现注销然后换用户登录之后,符号链接“不见了”的严重错误。这也是常常让初学者抓狂几周都不知道如何解决的一个问题。
其实解决的方案很简单,任何用户都可以生成全局符号链接,让所有其他用户都能看见。路径“\DosDevices\MyCDOSL”改为“\DosDevices\Global\MyCDOSL”即可。
但是在不支持符号链接用户相关性的系统上,生成“\DosDevices\Global\MyCDOSL”这样的符号链接是一种错误。为此必须先判断一下。幸运的是,这个判断并不难。下面是一个例子,这个例子生成的符号链接总是随时可以使用,不用担心用户注销:
UNICODE_STRING device_name;
UNICODE_STRING symbl_name;
if (IoIsWdmVersionAvailable(1, 0x10))
{
// 如果是支持符号链接用户相关性的版本的系统,用\DosDevices\Global.
RtlInitUnicodeString(&symbl_name, L"\\DosDevices\\Global\\SymbolicLinkName");
}
else
{
// 如果是不支持的,则用\DosDevices
RtlInitUnicodeString(&symbl, L"\\DosDevices\\SymbolicLinkName");
}
// 生成符号链接
IoCreateSymbolicLink(&symbl_name, &device_name);