mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-12-28 03:10:57 +08:00
[vcpkg] implement copy_symlink working for non-elevated processes (#12400)
* [vcpkg] implement copy_symlink working for non-elevated processes * [vcpkg] read_symlink Windows implementation * [vcpkg] normalize_path on Windows only * Update toolsrc/src/vcpkg/base/files.cpp Co-authored-by: nicole mazzuca <mazzucan@outlook.com> * Update toolsrc/src/vcpkg/base/files.cpp Co-authored-by: nicole mazzuca <mazzucan@outlook.com> * Update toolsrc/src/vcpkg/base/files.cpp Co-authored-by: nicole mazzuca <mazzucan@outlook.com> * remove normalization * Update toolsrc/src/vcpkg/base/files.cpp Co-authored-by: nicole mazzuca <mazzucan@outlook.com> * Update toolsrc/src/vcpkg/base/files.cpp Co-authored-by: nicole mazzuca <mazzucan@outlook.com> * Update toolsrc/src/vcpkg/base/files.cpp Co-authored-by: nicole mazzuca <mazzucan@outlook.com> * Update toolsrc/src/vcpkg/base/files.cpp Co-authored-by: nicole mazzuca <mazzucan@outlook.com> * Update toolsrc/src/vcpkg/base/files.cpp Co-authored-by: nicole mazzuca <mazzucan@outlook.com> * use unique_ptr * comments Co-authored-by: nicole mazzuca <mazzucan@outlook.com>
This commit is contained in:
parent
830893fb8e
commit
8254d3be9f
@ -102,6 +102,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
|
||||
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
|
||||
{
|
||||
@ -800,7 +855,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
|
||||
|
Loading…
x
Reference in New Issue
Block a user