aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaksim Moisiuk <ConEmu.Maximus5@gmail.com>2020-07-16 00:13:54 +0200
committerGitHub <noreply@github.com>2020-07-15 15:13:54 -0700
commit8254d3be9f5f55bafbe3532fca7deb4889b72617 (patch)
treea4146cc1485f28fe8447c50c18e339a53e32d3f6
parent830893fb8eefbc12f5a7f8274bfc2ac79dd85449 (diff)
downloadvcpkg-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.cpp57
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