diff options
| author | Maksim Moisiuk <ConEmu.Maximus5@gmail.com> | 2020-07-16 00:13:54 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-15 15:13:54 -0700 |
| commit | 8254d3be9f5f55bafbe3532fca7deb4889b72617 (patch) | |
| tree | a4146cc1485f28fe8447c50c18e339a53e32d3f6 | |
| parent | 830893fb8eefbc12f5a7f8274bfc2ac79dd85449 (diff) | |
| download | vcpkg-8254d3be9f5f55bafbe3532fca7deb4889b72617.tar.gz vcpkg-8254d3be9f5f55bafbe3532fca7deb4889b72617.zip | |
[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>
| -rw-r--r-- | toolsrc/src/vcpkg/base/files.cpp | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 4e3531c22..704f5c24f 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -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 |
