diff --git a/src/operations.cpp b/src/operations.cpp index 4114e02a..d689a16d 100644 --- a/src/operations.cpp +++ b/src/operations.cpp @@ -1636,15 +1636,34 @@ namespace detail DWORD sz; - if (!error(::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, + if (error(::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, 0, 0, info.buf, sizeof(info), &sz, 0) == 0 ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::read_symlink" )) - symlink_path.assign( - static_cast(info.rdb.SymbolicLinkReparseBuffer.PathBuffer) - + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t), - static_cast(info.rdb.SymbolicLinkReparseBuffer.PathBuffer) - + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t) - + info.rdb.SymbolicLinkReparseBuffer.PrintNameLength/sizeof(wchar_t)); + return symlink_path; + + wchar_t const* path_buffer = NULL; + size_t path_length = 0; + switch (info.rdb.ReparseTag) + { + case IO_REPARSE_TAG_SYMLINK: + path_buffer = info.rdb.SymbolicLinkReparseBuffer.PathBuffer + + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t); + path_length + = info.rdb.SymbolicLinkReparseBuffer.PrintNameLength/sizeof(wchar_t); + break; + case IO_REPARSE_TAG_MOUNT_POINT: + path_buffer = info.rdb.MountPointReparseBuffer.PathBuffer + + info.rdb.MountPointReparseBuffer.PrintNameOffset/sizeof(wchar_t); + path_length + = info.rdb.MountPointReparseBuffer.PrintNameLength/sizeof(wchar_t); + break; + default: + error(BOOST_ERROR_NOT_SUPPORTED, p, ec, + "boost::filesystem::read_symlink"); + return symlink_path; + } + + symlink_path.assign(path_buffer, path_buffer + path_length); # endif return symlink_path; } diff --git a/test/operations_test.cpp b/test/operations_test.cpp index 32f3d7bf..e5ee44e8 100644 --- a/test/operations_test.cpp +++ b/test/operations_test.cpp @@ -1805,6 +1805,7 @@ namespace BOOST_TEST(!fs::is_regular_file(junc)); BOOST_TEST(fs::exists(junc / "d1f1")); BOOST_TEST(fs::is_regular_file(junc / "d1f1")); + BOOST_TEST_EQ(fs::read_symlink(junc), dir / "d1"); int count = 0; for (fs::directory_iterator itr(junc); @@ -1824,6 +1825,7 @@ namespace BOOST_TEST(!fs::is_regular_file(new_junc)); BOOST_TEST(fs::exists(new_junc / "d1f1")); BOOST_TEST(fs::is_regular_file(new_junc / "d1f1")); + BOOST_TEST_EQ(fs::read_symlink(new_junc), dir / "d1"); fs::remove(new_junc); BOOST_TEST(!fs::exists(new_junc / "d1f1"));