如何以编程方式访问Windows符号链接的目标路径?

时间:2021-07-28 16:26:37

Windows 6 (Vista and Server 2008) support proper symbolic links, which can be created via the CreateSymbolicLink function. But there doesn't appear to be a corresponding function for interrogating a symbolic link to obtain the path of the link's target.

Windows 6(Vista和Server 2008)支持正确的符号链接,可以通过CreateSymbolicLink函数创建。但似乎没有相应的函数来询问符号链接以获得链接目标的路径。

I have found out that symbolic links are an implementation of reparse points, and so the reparse point functions can be used to obtain the target path. But the header files that I need to use reparse points appear to come with the Windows Driver Kit. Setting up this kit with VS2008 appears to be a non trivial task.

我发现符号链接是重新分析点的实现,因此重新分析点函数可用于获取目标路径。但我需要使用重新分析点的头文件似乎附带Windows驱动程序工具包。使用VS2008设置此套件似乎是一项非常重要的任务。

Is there a nice simple function that I've missed for obtaining a link's target, or do I really have to set up a windows driver development environment just to write code to access this information?

是否有一个很好的简单函数,我错过了获取链接的目标,或者我是否真的必须设置一个Windows驱动程序开发环境只是为了编写代码来访问这些信息?

EDIT: Adam Mitz came up with the suggestion of GetFinalPathNameByHandle. This function works just great for local symlinks, but doesn't appear to work for resolving remote links (via a UNC path).

编辑:Adam Mitz提出了GetFinalPathNameByHandle的建议。此函数适用于本地符号链接,但似乎不适用于解析远程链接(通过UNC路径)。

EDIT 2: At Adam's request, here are more details of what I've tried:

编辑2:在亚当的要求下,这里有更多关于我尝试过的细节:

I initially went down the FSCTL_GET_REPARSE_POINT/ DeviceIoControl route, but that yields a REPARSE_DATA_BUFFER structure. The headers that define this structure seem to exist solely within the Windows Driver Kit.

我最初关闭了FSCTL_GET_REPARSE_POINT / DeviceIoControl路由,但这产生了一个REPARSE_DATA_BUFFER结构。定义此结构的标头似乎仅存在于Windows驱动程序工具包中。

GetFinalPathNameByHandle() works fine when the link exists on a local disk (C:\...\link etc). Curiously, I found that I could obtain the handle to the link - and thus get the target - using CreateFileW() whether the FILE_FLAG_OPEN_REPARSE_POINT flag was specified or not, regardless of whether the target file exists.

当本地磁盘上存在链接时,GetFinalPathNameByHandle()可以正常工作(C:\ ... \ link等)。奇怪的是,我发现无论目标文件是否存在,我都可以使用CreateFileW()来获取链接的句柄 - 从而获得目标 - 无论是否指定了FILE_FLAG_OPEN_REPARSE_POINT标志。

When CreateFileW() and GetFinalPathNameByHandle() are used to interrogate a remote link though (\\?\UNC\....), things start to unravel. If FILE_FLAG_OPEN_REPARSE_POINT is specified, GetFinalPathNameByHandle() always returns the link path, not the target path. If FILE_FLAG_OPEN_REPARSE_POINT is not specified, then the target path is returned, but only if the target exists and is on the same machine as the link. If the link points to another machine, I get a network permissions error. If the link points to a local - non-existent - file, I get a file not found error.

当使用CreateFileW()和GetFinalPathNameByHandle()来询问远程链接(\\?\ UNC \ ....)时,事情开始解开。如果指定了FILE_FLAG_OPEN_REPARSE_POINT,则GetFinalPathNameByHandle()始终返回链接路径,而不是目标路径。如果未指定FILE_FLAG_OPEN_REPARSE_POINT,则返回目标路径,但仅在目标存在且与链接位于同一台计算机上时才返回。如果链接指向另一台计算机,则会出现网络权限错误。如果链接指向本地 - 不存在 - 文件,我得到一个文件未找到错误。

1 个解决方案

#1


13  

GetFinalPathNameByHandle

A final path is the path that is returned when a path is fully resolved. For example, for a symbolic link named "C:\tmp\mydir" that points to "D:\yourdir", the final filesystem path would be "D:\yourdir".

最终路径是完全解析路径时返回的路径。例如,对于名为“C:\ tmp \ mydir”的符号链接,指向“D:\ yourdir”,最终的文件系统路径将为“D:\ yourdir”。

#1


13  

GetFinalPathNameByHandle

A final path is the path that is returned when a path is fully resolved. For example, for a symbolic link named "C:\tmp\mydir" that points to "D:\yourdir", the final filesystem path would be "D:\yourdir".

最终路径是完全解析路径时返回的路径。例如,对于名为“C:\ tmp \ mydir”的符号链接,指向“D:\ yourdir”,最终的文件系统路径将为“D:\ yourdir”。