diff options
author | Zeno Albisser <zeno.albisser@nokia.com> | 2010-04-15 13:28:31 (GMT) |
---|---|---|
committer | Zeno Albisser <zeno.albisser@nokia.com> | 2010-04-23 08:13:54 (GMT) |
commit | 242845a50410e7b97206f6374408a2e53b5c29fb (patch) | |
tree | 082c813b80adad61e5d59db40bdf58e06f1fbb87 /tests/auto/qfileinfo | |
parent | 06823355a435fa9bc9b5aa39d8687e85b3b7beaf (diff) | |
download | Qt-242845a50410e7b97206f6374408a2e53b5c29fb.zip Qt-242845a50410e7b97206f6374408a2e53b5c29fb.tar.gz Qt-242845a50410e7b97206f6374408a2e53b5c29fb.tar.bz2 |
Added support for symlinks and junction points on Windows
Since ntfs symlinks (not .lnk files) can use
relative paths to targets, support for relative links
needed to be added.
Directory junctions can also be used to mount another
filesystem directly into an existing folder.
Such junctions in that case use the volume id of the
target volume for the link path. Therefor this commit
also includes an implementation for resolving volume ids.
To be independent of existing directories in test code
i added a function to create own junction points.
Reviewed-by: Joao
Task-number: QTBUG-9009, QTBUG-7036
Diffstat (limited to 'tests/auto/qfileinfo')
-rw-r--r-- | tests/auto/qfileinfo/tst_qfileinfo.cpp | 113 |
1 files changed, 112 insertions, 1 deletions
diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 403c5f9..d482cbc 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -56,6 +56,7 @@ #endif #ifdef Q_OS_WIN #include <qt_windows.h> +#include <qlibrary.h> #endif #include <qplatformdefs.h> #include <qdebug.h> @@ -65,6 +66,7 @@ #endif #include "../network-settings.h" #include <private/qfileinfo_p.h> +#include "../../shared/filesystem.h" #if defined(Q_OS_SYMBIAN) # define SRCDIR "" @@ -161,6 +163,8 @@ private slots: void refresh(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + void ntfsJunctionPointsAndSymlinks_data(); + void ntfsJunctionPointsAndSymlinks(); void brokenShortcut(); #endif @@ -194,8 +198,15 @@ tst_QFileInfo::~tst_QFileInfo() #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) QDir().rmdir("./.hidden-directory"); #endif -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QDir().rmdir("./hidden-directory"); + QDir().rmdir("abs_symlink"); + QDir().rmdir("rel_symlink"); + QDir().rmdir("junction_pwd"); + QDir().rmdir("junction_root"); + QDir().rmdir("mountpoint"); + QFile::remove("abs_symlink.cpp"); + QFile::remove("rel_symlink.cpp"); #endif } @@ -1236,6 +1247,106 @@ void tst_QFileInfo::refresh() } #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isSymLink"); + QTest::addColumn<QString>("linkTarget"); + QTest::addColumn<QString>("canonicalFilePath"); + + QDir pwd; + pwd.mkdir("target"); + + QLibrary kernel32("kernel32"); + typedef BOOLEAN (WINAPI *PtrCreateSymbolicLink)(LPCWSTR, LPCWSTR, DWORD); + PtrCreateSymbolicLink createSymbolicLinkW = 0; + createSymbolicLinkW = (PtrCreateSymbolicLink) kernel32.resolve("CreateSymbolicLinkW"); + if (!createSymbolicLinkW) + QSKIP("symbolic links not supported by operating system",SkipSingle); + + { + //Directory symlinks + QDir target("target"); + QVERIFY(target.exists()); + + QString absTarget = QDir::toNativeSeparators(target.absolutePath()); + QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink"); + QString relTarget = "target"; + QString relSymlink = "rel_symlink"; + QString fileInTarget(absTarget); + fileInTarget.append("\\file"); + QString fileInSymlink(absSymlink); + fileInSymlink.append("\\file"); + QFile file(fileInTarget); + file.open(QIODevice::ReadWrite); + file.close(); + + QVERIFY(pwd.exists("abs_symlink") || createSymbolicLinkW(absSymlink.utf16(),absTarget.utf16(),0x1)); + QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW(relSymlink.utf16(),relTarget.utf16(),0x1)); + QVERIFY(file.exists()); + + QTest::newRow("absolute dir symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath(); + QTest::newRow("relative dir symlink") << relSymlink << true << QDir::fromNativeSeparators(relTarget) << target.canonicalPath(); + QTest::newRow("file in symlink dir") << fileInSymlink << false << "" << target.canonicalPath().append("/file"); + } + { + //File symlinks + QFileInfo target(SRCDIR "tst_qfileinfo.cpp"); + QString absTarget = QDir::toNativeSeparators(target.absoluteFilePath()); + QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink.cpp"); + QString relTarget = QDir::toNativeSeparators(pwd.relativeFilePath(target.absoluteFilePath())); + QString relSymlink = "rel_symlink.cpp"; + QVERIFY(pwd.exists("abs_symlink.cpp") || createSymbolicLinkW(absSymlink.utf16(),absTarget.utf16(),0x0)); + QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW(relSymlink.utf16(),relTarget.utf16(),0x0)); + + QTest::newRow("absolute file symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath(); + QTest::newRow("relative file symlink") << relSymlink << true << QDir::fromNativeSeparators(relTarget) << target.canonicalFilePath(); + } + + //Junctions + QString target = "target"; + QString junction = "junction_pwd"; + FileSystem::createNtfsJunction(target, junction); + QFileInfo targetInfo(target); + QTest::newRow("junction_pwd") << junction << true << targetInfo.absoluteFilePath() << targetInfo.canonicalFilePath(); + + QFileInfo fileInJunction(targetInfo.absoluteFilePath().append("/file")); + QFile file(fileInJunction.absoluteFilePath()); + file.open(QIODevice::ReadWrite); + file.close(); + QVERIFY(file.exists()); + QTest::newRow("file in junction") << fileInJunction.absoluteFilePath() << false << "" << fileInJunction.canonicalFilePath(); + + target = QDir::rootPath(); + junction = "junction_root"; + FileSystem::createNtfsJunction(target, junction); + targetInfo.setFile(target); + QTest::newRow("junction_root") << junction << true << targetInfo.absoluteFilePath() << targetInfo.canonicalFilePath(); + + //Mountpoint + wchar_t buffer[MAX_PATH]; + QString rootPath = QDir::toNativeSeparators(QDir::rootPath()); + QVERIFY(GetVolumeNameForVolumeMountPointW(rootPath.utf16(), buffer, MAX_PATH)); + QString rootVolume = QString::fromWCharArray(buffer); + junction = "mountpoint"; + rootVolume.replace("\\\\?\\","\\??\\"); + FileSystem::createNtfsJunction(rootVolume, junction); + QTest::newRow("mountpoint") << junction << true << QDir::fromNativeSeparators(rootPath) << QDir::rootPath(); +} + +void tst_QFileInfo::ntfsJunctionPointsAndSymlinks() +{ + QFETCH(QString, path); + QFETCH(bool, isSymLink); + QFETCH(QString, linkTarget); + QFETCH(QString, canonicalFilePath); + + QFileInfo fi(path); + QCOMPARE(fi.isSymLink(), isSymLink); + QCOMPARE(fi.symLinkTarget(), linkTarget); + QCOMPARE(fi.canonicalFilePath(), canonicalFilePath); +} + void tst_QFileInfo::brokenShortcut() { QString linkName("borkenlink.lnk"); |