improve support for windows XP and earlier
This commit is contained in:
parent
640f3e1f2d
commit
3788ed23ca
|
@ -1,3 +1,4 @@
|
||||||
|
* improve support for windows XP and earlier
|
||||||
* introduce global connection priority for improved swarm performance
|
* introduce global connection priority for improved swarm performance
|
||||||
* make files deleted alert non-discardable
|
* make files deleted alert non-discardable
|
||||||
* make built-in sha functions not conflict with libcrypto
|
* make built-in sha functions not conflict with libcrypto
|
||||||
|
|
56
src/file.cpp
56
src/file.cpp
|
@ -1813,25 +1813,53 @@ namespace libtorrent
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if _WIN32_WINNT >= 0x501
|
|
||||||
if ((m_open_mode & sparse) == 0)
|
if ((m_open_mode & sparse) == 0)
|
||||||
{
|
{
|
||||||
// only allocate the space if the file
|
typedef DWORD (WINAPI *GetCompressedFileSizeW_t)(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh);
|
||||||
// is not fully allocated
|
typedef BOOL (WINAPI *SetFileValidData_t)(HANDLE hFile, LONGLONG ValidDataLength);
|
||||||
DWORD high_dword = 0;
|
|
||||||
offs.LowPart = GetCompressedFileSize(m_path.c_str(), &high_dword);
|
static GetCompressedFileSizeW_t GetCompressedFileSizeW = NULL;
|
||||||
offs.HighPart = high_dword;
|
static SetFileValidData_t SetFileValidData = NULL;
|
||||||
ec.assign(GetLastError(), get_system_category());
|
|
||||||
if (ec) return false;
|
static bool failed_kernel32 = false;
|
||||||
if (offs.QuadPart != s)
|
|
||||||
|
if ((GetCompressedFileSizeW == NULL) && !failed_kernel32)
|
||||||
{
|
{
|
||||||
// if the user has permissions, avoid filling
|
HMODULE kernel32 = LoadLibraryA("kernel32.dll");
|
||||||
// the file with zeroes, but just fill it with
|
if (kernel32)
|
||||||
// garbage instead
|
{
|
||||||
SetFileValidData(m_file_handle, offs.QuadPart);
|
GetCompressedFileSizeW = (GetCompressedFileSizeW_t)GetProcAddress(kernel32, "GetCompressedFileSizeW");
|
||||||
|
SetFileValidData = (SetFileValidData_t)GetProcAddress(kernel32, "SetFileValidData");
|
||||||
|
if ((GetCompressedFileSizeW == NULL) || (SetFileValidData == NULL))
|
||||||
|
{
|
||||||
|
failed_kernel32 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
failed_kernel32 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failed_kernel32 && GetCompressedFileSizeW && SetFileValidData)
|
||||||
|
{
|
||||||
|
// only allocate the space if the file
|
||||||
|
// is not fully allocated
|
||||||
|
DWORD high_dword = 0;
|
||||||
|
offs.LowPart = GetCompressedFileSize(m_path.c_str(), &high_dword);
|
||||||
|
offs.HighPart = high_dword;
|
||||||
|
ec.assign(GetLastError(), get_system_category());
|
||||||
|
if (ec) return false;
|
||||||
|
if (offs.QuadPart != s)
|
||||||
|
{
|
||||||
|
// if the user has permissions, avoid filling
|
||||||
|
// the file with zeroes, but just fill it with
|
||||||
|
// garbage instead
|
||||||
|
SetFileValidData(m_file_handle, offs.QuadPart);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // _WIN32_WINNT >= 0x501
|
|
||||||
#else // NON-WINDOWS
|
#else // NON-WINDOWS
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(m_fd, &st) != 0)
|
if (fstat(m_fd, &st) != 0)
|
||||||
|
|
|
@ -101,6 +101,73 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TORRENT_WINDOWS
|
||||||
|
void set_low_priority(boost::intrusive_ptr<file> const& f)
|
||||||
|
{
|
||||||
|
// file prio is only supported on vista and up
|
||||||
|
// so load the functions dynamically
|
||||||
|
typedef enum _FILE_INFO_BY_HANDLE_CLASS {
|
||||||
|
FileBasicInfo,
|
||||||
|
FileStandardInfo,
|
||||||
|
FileNameInfo,
|
||||||
|
FileRenameInfo,
|
||||||
|
FileDispositionInfo,
|
||||||
|
FileAllocationInfo,
|
||||||
|
FileEndOfFileInfo,
|
||||||
|
FileStreamInfo,
|
||||||
|
FileCompressionInfo,
|
||||||
|
FileAttributeTagInfo,
|
||||||
|
FileIdBothDirectoryInfo,
|
||||||
|
FileIdBothDirectoryRestartInfo,
|
||||||
|
FileIoPriorityHintInfo,
|
||||||
|
FileRemoteProtocolInfo,
|
||||||
|
MaximumFileInfoByHandleClass
|
||||||
|
} FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS;
|
||||||
|
|
||||||
|
typedef enum _PRIORITY_HINT {
|
||||||
|
IoPriorityHintVeryLow = 0,
|
||||||
|
IoPriorityHintLow,
|
||||||
|
IoPriorityHintNormal,
|
||||||
|
MaximumIoPriorityHintType
|
||||||
|
} PRIORITY_HINT;
|
||||||
|
|
||||||
|
typedef struct _FILE_IO_PRIORITY_HINT_INFO {
|
||||||
|
PRIORITY_HINT PriorityHint;
|
||||||
|
} FILE_IO_PRIORITY_HINT_INFO, *PFILE_IO_PRIORITY_HINT_INFO;
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *SetFileInformationByHandle_t)(HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize);
|
||||||
|
static SetFileInformationByHandle_t SetFileInformationByHandle = NULL;
|
||||||
|
|
||||||
|
static bool failed_kernel_load = false;
|
||||||
|
|
||||||
|
if (failed_kernel_load) return;
|
||||||
|
|
||||||
|
if (SetFileInformationByHandle == NULL)
|
||||||
|
{
|
||||||
|
HMODULE kernel32 = LoadLibraryA("kernel32.dll");
|
||||||
|
if (kernel32 == NULL)
|
||||||
|
{
|
||||||
|
failed_kernel_load = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFileInformationByHandle = (SetFileInformationByHandle_t)GetProcAddress(kernel32, "SetFileInformationByHandle");
|
||||||
|
if (SetFileInformationByHandle == NULL)
|
||||||
|
{
|
||||||
|
failed_kernel_load = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_ASSERT(SetFileInformationByHandle);
|
||||||
|
|
||||||
|
FILE_IO_PRIORITY_HINT_INFO io_hint;
|
||||||
|
io_hint.PriorityHint = IoPriorityHintLow;
|
||||||
|
SetFileInformationByHandle(f->native_handle(),
|
||||||
|
FileIoPriorityHintInfo, &io_hint, sizeof(io_hint));
|
||||||
|
}
|
||||||
|
#endif // TORRENT_WINDOWS
|
||||||
|
|
||||||
boost::intrusive_ptr<file> file_pool::open_file(void* st, std::string const& p
|
boost::intrusive_ptr<file> file_pool::open_file(void* st, std::string const& p
|
||||||
, file_storage::iterator fe, file_storage const& fs, int m, error_code& ec)
|
, file_storage::iterator fe, file_storage const& fs, int m, error_code& ec)
|
||||||
{
|
{
|
||||||
|
@ -154,17 +221,8 @@ namespace libtorrent
|
||||||
return boost::intrusive_ptr<file>();
|
return boost::intrusive_ptr<file>();
|
||||||
}
|
}
|
||||||
#ifdef TORRENT_WINDOWS
|
#ifdef TORRENT_WINDOWS
|
||||||
// file prio is supported on vista and up
|
|
||||||
#if _WIN32_WINNT >= 0x0600
|
|
||||||
if (m_low_prio_io)
|
if (m_low_prio_io)
|
||||||
{
|
set_low_priority(e.file_ptr);
|
||||||
// TODO: load this function dynamically from Kernel32.dll
|
|
||||||
FILE_IO_PRIORITY_HINT_INFO priorityHint;
|
|
||||||
priorityHint.PriorityHint = IoPriorityHintLow;
|
|
||||||
SetFileInformationByHandle(e.file_ptr->native_handle(),
|
|
||||||
FileIoPriorityHintInfo, &priorityHint, sizeof(priorityHint));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
TORRENT_ASSERT(e.file_ptr->is_open());
|
TORRENT_ASSERT(e.file_ptr->is_open());
|
||||||
e.mode = m;
|
e.mode = m;
|
||||||
|
@ -189,6 +247,10 @@ namespace libtorrent
|
||||||
std::string full_path = combine_path(p, fs.file_path(*fe));
|
std::string full_path = combine_path(p, fs.file_path(*fe));
|
||||||
if (!e.file_ptr->open(full_path, m, ec))
|
if (!e.file_ptr->open(full_path, m, ec))
|
||||||
return boost::intrusive_ptr<file>();
|
return boost::intrusive_ptr<file>();
|
||||||
|
#ifdef TORRENT_WINDOWS
|
||||||
|
if (m_low_prio_io)
|
||||||
|
set_low_priority(e.file_ptr);
|
||||||
|
#endif
|
||||||
e.mode = m;
|
e.mode = m;
|
||||||
e.key = st;
|
e.key = st;
|
||||||
m_files.insert(std::make_pair(std::make_pair(st, fs.file_index(*fe)), e));
|
m_files.insert(std::make_pair(std::make_pair(st, fs.file_index(*fe)), e));
|
||||||
|
|
Loading…
Reference in New Issue