//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "lldb/Host/windows/windows.h" #include #include "lldb/Host/FileSystem.h" #include "llvm/Support/FileSystem.h" using namespace lldb_private; FileSpec::PathSyntax FileSystem::GetNativePathSyntax() { return FileSpec::ePathSyntaxWindows; } Error FileSystem::MakeDirectory(const FileSpec &file_spec, uint32_t file_permissions) { // On Win32, the mode parameter is ignored, as Windows files and directories support a // different permission model than POSIX. Error error; const auto err_code = llvm::sys::fs::create_directories(file_spec.GetPath(), true); if (err_code) { error.SetErrorString(err_code.message().c_str()); } return error; } Error FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse) { Error error; if (!recurse) { BOOL result = ::RemoveDirectory(file_spec.GetCString()); if (!result) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); } else { // SHFileOperation() accepts a list of paths, and so must be double-null-terminated to // indicate the end of the list. std::string path_buffer{file_spec.GetPath()}; path_buffer.push_back(0); SHFILEOPSTRUCT shfos = {0}; shfos.wFunc = FO_DELETE; shfos.pFrom = path_buffer.c_str(); shfos.fFlags = FOF_NO_UI; int result = ::SHFileOperation(&shfos); // TODO(zturner): Correctly handle the intricacies of SHFileOperation return values. if (result != 0) error.SetErrorStringWithFormat("SHFileOperation failed"); } return error; } Error FileSystem::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) { Error error; error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); return error; } Error FileSystem::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions) { Error error; error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); return error; } lldb::user_id_t FileSystem::GetFileSize(const FileSpec &file_spec) { return file_spec.GetByteSize(); } bool FileSystem::GetFileExists(const FileSpec &file_spec) { return file_spec.Exists(); } Error FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst) { Error error; if (!::CreateHardLink(src.GetCString(), dst.GetCString(), nullptr)) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; } Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) { Error error; DWORD attrib = ::GetFileAttributes(dst.GetCString()); if (attrib == INVALID_FILE_ATTRIBUTES) { error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; } bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY); DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; BOOL result = ::CreateSymbolicLink(src.GetCString(), dst.GetCString(), flag); if (!result) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; } Error FileSystem::Unlink(const FileSpec &file_spec) { Error error; BOOL result = ::DeleteFile(file_spec.GetCString()); if (!result) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; } Error FileSystem::Readlink(const FileSpec &src, FileSpec &dst) { Error error; HANDLE h = ::CreateFile(src.GetCString(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (h == INVALID_HANDLE_VALUE) { error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; } char buf[PATH_MAX]; // Subtract 1 from the path length since this function does not add a null terminator. DWORD result = ::GetFinalPathNameByHandle(h, buf, sizeof(buf) - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); if (result == 0) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); else dst.SetFile(buf, false); ::CloseHandle(h); return error; } bool FileSystem::IsLocal(const FileSpec &spec) { if (spec) { // TODO: return true if the file is on a locally mounted file system return true; } return false; }