1 //===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Host/windows/windows.h" 11 12 #include <shellapi.h> 13 14 #include "lldb/Host/FileSystem.h" 15 16 using namespace lldb_private; 17 18 FileSpec::PathSyntax 19 FileSystem::GetNativePathSyntax() 20 { 21 return FileSpec::ePathSyntaxWindows; 22 } 23 24 Error 25 FileSystem::MakeDirectory(const char *path, uint32_t file_permissions) 26 { 27 // On Win32, the mode parameter is ignored, as Windows files and directories support a 28 // different permission model than POSIX. 29 Error error; 30 if (!::CreateDirectory(path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) 31 error.SetError(::GetLastError(), lldb::eErrorTypeWin32); 32 return error; 33 } 34 35 Error 36 FileSystem::DeleteDirectory(const char *path, bool recurse) 37 { 38 Error error; 39 if (!recurse) 40 { 41 BOOL result = ::RemoveDirectory(path); 42 if (!result) 43 error.SetError(::GetLastError(), lldb::eErrorTypeWin32); 44 } 45 else 46 { 47 // SHFileOperation() accepts a list of paths, and so must be double-null-terminated to 48 // indicate the end of the list. 49 std::string path_buffer(path); 50 path_buffer.push_back(0); 51 52 SHFILEOPSTRUCT shfos = {0}; 53 shfos.wFunc = FO_DELETE; 54 shfos.pFrom = path_buffer.c_str(); 55 shfos.fFlags = FOF_NO_UI; 56 57 int result = ::SHFileOperation(&shfos); 58 // TODO(zturner): Correctly handle the intricacies of SHFileOperation return values. 59 if (result != 0) 60 error.SetErrorStringWithFormat("SHFileOperation failed"); 61 } 62 return error; 63 } 64 65 Error 66 FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions) 67 { 68 Error error; 69 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 70 return error; 71 } 72 73 Error 74 FileSystem::SetFilePermissions(const char *path, uint32_t file_permissions) 75 { 76 Error error; 77 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 78 return error; 79 } 80 81 lldb::user_id_t 82 FileSystem::GetFileSize(const FileSpec &file_spec) 83 { 84 return file_spec.GetByteSize(); 85 } 86 87 bool 88 FileSystem::GetFileExists(const FileSpec &file_spec) 89 { 90 return file_spec.Exists(); 91 } 92 93 Error 94 FileSystem::Symlink(const char *linkname, const char *target) 95 { 96 Error error; 97 DWORD attrib = ::GetFileAttributes(target); 98 if (attrib == INVALID_FILE_ATTRIBUTES) 99 { 100 error.SetError(::GetLastError(), lldb::eErrorTypeWin32); 101 return error; 102 } 103 bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY); 104 DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; 105 BOOL result = ::CreateSymbolicLink(linkname, target, flag); 106 if (!result) 107 error.SetError(::GetLastError(), lldb::eErrorTypeWin32); 108 return error; 109 } 110 111 Error 112 FileSystem::Unlink(const char *path) 113 { 114 Error error; 115 BOOL result = ::DeleteFile(path); 116 if (!result) 117 error.SetError(::GetLastError(), lldb::eErrorTypeWin32); 118 return error; 119 } 120 121 Error 122 FileSystem::Readlink(const char *path, char *buf, size_t buf_len) 123 { 124 Error error; 125 HANDLE h = ::CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 126 FILE_FLAG_OPEN_REPARSE_POINT, NULL); 127 if (h == INVALID_HANDLE_VALUE) 128 { 129 error.SetError(::GetLastError(), lldb::eErrorTypeWin32); 130 return error; 131 } 132 133 // Subtract 1 from the path length since this function does not add a null terminator. 134 DWORD result = ::GetFinalPathNameByHandle(h, buf, buf_len - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 135 if (result == 0) 136 error.SetError(::GetLastError(), lldb::eErrorTypeWin32); 137 138 ::CloseHandle(h); 139 return error; 140 } 141 142 bool 143 FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high) 144 { 145 return false; 146 } 147