diff options
author | Ritt Konstantin <ritt.ks@gmail.com> | 2009-08-21 15:26:53 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@trolltech.com> | 2009-08-21 15:27:28 +0200 |
commit | 1216161584b730576c24fb128131838be1826b37 (patch) | |
tree | ce51a1310cf0617ac23da46c17ecec91bea48c02 | |
parent | bf417fc0347467092dfd12a72ed8177524b473d4 (diff) |
NTFS symlink support for QFileInfo::isSymLink()
We will handle reparse points with IO_REPARSE_TAG_MOUNT_POINT
and IO_REPARSE_TAG_SYMLINK tag values only.
isSymlink() assumes doStat() was called early.
Merge-request: 1217
Reviewed-by: Joerg Bornemann <joerg.bornemann@trolltech.com>
-rw-r--r-- | src/corelib/io/qfsfileengine.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_p.h | 3 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_win.cpp | 40 |
3 files changed, 42 insertions, 3 deletions
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 3d109d137c..1ca19cfc45 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -109,7 +109,7 @@ void QFSFileEnginePrivate::init() { is_sequential = 0; tried_stat = 0; -#ifdef Q_OS_UNIX +#if !defined(Q_OS_WINCE) need_lstat = 1; is_link = 0; #endif diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 15cbf5cb3b..3c1e7e0432 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -137,10 +137,11 @@ public: mutable uint is_sequential : 2; mutable uint could_stat : 1; mutable uint tried_stat : 1; -#ifdef Q_OS_UNIX +#if !defined(Q_OS_WINCE) mutable uint need_lstat : 1; mutable uint is_link : 1; #endif + bool doStat() const; bool isSymlink() const; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index e524e8e3a1..7b08767319 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1440,6 +1440,41 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const } /*! + \internal +*/ +bool QFSFileEnginePrivate::isSymlink() const +{ +#if !defined(Q_OS_WINCE) + if (need_lstat) { + need_lstat = false; + is_link = false; + + if (fileAttrib & FILE_ATTRIBUTE_REPARSE_POINT) { + QString path = QDir::toNativeSeparators(filePath); + // path for the FindFirstFile should not end with a trailing slash + while (path.endsWith(QLatin1Char('\\'))) + path.chop(1); + + WIN32_FIND_DATA findData; + HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), + &findData); + if (hFind != INVALID_HANDLE_VALUE) { + ::FindClose(hFind); + if ((findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + && (findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT + || findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) { + is_link = true; + } + } + } + } + return is_link; +#else + return false; +#endif // Q_OS_WINCE +} + +/*! \reimp */ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::FileFlags type) const @@ -1449,6 +1484,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil // Force a stat, so that we're guaranteed to get up-to-date results if (type & Refresh) { d->tried_stat = 0; +#if !defined(Q_OS_WINCE) + d->need_lstat = 1; +#endif } if (type & PermsMask) { @@ -1472,7 +1510,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil ret |= FileType; } } else if (d->doStat()) { - if (d->fileAttrib & FILE_ATTRIBUTE_REPARSE_POINT) + if ((type & LinkType) && d->isSymlink()) ret |= LinkType; if (d->fileAttrib & FILE_ATTRIBUTE_DIRECTORY) { ret |= DirectoryType; |