From 97b448b152f0148adb2426c2a4e1f83dd150db3c Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 26 Jan 2016 12:06:40 +0300 Subject: Use QFile::exists(f) instead of QFile(f).exists(). It's faster. Change-Id: Ie57619b4e0c53975aa955c83c833c34e1446e4c8 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/io') diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index ce1684a943..4474fd3f52 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -747,7 +747,7 @@ QFile::copy(const QString &newName) qWarning("QFile::copy: Empty or null file name"); return false; } - if (QFile(newName).exists()) { + if (QFile::exists(newName)) { // ### Race condition. If a file is moved in after this, it /will/ be // overwritten. On Unix, the proper solution is to use hardlinks: // return ::link(old, new) && ::remove(old); See also rename(). -- cgit v1.2.3 From 910f719bd111813f37278b67d07f9d12cb03a4ff Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 26 Jan 2016 10:44:28 +0100 Subject: Refactor QStandardPaths for Desktop Windows. Replace the large switch in QStandardPaths::writableLocation() by a function mapping QStandardPaths::StandardLocation to the int clsid required by SHGetSpecialFolderPath(). Warn if SHGetSpecialFolderPath() fails for config location and append prefixes (cache/application name/organization) only on success. Change the logic in QStandardPaths::standardLocations() to append the writable location first, avoiding the prepend(). Task-number: QTBUG-50570 Change-Id: I9d80e83d1ca7af3ea8d3ac2c720ee981b1b2c32a Reviewed-by: Joerg Bornemann --- src/corelib/io/qstandardpaths_win.cpp | 258 +++++++++++++++++++--------------- 1 file changed, 143 insertions(+), 115 deletions(-) (limited to 'src/corelib/io') diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index ed1c14ad8a..73d49cbc25 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -41,9 +41,7 @@ #include #endif -#if !defined(Q_OS_WINCE) const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; -#endif #include #include @@ -64,113 +62,152 @@ const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x6 QT_BEGIN_NAMESPACE -#if !defined(Q_OS_WINCE) -typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*); -#endif - static QString convertCharArray(const wchar_t *path) { return QDir::fromNativeSeparators(QString::fromWCharArray(path)); } -static inline int clsidForAppDataLocation(QStandardPaths::StandardLocation type) +static inline bool isGenericConfigLocation(QStandardPaths::StandardLocation type) { -#ifndef Q_OS_WINCE - return type == QStandardPaths::AppDataLocation ? - CSIDL_APPDATA : // "Roaming" path - CSIDL_LOCAL_APPDATA; // Local path -#else - Q_UNUSED(type) - return CSIDL_APPDATA; -#endif + return type == QStandardPaths::GenericConfigLocation || type == QStandardPaths::GenericDataLocation; } -QString QStandardPaths::writableLocation(StandardLocation type) +static inline bool isConfigLocation(QStandardPaths::StandardLocation type) { - QString result; + return type == QStandardPaths::ConfigLocation || type == QStandardPaths::AppConfigLocation + || type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation + || isGenericConfigLocation(type); +} -#if !defined(Q_OS_WINCE) - static GetKnownFolderPath SHGetKnownFolderPath = (GetKnownFolderPath)QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath"); +static void appendOrganizationAndApp(QString &path) // Courtesy qstandardpaths_unix.cpp +{ +#ifndef QT_BOOTSTRAPPED + const QString &org = QCoreApplication::organizationName(); + if (!org.isEmpty()) + path += QLatin1Char('/') + org; + const QString &appName = QCoreApplication::applicationName(); + if (!appName.isEmpty()) + path += QLatin1Char('/') + appName; +#else // !QT_BOOTSTRAPPED + Q_UNUSED(path) #endif +} - wchar_t path[MAX_PATH]; - - switch (type) { - case ConfigLocation: // same as AppLocalDataLocation, on Windows - case GenericConfigLocation: // same as GenericDataLocation on Windows - case AppConfigLocation: - case AppDataLocation: - case AppLocalDataLocation: - case GenericDataLocation: - if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE)) - result = convertCharArray(path); - if (isTestModeEnabled()) - result += QLatin1String("/qttest"); +static inline QString displayName(QStandardPaths::StandardLocation type) +{ #ifndef QT_BOOTSTRAPPED - if (type != GenericDataLocation && type != GenericConfigLocation) { - if (!QCoreApplication::organizationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::organizationName(); - if (!QCoreApplication::applicationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::applicationName(); - } + return QStandardPaths::displayName(type); +#else + return QString::number(type); #endif - break; +} - case DesktopLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE)) - result = convertCharArray(path); - break; +static inline void appendTestMode(QString &path) +{ + if (QStandardPaths::isTestModeEnabled()) + path += QLatin1String("/qttest"); +} - case DownloadLocation: -#if !defined(Q_OS_WINCE) - if (SHGetKnownFolderPath) { - LPWSTR path; - if (SHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, 0, 0, &path) == S_OK) { - result = convertCharArray(path); - CoTaskMemFree(path); - } - break; +// Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath() +static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type) +{ + static const int clsids[] = { + CSIDL_DESKTOPDIRECTORY, // DesktopLocation + CSIDL_PERSONAL, // DocumentsLocation + CSIDL_FONTS, // FontsLocation + CSIDL_PROGRAMS, // ApplicationsLocation + CSIDL_MYMUSIC, // MusicLocation + CSIDL_MYVIDEO, // MoviesLocation + CSIDL_MYPICTURES, // PicturesLocation + -1, -1, // TempLocation/HomeLocation + CSIDL_LOCAL_APPDATA, // AppLocalDataLocation ("Local" path), AppLocalDataLocation = DataLocation + -1, // CacheLocation + CSIDL_LOCAL_APPDATA, // GenericDataLocation ("Local" path) + -1, // RuntimeLocation + CSIDL_LOCAL_APPDATA, // ConfigLocation ("Local" path) + -1, -1, // DownloadLocation/GenericCacheLocation + CSIDL_LOCAL_APPDATA, // GenericConfigLocation ("Local" path) + CSIDL_APPDATA, // AppDataLocation ("Roaming" path) + CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path) + }; + + Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1)); + return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1; +}; + +// Convenience for SHGetSpecialFolderPath(). +static QString sHGetSpecialFolderPath(int clsid, QStandardPaths::StandardLocation type, bool warn = false) +{ + QString result; + wchar_t path[MAX_PATH]; + if (Q_LIKELY(clsid >= 0 && SHGetSpecialFolderPath(0, path, clsid, FALSE))) { + result = convertCharArray(path); + } else { + if (warn) { + qErrnoWarning("SHGetSpecialFolderPath() failed for standard location \"%s\", clsid=0x%x.", + qPrintable(displayName(type)), clsid); } -#endif - // fall through - case DocumentsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE)) - result = convertCharArray(path); - break; - - case FontsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_FONTS, FALSE)) - result = convertCharArray(path); - break; - - case ApplicationsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_PROGRAMS, FALSE)) - result = convertCharArray(path); - break; - - case MusicLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYMUSIC, FALSE)) - result = convertCharArray(path); - break; + } + return result; +} - case MoviesLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE)) - result = convertCharArray(path); - break; +// Convenience for SHGetKnownFolderPath(). +static QString sHGetKnownFolderPath(const GUID &clsid, QStandardPaths::StandardLocation type, bool warn = false) +{ + QString result; +#ifndef Q_OS_WINCE + typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*); + + static const GetKnownFolderPath sHGetKnownFolderPath = // Vista onwards. + reinterpret_cast(QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath")); + + LPWSTR path; + if (Q_LIKELY(sHGetKnownFolderPath && SUCCEEDED(sHGetKnownFolderPath(clsid, 0, 0, &path)))) { + result = convertCharArray(path); + CoTaskMemFree(path); + } else { + if (warn) { + qErrnoWarning("SHGetKnownFolderPath() failed for standard location \"%s\".", + qPrintable(displayName(type))); + } + } +#else // !Q_OS_WINCE + Q_UNUSED(clsid) + Q_UNUSED(type) + Q_UNUSED(warn) +#endif + return result; +} - case PicturesLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE)) - result = convertCharArray(path); +QString QStandardPaths::writableLocation(StandardLocation type) +{ + QString result; + switch (type) { + case DownloadLocation: + result = sHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, type); + if (result.isEmpty()) + result = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); break; case CacheLocation: // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache // location for everyone. Most applications seem to be using a // cache directory located in their AppData directory - return writableLocation(AppLocalDataLocation) + QLatin1String("/cache"); + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(AppLocalDataLocation), type, /* warn */ true); + if (!result.isEmpty()) { + appendTestMode(result); + appendOrganizationAndApp(result); + result += QLatin1String("/cache"); + } + break; case GenericCacheLocation: - return writableLocation(GenericDataLocation) + QLatin1String("/cache"); + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(GenericDataLocation), type, /* warn */ true); + if (!result.isEmpty()) { + appendTestMode(result); + result += QLatin1String("/cache"); + } + break; case RuntimeLocation: case HomeLocation: @@ -180,6 +217,15 @@ QString QStandardPaths::writableLocation(StandardLocation type) case TempLocation: result = QDir::tempPath(); break; + + default: + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(type), type, /* warn */ isConfigLocation(type)); + if (!result.isEmpty() && isConfigLocation(type)) { + appendTestMode(result); + if (!isGenericConfigLocation(type)) + appendOrganizationAndApp(result); + } + break; } return result; } @@ -187,44 +233,26 @@ QString QStandardPaths::writableLocation(StandardLocation type) QStringList QStandardPaths::standardLocations(StandardLocation type) { QStringList dirs; + const QString localDir = writableLocation(type); + if (!localDir.isEmpty()) + dirs.append(localDir); // type-specific handling goes here - #ifndef Q_OS_WINCE - { - wchar_t path[MAX_PATH]; - switch (type) { - case ConfigLocation: // same as AppLocalDataLocation, on Windows (oversight, but too late to fix it) - case GenericConfigLocation: // same as GenericDataLocation, on Windows - case AppConfigLocation: // same as AppLocalDataLocation, that one on purpose - case AppDataLocation: - case AppLocalDataLocation: - case GenericDataLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) { - QString result = convertCharArray(path); - if (type != GenericDataLocation && type != GenericConfigLocation) { -#ifndef QT_BOOTSTRAPPED - if (!QCoreApplication::organizationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::organizationName(); - if (!QCoreApplication::applicationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::applicationName(); -#endif - } - dirs.append(result); -#ifndef QT_BOOTSTRAPPED - dirs.append(QCoreApplication::applicationDirPath()); - dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data")); -#endif - } - break; - default: - break; + if (isConfigLocation(type)) { + QString programData = sHGetSpecialFolderPath(CSIDL_COMMON_APPDATA, type); + if (!programData.isEmpty()) { + if (!isGenericConfigLocation(type)) + appendOrganizationAndApp(programData); + dirs.append(programData); } - } -#endif +# ifndef QT_BOOTSTRAPPED + dirs.append(QCoreApplication::applicationDirPath()); + dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data")); +# endif // !QT_BOOTSTRAPPED + } // isConfigLocation() +#endif // !Q_OS_WINCE - const QString localDir = writableLocation(type); - dirs.prepend(localDir); return dirs; } -- cgit v1.2.3 From 0ec1e13234684feb632fc980ba2a90db9a2dd936 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 9 Apr 2015 16:17:37 +0200 Subject: Do not build QWindowsPipeWriter on Windows CE QWindowsPipeWriter is not used in the Windows CE port. Change-Id: I068dd2408bb21a7e2a86886e0692b1636016ff6a Reviewed-by: Andreas Holzammer --- src/corelib/io/io.pri | 6 +++--- src/corelib/io/qprocess_wince.cpp | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/corelib/io') diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index b2bcbdf727..8d9908cd90 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -107,8 +107,6 @@ win32 { !winrt { SOURCES += io/qsettings_win.cpp - HEADERS += io/qwindowspipewriter_p.h - SOURCES += io/qwindowspipewriter.cpp SOURCES += io/qstandardpaths_win.cpp wince* { @@ -117,11 +115,13 @@ win32 { } else { HEADERS += \ io/qwinoverlappedionotifier_p.h \ - io/qwindowspipereader_p.h + io/qwindowspipereader_p.h \ + io/qwindowspipewriter_p.h SOURCES += \ io/qprocess_win.cpp \ io/qwinoverlappedionotifier.cpp \ io/qwindowspipereader.cpp \ + io/qwindowspipewriter.cpp \ io/qstorageinfo_win.cpp LIBS += -lmpr } diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index acacdb8540..050d6879db 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -33,7 +33,6 @@ #include "qprocess.h" #include "qprocess_p.h" -#include "qwindowspipewriter_p.h" #include #include @@ -156,7 +155,7 @@ void QProcessPrivate::startProcess() } // give the process a chance to start ... - Sleep(SLEEPMIN * 2); + Sleep(20); _q_startupNotification(); } -- cgit v1.2.3