Allow symbolic links in torrent creator on Windows

Note that .lnk files (shortcuts) are always ignored on Windows.

Closes #22665.
PR #22675.
This commit is contained in:
Chocobo1 2025-05-14 07:13:52 +08:00 committed by GitHub
commit 09071d2b69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -124,18 +124,20 @@ void TorrentCreator::run()
// need to sort the file names by natural sort order // need to sort the file names by natural sort order
QStringList dirs = {m_params.sourcePath.data()}; QStringList dirs = {m_params.sourcePath.data()};
#ifdef Q_OS_WIN QDirIterator dirIter {m_params.sourcePath.data(), (QDir::AllDirs | QDir::NoDotAndDotDot), QDirIterator::Subdirectories};
// libtorrent couldn't handle .lnk files on Windows
// Also, Windows users do not expect torrent creator to traverse into .lnk files so skip over them
const QDir::Filters dirFilters {QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks};
#else
const QDir::Filters dirFilters {QDir::AllDirs | QDir::NoDotAndDotDot};
#endif
QDirIterator dirIter {m_params.sourcePath.data(), dirFilters, QDirIterator::Subdirectories};
while (dirIter.hasNext()) while (dirIter.hasNext())
{ {
const QString filePath = dirIter.next(); const QFileInfo dirInfo = dirIter.nextFileInfo();
dirs.append(filePath);
#ifdef Q_OS_WIN
// .lnk to directory
// Windows users do not expect torrent creator to traverse into .lnk files so skip over them
if (dirInfo.isShortcut())
continue;
#endif
const QString dirPath = dirInfo.filePath();
dirs.append(dirPath);
} }
std::sort(dirs.begin(), dirs.end(), naturalLessThan); std::sort(dirs.begin(), dirs.end(), naturalLessThan);
@ -146,19 +148,29 @@ void TorrentCreator::run()
{ {
QStringList tmpNames; // natural sort files within each dir QStringList tmpNames; // natural sort files within each dir
#ifdef Q_OS_WIN QDirIterator fileIter {dir, QDir::Files};
const QDir::Filters fileFilters {QDir::Files | QDir::NoSymLinks};
#else
const QDir::Filters fileFilters {QDir::Files};
#endif
QDirIterator fileIter {dir, fileFilters};
while (fileIter.hasNext()) while (fileIter.hasNext())
{ {
const QFileInfo fileInfo = fileIter.nextFileInfo(); const QFileInfo fileInfo = fileIter.nextFileInfo();
const Path filePath {fileInfo.filePath()};
qint64 fileSize = fileInfo.size();
const Path relFilePath = parentPath.relativePathOf(Path(fileInfo.filePath())); #ifdef Q_OS_WIN
// .lnk to file
// libtorrent couldn't handle .lnk files on Windows
if (fileInfo.isShortcut())
continue;
// file symbolic link
// QFileInfo::size() failed to return the target file size
// and we need to redirect it manually
if (fileInfo.isSymbolicLink())
fileSize = QFileInfo(fileInfo.symLinkTarget()).size();
#endif
const Path relFilePath = parentPath.relativePathOf(filePath);
tmpNames.append(relFilePath.toString()); tmpNames.append(relFilePath.toString());
fileSizeMap[tmpNames.last()] = fileInfo.size(); fileSizeMap[tmpNames.last()] = fileSize;
} }
std::sort(tmpNames.begin(), tmpNames.end(), naturalLessThan); std::sort(tmpNames.begin(), tmpNames.end(), naturalLessThan);
@ -174,8 +186,8 @@ void TorrentCreator::run()
#ifdef QBT_USES_LIBTORRENT2 #ifdef QBT_USES_LIBTORRENT2
lt::create_torrent newTorrent {fs, m_params.pieceSize, toNativeTorrentFormatFlag(m_params.torrentFormat)}; lt::create_torrent newTorrent {fs, m_params.pieceSize, toNativeTorrentFormatFlag(m_params.torrentFormat)};
#else #else
lt::create_torrent newTorrent(fs, m_params.pieceSize, m_params.paddedFileSizeLimit lt::create_torrent newTorrent {fs, m_params.pieceSize, m_params.paddedFileSizeLimit
, (m_params.isAlignmentOptimized ? lt::create_torrent::optimize_alignment : lt::create_flags_t {})); , (m_params.isAlignmentOptimized ? lt::create_torrent::optimize_alignment : lt::create_flags_t {})};
#endif #endif
// Add url seeds // Add url seeds