summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRitt Konstantin <ritt.ks@gmail.com>2009-08-21 15:26:53 +0200
committerJoerg Bornemann <joerg.bornemann@trolltech.com>2009-08-21 15:27:28 +0200
commit1216161584b730576c24fb128131838be1826b37 (patch)
treece51a1310cf0617ac23da46c17ecec91bea48c02
parentbf417fc0347467092dfd12a72ed8177524b473d4 (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.cpp2
-rw-r--r--src/corelib/io/qfsfileengine_p.h3
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp40
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;