Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) { Status error; std::wstring wsrc; if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc)) { error.SetErrorString(PATH_CONVERSION_ERROR); return error; } HANDLE h = ::CreateFileW(wsrc.c_str(), 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; } std::vector<wchar_t> buf(PATH_MAX + 1); // Subtract 1 from the path length since this function does not add a null // terminator. DWORD result = ::GetFinalPathNameByHandleW( h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); std::string path; if (result == 0) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); else if (!llvm::convertWideToUTF8(buf.data(), path)) error.SetErrorString(PATH_CONVERSION_ERROR); else dst.SetFile(path, false); ::CloseHandle(h); return error; }
void Socket::SetLastError(Status &error) { #if defined(_WIN32) error.SetError(::WSAGetLastError(), lldb::eErrorTypeWin32); #else error.SetErrorToErrno(); #endif }
Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) { Status error; std::wstring wsrc, wdst; if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) || !llvm::ConvertUTF8toWide(dst.GetCString(), wdst)) error.SetErrorString(PATH_CONVERSION_ERROR); if (error.Fail()) return error; DWORD attrib = ::GetFileAttributesW(wdst.c_str()); 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 = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag); if (!result) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; }
Status PipeWindows::CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit, llvm::SmallVectorImpl<char> &name) { llvm::SmallString<128> pipe_name; Status error; ::UUID unique_id; RPC_CSTR unique_string; RPC_STATUS status = ::UuidCreate(&unique_id); if (status == RPC_S_OK || status == RPC_S_UUID_LOCAL_ONLY) status = ::UuidToStringA(&unique_id, &unique_string); if (status == RPC_S_OK) { pipe_name = prefix; pipe_name += "-"; pipe_name += reinterpret_cast<char *>(unique_string); ::RpcStringFreeA(&unique_string); error = CreateNew(pipe_name, child_process_inherit); } else { error.SetError(status, eErrorTypeWin32); } if (error.Success()) name = pipe_name; return error; }