forked from premiere/premiere-libtorrent
move LoadLibrary logic to new win_util module (#1464)
move LoadLibrary logic to new win_util module. use get_library_procedure as common windows dyn proc load routine
This commit is contained in:
parent
08aab3a879
commit
e10edb5e0b
|
@ -184,6 +184,7 @@ nobase_include_HEADERS = \
|
|||
aux_/has_block.hpp \
|
||||
aux_/scope_end.hpp \
|
||||
aux_/vector.hpp \
|
||||
aux_/win_util.hpp \
|
||||
\
|
||||
extensions/smart_ban.hpp \
|
||||
extensions/ut_metadata.hpp \
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2016, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_WIN_UTIL_HPP
|
||||
#define TORRENT_WIN_UTIL_HPP
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
|
||||
namespace libtorrent { namespace aux
|
||||
{
|
||||
template <typename Library>
|
||||
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 <typename Library, typename Signature>
|
||||
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<Library>();
|
||||
if (handle) proc = (Signature)GetProcAddress(handle, name);
|
||||
failed_proc = (proc == nullptr);
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
|
||||
struct iphlpapi {
|
||||
static constexpr char const* library_name = "iphlpapi.dll";
|
||||
};
|
||||
|
||||
struct kernel32 {
|
||||
static constexpr char const* library_name = "kernel32.dll";
|
||||
};
|
||||
|
||||
struct advapi32 {
|
||||
static constexpr char const* library_name = "advapi32.dll";
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
} // namespace libtorrent
|
||||
|
||||
#endif
|
||||
|
|
@ -35,6 +35,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/broadcast_socket.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/socket_type.hpp"
|
||||
#ifdef TORRENT_WINDOWS
|
||||
#include "libtorrent/aux_/win_util.hpp"
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
#include <cstdlib> // for wcstombscstombs
|
||||
|
@ -385,41 +388,6 @@ namespace libtorrent
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
struct iphlpapi {
|
||||
static constexpr char const* library_name = "iphlpapi.dll";
|
||||
};
|
||||
|
||||
template <typename Library>
|
||||
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 <typename Library, typename Signature>
|
||||
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<Library>();
|
||||
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)
|
||||
{
|
||||
|
@ -628,7 +596,7 @@ namespace libtorrent
|
|||
typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
|
||||
// Get GetAdaptersAddresses() pointer
|
||||
auto GetAdaptersAddresses =
|
||||
get_library_procedure<iphlpapi, GetAdaptersAddresses_t>("GetAdaptersAddresses");
|
||||
aux::get_library_procedure<aux::iphlpapi, GetAdaptersAddresses_t>("GetAdaptersAddresses");
|
||||
|
||||
if (GetAdaptersAddresses != nullptr)
|
||||
{
|
||||
|
@ -988,7 +956,7 @@ namespace libtorrent
|
|||
*/
|
||||
|
||||
typedef DWORD (WINAPI *GetIfEntry_t)(PMIB_IFROW pIfRow);
|
||||
auto GetIfEntry = get_library_procedure<iphlpapi, GetIfEntry_t>("GetIfEntry");
|
||||
auto GetIfEntry = aux::get_library_procedure<aux::iphlpapi, GetIfEntry_t>("GetIfEntry");
|
||||
|
||||
if (GetIfEntry == nullptr)
|
||||
{
|
||||
|
@ -1001,8 +969,8 @@ namespace libtorrent
|
|||
ADDRESS_FAMILY, PMIB_IPFORWARD_TABLE2*);
|
||||
typedef void (WINAPI *FreeMibTable_t)(PVOID Memory);
|
||||
|
||||
auto GetIpForwardTable2 = get_library_procedure<iphlpapi, GetIpForwardTable2_t>("GetIpForwardTable2");
|
||||
auto FreeMibTable = get_library_procedure<iphlpapi, FreeMibTable_t>("FreeMibTable");
|
||||
auto GetIpForwardTable2 = aux::get_library_procedure<aux::iphlpapi, GetIpForwardTable2_t>("GetIpForwardTable2");
|
||||
auto FreeMibTable = aux::get_library_procedure<aux::iphlpapi, FreeMibTable_t>("FreeMibTable");
|
||||
if (GetIpForwardTable2 != nullptr && FreeMibTable != nullptr)
|
||||
{
|
||||
MIB_IPFORWARD_TABLE2* routes = nullptr;
|
||||
|
@ -1035,7 +1003,7 @@ namespace libtorrent
|
|||
// Get GetIpForwardTable() pointer
|
||||
typedef DWORD (WINAPI *GetIpForwardTable_t)(PMIB_IPFORWARDTABLE pIpForwardTable,PULONG pdwSize,BOOL bOrder);
|
||||
|
||||
auto GetIpForwardTable = get_library_procedure<iphlpapi, GetIpForwardTable_t>("GetIpForwardTable");
|
||||
auto GetIpForwardTable = aux::get_library_procedure<aux::iphlpapi, GetIpForwardTable_t>("GetIpForwardTable");
|
||||
if (GetIpForwardTable == nullptr)
|
||||
{
|
||||
ec = boost::asio::error::operation_not_supported;
|
||||
|
|
84
src/file.cpp
84
src/file.cpp
|
@ -99,6 +99,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#endif
|
||||
|
||||
#include "libtorrent/utf8.hpp"
|
||||
#include "libtorrent/aux_/win_util.hpp"
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
@ -1976,38 +1977,23 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
PTOKEN_PRIVILEGES PreviousState,
|
||||
PDWORD ReturnLength);
|
||||
|
||||
static OpenProcessToken_t pOpenProcessToken = nullptr;
|
||||
static LookupPrivilegeValue_t pLookupPrivilegeValue = nullptr;
|
||||
static AdjustTokenPrivileges_t pAdjustTokenPrivileges = nullptr;
|
||||
static bool failed_advapi = false;
|
||||
auto OpenProcessToken =
|
||||
aux::get_library_procedure<aux::advapi32, OpenProcessToken_t>("OpenProcessToken");
|
||||
auto LookupPrivilegeValue =
|
||||
aux::get_library_procedure<aux::advapi32, LookupPrivilegeValue_t>("LookupPrivilegeValueA");
|
||||
auto AdjustTokenPrivileges =
|
||||
aux::get_library_procedure<aux::advapi32, AdjustTokenPrivileges_t>("AdjustTokenPrivileges");
|
||||
|
||||
if (OpenProcessToken == nullptr || LookupPrivilegeValue == nullptr || AdjustTokenPrivileges == nullptr) return false;
|
||||
|
||||
if (pOpenProcessToken == nullptr && !failed_advapi)
|
||||
{
|
||||
HMODULE advapi = LoadLibraryA("advapi32");
|
||||
if (advapi == nullptr)
|
||||
{
|
||||
failed_advapi = true;
|
||||
return false;
|
||||
}
|
||||
pOpenProcessToken = (OpenProcessToken_t)GetProcAddress(advapi, "OpenProcessToken");
|
||||
pLookupPrivilegeValue = (LookupPrivilegeValue_t)GetProcAddress(advapi, "LookupPrivilegeValueA");
|
||||
pAdjustTokenPrivileges = (AdjustTokenPrivileges_t)GetProcAddress(advapi, "AdjustTokenPrivileges");
|
||||
if (pOpenProcessToken == nullptr
|
||||
|| pLookupPrivilegeValue == nullptr
|
||||
|| pAdjustTokenPrivileges == nullptr)
|
||||
{
|
||||
failed_advapi = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE token;
|
||||
if (!pOpenProcessToken(GetCurrentProcess()
|
||||
if (!OpenProcessToken(GetCurrentProcess()
|
||||
, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
|
||||
return false;
|
||||
|
||||
TOKEN_PRIVILEGES privs;
|
||||
if (!pLookupPrivilegeValue(nullptr, "SeManageVolumePrivilege"
|
||||
if (!LookupPrivilegeValue(nullptr, "SeManageVolumePrivilege"
|
||||
, &privs.Privileges[0].Luid))
|
||||
{
|
||||
CloseHandle(token);
|
||||
|
@ -2017,7 +2003,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
privs.PrivilegeCount = 1;
|
||||
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
bool ret = pAdjustTokenPrivileges(token, FALSE, &privs, 0, nullptr, nullptr)
|
||||
bool ret = AdjustTokenPrivileges(token, FALSE, &privs, 0, nullptr, nullptr)
|
||||
&& GetLastError() == ERROR_SUCCESS;
|
||||
|
||||
CloseHandle(token);
|
||||
|
@ -2028,30 +2014,14 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
void set_file_valid_data(HANDLE f, std::int64_t size)
|
||||
{
|
||||
typedef BOOL (WINAPI *SetFileValidData_t)(HANDLE, LONGLONG);
|
||||
static SetFileValidData_t pSetFileValidData = nullptr;
|
||||
static bool failed_kernel32 = false;
|
||||
auto SetFileValidData =
|
||||
aux::get_library_procedure<aux::kernel32, SetFileValidData_t>("SetFileValidData");
|
||||
|
||||
if (pSetFileValidData == nullptr && !failed_kernel32)
|
||||
{
|
||||
HMODULE k32 = LoadLibraryA("kernel32");
|
||||
if (k32 == nullptr)
|
||||
{
|
||||
failed_kernel32 = true;
|
||||
return;
|
||||
}
|
||||
pSetFileValidData = (SetFileValidData_t)GetProcAddress(k32, "SetFileValidData");
|
||||
if (pSetFileValidData == nullptr)
|
||||
{
|
||||
failed_kernel32 = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(pSetFileValidData);
|
||||
if (SetFileValidData == nullptr) return;
|
||||
|
||||
// we don't necessarily expect to have enough
|
||||
// privilege to do this, so ignore errors.
|
||||
pSetFileValidData(f, size);
|
||||
SetFileValidData(f, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2095,30 +2065,16 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
, LPVOID lpFileInformation
|
||||
, DWORD dwBufferSize);
|
||||
|
||||
static GetFileInformationByHandleEx_t GetFileInformationByHandleEx_ = nullptr;
|
||||
|
||||
static bool failed_kernel32 = false;
|
||||
|
||||
if ((GetFileInformationByHandleEx_ == nullptr) && !failed_kernel32)
|
||||
{
|
||||
HMODULE kernel32 = LoadLibraryA("kernel32.dll");
|
||||
if (kernel32)
|
||||
{
|
||||
GetFileInformationByHandleEx_ = (GetFileInformationByHandleEx_t)GetProcAddress(kernel32, "GetFileInformationByHandleEx");
|
||||
}
|
||||
else
|
||||
{
|
||||
failed_kernel32 = true;
|
||||
}
|
||||
}
|
||||
auto GetFileInformationByHandleEx =
|
||||
aux::get_library_procedure<aux::kernel32, GetFileInformationByHandleEx_t>("GetFileInformationByHandleEx");
|
||||
|
||||
offs.QuadPart = 0;
|
||||
if (GetFileInformationByHandleEx_)
|
||||
if (GetFileInformationByHandleEx != nullptr)
|
||||
{
|
||||
// only allocate the space if the file
|
||||
// is not fully allocated
|
||||
FILE_STANDARD_INFO inf;
|
||||
if (GetFileInformationByHandleEx_(native_handle()
|
||||
if (GetFileInformationByHandleEx(native_handle()
|
||||
, FileStandardInfo, &inf, sizeof(inf)) == FALSE)
|
||||
{
|
||||
ec.assign(GetLastError(), system_category());
|
||||
|
|
|
@ -37,6 +37,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/file_storage.hpp"
|
||||
#include "libtorrent/units.hpp"
|
||||
#ifdef TORRENT_WINDOWS
|
||||
#include "libtorrent/aux_/win_util.hpp"
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
@ -85,30 +88,10 @@ namespace libtorrent
|
|||
} FILE_IO_PRIORITY_HINT_INFO_LOCAL;
|
||||
|
||||
typedef BOOL (WINAPI *SetFileInformationByHandle_t)(HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS_LOCAL FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize);
|
||||
static SetFileInformationByHandle_t SetFileInformationByHandle = nullptr;
|
||||
auto SetFileInformationByHandle =
|
||||
aux::get_library_procedure<aux::kernel32, SetFileInformationByHandle_t>("SetFileInformationByHandle");
|
||||
|
||||
static bool failed_kernel_load = false;
|
||||
|
||||
if (failed_kernel_load) return;
|
||||
|
||||
if (SetFileInformationByHandle == nullptr)
|
||||
{
|
||||
HMODULE kernel32 = LoadLibraryA("kernel32.dll");
|
||||
if (kernel32 == nullptr)
|
||||
{
|
||||
failed_kernel_load = true;
|
||||
return;
|
||||
}
|
||||
|
||||
SetFileInformationByHandle = (SetFileInformationByHandle_t)GetProcAddress(kernel32, "SetFileInformationByHandle");
|
||||
if (SetFileInformationByHandle == nullptr)
|
||||
{
|
||||
failed_kernel_load = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(SetFileInformationByHandle);
|
||||
if (SetFileInformationByHandle == nullptr) return;
|
||||
|
||||
FILE_IO_PRIORITY_HINT_INFO_LOCAL io_hint;
|
||||
io_hint.PriorityHint = IoPriorityHintLow;
|
||||
|
|
Loading…
Reference in New Issue