diff options
Diffstat (limited to 'drivers/windows/dir_access_windows.cpp')
-rw-r--r-- | drivers/windows/dir_access_windows.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 43dd62cdf6..63ba6a6c96 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -396,6 +396,66 @@ bool DirAccessWindows::is_case_sensitive(const String &p_path) const { } } +bool DirAccessWindows::is_link(String p_file) { + String f = p_file; + + if (!f.is_absolute_path()) { + f = get_current_dir().path_join(f); + } + f = fix_path(f); + + DWORD attr = GetFileAttributesW((LPCWSTR)(f.utf16().get_data())); + if (attr == INVALID_FILE_ATTRIBUTES) { + return false; + } + + return (attr & FILE_ATTRIBUTE_REPARSE_POINT); +} + +String DirAccessWindows::read_link(String p_file) { + String f = p_file; + + if (!f.is_absolute_path()) { + f = get_current_dir().path_join(f); + } + f = fix_path(f); + + HANDLE hfile = CreateFileW((LPCWSTR)(f.utf16().get_data()), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + if (hfile == INVALID_HANDLE_VALUE) { + return f; + } + + DWORD ret = GetFinalPathNameByHandleW(hfile, nullptr, 0, VOLUME_NAME_DOS | FILE_NAME_NORMALIZED); + if (ret == 0) { + return f; + } + Char16String cs; + cs.resize(ret + 1); + GetFinalPathNameByHandleW(hfile, (LPWSTR)cs.ptrw(), ret, VOLUME_NAME_DOS | FILE_NAME_NORMALIZED); + CloseHandle(hfile); + + return String::utf16((const char16_t *)cs.ptr(), ret).trim_prefix(R"(\\?\)"); +} + +Error DirAccessWindows::create_link(String p_source, String p_target) { + if (p_target.is_relative_path()) { + p_target = get_current_dir().path_join(p_target); + } + + p_source = fix_path(p_source); + p_target = fix_path(p_target); + + DWORD file_attr = GetFileAttributesW((LPCWSTR)(p_source.utf16().get_data())); + bool is_dir = (file_attr & FILE_ATTRIBUTE_DIRECTORY); + + DWORD flags = ((is_dir) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; + if (CreateSymbolicLinkW((LPCWSTR)p_target.utf16().get_data(), (LPCWSTR)p_source.utf16().get_data(), flags) != 0) { + return OK; + } else { + return FAILED; + } +} + DirAccessWindows::DirAccessWindows() { p = memnew(DirAccessWindowsPrivate); p->h = INVALID_HANDLE_VALUE; |