使用 boost 解析符号链接时,结果不等于原始路径名



Windows 10
MS VS 2015
C 11
提升1.60

我创建此符号链接:

mklink /J "C:T4 2.0ApplicationSymlinksT4" "C:T4 2.0Data"

这是程序的简化版本,用于检查符号链接是否链接到适当目录:

#include <boost/filesystem.hpp>
#include <iostream>
int main()
{
    boost::filesystem::path directory = "c:\T4 2.0\Data";
    boost::filesystem::path symlink = "c:\T4 2.0\ApplicationSymlinks\T4";
    boost::filesystem::path path_linked_to("");
    path_linked_to = boost::filesystem::read_symlink(symlink);    // Resolve symlink. path_linked_to is not absolute. L"\T4 2.0\Data"
    path_linked_to = boost::filesystem::absolute(path_linked_to); // Absolute path. L"c:\T4 2.0\Data"
    if (directory == path_linked_to)
        std::cout << "paths are equal" << std::endl;
    else
        std::cout << "paths are not equal" << std::endl;                    
    return 0;
}

输出是"路径不相等"。他们不应该平等吗?在调试器的汽车窗口中,我确实看到了:

directory size 14 capacity 15

其中

path_linked_to size 16 capacity 23 because it includes two trailing ''s.

read_symlink中引入了这两个尾声''S。

如何解决这个问题?read_symlink为什么不返回绝对?read_symlink为什么添加两个尾随'' S(假设这是问题)?operator==为什么不忽略'' S?

我如何编译和链接:

C:Program Files (x86)Microsoft Visual Studio 14.0VCbinx86_amd64CL.exe /c /IC:Librariesboost_1_60_0 /ZI /nologo /W3 /WX- /sdl /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"x64Debug\" /Fd"x64Debugvc140.pdb" /Gd /TP /errorReport:prompt resolvesymlilnk.cpp stdafx.cpp
C:Program Files (x86)Microsoft Visual Studio 14.0VCbinx86_amd64link.exe /ERRORREPORT:PROMPT /OUT:"c:UsersThereforeDocumentsVisual Studio 2015Projectsresolvesymlilnkx64Debugresolvesymlilnk.exe" /INCREMENTAL /NOLOGO /LIBPATH:"C:Librariesboost_1_60_0lib64-msvc-14.0" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /Debug /PDB:"c:UsersThereforeDocumentsVisual Studio 2015Projectsresolvesymlilnkx64Debugresolvesymlilnk.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"c:UsersThereforeDocumentsVisual Studio 2015Projectsresolvesymlilnkx64Debugresolvesymlilnk.lib" /MACHINE:X64 x64Debugresolvesymlilnk.obj

这是BOOST中的一个已知错误:https://svn.boost.org/trac/boost/ticket/ticket/10900

不幸的是,它尚未修复,并且被分配了低优先级,因此,如果您愿意修复它,则必须自己做。

问题在于,当boost.filesystem读取REPARSE_DATA_BUFFER结构时,它假设reparse是符号链接,因此始终使用SymbolicLinkReparseBuffer联合成员;对于连接点,应使用MountPointReparseBuffer。这意味着缓冲区计算是sizeof(ULONG)关闭的,因此读取路径缺少驱动器字母和结肠(L"C:"),而末尾添加了两个宽字符,而您通常观察到的通常为空字符。(宽字符在离开Boost.Filesystem内部的路上转换为狭窄字符。)

修复程序将在read_symlink中检查ReparseTag成员是IO_REPARSE_TAG_SYMLINK还是IO_REPARSE_TAG_MOUNT_POINT(如is_reparse_point_a_symlink中),并分别使用SymbolicLinkReparseBufferMountPointReparseBuffer。正如上面链接的票面所述,Boost应该真正使用SubstituteNameOffset/SubstituteNameLength代替PrintNameOffset/PrintNameLength,并剥离主要Symlink和交界处的领先L"??"

最新更新