diff --git a/include/libtorrent/file.hpp b/include/libtorrent/file.hpp index 9a37d4561..2612b8c5a 100644 --- a/include/libtorrent/file.hpp +++ b/include/libtorrent/file.hpp @@ -146,7 +146,8 @@ namespace libtorrent TORRENT_EXTRA_EXPORT void hard_link(std::string const& file , std::string const& link, error_code& ec); - TORRENT_EXTRA_EXPORT std::string split_path(std::string const& f); + TORRENT_EXTRA_EXPORT std::string split_path(std::string const& f + , bool only_first_part = false); TORRENT_EXTRA_EXPORT char const* next_path_element(char const* p); TORRENT_EXTRA_EXPORT std::string extension(std::string const& f); TORRENT_EXTRA_EXPORT std::string remove_extension(std::string const& f); diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index f49af2e04..d8e77330a 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -173,6 +173,7 @@ namespace libtorrent if (m_lock) m_lock->lock(); m_lock = rhs.m_lock; rhs.m_lock = nullptr; + return *this; } private: Lock* m_lock; diff --git a/src/enum_net.cpp b/src/enum_net.cpp index 6ba8d9160..f9c790431 100644 --- a/src/enum_net.cpp +++ b/src/enum_net.cpp @@ -385,6 +385,41 @@ namespace libtorrent return false; } +#ifdef TORRENT_WINDOWS + struct iphlpapi { + static constexpr char const* library_name = "iphlpapi.dll"; + }; + + template + HMODULE get_library_handle() + { + static bool handle_checked = false; + static HMODULE handle = 0; + + if (!handle_checked) + { + handle = LoadLibraryA(Library::library_name); + handle_checked = true; + } + return handle; + } + + template + Signature get_library_procedure(LPCSTR name) + { + static Signature proc = nullptr; + static bool failed_proc = false; + + if ((proc == nullptr) && !failed_proc) + { + HMODULE const handle = get_library_handle(); + if (handle) proc = (Signature)GetProcAddress(handle, name); + failed_proc = (proc == nullptr); + } + return proc; + } +#endif + #if TORRENT_USE_GETIPFORWARDTABLE address build_netmask(int bits, int family) { @@ -590,22 +625,13 @@ namespace libtorrent #elif TORRENT_USE_GETADAPTERSADDRESSES #if _WIN32_WINNT >= 0x0501 - // Load Iphlpapi library - HMODULE iphlp = LoadLibraryA("Iphlpapi.dll"); - if (iphlp) + typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG); + // Get GetAdaptersAddresses() pointer + auto GetAdaptersAddresses = + get_library_procedure("GetAdaptersAddresses"); + + if (GetAdaptersAddresses != nullptr) { - // Get GetAdaptersAddresses() pointer - typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG); - GetAdaptersAddresses_t GetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress( - iphlp, "GetAdaptersAddresses"); - - if (GetAdaptersAddresses == nullptr) - { - FreeLibrary(iphlp); - ec = error_code(boost::system::errc::not_supported, generic_category()); - return std::vector(); - } - ULONG buf_size = 10000; std::vector buffer(buf_size); PIP_ADAPTER_ADDRESSES adapter_addresses @@ -622,7 +648,6 @@ namespace libtorrent } if (res != NO_ERROR) { - FreeLibrary(iphlp); ec = error_code(WSAGetLastError(), system_category()); return std::vector(); } @@ -645,8 +670,6 @@ namespace libtorrent } } - // Free memory - FreeLibrary(iphlp); return ret; } #endif @@ -915,20 +938,11 @@ namespace libtorrent #elif TORRENT_USE_GETIPFORWARDTABLE /* move this to enum_net_interfaces - // Load Iphlpapi library - HMODULE iphlp = LoadLibraryA("Iphlpapi.dll"); - if (!iphlp) - { - ec = boost::asio::error::operation_not_supported; - return std::vector(); - } - // Get GetAdaptersInfo() pointer typedef DWORD (WINAPI *GetAdaptersInfo_t)(PIP_ADAPTER_INFO, PULONG); - GetAdaptersInfo_t GetAdaptersInfo = (GetAdaptersInfo_t)GetProcAddress(iphlp, "GetAdaptersInfo"); - if (!GetAdaptersInfo) + GetAdaptersInfo_t GetAdaptersInfo = get_library_procedure("GetAdaptersInfo"); + if (GetAdaptersInfo == nullptr) { - FreeLibrary(iphlp); ec = boost::asio::error::operation_not_supported; return std::vector(); } @@ -937,7 +951,6 @@ namespace libtorrent ULONG out_buf_size = 0; if (GetAdaptersInfo(adapter_info, &out_buf_size) != ERROR_BUFFER_OVERFLOW) { - FreeLibrary(iphlp); ec = boost::asio::error::operation_not_supported; return std::vector(); } @@ -945,7 +958,6 @@ namespace libtorrent adapter_info = (IP_ADAPTER_INFO*)malloc(out_buf_size); if (!adapter_info) { - FreeLibrary(iphlp); ec = boost::asio::error::no_memory; return std::vector(); } @@ -973,20 +985,12 @@ namespace libtorrent // Free memory free(adapter_info); - FreeLibrary(iphlp); */ - // Load Iphlpapi library - HMODULE iphlp = LoadLibraryA("Iphlpapi.dll"); - if (!iphlp) - { - ec = boost::asio::error::operation_not_supported; - return std::vector(); - } - typedef DWORD (WINAPI *GetIfEntry_t)(PMIB_IFROW pIfRow); - GetIfEntry_t GetIfEntry = (GetIfEntry_t)GetProcAddress(iphlp, "GetIfEntry"); - if (!GetIfEntry) + auto GetIfEntry = get_library_procedure("GetIfEntry"); + + if (GetIfEntry == nullptr) { ec = boost::asio::error::operation_not_supported; return std::vector(); @@ -997,11 +1001,9 @@ namespace libtorrent ADDRESS_FAMILY, PMIB_IPFORWARD_TABLE2*); typedef void (WINAPI *FreeMibTable_t)(PVOID Memory); - GetIpForwardTable2_t GetIpForwardTable2 = (GetIpForwardTable2_t)GetProcAddress( - iphlp, "GetIpForwardTable2"); - FreeMibTable_t FreeMibTable = (FreeMibTable_t)GetProcAddress( - iphlp, "FreeMibTable"); - if (GetIpForwardTable2 && FreeMibTable) + auto GetIpForwardTable2 = get_library_procedure("GetIpForwardTable2"); + auto FreeMibTable = get_library_procedure("FreeMibTable"); + if (GetIpForwardTable2 != nullptr && FreeMibTable != nullptr) { MIB_IPFORWARD_TABLE2* routes = nullptr; int res = GetIpForwardTable2(AF_UNSPEC, &routes); @@ -1026,7 +1028,6 @@ namespace libtorrent } } if (routes) FreeMibTable(routes); - FreeLibrary(iphlp); return ret; } #endif @@ -1034,11 +1035,9 @@ namespace libtorrent // Get GetIpForwardTable() pointer typedef DWORD (WINAPI *GetIpForwardTable_t)(PMIB_IPFORWARDTABLE pIpForwardTable,PULONG pdwSize,BOOL bOrder); - GetIpForwardTable_t GetIpForwardTable = (GetIpForwardTable_t)GetProcAddress( - iphlp, "GetIpForwardTable"); - if (!GetIpForwardTable) + auto GetIpForwardTable = get_library_procedure("GetIpForwardTable"); + if (GetIpForwardTable == nullptr) { - FreeLibrary(iphlp); ec = boost::asio::error::operation_not_supported; return std::vector(); } @@ -1047,7 +1046,6 @@ namespace libtorrent ULONG out_buf_size = 0; if (GetIpForwardTable(routes, &out_buf_size, FALSE) != ERROR_INSUFFICIENT_BUFFER) { - FreeLibrary(iphlp); ec = boost::asio::error::operation_not_supported; return std::vector(); } @@ -1055,7 +1053,6 @@ namespace libtorrent routes = (MIB_IPFORWARDTABLE*)malloc(out_buf_size); if (!routes) { - FreeLibrary(iphlp); ec = boost::asio::error::no_memory; return std::vector(); } @@ -1082,7 +1079,6 @@ namespace libtorrent // Free memory free(routes); - FreeLibrary(iphlp); #elif TORRENT_USE_NETLINK enum { BUFSIZE = 8192 }; diff --git a/src/file.cpp b/src/file.cpp index 0640a28e0..e661c7c91 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -720,7 +720,7 @@ namespace libtorrent } } - std::string split_path(std::string const& f) + std::string split_path(std::string const& f, bool only_first_part) { if (f.empty()) return f; @@ -738,11 +738,13 @@ namespace libtorrent if (p - start > 0) { ret.append(start, p - start); + if (only_first_part) return ret; ret.append(1, '\0'); } if (*p != 0) ++p; start = p; } + if (only_first_part) return ret; ret.append(1, '\0'); return ret; } diff --git a/src/file_storage.cpp b/src/file_storage.cpp index 865b1c4e5..fe2dbbfe2 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -563,7 +563,7 @@ namespace libtorrent else { if (m_files.empty()) - m_name = split_path(path).c_str(); + m_name = split_path(path, true); } // this is poor-man's emplace_back() diff --git a/src/storage.cpp b/src/storage.cpp index d6d3c5a6d..5b57b9040 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -834,8 +834,9 @@ namespace libtorrent , storage_error& ec) { file_storage const& fs = files(); - -#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS +#ifdef TORRENT_DISABLE_MUTABLE_TORRENTS + TORRENT_UNUSED(links); +#else if (!links.empty()) { TORRENT_ASSERT(int(links.size()) == fs.num_files()); diff --git a/src/utp_socket_manager.cpp b/src/utp_socket_manager.cpp index 3cc60588d..db5b357ee 100644 --- a/src/utp_socket_manager.cpp +++ b/src/utp_socket_manager.cpp @@ -161,7 +161,7 @@ namespace libtorrent { // UTP_LOGV("incoming packet size:%d\n", size); - if (p.size() < int(sizeof(utp_header))) return false; + if (p.size() < sizeof(utp_header)) return false; utp_header const* ph = reinterpret_cast(p.data()); diff --git a/src/utp_stream.cpp b/src/utp_stream.cpp index bbbe07bd2..98a9730a2 100644 --- a/src/utp_stream.cpp +++ b/src/utp_stream.cpp @@ -712,8 +712,7 @@ bool utp_incoming_packet(utp_socket_impl* s , span p , udp::endpoint const& ep, time_point receive_time) { - return s->incoming_packet( - span(reinterpret_cast(p.data()), int(p.size())) + return s->incoming_packet({reinterpret_cast(p.data()), p.size()} , ep, receive_time); }