Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion toolsrc/src/vcpkg/base/files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,61 @@ namespace vcpkg::Files
return status_implementation(false, p, ec);
}

fs::path read_symlink_implementation(const fs::path& oldpath, std::error_code& ec)
{
#if defined(_WIN32) && !VCPKG_USE_STD_FILESYSTEM
Comment thread
Maximus5 marked this conversation as resolved.
ec.clear();
auto handle = CreateFileW(oldpath.c_str(),
0, // open just the metadata
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr /* no security attributes */,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr /* no template file */);
if (handle == INVALID_HANDLE_VALUE)
{
ec.assign(GetLastError(), std::system_category());
return oldpath;
}
fs::path target;
const DWORD maxsize = 32768;
const std::unique_ptr<wchar_t[]> buffer(new wchar_t[maxsize]);
const auto rc = GetFinalPathNameByHandleW(handle, buffer.get(), maxsize, 0);
if (rc > 0 && rc < maxsize)
{
target = buffer.get();
}
else
{
ec.assign(GetLastError(), std::system_category());
}
CloseHandle(handle);
return target;
#else // ^^^ defined(_WIN32) && !VCPKG_USE_STD_FILESYSTEM // !defined(_WIN32) || VCPKG_USE_STD_FILESYSTEM vvv
return fs::stdfs::read_symlink(oldpath, ec);
#endif // ^^^ !defined(_WIN32) || VCPKG_USE_STD_FILESYSTEM
}

void copy_symlink_implementation(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec)
{
#if defined(_WIN32) && !VCPKG_USE_STD_FILESYSTEM
const auto target = read_symlink_implementation(oldpath, ec);
if (ec) return;

const DWORD flags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
if (!CreateSymbolicLinkW(newpath.c_str(), target.c_str(), flags))
{
const auto err = GetLastError();
ec.assign(err, std::system_category());
return;
}
ec.clear();
return;
#else // ^^^ defined(_WIN32) && !VCPKG_USE_STD_FILESYSTEM // !defined(_WIN32) || VCPKG_USE_STD_FILESYSTEM vvv
return fs::stdfs::copy_symlink(oldpath, newpath, ec);
#endif // ^^^ !defined(_WIN32) || VCPKG_USE_STD_FILESYSTEM
}

// does _not_ follow symlinks
void set_writeable(const fs::path& path, std::error_code& ec) noexcept
{
Expand Down Expand Up @@ -799,7 +854,7 @@ namespace vcpkg::Files
}
virtual void copy_symlink(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) override
{
return fs::stdfs::copy_symlink(oldpath, newpath, ec);
return Files::copy_symlink_implementation(oldpath, newpath, ec);
}

virtual fs::file_status status(const fs::path& path, std::error_code& ec) const override
Expand Down