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