forward port of windows symlink fix from RC_1_0

This commit is contained in:
arvidn 2016-01-15 21:21:23 -05:00 committed by arvidn
parent 13c3369463
commit 78d306157b
2 changed files with 33 additions and 22 deletions

View File

@ -78,6 +78,7 @@
* almost completely changed the storage interface (for custom storage) * almost completely changed the storage interface (for custom storage)
* added support for hashing pieces in multiple threads * added support for hashing pieces in multiple threads
* fix support for symlinks on windows
* fix long filename issue (on unixes) * fix long filename issue (on unixes)
* fixed performance bug in DHT torrent eviction * fixed performance bug in DHT torrent eviction
* fixed win64 build (GetFileAttributesEx) * fixed win64 build (GetFileAttributesEx)

View File

@ -359,29 +359,39 @@ namespace libtorrent
TORRENT_UNUSED(flags); TORRENT_UNUSED(flags);
#if TORRENT_USE_WSTRING && defined TORRENT_WINDOWS std::string p = convert_separators(inf);
#define GetFileAttributesEx_ GetFileAttributesExW #if TORRENT_USE_UNC_PATHS
std::wstring f = convert_to_wstring(inf); // UNC paths must be absolute
// network paths are already UNC paths
// apparently windows doesn't expect paths if (inf.substr(0,2) == "\\\\") p = inf;
// to directories to ever end with a \ or / else p = "\\\\?\\" + (is_complete(p) ? p : combine_path(current_working_directory(), p));
if (!f.empty() && (f[f.size() - 1] == L'\\'
|| f[f.size() - 1] == L'/'))
f.resize(f.size() - 1);
#else
#define GetFileAttributesEx_ GetFileAttributesExA
std::string f = convert_to_native(inf);
// apparently windows doesn't expect paths
// to directories to ever end with a \ or /
if (!f.empty() && (f[f.size() - 1] == '\\'
|| f[f.size() - 1] == '/'))
f.resize(f.size() - 1);
#endif #endif
WIN32_FILE_ATTRIBUTE_DATA data;
if (!GetFileAttributesEx_(f.c_str(), GetFileExInfoStandard, &data)) #if TORRENT_USE_WSTRING
#define CreateFile_ CreateFileW
std::wstring f = convert_to_wstring(p);
#else
#define CreateFile_ CreateFileA
std::string f = convert_to_native(p);
#endif
// in order to open a directory, we need the FILE_FLAG_BACKUP_SEMANTICS
HANDLE h = CreateFile_(f.c_str(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ
| FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
{ {
ec.assign(GetLastError(), system_category()); ec.assign(GetLastError(), system_category());
TORRENT_ASSERT(ec);
return;
}
BY_HANDLE_FILE_INFORMATION data;
if (!GetFileInformationByHandle(h, &data))
{
ec.assign(GetLastError(), system_category());
TORRENT_ASSERT(ec);
CloseHandle(h);
return; return;
} }
@ -394,9 +404,9 @@ namespace libtorrent
? file_status::directory ? file_status::directory
: (data.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) : (data.dwFileAttributes & FILE_ATTRIBUTE_DEVICE)
? file_status::character_special : file_status::regular_file; ? file_status::character_special : file_status::regular_file;
CloseHandle(h);
#else #else
// posix version // posix version
std::string const& f = convert_to_native(inf); std::string const& f = convert_to_native(inf);