获取符号链接目标的卷名的最佳方法 [NTFS]

Posted

技术标签:

【中文标题】获取符号链接目标的卷名的最佳方法 [NTFS]【英文标题】:Best way to get volume name of symbolic link target [NTFS] 【发布时间】:2015-03-28 01:05:04 【问题描述】:

我想要一种可靠的方法来获取符号链接目标的卷名,而且不是很复杂。

所以看起来FILE_NAME_INFO 结构不包含有关文件所在卷的任何信息。我能够从这个结构中获取符号链接目标的路径,但现在我只是假设目标驻留在同一个卷上。但是,我知道符号链接允许其他卷上的目标。

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <ole2.h>

struct FILE_NAME_INFO_AND_BUF 
    FILE_NAME_INFO fni;
    WCHAR buf[260];
;

WCHAR* getReparseTarget(WCHAR* linkFileName) 
    HANDLE hFile;
    WCHAR *szGuid = (WCHAR *)malloc(sizeof(WCHAR) * MAX_PATH);
    BOOL result;
    FILE_NAME_INFO_AND_BUF fnib =  0 ;

    hFile = ::CreateFile(linkFileName, FILE_READ_ATTRIBUTES,
        FILE_SHARE_READ |
        FILE_SHARE_WRITE,
        0,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS, 0);
    if (hFile == INVALID_HANDLE_VALUE) 
        ::CloseHandle(hFile);
        return NULL;
    

    result = ::GetFileInformationByHandleEx(hFile, FileNameInfo, &fnib, sizeof(fnib));
    if (!result) 
        fprintf(stderr, "GetFileInformationByHandleEx Error %d\n", ::GetLastError());
        ::CloseHandle(hFile);
        return NULL;
    

    WCHAR *targetFileName = (WCHAR *)malloc(sizeof(WCHAR) * MAX_PATH);
    wmemset(targetFileName, 0, MAX_PATH);
    wcsncpy(targetFileName, linkFileName, 2);
    wcscat(targetFileName, fnib.fni.FileName);

    return targetFileName;

如您所见,我在作弊并从输入字符串中获取卷名,在本例中为驱动器号,但如果目标位于另一个卷上,这将不起作用。此外,我更喜欢使用 GUID 获取卷名,例如\\?\Volumef993747a-5d7a-4de1-a97a-c20c1af1ba02\ 比驱动器号,例如C:\

【问题讨论】:

【参考方案1】:

最简单的方法是使用GetFinalPathNameByHandle 函数,只要您可以针对Vista 或更高版本。

如果您还需要以 XP 为目标,那么您可以通过使用 FILE_FLAG_OPEN_REPARSE_POINT 标志打开链接本身(而不是它指向的文件)来找到符号链接的目标,然后使用 FSCTL_GET_REPARSE_POINT IO 控制代码来查找链接的目标。

由于链接的目标可能包含其他链接(我相信最多 31 个),因此您必须在路径的每个元素上执行此操作,以确保找到最终目标。

【讨论】:

我还没有尝试过 GetFinalPathNameByHandle 并且会试一试,但我已经尝试过您建议的第二种方法。不幸的是,它有时会产生相对路径而不是绝对路径,我需要后者。 @Wes 如果你最终得到一个相对路径,使用 GetFullPathName 将其转换为绝对路径(或者只是自己进行解析) 这对我来说似乎很完美(使用 GetFinalPathNameByHandle):pastebin.com/6PgGDttC

以上是关于获取符号链接目标的卷名的最佳方法 [NTFS]的主要内容,如果未能解决你的问题,请参考以下文章

为 Cygwin 启用本机 NTFS 符号链接

Ntfs 下的链接符号创建

如何列出 NTFS 文件系统上的所有符号链接

NTFS 连接与符号链接(用于目录)[关闭]

Bash 脚本实例:获取符号链接的目标位置

dtrace:如何从文件中获取符号链接目标