diff options
author | axis <qt-info@nokia.com> | 2009-08-21 13:48:44 (GMT) |
---|---|---|
committer | axis <qt-info@nokia.com> | 2009-08-21 13:48:44 (GMT) |
commit | afd7cfce7333635edc8d3637f81cc9c3023ee874 (patch) | |
tree | 433345bd8cfd4a2c057a24ee3c906d274d6282ca | |
parent | 044680951401487590c0ed554092dd9b7e0ee783 (diff) | |
parent | 3513c1a01b319fb5fd4057be306c9f9506f8223d (diff) | |
download | Qt-afd7cfce7333635edc8d3637f81cc9c3023ee874.zip Qt-afd7cfce7333635edc8d3637f81cc9c3023ee874.tar.gz Qt-afd7cfce7333635edc8d3637f81cc9c3023ee874.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt into master-s60
Conflicts:
src/corelib/io/qfsfileengine_unix.cpp
src/corelib/plugin/qlibrary.cpp
tests/auto/qfileinfo/tst_qfileinfo.cpp
-rw-r--r-- | src/corelib/io/qfsfileengine.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_p.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 26 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_win.cpp | 236 | ||||
-rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 29 | ||||
-rw-r--r-- | tests/auto/qfileinfo/tst_qfileinfo.cpp | 64 |
6 files changed, 249 insertions, 112 deletions
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 3d109d1..1ca19cf 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 15cbf5c..b245dca 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; @@ -161,7 +162,6 @@ protected: #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) QAbstractFileEngine::FileFlags getPermissions() const; - QString getLink() const; #endif }; diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 3bc2616..7a815fe 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -594,21 +594,21 @@ QString QFSFileEngine::homePath() QString QFSFileEngine::rootPath() { #if defined(Q_OS_SYMBIAN) - return QString::fromLatin1("C:/"); + return QLatin1String("C:/"); #else - return QString::fromLatin1("/"); + return QLatin1String("/"); #endif } QString QFSFileEngine::tempPath() { #ifdef Q_OS_SYMBIAN - QString temp = QDir::currentPath().left(2); - temp += QString::fromLatin1( "/system/temp/"); + QString temp = QDir::currentPath().left(2); + temp += QLatin1String("/system/temp/"); #else - QString temp = QFile::decodeName(qgetenv("TMPDIR")); - if (temp.isEmpty()) - temp = QString::fromLatin1("/tmp/"); + QString temp = QFile::decodeName(qgetenv("TMPDIR")); + if (temp.isEmpty()) + temp = QLatin1String("/tmp/"); #endif return temp; } @@ -631,7 +631,7 @@ QFileInfoList QFSFileEngine::drives() qWarning("QDir::drives: Getting drives failed"); } #else - ret.append(rootPath()); + ret.append(QFileInfo(rootPath())); #endif return ret; } @@ -778,11 +778,11 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const else if (exists && (d->st.st_mode & S_IFMT) == S_IFDIR) ret |= DirectoryType; #if !defined(QWS) && defined(Q_OS_MAC) - if((ret & DirectoryType) && (type & BundleType)) { + if ((ret & DirectoryType) && (type & BundleType)) { QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath), kCFURLPOSIXPathStyle, true); UInt32 type, creator; - if(CFBundleGetPackageInfoInDirectory(url, &type, &creator)) + if (CFBundleGetPackageInfoInDirectory(url, &type, &creator)) ret |= BundleType; } #endif @@ -943,9 +943,9 @@ QString QFSFileEngine::fileName(FileName file) const #if !defined(QWS) && defined(Q_OS_MAC) QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath), kCFURLPOSIXPathStyle, true); - if(CFDictionaryRef dict = CFBundleCopyInfoDictionaryForURL(url)) { - if(CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) { - if(CFGetTypeID(name) == CFStringGetTypeID()) + if (CFDictionaryRef dict = CFBundleCopyInfoDictionaryForURL(url)) { + if (CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) { + if (CFGetTypeID(name) == CFStringGetTypeID()) return QCFString::toQString((CFStringRef)name); } } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index afe7b35..f1f69e7 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -55,6 +55,7 @@ #if !defined(Q_OS_WINCE) # include <sys/types.h> # include <direct.h> +# include <winioctl.h> #else # include <types.h> #endif @@ -88,6 +89,37 @@ typedef INT_PTR intptr_t; # define INVALID_FILE_ATTRIBUTES (DWORD (-1)) #endif +#if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) && !defined(Q_OS_WINCE) +typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + }; +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; + +# define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) +# define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384 +#endif + QT_BEGIN_NAMESPACE static QString readLink(const QString &link); @@ -122,7 +154,7 @@ QT_END_INCLUDE_NAMESPACE void QFSFileEnginePrivate::resolveLibs() { static bool triedResolve = false; - if(!triedResolve) { + if (!triedResolve) { // need to resolve the security info functions // protect initialization @@ -130,7 +162,7 @@ void QFSFileEnginePrivate::resolveLibs() QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); // check triedResolve again, since another thread may have already // done the initialization - if(triedResolve) { + if (triedResolve) { // another thread did initialize the security function pointers, // so we shouldn't do it again. return; @@ -219,7 +251,7 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL if (resolveUNCLibs()) { SHARE_INFO_1 *BufPtr, *p; DWORD res; - DWORD er=0,tr=0,resume=0, i; + DWORD er = 0, tr = 0, resume = 0, i; do { res = ptrNetShareEnum((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume); if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) { @@ -231,7 +263,7 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL } } ptrNetApiBufferFree(BufPtr); - } while (res==ERROR_MORE_DATA); + } while (res == ERROR_MORE_DATA); return res == ERROR_SUCCESS; } return false; @@ -893,7 +925,7 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con for (int slash=0; slash != -1; oldslash = slash) { slash = dirName.indexOf(QDir::separator(), oldslash+1); if (slash == -1) { - if(oldslash == dirName.length()) + if (oldslash == dirName.length()) break; slash = dirName.length(); } @@ -948,8 +980,8 @@ bool QFSFileEngine::setCurrentPath(const QString &path) #if !defined(Q_OS_WINCE) return ::SetCurrentDirectory((wchar_t*)path.utf16()) != 0; #else - qfsPrivateCurrentDir = QFSFileEnginePrivate::longFileName(path); - return true; + qfsPrivateCurrentDir = QFSFileEnginePrivate::longFileName(path); + return true; #endif } @@ -987,9 +1019,9 @@ QString QFSFileEngine::currentPath(const QString &fileName) ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. return QDir::fromNativeSeparators(ret); #else - Q_UNUSED(fileName); - if (qfsPrivateCurrentDir.isEmpty()) - qfsPrivateCurrentDir = QCoreApplication::applicationDirPath(); + Q_UNUSED(fileName); + if (qfsPrivateCurrentDir.isEmpty()) + qfsPrivateCurrentDir = QCoreApplication::applicationDirPath(); return QDir::fromNativeSeparators(qfsPrivateCurrentDir); #endif @@ -1021,15 +1053,15 @@ QString QFSFileEngine::homePath() } } #endif - if(ret.isEmpty() || !QFile::exists(ret)) { + if (ret.isEmpty() || !QFile::exists(ret)) { ret = QString::fromLocal8Bit(qgetenv("USERPROFILE").constData()); - if(ret.isEmpty() || !QFile::exists(ret)) { + if (ret.isEmpty() || !QFile::exists(ret)) { ret = QString::fromLocal8Bit(qgetenv("HOMEDRIVE").constData()) + QString::fromLocal8Bit(qgetenv("HOMEPATH").constData()); - if(ret.isEmpty() || !QFile::exists(ret)) { + if (ret.isEmpty() || !QFile::exists(ret)) { ret = QString::fromLocal8Bit(qgetenv("HOME").constData()); - if(ret.isEmpty() || !QFile::exists(ret)) { + if (ret.isEmpty() || !QFile::exists(ret)) { #if defined(Q_OS_WINCE) - ret = QString::fromLatin1("\\My Documents"); + ret = QLatin1String("\\My Documents"); if (!QFile::exists(ret)) #endif ret = rootPath(); @@ -1043,12 +1075,12 @@ QString QFSFileEngine::homePath() QString QFSFileEngine::rootPath() { #if defined(Q_OS_WINCE) - QString ret = QString::fromLatin1("/"); + QString ret = QLatin1String("/"); #elif defined(Q_FS_FAT) QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData()); - if(ret.isEmpty()) + if (ret.isEmpty()) ret = QLatin1String("c:"); - ret += QLatin1Char('/'); + ret.append(QLatin1Char('/')); #elif defined(Q_OS_OS2EMX) char dir[4]; _abspath(dir, QLatin1String("/"), _MAX_PATH); @@ -1059,20 +1091,23 @@ QString QFSFileEngine::rootPath() QString QFSFileEngine::tempPath() { - wchar_t tempPath[MAX_PATH]; - int success = GetTempPath(MAX_PATH, tempPath); - QString ret = QString::fromWCharArray(tempPath); - - if (ret.isEmpty() || !success) { + QString ret; + { + wchar_t tempPath[MAX_PATH]; + if (GetTempPath(MAX_PATH, tempPath)) + ret = QString::fromWCharArray(tempPath); + if (!ret.isEmpty()) { + while (ret.endsWith(QLatin1Char('\\'))) + ret.chop(1); + ret = QDir::fromNativeSeparators(ret); + } + } + if (ret.isEmpty()) { #if !defined(Q_OS_WINCE) - ret = QString::fromLatin1("c:/tmp"); + ret = QLatin1String("c:/tmp"); #else - ret = QString::fromLatin1("\\Temp"); + ret = QLatin1String("/Temp"); #endif - } else { - ret = QDir::fromNativeSeparators(ret); - while (ret.at(ret.length()-1) == QLatin1Char('/')) - ret = ret.left(ret.length()-1); } return ret; } @@ -1085,21 +1120,21 @@ QFileInfoList QFSFileEngine::drives() quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff; #elif defined(Q_OS_OS2EMX) quint32 driveBits, cur; - if(DosQueryCurrentDisk(&cur,&driveBits) != NO_ERROR) + if (DosQueryCurrentDisk(&cur, &driveBits) != NO_ERROR) exit(1); driveBits &= 0x3ffffff; #endif char driveName[] = "A:/"; - while(driveBits) { - if(driveBits & 1) - ret.append(QString::fromLatin1(driveName)); + while (driveBits) { + if (driveBits & 1) + ret.append(QFileInfo(QLatin1String(driveName))); driveName[0]++; driveBits = driveBits >> 1; } return ret; #else - ret.append(QString::fromLatin1("/")); + ret.append(QFileInfo(QLatin1String("/"))); return ret; #endif } @@ -1112,10 +1147,11 @@ bool QFSFileEnginePrivate::doStat() const if (filePath.isEmpty()) return could_stat; + QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath; fname = fixIfRelativeUncPath(fname); - UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); + UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); if (fd != -1) { #if !defined(Q_OS_WINCE) @@ -1204,12 +1240,51 @@ bool QFSFileEnginePrivate::doStat() const #endif } } + SetErrorMode(oldmode); } return could_stat; } +static QString readSymLink(const QString &link) +{ + QString result; +#if !defined(Q_OS_WINCE) + HANDLE handle = CreateFile((wchar_t*)QFSFileEnginePrivate::longFileName(link).utf16(), + FILE_READ_EA, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, + 0); + if (handle != INVALID_HANDLE_VALUE) { + DWORD bufsize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE; + REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)qMalloc(bufsize); + DWORD retsize = 0; + if (::DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, 0, 0, rdb, bufsize, &retsize, 0)) { + if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { + int length = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t); + int offset = rdb->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); + const wchar_t* PathBuffer = &rdb->MountPointReparseBuffer.PathBuffer[offset]; + result = QString::fromWCharArray(PathBuffer, length); + } else { + int length = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); + int offset = rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); + const wchar_t* PathBuffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[offset]; + result = QString::fromWCharArray(PathBuffer, length); + } + // cut-off "//?/" and "/??/" + if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\')) + result = result.mid(4); + } + qFree(rdb); + CloseHandle(handle); + } +#endif // Q_OS_WINCE + return result; +} + static QString readLink(const QString &link) { #if !defined(Q_OS_WINCE) @@ -1233,11 +1308,11 @@ static QString readLink(const QString &link) if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface. IPersistFile *ppf; hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); - if(SUCCEEDED(hres)) { + if (SUCCEEDED(hres)) { hres = ppf->Load((LPOLESTR)link.utf16(), STGM_READ); //The original path of the link is retrieved. If the file/folder //was moved, the return value still have the old path. - if(SUCCEEDED(hres)) { + if (SUCCEEDED(hres)) { if (psl->GetPath(szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY) == NOERROR) ret = QString::fromWCharArray(szGotPath); } @@ -1267,14 +1342,6 @@ static QString readLink(const QString &link) #endif // Q_OS_WINCE } -/*! - \internal -*/ -QString QFSFileEnginePrivate::getLink() const -{ - return readLink(filePath); -} - bool QFSFileEngine::link(const QString &newName) { #if !defined(Q_OS_WINCE) @@ -1315,8 +1382,8 @@ bool QFSFileEngine::link(const QString &newName) if (!ret) setError(QFile::RenameError, qt_error_string()); - if(neededCoInit) - CoUninitialize(); + if (neededCoInit) + CoUninitialize(); return ret; #else @@ -1440,6 +1507,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 +1551,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 +1577,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; @@ -1500,32 +1605,32 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); - if(file == BaseName) { + if (file == BaseName) { int slash = d->filePath.lastIndexOf(QLatin1Char('/')); - if(slash == -1) { + if (slash == -1) { int colon = d->filePath.lastIndexOf(QLatin1Char(':')); - if(colon != -1) + if (colon != -1) return d->filePath.mid(colon + 1); return d->filePath; } return d->filePath.mid(slash + 1); - } else if(file == PathName) { - if(!d->filePath.size()) + } else if (file == PathName) { + if (!d->filePath.size()) return d->filePath; int slash = d->filePath.lastIndexOf(QLatin1Char('/')); - if(slash == -1) { - if(d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) + if (slash == -1) { + if (d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) return d->filePath.left(2); return QString(QLatin1Char('.')); } else { - if(!slash) + if (!slash) return QString(QLatin1Char('/')); - if(slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) + if (slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) slash++; return d->filePath.left(slash); } - } else if(file == AbsoluteName || file == AbsolutePathName) { + } else if (file == AbsoluteName || file == AbsolutePathName) { QString ret; if (!isRelativePath()) { @@ -1539,7 +1644,7 @@ QString QFSFileEngine::fileName(FileName file) const ret = d->filePath; } #else - ret = d->filePath; + ret = d->filePath; #endif } else { ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->filePath); @@ -1568,7 +1673,7 @@ QString QFSFileEngine::fileName(FileName file) const return ret.left(slash > 0 ? slash : 1); } return ret; - } else if(file == CanonicalName || file == CanonicalPathName) { + } else if (file == CanonicalName || file == CanonicalPathName) { if (!(fileFlags(ExistsFlag) & ExistsFlag)) return QString(); @@ -1582,9 +1687,14 @@ QString QFSFileEngine::fileName(FileName file) const ret = ret.left(slash); } return ret; - } else if(file == LinkName) { - return QDir::fromNativeSeparators(d->getLink()); - } else if(file == BundleName) { + } else if (file == LinkName) { + QString ret; + if (d->filePath.endsWith(QLatin1String(".lnk"))) + ret = readLink(d->filePath); + else if (d->doStat() && d->isSymlink()) + ret = readSymLink(d->filePath); + return QDir::fromNativeSeparators(ret); + } else if (file == BundleName) { return QString(); } return d->filePath; diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 3a5bb55..5cf6513 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -421,7 +421,23 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB #endif // Q_OS_UNIX && !Q_OS_MAC && !defined(Q_OS_SYMBIAN) && !defined(QT_NO_PLUGIN_CHECK) typedef QMap<QString, QLibraryPrivate*> LibraryMap; -Q_GLOBAL_STATIC(LibraryMap, libraryMap) + +struct LibraryData { + LibraryData() : settings(0) { } + ~LibraryData() { + delete settings; + } + + QSettings *settings; + LibraryMap libraryMap; +}; + +Q_GLOBAL_STATIC(LibraryData, libraryData) + +static LibraryMap *libraryMap() +{ + return &(libraryData()->libraryMap); +} QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version) :pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0), qt_version(0), @@ -614,10 +630,12 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) .arg(fileName); QStringList reg; #ifndef QT_NO_SETTINGS - QScopedPointer<QSettings> madeSettings; if (!settings) { - settings = new QSettings(QSettings::UserScope, QLatin1String("Trolltech")); - madeSettings.reset(settings); + settings = libraryData()->settings; + if (!settings) { + settings = new QSettings(QSettings::UserScope, QLatin1String("Trolltech")); + libraryData()->settings = settings; + } } reg = settings->value(regkey).toStringList(); #endif @@ -709,9 +727,6 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) settings->setValue(regkey, queried); #endif } -#ifndef QT_NO_SETTINGS - madeSettings.reset(); -#endif if (!success) { if (errorString.isEmpty()){ diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 9184def..fb150e5 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -142,6 +142,7 @@ private slots: void fileTimes(); void fileTimes_oldFile(); + void isSymLink_data(); void isSymLink(); void isHidden_data(); @@ -169,6 +170,10 @@ private slots: void notEqualOperator() const; }; +tst_QFileInfo::tst_QFileInfo() +{ +} + tst_QFileInfo::~tst_QFileInfo() { QFile::remove("brokenlink.lnk"); @@ -241,12 +246,6 @@ void tst_QFileInfo::copy() QVERIFY(privateInfo->data != privateInfo3->data); QVERIFY(privateInfo2->data != privateInfo3->data); QCOMPARE(privateInfo->data, privateInfo2->data); - - -} - -tst_QFileInfo::tst_QFileInfo() -{ } void tst_QFileInfo::isFile_data() @@ -532,7 +531,6 @@ void tst_QFileInfo::canonicalFilePath() } # endif #endif - } void tst_QFileInfo::fileName_data() @@ -732,7 +730,6 @@ void tst_QFileInfo::permission_data() QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::ReadUser) << true; QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::WriteUser) << false; QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::ExeUser) << false; - } void tst_QFileInfo::permission() @@ -799,8 +796,8 @@ void tst_QFileInfo::compare_data() #else << false; #endif - } + void tst_QFileInfo::compare() { QFETCH(QString, file1); @@ -973,31 +970,46 @@ void tst_QFileInfo::fileTimes_oldFile() #endif } -void tst_QFileInfo::isSymLink() +void tst_QFileInfo::isSymLink_data() { QFile::remove("link.lnk"); QFile::remove("brokenlink.lnk"); QFile::remove("dummyfile"); - QFileInfo info1("tst_qfileinfo.cpp"); - QVERIFY( !info1.isSymLink() ); + QFile file1("tst_qfileinfo.cpp"); + QVERIFY(file1.link("link.lnk")); - QFile file2("tst_qfileinfo.cpp"); - if (file2.link("link.lnk")) { - QFileInfo info2("link.lnk"); - QVERIFY( info2.isSymLink() ); - } + QFile file2("dummyfile"); + file2.open(QIODevice::WriteOnly); + QVERIFY(file2.link("brokenlink.lnk")); + file2.remove(); - QFile file3("dummyfile"); - file3.open(QIODevice::WriteOnly); - if (file3.link("brokenlink.lnk")) { - // In Symbian ARMV5 builds, this will panic with KERN-EXEC 3 inside OpenC fclose() call - // in QFSFileEnginePrivate::closeFdFh(), if "dummyfile" exists prior calling to isSymLink - // and is not deleted at the beginning of isSymLink. - file3.remove(); - QFileInfo info3("brokenlink.lnk"); - QVERIFY( info3.isSymLink() ); + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isSymLink"); + QTest::addColumn<QString>("linkTarget"); + + QTest::newRow("existent file") << "tst_qfileinfo.cpp" << false << ""; + QTest::newRow("link") << "link.lnk" << true << QFileInfo("tst_qfileinfo.cpp").absoluteFilePath(); + QTest::newRow("broken link") << "brokenlink.lnk" << true << QFileInfo("dummyfile").absoluteFilePath(); + +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + if (QSysInfo::WindowsVersion & QSysInfo::WV_VISTA) { + QTest::newRow("Documents and Settings") << "C:/Documents and Settings" << true << "C:/Users"; + QTest::newRow("All Users") << "C:/Users/All Users" << true << "C:/ProgramData"; + QTest::newRow("Default User") << "C:/Users/Default User" << true << "C:/Users/Default"; } +#endif +} + +void tst_QFileInfo::isSymLink() +{ + QFETCH(QString, path); + QFETCH(bool, isSymLink); + QFETCH(QString, linkTarget); + + QFileInfo fi(path); + QCOMPARE(fi.isSymLink(), isSymLink); + QCOMPARE(fi.symLinkTarget(), linkTarget); } void tst_QFileInfo::isHidden_data() |