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
|
||||
* make files deleted alert non-discardable
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
#if _WIN32_WINNT >= 0x501
|
||||
|
||||
if ((m_open_mode & sparse) == 0)
|
||||
{
|
||||
// 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)
|
||||
typedef DWORD (WINAPI *GetCompressedFileSizeW_t)(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh);
|
||||
typedef BOOL (WINAPI *SetFileValidData_t)(HANDLE hFile, LONGLONG ValidDataLength);
|
||||
|
||||
static GetCompressedFileSizeW_t GetCompressedFileSizeW = NULL;
|
||||
static SetFileValidData_t SetFileValidData = NULL;
|
||||
|
||||
static bool failed_kernel32 = false;
|
||||
|
||||
if ((GetCompressedFileSizeW == NULL) && !failed_kernel32)
|
||||
{
|
||||
// if the user has permissions, avoid filling
|
||||
// the file with zeroes, but just fill it with
|
||||
// garbage instead
|
||||
SetFileValidData(m_file_handle, offs.QuadPart);
|
||||
HMODULE kernel32 = LoadLibraryA("kernel32.dll");
|
||||
if (kernel32)
|
||||
{
|
||||
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
|
||||
struct stat st;
|
||||
if (fstat(m_fd, &st) != 0)
|
||||
|
|
|
@ -101,6 +101,73 @@ namespace libtorrent
|
|||
}
|
||||
#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
|
||||
, file_storage::iterator fe, file_storage const& fs, int m, error_code& ec)
|
||||
{
|
||||
|
@ -154,17 +221,8 @@ namespace libtorrent
|
|||
return boost::intrusive_ptr<file>();
|
||||
}
|
||||
#ifdef TORRENT_WINDOWS
|
||||
// file prio is supported on vista and up
|
||||
#if _WIN32_WINNT >= 0x0600
|
||||
if (m_low_prio_io)
|
||||
{
|
||||
// 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
|
||||
set_low_priority(e.file_ptr);
|
||||
#endif
|
||||
TORRENT_ASSERT(e.file_ptr->is_open());
|
||||
e.mode = m;
|
||||
|
@ -189,6 +247,10 @@ namespace libtorrent
|
|||
std::string full_path = combine_path(p, fs.file_path(*fe));
|
||||
if (!e.file_ptr->open(full_path, m, ec))
|
||||
return boost::intrusive_ptr<file>();
|
||||
#ifdef TORRENT_WINDOWS
|
||||
if (m_low_prio_io)
|
||||
set_low_priority(e.file_ptr);
|
||||
#endif
|
||||
e.mode = m;
|
||||
e.key = st;
|
||||
m_files.insert(std::make_pair(std::make_pair(st, fs.file_index(*fe)), e));
|
||||
|
|
Loading…
Reference in New Issue